overte-HifiExperiments/libraries/voxels/src/VoxelProjectedPolygon.cpp
2013-07-03 10:58:30 -07:00

1235 lines
46 KiB
C++

//
// VoxelProjectedPolygon.cpp - The projected shadow (on the 2D view plane) for a voxel
// hifi
//
// Added by Brad Hefta-Gaub on 06/11/13.
//
#include <algorithm>
#include "VoxelProjectedPolygon.h"
#include "GeometryUtil.h"
#include "Log.h"
#include "SharedUtil.h"
glm::vec2 BoundingBox::getVertex(int vertexNumber) const {
switch (vertexNumber) {
case BoundingBox::BOTTOM_LEFT:
return corner;
case BoundingBox::TOP_LEFT:
return glm::vec2(corner.x, corner.y + size.y);
case BoundingBox::BOTTOM_RIGHT:
return glm::vec2(corner.x + size.x, corner.y);
case BoundingBox::TOP_RIGHT:
return corner + size;
}
assert(false); // not allowed
return glm::vec2(0,0);
}
BoundingBox BoundingBox::topHalf() const {
float halfY = size.y/2.0f;
BoundingBox result(glm::vec2(corner.x,corner.y + halfY), glm::vec2(size.x, halfY));
return result;
}
BoundingBox BoundingBox::bottomHalf() const {
float halfY = size.y/2.0f;
BoundingBox result(corner, glm::vec2(size.x, halfY));
return result;
}
BoundingBox BoundingBox::leftHalf() const {
float halfX = size.x/2.0f;
BoundingBox result(corner, glm::vec2(halfX, size.y));
return result;
}
BoundingBox BoundingBox::rightHalf() const {
float halfX = size.x/2.0f;
BoundingBox result(glm::vec2(corner.x + halfX , corner.y), glm::vec2(halfX, size.y));
return result;
}
bool BoundingBox::contains(const BoundingBox& box) const {
return ( _set &&
(box.corner.x >= corner.x) &&
(box.corner.y >= corner.y) &&
(box.corner.x + box.size.x <= corner.x + size.x) &&
(box.corner.y + box.size.y <= corner.y + size.y)
);
};
bool BoundingBox::contains(const glm::vec2& point) const {
return ( _set &&
(point.x > corner.x) &&
(point.y > corner.y) &&
(point.x < corner.x + size.x) &&
(point.y < corner.y + size.y)
);
};
void BoundingBox::explandToInclude(const BoundingBox& box) {
if (!_set) {
corner = box.corner;
size = box.size;
_set = true;
} else {
float minX = std::min(box.corner.x, corner.x);
float minY = std::min(box.corner.y, corner.y);
float maxX = std::max(box.corner.x + box.size.x, corner.x + size.x);
float maxY = std::max(box.corner.y + box.size.y, corner.y + size.y);
corner.x = minX;
corner.y = minY;
size.x = maxX - minX;
size.y = maxY - minY;
}
}
void BoundingBox::printDebugDetails(const char* label) const {
if (label) {
printLog(label);
} else {
printLog("BoundingBox");
}
printLog("\n _set=%s\n corner=%f,%f size=%f,%f\n bounds=[(%f,%f) to (%f,%f)]\n",
debug::valueOf(_set), corner.x, corner.y, size.x, size.y, corner.x, corner.y, corner.x+size.x, corner.y+size.y);
}
long VoxelProjectedPolygon::pointInside_calls = 0;
long VoxelProjectedPolygon::occludes_calls = 0;
long VoxelProjectedPolygon::intersects_calls = 0;
VoxelProjectedPolygon::VoxelProjectedPolygon(const BoundingBox& box) :
_vertexCount(4),
_maxX(-FLT_MAX), _maxY(-FLT_MAX), _minX(FLT_MAX), _minY(FLT_MAX),
_distance(0)
{
for (int i = 0; i < _vertexCount; i++) {
setVertex(i, box.getVertex(i));
}
}
void VoxelProjectedPolygon::setVertex(int vertex, const glm::vec2& point) {
_vertices[vertex] = point;
// keep track of our bounding box
if (point.x > _maxX) {
_maxX = point.x;
}
if (point.y > _maxY) {
_maxY = point.y;
}
if (point.x < _minX) {
_minX = point.x;
}
if (point.y < _minY) {
_minY = point.y;
}
};
// can be optimized with new pointInside()
bool VoxelProjectedPolygon::occludes(const VoxelProjectedPolygon& occludee, bool checkAllInView) const {
VoxelProjectedPolygon::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
//
// 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 (checkAllInView && (!getAllInView() || !occludee.getAllInView())) {
return false;
}
// first check the bounding boxes, the occludee must be fully within the boounding box of this shadow
if ((occludee.getMaxX() > getMaxX()) ||
(occludee.getMaxY() > getMaxY()) ||
(occludee.getMinX() < getMinX()) ||
(occludee.getMinY() < getMinY())) {
return false;
}
// we need to test for identity as well, because in the case of identity, none of the points
// will be "inside" but we don't want to bail early on the first non-inside point
bool potentialIdenity = false;
if ((occludee.getVertexCount() == getVertexCount()) && (getBoundingBox().contains(occludee.getBoundingBox())) ) {
potentialIdenity = true;
}
// if we got this far, then check each vertex of the occludee, if all those points
// are inside our polygon, then the tested occludee is fully occluded
int pointsInside = 0;
for(int i = 0; i < occludee.getVertexCount(); i++) {
bool vertexMatched = false;
if (!pointInside(occludee.getVertex(i), &vertexMatched)) {
// so the point we just tested isn't inside, but it might have matched a vertex
// if it didn't match a vertext, then we bail because we can't be an identity
// or if we're not expecting identity, then we also bail early, no matter what
if (!potentialIdenity || !vertexMatched) {
return false;
}
} else {
pointsInside++;
}
}
// we're only here if all points are inside matched and/or we had a potentialIdentity we need to check
if (pointsInside == occludee.getVertexCount()) {
return true;
}
// If we have the potential for identity, then test to see if we match, if we match, we occlude
if (potentialIdenity) {
return matches(occludee);
}
return false; // if we got this far, then we're not occluded
}
bool VoxelProjectedPolygon::occludes(const BoundingBox& boxOccludee) const {
VoxelProjectedPolygon testee(boxOccludee);
return occludes(testee);
}
bool VoxelProjectedPolygon::matches(const VoxelProjectedPolygon& testee) const {
if (testee.getVertexCount() != getVertexCount()) {
return false;
}
int vertextCount = getVertexCount();
// find which testee vertex matches our first polygon vertex.
glm::vec2 polygonVertex = getVertex(0);
int originIndex = 0;
for(int i = 0; i < vertextCount; i++) {
glm::vec2 testeeVertex = testee.getVertex(i);
// if they match, we found our origin.
if (testeeVertex == polygonVertex) {
originIndex = i;
break;
}
}
// Now, starting at the originIndex, walk the vertices of both the testee and ourselves
for(int i = 0; i < vertextCount; i++) {
glm::vec2 testeeVertex = testee.getVertex((i + originIndex) % vertextCount);
glm::vec2 polygonVertex = getVertex(i);
if (testeeVertex != polygonVertex) {
return false; // we don't match, therefore we're not the same
}
}
return true; // all of our vertices match, therefore we're the same
}
bool VoxelProjectedPolygon::matches(const BoundingBox& box) const {
VoxelProjectedPolygon testee(box);
return matches(testee);
}
bool VoxelProjectedPolygon::pointInside(const glm::vec2& point, bool* matchesVertex) const {
VoxelProjectedPolygon::pointInside_calls++;
// first check the bounding boxes, the point must be fully within the boounding box of this polygon
if ((point.x > getMaxX()) ||
(point.y > getMaxY()) ||
(point.x < getMinX()) ||
(point.y < getMinY())) {
return false;
}
// consider each edge of this polygon as a potential separating axis
// check the point against each edge
for (int i = 0; i < getVertexCount(); i++) {
glm::vec2 start = getVertex(i);
glm::vec2 end = getVertex((i + 1) % getVertexCount());
float a = start.y - end.y;
float b = end.x - start.x;
float c = a * start.x + b * start.y;
if (a * point.x + b * point.y < c) {
return false;
}
}
return true;
}
/*
// This old version of pointInside works on concave or convex polygons. But it's slower, and since we don't need
// to support concave polygons, we don't need to do this extra heavy lifting
bool VoxelProjectedPolygon::pointInside(const glm::vec2& point, bool* matchesVertex) const {
// first check the bounding boxes, the point must be fully within the boounding box of this shadow
if ((point.x > getMaxX()) ||
(point.y > getMaxY()) ||
(point.x < getMinX()) ||
(point.y < getMinY())) {
return false;
}
//float e = (getMaxX() - getMinX()) / 100.0f; // some epsilon
float e = 1.0f; // some epsilon
// We need to have one ray that goes from a known outside position to the point in question. We'll pick a
// start point outside of our min X, min Y
glm::vec2 r1p1(getMinX() - e, point.y);
glm::vec2 r1p2(point);
glm::vec2 r2p1(getVertex(getVertexCount()-1)); // start with last vertex to first vertex
glm::vec2 r2p2;
// Test the ray against all sides
int intersections = 0;
bool someVertexMatches = false;
for (int i = 0; i < getVertexCount(); i++) {
r2p2 = getVertex(i);
// if the point in question matches one of our vetices, then we consider it to NOT be inside.
if (point.x == r2p2.x && point.y == r2p2.y) {
// caller wants to know if we match any of the vertices
if (matchesVertex) {
*matchesVertex = true;
}
return false;
}
// if we're still processing, then check for intersections
if (doLineSegmentsIntersect(r1p1, r1p2, r2p1, r2p2)) {
intersections++;
}
r2p1 = r2p2; // set up for next side
}
// If odd number of intersections and we got here, we're inside
return ((intersections & 1) == 1);
}
*/
void VoxelProjectedPolygon::printDebugDetails() const {
printf("VoxelProjectedPolygon...");
printf(" minX=%f maxX=%f minY=%f maxY=%f\n", getMinX(), getMaxX(), getMinY(), getMaxY());
printf(" vertex count=%d distance=%f\n", getVertexCount(), getDistance());
for (int i = 0; i < getVertexCount(); i++) {
glm::vec2 point = getVertex(i);
printf(" vertex[%d] = %f, %f \n", i, point.x, point.y);
}
}
bool VoxelProjectedPolygon::intersects(const BoundingBox& box) const {
VoxelProjectedPolygon testee(box);
return intersects(testee);
}
bool VoxelProjectedPolygon::intersects(const VoxelProjectedPolygon& testee) const {
VoxelProjectedPolygon::intersects_calls++;
return intersectsOnAxes(testee) && testee.intersectsOnAxes(*this);
}
//
// Tests the edges of this polygon as potential separating axes for this polygon and the
// specified other.
//
// @return false if the polygons are disjoint on any of this polygon's axes, true if they
// intersect on all axes.
//
// Note: this only works on convex polygons
//
//
bool VoxelProjectedPolygon::intersectsOnAxes(const VoxelProjectedPolygon& testee) const {
// consider each edge of this polygon as a potential separating axis
for (int i = 0; i < getVertexCount(); i++) {
glm::vec2 start = getVertex(i);
glm::vec2 end = getVertex((i + 1) % getVertexCount());
float a = start.y - end.y;
float b = end.x - start.x;
float c = a * start.x + b * start.y;
// if all vertices fall outside the edge, the polygons are disjoint
// points that are ON the edge, are considered to be "outside"
for (int j = 0; j < testee.getVertexCount(); j++) {
glm::vec2 testeeVertex = testee.getVertex(j);
// in comparison below:
// >= will cause points on edge to be considered inside
// > will cause points on edge to be considered outside
float c2 = a * testeeVertex.x + b * testeeVertex.y;
if (c2 >= c) {
goto CONTINUE_OUTER;
}
}
return false;
CONTINUE_OUTER: ;
}
return true;
}
bool VoxelProjectedPolygon::canMerge(const VoxelProjectedPolygon& that) const {
// RIGHT/NEAR
// LEFT/NEAR
if (
(getProjectionType() == that.getProjectionType()) &&
(
getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR) ||
getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR)
)
) {
if (getVertex(1) == that.getVertex(0) && getVertex(4) == that.getVertex(5)) {
return true;
}
if (getVertex(0) == that.getVertex(1) && getVertex(5) == that.getVertex(4)) {
return true;
}
if (getVertex(2) == that.getVertex(1) && getVertex(3) == that.getVertex(4)) {
return true;
}
if (getVertex(1) == that.getVertex(2) && getVertex(4) == that.getVertex(3)) {
return true;
}
}
// NEAR/BOTTOM
if (
(getProjectionType() == that.getProjectionType()) &&
(
getProjectionType() == (PROJECTION_NEAR | PROJECTION_BOTTOM)
)
) {
if (getVertex(0) == that.getVertex(5) && getVertex(3) == that.getVertex(4)) {
return true;
}
if (getVertex(5) == that.getVertex(0) && getVertex(4) == that.getVertex(3)) {
return true;
}
if (getVertex(1) == that.getVertex(0) && getVertex(2) == that.getVertex(3)) {
return true;
}
if (getVertex(0) == that.getVertex(1) && getVertex(3) == that.getVertex(2)) {
return true;
}
}
// NEAR/TOP
if (
(getProjectionType() == that.getProjectionType()) &&
(
getProjectionType() == (PROJECTION_NEAR | PROJECTION_TOP)
)
) {
if (getVertex(0) == that.getVertex(5) && getVertex(1) == that.getVertex(2)) {
return true;
}
if (getVertex(5) == that.getVertex(0) && getVertex(2) == that.getVertex(1)) {
return true;
}
if (getVertex(4) == that.getVertex(5) && getVertex(3) == that.getVertex(2)) {
return true;
}
if (getVertex(5) == that.getVertex(4) && getVertex(2) == that.getVertex(3)) {
return true;
}
}
// RIGHT/NEAR & NEAR/RIGHT/TOP
// LEFT/NEAR & NEAR/LEFT/TOP
if (
((getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_TOP)) &&
(that.getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR)))
||
((getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_TOP)) &&
(that.getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR)))
)
{
if (getVertex(5) == that.getVertex(0) && getVertex(3) == that.getVertex(2)) {
return true;
}
}
// RIGHT/NEAR & NEAR/RIGHT/TOP
// LEFT/NEAR & NEAR/LEFT/TOP
if (
((that.getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_TOP)) &&
(getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR)))
||
((that.getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_TOP)) &&
(getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR)))
)
{
if (getVertex(0) == that.getVertex(5) && getVertex(2) == that.getVertex(3)) {
return true;
}
}
// RIGHT/NEAR & NEAR/RIGHT/BOTTOM
// NEAR/LEFT & NEAR/LEFT/BOTTOM
if (
((that.getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_BOTTOM)) &&
(getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR)))
||
((that.getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_BOTTOM)) &&
(getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR)))
)
{
if (getVertex(5) == that.getVertex(0) && getVertex(3) == that.getVertex(2)) {
return true;
}
}
// RIGHT/NEAR & NEAR/RIGHT/BOTTOM
// NEAR/LEFT & NEAR/LEFT/BOTTOM
if (
((getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_BOTTOM)) &&
(that.getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR)))
||
((getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_BOTTOM)) &&
(that.getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR)))
)
{
if (getVertex(0) == that.getVertex(5) && getVertex(2) == that.getVertex(3)) {
return true;
}
}
// NEAR/TOP & NEAR
if (
(getProjectionType() == (PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_NEAR | PROJECTION_TOP ))
)
{
if (getVertex(0) == that.getVertex(5) && getVertex(1) == that.getVertex(2)) {
return true;
}
}
// NEAR/TOP & NEAR
if (
(that.getProjectionType() == (PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_NEAR | PROJECTION_TOP ))
)
{
if (getVertex(5) == that.getVertex(0) && getVertex(2) == that.getVertex(1)) {
return true;
}
}
// NEAR/BOTTOM & NEAR
if (
(getProjectionType() == (PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_NEAR | PROJECTION_BOTTOM ))
)
{
if (getVertex(2) == that.getVertex(3) && getVertex(3) == that.getVertex(0)) {
return true;
}
}
// NEAR/BOTTOM & NEAR
if (
(that.getProjectionType() == (PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_NEAR | PROJECTION_BOTTOM ))
)
{
if (getVertex(3) == that.getVertex(2) && getVertex(0) == that.getVertex(3)) {
return true;
}
}
// NEAR/RIGHT & NEAR
if (
(getProjectionType() == (PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_NEAR | PROJECTION_RIGHT ))
)
{
if (getVertex(0) == that.getVertex(1) && getVertex(3) == that.getVertex(4)) {
return true;
}
}
// NEAR/RIGHT & NEAR
if (
(that.getProjectionType() == (PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_NEAR | PROJECTION_RIGHT ))
)
{
if (getVertex(1) == that.getVertex(0) && getVertex(4) == that.getVertex(3)) {
return true;
}
}
// NEAR/LEFT & NEAR
if (
(getProjectionType() == (PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_NEAR | PROJECTION_LEFT ))
)
{
if (getVertex(1) == that.getVertex(1) && getVertex(2) == that.getVertex(4)) {
return true;
}
}
// NEAR/LEFT & NEAR
if (
(that.getProjectionType() == (PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_NEAR | PROJECTION_LEFT ))
)
{
if (getVertex(1) == that.getVertex(0) && getVertex(4) == that.getVertex(3)) {
return true;
}
}
// NEAR/RIGHT/TOP & NEAR/TOP
if (
((getProjectionType() == (PROJECTION_TOP | PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_TOP | PROJECTION_NEAR | PROJECTION_RIGHT )))
)
{
if (getVertex(0) == that.getVertex(1) && getVertex(4) == that.getVertex(3)) {
return true;
}
}
// NEAR/RIGHT/TOP & NEAR/TOP
if (
((that.getProjectionType() == (PROJECTION_TOP | PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_TOP | PROJECTION_NEAR | PROJECTION_RIGHT )))
)
{
if (getVertex(1) == that.getVertex(0) && getVertex(3) == that.getVertex(4)) {
return true;
}
}
// NEAR/RIGHT/BOTTOM & NEAR/BOTTOM
if (
((getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR | PROJECTION_RIGHT )))
)
{
if (getVertex(1) == that.getVertex(2) && getVertex(5) == that.getVertex(4)) {
return true;
}
}
// NEAR/RIGHT/BOTTOM & NEAR/BOTTOM
if (
((that.getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR | PROJECTION_RIGHT )))
)
{
if (getVertex(2) == that.getVertex(1) && getVertex(4) == that.getVertex(5)) {
return true;
}
}
// NEAR/LEFT/BOTTOM & NEAR/BOTTOM
if (
((getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR | PROJECTION_LEFT )))
)
{
if (getVertex(2) == that.getVertex(0) && getVertex(4) == that.getVertex(4)) {
return true;
}
}
// NEAR/LEFT/BOTTOM & NEAR/BOTTOM
if (
((that.getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR | PROJECTION_LEFT )))
)
{
if (getVertex(0) == that.getVertex(2) && getVertex(4) == that.getVertex(4)) {
return true;
}
}
// RIGHT/NEAR/BOTTOM
// RIGHT/NEAR/TOP
// LEFT/NEAR/BOTTOM
// LEFT/NEAR/TOP
if (
(getProjectionType() == that.getProjectionType()) &&
(
getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_BOTTOM ) ||
getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_TOP ) ||
getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_BOTTOM ) ||
getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_TOP )
)
) {
if (getVertex(0) == that.getVertex(5) && getVertex(2) == that.getVertex(3)) {
return true;
}
if (getVertex(5) == that.getVertex(0) && getVertex(3) == that.getVertex(2)) {
return true;
}
if (getVertex(2) == that.getVertex(1) && getVertex(4) == that.getVertex(5)) {
return true;
}
if (getVertex(1) == that.getVertex(2) && getVertex(5) == that.getVertex(4)) {
return true;
}
if (getVertex(1) == that.getVertex(0) && getVertex(3) == that.getVertex(4)) {
return true;
}
if (getVertex(0) == that.getVertex(1) && getVertex(4) == that.getVertex(3)) {
return true;
}
}
return false;
}
void VoxelProjectedPolygon::merge(const VoxelProjectedPolygon& that) {
// RIGHT/NEAR
// LEFT/NEAR
if (
(getProjectionType() == that.getProjectionType()) &&
(
getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR) ||
getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR)
)
) {
if (getVertex(1) == that.getVertex(0) && getVertex(4) == that.getVertex(5)) {
//setVertex(0, this.getVertex(0)); // no change
setVertex(1, that.getVertex(1));
setVertex(2, that.getVertex(2));
setVertex(3, that.getVertex(3));
setVertex(4, that.getVertex(4));
//setVertex(5, this.getVertex(5)); // no change
return; // done
}
if (getVertex(0) == that.getVertex(1) && getVertex(5) == that.getVertex(4)) {
setVertex(0, that.getVertex(0));
//setVertex(1, this.getVertex(1)); // no change
//setVertex(2, this.getVertex(2)); // no change
//setVertex(3, this.getVertex(3)); // no change
//setVertex(4, that.getVertex(4)); // no change
setVertex(5, that.getVertex(5));
return; // done
}
if (getVertex(2) == that.getVertex(1) && getVertex(3) == that.getVertex(4)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, this.getVertex(1)); // no change
setVertex(2, that.getVertex(2));
setVertex(3, that.getVertex(3));
//setVertex(4, this.getVertex(4)); // no change
//setVertex(5, that.getVertex(5)); // no change
return; // done
}
if (getVertex(1) == that.getVertex(2) && getVertex(4) == that.getVertex(3)) {
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
//setVertex(2, this.getVertex(2)); // no change
//setVertex(3, that.getVertex(3)); // no change
setVertex(4, that.getVertex(4));
setVertex(5, that.getVertex(5));
return; // done
}
}
// NEAR/BOTTOM
if (
(getProjectionType() == that.getProjectionType()) &&
(
getProjectionType() == (PROJECTION_NEAR | PROJECTION_BOTTOM)
)
) {
if (getVertex(0) == that.getVertex(5) && getVertex(3) == that.getVertex(4)) {
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
setVertex(2, that.getVertex(2));
setVertex(3, that.getVertex(3));
//setVertex(4, this.getVertex(4)); // no change
//setVertex(5, that.getVertex(5)); // no change
return; // done
}
if (getVertex(5) == that.getVertex(0) && getVertex(4) == that.getVertex(3)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, that.getVertex(1)); // no change
//setVertex(2, this.getVertex(2)); // no change
//setVertex(3, that.getVertex(3)); // no change
setVertex(4, that.getVertex(4));
setVertex(5, that.getVertex(5));
return; // done
}
if (getVertex(1) == that.getVertex(0) && getVertex(2) == that.getVertex(3)) {
//setVertex(0, this.getVertex(0)); // no change
setVertex(1, that.getVertex(1));
setVertex(2, that.getVertex(2));
//setVertex(3, that.getVertex(3)); // no change
//setVertex(4, this.getVertex(4)); // no change
//setVertex(5, that.getVertex(5)); // no change
return; // done
}
if (getVertex(0) == that.getVertex(1) && getVertex(3) == that.getVertex(2)) {
setVertex(0, that.getVertex(0));
//setVertex(1, this.getVertex(1)); // no change
//setVertex(2, that.getVertex(2)); // no change
setVertex(3, that.getVertex(3));
setVertex(4, that.getVertex(4));
setVertex(5, that.getVertex(5));
return; // done
}
}
// NEAR/TOP
if (
(getProjectionType() == that.getProjectionType()) &&
(
getProjectionType() == (PROJECTION_NEAR | PROJECTION_TOP)
)
) {
if (getVertex(0) == that.getVertex(5) && getVertex(1) == that.getVertex(2)) {
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
//setVertex(2, this.getVertex(2)); // no change
//setVertex(3, that.getVertex(3)); // no change
//setVertex(4, this.getVertex(4)); // no change
//setVertex(5, that.getVertex(5)); // no change
return; // done
}
if (getVertex(5) == that.getVertex(0) && getVertex(2) == that.getVertex(1)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, that.getVertex(1)); // no change
setVertex(2, that.getVertex(2));
setVertex(3, that.getVertex(3));
setVertex(4, that.getVertex(4));
setVertex(5, that.getVertex(5));
return; // done
}
if (getVertex(4) == that.getVertex(5) && getVertex(3) == that.getVertex(2)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, that.getVertex(1)); // no change
//setVertex(2, that.getVertex(2)); // no change
setVertex(3, that.getVertex(3));
setVertex(4, that.getVertex(4));
//setVertex(5, that.getVertex(5)); // no change
return; // done
}
if (getVertex(5) == that.getVertex(4) && getVertex(2) == that.getVertex(3)) {
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
setVertex(2, that.getVertex(2));
//setVertex(3, this.getVertex(3)); // no change
//setVertex(4, that.getVertex(3)); // no change
setVertex(5, that.getVertex(5));
return; // done
}
}
// RIGHT/NEAR & NEAR/RIGHT/TOP
// LEFT/NEAR & NEAR/LEFT/TOP
if (
((getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_TOP)) &&
(that.getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR)))
||
((getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_TOP)) &&
(that.getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR)))
)
{
if (getVertex(5) == that.getVertex(0) && getVertex(3) == that.getVertex(2)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, this.getVertex(1)); // no change
//setVertex(2, this.getVertex(2)); // no change
setVertex(3, that.getVertex(3));
setVertex(4, that.getVertex(4));
setVertex(5, that.getVertex(5));
setProjectionType((PROJECTION_RIGHT | PROJECTION_NEAR));
return; // done
}
}
// RIGHT/NEAR & NEAR/RIGHT/TOP
// LEFT/NEAR & NEAR/LEFT/TOP
if (
((that.getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_TOP)) &&
(getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR)))
||
((that.getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_TOP)) &&
(getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR)))
)
{
if (getVertex(0) == that.getVertex(5) && getVertex(2) == that.getVertex(3)) {
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
setVertex(2, that.getVertex(2));
//setVertex(3, this.getVertex(3)); // no change
//setVertex(4, this.getVertex(4)); // no change
//setVertex(5, this.getVertex(5)); // no change
//setProjectionType((PROJECTION_RIGHT | PROJECTION_NEAR)); // no change
return; // done
}
}
// RIGHT/NEAR & NEAR/RIGHT/BOTTOM
// NEAR/LEFT & NEAR/LEFT/BOTTOM
if (
((that.getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_BOTTOM)) &&
(getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR)))
||
((that.getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_BOTTOM)) &&
(getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR)))
)
{
if (getVertex(5) == that.getVertex(0) && getVertex(3) == that.getVertex(2)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, this.getVertex(1)); // no change
//setVertex(2, this.getVertex(2)); // no change
setVertex(3, that.getVertex(3));
setVertex(4, that.getVertex(4));
setVertex(5, that.getVertex(5));
//setProjectionType((PROJECTION_RIGHT | PROJECTION_NEAR)); // no change
return; // done
}
}
// RIGHT/NEAR & NEAR/RIGHT/BOTTOM
// NEAR/LEFT & NEAR/LEFT/BOTTOM
if (
((getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_BOTTOM)) &&
(that.getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR)))
||
((getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_BOTTOM)) &&
(that.getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR)))
)
{
if (getVertex(0) == that.getVertex(5) && getVertex(2) == that.getVertex(3)) {
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
setVertex(2, that.getVertex(2));
//setVertex(3, this.getVertex(3)); // no change
//setVertex(4, this.getVertex(4)); // no change
//setVertex(5, this.getVertex(5)); // no change
setProjectionType((PROJECTION_RIGHT | PROJECTION_NEAR));
return; // done
}
}
// NEAR/TOP & NEAR
if (
(getProjectionType() == (PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_NEAR | PROJECTION_TOP ))
)
{
if (getVertex(0) == that.getVertex(5) && getVertex(1) == that.getVertex(2)) {
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
//setVertex(2, this.getVertex(2)); // no change
//setVertex(3, this.getVertex(3)); // no change
//setVertexCount(4); // no change
//setProjectionType((PROJECTION_NEAR)); // no change
return; // done
}
}
// NEAR/TOP & NEAR
if (
(that.getProjectionType() == (PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_NEAR | PROJECTION_TOP ))
)
{
if (getVertex(5) == that.getVertex(0) && getVertex(2) == that.getVertex(1)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, this.getVertex(1)); // no change
setVertex(2, that.getVertex(2));
setVertex(3, that.getVertex(3));
setVertexCount(4);
setProjectionType((PROJECTION_NEAR));
return; // done
}
}
// NEAR/BOTTOM & NEAR
if (
(getProjectionType() == (PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_NEAR | PROJECTION_BOTTOM ))
)
{
if (getVertex(2) == that.getVertex(3) && getVertex(3) == that.getVertex(0)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, this.getVertex(1)); // no change
setVertex(2, that.getVertex(4));
setVertex(3, that.getVertex(5));
//setVertexCount(4); // no change
//setProjectionType((PROJECTION_NEAR)); // no change
}
}
// NEAR/BOTTOM & NEAR
if (
(that.getProjectionType() == (PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_NEAR | PROJECTION_BOTTOM ))
)
{
if (getVertex(3) == that.getVertex(2) && getVertex(0) == that.getVertex(3)) {
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
setVertex(2, getVertex(4));
setVertex(3, getVertex(5));
setVertexCount(4);
setProjectionType((PROJECTION_NEAR));
return; // done
}
}
// NEAR/RIGHT & NEAR
if (
(getProjectionType() == (PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_NEAR | PROJECTION_RIGHT ))
)
{
if (getVertex(0) == that.getVertex(1) && getVertex(3) == that.getVertex(4)) {
setVertex(0, that.getVertex(0));
//setVertex(1, this.getVertex(1)); // no change
//setVertex(2, this.getVertex(2)); // no change
setVertex(3, that.getVertex(5));
//setVertexCount(4); // no change
//setProjectionType((PROJECTION_NEAR)); // no change
}
}
// NEAR/RIGHT & NEAR
if (
(that.getProjectionType() == (PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_NEAR | PROJECTION_RIGHT ))
)
{
if (getVertex(1) == that.getVertex(0) && getVertex(4) == that.getVertex(3)) {
//setVertex(0, this.getVertex(0)); // no change
setVertex(1, that.getVertex(1));
setVertex(2, that.getVertex(2));
setVertex(3, getVertex(5));
setVertexCount(4);
setProjectionType((PROJECTION_NEAR));
return; // done
}
}
// NEAR/LEFT & NEAR
if (
(getProjectionType() == (PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_NEAR | PROJECTION_LEFT ))
)
{
if (getVertex(1) == that.getVertex(1) && getVertex(2) == that.getVertex(4)) {
//setVertex(0, this.getVertex()); // no change
setVertex(1, that.getVertex(2));
setVertex(2, that.getVertex(3));
//setVertex(3, this.getVertex(3)); // no change
//setVertexCount(4); // no change
//setProjectionType((PROJECTION_NEAR)); // no change
return; // done
}
}
// NEAR/LEFT & NEAR
if (
(that.getProjectionType() == (PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_NEAR | PROJECTION_LEFT ))
)
{
if (getVertex(1) == that.getVertex(0) && getVertex(4) == that.getVertex(3)) {
setVertex(0, that.getVertex(0));
setVertex(1, getVertex(2));
setVertex(2, getVertex(3));
setVertex(3, that.getVertex(3));
setVertexCount(4);
setProjectionType((PROJECTION_NEAR));
return; // done
}
}
// NEAR/RIGHT/TOP & NEAR/TOP
if (
((getProjectionType() == (PROJECTION_TOP | PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_TOP | PROJECTION_NEAR | PROJECTION_RIGHT )))
)
{
if (getVertex(0) == that.getVertex(1) && getVertex(4) == that.getVertex(3)) {
setVertex(0, that.getVertex(0));
//setVertex(1, this.getVertex(1)); // no change
//setVertex(2, this.getVertex(2)); // no change
//setVertex(3, this.getVertex(3)); // no change
setVertex(4, that.getVertex(4));
setVertex(5, that.getVertex(5));
return; // done
}
}
// NEAR/RIGHT/TOP & NEAR/TOP
if (
((that.getProjectionType() == (PROJECTION_TOP | PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_TOP | PROJECTION_NEAR | PROJECTION_RIGHT )))
)
{
if (getVertex(1) == that.getVertex(0) && getVertex(3) == that.getVertex(4)) {
//setVertex(0, this.getVertex(0)); // no change
setVertex(1, that.getVertex(1));
setVertex(2, that.getVertex(2));
setVertex(3, that.getVertex(3));
//setVertex(4, this.getVertex(4)); // no change
//setVertex(5, this.getVertex(5)); // no change
setProjectionType((PROJECTION_TOP | PROJECTION_NEAR));
return; // done
}
}
// NEAR/RIGHT/BOTTOM & NEAR/BOTTOM
if (
((getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR | PROJECTION_RIGHT )))
)
{
if (getVertex(1) == that.getVertex(2) && getVertex(5) == that.getVertex(4)) {
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
//setVertex(2, this.getVertex(2)); // no change
//setVertex(3, this.getVertex(3)); // no change
//setVertex(4, this.getVertex(4)); // no change
setVertex(5, that.getVertex(5));
return; // done
}
}
// NEAR/RIGHT/BOTTOM & NEAR/BOTTOM
if (
((that.getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR | PROJECTION_RIGHT )))
)
{
if (getVertex(2) == that.getVertex(1) && getVertex(4) == that.getVertex(5)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, this.getVertex(1)); // no change
setVertex(2, that.getVertex(2));
setVertex(3, that.getVertex(3));
setVertex(4, that.getVertex(4));
//setVertex(5, this.getVertex(5)); // no change
setProjectionType((PROJECTION_BOTTOM | PROJECTION_NEAR));
return; // done
}
}
// NEAR/LEFT/BOTTOM & NEAR/BOTTOM
if (
((getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR )) &&
(that.getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR | PROJECTION_LEFT )))
)
{
if (getVertex(2) == that.getVertex(0) && getVertex(4) == that.getVertex(4)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, this.getVertex(1)); // no change
setVertex(2, that.getVertex(1));
setVertex(3, that.getVertex(2));
setVertex(4, that.getVertex(3));
//setVertex(5, this.getVertex(5)); // no change
return; // done
}
}
// NEAR/LEFT/BOTTOM & NEAR/BOTTOM
if (
((that.getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR )) &&
(getProjectionType() == (PROJECTION_BOTTOM | PROJECTION_NEAR | PROJECTION_LEFT )))
)
{
if (getVertex(0) == that.getVertex(2) && getVertex(4) == that.getVertex(4)) {
// we need to do this in an unusual order, because otherwise we'd overwrite our own values
setVertex(4, getVertex(3));
setVertex(3, getVertex(2));
setVertex(2, getVertex(1));
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
setVertex(5, that.getVertex(5));
setProjectionType((PROJECTION_BOTTOM | PROJECTION_NEAR));
return; // done
}
}
// RIGHT/NEAR/BOTTOM
// RIGHT/NEAR/TOP
// LEFT/NEAR/BOTTOM
// LEFT/NEAR/TOP
if (
(getProjectionType() == that.getProjectionType()) &&
(
getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_BOTTOM ) ||
getProjectionType() == (PROJECTION_RIGHT | PROJECTION_NEAR | PROJECTION_TOP ) ||
getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_BOTTOM ) ||
getProjectionType() == (PROJECTION_LEFT | PROJECTION_NEAR | PROJECTION_TOP )
)
) {
if (getVertex(0) == that.getVertex(5) && getVertex(2) == that.getVertex(3)) {
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
setVertex(2, that.getVertex(2));
//setVertex(3, this.getVertex(3)); // no change
//setVertex(4, this.getVertex(4)); // no change
//setVertex(5, this.getVertex(5)); // no change
return; // done
}
if (getVertex(5) == that.getVertex(0) && getVertex(3) == that.getVertex(2)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, this.getVertex(1)); // no change
//setVertex(2, this.getVertex(2)); // no change
setVertex(3, that.getVertex(3));
setVertex(4, that.getVertex(4));
setVertex(5, that.getVertex(5));
return; // done
}
if (getVertex(2) == that.getVertex(1) && getVertex(4) == that.getVertex(5)) {
//setVertex(0, this.getVertex(0)); // no change
//setVertex(1, this.getVertex(1)); // no change
setVertex(2, that.getVertex(2));
setVertex(3, that.getVertex(3));
setVertex(4, that.getVertex(4));
//setVertex(5, this.getVertex(5)); // no change
return; // done
}
if (getVertex(1) == that.getVertex(2) && getVertex(5) == that.getVertex(4)) {
setVertex(0, that.getVertex(0));
setVertex(1, that.getVertex(1));
//setVertex(2, this.getVertex(2)); // no change
//setVertex(3, this.getVertex(3)); // no change
//setVertex(4, this.getVertex(4)); // no change
setVertex(5, that.getVertex(5));
return; // done
}
// if this.([1],[3]) == that.([0],[4]) then create polygon: this.[0], that.[1], that.[2], that.[3], this.[4], this.[5]
if (getVertex(1) == that.getVertex(0) && getVertex(3) == that.getVertex(4)) {
//setVertex(0, this.getVertex(0)); // no change
setVertex(1, that.getVertex(1));
setVertex(2, that.getVertex(2));
setVertex(3, that.getVertex(3));
//setVertex(4, this.getVertex(4)); // no change
//setVertex(5, this.getVertex(5)); // no change
return; // done
}
// if this.([0],[4]) == that.([1],[3]) then create polygon: that.[0], this.[1], this.[2], this.[3], that.[4], that.[5]
if (getVertex(0) == that.getVertex(1) && getVertex(4) == that.getVertex(3)) {
setVertex(0, that.getVertex(0));
//setVertex(1, this.getVertex(1)); // no change
//setVertex(2, this.getVertex(2)); // no change
//setVertex(3, this.getVertex(3)); // no change
setVertex(4, that.getVertex(4));
setVertex(5, that.getVertex(5));
return; // done
}
}
}