Add collision and raycast filtering using bits mask
This commit is contained in:
parent
aae4da54d0
commit
c15b83db4a
|
@ -171,9 +171,12 @@ void CollisionDetection::computeNarrowPhase() {
|
|||
|
||||
assert(shape1->mBroadPhaseID != shape2->mBroadPhaseID);
|
||||
|
||||
// Check that the two shapes are overlapping. If the shapes are not overlapping
|
||||
// anymore, we remove the overlapping pair.
|
||||
if (!mBroadPhaseAlgorithm.testOverlappingShapes(shape1, shape2)) {
|
||||
// Check if the collision filtering allows collision between the two shapes and
|
||||
// that the two shapes are still overlapping. Otherwise, we destroy the
|
||||
// overlapping pair
|
||||
if (((shape1->getCollideWithMaskBits() & shape2->getCollisionCategoryBits()) == 0 ||
|
||||
(shape1->getCollisionCategoryBits() & shape2->getCollideWithMaskBits()) == 0) ||
|
||||
!mBroadPhaseAlgorithm.testOverlappingShapes(shape1, shape2)) {
|
||||
|
||||
std::map<overlappingpairid, OverlappingPair*>::iterator itToRemove = it;
|
||||
++it;
|
||||
|
@ -252,12 +255,6 @@ void CollisionDetection::computeNarrowPhaseBetweenShapes(CollisionCallback* call
|
|||
|
||||
assert(shape1->mBroadPhaseID != shape2->mBroadPhaseID);
|
||||
|
||||
bool test1 = shapes1.count(shape1->mBroadPhaseID) == 0;
|
||||
bool test2 = shapes2.count(shape2->mBroadPhaseID) == 0;
|
||||
bool test3 = shapes1.count(shape2->mBroadPhaseID) == 0;
|
||||
bool test4 = shapes2.count(shape1->mBroadPhaseID) == 0;
|
||||
bool test5 = !shapes1.empty() && !shapes2.empty();
|
||||
|
||||
// If both shapes1 and shapes2 sets are non-empty, we check that
|
||||
// shape1 is among on set and shape2 is among the other one
|
||||
if (!shapes1.empty() && !shapes2.empty() &&
|
||||
|
@ -279,9 +276,12 @@ void CollisionDetection::computeNarrowPhaseBetweenShapes(CollisionCallback* call
|
|||
continue;
|
||||
}
|
||||
|
||||
// Check that the two shapes are overlapping. If the shapes are not overlapping
|
||||
// anymore, we remove the overlapping pair.
|
||||
if (!mBroadPhaseAlgorithm.testOverlappingShapes(shape1, shape2)) {
|
||||
// Check if the collision filtering allows collision between the two shapes and
|
||||
// that the two shapes are still overlapping. Otherwise, we destroy the
|
||||
// overlapping pair
|
||||
if (((shape1->getCollideWithMaskBits() & shape2->getCollisionCategoryBits()) == 0 ||
|
||||
(shape1->getCollisionCategoryBits() & shape2->getCollideWithMaskBits()) == 0) ||
|
||||
!mBroadPhaseAlgorithm.testOverlappingShapes(shape1, shape2)) {
|
||||
|
||||
std::map<overlappingpairid, OverlappingPair*>::iterator itToRemove = it;
|
||||
++it;
|
||||
|
@ -345,6 +345,10 @@ void CollisionDetection::broadPhaseNotifyOverlappingPair(ProxyShape* shape1, Pro
|
|||
// If the two proxy collision shapes are from the same body, skip it
|
||||
if (shape1->getBody()->getID() == shape2->getBody()->getID()) return;
|
||||
|
||||
// Check if the collision filtering allows collision between the two shapes
|
||||
if ((shape1->getCollideWithMaskBits() & shape2->getCollisionCategoryBits()) == 0 ||
|
||||
(shape1->getCollisionCategoryBits() & shape2->getCollideWithMaskBits()) == 0) return;
|
||||
|
||||
// Compute the overlapping pair ID
|
||||
overlappingpairid pairID = OverlappingPair::computeID(shape1, shape2);
|
||||
|
||||
|
@ -358,6 +362,10 @@ void CollisionDetection::broadPhaseNotifyOverlappingPair(ProxyShape* shape1, Pro
|
|||
std::pair<map<overlappingpairid, OverlappingPair*>::iterator, bool> check =
|
||||
mOverlappingPairs.insert(make_pair(pairID, newPair));
|
||||
assert(check.second);
|
||||
|
||||
// Wake up the two bodies
|
||||
shape1->getBody()->setIsSleeping(false);
|
||||
shape2->getBody()->setIsSleeping(false);
|
||||
}
|
||||
|
||||
// Remove a body from the collision detection
|
||||
|
|
|
@ -153,7 +153,8 @@ class CollisionDetection {
|
|||
const std::set<uint>& shapes2) ;
|
||||
|
||||
/// Ray casting method
|
||||
void raycast(RaycastCallback* raycastCallback, const Ray& ray) const;
|
||||
void raycast(RaycastCallback* raycastCallback, const Ray& ray,
|
||||
unsigned short raycastWithCategoryMaskBits) const;
|
||||
|
||||
/// Test if the AABBs of two bodies overlap
|
||||
bool testAABBOverlap(const CollisionBody* body1,
|
||||
|
@ -228,13 +229,14 @@ inline void CollisionDetection::updateProxyCollisionShape(ProxyShape* shape, con
|
|||
|
||||
// Ray casting method
|
||||
inline void CollisionDetection::raycast(RaycastCallback* raycastCallback,
|
||||
const Ray& ray) const {
|
||||
const Ray& ray,
|
||||
unsigned short raycastWithCategoryMaskBits) const {
|
||||
|
||||
RaycastTest rayCastTest(raycastCallback);
|
||||
|
||||
// Ask the broad-phase algorithm to call the testRaycastAgainstShape()
|
||||
// callback method for each proxy shape hit by the ray in the broad-phase
|
||||
mBroadPhaseAlgorithm.raycast(ray, rayCastTest);
|
||||
mBroadPhaseAlgorithm.raycast(ray, rayCastTest, raycastWithCategoryMaskBits);
|
||||
}
|
||||
|
||||
// Test if the AABBs of two proxy shapes overlap
|
||||
|
|
|
@ -8,7 +8,8 @@ using namespace reactphysics3d;
|
|||
ProxyShape::ProxyShape(CollisionBody* body, CollisionShape* shape, const Transform& transform,
|
||||
decimal mass)
|
||||
:mBody(body), mCollisionShape(shape), mLocalToBodyTransform(transform), mMass(mass),
|
||||
mNext(NULL), mBroadPhaseID(-1), mCachedCollisionData(NULL), mUserData(NULL) {
|
||||
mNext(NULL), mBroadPhaseID(-1), mCachedCollisionData(NULL), mUserData(NULL),
|
||||
mCollisionCategoryBits(0x0001), mCollideWithMaskBits(0xFFFF) {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,19 @@ class ProxyShape {
|
|||
/// Pointer to user data
|
||||
void* mUserData;
|
||||
|
||||
/// Bits used to define the collision category of this shape.
|
||||
/// You can set a single bit to one to define a category value for this
|
||||
/// shape. This value is one (0x0001) by default. This variable can be used
|
||||
/// together with the mCollideWithMaskBits variable so that given
|
||||
/// categories of shapes collide with each other and do not collide with
|
||||
/// other categories.
|
||||
unsigned short mCollisionCategoryBits;
|
||||
|
||||
/// Bits mask used to state which collision categories this shape can
|
||||
/// collide with. This value is 0xFFFF by default. It means that this
|
||||
/// proxy shape will collide with every collision categories by default.
|
||||
unsigned short mCollideWithMaskBits;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Private copy-constructor
|
||||
|
@ -108,6 +121,18 @@ class ProxyShape {
|
|||
/// Raycast method with feedback information
|
||||
bool raycast(const Ray& ray, RaycastInfo& raycastInfo);
|
||||
|
||||
/// Return the collision category bits
|
||||
unsigned short getCollisionCategoryBits() const;
|
||||
|
||||
/// Set the collision category bits
|
||||
void setCollisionCategoryBits(unsigned short collisionCategoryBits);
|
||||
|
||||
/// Return the collision bits mask
|
||||
unsigned short getCollideWithMaskBits() const;
|
||||
|
||||
/// Set the collision bits mask
|
||||
void setCollideWithMaskBits(unsigned short collideWithMaskBits);
|
||||
|
||||
// -------------------- Friendship -------------------- //
|
||||
|
||||
friend class OverlappingPair;
|
||||
|
@ -192,6 +217,26 @@ inline const ProxyShape* ProxyShape::getNext() const {
|
|||
return mNext;
|
||||
}
|
||||
|
||||
// Return the collision category bits
|
||||
inline unsigned short ProxyShape::getCollisionCategoryBits() const {
|
||||
return mCollisionCategoryBits;
|
||||
}
|
||||
|
||||
// Set the collision category bits
|
||||
inline void ProxyShape::setCollisionCategoryBits(unsigned short collisionCategoryBits) {
|
||||
mCollisionCategoryBits = collisionCategoryBits;
|
||||
}
|
||||
|
||||
// Return the collision bits mask
|
||||
inline unsigned short ProxyShape::getCollideWithMaskBits() const {
|
||||
return mCollideWithMaskBits;
|
||||
}
|
||||
|
||||
// Set the collision bits mask
|
||||
inline void ProxyShape::setCollideWithMaskBits(unsigned short collideWithMaskBits) {
|
||||
mCollideWithMaskBits = collideWithMaskBits;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -159,7 +159,8 @@ class BroadPhaseAlgorithm {
|
|||
bool testOverlappingShapes(const ProxyShape* shape1, const ProxyShape* shape2) const;
|
||||
|
||||
/// Ray casting method
|
||||
void raycast(const Ray& ray, RaycastTest& raycastTest) const;
|
||||
void raycast(const Ray& ray, RaycastTest& raycastTest,
|
||||
unsigned short raycastWithCategoryMaskBits) const;
|
||||
};
|
||||
|
||||
// Method used to compare two pairs for sorting algorithm
|
||||
|
@ -185,8 +186,9 @@ inline bool BroadPhaseAlgorithm::testOverlappingShapes(const ProxyShape* shape1,
|
|||
|
||||
// Ray casting method
|
||||
inline void BroadPhaseAlgorithm::raycast(const Ray& ray,
|
||||
RaycastTest& raycastTest) const {
|
||||
mDynamicAABBTree.raycast(ray, raycastTest);
|
||||
RaycastTest& raycastTest,
|
||||
unsigned short raycastWithCategoryMaskBits) const {
|
||||
mDynamicAABBTree.raycast(ray, raycastTest, raycastWithCategoryMaskBits);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -606,7 +606,8 @@ void DynamicAABBTree::reportAllShapesOverlappingWith(int nodeID, const AABB& aab
|
|||
}
|
||||
|
||||
// Ray casting method
|
||||
void DynamicAABBTree::raycast(const Ray& ray, RaycastTest& raycastTest) const {
|
||||
void DynamicAABBTree::raycast(const Ray& ray, RaycastTest& raycastTest,
|
||||
unsigned short raycastWithCategoryMaskBits) const {
|
||||
|
||||
decimal maxFraction = ray.maxFraction;
|
||||
|
||||
|
@ -638,35 +639,39 @@ void DynamicAABBTree::raycast(const Ray& ray, RaycastTest& raycastTest) const {
|
|||
// If the node is a leaf of the tree
|
||||
if (node->isLeaf()) {
|
||||
|
||||
Ray rayTemp(ray.point1, ray.point2, maxFraction);
|
||||
// Check if the raycast filtering mask allows raycast against this shape
|
||||
if ((raycastWithCategoryMaskBits & node->proxyShape->getCollisionCategoryBits()) != 0) {
|
||||
|
||||
// Ask the collision detection to perform a ray cast test against
|
||||
// the proxy shape of this node because the ray is overlapping
|
||||
// with the shape in the broad-phase
|
||||
decimal hitFraction = raycastTest.raycastAgainstShape(node->proxyShape,
|
||||
rayTemp);
|
||||
Ray rayTemp(ray.point1, ray.point2, maxFraction);
|
||||
|
||||
// If the user returned a hitFraction of zero, it means that
|
||||
// the raycasting should stop here
|
||||
if (hitFraction == decimal(0.0)) {
|
||||
return;
|
||||
}
|
||||
// Ask the collision detection to perform a ray cast test against
|
||||
// the proxy shape of this node because the ray is overlapping
|
||||
// with the shape in the broad-phase
|
||||
decimal hitFraction = raycastTest.raycastAgainstShape(node->proxyShape,
|
||||
rayTemp);
|
||||
|
||||
// If the user returned a positive fraction
|
||||
if (hitFraction > decimal(0.0)) {
|
||||
|
||||
// We update the maxFraction value and the ray
|
||||
// AABB using the new maximum fraction
|
||||
if (hitFraction < maxFraction) {
|
||||
maxFraction = hitFraction;
|
||||
// If the user returned a hitFraction of zero, it means that
|
||||
// the raycasting should stop here
|
||||
if (hitFraction == decimal(0.0)) {
|
||||
return;
|
||||
}
|
||||
endPoint = ray.point1 + maxFraction * (ray.point2 - ray.point1);
|
||||
rayAABB.mMinCoordinates = Vector3::min(ray.point1, endPoint);
|
||||
rayAABB.mMaxCoordinates = Vector3::max(ray.point1, endPoint);
|
||||
}
|
||||
|
||||
// If the user returned a negative fraction, we continue
|
||||
// the raycasting as if the proxy shape did not exist
|
||||
// If the user returned a positive fraction
|
||||
if (hitFraction > decimal(0.0)) {
|
||||
|
||||
// We update the maxFraction value and the ray
|
||||
// AABB using the new maximum fraction
|
||||
if (hitFraction < maxFraction) {
|
||||
maxFraction = hitFraction;
|
||||
}
|
||||
endPoint = ray.point1 + maxFraction * (ray.point2 - ray.point1);
|
||||
rayAABB.mMinCoordinates = Vector3::min(ray.point1, endPoint);
|
||||
rayAABB.mMaxCoordinates = Vector3::max(ray.point1, endPoint);
|
||||
}
|
||||
|
||||
// If the user returned a negative fraction, we continue
|
||||
// the raycasting as if the proxy shape did not exist
|
||||
}
|
||||
|
||||
}
|
||||
else { // If the node has children
|
||||
|
|
|
@ -168,7 +168,8 @@ class DynamicAABBTree {
|
|||
void reportAllShapesOverlappingWith(int nodeID, const AABB& aabb);
|
||||
|
||||
/// Ray casting method
|
||||
void raycast(const Ray& ray, RaycastTest& raycastTest) const;
|
||||
void raycast(const Ray& ray, RaycastTest& raycastTest,
|
||||
unsigned short raycastWithCategoryMaskBits) const;
|
||||
};
|
||||
|
||||
// Return true if the node is a leaf of the tree
|
||||
|
|
|
@ -124,7 +124,8 @@ class CollisionWorld {
|
|||
void destroyCollisionBody(CollisionBody* collisionBody);
|
||||
|
||||
/// Ray cast method
|
||||
void raycast(const Ray& ray, RaycastCallback* raycastCallback) const;
|
||||
void raycast(const Ray& ray, RaycastCallback* raycastCallback,
|
||||
unsigned short raycastWithCategoryMaskBits = 0xFFFF) const;
|
||||
|
||||
/// Test if the AABBs of two bodies overlap
|
||||
bool testAABBOverlap(const CollisionBody* body1,
|
||||
|
@ -177,8 +178,9 @@ inline std::set<CollisionBody*>::iterator CollisionWorld::getBodiesEndIterator()
|
|||
|
||||
// Ray cast method
|
||||
inline void CollisionWorld::raycast(const Ray& ray,
|
||||
RaycastCallback* raycastCallback) const {
|
||||
mCollisionDetection.raycast(raycastCallback, ray);
|
||||
RaycastCallback* raycastCallback,
|
||||
unsigned short raycastWithCategoryMaskBits) const {
|
||||
mCollisionDetection.raycast(raycastCallback, ray, raycastWithCategoryMaskBits);
|
||||
}
|
||||
|
||||
// Test if the AABBs of two proxy shapes overlap
|
||||
|
|
|
@ -32,6 +32,13 @@
|
|||
/// Reactphysics3D namespace
|
||||
namespace reactphysics3d {
|
||||
|
||||
// Enumeration for categories
|
||||
enum CollisionCategory {
|
||||
CATEGORY_1 = 0x0001,
|
||||
CATEGORY_2 = 0x0002,
|
||||
CATEGORY_3 = 0x0004
|
||||
};
|
||||
|
||||
// Class
|
||||
class WorldCollisionCallback : public CollisionCallback
|
||||
{
|
||||
|
@ -60,7 +67,6 @@ class WorldCollisionCallback : public CollisionCallback
|
|||
sphere1CollideWithSphere2 = false;
|
||||
}
|
||||
|
||||
|
||||
// This method will be called for contact
|
||||
virtual void notifyContact(const ContactPointInfo& contactPointInfo) {
|
||||
|
||||
|
@ -145,6 +151,12 @@ class TestCollisionWorld : public Test {
|
|||
CylinderShape cylinderShape(2, 5);
|
||||
mCylinderShape = mCylinderBody->addCollisionShape(cylinderShape, Transform::identity());
|
||||
|
||||
// Assign collision categories to proxy shapes
|
||||
mBoxShape->setCollisionCategoryBits(CATEGORY_1);
|
||||
mSphere1Shape->setCollisionCategoryBits(CATEGORY_1);
|
||||
mSphere2Shape->setCollisionCategoryBits(CATEGORY_2);
|
||||
mCylinderShape->setCollisionCategoryBits(CATEGORY_3);
|
||||
|
||||
mCollisionCallback.boxBody = mBoxBody;
|
||||
mCollisionCallback.sphere1Body = mSphere1Body;
|
||||
mCollisionCallback.sphere2Body = mSphere2Body;
|
||||
|
@ -235,7 +247,11 @@ class TestCollisionWorld : public Test {
|
|||
test(!mCollisionCallback.sphere1CollideWithCylinder);
|
||||
test(!mCollisionCallback.sphere1CollideWithSphere2);
|
||||
|
||||
// Test collision with inactive bodies
|
||||
// Move sphere 1 to collide with box
|
||||
mSphere1Body->setTransform(Transform(Vector3(10, 5, 0), Quaternion::identity()));
|
||||
|
||||
// --------- Test collision with inactive bodies --------- //
|
||||
|
||||
mCollisionCallback.reset();
|
||||
mBoxBody->setIsActive(false);
|
||||
mCylinderBody->setIsActive(false);
|
||||
|
@ -261,6 +277,50 @@ class TestCollisionWorld : public Test {
|
|||
mCylinderBody->setIsActive(true);
|
||||
mSphere1Body->setIsActive(true);
|
||||
mSphere2Body->setIsActive(true);
|
||||
|
||||
// --------- Test collision with collision filtering -------- //
|
||||
|
||||
mBoxShape->setCollideWithMaskBits(CATEGORY_1 | CATEGORY_3);
|
||||
mSphere1Shape->setCollideWithMaskBits(CATEGORY_1 | CATEGORY_2);
|
||||
mSphere2Shape->setCollideWithMaskBits(CATEGORY_1);
|
||||
mCylinderShape->setCollideWithMaskBits(CATEGORY_1);
|
||||
|
||||
mCollisionCallback.reset();
|
||||
mWorld->testCollision(&mCollisionCallback);
|
||||
test(mCollisionCallback.boxCollideWithSphere1);
|
||||
test(mCollisionCallback.boxCollideWithCylinder);
|
||||
test(!mCollisionCallback.sphere1CollideWithCylinder);
|
||||
test(!mCollisionCallback.sphere1CollideWithSphere2);
|
||||
|
||||
// Move sphere 1 to collide with sphere 2
|
||||
mSphere1Body->setTransform(Transform(Vector3(30, 15, 10), Quaternion::identity()));
|
||||
|
||||
mCollisionCallback.reset();
|
||||
mWorld->testCollision(&mCollisionCallback);
|
||||
test(!mCollisionCallback.boxCollideWithSphere1);
|
||||
test(mCollisionCallback.boxCollideWithCylinder);
|
||||
test(!mCollisionCallback.sphere1CollideWithCylinder);
|
||||
test(mCollisionCallback.sphere1CollideWithSphere2);
|
||||
|
||||
mBoxShape->setCollideWithMaskBits(CATEGORY_2);
|
||||
mSphere1Shape->setCollideWithMaskBits(CATEGORY_2);
|
||||
mSphere2Shape->setCollideWithMaskBits(CATEGORY_3);
|
||||
mCylinderShape->setCollideWithMaskBits(CATEGORY_1);
|
||||
|
||||
mCollisionCallback.reset();
|
||||
mWorld->testCollision(&mCollisionCallback);
|
||||
test(!mCollisionCallback.boxCollideWithSphere1);
|
||||
test(!mCollisionCallback.boxCollideWithCylinder);
|
||||
test(!mCollisionCallback.sphere1CollideWithCylinder);
|
||||
test(!mCollisionCallback.sphere1CollideWithSphere2);
|
||||
|
||||
// Move sphere 1 to collide with box
|
||||
mSphere1Body->setTransform(Transform(Vector3(10, 5, 0), Quaternion::identity()));
|
||||
|
||||
mBoxShape->setCollideWithMaskBits(0xFFFF);
|
||||
mSphere1Shape->setCollideWithMaskBits(0xFFFF);
|
||||
mSphere2Shape->setCollideWithMaskBits(0xFFFF);
|
||||
mCylinderShape->setCollideWithMaskBits(0xFFFF);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -40,6 +40,12 @@
|
|||
/// Reactphysics3D namespace
|
||||
namespace reactphysics3d {
|
||||
|
||||
// Enumeration for categories
|
||||
enum Category {
|
||||
CATEGORY1 = 0x0001,
|
||||
CATEGORY2 = 0x0002
|
||||
};
|
||||
|
||||
/// Class WorldRaycastCallback
|
||||
class WorldRaycastCallback : public RaycastCallback {
|
||||
|
||||
|
@ -220,6 +226,17 @@ class TestRaycast : public Test {
|
|||
mLocalShape2ToWorld = mBodyTransform * shapeTransform2;
|
||||
mCompoundCylinderShape = mCompoundBody->addCollisionShape(cylinderShape, mShapeTransform);
|
||||
mCompoundSphereShape = mCompoundBody->addCollisionShape(sphereShape, shapeTransform2);
|
||||
|
||||
// Assign proxy shapes to the different categories
|
||||
mBoxShape->setCollisionCategoryBits(CATEGORY1);
|
||||
mSphereShape->setCollisionCategoryBits(CATEGORY1);
|
||||
mCapsuleShape->setCollisionCategoryBits(CATEGORY1);
|
||||
mConeShape->setCollisionCategoryBits(CATEGORY2);
|
||||
mConvexMeshShape->setCollisionCategoryBits(CATEGORY2);
|
||||
mConvexMeshShapeEdgesInfo->setCollisionCategoryBits(CATEGORY2);
|
||||
mCylinderShape->setCollisionCategoryBits(CATEGORY2);
|
||||
mCompoundSphereShape->setCollisionCategoryBits(CATEGORY2);
|
||||
mCompoundCylinderShape->setCollisionCategoryBits(CATEGORY2);
|
||||
}
|
||||
|
||||
/// Run the tests
|
||||
|
@ -256,6 +273,16 @@ class TestRaycast : public Test {
|
|||
test(approxEqual(callback.raycastInfo.worldPoint.y, hitPoint.y, epsilon));
|
||||
test(approxEqual(callback.raycastInfo.worldPoint.z, hitPoint.z, epsilon));
|
||||
|
||||
// Correct category filter mask
|
||||
callback.reset();
|
||||
mWorld->raycast(ray, &callback, CATEGORY1);
|
||||
test(callback.isHit);
|
||||
|
||||
// Wrong category filter mask
|
||||
callback.reset();
|
||||
mWorld->raycast(ray, &callback, CATEGORY2);
|
||||
test(!callback.isHit);
|
||||
|
||||
// CollisionBody::raycast()
|
||||
RaycastInfo raycastInfo2;
|
||||
test(mBoxBody->raycast(ray, raycastInfo2));
|
||||
|
@ -458,6 +485,16 @@ class TestRaycast : public Test {
|
|||
test(approxEqual(callback.raycastInfo.worldPoint.y, hitPoint.y, epsilon));
|
||||
test(approxEqual(callback.raycastInfo.worldPoint.z, hitPoint.z, epsilon));
|
||||
|
||||
// Correct category filter mask
|
||||
callback.reset();
|
||||
mWorld->raycast(ray, &callback, CATEGORY1);
|
||||
test(callback.isHit);
|
||||
|
||||
// Wrong category filter mask
|
||||
callback.reset();
|
||||
mWorld->raycast(ray, &callback, CATEGORY2);
|
||||
test(!callback.isHit);
|
||||
|
||||
// CollisionBody::raycast()
|
||||
RaycastInfo raycastInfo2;
|
||||
test(mSphereBody->raycast(ray, raycastInfo2));
|
||||
|
@ -668,6 +705,16 @@ class TestRaycast : public Test {
|
|||
test(approxEqual(callback.raycastInfo.worldPoint.y, hitPoint.y, epsilon));
|
||||
test(approxEqual(callback.raycastInfo.worldPoint.z, hitPoint.z, epsilon));
|
||||
|
||||
// Correct category filter mask
|
||||
callback.reset();
|
||||
mWorld->raycast(ray, &callback, CATEGORY1);
|
||||
test(callback.isHit);
|
||||
|
||||
// Wrong category filter mask
|
||||
callback.reset();
|
||||
mWorld->raycast(ray, &callback, CATEGORY2);
|
||||
test(!callback.isHit);
|
||||
|
||||
// CollisionBody::raycast()
|
||||
RaycastInfo raycastInfo2;
|
||||
test(mCapsuleBody->raycast(ray, raycastInfo2));
|
||||
|
@ -893,6 +940,16 @@ class TestRaycast : public Test {
|
|||
test(approxEqual(callback.raycastInfo.worldPoint.y, hitPoint.y));
|
||||
test(approxEqual(callback.raycastInfo.worldPoint.z, hitPoint.z));
|
||||
|
||||
// Correct category filter mask
|
||||
callback.reset();
|
||||
mWorld->raycast(ray, &callback, CATEGORY2);
|
||||
test(callback.isHit);
|
||||
|
||||
// Wrong category filter mask
|
||||
callback.reset();
|
||||
mWorld->raycast(ray, &callback, CATEGORY1);
|
||||
test(!callback.isHit);
|
||||
|
||||
// CollisionBody::raycast()
|
||||
RaycastInfo raycastInfo2;
|
||||
test(mConeBody->raycast(ray, raycastInfo2));
|
||||
|
@ -1125,6 +1182,16 @@ class TestRaycast : public Test {
|
|||
test(approxEqual(callback.raycastInfo.worldPoint.y, hitPoint.y, epsilon));
|
||||
test(approxEqual(callback.raycastInfo.worldPoint.z, hitPoint.z, epsilon));
|
||||
|
||||
// Correct category filter mask
|
||||
callback.reset();
|
||||
mWorld->raycast(ray, &callback, CATEGORY2);
|
||||
test(callback.isHit);
|
||||
|
||||
// Wrong category filter mask
|
||||
callback.reset();
|
||||
mWorld->raycast(ray, &callback, CATEGORY1);
|
||||
test(!callback.isHit);
|
||||
|
||||
// CollisionBody::raycast()
|
||||
RaycastInfo raycastInfo2;
|
||||
test(mConvexMeshBody->raycast(ray, raycastInfo2));
|
||||
|
@ -1389,6 +1456,16 @@ class TestRaycast : public Test {
|
|||
test(approxEqual(callback.raycastInfo.worldPoint.y, hitPoint.y, epsilon));
|
||||
test(approxEqual(callback.raycastInfo.worldPoint.z, hitPoint.z, epsilon));
|
||||
|
||||
// Correct category filter mask
|
||||
callback.reset();
|
||||
mWorld->raycast(ray, &callback, CATEGORY2);
|
||||
test(callback.isHit);
|
||||
|
||||
// Wrong category filter mask
|
||||
callback.reset();
|
||||
mWorld->raycast(ray, &callback, CATEGORY1);
|
||||
test(!callback.isHit);
|
||||
|
||||
// CollisionBody::raycast()
|
||||
RaycastInfo raycastInfo2;
|
||||
test(mCylinderBody->raycast(ray, raycastInfo2));
|
||||
|
@ -1604,6 +1681,16 @@ class TestRaycast : public Test {
|
|||
|
||||
callback.shapeToTest = mCompoundSphereShape;
|
||||
|
||||
// Correct category filter mask
|
||||
callback.reset();
|
||||
mWorld->raycast(ray1, &callback, CATEGORY2);
|
||||
test(callback.isHit);
|
||||
|
||||
// Wrong category filter mask
|
||||
callback.reset();
|
||||
mWorld->raycast(ray1, &callback, CATEGORY1);
|
||||
test(!callback.isHit);
|
||||
|
||||
RaycastInfo raycastInfo;
|
||||
test(mCompoundBody->raycast(ray1, raycastInfo));
|
||||
callback.reset();
|
||||
|
|
Loading…
Reference in New Issue
Block a user