diff --git a/avogadro/rendering/CMakeLists.txt b/avogadro/rendering/CMakeLists.txt index 02533642f0..ddebfe8483 100644 --- a/avogadro/rendering/CMakeLists.txt +++ b/avogadro/rendering/CMakeLists.txt @@ -95,10 +95,6 @@ target_sources(Rendering PRIVATE ambientocclusionspheregeometry.cpp ) -if(USE_3DCONNEXION AND (WIN32 OR APPLE)) - target_sources(Rendering PRIVATE tdxextensions.cpp) -endif() - set(shader_files "arrow_vs.glsl" "cylinders_fs.glsl" diff --git a/avogadro/rendering/camera.cpp b/avogadro/rendering/camera.cpp index 6970e74760..528a238af0 100644 --- a/avogadro/rendering/camera.cpp +++ b/avogadro/rendering/camera.cpp @@ -132,7 +132,7 @@ Vector3f Camera::unProject(const Vector2f& point, } void Camera::calculatePerspective(float fieldOfView, float aspectRatio, - float zNear, float zFar) + float zNear, float zFar) { m_data->projection.setIdentity(); float f = 1.0f / std::tan(fieldOfView * float(M_PI) / 360.0f); @@ -152,7 +152,7 @@ void Camera::calculatePerspective(float fieldOfView, float zNear, float zFar) } void Camera::calculateOrthographic(float left, float right, float bottom, - float top, float zNear, float zFar) + float top, float zNear, float zFar) { left *= m_orthographicScale; right *= m_orthographicScale; @@ -184,4 +184,20 @@ void Camera::setModelView(const Eigen::Affine3f& transform) m_data->modelView = transform; } +void Camera::calculatePerspective(float left, float right, + float bottom, float top, + float zNear, float zFar) +{ + m_data->projection.setIdentity(); + + m_data->projection(0, 0) = (2.0f * zNear) / (right - left); + m_data->projection(1, 1) = (2.0f * zNear) / (top - bottom); + m_data->projection(0, 2) = (right + left) / (right - left); + m_data->projection(1, 2) = (top + bottom) / (top - bottom); + m_data->projection(2, 2) = -(zFar + zNear) / (zFar - zNear); + m_data->projection(3, 2) = -1.0f; + m_data->projection(2, 3) = -(2.0f * zFar * zNear) / (zFar - zNear); + m_data->projection(3, 3) = 0.0f; +} + } // namespace Avogadro diff --git a/avogadro/rendering/camera.h b/avogadro/rendering/camera.h index d5072c8763..2a584f5520 100644 --- a/avogadro/rendering/camera.h +++ b/avogadro/rendering/camera.h @@ -100,7 +100,7 @@ class AVOGADRORENDERING_EXPORT Camera * reference point (defaults to the origin if nothing is supplied). */ Vector3f unProject(const Vector2f& point, - const Vector3f& reference = Vector3f::Zero()) const; + const Vector3f& reference = Vector3f::Zero()) const; /** * Calculate the perspective projection matrix. @@ -110,7 +110,7 @@ class AVOGADRORENDERING_EXPORT Camera * @param zFar is the distance from the viewer to the far clipping plane. */ void calculatePerspective(float fieldOfView, float aspectRatio, float zNear, - float zFar); + float zFar); /** * Calculate the perspective projection matrix. Computes the aspect ratio @@ -120,7 +120,7 @@ class AVOGADRORENDERING_EXPORT Camera * @param zFar is the distance from the viewer to the far clipping plane. */ void calculatePerspective(float fieldOfView, float zNear, float zFar); -#ifdef _3DCONNEXION + /** * << API Extension for TDX >> * Calculate the perspective projection matrix using frustum planes @@ -134,7 +134,7 @@ class AVOGADRORENDERING_EXPORT Camera */ void calculatePerspective(float left, float right, float bottom, float top, float zNear, float zFar); -#endif + /** * Calculate the orthographic projection matrix. * @param left left vertical clipping plane. @@ -145,7 +145,7 @@ class AVOGADRORENDERING_EXPORT Camera * @param zFar distance to the far clipping plane. */ void calculateOrthographic(float left, float right, float bottom, float top, - float zNear, float zFar); + float zNear, float zFar); /** * Set the dimensions of the viewport in pixels. diff --git a/avogadro/rendering/geometryvisitor.cpp b/avogadro/rendering/geometryvisitor.cpp index bf471f9b21..d9c0a69686 100644 --- a/avogadro/rendering/geometryvisitor.cpp +++ b/avogadro/rendering/geometryvisitor.cpp @@ -9,9 +9,6 @@ #include "curvegeometry.h" #include "linestripgeometry.h" #include "spheregeometry.h" -#ifdef _3DCONNEXION -#include "cylindergeometry.h" -#endif namespace Avogadro::Rendering { @@ -30,9 +27,6 @@ void GeometryVisitor::visit(Drawable&) void GeometryVisitor::visit(SphereGeometry& geometry) { -#ifdef _3DCONNEXION - m_sphereGeometries.push_back(geometry); -#endif const Core::Array& spheres = geometry.spheres(); if (!spheres.size()) return; @@ -53,9 +47,7 @@ void GeometryVisitor::visit(SphereGeometry& geometry) float distance = (it->center - tmpCenter).squaredNorm(); if (distance > tmpRadius) tmpRadius = distance; -#ifdef _3DCONNEXION m_spheres.push_back(*it); -#endif } } tmpRadius = std::sqrt(tmpRadius); @@ -154,11 +146,7 @@ void GeometryVisitor::clear() m_dirty = false; m_centers.clear(); m_radii.clear(); -#ifdef _3DCONNEXION m_spheres.clear(); - m_sphereGeometries.clear(); - m_cylinderGeometries.clear(); -#endif } Vector3f GeometryVisitor::center() @@ -201,4 +189,55 @@ void GeometryVisitor::average() } } +void GeometryVisitor::boundingBox(double& minX, double& minY, double& minZ, + double& maxX, double& maxY, double& maxZ, + const std::vector& flags) const +{ + minX = std::numeric_limits::max(); + minY = minX; + minZ = minX; + maxX = -minX; + maxY = maxX; + maxZ = maxX; + + bool noSelection = true; + + for (uint32_t i = 0; i < flags.size(); i++) { + if (flags[i]) { + noSelection = false; + break; + } + } + + for (uint32_t i = 0; i < m_spheres.size(); i++) { + if (flags.empty() || noSelection || flags[i]) { + float radius = m_spheres[i].radius + 0.5f; + double bufferMinX = m_spheres[i].center.x() - radius; + double bufferMinY = m_spheres[i].center.y() - radius; + double bufferMinZ = m_spheres[i].center.z() - radius; + double bufferMaxX = m_spheres[i].center.x() + radius; + double bufferMaxY = m_spheres[i].center.y() + radius; + double bufferMaxZ = m_spheres[i].center.z() + radius; + + if (bufferMinX < minX) + minX = bufferMinX; + + if (bufferMinY < minY) + minY = bufferMinY; + + if (bufferMinZ < minZ) + minZ = bufferMinZ; + + if (bufferMaxX > maxX) + maxX = bufferMaxX; + + if (bufferMaxY > maxY) + maxY = bufferMaxY; + + if (bufferMaxZ > maxZ) + maxZ = bufferMaxZ; + } + } +} + } // End namespace Avogadro diff --git a/avogadro/rendering/geometryvisitor.h b/avogadro/rendering/geometryvisitor.h index 5b15df449c..c07730ae5a 100644 --- a/avogadro/rendering/geometryvisitor.h +++ b/avogadro/rendering/geometryvisitor.h @@ -25,11 +25,7 @@ namespace Rendering { * notably the center and radius of the bounding sphere. */ -#ifdef _3DCONNEXION struct SphereColor; -class SphereGeometry; -class CylinderGeometry; -#endif class GeometryVisitor : public Visitor { @@ -47,11 +43,7 @@ class GeometryVisitor : public Visitor void visit(SphereGeometry&) override; void visit(AmbientOcclusionSphereGeometry&) override; void visit(CurveGeometry&) override; -#ifdef _3DCONNEXION - void visit(CylinderGeometry&) override; -#else void visit(CylinderGeometry&) override { return; } -#endif void visit(MeshGeometry&) override { return; } void visit(TextLabel2D&) override { return; } void visit(TextLabel3D&) override { return; } @@ -71,7 +63,7 @@ class GeometryVisitor : public Visitor * Get the radius of the scene. */ float radius(); -#ifdef _3DCONNEXION + /** * <> * Calculates the bounding box of the molecule. @@ -88,17 +80,6 @@ class GeometryVisitor : public Visitor double& maxY, double& maxZ, const std::vector& flags) const; - /** - * <> - * Hit-tests underlying geometry. - * @param rayOrigin Origin of the ray. - * @param rayDirection Normalized direction of the ray. - * @return Distance to the intersection point lying on the passed ray. - * If returned value is less than zero, then there is no intersection. - */ - float hit(const Vector3f& rayOrigin, const Vector3f& rayDirection, - const float rayLength); -#endif private: /** * Get the average of the accumulated spherical centers and minimal radius. @@ -111,11 +92,7 @@ class GeometryVisitor : public Visitor std::vector m_centers; std::vector m_radii; -#ifdef _3DCONNEXION std::vector m_spheres; - std::vector m_sphereGeometries; - std::vector m_cylinderGeometries; -#endif }; } // End namespace Rendering diff --git a/avogadro/rendering/glrenderer.cpp b/avogadro/rendering/glrenderer.cpp index 8e94b1cb7b..e2a13f366e 100644 --- a/avogadro/rendering/glrenderer.cpp +++ b/avogadro/rendering/glrenderer.cpp @@ -34,7 +34,7 @@ GLRenderer::GLRenderer() #endif { m_overlayCamera.setIdentity(); -#ifdef _3DCONNEXION + float aspectRatio = static_cast(m_camera.width()) / static_cast(m_camera.height()); float distance = m_camera.distance(m_center); @@ -45,7 +45,7 @@ GLRenderer::GLRenderer() m_orthographicFrustum = { -5.0f * aspectRatio, 5.0f * aspectRatio, -5.0f, 5.0f, -offset, offset }; -#endif + } GLRenderer::~GLRenderer() @@ -204,12 +204,9 @@ void GLRenderer::setTextRenderStrategy(TextRenderStrategy* tren) void GLRenderer::applyProjection() { float distance = m_camera.distance(m_center); -#ifdef _3DCONNEXION float aspectRatio = static_cast(m_camera.width()) / static_cast(m_camera.height()); -#endif if (m_camera.projectionType() == Perspective) { -#ifdef _3DCONNEXION m_perspectiveFrustum[0] = m_perspectiveFrustum[2] * aspectRatio; m_perspectiveFrustum[1] = m_perspectiveFrustum[3] * aspectRatio; m_perspectiveFrustum[5] = distance + m_radius; @@ -217,13 +214,8 @@ void GLRenderer::applyProjection() m_perspectiveFrustum[0], m_perspectiveFrustum[1], m_perspectiveFrustum[2], m_perspectiveFrustum[3], m_perspectiveFrustum[4], m_perspectiveFrustum[5]); -#else - m_camera.calculatePerspective(40.0f, std::max(2.0f, distance - m_radius), - distance + m_radius); -#endif } else { // Renders the orthographic projection of the molecule -#ifdef _3DCONNEXION m_orthographicFrustum[0] = m_orthographicFrustum[2] * aspectRatio; m_orthographicFrustum[1] = m_orthographicFrustum[3] * aspectRatio; m_orthographicFrustum[5] = distance + m_radius; @@ -234,13 +226,6 @@ void GLRenderer::applyProjection() m_orthographicFrustum[3], // T m_orthographicFrustum[4], // N m_orthographicFrustum[5]); // F -#else - const double halfHeight = m_radius; - const double halfWidth = halfHeight * m_camera.width() / m_camera.height(); - m_camera.calculateOrthographic( - -halfWidth, halfWidth, -halfHeight, halfHeight, - std::max(2.0f, distance - m_radius), distance + m_radius); -#endif } m_overlayCamera.calculateOrthographic( 0.f, static_cast(m_overlayCamera.width()), 0.f, @@ -320,6 +305,17 @@ Array GLRenderer::hits(const GroupNode* group, return result; } +float GLRenderer::hit(const Vector3f& rayOrigin, + const Vector3f& rayEnd, + const Vector3f& rayDirection) const +{ + std::multimap results = + hits(&m_scene.rootNode(), rayOrigin, rayEnd, rayDirection); + if (results.size()) + return results.begin()->first; + return std::numeric_limits::max(); +} + Array GLRenderer::hits(int x1, int y1, int x2, int y2) const { // Figure out where the corners of our rectangle are. diff --git a/avogadro/rendering/glrenderer.h b/avogadro/rendering/glrenderer.h index 34136bca17..0e3a59e925 100644 --- a/avogadro/rendering/glrenderer.h +++ b/avogadro/rendering/glrenderer.h @@ -68,6 +68,12 @@ class AVOGADRORENDERING_EXPORT GLRenderer */ Identifier hit(int x, int y) const; + /** Return the depth of provided ray - geometry hit test. + */ + float hit(const Vector3f& rayOrigin, + const Vector3f& rayEnd, + const Vector3f& rayDirection) const; + /** Return the primitives in the rectangular area provided. */ Core::Array hits(int x1, int y1, int x2, int y2) const; @@ -104,9 +110,9 @@ class AVOGADRORENDERING_EXPORT GLRenderer void setTextRenderStrategy(TextRenderStrategy* tren); /** @} */ -#ifdef _3DCONNEXION std::array m_perspectiveFrustum; // L, R, B, T, N, F (planes order) std::array m_orthographicFrustum; // L, R, B, T, N, F (planes order) +#ifdef _3DCONNEXION bool m_drawIcon; void* m_iconData; uint32_t m_iconWidth; diff --git a/avogadro/rendering/scene.cpp b/avogadro/rendering/scene.cpp index edc3e1b1ce..1e6c158e1b 100644 --- a/avogadro/rendering/scene.cpp +++ b/avogadro/rendering/scene.cpp @@ -53,4 +53,14 @@ void Scene::clear() m_dirty = true; } +void Scene::getBoundingBox(double& minX, double& minY, double& minZ, + double& maxX, double& maxY, double& maxZ, + const std::vector& flags) +{ + GeometryVisitor visitor; + + m_rootNode.accept(visitor); + visitor.boundingBox(minX, minY, minZ, maxX, maxY, maxZ, flags); +} + } // End Avogadro namespace diff --git a/avogadro/rendering/scene.h b/avogadro/rendering/scene.h index aa72e7e722..e29c250b44 100644 --- a/avogadro/rendering/scene.h +++ b/avogadro/rendering/scene.h @@ -130,7 +130,7 @@ class AVOGADRORENDERING_EXPORT Scene /** Clear the scene of all elements. */ void clear(); -#ifdef _3DCONNEXION + /** * <> * Calculte and return bounding box of the scene objects. @@ -147,18 +147,6 @@ class AVOGADRORENDERING_EXPORT Scene double& maxY, double& maxZ, const std::vector& flags); - /** <> - * Return distance from ray origin to the ray with scene content instersection - * point. - * @param rayOrigin Origin of the ray. - * @param rayEnd End point of the ray. - * @param rayDirection Normalized direction of the ray. - * @return Distance to the intersection point lying on the passed ray. If - * returned value is less than zero, then there is no intersection. - */ - float getHitDistance(const Vector3f& rayOrigin, const Vector3f& rayDirection, - const float rayLength); -#endif private: GroupNode m_rootNode; Vector4ub m_backgroundColor; diff --git a/avogadro/rendering/tdxextensions.cpp b/avogadro/rendering/tdxextensions.cpp deleted file mode 100644 index f8568dafde..0000000000 --- a/avogadro/rendering/tdxextensions.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/****************************************************************************** - This source file is part of the Avogadro project. - This source code is released under the 3-Clause BSD License, (see "LICENSE"). -******************************************************************************/ - -#include "camera.h" -#include "cylindergeometry.h" -#include "geometryvisitor.h" -#include "scene.h" -#include "spheregeometry.h" - -void Avogadro::Rendering::Camera::calculatePerspective(float left, float right, - float bottom, float top, - float zNear, float zFar) -{ - m_data->projection.setIdentity(); - - m_data->projection(0, 0) = (2.0f * zNear) / (right - left); - m_data->projection(1, 1) = (2.0f * zNear) / (top - bottom); - m_data->projection(0, 2) = (right + left) / (right - left); - m_data->projection(1, 2) = (top + bottom) / (top - bottom); - m_data->projection(2, 2) = -(zFar + zNear) / (zFar - zNear); - m_data->projection(3, 2) = -1.0f; - m_data->projection(2, 3) = -(2.0f * zFar * zNear) / (zFar - zNear); - m_data->projection(3, 3) = 0.0f; -} - -void Avogadro::Rendering::Scene::getBoundingBox(double& minX, double& minY, - double& minZ, double& maxX, - double& maxY, double& maxZ, - const std::vector& flags) -{ - GeometryVisitor visitor; - - m_rootNode.accept(visitor); - visitor.boundingBox(minX, minY, minZ, maxX, maxY, maxZ, flags); -} - -float Avogadro::Rendering::Scene::getHitDistance(const Vector3f& rayOrigin, - const Vector3f& rayDirection, - const float rayLength) -{ - GeometryVisitor visitor; - - m_rootNode.accept(visitor); - return visitor.hit(rayOrigin, rayDirection, rayLength); -} - -void Avogadro::Rendering::GeometryVisitor::visit(CylinderGeometry& geometry) -{ - m_cylinderGeometries.push_back(geometry); -} - -void Avogadro::Rendering::GeometryVisitor::boundingBox( - double& minX, double& minY, double& minZ, double& maxX, double& maxY, - double& maxZ, const std::vector& flags) const -{ - minX = std::numeric_limits::max(); - minY = minX; - minZ = minX; - maxX = -minX; - maxY = maxX; - maxZ = maxX; - - bool noSelection = true; - - for (uint32_t i = 0; i < flags.size(); i++) { - if (flags[i]) { - noSelection = false; - break; - } - } - - for (uint32_t i = 0; i < m_spheres.size(); i++) { - - if (flags.empty() || noSelection || flags[i]) { - - float radius = m_spheres[i].radius + 0.5f; - - double bufferMinX = m_spheres[i].center.x() - radius; - double bufferMinY = m_spheres[i].center.y() - radius; - double bufferMinZ = m_spheres[i].center.z() - radius; - double bufferMaxX = m_spheres[i].center.x() + radius; - double bufferMaxY = m_spheres[i].center.y() + radius; - double bufferMaxZ = m_spheres[i].center.z() + radius; - - if (bufferMinX < minX) - minX = bufferMinX; - - if (bufferMinY < minY) - minY = bufferMinY; - - if (bufferMinZ < minZ) - minZ = bufferMinZ; - - if (bufferMaxX > maxX) - maxX = bufferMaxX; - - if (bufferMaxY > maxY) - maxY = bufferMaxY; - - if (bufferMaxZ > maxZ) - maxZ = bufferMaxZ; - } - } -} - -float Avogadro::Rendering::GeometryVisitor::hit(const Vector3f& rayOrigin, - const Vector3f& rayDirection, - const float rayLength) -{ - auto minDistance = [rayOrigin, rayDirection, rayLength]( - const std::vector& drawables) -> float { - float result = std::numeric_limits::max(); - - for (auto& drawable : drawables) { - std::multimap hitsMap = - drawable->hits(rayOrigin, rayOrigin + rayLength * rayDirection, - rayDirection); - - for (auto& hit : hitsMap) { - if (hit.first < result) - result = hit.first; - } - } - return result; - }; - - std::vector pDrawables; - pDrawables.reserve(m_sphereGeometries.size() + m_cylinderGeometries.size()); - - for (auto& m_sphereGeometry : m_sphereGeometries) - pDrawables.push_back(&m_sphereGeometry); - - for (auto& m_cylinderGeometry : m_cylinderGeometries) - pDrawables.push_back(&m_cylinderGeometry); - - float result = minDistance(pDrawables); - - return result < std::numeric_limits::max() ? result : -1.0f; -}