From 01950fba965df58c0ff45d73f53f4bb1b6fa4790 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 9 Mar 2016 11:50:34 -0800 Subject: [PATCH] recover unused code that may prove useful someday --- .../src/CubeProjectedPolygon.cpp} | 96 ++++---- .../src/CubeProjectedPolygon.h} | 76 +++--- libraries/shared/src/ViewFrustum.cpp | 217 ++++++++++++++++++ libraries/shared/src/ViewFrustum.h | 10 + 4 files changed, 313 insertions(+), 86 deletions(-) rename libraries/{octree/src/OctreeProjectedPolygon.cpp => shared/src/CubeProjectedPolygon.cpp} (93%) rename libraries/{octree/src/OctreeProjectedPolygon.h => shared/src/CubeProjectedPolygon.h} (64%) diff --git a/libraries/octree/src/OctreeProjectedPolygon.cpp b/libraries/shared/src/CubeProjectedPolygon.cpp similarity index 93% rename from libraries/octree/src/OctreeProjectedPolygon.cpp rename to libraries/shared/src/CubeProjectedPolygon.cpp index b8e2d4d999..04d6e8bb4e 100644 --- a/libraries/octree/src/OctreeProjectedPolygon.cpp +++ b/libraries/shared/src/CubeProjectedPolygon.cpp @@ -1,6 +1,6 @@ // -// OctreeProjectedPolygon.cpp -// libraries/octree/src +// CubeProjectedPolygon.cpp +// libraries/shared/src // // Created by Brad Hefta-Gaub on 06/11/13. // Copyright 2013 High Fidelity, Inc. @@ -15,50 +15,50 @@ #include "GeometryUtil.h" #include "SharedUtil.h" -#include "OctreeLogging.h" -#include "OctreeProjectedPolygon.h" +#include "SharedLogging.h" +#include "CubeProjectedPolygon.h" -glm::vec2 BoundingBox::getVertex(int vertexNumber) const { +glm::vec2 BoundingRectangle::getVertex(int vertexNumber) const { switch (vertexNumber) { - case BoundingBox::BOTTOM_LEFT: + case BoundingRectangle::BOTTOM_LEFT: return corner; - case BoundingBox::TOP_LEFT: + case BoundingRectangle::TOP_LEFT: return glm::vec2(corner.x, corner.y + size.y); - case BoundingBox::BOTTOM_RIGHT: + case BoundingRectangle::BOTTOM_RIGHT: return glm::vec2(corner.x + size.x, corner.y); - case BoundingBox::TOP_RIGHT: + case BoundingRectangle::TOP_RIGHT: return corner + size; } assert(false); // not allowed return glm::vec2(0,0); } -BoundingBox BoundingBox::topHalf() const { +BoundingRectangle BoundingRectangle::topHalf() const { float halfY = size.y/2.0f; - BoundingBox result(glm::vec2(corner.x,corner.y + halfY), glm::vec2(size.x, halfY)); + BoundingRectangle result(glm::vec2(corner.x,corner.y + halfY), glm::vec2(size.x, halfY)); return result; } -BoundingBox BoundingBox::bottomHalf() const { +BoundingRectangle BoundingRectangle::bottomHalf() const { float halfY = size.y/2.0f; - BoundingBox result(corner, glm::vec2(size.x, halfY)); + BoundingRectangle result(corner, glm::vec2(size.x, halfY)); return result; } -BoundingBox BoundingBox::leftHalf() const { +BoundingRectangle BoundingRectangle::leftHalf() const { float halfX = size.x/2.0f; - BoundingBox result(corner, glm::vec2(halfX, size.y)); + BoundingRectangle result(corner, glm::vec2(halfX, size.y)); return result; } -BoundingBox BoundingBox::rightHalf() const { +BoundingRectangle BoundingRectangle::rightHalf() const { float halfX = size.x/2.0f; - BoundingBox result(glm::vec2(corner.x + halfX , corner.y), glm::vec2(halfX, size.y)); + BoundingRectangle result(glm::vec2(corner.x + halfX , corner.y), glm::vec2(halfX, size.y)); return result; } -bool BoundingBox::contains(const BoundingBox& box) const { +bool BoundingRectangle::contains(const BoundingRectangle& box) const { return ( _set && (box.corner.x >= corner.x) && (box.corner.y >= corner.y) && @@ -67,7 +67,7 @@ bool BoundingBox::contains(const BoundingBox& box) const { ); } -bool BoundingBox::contains(const glm::vec2& point) const { +bool BoundingRectangle::contains(const glm::vec2& point) const { return ( _set && (point.x > corner.x) && (point.y > corner.y) && @@ -76,7 +76,7 @@ bool BoundingBox::contains(const glm::vec2& point) const { ); } -void BoundingBox::explandToInclude(const BoundingBox& box) { +void BoundingRectangle::explandToInclude(const BoundingRectangle& box) { if (!_set) { corner = box.corner; size = box.size; @@ -94,20 +94,20 @@ void BoundingBox::explandToInclude(const BoundingBox& box) { } -void BoundingBox::printDebugDetails(const char* label) const { - qCDebug(octree, "%s _set=%s\n corner=%f,%f size=%f,%f\n bounds=[(%f,%f) to (%f,%f)]", - (label ? label : "BoundingBox"), +void BoundingRectangle::printDebugDetails(const char* label) const { + qCDebug(shared, "%s _set=%s\n corner=%f,%f size=%f,%f\n bounds=[(%f,%f) to (%f,%f)]", + (label ? label : "BoundingRectangle"), debug::valueOf(_set), (double)corner.x, (double)corner.y, (double)size.x, (double)size.y, (double)corner.x, (double)corner.y, (double)(corner.x+size.x), (double)(corner.y+size.y)); } -long OctreeProjectedPolygon::pointInside_calls = 0; -long OctreeProjectedPolygon::occludes_calls = 0; -long OctreeProjectedPolygon::intersects_calls = 0; +long CubeProjectedPolygon::pointInside_calls = 0; +long CubeProjectedPolygon::occludes_calls = 0; +long CubeProjectedPolygon::intersects_calls = 0; -OctreeProjectedPolygon::OctreeProjectedPolygon(const BoundingBox& box) : +CubeProjectedPolygon::CubeProjectedPolygon(const BoundingRectangle& box) : _vertexCount(4), _maxX(-FLT_MAX), _maxY(-FLT_MAX), _minX(FLT_MAX), _minY(FLT_MAX), _distance(0) @@ -118,7 +118,7 @@ OctreeProjectedPolygon::OctreeProjectedPolygon(const BoundingBox& box) : } -void OctreeProjectedPolygon::setVertex(int vertex, const glm::vec2& point) { +void CubeProjectedPolygon::setVertex(int vertex, const glm::vec2& point) { _vertices[vertex] = point; // keep track of our bounding box @@ -138,9 +138,9 @@ void OctreeProjectedPolygon::setVertex(int vertex, const glm::vec2& point) { } // can be optimized with new pointInside() -bool OctreeProjectedPolygon::occludes(const OctreeProjectedPolygon& occludee, bool checkAllInView) const { +bool CubeProjectedPolygon::occludes(const CubeProjectedPolygon& occludee, bool checkAllInView) const { - OctreeProjectedPolygon::occludes_calls++; + CubeProjectedPolygon::occludes_calls++; // if we are completely out of view, then we definitely don't occlude! // if the occludee is completely out of view, then we also don't occlude it @@ -197,12 +197,12 @@ bool OctreeProjectedPolygon::occludes(const OctreeProjectedPolygon& occludee, bo return false; // if we got this far, then we're not occluded } -bool OctreeProjectedPolygon::occludes(const BoundingBox& boxOccludee) const { - OctreeProjectedPolygon testee(boxOccludee); +bool CubeProjectedPolygon::occludes(const BoundingRectangle& boxOccludee) const { + CubeProjectedPolygon testee(boxOccludee); return occludes(testee); } -bool OctreeProjectedPolygon::matches(const OctreeProjectedPolygon& testee) const { +bool CubeProjectedPolygon::matches(const CubeProjectedPolygon& testee) const { if (testee.getVertexCount() != getVertexCount()) { return false; } @@ -231,14 +231,14 @@ bool OctreeProjectedPolygon::matches(const OctreeProjectedPolygon& testee) const return true; // all of our vertices match, therefore we're the same } -bool OctreeProjectedPolygon::matches(const BoundingBox& box) const { - OctreeProjectedPolygon testee(box); +bool CubeProjectedPolygon::matches(const BoundingRectangle& box) const { + CubeProjectedPolygon testee(box); return matches(testee); } -bool OctreeProjectedPolygon::pointInside(const glm::vec2& point, bool* matchesVertex) const { +bool CubeProjectedPolygon::pointInside(const glm::vec2& point, bool* matchesVertex) const { - OctreeProjectedPolygon::pointInside_calls++; + CubeProjectedPolygon::pointInside_calls++; // first check the bounding boxes, the point must be fully within the boounding box of this polygon if ((point.x > getMaxX()) || @@ -264,23 +264,23 @@ bool OctreeProjectedPolygon::pointInside(const glm::vec2& point, bool* matchesVe return true; } -void OctreeProjectedPolygon::printDebugDetails() const { - qCDebug(octree, "OctreeProjectedPolygon..." +void CubeProjectedPolygon::printDebugDetails() const { + qCDebug(shared, "CubeProjectedPolygon..." " minX=%f maxX=%f minY=%f maxY=%f", (double)getMinX(), (double)getMaxX(), (double)getMinY(), (double)getMaxY()); - qCDebug(octree, " vertex count=%d distance=%f", getVertexCount(), (double)getDistance()); + qCDebug(shared, " vertex count=%d distance=%f", getVertexCount(), (double)getDistance()); for (int i = 0; i < getVertexCount(); i++) { glm::vec2 point = getVertex(i); - qCDebug(octree, " vertex[%d] = %f, %f ", i, (double)point.x, (double)point.y); + qCDebug(shared, " vertex[%d] = %f, %f ", i, (double)point.x, (double)point.y); } } -bool OctreeProjectedPolygon::intersects(const BoundingBox& box) const { - OctreeProjectedPolygon testee(box); +bool CubeProjectedPolygon::intersects(const BoundingRectangle& box) const { + CubeProjectedPolygon testee(box); return intersects(testee); } -bool OctreeProjectedPolygon::intersects(const OctreeProjectedPolygon& testee) const { - OctreeProjectedPolygon::intersects_calls++; +bool CubeProjectedPolygon::intersects(const CubeProjectedPolygon& testee) const { + CubeProjectedPolygon::intersects_calls++; return intersectsOnAxes(testee) && testee.intersectsOnAxes(*this); } @@ -294,7 +294,7 @@ bool OctreeProjectedPolygon::intersects(const OctreeProjectedPolygon& testee) co // Note: this only works on convex polygons // // -bool OctreeProjectedPolygon::intersectsOnAxes(const OctreeProjectedPolygon& testee) const { +bool CubeProjectedPolygon::intersectsOnAxes(const CubeProjectedPolygon& testee) const { // consider each edge of this polygon as a potential separating axis for (int i = 0; i < getVertexCount(); i++) { @@ -324,7 +324,7 @@ bool OctreeProjectedPolygon::intersectsOnAxes(const OctreeProjectedPolygon& test return true; } -bool OctreeProjectedPolygon::canMerge(const OctreeProjectedPolygon& that) const { +bool CubeProjectedPolygon::canMerge(const CubeProjectedPolygon& that) const { // RIGHT/NEAR // LEFT/NEAR @@ -642,7 +642,7 @@ bool OctreeProjectedPolygon::canMerge(const OctreeProjectedPolygon& that) const } -void OctreeProjectedPolygon::merge(const OctreeProjectedPolygon& that) { +void CubeProjectedPolygon::merge(const CubeProjectedPolygon& that) { // RIGHT/NEAR // LEFT/NEAR diff --git a/libraries/octree/src/OctreeProjectedPolygon.h b/libraries/shared/src/CubeProjectedPolygon.h similarity index 64% rename from libraries/octree/src/OctreeProjectedPolygon.h rename to libraries/shared/src/CubeProjectedPolygon.h index a8507e8fb2..6eb35e100b 100644 --- a/libraries/octree/src/OctreeProjectedPolygon.h +++ b/libraries/shared/src/CubeProjectedPolygon.h @@ -1,55 +1,55 @@ // -// OctreeProjectedPolygon.h -// libraries/octree/src +// CubeProjectedPolygon.h +// libraries/shared/src // // Created by Brad Hefta-Gaub on 06/11/13. // Copyright 2013 High Fidelity, Inc. // -// The projected shadow (on the 2D view plane) for a voxel +// The projected shadow (on the 2D view plane) for a cube // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef hifi_OctreeProjectedPolygon_h -#define hifi_OctreeProjectedPolygon_h +#ifndef hifi_CubeProjectedPolygon_h +#define hifi_CubeProjectedPolygon_h #include // there's a max of 6 vertices of a project polygon, and a max of twice that when clipped to the screen -const int MAX_PROJECTED_POLYGON_VERTEX_COUNT = 6; -const int MAX_CLIPPED_PROJECTED_POLYGON_VERTEX_COUNT = MAX_PROJECTED_POLYGON_VERTEX_COUNT * 2; +const int MAX_PROJECTED_POLYGON_VERTEX_COUNT = 6; +const int MAX_CLIPPED_PROJECTED_POLYGON_VERTEX_COUNT = MAX_PROJECTED_POLYGON_VERTEX_COUNT * 2; typedef glm::vec2 ProjectedVertices[MAX_CLIPPED_PROJECTED_POLYGON_VERTEX_COUNT]; -class BoundingBox { +class BoundingRectangle { public: enum { BOTTOM_LEFT, BOTTOM_RIGHT, TOP_RIGHT, TOP_LEFT, VERTEX_COUNT }; - BoundingBox(const glm::vec2 corner, const glm::vec2 size) : corner(corner), size(size), _set(true) {} - BoundingBox() : _set(false) {} + BoundingRectangle(const glm::vec2 corner, const glm::vec2 size) : corner(corner), size(size), _set(true) {} + BoundingRectangle() : _set(false) {} glm::vec2 corner; glm::vec2 size; - bool contains(const BoundingBox& box) const; + bool contains(const BoundingRectangle& box) const; bool contains(const glm::vec2& point) const; bool pointInside(const glm::vec2& point) const { return contains(point); } - void explandToInclude(const BoundingBox& box); + void explandToInclude(const BoundingRectangle& box); float area() const { return size.x * size.y; } int getVertexCount() const { return VERTEX_COUNT; } glm::vec2 getVertex(int vertexNumber) const; - BoundingBox topHalf() const; - BoundingBox bottomHalf() const; - BoundingBox leftHalf() const; - BoundingBox rightHalf() const; + BoundingRectangle topHalf() const; + BoundingRectangle bottomHalf() const; + BoundingRectangle leftHalf() const; + BoundingRectangle rightHalf() const; float getMaxX() const { return corner.x + size.x; } float getMaxY() const { return corner.y + size.y; } float getMinX() const { return corner.x; } float getMinY() const { return corner.y; } - + void printDebugDetails(const char* label=NULL) const; private: bool _set; @@ -63,18 +63,18 @@ const int PROJECTION_NEAR = 16; const int PROJECTION_FAR = 32; const int PROJECTION_CLIPPED = 64; -class OctreeProjectedPolygon { +class CubeProjectedPolygon { public: - OctreeProjectedPolygon(const BoundingBox& box); + CubeProjectedPolygon(const BoundingRectangle& box); - OctreeProjectedPolygon(int vertexCount = 0) : - _vertexCount(vertexCount), + CubeProjectedPolygon(int vertexCount = 0) : + _vertexCount(vertexCount), _maxX(-FLT_MAX), _maxY(-FLT_MAX), _minX(FLT_MAX), _minY(FLT_MAX), _distance(0) { } - - ~OctreeProjectedPolygon() { } + + ~CubeProjectedPolygon() { } const ProjectedVertices& getVertices() const { return _vertices; } const glm::vec2& getVertex(int i) const { return _vertices[i]; } void setVertex(int vertex, const glm::vec2& point); @@ -92,28 +92,28 @@ public: bool pointInside(const glm::vec2& point, bool* matchesVertex = NULL) const; - bool occludes(const OctreeProjectedPolygon& occludee, bool checkAllInView = false) const; - bool occludes(const BoundingBox& occludee) const; - bool intersects(const OctreeProjectedPolygon& testee) const; - bool intersects(const BoundingBox& box) const; - bool matches(const OctreeProjectedPolygon& testee) const; - bool matches(const BoundingBox& testee) const; - bool intersectsOnAxes(const OctreeProjectedPolygon& testee) const; + bool occludes(const CubeProjectedPolygon& occludee, bool checkAllInView = false) const; + bool occludes(const BoundingRectangle& occludee) const; + bool intersects(const CubeProjectedPolygon& testee) const; + bool intersects(const BoundingRectangle& box) const; + bool matches(const CubeProjectedPolygon& testee) const; + bool matches(const BoundingRectangle& testee) const; + bool intersectsOnAxes(const CubeProjectedPolygon& testee) const; + + bool canMerge(const CubeProjectedPolygon& that) const; + void merge(const CubeProjectedPolygon& that); // replaces vertices of this with new merged version - bool canMerge(const OctreeProjectedPolygon& that) const; - void merge(const OctreeProjectedPolygon& that); // replaces vertices of this with new merged version - float getMaxX() const { return _maxX; } float getMaxY() const { return _maxY; } float getMinX() const { return _minX; } float getMinY() const { return _minY; } - - BoundingBox getBoundingBox() const { - return BoundingBox(glm::vec2(_minX,_minY), glm::vec2(_maxX - _minX, _maxY - _minY)); + + BoundingRectangle getBoundingBox() const { + return BoundingRectangle(glm::vec2(_minX,_minY), glm::vec2(_maxX - _minX, _maxY - _minY)); } void printDebugDetails() const; - + static long pointInside_calls; static long occludes_calls; static long intersects_calls; @@ -132,4 +132,4 @@ private: }; -#endif // hifi_OctreeProjectedPolygon_h +#endif // hifi_CubeProjectedPolygon_h diff --git a/libraries/shared/src/ViewFrustum.cpp b/libraries/shared/src/ViewFrustum.cpp index d6ba9e1dce..4a7d4eff95 100644 --- a/libraries/shared/src/ViewFrustum.cpp +++ b/libraries/shared/src/ViewFrustum.cpp @@ -107,6 +107,14 @@ void ViewFrustum::calculate() { _planes[RIGHT_PLANE].set3Points(_cornersWorld[BOTTOM_RIGHT_FAR], _cornersWorld[BOTTOM_RIGHT_NEAR], _cornersWorld[TOP_RIGHT_FAR]); _planes[NEAR_PLANE].set3Points(_cornersWorld[BOTTOM_RIGHT_NEAR], _cornersWorld[BOTTOM_LEFT_NEAR], _cornersWorld[TOP_LEFT_NEAR]); _planes[FAR_PLANE].set3Points(_cornersWorld[BOTTOM_LEFT_FAR], _cornersWorld[BOTTOM_RIGHT_FAR], _cornersWorld[TOP_RIGHT_FAR]); + + // Also calculate our projection matrix in case people want to project points... + // Projection matrix : Field of View, ratio, display range : near to far + glm::vec3 lookAt = _position + _direction; + glm::mat4 view = glm::lookAt(_position, lookAt, _up); + + // Our ModelViewProjection : multiplication of our 3 matrices (note: model is identity, so we can drop it) + _ourModelViewProjectionMatrix = _projection * view; // Remember, matrix multiplication is the other way around } //enum { TOP_PLANE = 0, BOTTOM_PLANE, LEFT_PLANE, RIGHT_PLANE, NEAR_PLANE, FAR_PLANE }; @@ -260,6 +268,55 @@ bool testMatches(float lhs, float rhs, float epsilon = EPSILON) { return (fabs(lhs - rhs) <= epsilon); } +bool ViewFrustum::matches(const ViewFrustum& compareTo, bool debug) const { + bool result = + testMatches(compareTo._position, _position) && + testMatches(compareTo._direction, _direction) && + testMatches(compareTo._up, _up) && + testMatches(compareTo._right, _right) && + testMatches(compareTo._fieldOfView, _fieldOfView) && + testMatches(compareTo._aspectRatio, _aspectRatio) && + testMatches(compareTo._nearClip, _nearClip) && + testMatches(compareTo._farClip, _farClip) && + testMatches(compareTo._focalLength, _focalLength); + + if (!result && debug) { + qCDebug(shared, "ViewFrustum::matches()... result=%s", debug::valueOf(result)); + qCDebug(shared, "%s -- compareTo._position=%f,%f,%f _position=%f,%f,%f", + (testMatches(compareTo._position,_position) ? "MATCHES " : "NO MATCH"), + (double)compareTo._position.x, (double)compareTo._position.y, (double)compareTo._position.z, + (double)_position.x, (double)_position.y, (double)_position.z); + qCDebug(shared, "%s -- compareTo._direction=%f,%f,%f _direction=%f,%f,%f", + (testMatches(compareTo._direction, _direction) ? "MATCHES " : "NO MATCH"), + (double)compareTo._direction.x, (double)compareTo._direction.y, (double)compareTo._direction.z, + (double)_direction.x, (double)_direction.y, (double)_direction.z ); + qCDebug(shared, "%s -- compareTo._up=%f,%f,%f _up=%f,%f,%f", + (testMatches(compareTo._up, _up) ? "MATCHES " : "NO MATCH"), + (double)compareTo._up.x, (double)compareTo._up.y, (double)compareTo._up.z, + (double)_up.x, (double)_up.y, (double)_up.z ); + qCDebug(shared, "%s -- compareTo._right=%f,%f,%f _right=%f,%f,%f", + (testMatches(compareTo._right, _right) ? "MATCHES " : "NO MATCH"), + (double)compareTo._right.x, (double)compareTo._right.y, (double)compareTo._right.z, + (double)_right.x, (double)_right.y, (double)_right.z ); + qCDebug(shared, "%s -- compareTo._fieldOfView=%f _fieldOfView=%f", + (testMatches(compareTo._fieldOfView, _fieldOfView) ? "MATCHES " : "NO MATCH"), + (double)compareTo._fieldOfView, (double)_fieldOfView); + qCDebug(shared, "%s -- compareTo._aspectRatio=%f _aspectRatio=%f", + (testMatches(compareTo._aspectRatio, _aspectRatio) ? "MATCHES " : "NO MATCH"), + (double)compareTo._aspectRatio, (double)_aspectRatio); + qCDebug(shared, "%s -- compareTo._nearClip=%f _nearClip=%f", + (testMatches(compareTo._nearClip, _nearClip) ? "MATCHES " : "NO MATCH"), + (double)compareTo._nearClip, (double)_nearClip); + qCDebug(shared, "%s -- compareTo._farClip=%f _farClip=%f", + (testMatches(compareTo._farClip, _farClip) ? "MATCHES " : "NO MATCH"), + (double)compareTo._farClip, (double)_farClip); + qCDebug(shared, "%s -- compareTo._focalLength=%f _focalLength=%f", + (testMatches(compareTo._focalLength, _focalLength) ? "MATCHES " : "NO MATCH"), + (double)compareTo._focalLength, (double)_focalLength); + } + return result; +} + bool ViewFrustum::isVerySimilar(const ViewFrustum& compareTo, bool debug) const { // Compute distance between the two positions @@ -383,6 +440,166 @@ void ViewFrustum::printDebugDetails() const { qCDebug(shared, "_focalLength=%f", (double)_focalLength); } +glm::vec2 ViewFrustum::projectPoint(glm::vec3 point, bool& pointInView) const { + + glm::vec4 pointVec4 = glm::vec4(point, 1.0f); + glm::vec4 projectedPointVec4 = _ourModelViewProjectionMatrix * pointVec4; + pointInView = (projectedPointVec4.w > 0.0f); // math! If the w result is negative then the point is behind the viewer + + // what happens with w is 0??? + float x = projectedPointVec4.x / projectedPointVec4.w; + float y = projectedPointVec4.y / projectedPointVec4.w; + glm::vec2 projectedPoint(x,y); + + // if the point is out of view we also need to flip the signs of x and y + if (!pointInView) { + projectedPoint.x = -x; + projectedPoint.y = -y; + } + + return projectedPoint; +} + + +const int MAX_POSSIBLE_COMBINATIONS = 43; + +const int hullVertexLookup[MAX_POSSIBLE_COMBINATIONS][MAX_PROJECTED_POLYGON_VERTEX_COUNT+1] = { + // Number of vertices in shadow polygon for the visible faces, then a list of the index of each vertice from the AACube + +//0 + {0}, // inside + {4, BOTTOM_RIGHT_NEAR, BOTTOM_RIGHT_FAR, TOP_RIGHT_FAR, TOP_RIGHT_NEAR}, // right + {4, BOTTOM_LEFT_FAR, BOTTOM_LEFT_NEAR, TOP_LEFT_NEAR, TOP_LEFT_FAR }, // left + {0}, // n/a + +//4 + {4, BOTTOM_RIGHT_NEAR, BOTTOM_LEFT_NEAR, BOTTOM_LEFT_FAR, BOTTOM_RIGHT_FAR}, // bottom +//5 + {6, BOTTOM_RIGHT_NEAR, BOTTOM_LEFT_NEAR, BOTTOM_LEFT_FAR, BOTTOM_RIGHT_FAR, TOP_RIGHT_FAR, TOP_RIGHT_NEAR },//bottom, right + {6, BOTTOM_RIGHT_NEAR, BOTTOM_LEFT_NEAR, TOP_LEFT_NEAR, TOP_LEFT_FAR, BOTTOM_LEFT_FAR, BOTTOM_RIGHT_FAR, },//bottom, left + {0}, // n/a +//8 + {4, TOP_RIGHT_NEAR, TOP_RIGHT_FAR, TOP_LEFT_FAR, TOP_LEFT_NEAR}, // top + {6, TOP_RIGHT_NEAR, BOTTOM_RIGHT_NEAR, BOTTOM_RIGHT_FAR, TOP_RIGHT_FAR, TOP_LEFT_FAR, TOP_LEFT_NEAR}, // top, right + {6, TOP_RIGHT_NEAR, TOP_RIGHT_FAR, TOP_LEFT_FAR, BOTTOM_LEFT_FAR, BOTTOM_LEFT_NEAR, TOP_LEFT_NEAR}, // top, left + {0}, // n/a + {0}, // n/a + {0}, // n/a + {0}, // n/a + {0}, // n/a +//16 + {4, BOTTOM_LEFT_NEAR, BOTTOM_RIGHT_NEAR, TOP_RIGHT_NEAR, TOP_LEFT_NEAR }, // front or near + + {6, BOTTOM_LEFT_NEAR, BOTTOM_RIGHT_NEAR, BOTTOM_RIGHT_FAR, TOP_RIGHT_FAR, TOP_RIGHT_NEAR, TOP_LEFT_NEAR }, // front, right + {6, BOTTOM_LEFT_FAR, BOTTOM_LEFT_NEAR, BOTTOM_RIGHT_NEAR, TOP_RIGHT_NEAR, TOP_LEFT_NEAR, TOP_LEFT_FAR, }, // front, left + {0}, // n/a +//20 + {6, BOTTOM_LEFT_NEAR, BOTTOM_LEFT_FAR, BOTTOM_RIGHT_FAR, BOTTOM_RIGHT_NEAR, TOP_RIGHT_NEAR, TOP_LEFT_NEAR }, // front,bottom + +//21 + {6, BOTTOM_LEFT_NEAR, BOTTOM_LEFT_FAR, BOTTOM_RIGHT_FAR, TOP_RIGHT_FAR, TOP_RIGHT_NEAR, TOP_LEFT_NEAR }, //front,bottom,right +//22 + {6, BOTTOM_LEFT_FAR, BOTTOM_RIGHT_FAR, BOTTOM_RIGHT_NEAR, TOP_RIGHT_NEAR, TOP_LEFT_NEAR, TOP_LEFT_FAR }, //front,bottom,left + {0}, // n/a + + {6, BOTTOM_LEFT_NEAR, BOTTOM_RIGHT_NEAR, TOP_RIGHT_NEAR, TOP_RIGHT_FAR, TOP_LEFT_FAR, TOP_LEFT_NEAR}, // front, top + + {6, BOTTOM_LEFT_NEAR, BOTTOM_RIGHT_NEAR, BOTTOM_RIGHT_FAR, TOP_RIGHT_FAR, TOP_LEFT_FAR, TOP_LEFT_NEAR }, // front, top, right + + {6, BOTTOM_LEFT_FAR, BOTTOM_LEFT_NEAR, BOTTOM_RIGHT_NEAR, TOP_RIGHT_NEAR, TOP_RIGHT_FAR, TOP_LEFT_FAR }, // front, top, left + {0}, // n/a + {0}, // n/a + {0}, // n/a + {0}, // n/a + {0}, // n/a +//32 + {4, BOTTOM_RIGHT_FAR, BOTTOM_LEFT_FAR, TOP_LEFT_FAR, TOP_RIGHT_FAR }, // back + {6, BOTTOM_RIGHT_NEAR, BOTTOM_RIGHT_FAR, BOTTOM_LEFT_FAR, TOP_LEFT_FAR, TOP_RIGHT_FAR, TOP_RIGHT_NEAR}, // back, right +//34 + {6, BOTTOM_RIGHT_FAR, BOTTOM_LEFT_FAR, BOTTOM_LEFT_NEAR, TOP_LEFT_NEAR, TOP_LEFT_FAR, TOP_RIGHT_FAR }, // back, left + + + {0}, // n/a +//36 + {6, BOTTOM_RIGHT_NEAR, BOTTOM_LEFT_NEAR, BOTTOM_LEFT_FAR, TOP_LEFT_FAR, TOP_RIGHT_FAR, BOTTOM_RIGHT_FAR}, // back, bottom + {6, BOTTOM_RIGHT_NEAR, BOTTOM_LEFT_NEAR, BOTTOM_LEFT_FAR, TOP_LEFT_FAR, TOP_RIGHT_FAR, TOP_RIGHT_NEAR},//back, bottom, right + +// 38 + {6, BOTTOM_RIGHT_NEAR, BOTTOM_LEFT_NEAR, TOP_LEFT_NEAR, TOP_LEFT_FAR, TOP_RIGHT_FAR, BOTTOM_RIGHT_FAR },//back, bottom, left + {0}, // n/a + +// 40 + {6, BOTTOM_RIGHT_FAR, BOTTOM_LEFT_FAR, TOP_LEFT_FAR, TOP_LEFT_NEAR, TOP_RIGHT_NEAR, TOP_RIGHT_FAR}, // back, top + + {6, BOTTOM_RIGHT_NEAR, BOTTOM_RIGHT_FAR, BOTTOM_LEFT_FAR, TOP_LEFT_FAR, TOP_LEFT_NEAR, TOP_RIGHT_NEAR}, // back, top, right +//42 + {6, TOP_RIGHT_NEAR, TOP_RIGHT_FAR, BOTTOM_RIGHT_FAR, BOTTOM_LEFT_FAR, BOTTOM_LEFT_NEAR, TOP_LEFT_NEAR}, // back, top, left +}; + +CubeProjectedPolygon ViewFrustum::getProjectedPolygon(const AACube& box) const { + const glm::vec3& bottomNearRight = box.getCorner(); + glm::vec3 topFarLeft = box.calcTopFarLeft(); + + int lookUp = ((_position.x < bottomNearRight.x) ) // 1 = right | compute 6-bit + + ((_position.x > topFarLeft.x ) << 1) // 2 = left | code to + + ((_position.y < bottomNearRight.y) << 2) // 4 = bottom | classify camera + + ((_position.y > topFarLeft.y ) << 3) // 8 = top | with respect to + + ((_position.z < bottomNearRight.z) << 4) // 16 = front/near | the 6 defining + + ((_position.z > topFarLeft.z ) << 5); // 32 = back/far | planes + + int vertexCount = hullVertexLookup[lookUp][0]; //look up number of vertices + + CubeProjectedPolygon projectedPolygon(vertexCount); + + bool pointInView = true; + bool allPointsInView = false; // assume the best, but wait till we know we have a vertex + bool anyPointsInView = false; // assume the worst! + if (vertexCount) { + allPointsInView = true; // assume the best! + for(int i = 0; i < vertexCount; i++) { + int vertexNum = hullVertexLookup[lookUp][i+1]; + glm::vec3 point = box.getVertex((BoxVertex)vertexNum); + glm::vec2 projectedPoint = projectPoint(point, pointInView); + allPointsInView = allPointsInView && pointInView; + anyPointsInView = anyPointsInView || pointInView; + projectedPolygon.setVertex(i, projectedPoint); + } + + /*** + // Now that we've got the polygon, if it extends beyond the clipping window, then let's clip it + // NOTE: This clipping does not improve our overall performance. It basically causes more polygons to + // end up in the same quad/half and so the polygon lists get longer, and that's more calls to polygon.occludes() + if ( (projectedPolygon.getMaxX() > PolygonClip::RIGHT_OF_CLIPPING_WINDOW ) || + (projectedPolygon.getMaxY() > PolygonClip::TOP_OF_CLIPPING_WINDOW ) || + (projectedPolygon.getMaxX() < PolygonClip::LEFT_OF_CLIPPING_WINDOW ) || + (projectedPolygon.getMaxY() < PolygonClip::BOTTOM_OF_CLIPPING_WINDOW) ) { + + CoverageRegion::_clippedPolygons++; + + glm::vec2* clippedVertices; + int clippedVertexCount; + PolygonClip::clipToScreen(projectedPolygon.getVertices(), vertexCount, clippedVertices, clippedVertexCount); + + // Now reset the vertices of our projectedPolygon object + projectedPolygon.setVertexCount(clippedVertexCount); + for(int i = 0; i < clippedVertexCount; i++) { + projectedPolygon.setVertex(i, clippedVertices[i]); + } + delete[] clippedVertices; + + lookUp += PROJECTION_CLIPPED; + } + ***/ + } + // set the distance from our camera position, to the closest vertex + float distance = glm::distance(getPosition(), box.calcCenter()); + projectedPolygon.setDistance(distance); + projectedPolygon.setAnyInView(anyPointsInView); + projectedPolygon.setAllInView(allPointsInView); + projectedPolygon.setProjectionType(lookUp); // remember the projection type + return projectedPolygon; +} + // Similar strategy to getProjectedPolygon() we use the knowledge of camera position relative to the // axis-aligned voxels to determine which of the voxels vertices must be the furthest. No need for // squares and square-roots. Just compares. diff --git a/libraries/shared/src/ViewFrustum.h b/libraries/shared/src/ViewFrustum.h index fc091d4bc3..6d0bdb0fda 100644 --- a/libraries/shared/src/ViewFrustum.h +++ b/libraries/shared/src/ViewFrustum.h @@ -21,6 +21,7 @@ #include "AABox.h" #include "AACube.h" +#include "CubeProjectedPolygon.h" #include "Plane.h" #include "RegisteredMetaTypes.h" #include "Transform.h" @@ -108,6 +109,10 @@ public: bool cubeIntersectsKeyhole(const AACube& cube) const; bool boxIntersectsKeyhole(const AABox& box) const; + // some frustum comparisons + bool matches(const ViewFrustum& compareTo, bool debug = false) const; + bool matches(const ViewFrustum* compareTo, bool debug = false) const { return matches(*compareTo, debug); } + bool isVerySimilar(const ViewFrustum& compareTo, bool debug = false) const; bool isVerySimilar(const ViewFrustum* compareTo, bool debug = false) const { return isVerySimilar(*compareTo, debug); } @@ -119,6 +124,8 @@ public: void printDebugDetails() const; + glm::vec2 projectPoint(glm::vec3 point, bool& pointInView) const; + CubeProjectedPolygon getProjectedPolygon(const AACube& box) const; void getFurthestPointFromCamera(const AACube& box, glm::vec3& furthestPoint) const; float distanceToCamera(const glm::vec3& point) const; @@ -159,6 +166,9 @@ private: float _farClip { DEFAULT_FAR_CLIP }; const char* debugPlaneName (int plane) const; + + // Used to project points + glm::mat4 _ourModelViewProjectionMatrix; }; using ViewFrustumPointer = std::shared_ptr;