Add fields to ProxyShapesComponents

This commit is contained in:
Daniel Chappuis 2019-01-14 18:35:51 +01:00
parent 7d8f043cdb
commit c5c7e81260
6 changed files with 104 additions and 29 deletions

View File

@ -81,10 +81,9 @@ ProxyShape* CollisionBody::addCollisionShape(CollisionShape* collisionShape,
Vector3 localBoundsMax; Vector3 localBoundsMax;
// TODO : Maybe this method can directly returns an AABB // TODO : Maybe this method can directly returns an AABB
collisionShape->getLocalBounds(localBoundsMin, localBoundsMax); collisionShape->getLocalBounds(localBoundsMin, localBoundsMax);
ProxyShapesComponents::ProxyShapeComponent proxyShapeComponent(proxyShape, -1, ProxyShapesComponents::ProxyShapeComponent proxyShapeComponent(proxyShape, -1,
AABB(localBoundsMin, localBoundsMax), AABB(localBoundsMin, localBoundsMax),
transform, collisionShape, decimal(1)); transform, collisionShape, decimal(1), 0x0001, 0xFFFF);
mWorld.mProxyShapesComponents.addComponent(mEntity, mIsSleeping, proxyShapeComponent); mWorld.mProxyShapesComponents.addComponent(mEntity, mIsSleeping, proxyShapeComponent);
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE

View File

@ -293,7 +293,7 @@ ProxyShape* RigidBody::addCollisionShape(CollisionShape* collisionShape,
ProxyShapesComponents::ProxyShapeComponent proxyShapeComponent(proxyShape, -1, ProxyShapesComponents::ProxyShapeComponent proxyShapeComponent(proxyShape, -1,
AABB(localBoundsMin, localBoundsMax), AABB(localBoundsMin, localBoundsMax),
transform, collisionShape, mass); transform, collisionShape, mass, 0x0001, 0xFFFF);
mWorld.mProxyShapesComponents.addComponent(mEntity, mIsSleeping, proxyShapeComponent); mWorld.mProxyShapesComponents.addComponent(mEntity, mIsSleeping, proxyShapeComponent);
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE

View File

@ -41,7 +41,7 @@ using namespace reactphysics3d;
*/ */
ProxyShape::ProxyShape(CollisionBody* body, MemoryManager& memoryManager) ProxyShape::ProxyShape(CollisionBody* body, MemoryManager& memoryManager)
:mMemoryManager(memoryManager), mBody(body), :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 * @param collisionCategoryBits The collision category bits mask of the proxy shape
*/ */
void ProxyShape::setCollisionCategoryBits(unsigned short collisionCategoryBits) { void ProxyShape::setCollisionCategoryBits(unsigned short collisionCategoryBits) {
mCollisionCategoryBits = collisionCategoryBits;
mBody->mWorld.mProxyShapesComponents.setCollisionCategoryBits(this, collisionCategoryBits);
int broadPhaseId = mBody->mWorld.mProxyShapesComponents.getBroadPhaseId(this); int broadPhaseId = mBody->mWorld.mProxyShapesComponents.getBroadPhaseId(this);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::ProxyShape, RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::ProxyShape,
"ProxyShape " + std::to_string(broadPhaseId) + ": Set collisionCategoryBits=" + "ProxyShape " + std::to_string(broadPhaseId) + ": Set collisionCategoryBits=" +
std::to_string(mCollisionCategoryBits)); std::to_string(collisionCategoryBits));
} }
// Set the collision bits mask // 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 * @param collideWithMaskBits The bits mask that specifies with which collision category this shape will collide
*/ */
void ProxyShape::setCollideWithMaskBits(unsigned short collideWithMaskBits) { void ProxyShape::setCollideWithMaskBits(unsigned short collideWithMaskBits) {
mCollideWithMaskBits = collideWithMaskBits;
mBody->mWorld.mProxyShapesComponents.setCollideWithMaskBits(this, collideWithMaskBits);
int broadPhaseId = mBody->mWorld.mProxyShapesComponents.getBroadPhaseId(this); int broadPhaseId = mBody->mWorld.mProxyShapesComponents.getBroadPhaseId(this);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::ProxyShape, RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::ProxyShape,
"ProxyShape " + std::to_string(broadPhaseId) + ": Set collideWithMaskBits=" + "ProxyShape " + std::to_string(broadPhaseId) + ": Set collideWithMaskBits=" +
std::to_string(mCollideWithMaskBits)); std::to_string(collideWithMaskBits));
} }
// Set the local to parent body transform // Set the local to parent body transform
@ -207,6 +209,22 @@ bool ProxyShape::raycast(const Ray& ray, RaycastInfo& raycastInfo) {
return isHit; 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 local to world transform
/** /**
* @return The transformation that transforms the local-space of the collision * @return The transformation that transforms the local-space of the collision

View File

@ -81,12 +81,12 @@ class ProxyShape {
/// together with the mCollideWithMaskBits variable so that given /// together with the mCollideWithMaskBits variable so that given
/// categories of shapes collide with each other and do not collide with /// categories of shapes collide with each other and do not collide with
/// other categories. /// other categories.
unsigned short mCollisionCategoryBits; //unsigned short mCollisionCategoryBits;
/// Bits mask used to state which collision categories this shape can /// Bits mask used to state which collision categories this shape can
/// collide with. This value is 0xFFFF by default. It means that this /// collide with. This value is 0xFFFF by default. It means that this
/// proxy shape will collide with every collision categories by default. /// proxy shape will collide with every collision categories by default.
unsigned short mCollideWithMaskBits; //unsigned short mCollideWithMaskBits;
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE
@ -233,22 +233,6 @@ inline void ProxyShape::setUserData(void* userData) {
mUserData = 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 /// 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 * @param worldAABB The AABB (in world-space coordinates) that will be used to test overlap

View File

@ -85,6 +85,8 @@ void ProxyShapesComponents::allocate(uint32 nbComponentsToAllocate) {
decimal* newMasses = reinterpret_cast<decimal*>(newCollisionShapes + nbComponentsToAllocate); decimal* newMasses = reinterpret_cast<decimal*>(newCollisionShapes + nbComponentsToAllocate);
uint32* newPreviousBodyProxyShapes = reinterpret_cast<uint32*>(newMasses + nbComponentsToAllocate); uint32* newPreviousBodyProxyShapes = reinterpret_cast<uint32*>(newMasses + nbComponentsToAllocate);
uint32* newNextBodyProxyShapes = reinterpret_cast<uint32*>(newPreviousBodyProxyShapes + nbComponentsToAllocate); uint32* newNextBodyProxyShapes = reinterpret_cast<uint32*>(newPreviousBodyProxyShapes + nbComponentsToAllocate);
unsigned short* newCollisionCategoryBits = reinterpret_cast<unsigned short*>(newNextBodyProxyShapes + nbComponentsToAllocate);
unsigned short* newCollideWithMaskBits = reinterpret_cast<unsigned short*>(newCollisionCategoryBits + nbComponentsToAllocate);
// If there was already components before // If there was already components before
if (mNbComponents > 0) { if (mNbComponents > 0) {
@ -99,6 +101,8 @@ void ProxyShapesComponents::allocate(uint32 nbComponentsToAllocate) {
memcpy(newMasses, mMasses, mNbComponents * sizeof(decimal)); memcpy(newMasses, mMasses, mNbComponents * sizeof(decimal));
memcpy(newPreviousBodyProxyShapes, mPreviousBodyProxyShapes, mNbComponents * sizeof(uint32)); memcpy(newPreviousBodyProxyShapes, mPreviousBodyProxyShapes, mNbComponents * sizeof(uint32));
memcpy(newNextBodyProxyShapes, mNextBodyProxyShapes, 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 // Deallocate previous memory
mMemoryAllocator.release(mBuffer, mNbAllocatedComponents * COMPONENT_DATA_SIZE); mMemoryAllocator.release(mBuffer, mNbAllocatedComponents * COMPONENT_DATA_SIZE);
@ -114,6 +118,8 @@ void ProxyShapesComponents::allocate(uint32 nbComponentsToAllocate) {
mMasses = newMasses; mMasses = newMasses;
mPreviousBodyProxyShapes = newPreviousBodyProxyShapes; mPreviousBodyProxyShapes = newPreviousBodyProxyShapes;
mNextBodyProxyShapes = newNextBodyProxyShapes; mNextBodyProxyShapes = newNextBodyProxyShapes;
mCollisionCategoryBits = newCollisionCategoryBits;
mCollideWithMaskBits = newCollideWithMaskBits;
mNbAllocatedComponents = nbComponentsToAllocate; mNbAllocatedComponents = nbComponentsToAllocate;
} }
@ -199,6 +205,8 @@ void ProxyShapesComponents::addComponent(Entity entity, bool isSleeping, const P
new (mLocalToBodyTransforms + index) Transform(component.localToBodyTransform); new (mLocalToBodyTransforms + index) Transform(component.localToBodyTransform);
mCollisionShapes[index] = component.collisionShape; mCollisionShapes[index] = component.collisionShape;
new (mMasses + index) decimal(component.mass); new (mMasses + index) decimal(component.mass);
new (mCollisionCategoryBits + index) unsigned short(component.collisionCategoryBits);
new (mCollideWithMaskBits + index) unsigned short(component.collideWithMaskBits);
mMapProxyShapeToComponentIndex.add(Pair<const ProxyShape*, uint32>(component.proxyShape, index)); mMapProxyShapeToComponentIndex.add(Pair<const ProxyShape*, uint32>(component.proxyShape, index));
@ -232,6 +240,8 @@ void ProxyShapesComponents::moveComponentToIndex(uint32 srcIndex, uint32 destInd
new (mMasses + destIndex) decimal(mMasses[srcIndex]); new (mMasses + destIndex) decimal(mMasses[srcIndex]);
new (mPreviousBodyProxyShapes + destIndex) uint32(hasPreviousProxyShape(srcIndex) ? mPreviousBodyProxyShapes[srcIndex] : destIndex); new (mPreviousBodyProxyShapes + destIndex) uint32(hasPreviousProxyShape(srcIndex) ? mPreviousBodyProxyShapes[srcIndex] : destIndex);
new (mNextBodyProxyShapes + destIndex) uint32(hasNextProxyShape(srcIndex) ? mNextBodyProxyShapes[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 // Update the the next proxy-shape index of the previous proxy-shape
if (hasPreviousProxyShape(destIndex)) { if (hasPreviousProxyShape(destIndex)) {
@ -274,6 +284,8 @@ void ProxyShapesComponents::swapComponents(uint32 index1, uint32 index2) {
decimal mass1 = mMasses[index1]; decimal mass1 = mMasses[index1];
uint32 previousProxyShape1 = hasPreviousProxyShape(index1) ? mPreviousBodyProxyShapes[index1] : index2; uint32 previousProxyShape1 = hasPreviousProxyShape(index1) ? mPreviousBodyProxyShapes[index1] : index2;
uint32 nextProxyShape1 = hasNextProxyShape(index1) ? mNextBodyProxyShapes[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; const bool isFirstBodyProxyShape1 = mMapEntityToComponentIndex[mEntities[index1]] == index1;
@ -292,6 +304,8 @@ void ProxyShapesComponents::swapComponents(uint32 index1, uint32 index2) {
new (mMasses + index2) decimal(mass1); new (mMasses + index2) decimal(mass1);
new (mPreviousBodyProxyShapes + index2) uint32(previousProxyShape1); new (mPreviousBodyProxyShapes + index2) uint32(previousProxyShape1);
new (mNextBodyProxyShapes + index2) uint32(nextProxyShape1); 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 // Update the the next proxy-shape index of the previous proxy-shape
if (hasPreviousProxyShape(index2)) { if (hasPreviousProxyShape(index2)) {

View File

@ -64,7 +64,7 @@ class ProxyShapesComponents {
const size_t COMPONENT_DATA_SIZE = sizeof(Entity) + sizeof(ProxyShape*) + sizeof(int) + sizeof(AABB) + const size_t COMPONENT_DATA_SIZE = sizeof(Entity) + sizeof(ProxyShape*) + sizeof(int) + sizeof(AABB) +
sizeof(Transform) + sizeof(CollisionShape*) + sizeof(decimal) + sizeof(uint32) + sizeof(Transform) + sizeof(CollisionShape*) + sizeof(decimal) + sizeof(uint32) +
sizeof(uint32); sizeof(uint32) + sizeof(unsigned short) + sizeof(unsigned short);
// -------------------- Attributes -------------------- // // -------------------- Attributes -------------------- //
@ -119,6 +119,19 @@ class ProxyShapesComponents {
/// mNextBodyProxyShapes[i] == i means that the proxy-shape component has no next proxy-shape /// mNextBodyProxyShapes[i] == i means that the proxy-shape component has no next proxy-shape
uint32* mNextBodyProxyShapes; 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 -------------------- // // -------------------- Methods -------------------- //
/// Remove a component at a given index /// Remove a component at a given index
@ -153,12 +166,15 @@ class ProxyShapesComponents {
Transform localToBodyTransform; Transform localToBodyTransform;
CollisionShape* collisionShape; CollisionShape* collisionShape;
decimal mass; decimal mass;
unsigned short collisionCategoryBits;
unsigned short collideWithMaskBits;
/// Constructor /// Constructor
ProxyShapeComponent(ProxyShape* proxyShape, int broadPhaseId, AABB localBounds, Transform localToBodyTransform, 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), :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 /// Return the first proxy-shape in the linked-list of all proxy-shapes of a body
ProxyShape* getFirstProxyShapeOfBody(Entity entity) const; 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 // Return the mass of a proxy-shape
@ -287,6 +315,38 @@ inline ProxyShape* ProxyShapesComponents::getFirstProxyShapeOfBody(Entity entity
return nullptr; 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 #endif