ListShape now handled by ShapeCollider

This commit is contained in:
Andrew Meadows 2014-02-26 15:36:19 -08:00
parent 07eb366138
commit 5954bb91d4
6 changed files with 105 additions and 24 deletions

View file

@ -396,10 +396,9 @@ bool Avatar::findRayIntersection(const glm::vec3& origin, const glm::vec3& direc
bool Avatar::findSphereCollisions(const glm::vec3& penetratorCenter, float penetratorRadius,
CollisionList& collisions, int skeletonSkipIndex) {
// Temporarily disabling collisions against the skeleton because the collision proxies up
// near the neck are bad and prevent the hand from hitting the face.
//return _skeletonModel.findSphereCollisions(penetratorCenter, penetratorRadius, collisions, 1.0f, skeletonSkipIndex);
return getHead()->getFaceModel().findSphereCollisions(penetratorCenter, penetratorRadius, collisions);
return _skeletonModel.findSphereCollisions(penetratorCenter, penetratorRadius, collisions, 1.0f, skeletonSkipIndex);
// Temporarily disabling collisions against the head because most of its collision proxies are bad.
//return getHead()->getFaceModel().findSphereCollisions(penetratorCenter, penetratorRadius, collisions);
}
bool Avatar::findParticleCollisions(const glm::vec3& particleCenter, float particleRadius, CollisionList& collisions) {

View file

@ -80,6 +80,9 @@ public:
/// \return pointer to collision by index. NULL if index out of bounds.
CollisionInfo* getCollision(int index);
/// \return true if list is full
bool isFull() const { return _size == _maxSize; }
/// \return number of valid collisions
int size() const { return _size; }

View file

@ -32,6 +32,13 @@ void ListShape::setRotation(const glm::quat& rotation) {
Shape::setRotation(rotation);
}
const Shape* ListShape::getSubShape(int index) const {
if (index < 0 || index > _subShapeEntries.size()) {
return NULL;
}
return _subShapeEntries[index]._shape;
}
void ListShape::updateSubTransforms() {
if (_subShapeTransformsAreDirty) {
for (int i = 0; i < _subShapeEntries.size(); ++i) {

View file

@ -41,16 +41,16 @@ public:
void setPosition(const glm::vec3& position);
void setRotation(const glm::quat& rotation);
const Shape* getSubShape(int index) const;
void updateSubTransforms();
int size() { return _subShapeEntries.size(); }
int size() const { return _subShapeEntries.size(); }
void addShape(Shape* shape, const glm::vec3& localPosition, const glm::quat& localRotation);
void setShapes(QVector<ListShapeEntry>& shapes);
//const QVector<ListShapeEntry>& getSubShapes() { return _subShapeEntries; }
protected:
void clear();
void computeBoundingRadius();

View file

@ -12,6 +12,11 @@
#include "ShapeCollider.h"
// NOTE:
//
// * Large ListShape's are inefficient keep the lists short.
// * Collisions between lists of lists do not work.
namespace ShapeCollider {
bool shapeShape(const Shape* shapeA, const Shape* shapeB, CollisionList& collisions) {
@ -334,16 +339,71 @@ bool capsuleCapsule(const CapsuleShape* capsuleA, const CapsuleShape* capsuleB,
return false;
}
bool sphereList(const SphereShape* sphereA, const ListShape* listB, CollisionList& collisions) {
bool touching = false;
for (int i = 0; i < listB->size() && !collisions.isFull(); ++i) {
const Shape* subShape = listB->getSubShape(i);
int subType = subShape->getType();
if (subType == Shape::SPHERE_SHAPE) {
touching = sphereSphere(sphereA, static_cast<const SphereShape*>(subShape), collisions) || touching;
} else if (subType == Shape::CAPSULE_SHAPE) {
touching = sphereCapsule(sphereA, static_cast<const CapsuleShape*>(subShape), collisions) || touching;
}
}
return touching;
}
bool capsuleList(const CapsuleShape* capsuleA, const ListShape* listB, CollisionList& collisions) {
bool touching = false;
for (int i = 0; i < listB->size() && !collisions.isFull(); ++i) {
const Shape* subShape = listB->getSubShape(i);
int subType = subShape->getType();
if (subType == Shape::SPHERE_SHAPE) {
touching = capsuleSphere(capsuleA, static_cast<const SphereShape*>(subShape), collisions) || touching;
} else if (subType == Shape::CAPSULE_SHAPE) {
touching = capsuleCapsule(capsuleA, static_cast<const CapsuleShape*>(subShape), collisions) || touching;
}
}
return touching;
}
bool listSphere(const ListShape* listA, const SphereShape* sphereB, CollisionList& collisions) {
return false;
bool touching = false;
for (int i = 0; i < listA->size() && !collisions.isFull(); ++i) {
const Shape* subShape = listA->getSubShape(i);
int subType = subShape->getType();
if (subType == Shape::SPHERE_SHAPE) {
touching = sphereSphere(static_cast<const SphereShape*>(subShape), sphereB, collisions) || touching;
} else if (subType == Shape::CAPSULE_SHAPE) {
touching = capsuleSphere(static_cast<const CapsuleShape*>(subShape), sphereB, collisions) || touching;
}
}
return touching;
}
bool listCapsule(const ListShape* listA, const CapsuleShape* capsuleB, CollisionList& collisions) {
return false;
bool touching = false;
for (int i = 0; i < listA->size() && !collisions.isFull(); ++i) {
const Shape* subShape = listA->getSubShape(i);
int subType = subShape->getType();
if (subType == Shape::SPHERE_SHAPE) {
touching = sphereCapsule(static_cast<const SphereShape*>(subShape), capsuleB, collisions) || touching;
} else if (subType == Shape::CAPSULE_SHAPE) {
touching = capsuleCapsule(static_cast<const CapsuleShape*>(subShape), capsuleB, collisions) || touching;
}
}
return touching;
}
bool listList(const ListShape* listA, const ListShape* listB, CollisionList& collisions) {
return false;
bool touching = false;
for (int i = 0; i < listA->size() && !collisions.isFull(); ++i) {
const Shape* subShape = listA->getSubShape(i);
for (int j = 0; j < listB->size() && !collisions.isFull(); ++j) {
touching = shapeShape(subShape, listB->getSubShape(j), collisions) || touching;
}
}
return touching;
}
} // namespace ShapeCollider

View file

@ -23,44 +23,56 @@ namespace ShapeCollider {
/// \return true if shapes collide
bool shapeShape(const Shape* shapeA, const Shape* shapeB, CollisionList& collisions);
/// \param sphereA pointer to first shape (sphere)
/// \param sphereB pointer to second shape (sphere)
/// \param sphereA pointer to first shape
/// \param sphereB pointer to second shape
/// \param[out] collisions where to append collision details
/// \return true if shapes collide
bool sphereSphere(const SphereShape* sphereA, const SphereShape* sphereB, CollisionList& collisions);
/// \param sphereA pointer to first shape (sphere)
/// \param capsuleB pointer to second shape (capsule)
/// \param sphereA pointer to first shape
/// \param capsuleB pointer to second shape
/// \param[out] collisions where to append collision details
/// \return true if shapes collide
bool sphereCapsule(const SphereShape* sphereA, const CapsuleShape* capsuleB, CollisionList& collisions);
/// \param capsuleA pointer to first shape (capsule)
/// \param sphereB pointer to second shape (sphere)
/// \param capsuleA pointer to first shape
/// \param sphereB pointer to second shape
/// \param[out] collisions where to append collision details
/// \return true if shapes collide
bool capsuleSphere(const CapsuleShape* capsuleA, const SphereShape* sphereB, CollisionList& collisions);
/// \param capsuleA pointer to first shape (capsule)
/// \param capsuleB pointer to second shape (capsule)
/// \param capsuleA pointer to first shape
/// \param capsuleB pointer to second shape
/// \param[out] collisions where to append collision details
/// \return true if shapes collide
bool capsuleCapsule(const CapsuleShape* capsuleA, const CapsuleShape* capsuleB, CollisionList& collisions);
/// \param listA pointer to first shape (list)
/// \param sphereB pointer to second shape (sphere)
/// \param sphereA pointer to first shape
/// \param listB pointer to second shape
/// \param[out] collisions where to append collision details
/// \return true if shapes collide
bool sphereList(const SphereShape* sphereA, const ListShape* listB, CollisionList& collisions);
/// \param capuleA pointer to first shape
/// \param listB pointer to second shape
/// \param[out] collisions where to append collision details
/// \return true if shapes collide
bool capsuleList(const CapsuleShape* capsuleA, const ListShape* listB, CollisionList& collisions);
/// \param listA pointer to first shape
/// \param sphereB pointer to second shape
/// \param[out] collisions where to append collision details
/// \return true if shapes collide
bool listSphere(const ListShape* listA, const SphereShape* sphereB, CollisionList& collisions);
/// \param listA pointer to first shape (list)
/// \param capsuleB pointer to second shape (capsule)
/// \param listA pointer to first shape
/// \param capsuleB pointer to second shape
/// \param[out] collisions where to append collision details
/// \return true if shapes collide
bool listCapsule(const ListShape* listA, const CapsuleShape* capsuleB, CollisionList& collisions);
/// \param listA pointer to first shape (list)
/// \param capsuleB pointer to second shape (capsule)
/// \param listA pointer to first shape
/// \param capsuleB pointer to second shape
/// \param[out] collisions where to append collision details
/// \return true if shapes collide
bool listList(const ListShape* listA, const ListShape* listB, CollisionList& collisions);