recover unused code that may prove useful someday

This commit is contained in:
Andrew Meadows 2016-03-09 11:50:34 -08:00
parent 64c2e2d175
commit 01950fba96
4 changed files with 313 additions and 86 deletions

View file

@ -1,6 +1,6 @@
// //
// OctreeProjectedPolygon.cpp // CubeProjectedPolygon.cpp
// libraries/octree/src // libraries/shared/src
// //
// Created by Brad Hefta-Gaub on 06/11/13. // Created by Brad Hefta-Gaub on 06/11/13.
// Copyright 2013 High Fidelity, Inc. // Copyright 2013 High Fidelity, Inc.
@ -15,50 +15,50 @@
#include "GeometryUtil.h" #include "GeometryUtil.h"
#include "SharedUtil.h" #include "SharedUtil.h"
#include "OctreeLogging.h" #include "SharedLogging.h"
#include "OctreeProjectedPolygon.h" #include "CubeProjectedPolygon.h"
glm::vec2 BoundingBox::getVertex(int vertexNumber) const { glm::vec2 BoundingRectangle::getVertex(int vertexNumber) const {
switch (vertexNumber) { switch (vertexNumber) {
case BoundingBox::BOTTOM_LEFT: case BoundingRectangle::BOTTOM_LEFT:
return corner; return corner;
case BoundingBox::TOP_LEFT: case BoundingRectangle::TOP_LEFT:
return glm::vec2(corner.x, corner.y + size.y); 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); return glm::vec2(corner.x + size.x, corner.y);
case BoundingBox::TOP_RIGHT: case BoundingRectangle::TOP_RIGHT:
return corner + size; return corner + size;
} }
assert(false); // not allowed assert(false); // not allowed
return glm::vec2(0,0); return glm::vec2(0,0);
} }
BoundingBox BoundingBox::topHalf() const { BoundingRectangle BoundingRectangle::topHalf() const {
float halfY = size.y/2.0f; 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; return result;
} }
BoundingBox BoundingBox::bottomHalf() const { BoundingRectangle BoundingRectangle::bottomHalf() const {
float halfY = size.y/2.0f; float halfY = size.y/2.0f;
BoundingBox result(corner, glm::vec2(size.x, halfY)); BoundingRectangle result(corner, glm::vec2(size.x, halfY));
return result; return result;
} }
BoundingBox BoundingBox::leftHalf() const { BoundingRectangle BoundingRectangle::leftHalf() const {
float halfX = size.x/2.0f; float halfX = size.x/2.0f;
BoundingBox result(corner, glm::vec2(halfX, size.y)); BoundingRectangle result(corner, glm::vec2(halfX, size.y));
return result; return result;
} }
BoundingBox BoundingBox::rightHalf() const { BoundingRectangle BoundingRectangle::rightHalf() const {
float halfX = size.x/2.0f; 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; return result;
} }
bool BoundingBox::contains(const BoundingBox& box) const { bool BoundingRectangle::contains(const BoundingRectangle& box) const {
return ( _set && return ( _set &&
(box.corner.x >= corner.x) && (box.corner.x >= corner.x) &&
(box.corner.y >= corner.y) && (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 && return ( _set &&
(point.x > corner.x) && (point.x > corner.x) &&
(point.y > corner.y) && (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) { if (!_set) {
corner = box.corner; corner = box.corner;
size = box.size; size = box.size;
@ -94,20 +94,20 @@ void BoundingBox::explandToInclude(const BoundingBox& box) {
} }
void BoundingBox::printDebugDetails(const char* label) const { void BoundingRectangle::printDebugDetails(const char* label) const {
qCDebug(octree, "%s _set=%s\n corner=%f,%f size=%f,%f\n bounds=[(%f,%f) to (%f,%f)]", qCDebug(shared, "%s _set=%s\n corner=%f,%f size=%f,%f\n bounds=[(%f,%f) to (%f,%f)]",
(label ? label : "BoundingBox"), (label ? label : "BoundingRectangle"),
debug::valueOf(_set), (double)corner.x, (double)corner.y, (double)size.x, (double)size.y, 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)); (double)corner.x, (double)corner.y, (double)(corner.x+size.x), (double)(corner.y+size.y));
} }
long OctreeProjectedPolygon::pointInside_calls = 0; long CubeProjectedPolygon::pointInside_calls = 0;
long OctreeProjectedPolygon::occludes_calls = 0; long CubeProjectedPolygon::occludes_calls = 0;
long OctreeProjectedPolygon::intersects_calls = 0; long CubeProjectedPolygon::intersects_calls = 0;
OctreeProjectedPolygon::OctreeProjectedPolygon(const BoundingBox& box) : CubeProjectedPolygon::CubeProjectedPolygon(const BoundingRectangle& box) :
_vertexCount(4), _vertexCount(4),
_maxX(-FLT_MAX), _maxY(-FLT_MAX), _minX(FLT_MAX), _minY(FLT_MAX), _maxX(-FLT_MAX), _maxY(-FLT_MAX), _minX(FLT_MAX), _minY(FLT_MAX),
_distance(0) _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; _vertices[vertex] = point;
// keep track of our bounding box // 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() // 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 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 // 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 return false; // if we got this far, then we're not occluded
} }
bool OctreeProjectedPolygon::occludes(const BoundingBox& boxOccludee) const { bool CubeProjectedPolygon::occludes(const BoundingRectangle& boxOccludee) const {
OctreeProjectedPolygon testee(boxOccludee); CubeProjectedPolygon testee(boxOccludee);
return occludes(testee); return occludes(testee);
} }
bool OctreeProjectedPolygon::matches(const OctreeProjectedPolygon& testee) const { bool CubeProjectedPolygon::matches(const CubeProjectedPolygon& testee) const {
if (testee.getVertexCount() != getVertexCount()) { if (testee.getVertexCount() != getVertexCount()) {
return false; 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 return true; // all of our vertices match, therefore we're the same
} }
bool OctreeProjectedPolygon::matches(const BoundingBox& box) const { bool CubeProjectedPolygon::matches(const BoundingRectangle& box) const {
OctreeProjectedPolygon testee(box); CubeProjectedPolygon testee(box);
return matches(testee); 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 // first check the bounding boxes, the point must be fully within the boounding box of this polygon
if ((point.x > getMaxX()) || if ((point.x > getMaxX()) ||
@ -264,23 +264,23 @@ bool OctreeProjectedPolygon::pointInside(const glm::vec2& point, bool* matchesVe
return true; return true;
} }
void OctreeProjectedPolygon::printDebugDetails() const { void CubeProjectedPolygon::printDebugDetails() const {
qCDebug(octree, "OctreeProjectedPolygon..." qCDebug(shared, "CubeProjectedPolygon..."
" minX=%f maxX=%f minY=%f maxY=%f", (double)getMinX(), (double)getMaxX(), (double)getMinY(), (double)getMaxY()); " 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++) { for (int i = 0; i < getVertexCount(); i++) {
glm::vec2 point = getVertex(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 { bool CubeProjectedPolygon::intersects(const BoundingRectangle& box) const {
OctreeProjectedPolygon testee(box); CubeProjectedPolygon testee(box);
return intersects(testee); return intersects(testee);
} }
bool OctreeProjectedPolygon::intersects(const OctreeProjectedPolygon& testee) const { bool CubeProjectedPolygon::intersects(const CubeProjectedPolygon& testee) const {
OctreeProjectedPolygon::intersects_calls++; CubeProjectedPolygon::intersects_calls++;
return intersectsOnAxes(testee) && testee.intersectsOnAxes(*this); return intersectsOnAxes(testee) && testee.intersectsOnAxes(*this);
} }
@ -294,7 +294,7 @@ bool OctreeProjectedPolygon::intersects(const OctreeProjectedPolygon& testee) co
// Note: this only works on convex polygons // 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 // consider each edge of this polygon as a potential separating axis
for (int i = 0; i < getVertexCount(); i++) { for (int i = 0; i < getVertexCount(); i++) {
@ -324,7 +324,7 @@ bool OctreeProjectedPolygon::intersectsOnAxes(const OctreeProjectedPolygon& test
return true; return true;
} }
bool OctreeProjectedPolygon::canMerge(const OctreeProjectedPolygon& that) const { bool CubeProjectedPolygon::canMerge(const CubeProjectedPolygon& that) const {
// RIGHT/NEAR // RIGHT/NEAR
// LEFT/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 // RIGHT/NEAR
// LEFT/NEAR // LEFT/NEAR

View file

@ -1,18 +1,18 @@
// //
// OctreeProjectedPolygon.h // CubeProjectedPolygon.h
// libraries/octree/src // libraries/shared/src
// //
// Created by Brad Hefta-Gaub on 06/11/13. // Created by Brad Hefta-Gaub on 06/11/13.
// Copyright 2013 High Fidelity, Inc. // 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. // Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#ifndef hifi_OctreeProjectedPolygon_h #ifndef hifi_CubeProjectedPolygon_h
#define hifi_OctreeProjectedPolygon_h #define hifi_CubeProjectedPolygon_h
#include <glm/glm.hpp> #include <glm/glm.hpp>
@ -21,29 +21,29 @@ 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_CLIPPED_PROJECTED_POLYGON_VERTEX_COUNT = MAX_PROJECTED_POLYGON_VERTEX_COUNT * 2;
typedef glm::vec2 ProjectedVertices[MAX_CLIPPED_PROJECTED_POLYGON_VERTEX_COUNT]; typedef glm::vec2 ProjectedVertices[MAX_CLIPPED_PROJECTED_POLYGON_VERTEX_COUNT];
class BoundingBox { class BoundingRectangle {
public: public:
enum { BOTTOM_LEFT, BOTTOM_RIGHT, TOP_RIGHT, TOP_LEFT, VERTEX_COUNT }; 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) {} BoundingRectangle(const glm::vec2 corner, const glm::vec2 size) : corner(corner), size(size), _set(true) {}
BoundingBox() : _set(false) {} BoundingRectangle() : _set(false) {}
glm::vec2 corner; glm::vec2 corner;
glm::vec2 size; glm::vec2 size;
bool contains(const BoundingBox& box) const; bool contains(const BoundingRectangle& box) const;
bool contains(const glm::vec2& point) const; bool contains(const glm::vec2& point) const;
bool pointInside(const glm::vec2& point) const { return contains(point); } 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; } float area() const { return size.x * size.y; }
int getVertexCount() const { return VERTEX_COUNT; } int getVertexCount() const { return VERTEX_COUNT; }
glm::vec2 getVertex(int vertexNumber) const; glm::vec2 getVertex(int vertexNumber) const;
BoundingBox topHalf() const; BoundingRectangle topHalf() const;
BoundingBox bottomHalf() const; BoundingRectangle bottomHalf() const;
BoundingBox leftHalf() const; BoundingRectangle leftHalf() const;
BoundingBox rightHalf() const; BoundingRectangle rightHalf() const;
float getMaxX() const { return corner.x + size.x; } float getMaxX() const { return corner.x + size.x; }
float getMaxY() const { return corner.y + size.y; } float getMaxY() const { return corner.y + size.y; }
@ -63,18 +63,18 @@ const int PROJECTION_NEAR = 16;
const int PROJECTION_FAR = 32; const int PROJECTION_FAR = 32;
const int PROJECTION_CLIPPED = 64; const int PROJECTION_CLIPPED = 64;
class OctreeProjectedPolygon { class CubeProjectedPolygon {
public: public:
OctreeProjectedPolygon(const BoundingBox& box); CubeProjectedPolygon(const BoundingRectangle& box);
OctreeProjectedPolygon(int vertexCount = 0) : CubeProjectedPolygon(int vertexCount = 0) :
_vertexCount(vertexCount), _vertexCount(vertexCount),
_maxX(-FLT_MAX), _maxY(-FLT_MAX), _minX(FLT_MAX), _minY(FLT_MAX), _maxX(-FLT_MAX), _maxY(-FLT_MAX), _minX(FLT_MAX), _minY(FLT_MAX),
_distance(0) _distance(0)
{ } { }
~OctreeProjectedPolygon() { } ~CubeProjectedPolygon() { }
const ProjectedVertices& getVertices() const { return _vertices; } const ProjectedVertices& getVertices() const { return _vertices; }
const glm::vec2& getVertex(int i) const { return _vertices[i]; } const glm::vec2& getVertex(int i) const { return _vertices[i]; }
void setVertex(int vertex, const glm::vec2& point); void setVertex(int vertex, const glm::vec2& point);
@ -92,24 +92,24 @@ public:
bool pointInside(const glm::vec2& point, bool* matchesVertex = NULL) const; bool pointInside(const glm::vec2& point, bool* matchesVertex = NULL) const;
bool occludes(const OctreeProjectedPolygon& occludee, bool checkAllInView = false) const; bool occludes(const CubeProjectedPolygon& occludee, bool checkAllInView = false) const;
bool occludes(const BoundingBox& occludee) const; bool occludes(const BoundingRectangle& occludee) const;
bool intersects(const OctreeProjectedPolygon& testee) const; bool intersects(const CubeProjectedPolygon& testee) const;
bool intersects(const BoundingBox& box) const; bool intersects(const BoundingRectangle& box) const;
bool matches(const OctreeProjectedPolygon& testee) const; bool matches(const CubeProjectedPolygon& testee) const;
bool matches(const BoundingBox& testee) const; bool matches(const BoundingRectangle& testee) const;
bool intersectsOnAxes(const OctreeProjectedPolygon& testee) const; bool intersectsOnAxes(const CubeProjectedPolygon& testee) const;
bool canMerge(const OctreeProjectedPolygon& that) const; bool canMerge(const CubeProjectedPolygon& that) const;
void merge(const OctreeProjectedPolygon& that); // replaces vertices of this with new merged version void merge(const CubeProjectedPolygon& that); // replaces vertices of this with new merged version
float getMaxX() const { return _maxX; } float getMaxX() const { return _maxX; }
float getMaxY() const { return _maxY; } float getMaxY() const { return _maxY; }
float getMinX() const { return _minX; } float getMinX() const { return _minX; }
float getMinY() const { return _minY; } float getMinY() const { return _minY; }
BoundingBox getBoundingBox() const { BoundingRectangle getBoundingBox() const {
return BoundingBox(glm::vec2(_minX,_minY), glm::vec2(_maxX - _minX, _maxY - _minY)); return BoundingRectangle(glm::vec2(_minX,_minY), glm::vec2(_maxX - _minX, _maxY - _minY));
} }
void printDebugDetails() const; void printDebugDetails() const;
@ -132,4 +132,4 @@ private:
}; };
#endif // hifi_OctreeProjectedPolygon_h #endif // hifi_CubeProjectedPolygon_h

View file

@ -107,6 +107,14 @@ void ViewFrustum::calculate() {
_planes[RIGHT_PLANE].set3Points(_cornersWorld[BOTTOM_RIGHT_FAR], _cornersWorld[BOTTOM_RIGHT_NEAR], _cornersWorld[TOP_RIGHT_FAR]); _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[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]); _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 }; //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); 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 { bool ViewFrustum::isVerySimilar(const ViewFrustum& compareTo, bool debug) const {
// Compute distance between the two positions // Compute distance between the two positions
@ -383,6 +440,166 @@ void ViewFrustum::printDebugDetails() const {
qCDebug(shared, "_focalLength=%f", (double)_focalLength); 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 // 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 // axis-aligned voxels to determine which of the voxels vertices must be the furthest. No need for
// squares and square-roots. Just compares. // squares and square-roots. Just compares.

View file

@ -21,6 +21,7 @@
#include "AABox.h" #include "AABox.h"
#include "AACube.h" #include "AACube.h"
#include "CubeProjectedPolygon.h"
#include "Plane.h" #include "Plane.h"
#include "RegisteredMetaTypes.h" #include "RegisteredMetaTypes.h"
#include "Transform.h" #include "Transform.h"
@ -108,6 +109,10 @@ public:
bool cubeIntersectsKeyhole(const AACube& cube) const; bool cubeIntersectsKeyhole(const AACube& cube) const;
bool boxIntersectsKeyhole(const AABox& box) 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;
bool isVerySimilar(const ViewFrustum* compareTo, bool debug = false) const { return isVerySimilar(*compareTo, debug); } bool isVerySimilar(const ViewFrustum* compareTo, bool debug = false) const { return isVerySimilar(*compareTo, debug); }
@ -119,6 +124,8 @@ public:
void printDebugDetails() const; 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; void getFurthestPointFromCamera(const AACube& box, glm::vec3& furthestPoint) const;
float distanceToCamera(const glm::vec3& point) const; float distanceToCamera(const glm::vec3& point) const;
@ -159,6 +166,9 @@ private:
float _farClip { DEFAULT_FAR_CLIP }; float _farClip { DEFAULT_FAR_CLIP };
const char* debugPlaneName (int plane) const; const char* debugPlaneName (int plane) const;
// Used to project points
glm::mat4 _ourModelViewProjectionMatrix;
}; };
using ViewFrustumPointer = std::shared_ptr<ViewFrustum>; using ViewFrustumPointer = std::shared_ptr<ViewFrustum>;