fixes to source files for code remove in regex replace

This commit is contained in:
Stephen Birarda 2014-04-09 10:16:56 -07:00
parent 86d236faef
commit 11c235a29e
2 changed files with 328 additions and 2 deletions

View file

@ -9,6 +9,41 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <cstring>
#include <QtCore/QDebug>
#include <SharedUtil.h>
#include "CoverageMap.h"
int CoverageMap::_mapCount = 0;
int CoverageMap::_checkMapRootCalls = 0;
int CoverageMap::_notAllInView = 0;
bool CoverageMap::wantDebugging = false;
const int MAX_POLYGONS_PER_REGION = 50;
const BoundingBox CoverageMap::ROOT_BOUNDING_BOX = BoundingBox(glm::vec2(-1.f,-1.f), glm::vec2(2.f,2.f));
// Coverage Map's polygon coordinates are from -1 to 1 in the following mapping to screen space.
//
// (0,0) (windowWidth, 0)
// -1,1 1,1
// +-----------------------+
// | | |
// | | |
// | -1,0 | |
// |-----------+-----------|
// | 0,0 |
// | | |
// | | |
// | | |
// +-----------------------+
// -1,-1 1,-1
// (0,windowHeight) (windowWidth,windowHeight)
//
// Choosing a minimum sized polygon. Since we know a typical window is approximately 1500 pixels wide
// then a pixel on our screen will be ~ 2.0/1500 or 0.0013 "units" wide, similarly pixels are typically
// about that tall as well. If we say that polygons should be at least 10x10 pixels to be considered "big enough"
@ -523,4 +558,4 @@ CoverageMapStorageResult CoverageRegion::checkRegion(OctreeProjectedPolygon* pol
}
}
return result;
}
}

View file

@ -9,6 +9,297 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <cstring>
#include <cmath>
#include "SharedUtil.h"
#include "GeometryUtil.h"
glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec3& start, const glm::vec3& end) {
// compute the projection of the point vector onto the segment vector
glm::vec3 segmentVector = end - start;
float lengthSquared = glm::dot(segmentVector, segmentVector);
if (lengthSquared < EPSILON) {
return start - point; // start and end the same
}
float proj = glm::dot(point - start, segmentVector) / lengthSquared;
if (proj <= 0.0f) { // closest to the start
return start - point;
} else if (proj >= 1.0f) { // closest to the end
return end - point;
} else { // closest to the middle
return start + segmentVector*proj - point;
}
}
// Computes the penetration between a point and a sphere (centered at the origin)
// if point is inside sphere: returns true and stores the result in 'penetration'
// (the vector that would move the point outside the sphere)
// otherwise returns false
bool findSpherePenetration(const glm::vec3& point, const glm::vec3& defaultDirection, float sphereRadius,
glm::vec3& penetration) {
float vectorLength = glm::length(point);
if (vectorLength < EPSILON) {
penetration = defaultDirection * sphereRadius;
return true;
}
float distance = vectorLength - sphereRadius;
if (distance < 0.0f) {
penetration = point * (-distance / vectorLength);
return true;
}
return false;
}
bool findSpherePointPenetration(const glm::vec3& sphereCenter, float sphereRadius,
const glm::vec3& point, glm::vec3& penetration) {
return findSpherePenetration(point - sphereCenter, glm::vec3(0.0f, -1.0f, 0.0f), sphereRadius, penetration);
}
bool findPointSpherePenetration(const glm::vec3& point, const glm::vec3& sphereCenter,
float sphereRadius, glm::vec3& penetration) {
return findSpherePenetration(sphereCenter - point, glm::vec3(0.0f, -1.0f, 0.0f), sphereRadius, penetration);
}
bool findSphereSpherePenetration(const glm::vec3& firstCenter, float firstRadius,
const glm::vec3& secondCenter, float secondRadius, glm::vec3& penetration) {
return findSpherePointPenetration(firstCenter, firstRadius + secondRadius, secondCenter, penetration);
}
bool findSphereSegmentPenetration(const glm::vec3& sphereCenter, float sphereRadius,
const glm::vec3& segmentStart, const glm::vec3& segmentEnd, glm::vec3& penetration) {
return findSpherePenetration(computeVectorFromPointToSegment(sphereCenter, segmentStart, segmentEnd),
glm::vec3(0.0f, -1.0f, 0.0f), sphereRadius, penetration);
}
bool findSphereCapsulePenetration(const glm::vec3& sphereCenter, float sphereRadius, const glm::vec3& capsuleStart,
const glm::vec3& capsuleEnd, float capsuleRadius, glm::vec3& penetration) {
return findSphereSegmentPenetration(sphereCenter, sphereRadius + capsuleRadius,
capsuleStart, capsuleEnd, penetration);
}
bool findPointCapsuleConePenetration(const glm::vec3& point, const glm::vec3& capsuleStart,
const glm::vec3& capsuleEnd, float startRadius, float endRadius, glm::vec3& penetration) {
// compute the projection of the point vector onto the segment vector
glm::vec3 segmentVector = capsuleEnd - capsuleStart;
float lengthSquared = glm::dot(segmentVector, segmentVector);
if (lengthSquared < EPSILON) { // start and end the same
return findPointSpherePenetration(point, capsuleStart,
glm::max(startRadius, endRadius), penetration);
}
float proj = glm::dot(point - capsuleStart, segmentVector) / lengthSquared;
if (proj <= 0.0f) { // closest to the start
return findPointSpherePenetration(point, capsuleStart, startRadius, penetration);
} else if (proj >= 1.0f) { // closest to the end
return findPointSpherePenetration(point, capsuleEnd, endRadius, penetration);
} else { // closest to the middle
return findPointSpherePenetration(point, capsuleStart + segmentVector * proj,
glm::mix(startRadius, endRadius, proj), penetration);
}
}
bool findSphereCapsuleConePenetration(const glm::vec3& sphereCenter,
float sphereRadius, const glm::vec3& capsuleStart, const glm::vec3& capsuleEnd,
float startRadius, float endRadius, glm::vec3& penetration) {
return findPointCapsuleConePenetration(sphereCenter, capsuleStart, capsuleEnd,
startRadius + sphereRadius, endRadius + sphereRadius, penetration);
}
bool findSpherePlanePenetration(const glm::vec3& sphereCenter, float sphereRadius,
const glm::vec4& plane, glm::vec3& penetration) {
float distance = glm::dot(plane, glm::vec4(sphereCenter, 1.0f)) - sphereRadius;
if (distance < 0.0f) {
penetration = glm::vec3(plane) * distance;
return true;
}
return false;
}
bool findSphereDiskPenetration(const glm::vec3& sphereCenter, float sphereRadius,
const glm::vec3& diskCenter, float diskRadius, float diskThickness, const glm::vec3& diskNormal,
glm::vec3& penetration) {
glm::vec3 localCenter = sphereCenter - diskCenter;
float axialDistance = glm::dot(localCenter, diskNormal);
if (std::fabs(axialDistance) < (sphereRadius + 0.5f * diskThickness)) {
// sphere hit the plane, but does it hit the disk?
// Note: this algorithm ignores edge hits.
glm::vec3 axialOffset = axialDistance * diskNormal;
if (glm::length(localCenter - axialOffset) < diskRadius) {
// yes, hit the disk
penetration = (std::fabs(axialDistance) - (sphereRadius + 0.5f * diskThickness) ) * diskNormal;
if (axialDistance < 0.f) {
// hit the backside of the disk, so negate penetration vector
penetration *= -1.f;
}
return true;
}
}
return false;
}
bool findCapsuleSpherePenetration(const glm::vec3& capsuleStart, const glm::vec3& capsuleEnd, float capsuleRadius,
const glm::vec3& sphereCenter, float sphereRadius, glm::vec3& penetration) {
if (findSphereCapsulePenetration(sphereCenter, sphereRadius,
capsuleStart, capsuleEnd, capsuleRadius, penetration)) {
penetration = -penetration;
return true;
}
return false;
}
bool findCapsulePlanePenetration(const glm::vec3& capsuleStart, const glm::vec3& capsuleEnd, float capsuleRadius,
const glm::vec4& plane, glm::vec3& penetration) {
float distance = glm::min(glm::dot(plane, glm::vec4(capsuleStart, 1.0f)),
glm::dot(plane, glm::vec4(capsuleEnd, 1.0f))) - capsuleRadius;
if (distance < 0.0f) {
penetration = glm::vec3(plane) * distance;
return true;
}
return false;
}
glm::vec3 addPenetrations(const glm::vec3& currentPenetration, const glm::vec3& newPenetration) {
// find the component of the new penetration in the direction of the current
float currentLength = glm::length(currentPenetration);
if (currentLength == 0.0f) {
return newPenetration;
}
glm::vec3 currentDirection = currentPenetration / currentLength;
float directionalComponent = glm::dot(newPenetration, currentDirection);
// if orthogonal or in the opposite direction, we can simply add
if (directionalComponent <= 0.0f) {
return currentPenetration + newPenetration;
}
// otherwise, we need to take the maximum component of current and new
return currentDirection * glm::max(directionalComponent, currentLength) +
newPenetration - (currentDirection * directionalComponent);
}
bool findRaySphereIntersection(const glm::vec3& origin, const glm::vec3& direction,
const glm::vec3& center, float radius, float& distance) {
glm::vec3 relativeOrigin = origin - center;
float c = glm::dot(relativeOrigin, relativeOrigin) - radius * radius;
if (c < 0.0f) {
distance = 0.0f;
return true; // starts inside the sphere
}
float b = glm::dot(direction, relativeOrigin);
float radicand = b * b - c;
if (radicand < 0.0f) {
return false; // doesn't hit the sphere
}
float t = -b - sqrtf(radicand);
if (t < 0.0f) {
return false; // doesn't hit the sphere
}
distance = t;
return true;
}
bool findRayCapsuleIntersection(const glm::vec3& origin, const glm::vec3& direction,
const glm::vec3& start, const glm::vec3& end, float radius, float& distance) {
if (start == end) {
return findRaySphereIntersection(origin, direction, start, radius, distance); // handle degenerate case
}
glm::vec3 relativeOrigin = origin - start;
glm::vec3 relativeEnd = end - start;
float capsuleLength = glm::length(relativeEnd);
relativeEnd /= capsuleLength;
float originProjection = glm::dot(relativeEnd, relativeOrigin);
glm::vec3 constant = relativeOrigin - relativeEnd * originProjection;
float c = glm::dot(constant, constant) - radius * radius;
if (c < 0.0f) { // starts inside cylinder
if (originProjection < 0.0f) { // below start
return findRaySphereIntersection(origin, direction, start, radius, distance);
} else if (originProjection > capsuleLength) { // above end
return findRaySphereIntersection(origin, direction, end, radius, distance);
} else { // between start and end
distance = 0.0f;
return true;
}
}
glm::vec3 coefficient = direction - relativeEnd * glm::dot(relativeEnd, direction);
float a = glm::dot(coefficient, coefficient);
if (a == 0.0f) {
return false; // parallel to enclosing cylinder
}
float b = 2.0f * glm::dot(constant, coefficient);
float radicand = b * b - 4.0f * a * c;
if (radicand < 0.0f) {
return false; // doesn't hit the enclosing cylinder
}
float t = (-b - sqrtf(radicand)) / (2.0f * a);
if (t < 0.0f) {
return false; // doesn't hit the enclosing cylinder
}
glm::vec3 intersection = relativeOrigin + direction * t;
float intersectionProjection = glm::dot(relativeEnd, intersection);
if (intersectionProjection < 0.0f) { // below start
return findRaySphereIntersection(origin, direction, start, radius, distance);
} else if (intersectionProjection > capsuleLength) { // above end
return findRaySphereIntersection(origin, direction, end, radius, distance);
}
distance = t; // between start and end
return true;
}
// Do line segments (r1p1.x, r1p1.y)--(r1p2.x, r1p2.y) and (r2p1.x, r2p1.y)--(r2p2.x, r2p2.y) intersect?
// from: http://ptspts.blogspot.com/2010/06/how-to-determine-if-two-line-segments.html
bool doLineSegmentsIntersect(glm::vec2 r1p1, glm::vec2 r1p2, glm::vec2 r2p1, glm::vec2 r2p2) {
int d1 = computeDirection(r2p1.x, r2p1.y, r2p2.x, r2p2.y, r1p1.x, r1p1.y);
int d2 = computeDirection(r2p1.x, r2p1.y, r2p2.x, r2p2.y, r1p2.x, r1p2.y);
int d3 = computeDirection(r1p1.x, r1p1.y, r1p2.x, r1p2.y, r2p1.x, r2p1.y);
int d4 = computeDirection(r1p1.x, r1p1.y, r1p2.x, r1p2.y, r2p2.x, r2p2.y);
return (((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0)) &&
((d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0))) ||
(d1 == 0 && isOnSegment(r2p1.x, r2p1.y, r2p2.x, r2p2.y, r1p1.x, r1p1.y)) ||
(d2 == 0 && isOnSegment(r2p1.x, r2p1.y, r2p2.x, r2p2.y, r1p2.x, r1p2.y)) ||
(d3 == 0 && isOnSegment(r1p1.x, r1p1.y, r1p2.x, r1p2.y, r2p1.x, r2p1.y)) ||
(d4 == 0 && isOnSegment(r1p1.x, r1p1.y, r1p2.x, r1p2.y, r2p2.x, r2p2.y));
}
bool isOnSegment(float xi, float yi, float xj, float yj, float xk, float yk) {
return (xi <= xk || xj <= xk) && (xk <= xi || xk <= xj) &&
(yi <= yk || yj <= yk) && (yk <= yi || yk <= yj);
}
int computeDirection(float xi, float yi, float xj, float yj, float xk, float yk) {
float a = (xk - xi) * (yj - yi);
float b = (xj - xi) * (yk - yi);
return a < b ? -1 : a > b ? 1 : 0;
}
//
// Polygon Clipping routines inspired by, pseudo code found here: http://www.cs.rit.edu/~icss571/clipTrans/PolyClipBack.html
//
// Coverage Map's polygon coordinates are from -1 to 1 in the following mapping to screen space.
//
// (0,0) (windowWidth, 0)
// -1,1 1,1
// +-----------------------+
// | | |
// | | |
// | -1,0 | |
// |-----------+-----------|
// | 0,0 |
// | | |
// | | |
// | | |
// +-----------------------+
// -1,-1 1,-1
// (0,windowHeight) (windowWidth,windowHeight)
//
const float PolygonClip::TOP_OF_CLIPPING_WINDOW = 1.0f;
const float PolygonClip::BOTTOM_OF_CLIPPING_WINDOW = -1.0f;
const float PolygonClip::LEFT_OF_CLIPPING_WINDOW = -1.0f;
@ -175,4 +466,4 @@ void PolygonClip::copyCleanArray(int& lengthA, glm::vec2* vertexArrayA, int& len
vertexArrayA[i] = vertexArrayB[i];
}
}
}
}