diff --git a/libraries/voxels/src/ViewFrustum.cpp b/libraries/voxels/src/ViewFrustum.cpp index 491a355040..0a492d2d6e 100644 --- a/libraries/voxels/src/ViewFrustum.cpp +++ b/libraries/voxels/src/ViewFrustum.cpp @@ -426,7 +426,7 @@ void ViewFrustum::printDebugDetails() const { } -glm::vec2 ViewFrustum::projectPoint(glm::vec3 point) const { +glm::vec2 ViewFrustum::projectPoint(glm::vec3 point, bool& pointInView) const { // Projection matrix : Field of View, ratio, display range : near to far glm::mat4 projection = glm::perspective(_fieldOfView, _aspectRatio, _nearClip, _farClip); @@ -437,7 +437,19 @@ glm::vec2 ViewFrustum::projectPoint(glm::vec3 point) const { glm::vec4 pointVec4 = glm::vec4(point,1); glm::vec4 projectedPointVec4 = VP * pointVec4; - glm::vec2 projectedPoint(projectedPointVec4.x / projectedPointVec4.w, projectedPointVec4.y / projectedPointVec4.w); + pointInView = (projectedPointVec4.w > 0); // 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; } @@ -505,16 +517,24 @@ VoxelProjectedShadow ViewFrustum::getProjectedShadow(const AABox& box) const { VoxelProjectedShadow shadow(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); + glm::vec2 projectedPoint = projectPoint(point, pointInView); + allPointsInView = allPointsInView && pointInView; + anyPointsInView = anyPointsInView || pointInView; shadow.setVertex(i, projectedPoint); } } // set the distance from our camera position, to the closest vertex float distance = glm::distance(getPosition(), box.getCenter()); shadow.setDistance(distance); + shadow.setAnyInView(anyPointsInView); + shadow.setAllInView(allPointsInView); return shadow; } diff --git a/libraries/voxels/src/ViewFrustum.h b/libraries/voxels/src/ViewFrustum.h index 04ef0dc7a9..bf30aa4818 100644 --- a/libraries/voxels/src/ViewFrustum.h +++ b/libraries/voxels/src/ViewFrustum.h @@ -88,7 +88,7 @@ public: void printDebugDetails() const; - glm::vec2 projectPoint(glm::vec3 point) const; + glm::vec2 projectPoint(glm::vec3 point, bool& pointInView) const; VoxelProjectedShadow getProjectedShadow(const AABox& box) const; private: diff --git a/libraries/voxels/src/VoxelProjectedShadow.cpp b/libraries/voxels/src/VoxelProjectedShadow.cpp index 1ddb6370a9..19e0fe5e7d 100644 --- a/libraries/voxels/src/VoxelProjectedShadow.cpp +++ b/libraries/voxels/src/VoxelProjectedShadow.cpp @@ -50,6 +50,16 @@ void VoxelProjectedShadow::setVertex(int vertex, const glm::vec2& point) { bool VoxelProjectedShadow::occludes(const VoxelProjectedShadow& occludee) const { + // 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 + // + // this is true, but unfortunately, we're not quite handling projects in the + // case when SOME points are in view and others are not. So, we will not consider + // occlusion for any shadows that are partially in view. + if (!getAllInView() || !occludee.getAllInView() ) { + return false; + } + // first check the bounding boxes, the occludee mush be fully within the boounding box of this shadow if ((occludee.getMaxX() > getMaxX()) || (occludee.getMaxY() > getMaxY()) || diff --git a/libraries/voxels/src/VoxelProjectedShadow.h b/libraries/voxels/src/VoxelProjectedShadow.h index ffe13bb9b6..30bf80b630 100644 --- a/libraries/voxels/src/VoxelProjectedShadow.h +++ b/libraries/voxels/src/VoxelProjectedShadow.h @@ -43,6 +43,11 @@ public: float getDistance() const { return _distance; } void setDistance(float distance) { _distance = distance; } + bool getAnyInView() const { return _anyInView; }; + void setAnyInView(bool anyInView) { _anyInView = anyInView; }; + bool getAllInView() const { return _allInView; }; + void setAllInView(bool allInView) { _allInView = allInView; }; + bool occludes(const VoxelProjectedShadow& occludee) const; bool pointInside(const glm::vec2& point) const; @@ -65,6 +70,8 @@ private: float _minX; float _minY; float _distance; + bool _anyInView; // if any points are in view + bool _allInView; // if all points are in view };