More plane intersection bits.

This commit is contained in:
Andrzej Kapolka 2014-04-10 11:24:45 -07:00
parent f61c746b4a
commit a12dd916fa
3 changed files with 45 additions and 10 deletions

View file

@ -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);

View file

@ -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

View file

@ -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;
}