From 8506e0c01add08c6ce0e02178cee9dc815568cce Mon Sep 17 00:00:00 2001 From: ganthern <nils.ganther@stud.hs-hannover.de> Date: Wed, 7 Apr 2021 19:30:45 +0200 Subject: [PATCH] add right-click neighborhood picking --- CgQtViewer/CGQtGLRenderWidget.cpp | 1 + CgQtViewer/CgQtGui.cpp | 26 ++-- CgSceneGraph/CgAABB.cpp | 87 ++++++++++++++ CgSceneGraph/CgAABB.h | 9 ++ CgSceneGraph/CgPointCloud.cpp | 90 ++++++++++++-- CgSceneGraph/CgPointCloud.h | 16 ++- CgSceneGraph/CgQuad.cpp | 1 - CgSceneGraph/CgQuad.h | 1 + CgSceneGraph/CgSceneControl.cpp | 189 ++++++++++++++---------------- CgSceneGraph/CgSceneControl.h | 3 +- CgShader/simple.vert | 2 +- 11 files changed, 288 insertions(+), 137 deletions(-) diff --git a/CgQtViewer/CGQtGLRenderWidget.cpp b/CgQtViewer/CGQtGLRenderWidget.cpp index 86c828b..e2e5300 100644 --- a/CgQtViewer/CGQtGLRenderWidget.cpp +++ b/CgQtViewer/CGQtGLRenderWidget.cpp @@ -290,6 +290,7 @@ void CgQtGLRenderWidget::paintGL() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_PROGRAM_POINT_SIZE); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); if(m_backface_culling) diff --git a/CgQtViewer/CgQtGui.cpp b/CgQtViewer/CgQtGui.cpp index 4cc6089..5ea3956 100644 --- a/CgQtViewer/CgQtGui.cpp +++ b/CgQtViewer/CgQtGui.cpp @@ -101,7 +101,7 @@ CgQtGui::CgQtGui(CgQtMainApplication *mw) QAction* show_pickray=settings_menu->addAction("&show pick ray", this, SLOT(slotPickRay())); show_pickray->setCheckable(true); - show_pickray->setChecked(false); + show_pickray->setChecked(true); QActionGroup* polygonmode_group = new QActionGroup(this); polygonmode_group->setExclusive(true); @@ -279,14 +279,7 @@ void CgQtGui::slotTrackballChanged() void CgQtGui::mouseEvent(QMouseEvent* event) { - // std::cout << QApplication::keyboardModifiers() << std::endl; - - // if(QApplication::keyboardModifiers().testFlag(Qt::ControlModifier)==true) - // std::cout << Cg::ControlModifier << endl; - - - if(event->type()==QEvent::MouseButtonPress) - { + if(event->type()==QEvent::MouseButtonPress) { CgBaseEvent* e = new CgMouseEvent(Cg::CgMouseButtonPress, @@ -296,8 +289,7 @@ void CgQtGui::mouseEvent(QMouseEvent* event) notifyObserver(e); } - if(event->type() == QEvent::MouseButtonRelease) - { + if(event->type() == QEvent::MouseButtonRelease) { CgBaseEvent* e = new CgMouseEvent(Cg::CgMouseButtonRelease, glm::vec2(event->localPos().x() ,event->localPos().y()), (Cg::MouseButtons)event->button()); @@ -305,8 +297,7 @@ void CgQtGui::mouseEvent(QMouseEvent* event) notifyObserver(e); } - if(event->type()==QEvent::MouseMove) - { + if(event->type()==QEvent::MouseMove) { CgBaseEvent* e= new CgMouseEvent(Cg::CgMouseMove, glm::vec2(event->localPos().x() ,event->localPos().y()), (Cg::MouseButtons)event->button()); @@ -317,21 +308,18 @@ void CgQtGui::mouseEvent(QMouseEvent* event) } -void CgQtGui::wheelEvent(QWheelEvent* event) -{ +void CgQtGui::wheelEvent(QWheelEvent* event) { CgBaseEvent* e = new CgWheelEvent(Cg::CgMouseWheel, event->angleDelta().y() / 8.0); notifyObserver(e); } -void CgQtGui::keyPressEvent(QKeyEvent *event) -{ +void CgQtGui::keyPressEvent(QKeyEvent *event) { CgBaseEvent* e= new CgKeyEvent(Cg::CgKeyPressEvent,(Cg::Key)event->key(),(Cg::KeyboardModifiers)event->nativeModifiers(),event->text().toStdString()); notifyObserver(e); } -void CgQtGui::viewportChanged(int w, int h) -{ +void CgQtGui::viewportChanged(int w, int h) { CgBaseEvent* e = new CgWindowResizeEvent(Cg::WindowResizeEvent,w,h); notifyObserver(e); } diff --git a/CgSceneGraph/CgAABB.cpp b/CgSceneGraph/CgAABB.cpp index 4d8354e..b2e3ad0 100644 --- a/CgSceneGraph/CgAABB.cpp +++ b/CgSceneGraph/CgAABB.cpp @@ -24,4 +24,91 @@ std::pair<CgAABB, CgAABB> CgAABB::split(int axis, double value) { new_extent1[axis] *= .5; new_extent2[axis] *= .5; return {CgAABB(new_position1, new_extent1), CgAABB(new_position2, new_extent2)}; +} + +// idea stolen from https://tavianator.com/2011/ray_box.html +bool CgAABB::intersectsRay(glm::vec3 origin, glm::vec3 inv_direction) { + glm::vec3 bmin = position - extent; + glm::vec3 bmax = position + extent; + + // t-val for intersection with each plane + glm::vec3 tlo = (bmin - origin) * inv_direction; + glm::vec3 thi = (bmax - origin) * inv_direction; + + // t-vals that intersect first for each dimension + glm::vec3 tmin = glm::vec3( + std::min(tlo.x, thi.x), + std::min(tlo.y, thi.y), + std::min(tlo.z, thi.z) + ); + // t-vals that intersect last for each dimension + glm::vec3 tmax = glm::vec3( + std::max(tlo.x, thi.x), + std::max(tlo.y, thi.y), + std::max(tlo.z, thi.z) + ); + + return glm::compMax(tmin) >= glm::compMin(tmax); +} + +float CgAABB::sqrDistanceToRay(glm::vec3 origin, glm::vec3 direction, glm::vec3 inv_direction) { + glm::vec3 bmin = position - extent; + glm::vec3 bmax = position + extent; + + // calculate distance along the ray for intersection with each + // of the boxes planes + float tx1 = (bmin.x - origin.y) * inv_direction.x; + float tx2 = (bmax.x - origin.y) * inv_direction.x; + float ty1 = (bmin.y - origin.y) * inv_direction.y; + float ty2 = (bmax.y - origin.y) * inv_direction.y; + float tz1 = (bmin.z - origin.z) * inv_direction.z; + float tz2 = (bmax.z - origin.z) * inv_direction.z; + + // figure out which of the planes is closest + float minX = std::min(tx1, tx2); + float maxX = std::max(tx1, tx2); + float minY = std::min(ty1, ty2); + float maxY = std::max(ty1, ty2); + float minZ = std::min(tz1, tz2); + float maxZ = std::max(tz1, tz2); + + float p1 = std::max(minX, std::max(minY, minZ)); + float p2 = std::min(maxX, std::min(maxY, maxZ)); + + // clamp in ray direction + p1 = std::max(0.0f, p1); + p2 = std::max(0.0f, p2); + + // closest point on box + float boxX = (origin.x + direction.x * p1 + origin.x + direction.x * p2) / 2; + float boxY = (origin.y + direction.y * p1 + origin.y + direction.y * p2) / 2; + float boxZ = (origin.z + direction.z * p1 + origin.z + direction.z * p2) / 2; + + boxX = std::max(std::min(boxX, bmax.x), bmin.x); + boxY = std::max(std::min(boxY, bmax.y), bmin.y); + boxZ = std::max(std::min(boxZ, bmax.z), bmin.z); + + // closest point on ray + float t = (boxX - origin.x) * direction.x + (boxY - origin.y) * direction.y + (boxZ - origin.z) * direction.z; + t = t / (direction.x * direction.x + direction.y * direction.y + direction.z * direction.z); + t = std::max(0.0f, t); + + float rayX = origin.x + direction.x * t; + float rayY = origin.y + direction.y * t; + float rayZ = origin.z + direction.z * t; + + // deltas between ray point and box point + float dx = rayX - boxX; + float dy = rayY - boxY; + float dz = rayZ - boxZ; + + // squared dist + return dx * dx + dy * dy + dz * dz; +} + +bool CgAABB::intersectsPoint(glm::vec3 point) { + return true + && (point.x <= position.x + extent.x && point.x >= position.x + extent.x) + && (point.y <= position.y + extent.y && point.y >= position.y + extent.y) + && (point.z <= position.z + extent.z && point.z >= position.z + extent.z); } \ No newline at end of file diff --git a/CgSceneGraph/CgAABB.h b/CgSceneGraph/CgAABB.h index d2026bf..7737180 100644 --- a/CgSceneGraph/CgAABB.h +++ b/CgSceneGraph/CgAABB.h @@ -2,8 +2,11 @@ #define CGAABB_H #include <utility> +#include <algorithm> #include <glm/glm.hpp> +#include <glm/gtx/component_wise.hpp> +// a class representing an axis-aligned bounding box class CgAABB { public: glm::vec3 position; @@ -12,6 +15,12 @@ public: CgAABB(glm::vec3 pos, glm::vec3 ext); // split a aabb on an axis into two aabb whose union occupies the same space std::pair<CgAABB, CgAABB> split(int axis, double value); + // ray-box collision + bool intersectsRay(glm::vec3 origin, glm::vec3 inv_direction); + // point-box collision + bool intersectsPoint(glm::vec3 point); + // return the squared distance between the box and a ray + float sqrDistanceToRay(glm::vec3 origin, glm::vec3 direction, glm::vec3 inv_direction); }; diff --git a/CgSceneGraph/CgPointCloud.cpp b/CgSceneGraph/CgPointCloud.cpp index 6e5f60d..d640829 100644 --- a/CgSceneGraph/CgPointCloud.cpp +++ b/CgSceneGraph/CgPointCloud.cpp @@ -1,11 +1,15 @@ #include "CgPointCloud.h" -CgPointCloud::CgPointCloud(): -CgPointCloud::CgPointCloud(51) -{ +// squared distance between a point and a ray +float sqrPointRayDist(glm::vec3 point, glm::vec3 origin, glm::vec3 direction) { + glm::vec3 delta = point - origin; + float t = std::max(0.0f, glm::dot(direction, delta) / glm::length2(direction)); + return glm::length2(direction * t - delta); } +CgPointCloud::CgPointCloud(): CgPointCloud::CgPointCloud(51) {} + CgPointCloud::CgPointCloud(int id): m_type(Cg::PointCloud), m_id(id) { @@ -45,8 +49,7 @@ void CgPointCloud::calculateSplatOrientations() { } -void CgPointCloud::init( std::string filename, bool cheat_normals) -{ +void CgPointCloud::init( std::string filename, bool cheat_normals) { m_vertices.clear(); m_vertex_normals.clear(); m_vertex_colors.clear(); @@ -82,10 +85,7 @@ void CgPointCloud::init( std::string filename, bool cheat_normals) // "fast" if k is relatively small, if k is on the order // of m_vertices.size(), this is slower than brute force. std::vector<unsigned int> neighbors = getNearestNeighborsFast(0, k); - - for(unsigned int i = 0;i < k; i++) { - m_vertex_colors[neighbors[i]] = glm::vec3(0.0,0.0,1.0); - } + setColors(neighbors, glm::vec3(0.0, 0.0, .75)); } void CgPointCloud::buildKdTree(glm::vec3* begin, glm::vec3* end, int depth) { @@ -199,7 +199,7 @@ std::vector<unsigned int> CgPointCloud::getNearestNeighborsFast(unsigned int cur glm::vec3 curr_point = *(begin + half_size); // insert current point into set - set.insert({glm::distance(query, curr_point), begin + half_size - first}); + set.insert({glm::distance2(query, curr_point), begin + half_size - first}); // make sure our set only contains k elements at most while(set.size() > k) set.erase(std::prev(set.end())); @@ -236,6 +236,71 @@ std::vector<unsigned int> CgPointCloud::getNearestNeighborsFast(unsigned int cur return erg; } +int CgPointCloud::getClosestPointToRay(glm::vec3 origin, glm::vec3 direction) { + if(m_vertices.size() == 0) return -1; + + glm::vec3 inv_direction = glm::vec3(1.0 / direction.x, 1.0 / direction.y, 1.0 / direction.z); + glm::vec3* first = &m_vertices.front(); + glm::vec3* last = &(*(m_vertices.end() - 1)); + // sensible starting point + float erg_sqr_dist = std::numeric_limits<float>::infinity(); + int erg = -1; + + // stack of traversed nodes (start index, end index, aabb, depth) + std::vector<std::tuple<glm::vec3*, glm::vec3*, CgAABB, unsigned int>> nodes; + nodes.push_back({first, last, m_aabb, 0}); + + // traverse the tree as long as there's something to do. + while(!nodes.empty()) { + // unpack current node & pop it + glm::vec3* begin; + glm::vec3* end; + CgAABB aabb; + unsigned int depth; + std::tie(begin, end, aabb, depth) = nodes.back(); + auto half_size = (end - begin) / 2; + nodes.pop_back(); + + glm::vec3 curr_point = *(begin + half_size); + // insert current point into set if it's closer to ray than last one + float cand_dist = sqrPointRayDist(curr_point, origin, direction); + if(cand_dist < erg_sqr_dist) { + erg_sqr_dist = cand_dist; + erg = begin + half_size - first; + } + + // the aabb of the sub-nodes + unsigned int axis = depth % 3; + CgAABB lower_aabb; + CgAABB higher_aabb; + std::tie(lower_aabb, higher_aabb) = aabb.split(axis, curr_point[axis]); + // only push children if their aabb is closer to ray than + // the closest point we found until now and there are + // points in them + if ( + begin != begin + half_size + && lower_aabb.sqrDistanceToRay(origin, direction, inv_direction) < erg_sqr_dist + ) { + nodes.push_back({begin, begin + half_size, lower_aabb, depth + 1}); + } + if ( + end != begin + half_size + && higher_aabb.sqrDistanceToRay(origin, direction, inv_direction) < erg_sqr_dist + ) { + nodes.push_back({begin + half_size + 1, end, higher_aabb, depth + 1}); + } + } + + return erg; +} + +void CgPointCloud::setColors(std::vector<unsigned int> indices, glm::vec3 color) { + for(unsigned int i = 0; i < indices.size(); i++) m_vertex_colors[indices[i]] = color; +} + +void CgPointCloud::resetColors(glm::vec3 color) { + for(unsigned int i = 0; i < m_vertices.size(); i++) m_vertex_colors[i] = color; +} // calculates an arbitrary verctor perpendicular to the given one glm::vec3 CgPointCloud::getPerpendicularVector(glm::vec3 arg) { @@ -285,7 +350,6 @@ const CgAABB CgPointCloud::getAABB() const { return m_aabb; } -const std::vector<glm::vec2>& CgPointCloud::getSplatScalings() const -{ +const std::vector<glm::vec2>& CgPointCloud::getSplatScalings() const { return m_splat_scaling; -} +} \ No newline at end of file diff --git a/CgSceneGraph/CgPointCloud.h b/CgSceneGraph/CgPointCloud.h index 251ec4f..80938b8 100644 --- a/CgSceneGraph/CgPointCloud.h +++ b/CgSceneGraph/CgPointCloud.h @@ -17,6 +17,7 @@ #include "CgBase/CgEnums.h" #include "CgUtils/ObjLoader.h" #include <glm/glm.hpp> +#include <glm/gtx/norm.hpp> #include <glm/gtc/matrix_transform.hpp> class CgPointCloud : public CgBasePointCloud { @@ -53,6 +54,17 @@ public: // read a dataset from file, can cheat the normals, i.e read the mormals from file void init( std::string filename, bool cheat_normals=false); + // nearest-neighbour search in the point cloud + std::vector<unsigned int> getNearestNeighborsSlow(unsigned int current_point, unsigned int k); + std::vector<unsigned int> getNearestNeighborsFast(unsigned int current_point, unsigned int k); + + // get the point that's closest to the ray + int getClosestPointToRay(glm::vec3 origin, glm::vec3 direction); + + // change colors of a list of points + void setColors(std::vector<unsigned int> indices, glm::vec3 color); + void resetColors(glm::vec3 color); + // the center of gravity of the object, for rendering const glm::vec3 getCenter() const; @@ -73,10 +85,6 @@ private: // for demonstration: for a given normal direction find an arbitrary vector to span the tangent plane glm::vec3 getPerpendicularVector(glm::vec3 arg); - // for demonstration purposes, very inefficient - std::vector<unsigned int> getNearestNeighborsSlow(unsigned int current_point, unsigned int k); - std::vector<unsigned int> getNearestNeighborsFast(unsigned int current_point, unsigned int k); - // rearrange the vec3 between begin and end so they form a kd-tree void buildKdTree(glm::vec3* begin, glm::vec3* end, int depth); diff --git a/CgSceneGraph/CgQuad.cpp b/CgSceneGraph/CgQuad.cpp index 575c4c4..54f74d9 100644 --- a/CgSceneGraph/CgQuad.cpp +++ b/CgSceneGraph/CgQuad.cpp @@ -1,5 +1,4 @@ #include "CgQuad.h" -#include "CgBase/CgEnums.h" CgQuad::CgQuad(): m_type(Cg::Polyline), diff --git a/CgSceneGraph/CgQuad.h b/CgSceneGraph/CgQuad.h index 25f3179..a3daaf5 100644 --- a/CgSceneGraph/CgQuad.h +++ b/CgSceneGraph/CgQuad.h @@ -5,6 +5,7 @@ #include <glm/glm.hpp> #include <string> #include "CgBase/CgBasePolyline.h" +#include "CgBase/CgEnums.h" // four vertices arranged in a rectangle, //rendered as a wireframe diff --git a/CgSceneGraph/CgSceneControl.cpp b/CgSceneGraph/CgSceneControl.cpp index a27161f..e4ae4fb 100644 --- a/CgSceneGraph/CgSceneControl.cpp +++ b/CgSceneGraph/CgSceneControl.cpp @@ -29,24 +29,36 @@ using namespace Eigen; CgSceneControl::CgSceneControl() { - m_pointcloud=nullptr; + m_pointcloud = nullptr; resetTransform(); - m_lookAt_matrix= glm::lookAt(glm::vec3(0.0,0.0,1.0),glm::vec3(0.0,0.0,0.0),glm::vec3(0.0,1.0,0.0)); - m_proj_matrix= glm::mat4x4(glm::vec4(1.792591, 0.0, 0.0, 0.0), glm::vec4(0.0, 1.792591, 0.0, 0.0), glm::vec4(0.0, 0.0, -1.0002, -1.0), glm::vec4(0.0, 0.0, -0.020002, 0.0)); - m_select_ray=NULL; + m_lookAt_matrix= glm::lookAt( + glm::vec3(0.0,0.0,1.0), + glm::vec3(0.0,0.0,0.0), + glm::vec3(0.0,1.0,0.0) + ); + + m_proj_matrix= glm::mat4x4( + glm::vec4(1.792591, 0.0, 0.0, 0.0), + glm::vec4(0.0, 1.792591, 0.0, 0.0), + glm::vec4(0.0, 0.0, -1.0002, -1.0), + glm::vec4(0.0, 0.0, -0.020002, 0.0) + ); + + m_select_ray = nullptr; m_disc = new CgTriangleMesh(78); - m_pointcloud = NULL; - m_center=glm::vec3(0.); - m_triangle_mesh= NULL; - m_show_splats=false; - m_show_pickray=false; - m_is_dragging=false; - m_drag_center=glm::vec2(0.0,0.0); + m_pointcloud = nullptr; + m_center = glm::vec3(0.); + m_triangle_mesh= nullptr; + m_show_splats = false; + m_show_pickray = true; + m_is_dragging = false; + m_drag_center = glm::vec2(0.0,0.0); } void CgSceneControl::resetTransform() { m_current_translation = glm::mat4(1.0); + m_current_translation = glm::translate(m_current_translation, glm::vec3(0.0, 0.0, -2.0)); m_current_scale = glm::mat4(1.0); m_current_rotation = glm::mat4(1.0); m_current_transformation = glm::mat4(1.0); @@ -66,41 +78,34 @@ CgSceneControl::~CgSceneControl() m_kd_tree_mesh.clear(); } - - -void CgSceneControl::calculatePickRay(double x, double y) -{ - double w = (double) m_renderer->getViewportWidth(); - double h = (double) m_renderer->getViewportHeight(); +void CgSceneControl::calculatePickRay(float x, float y) { + float w = (float) m_renderer->getViewportWidth(); + float h = (float) m_renderer->getViewportHeight(); // normalize into [-1;1] - x=2.0*x / w -1.0; - if (x<-1.0) x=-1.0; - if (x>1.0) x=1.0; - - y=2.0*y / h -1.0; - if (y<-1.0) y=-1.0; - if (y>1.0) y=1.0; + x = std::max(-1.0f, std::min(1.0f, 2.0f * x / w - 1.0f)); + y = std::max(-1.0f, std::min(1.0f, 2.0f * y / h - 1.0f)); // change to right handed coordinate system - y=-y; + y = -y; - glm::mat4 inverse_proj=glm::inverse(m_proj_matrix); + glm::mat4 inverse_proj = glm::inverse(m_proj_matrix); //unproject point on front clipping plane - glm::vec4 p(x,y,-0.01,1); - glm::vec4 q= inverse_proj*p; - q/= q.w; + glm::vec4 p(x, y, -0.01, 1); + glm::vec4 q = inverse_proj * p; + q /= q.w; //unproject point on back clipping plane - glm::vec4 r(x,y,1.0,1); - glm::vec4 s= inverse_proj*r; - s/= s.w; + glm::vec4 r(x, y, 1.0, 1); + glm::vec4 s = inverse_proj * r; + s /= s.w; //construct current modelview matrix by hand, since there is no scenegraph - m_current_transformation = glm::translate(m_current_transformation,-m_center); - glm::mat4 mv_matrix = m_lookAt_matrix * m_current_rotation* m_current_transformation ; - m_current_transformation = glm::translate(m_current_transformation,m_center); + m_current_transformation = m_current_scale * m_current_translation * m_current_rotation; + m_current_transformation = glm::translate(m_current_transformation, -m_center); + glm::mat4 mv_matrix = m_lookAt_matrix * m_current_transformation; + m_current_transformation = glm::translate(m_current_transformation, m_center); // convert pick ray into local "bunny coordinates" @@ -109,15 +114,9 @@ void CgSceneControl::calculatePickRay(double x, double y) glm::vec4 rayend = mv_matrix_inv * s; // init new CgPolyline to draw the pick ray - if(m_select_ray!=NULL) - delete m_select_ray; - std::vector<glm::vec3> pointlist; - pointlist.push_back(raystart); - pointlist.push_back(rayend); - m_select_ray = new CgPolyLine(33,pointlist); + if(m_select_ray != nullptr) delete m_select_ray; + m_select_ray = new CgPolyLine(33, {raystart, rayend}); m_renderer->init(m_select_ray); - - m_renderer->redraw(); } @@ -223,10 +222,23 @@ void CgSceneControl::handleEvent(CgBaseEvent* e) if(e->getType() & Cg::CgMouseButtonPress) { CgMouseEvent* ev = (CgMouseEvent*)e; - if(ev->button()== Cg::RightButton) - calculatePickRay((double)ev->x(),(double)ev->y()); - else if(ev->button() == Cg::MiddleButton) - { + if(ev->button()== Cg::RightButton) { + calculatePickRay((double)ev->x(),(double)ev->y()); + if(m_pointcloud != nullptr) { + std::vector<glm::vec3> points = m_select_ray->getVertices(); + glm::vec3 start = points[0]; + glm::vec3 direction = points[1] - start; + int picked_index = m_pointcloud->getClosestPointToRay(start, direction); + if(picked_index != -1) { // -1 => point found + std::vector<unsigned int> neighbors = m_pointcloud->getNearestNeighborsFast(picked_index, 50); + m_pointcloud->resetColors(glm::vec3(0.0, 0.75, 0.0)); + m_pointcloud->setColors(neighbors, glm::vec3(0.75, 0.0, 0.0)); + m_pointcloud->setColors({picked_index}, glm::vec3(1.0, 1.0, 0.0)); + m_renderer->init(m_pointcloud); + m_renderer->redraw(); + } + } + } else if(ev->button() == Cg::MiddleButton) { m_drag_center = glm::vec2((double)ev->x(), (double)ev->y()); m_is_dragging = true; } @@ -282,20 +294,17 @@ void CgSceneControl::handleEvent(CgBaseEvent* e) { CgKeyEvent* ev = (CgKeyEvent*)e; - if(ev->text()=="e") - { - // example usage of eigen library to compute the eigen-decomposition of a matrix - calculateEigenDecomposition3x3(); + if(ev->text()=="e") { + // example usage of eigen library to compute the eigen-decomposition of a matrix + calculateEigenDecomposition3x3(); } - if(ev->text()=="s") - { + if(ev->text()=="s") { // example usage of eigen library to compute the eigen-decomposition of a matrix calculateSingularValueDecomposition(); } - if(ev->text() == "c") - { + if(ev->text() == "c") { resetTransform(); m_renderer->redraw(); } @@ -424,62 +433,47 @@ void CgSceneControl::handleEvent(CgBaseEvent* e) // rendering stuff /*******************************************************************************************************/ -void CgSceneControl::setRenderer(CgBaseRenderer* r) -{ - m_renderer=r; +void CgSceneControl::setRenderer(CgBaseRenderer* r) { + m_renderer = r; m_renderer->setSceneControl(this); - if(m_pointcloud!=NULL) - m_renderer->init(m_pointcloud); - - if(m_disc!=NULL) - m_renderer->init(m_disc); - - if(m_select_ray!=NULL) - m_renderer->init(m_select_ray); - - if(m_triangle_mesh!=NULL) - m_renderer->init(m_triangle_mesh); + if(m_pointcloud != nullptr) m_renderer->init(m_pointcloud); + if(m_disc != nullptr) m_renderer->init(m_disc); + if(m_select_ray != nullptr) m_renderer->init(m_select_ray); + if(m_triangle_mesh != nullptr) m_renderer->init(m_triangle_mesh); } -void CgSceneControl::renderObjects() -{ +void CgSceneControl::renderObjects() { // Materialeigenschaften setzen - - - m_renderer->setUniformValue("mycolor",glm::vec4(0.0,1.0,0.0,1.0)); - - m_renderer->setUniformValue("matDiffuseColor",glm::vec4(0.780392f, 0.568627f, 0.113725f, 1.0f )); - m_renderer->setUniformValue("lightDiffuseColor",glm::vec4(1.0,1.0,1.0,1.0)); - - m_renderer->setUniformValue("matAmbientColor",glm::vec4(0.329412f, 0.223529f, 0.027451f,1.0f )); - m_renderer->setUniformValue("lightAmbientColor",glm::vec4(1.0,1.0,1.0,1.0)); - - m_renderer->setUniformValue("matSpecularColor",glm::vec4(0.992157f, 0.941176f, 0.807843f, 1.0f)); - m_renderer->setUniformValue("lightSpecularColor",glm::vec4(1.0,1.0,1.0,1.0)); - - m_renderer->setUniformValue("shininess",27.8974f); - - m_current_transformation = m_current_scale * m_current_translation * m_current_rotation ; - - if(m_triangle_mesh!=NULL) { - m_current_transformation = glm::translate(m_current_transformation,-m_center); + m_renderer->setUniformValue("mycolor", glm::vec4(0.0,1.0,0.0,1.0)); + m_renderer->setUniformValue("matDiffuseColor", glm::vec4(0.780392f, 0.568627f, 0.113725f, 1.0f )); + m_renderer->setUniformValue("lightDiffuseColor", glm::vec4(1.0,1.0,1.0,1.0)); + m_renderer->setUniformValue("matAmbientColor", glm::vec4(0.329412f, 0.223529f, 0.027451f,1.0f )); + m_renderer->setUniformValue("lightAmbientColor", glm::vec4(1.0,1.0,1.0,1.0)); + m_renderer->setUniformValue("matSpecularColor", glm::vec4(0.992157f, 0.941176f, 0.807843f, 1.0f)); + m_renderer->setUniformValue("lightSpecularColor", glm::vec4(1.0,1.0,1.0,1.0)); + m_renderer->setUniformValue("shininess", 27.8974f); + + m_current_transformation = m_current_scale * m_current_translation * m_current_rotation; + + if(m_triangle_mesh != nullptr) { + m_current_transformation = glm::translate(m_current_transformation, -m_center); glm::mat4 mv_matrix = m_lookAt_matrix * m_current_transformation ; m_renderer->render(m_triangle_mesh, mv_matrix, m_proj_matrix); - m_current_transformation = glm::translate(m_current_transformation,m_center); + m_current_transformation = glm::translate(m_current_transformation, m_center); } - if((m_pointcloud!=NULL)&&(!m_show_splats)) { + if((m_pointcloud != nullptr)&& !m_show_splats) { m_current_transformation = glm::translate(m_current_transformation,-m_center); - glm::mat4 mv_matrix = m_lookAt_matrix * m_current_transformation ; + glm::mat4 mv_matrix = m_lookAt_matrix * m_current_transformation; m_renderer->render(m_pointcloud, mv_matrix, m_proj_matrix); m_current_transformation = glm::translate(m_current_transformation,m_center); } - if((m_select_ray!=NULL)&&(m_show_pickray)) { - m_current_transformation = glm::translate(m_current_transformation,-m_center); + if((m_select_ray != nullptr) && m_show_pickray) { + m_current_transformation = glm::translate(m_current_transformation, -m_center); glm::mat4 mv_matrix = m_lookAt_matrix * m_current_transformation; m_renderer->render(m_select_ray, mv_matrix, m_proj_matrix); m_current_transformation = glm::translate(m_current_transformation, m_center); @@ -496,7 +490,7 @@ void CgSceneControl::renderObjects() // you would never ever render splats like this, a splat is never a scenegraph object // just to have not much effort to show the shape, inefficient rendering! - if((m_pointcloud!=NULL)&&(m_show_splats)) { + if((m_pointcloud != nullptr) && m_show_splats) { m_renderer->setUniformValue("rendersplats",1); @@ -518,8 +512,7 @@ void CgSceneControl::renderObjects() mv_matrix = m_lookAt_matrix * m_current_rotation* m_current_transformation ; - if(m_disc!=NULL) - m_renderer->render(m_disc,mv_matrix,m_proj_matrix); + if(m_disc != nullptr) m_renderer->render(m_disc,mv_matrix,m_proj_matrix); m_current_transformation=glm::scale(m_current_transformation,glm::vec3(1.0/scalings[splat_indices[i]][0],1.0/scalings[splat_indices[i]][1],1.0)); diff --git a/CgSceneGraph/CgSceneControl.h b/CgSceneGraph/CgSceneControl.h index 2b6c36a..d919d4b 100644 --- a/CgSceneGraph/CgSceneControl.h +++ b/CgSceneGraph/CgSceneControl.h @@ -8,6 +8,7 @@ #include <vector> #include <queue> #include <iostream> +#include <numeric> class CgBaseEvent; class CgBaseRenderer; @@ -30,7 +31,7 @@ public: private: // since there is only one object, the select ray is in "bunny"-coordinates - void calculatePickRay(double x, double y); + void calculatePickRay(float x, float y); void resetTransform(); bool m_show_pickray; bool m_is_dragging; diff --git a/CgShader/simple.vert b/CgShader/simple.vert index ae48699..463e0fa 100644 --- a/CgShader/simple.vert +++ b/CgShader/simple.vert @@ -21,7 +21,7 @@ varying vec3 viewEye,lightEye, normalEye; void main() { vert = vertex.xyz; - + gl_PointSize = 3; vec4 vert4=vec4(vertex,1.0); col=color.xyz; -- GitLab