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
// 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

View file

@ -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 <glm/glm.hpp>
// 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

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[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.

View file

@ -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<ViewFrustum>;