History

remove PlaneShape dependency from GeometryUtils

also add unit tests for indRayRectangleIntersection()

Andrew Meadows committed 11 years ago

Commit ef5e7e91 parent c7f367b3 files · +222 −20Browse files

Showing the changes to libraries/shared/src/GeometryUtil.cpp (1 of 3 files). Show all

Unified · Split

libraries/shared/src/GeometryUtil.cpp+34−20
@@ -11,10 +11,10 @@ · 10 unmodified lines
11 11
12#include <cstring>12#include <cstring>
13#include <cmath>13#include <cmath>
14#include <glm/gtx/quaternion.hpp>
14 15
15#include "GeometryUtil.h"16#include "GeometryUtil.h"
16#include "NumericalConstants.h"17#include "NumericalConstants.h"
17#include "PlaneShape.h"
18#include "RayIntersectionInfo.h"18#include "RayIntersectionInfo.h"
19 19
20glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec3& start, const glm::vec3& end) {20glm::vec3 computeVectorFromPointToSegment(const glm::vec3& point, const glm::vec3& start, const glm::vec3& end) {
@@ -496,31 +496,45 @@ void PolygonClip::copyCleanArray(int& lengthA, glm::vec2* vertexArrayA, int& len · 475 unmodified lines
496 496
497bool findRayRectangleIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::quat& rotation,497bool findRayRectangleIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::quat& rotation,
498 const glm::vec3& position, const glm::vec2& dimensions, float& distance) {498 const glm::vec3& position, const glm::vec2& dimensions, float& distance) {
499 RayIntersectionInfo rayInfo;
500 rayInfo._rayStart = origin;
501 rayInfo._rayDirection = direction;
502 rayInfo._rayLength = std::numeric_limits<float>::max();
503
504 PlaneShape plane;
505
506 const glm::vec3 UNROTATED_NORMAL(0.0f, 0.0f, -1.0f);499 const glm::vec3 UNROTATED_NORMAL(0.0f, 0.0f, -1.0f);
507 glm::vec3 normal = rotation * UNROTATED_NORMAL;500 glm::vec3 normal = rotation * UNROTATED_NORMAL;
508 plane.setNormal(normal);
509 plane.setPoint(position); // the position is definitely a point on our plane
510
511 bool intersects = plane.findRayIntersection(rayInfo);
512 501
513 if (intersects) {502 bool maybeIntersects = false;
514 distance = rayInfo._hitDistance;503 float denominator = glm::dot(normal, direction);
504 glm::vec3 offset = origin - position;
505 float normDotOffset = glm::dot(offset, normal);
506 float d = 0.0f;
507 if (fabsf(denominator) < EPSILON) {
508 // line is perpendicular to plane
509 if (fabsf(normDotOffset) < EPSILON) {
510 // ray starts on the plane
511 maybeIntersects = true;
512
513 // compute distance to closest approach
514 d = - glm::dot(offset, direction); // distance to closest approach of center of rectangle
515 if (d < 0.0f) {
516 // ray points away from center of rectangle, so ray's start is the closest approach
517 d = 0.0f;
518 }
519 }
520 } else {
521 d = - normDotOffset / denominator;
522 if (d > 0.0f) {
523 // ray points toward plane
524 maybeIntersects = true;
525 }
526 }
515 527
516 glm::vec3 hitPosition = origin + (distance * direction);528 if (maybeIntersects) {
529 glm::vec3 hitPosition = origin + (d * direction);
517 glm::vec3 localHitPosition = glm::inverse(rotation) * (hitPosition - position);530 glm::vec3 localHitPosition = glm::inverse(rotation) * (hitPosition - position);
518
519 glm::vec2 halfDimensions = 0.5f * dimensions;531 glm::vec2 halfDimensions = 0.5f * dimensions;
520 532 if (fabsf(localHitPosition.x) < halfDimensions.x && fabsf(localHitPosition.y) < halfDimensions.y) {
521 intersects = -halfDimensions.x <= localHitPosition.x && localHitPosition.x <= halfDimensions.x533 // only update distance on intersection
522 && -halfDimensions.y <= localHitPosition.y && localHitPosition.y <= halfDimensions.y;534 distance = d;
535 return true;
536 }
523 }537 }
524 538
525 return intersects;539 return false;
526}540}