diff --git a/src/body/CollisionBody.cpp b/src/body/CollisionBody.cpp index 912ceeb6..eda0523c 100644 --- a/src/body/CollisionBody.cpp +++ b/src/body/CollisionBody.cpp @@ -81,10 +81,9 @@ ProxyShape* CollisionBody::addCollisionShape(CollisionShape* collisionShape, Vector3 localBoundsMax; // TODO : Maybe this method can directly returns an AABB collisionShape->getLocalBounds(localBoundsMin, localBoundsMax); - ProxyShapesComponents::ProxyShapeComponent proxyShapeComponent(proxyShape, -1, AABB(localBoundsMin, localBoundsMax), - transform, collisionShape, decimal(1)); + transform, collisionShape, decimal(1), 0x0001, 0xFFFF); mWorld.mProxyShapesComponents.addComponent(mEntity, mIsSleeping, proxyShapeComponent); #ifdef IS_PROFILING_ACTIVE diff --git a/src/body/RigidBody.cpp b/src/body/RigidBody.cpp index 6f62dc8b..e2072f81 100644 --- a/src/body/RigidBody.cpp +++ b/src/body/RigidBody.cpp @@ -293,7 +293,7 @@ ProxyShape* RigidBody::addCollisionShape(CollisionShape* collisionShape, ProxyShapesComponents::ProxyShapeComponent proxyShapeComponent(proxyShape, -1, AABB(localBoundsMin, localBoundsMax), - transform, collisionShape, mass); + transform, collisionShape, mass, 0x0001, 0xFFFF); mWorld.mProxyShapesComponents.addComponent(mEntity, mIsSleeping, proxyShapeComponent); #ifdef IS_PROFILING_ACTIVE diff --git a/src/collision/ProxyShape.cpp b/src/collision/ProxyShape.cpp index 658555cc..37b63376 100644 --- a/src/collision/ProxyShape.cpp +++ b/src/collision/ProxyShape.cpp @@ -41,7 +41,7 @@ using namespace reactphysics3d; */ ProxyShape::ProxyShape(CollisionBody* body, MemoryManager& memoryManager) :mMemoryManager(memoryManager), mBody(body), - mUserData(nullptr), mCollisionCategoryBits(0x0001), mCollideWithMaskBits(0xFFFF) { + mUserData(nullptr) { } @@ -77,13 +77,14 @@ bool ProxyShape::testPointInside(const Vector3& worldPoint) { * @param collisionCategoryBits The collision category bits mask of the proxy shape */ void ProxyShape::setCollisionCategoryBits(unsigned short collisionCategoryBits) { - mCollisionCategoryBits = collisionCategoryBits; + + mBody->mWorld.mProxyShapesComponents.setCollisionCategoryBits(this, collisionCategoryBits); int broadPhaseId = mBody->mWorld.mProxyShapesComponents.getBroadPhaseId(this); RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::ProxyShape, "ProxyShape " + std::to_string(broadPhaseId) + ": Set collisionCategoryBits=" + - std::to_string(mCollisionCategoryBits)); + std::to_string(collisionCategoryBits)); } // Set the collision bits mask @@ -91,13 +92,14 @@ void ProxyShape::setCollisionCategoryBits(unsigned short collisionCategoryBits) * @param collideWithMaskBits The bits mask that specifies with which collision category this shape will collide */ void ProxyShape::setCollideWithMaskBits(unsigned short collideWithMaskBits) { - mCollideWithMaskBits = collideWithMaskBits; + + mBody->mWorld.mProxyShapesComponents.setCollideWithMaskBits(this, collideWithMaskBits); int broadPhaseId = mBody->mWorld.mProxyShapesComponents.getBroadPhaseId(this); RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::ProxyShape, "ProxyShape " + std::to_string(broadPhaseId) + ": Set collideWithMaskBits=" + - std::to_string(mCollideWithMaskBits)); + std::to_string(collideWithMaskBits)); } // Set the local to parent body transform @@ -207,6 +209,22 @@ bool ProxyShape::raycast(const Ray& ray, RaycastInfo& raycastInfo) { return isHit; } +// Return the collision category bits +/** + * @return The collision category bits mask of the proxy shape + */ +unsigned short ProxyShape::getCollisionCategoryBits() const { + return mBody->mWorld.mProxyShapesComponents.getCollisionCategoryBits(this); +} + +// Return the collision bits mask +/** + * @return The bits mask that specifies with which collision category this shape will collide + */ +unsigned short ProxyShape::getCollideWithMaskBits() const { + return mBody->mWorld.mProxyShapesComponents.getCollideWithMaskBits(this); +} + // Return the local to world transform /** * @return The transformation that transforms the local-space of the collision diff --git a/src/collision/ProxyShape.h b/src/collision/ProxyShape.h index 17ee0c72..7381c01c 100644 --- a/src/collision/ProxyShape.h +++ b/src/collision/ProxyShape.h @@ -81,12 +81,12 @@ class ProxyShape { /// 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; + //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; + //unsigned short mCollideWithMaskBits; #ifdef IS_PROFILING_ACTIVE @@ -233,22 +233,6 @@ inline void ProxyShape::setUserData(void* userData) { mUserData = userData; } -// Return the collision category bits -/** - * @return The collision category bits mask of the proxy shape - */ -inline unsigned short ProxyShape::getCollisionCategoryBits() const { - return mCollisionCategoryBits; -} - -// Return the collision bits mask -/** - * @return The bits mask that specifies with which collision category this shape will collide - */ -inline unsigned short ProxyShape::getCollideWithMaskBits() const { - return mCollideWithMaskBits; -} - /// Test if the proxy shape overlaps with a given AABB /** * @param worldAABB The AABB (in world-space coordinates) that will be used to test overlap diff --git a/src/components/ProxyShapesComponents.cpp b/src/components/ProxyShapesComponents.cpp index 627690d5..f2284582 100644 --- a/src/components/ProxyShapesComponents.cpp +++ b/src/components/ProxyShapesComponents.cpp @@ -85,6 +85,8 @@ void ProxyShapesComponents::allocate(uint32 nbComponentsToAllocate) { decimal* newMasses = reinterpret_cast(newCollisionShapes + nbComponentsToAllocate); uint32* newPreviousBodyProxyShapes = reinterpret_cast(newMasses + nbComponentsToAllocate); uint32* newNextBodyProxyShapes = reinterpret_cast(newPreviousBodyProxyShapes + nbComponentsToAllocate); + unsigned short* newCollisionCategoryBits = reinterpret_cast(newNextBodyProxyShapes + nbComponentsToAllocate); + unsigned short* newCollideWithMaskBits = reinterpret_cast(newCollisionCategoryBits + nbComponentsToAllocate); // If there was already components before if (mNbComponents > 0) { @@ -99,6 +101,8 @@ void ProxyShapesComponents::allocate(uint32 nbComponentsToAllocate) { memcpy(newMasses, mMasses, mNbComponents * sizeof(decimal)); memcpy(newPreviousBodyProxyShapes, mPreviousBodyProxyShapes, mNbComponents * sizeof(uint32)); memcpy(newNextBodyProxyShapes, mNextBodyProxyShapes, mNbComponents * sizeof(uint32)); + memcpy(newCollisionCategoryBits, mCollisionCategoryBits, mNbComponents * sizeof(unsigned short)); + memcpy(newCollideWithMaskBits, mCollideWithMaskBits, mNbComponents * sizeof(unsigned short)); // Deallocate previous memory mMemoryAllocator.release(mBuffer, mNbAllocatedComponents * COMPONENT_DATA_SIZE); @@ -114,6 +118,8 @@ void ProxyShapesComponents::allocate(uint32 nbComponentsToAllocate) { mMasses = newMasses; mPreviousBodyProxyShapes = newPreviousBodyProxyShapes; mNextBodyProxyShapes = newNextBodyProxyShapes; + mCollisionCategoryBits = newCollisionCategoryBits; + mCollideWithMaskBits = newCollideWithMaskBits; mNbAllocatedComponents = nbComponentsToAllocate; } @@ -199,6 +205,8 @@ void ProxyShapesComponents::addComponent(Entity entity, bool isSleeping, const P new (mLocalToBodyTransforms + index) Transform(component.localToBodyTransform); mCollisionShapes[index] = component.collisionShape; new (mMasses + index) decimal(component.mass); + new (mCollisionCategoryBits + index) unsigned short(component.collisionCategoryBits); + new (mCollideWithMaskBits + index) unsigned short(component.collideWithMaskBits); mMapProxyShapeToComponentIndex.add(Pair(component.proxyShape, index)); @@ -232,6 +240,8 @@ void ProxyShapesComponents::moveComponentToIndex(uint32 srcIndex, uint32 destInd new (mMasses + destIndex) decimal(mMasses[srcIndex]); new (mPreviousBodyProxyShapes + destIndex) uint32(hasPreviousProxyShape(srcIndex) ? mPreviousBodyProxyShapes[srcIndex] : destIndex); new (mNextBodyProxyShapes + destIndex) uint32(hasNextProxyShape(srcIndex) ? mNextBodyProxyShapes[srcIndex] : destIndex); + new (mCollisionCategoryBits + destIndex) unsigned short(mCollisionCategoryBits[srcIndex]); + new (mCollideWithMaskBits + destIndex) unsigned short(mCollideWithMaskBits[srcIndex]); // Update the the next proxy-shape index of the previous proxy-shape if (hasPreviousProxyShape(destIndex)) { @@ -274,6 +284,8 @@ void ProxyShapesComponents::swapComponents(uint32 index1, uint32 index2) { decimal mass1 = mMasses[index1]; uint32 previousProxyShape1 = hasPreviousProxyShape(index1) ? mPreviousBodyProxyShapes[index1] : index2; uint32 nextProxyShape1 = hasNextProxyShape(index1) ? mNextBodyProxyShapes[index1] : index2; + unsigned short collisionCategoryBits1 = mCollisionCategoryBits[index1]; + unsigned short collideWithMaskBits1 = mCollideWithMaskBits[index1]; const bool isFirstBodyProxyShape1 = mMapEntityToComponentIndex[mEntities[index1]] == index1; @@ -292,6 +304,8 @@ void ProxyShapesComponents::swapComponents(uint32 index1, uint32 index2) { new (mMasses + index2) decimal(mass1); new (mPreviousBodyProxyShapes + index2) uint32(previousProxyShape1); new (mNextBodyProxyShapes + index2) uint32(nextProxyShape1); + new (mCollisionCategoryBits + index2) unsigned short(collisionCategoryBits1); + new (mCollideWithMaskBits + index2) unsigned short(collideWithMaskBits1); // Update the the next proxy-shape index of the previous proxy-shape if (hasPreviousProxyShape(index2)) { diff --git a/src/components/ProxyShapesComponents.h b/src/components/ProxyShapesComponents.h index 98368627..7ba0e0e6 100644 --- a/src/components/ProxyShapesComponents.h +++ b/src/components/ProxyShapesComponents.h @@ -64,7 +64,7 @@ class ProxyShapesComponents { const size_t COMPONENT_DATA_SIZE = sizeof(Entity) + sizeof(ProxyShape*) + sizeof(int) + sizeof(AABB) + sizeof(Transform) + sizeof(CollisionShape*) + sizeof(decimal) + sizeof(uint32) + - sizeof(uint32); + sizeof(uint32) + sizeof(unsigned short) + sizeof(unsigned short); // -------------------- Attributes -------------------- // @@ -119,6 +119,19 @@ class ProxyShapesComponents { /// mNextBodyProxyShapes[i] == i means that the proxy-shape component has no next proxy-shape uint32* mNextBodyProxyShapes; + /// Array of 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; + + /// Array of 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 -------------------- // /// Remove a component at a given index @@ -153,12 +166,15 @@ class ProxyShapesComponents { Transform localToBodyTransform; CollisionShape* collisionShape; decimal mass; + unsigned short collisionCategoryBits; + unsigned short collideWithMaskBits; /// Constructor ProxyShapeComponent(ProxyShape* proxyShape, int broadPhaseId, AABB localBounds, Transform localToBodyTransform, - CollisionShape* collisionShape, decimal mass) + CollisionShape* collisionShape, decimal mass, unsigned short collisionCategoryBits, + unsigned short collideWithMaskBits) :proxyShape(proxyShape), broadPhaseId(broadPhaseId), localBounds(localBounds), localToBodyTransform(localToBodyTransform), - collisionShape(collisionShape), mass(mass) { + collisionShape(collisionShape), mass(mass), collisionCategoryBits(collisionCategoryBits), collideWithMaskBits(collideWithMaskBits) { } }; @@ -209,6 +225,18 @@ class ProxyShapesComponents { /// Return the first proxy-shape in the linked-list of all proxy-shapes of a body ProxyShape* getFirstProxyShapeOfBody(Entity entity) const; + + /// Return the collision category bits of a given proxy-shape + unsigned short getCollisionCategoryBits(const ProxyShape* proxyShape) const; + + /// Set the collision category bits of a given proxy-shape + void setCollisionCategoryBits(const ProxyShape* proxyShape, unsigned short collisionCategoryBits); + + /// Return the "collide with" mask bits of a given proxy-shape + unsigned short getCollideWithMaskBits(const ProxyShape* proxyShape) const; + + /// Set the "collide with" mask bits of a given proxy-shape + void setCollideWithMaskBits(const ProxyShape* proxyShape, unsigned short collideWithMaskBits); }; // Return the mass of a proxy-shape @@ -287,6 +315,38 @@ inline ProxyShape* ProxyShapesComponents::getFirstProxyShapeOfBody(Entity entity return nullptr; } +// Return the collision category bits of a given proxy-shape +inline unsigned short ProxyShapesComponents::getCollisionCategoryBits(const ProxyShape* proxyShape) const { + + assert(mMapProxyShapeToComponentIndex.containsKey(proxyShape)); + + return mCollisionCategoryBits[mMapProxyShapeToComponentIndex[proxyShape]]; +} + +// Return the "collide with" mask bits of a given proxy-shape +inline unsigned short ProxyShapesComponents::getCollideWithMaskBits(const ProxyShape* proxyShape) const { + + assert(mMapProxyShapeToComponentIndex.containsKey(proxyShape)); + + return mCollideWithMaskBits[mMapProxyShapeToComponentIndex[proxyShape]]; +} + +// Set the collision category bits of a given proxy-shape +inline void ProxyShapesComponents::setCollisionCategoryBits(const ProxyShape* proxyShape, unsigned short collisionCategoryBits) { + + assert(mMapProxyShapeToComponentIndex.containsKey(proxyShape)); + + mCollisionCategoryBits[mMapProxyShapeToComponentIndex[proxyShape]] = collisionCategoryBits; +} + +// Set the "collide with" mask bits of a given proxy-shape +inline void ProxyShapesComponents::setCollideWithMaskBits(const ProxyShape* proxyShape, unsigned short collideWithMaskBits) { + + assert(mMapProxyShapeToComponentIndex.containsKey(proxyShape)); + + mCollideWithMaskBits[mMapProxyShapeToComponentIndex[proxyShape]] = collideWithMaskBits; +} + } #endif