mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:44:11 +02:00
fixes to source files for code remove in regex replace
This commit is contained in:
parent
86d236faef
commit
11c235a29e
2 changed files with 328 additions and 2 deletions
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue