mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 11:48:09 +02:00
Adding ShapeColliderTests.*
This commit is contained in:
parent
8c1dc40d39
commit
0e28e0947c
6 changed files with 56 additions and 29 deletions
|
@ -34,6 +34,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Shape(Type type) : _type(type), _boundingRadius(0.f), _position(0.f), _rotation() {}
|
Shape(Type type) : _type(type), _boundingRadius(0.f), _position(0.f), _rotation() {}
|
||||||
|
|
||||||
Shape(Type type, const glm::vec3& position, const glm::quat& rotation)
|
Shape(Type type, const glm::vec3& position, const glm::quat& rotation)
|
||||||
: _type(type), _boundingRadius(0.f), _position(position), _rotation(rotation) {}
|
: _type(type), _boundingRadius(0.f), _position(position), _rotation(rotation) {}
|
||||||
|
|
||||||
|
|
|
@ -11,35 +11,35 @@
|
||||||
namespace ShapeCollider {
|
namespace ShapeCollider {
|
||||||
|
|
||||||
bool shapeShape(const Shape* shapeA, const Shape* shapeB,
|
bool shapeShape(const Shape* shapeA, const Shape* shapeB,
|
||||||
const glm::quat& rotationAB, const glm::vec3& offsetB, CollisionInfo& collision) {
|
const glm::quat& rotationAB, const glm::vec3& offsetA, CollisionInfo& collision) {
|
||||||
// ATM we only have two shape types so we just check every case.
|
// ATM we only have two shape types so we just check every case.
|
||||||
// TODO: make a fast lookup for correct method
|
// TODO: make a fast lookup for correct method
|
||||||
if (shapeA->getType() == Shape::SPHERE_SHAPE) {
|
if (shapeA->getType() == Shape::SPHERE_SHAPE) {
|
||||||
const SphereShape* sphereA = static_cast<const SphereShape*>(shapeA);
|
const SphereShape* sphereA = static_cast<const SphereShape*>(shapeA);
|
||||||
if (shapeB->getType() == Shape::SPHERE_SHAPE) {
|
if (shapeB->getType() == Shape::SPHERE_SHAPE) {
|
||||||
return sphereSphere(sphereA, static_cast<const SphereShape*>(shapeB),
|
return sphereSphere(sphereA, static_cast<const SphereShape*>(shapeB),
|
||||||
rotationAB, offsetB, collision);
|
rotationAB, offsetA, collision);
|
||||||
} else if (shapeB->getType() == Shape::CAPSULE_SHAPE) {
|
} else if (shapeB->getType() == Shape::CAPSULE_SHAPE) {
|
||||||
return sphereCapsule(sphereA, static_cast<const CapsuleShape*>(shapeB),
|
return sphereCapsule(sphereA, static_cast<const CapsuleShape*>(shapeB),
|
||||||
rotationAB, offsetB, collision);
|
rotationAB, offsetA, collision);
|
||||||
}
|
}
|
||||||
} else if (shapeA->getType() == Shape::CAPSULE_SHAPE) {
|
} else if (shapeA->getType() == Shape::CAPSULE_SHAPE) {
|
||||||
const CapsuleShape* capsuleA = static_cast<const CapsuleShape*>(shapeA);
|
const CapsuleShape* capsuleA = static_cast<const CapsuleShape*>(shapeA);
|
||||||
if (shapeB->getType() == Shape::SPHERE_SHAPE) {
|
if (shapeB->getType() == Shape::SPHERE_SHAPE) {
|
||||||
return capsuleSphere(capsuleA, static_cast<const SphereShape*>(shapeB),
|
return capsuleSphere(capsuleA, static_cast<const SphereShape*>(shapeB),
|
||||||
rotationAB, offsetB, collision);
|
rotationAB, offsetA, collision);
|
||||||
} else if (shapeB->getType() == Shape::CAPSULE_SHAPE) {
|
} else if (shapeB->getType() == Shape::CAPSULE_SHAPE) {
|
||||||
return capsuleCapsule(capsuleA, static_cast<const CapsuleShape*>(shapeB),
|
return capsuleCapsule(capsuleA, static_cast<const CapsuleShape*>(shapeB),
|
||||||
rotationAB, offsetB, collision);
|
rotationAB, offsetA, collision);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sphereSphere(const SphereShape* sphereA, const SphereShape* sphereB,
|
bool sphereSphere(const SphereShape* sphereA, const SphereShape* sphereB,
|
||||||
const glm::quat& rotationAB, const glm::vec3& offsetB, CollisionInfo& collision) {
|
const glm::quat& rotationAB, const glm::vec3& offsetA, CollisionInfo& collision) {
|
||||||
// A in B's frame
|
// A in B's frame
|
||||||
glm::vec3 A = offsetB + rotationAB * sphereA->getPosition();
|
glm::vec3 A = rotationAB * sphereA->getPosition() + offsetA;
|
||||||
// BA = B - A = from A to B, in B's frame
|
// BA = B - A = from A to B, in B's frame
|
||||||
glm::vec3 BA = sphereB->getPosition() - A;
|
glm::vec3 BA = sphereB->getPosition() - A;
|
||||||
float distanceSquared = glm::dot(BA, BA);
|
float distanceSquared = glm::dot(BA, BA);
|
||||||
|
@ -119,10 +119,10 @@ bool sphereCapsuleHelper(float sphereRadius, const glm::vec3 sphereCenter,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sphereCapsule(const SphereShape* sphereA, const CapsuleShape* capsuleB,
|
bool sphereCapsule(const SphereShape* sphereA, const CapsuleShape* capsuleB,
|
||||||
const glm::quat& rotationAB, const glm::vec3& offsetB, CollisionInfo& collision) {
|
const glm::quat& rotationAB, const glm::vec3& offsetA, CollisionInfo& collision) {
|
||||||
// transform sphereA all the way to capsuleB's natural frame
|
// transform sphereA all the way to capsuleB's natural frame
|
||||||
glm::quat rotationB = capsuleB->getRotation();
|
glm::quat rotationB = capsuleB->getRotation();
|
||||||
glm::vec3 sphereCenter = rotationB * (offsetB + rotationAB * sphereA->getPosition() - capsuleB->getPosition());
|
glm::vec3 sphereCenter = rotationB * (offsetA + rotationAB * sphereA->getPosition() - capsuleB->getPosition());
|
||||||
if (sphereCapsuleHelper(sphereA->getRadius(), sphereCenter, capsuleB, collision)) {
|
if (sphereCapsuleHelper(sphereA->getRadius(), sphereCenter, capsuleB, collision)) {
|
||||||
// need to transform collision details back into B's offset frame
|
// need to transform collision details back into B's offset frame
|
||||||
collision.rotateThenTranslate(glm::inverse(rotationB), capsuleB->getPosition());
|
collision.rotateThenTranslate(glm::inverse(rotationB), capsuleB->getPosition());
|
||||||
|
@ -132,24 +132,24 @@ bool sphereCapsule(const SphereShape* sphereA, const CapsuleShape* capsuleB,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool capsuleSphere(const CapsuleShape* capsuleA, const SphereShape* sphereB,
|
bool capsuleSphere(const CapsuleShape* capsuleA, const SphereShape* sphereB,
|
||||||
const glm::quat& rotationAB, const glm::vec3& offsetB, CollisionInfo& collision) {
|
const glm::quat& rotationAB, const glm::vec3& offsetA, CollisionInfo& collision) {
|
||||||
// transform sphereB all the way to capsuleA's natural frame
|
// transform sphereB all the way to capsuleA's natural frame
|
||||||
glm::quat rotationBA = glm::inverse(rotationAB);
|
glm::quat rotationBA = glm::inverse(rotationAB);
|
||||||
glm::quat rotationA = capsuleA->getRotation();
|
glm::quat rotationA = capsuleA->getRotation();
|
||||||
glm::vec3 offsetA = rotationBA * (-offsetB);
|
glm::vec3 offsetB = rotationBA * (-offsetA);
|
||||||
glm::vec3 sphereCenter = rotationA * (offsetA + rotationBA * sphereB->getPosition() - capsuleA->getPosition());
|
glm::vec3 sphereCenter = rotationA * (offsetB + rotationBA * sphereB->getPosition() - capsuleA->getPosition());
|
||||||
if (sphereCapsuleHelper(sphereB->getRadius(), sphereCenter, capsuleA, collision)) {
|
if (sphereCapsuleHelper(sphereB->getRadius(), sphereCenter, capsuleA, collision)) {
|
||||||
// need to transform collision details back into B's offset frame
|
// need to transform collision details back into B's offset frame
|
||||||
// BUG: these back translations are probably not right
|
// BUG: these back translations are probably not right
|
||||||
collision.rotateThenTranslate(glm::inverse(rotationA), capsuleA->getPosition());
|
collision.rotateThenTranslate(glm::inverse(rotationA), capsuleA->getPosition());
|
||||||
collision.rotateThenTranslate(glm::inverse(rotationAB), -offsetB);
|
collision.rotateThenTranslate(glm::inverse(rotationAB), -offsetA);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool capsuleCapsule(const CapsuleShape* capsuleA, const CapsuleShape* capsuleB,
|
bool capsuleCapsule(const CapsuleShape* capsuleA, const CapsuleShape* capsuleB,
|
||||||
const glm::quat& rotationAB, const glm::vec3& offsetB, CollisionInfo& collision) {
|
const glm::quat& rotationAB, const glm::vec3& offsetA, CollisionInfo& collision) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,47 +19,47 @@ namespace ShapeCollider {
|
||||||
/// \param shapeA pointer to first shape
|
/// \param shapeA pointer to first shape
|
||||||
/// \param shapeB pointer to second shape
|
/// \param shapeB pointer to second shape
|
||||||
/// \param rotationAB rotation from A into reference frame of B
|
/// \param rotationAB rotation from A into reference frame of B
|
||||||
/// \param offsetB offset of B (in B's frame)
|
/// \param offsetA offset of A (in B's frame)
|
||||||
/// \param[out] collision where to store collision details
|
/// \param[out] collision where to store collision details
|
||||||
/// \return true of shapes collide
|
/// \return true of shapes collide
|
||||||
bool shapeShape(const Shape* shapeA, const Shape* shapeB,
|
bool shapeShape(const Shape* shapeA, const Shape* shapeB,
|
||||||
const glm::quat& rotationAB, const glm::vec3& offsetB, CollisionInfo& collision);
|
const glm::quat& rotationAB, const glm::vec3& offsetA, CollisionInfo& collision);
|
||||||
|
|
||||||
/// \param sphereA pointer to first shape (sphere)
|
/// \param sphereA pointer to first shape (sphere)
|
||||||
/// \param sphereB pointer to second shape (sphere)
|
/// \param sphereB pointer to second shape (sphere)
|
||||||
/// \param rotationAB rotation from A into reference frame of B
|
/// \param rotationAB rotation from A into reference frame of B
|
||||||
/// \param offsetB offset of B (in B's frame)
|
/// \param offsetA offset of A (in B's frame)
|
||||||
/// \param[out] collision where to store collision details
|
/// \param[out] collision where to store collision details
|
||||||
/// \return true of shapes collide
|
/// \return true of shapes collide
|
||||||
bool sphereSphere(const SphereShape* sphereA, const SphereShape* sphereB,
|
bool sphereSphere(const SphereShape* sphereA, const SphereShape* sphereB,
|
||||||
const glm::quat& rotationAB, const glm::vec3& offsetB, CollisionInfo& collision);
|
const glm::quat& rotationAB, const glm::vec3& offsetA, CollisionInfo& collision);
|
||||||
|
|
||||||
/// \param sphereA pointer to first shape (sphere)
|
/// \param sphereA pointer to first shape (sphere)
|
||||||
/// \param capsuleB pointer to second shape (capsule)
|
/// \param capsuleB pointer to second shape (capsule)
|
||||||
/// \param rotationAB rotation from A into reference frame of B
|
/// \param rotationAB rotation from A into reference frame of B
|
||||||
/// \param offsetB offset of B (in B's frame)
|
/// \param offsetA offset of A (in B's frame)
|
||||||
/// \param[out] collision where to store collision details
|
/// \param[out] collision where to store collision details
|
||||||
/// \return true of shapes collide
|
/// \return true of shapes collide
|
||||||
bool sphereCapsule(const SphereShape* sphereA, const CapsuleShape* capsuleB,
|
bool sphereCapsule(const SphereShape* sphereA, const CapsuleShape* capsuleB,
|
||||||
const glm::quat& rotationAB, const glm::vec3& offsetB, CollisionInfo& collision);
|
const glm::quat& rotationAB, const glm::vec3& offsetA, CollisionInfo& collision);
|
||||||
|
|
||||||
/// \param capsuleA pointer to first shape (capsule)
|
/// \param capsuleA pointer to first shape (capsule)
|
||||||
/// \param sphereB pointer to second shape (sphere)
|
/// \param sphereB pointer to second shape (sphere)
|
||||||
/// \param rotationAB rotation from A into reference frame of B
|
/// \param rotationAB rotation from A into reference frame of B
|
||||||
/// \param offsetB offset of B (in B's frame)
|
/// \param offsetA offset of A (in B's frame)
|
||||||
/// \param[out] collision where to store collision details
|
/// \param[out] collision where to store collision details
|
||||||
/// \return true of shapes collide
|
/// \return true of shapes collide
|
||||||
bool capsuleSphere(const CapsuleShape* capsuleA, const SphereShape* sphereB,
|
bool capsuleSphere(const CapsuleShape* capsuleA, const SphereShape* sphereB,
|
||||||
const glm::quat& rotationAB, const glm::vec3& offsetB, CollisionInfo& collision);
|
const glm::quat& rotationAB, const glm::vec3& offsetA, CollisionInfo& collision);
|
||||||
|
|
||||||
/// \param capsuleA pointer to first shape (capsule)
|
/// \param capsuleA pointer to first shape (capsule)
|
||||||
/// \param capsuleB pointer to second shape (capsule)
|
/// \param capsuleB pointer to second shape (capsule)
|
||||||
/// \param rotationAB rotation from A into reference frame of B
|
/// \param rotationAB rotation from A into reference frame of B
|
||||||
/// \param offsetB offset of B (in B's frame)
|
/// \param offsetA offset of A (in B's frame)
|
||||||
/// \param[out] collision where to store collision details
|
/// \param[out] collision where to store collision details
|
||||||
/// \return true of shapes collide
|
/// \return true of shapes collide
|
||||||
bool capsuleCapsule(const CapsuleShape* capsuleA, const CapsuleShape* capsuleB,
|
bool capsuleCapsule(const CapsuleShape* capsuleA, const CapsuleShape* capsuleB,
|
||||||
const glm::quat& rotationAB, const glm::vec3& offsetB, CollisionInfo& collision);
|
const glm::quat& rotationAB, const glm::vec3& offsetA, CollisionInfo& collision);
|
||||||
|
|
||||||
} // namespace ShapeCollider
|
} // namespace ShapeCollider
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,11 @@ class SphereShape : public Shape {
|
||||||
public:
|
public:
|
||||||
SphereShape() : Shape(Shape::SPHERE_SHAPE) {}
|
SphereShape() : Shape(Shape::SPHERE_SHAPE) {}
|
||||||
|
|
||||||
|
SphereShape(float radius, const glm::vec3& position) : Shape(Shape::SPHERE_SHAPE) {
|
||||||
|
_boundingRadius = radius;
|
||||||
|
setPosition(position);
|
||||||
|
}
|
||||||
|
|
||||||
float getRadius() const { return _boundingRadius; }
|
float getRadius() const { return _boundingRadius; }
|
||||||
|
|
||||||
void setRadius(float radius) { _boundingRadius = radius; }
|
void setRadius(float radius) { _boundingRadius = radius; }
|
||||||
|
|
|
@ -13,21 +13,42 @@
|
||||||
#include <glm/gtx/quaternion.hpp>
|
#include <glm/gtx/quaternion.hpp>
|
||||||
|
|
||||||
#include <CollisionInfo.h>
|
#include <CollisionInfo.h>
|
||||||
|
#include <ShapeCollider.h>
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
|
#include <SphereShape.h>
|
||||||
|
|
||||||
#include "PhysicsTestUtil.h"
|
#include "PhysicsTestUtil.h"
|
||||||
#include "ShapeColliderTests.h"
|
#include "ShapeColliderTests.h"
|
||||||
|
|
||||||
|
const glm::vec3 origin(0.f);
|
||||||
|
|
||||||
/*
|
void ShapeColliderTests::sphereSphere() {
|
||||||
void ShapeColliderTests::test1() {
|
CollisionInfo collision;
|
||||||
|
|
||||||
|
float radius = 2.f;
|
||||||
|
SphereShape sphereA(radius, origin);
|
||||||
|
SphereShape sphereB(radius, origin);
|
||||||
|
|
||||||
|
glm::vec3 translation(0.5f * radius, 0.f, 0.f);
|
||||||
|
glm::quat rotation;
|
||||||
|
|
||||||
|
// these spheres should be touching
|
||||||
|
bool touching = ShapeCollider::sphereSphere(&sphereA, &sphereB, rotation, translation, collision);
|
||||||
|
if (!touching) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__
|
||||||
|
<< " ERROR: sphereA and sphereB do not touch" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: verify the collision info is good...
|
||||||
|
// penetration should point from A into B
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
void ShapeColliderTests::test2() {
|
void ShapeColliderTests::test2() {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void ShapeColliderTests::runAllTests() {
|
void ShapeColliderTests::runAllTests() {
|
||||||
// ShapeColliderTests::test1();
|
ShapeColliderTests::sphereSphere();
|
||||||
// ShapeColliderTests::test2();
|
// ShapeColliderTests::test2();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
|
|
||||||
namespace ShapeColliderTests {
|
namespace ShapeColliderTests {
|
||||||
|
|
||||||
//void rotateThenTranslate();
|
void sphereSphere();
|
||||||
//void translateThenRotate();
|
//void test2();
|
||||||
|
|
||||||
void runAllTests();
|
void runAllTests();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue