From a12dd916fafe29cdc532c267af84e169c1392ab0 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 10 Apr 2014 11:24:45 -0700 Subject: [PATCH] More plane intersection bits. --- interface/src/renderer/Model.cpp | 2 +- libraries/shared/src/PlaneShape.h | 10 ++---- libraries/shared/src/ShapeCollider.cpp | 43 +++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index a317ddc07a..2d47a077b7 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -638,7 +638,7 @@ bool Model::findPlaneCollisions(const glm::vec4& plane, CollisionList& collision bool collided = false; PlaneShape planeShape(plane); for (int i = 0; i < _jointShapes.size(); i++) { - if (ShapeCollider::shapeShape(&planeShape, _jointShapes[i], collisions)) { + if (ShapeCollider::collideShapes(&planeShape, _jointShapes[i], collisions)) { CollisionInfo* collision = collisions.getLastCollision(); collision->_type = MODEL_COLLISION; collision->_data = (void*)(this); diff --git a/libraries/shared/src/PlaneShape.h b/libraries/shared/src/PlaneShape.h index 11823da701..524d53ec73 100644 --- a/libraries/shared/src/PlaneShape.h +++ b/libraries/shared/src/PlaneShape.h @@ -16,15 +16,9 @@ class PlaneShape : public Shape { public: - PlaneShape() : Shape(Shape::PLANE_SHAPE) {} - - PlaneShape(const glm::vec4& coefficients) : Shape(Shape::PLANE_SHAPE), _coefficients(coefficients) { } + PlaneShape(const glm::vec4& coefficients = glm::vec4(0.0f, 1.0f, 0.0f, 0.0f)); - const glm::vec4& getCoefficients() const { return _coefficients; } - -private: - - glm::vec4 _coefficients; + glm::vec4 getCoefficients() const; }; #endif // hifi_PlaneShape_h diff --git a/libraries/shared/src/ShapeCollider.cpp b/libraries/shared/src/ShapeCollider.cpp index 10211f1d78..c53c7fab7d 100644 --- a/libraries/shared/src/ShapeCollider.cpp +++ b/libraries/shared/src/ShapeCollider.cpp @@ -191,7 +191,7 @@ bool spherePlane(const SphereShape* sphereA, const PlaneShape* planeB, Collision return false; // collision list is full } collision->_penetration = penetration; - collision->_contactPoint = glm::vec3(); + collision->_contactPoint = sphereA->getPosition() + sphereA->getRadius() * glm::normalize(penetration); return true; } return false; @@ -404,18 +404,59 @@ bool capsuleCapsule(const CapsuleShape* capsuleA, const CapsuleShape* capsuleB, } bool capsulePlane(const CapsuleShape* capsuleA, const PlaneShape* planeB, CollisionList& collisions) { + glm::vec3 start, end, penetration; + capsuleA->getStartPoint(start); + capsuleA->getEndPoint(end); + glm::vec4 plane = planeB->getCoefficients(); + if (findCapsulePlanePenetration(start, end, capsuleA->getRadius(), plane, penetration)) { + CollisionInfo* collision = collisions.getNewCollision(); + if (!collision) { + return false; // collision list is full + } + collision->_penetration = penetration; + glm::vec3 deepestEnd = (glm::dot(start, glm::vec3(plane)) < glm::dot(end, glm::vec3(plane))) ? start : end; + collision->_contactPoint = deepestEnd + capsuleA->getRadius() * glm::normalize(penetration); + return true; + } return false; } bool planeSphere(const PlaneShape* planeA, const SphereShape* sphereB, CollisionList& collisions) { + glm::vec3 penetration; + if (findSpherePlanePenetration(sphereB->getPosition(), sphereB->getRadius(), planeA->getCoefficients(), penetration)) { + CollisionInfo* collision = collisions.getNewCollision(); + if (!collision) { + return false; // collision list is full + } + collision->_penetration = -penetration; + collision->_contactPoint = sphereB->getPosition() + + (sphereB->getRadius() / glm::length(penetration) - 1.0f) * penetration; + return true; + } return false; } bool planeCapsule(const PlaneShape* planeA, const CapsuleShape* capsuleB, CollisionList& collisions) { + glm::vec3 start, end, penetration; + capsuleB->getStartPoint(start); + capsuleB->getEndPoint(end); + glm::vec4 plane = planeA->getCoefficients(); + if (findCapsulePlanePenetration(start, end, capsuleB->getRadius(), plane, penetration)) { + CollisionInfo* collision = collisions.getNewCollision(); + if (!collision) { + return false; // collision list is full + } + collision->_penetration = -penetration; + glm::vec3 deepestEnd = (glm::dot(start, glm::vec3(plane)) < glm::dot(end, glm::vec3(plane))) ? start : end; + collision->_contactPoint = deepestEnd + (capsuleB->getRadius() / glm::length(penetration) - 1.0f) * penetration; + return true; + } return false; } bool planePlane(const PlaneShape* planeA, const PlaneShape* planeB, CollisionList& collisions) { + // technically, planes always collide unless they're parallel and not coincident; however, that's + // not going to give us any useful information return false; }