Move attribute in RigidBodyComponents

This commit is contained in:
Daniel Chappuis 2019-07-19 20:51:43 +02:00
parent ca80d95d84
commit 466455d15a
7 changed files with 67 additions and 64 deletions

View File

@ -57,7 +57,7 @@ RigidBody::~RigidBody() {
// Return the type of the body
BodyType RigidBody::getType() const {
return mWorld.mDynamicsComponents.getBodyType(mEntity);
return mWorld.mRigidBodyComponents.getBodyType(mEntity);
}
// Set the type of the body
@ -75,9 +75,9 @@ BodyType RigidBody::getType() const {
*/
void RigidBody::setType(BodyType type) {
if (mWorld.mDynamicsComponents.getBodyType(mEntity) == type) return;
if (mWorld.mRigidBodyComponents.getBodyType(mEntity) == type) return;
mWorld.mDynamicsComponents.setBodyType(mEntity, type);
mWorld.mRigidBodyComponents.setBodyType(mEntity, type);
// Recompute the total mass, center of mass and inertia tensor
recomputeMassInformation();
@ -168,7 +168,7 @@ decimal RigidBody::getMass() const {
void RigidBody::applyForce(const Vector3& force, const Vector3& point) {
// If it is not a dynamic body, we do nothing
if (mWorld.mDynamicsComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
if (mWorld.mRigidBodyComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
// Awake the body if it was sleeping
if (mWorld.mRigidBodyComponents.getIsSleeping(mEntity)) {
@ -197,7 +197,7 @@ void RigidBody::setInertiaTensorLocal(const Matrix3x3& inertiaTensorLocal) {
mUserInertiaTensorLocalInverse = inertiaTensorLocal.getInverse();
mIsInertiaTensorSetByUser = true;
if (mWorld.mDynamicsComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
if (mWorld.mRigidBodyComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
// Compute the inverse local inertia tensor
mWorld.mDynamicsComponents.setInverseInertiaTensorLocal(mEntity, mUserInertiaTensorLocalInverse);
@ -220,7 +220,7 @@ void RigidBody::setInertiaTensorLocal(const Matrix3x3& inertiaTensorLocal) {
void RigidBody::applyForceToCenterOfMass(const Vector3& force) {
// If it is not a dynamic body, we do nothing
if (mWorld.mDynamicsComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
if (mWorld.mRigidBodyComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
// Awake the body if it was sleeping
if (mWorld.mRigidBodyComponents.getIsSleeping(mEntity)) {
@ -260,7 +260,7 @@ void RigidBody::setInverseInertiaTensorLocal(const Matrix3x3& inverseInertiaTens
mUserInertiaTensorLocalInverse = inverseInertiaTensorLocal;
mIsInertiaTensorSetByUser = true;
if (mWorld.mDynamicsComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
if (mWorld.mRigidBodyComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
// Compute the inverse local inertia tensor
mWorld.mDynamicsComponents.setInverseInertiaTensorLocal(mEntity, mUserInertiaTensorLocalInverse);
@ -283,7 +283,7 @@ void RigidBody::setCenterOfMassLocal(const Vector3& centerOfMassLocal) {
// TODO : Check if we need to update the postion of the body here at the end (transform of the body)
if (mWorld.mDynamicsComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
if (mWorld.mRigidBodyComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
mIsCenterOfMassSetByUser = true;
@ -311,7 +311,7 @@ void RigidBody::setCenterOfMassLocal(const Vector3& centerOfMassLocal) {
*/
void RigidBody::setMass(decimal mass) {
if (mWorld.mDynamicsComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
if (mWorld.mRigidBodyComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
mWorld.mDynamicsComponents.setInitMass(mEntity, mass);
@ -533,7 +533,7 @@ void RigidBody::setMaterial(const Material& material) {
void RigidBody::setLinearVelocity(const Vector3& linearVelocity) {
// If it is a static body, we do nothing
if (mWorld.mDynamicsComponents.getBodyType(mEntity) == BodyType::STATIC) return;
if (mWorld.mRigidBodyComponents.getBodyType(mEntity) == BodyType::STATIC) return;
// Update the linear velocity of the current body state
mWorld.mDynamicsComponents.setLinearVelocity(mEntity, linearVelocity);
@ -556,7 +556,7 @@ void RigidBody::setAngularVelocity(const Vector3& angularVelocity) {
// TODO : Make sure this method is not called from the internal physics engine
// If it is a static body, we do nothing
if (mWorld.mDynamicsComponents.getBodyType(mEntity) == BodyType::STATIC) return;
if (mWorld.mRigidBodyComponents.getBodyType(mEntity) == BodyType::STATIC) return;
// Set the angular velocity
mWorld.mDynamicsComponents.setAngularVelocity(mEntity, angularVelocity);
@ -617,13 +617,13 @@ void RigidBody::recomputeMassInformation() {
const Transform& transform = mWorld.mTransformComponents.getTransform(mEntity);
// If it is a STATIC or a KINEMATIC body
BodyType type = mWorld.mDynamicsComponents.getBodyType(mEntity);
BodyType type = mWorld.mRigidBodyComponents.getBodyType(mEntity);
if (type == BodyType::STATIC || type == BodyType::KINEMATIC) {
mWorld.mDynamicsComponents.setCenterOfMassWorld(mEntity, transform.getPosition());
return;
}
assert(mWorld.mDynamicsComponents.getBodyType(mEntity) == BodyType::DYNAMIC);
assert(mWorld.mRigidBodyComponents.getBodyType(mEntity) == BodyType::DYNAMIC);
// Compute the total mass of the body
const List<Entity>& proxyShapesEntities = mWorld.mCollisionBodyComponents.getProxyShapes(mEntity);
@ -736,7 +736,7 @@ bool RigidBody::isGravityEnabled() const {
void RigidBody::applyTorque(const Vector3& torque) {
// If it is not a dynamic body, we do nothing
if (mWorld.mDynamicsComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
if (mWorld.mRigidBodyComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
// Awake the body if it was sleeping
if (mWorld.mRigidBodyComponents.getIsSleeping(mEntity)) {

View File

@ -237,10 +237,10 @@ void CollisionDetection::computeMiddlePhase(OverlappingPairMap& overlappingPairs
const Entity body1Entity = body1->getEntity();
const Entity body2Entity = body2->getEntity();
const bool isStaticRigidBody1 = mWorld->mDynamicsComponents.hasComponent(body1Entity) &&
mWorld->mDynamicsComponents.getBodyType(body1Entity) == BodyType::STATIC;
const bool isStaticRigidBody2 = mWorld->mDynamicsComponents.hasComponent(body2Entity) &&
mWorld->mDynamicsComponents.getBodyType(body2Entity) == BodyType::STATIC;
const bool isStaticRigidBody1 = mWorld->mRigidBodyComponents.hasComponent(body1Entity) &&
mWorld->mRigidBodyComponents.getBodyType(body1Entity) == BodyType::STATIC;
const bool isStaticRigidBody2 = mWorld->mRigidBodyComponents.hasComponent(body2Entity) &&
mWorld->mRigidBodyComponents.getBodyType(body2Entity) == BodyType::STATIC;
// Check that at least one body is enabled (active and awake) and not static
bool isBody1Active = !mWorld->mCollisionBodyComponents.getIsEntityDisabled(body1Entity) && !isStaticRigidBody1;

View File

@ -39,7 +39,7 @@ DynamicsComponents::DynamicsComponents(MemoryAllocator& allocator)
sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) + sizeof(decimal) +
sizeof(decimal) + sizeof(decimal) + sizeof(decimal) + sizeof(Matrix3x3) + sizeof(Matrix3x3) +
sizeof(Vector3) + sizeof(Quaternion) + sizeof(Vector3) + sizeof(Vector3) + sizeof(bool) +
sizeof(bool) + sizeof(BodyType)) {
sizeof(bool)) {
// Allocate memory for the components data
allocate(INIT_NB_ALLOCATED_COMPONENTS);
@ -79,7 +79,6 @@ void DynamicsComponents::allocate(uint32 nbComponentsToAllocate) {
Vector3* newCentersOfMassWorld = reinterpret_cast<Vector3*>(newCentersOfMassLocal + nbComponentsToAllocate);
bool* newIsGravityEnabled = reinterpret_cast<bool*>(newCentersOfMassWorld + nbComponentsToAllocate);
bool* newIsAlreadyInIsland = reinterpret_cast<bool*>(newIsGravityEnabled + nbComponentsToAllocate);
BodyType* newBodyTypes = reinterpret_cast<BodyType*>(newIsAlreadyInIsland + nbComponentsToAllocate);
// If there was already components before
if (mNbComponents > 0) {
@ -106,7 +105,6 @@ void DynamicsComponents::allocate(uint32 nbComponentsToAllocate) {
memcpy(newCentersOfMassWorld, mCentersOfMassWorld, mNbComponents * sizeof(Vector3));
memcpy(newIsGravityEnabled, mIsGravityEnabled, mNbComponents * sizeof(bool));
memcpy(newIsAlreadyInIsland, mIsAlreadyInIsland, mNbComponents * sizeof(bool));
memcpy(newBodyTypes, mBodyTypes, mNbComponents * sizeof(BodyType));
// Deallocate previous memory
mMemoryAllocator.release(mBuffer, mNbAllocatedComponents * mComponentDataSize);
@ -134,7 +132,6 @@ void DynamicsComponents::allocate(uint32 nbComponentsToAllocate) {
mCentersOfMassWorld = newCentersOfMassWorld;
mIsGravityEnabled = newIsGravityEnabled;
mIsAlreadyInIsland = newIsAlreadyInIsland;
mBodyTypes = newBodyTypes;
mNbAllocatedComponents = nbComponentsToAllocate;
}
@ -167,7 +164,6 @@ void DynamicsComponents::addComponent(Entity bodyEntity, bool isSleeping, const
new (mCentersOfMassWorld + index) Vector3(component.worldPosition);
mIsGravityEnabled[index] = true;
mIsAlreadyInIsland[index] = false;
mBodyTypes[index] = component.bodyType;
// Map the entity with the new component lookup index
mMapEntityToComponentIndex.add(Pair<Entity, uint32>(bodyEntity, index));
@ -206,7 +202,6 @@ void DynamicsComponents::moveComponentToIndex(uint32 srcIndex, uint32 destIndex)
new (mCentersOfMassWorld + destIndex) Vector3(mCentersOfMassWorld[srcIndex]);
mIsGravityEnabled[destIndex] = mIsGravityEnabled[srcIndex];
mIsAlreadyInIsland[destIndex] = mIsAlreadyInIsland[srcIndex];
mBodyTypes[destIndex] = mBodyTypes[srcIndex];
// Destroy the source component
destroyComponent(srcIndex);
@ -247,7 +242,6 @@ void DynamicsComponents::swapComponents(uint32 index1, uint32 index2) {
Vector3 centerOfMassWorld1 = mCentersOfMassWorld[index1];
bool isGravityEnabled1 = mIsGravityEnabled[index1];
bool isAlreadyInIsland1 = mIsAlreadyInIsland[index1];
BodyType bodyType1 = mBodyTypes[index1];
// Destroy component 1
destroyComponent(index1);
@ -276,7 +270,6 @@ void DynamicsComponents::swapComponents(uint32 index1, uint32 index2) {
mCentersOfMassWorld[index2] = centerOfMassWorld1;
mIsGravityEnabled[index2] = isGravityEnabled1;
mIsAlreadyInIsland[index2] = isAlreadyInIsland1;
mBodyTypes[index2] = bodyType1;
// Update the entity to component index mapping
mMapEntityToComponentIndex.add(Pair<Entity, uint32>(entity1, index2));

View File

@ -126,9 +126,6 @@ class DynamicsComponents : public Components {
/// Array with the boolean value to know if the body has already been added into an island
bool* mIsAlreadyInIsland;
/// Array with the type of bodies (static, kinematic or dynamic)
BodyType* mBodyTypes;
// -------------------- Methods -------------------- //
/// Allocate memory for a given number of components
@ -150,11 +147,9 @@ class DynamicsComponents : public Components {
const Vector3& worldPosition;
BodyType bodyType;
/// Constructor
DynamicsComponent(const Vector3& worldPosition, BodyType bodyType)
: worldPosition(worldPosition), bodyType(bodyType) {
DynamicsComponent(const Vector3& worldPosition)
: worldPosition(worldPosition) {
}
};
@ -290,12 +285,6 @@ class DynamicsComponents : public Components {
/// Set the value to know if the entity is already in an island
void setIsAlreadyInIsland(Entity bodyEntity, bool isAlreadyInIsland);
/// Return the body type of a body
BodyType getBodyType(Entity bodyEntity);
/// Set the body type of a body
void setBodyType(Entity bodyEntity, BodyType bodyType);
// -------------------- Friendship -------------------- //
friend class BroadPhaseSystem;
@ -619,7 +608,7 @@ inline void DynamicsComponents::setIsGravityEnabled(Entity bodyEntity, bool isGr
mIsGravityEnabled[mMapEntityToComponentIndex[bodyEntity]] = isGravityEnabled;
}
/// Set the value to know if the entity is already in an island
// Set the value to know if the entity is already in an island
inline void DynamicsComponents::setIsAlreadyInIsland(Entity bodyEntity, bool isAlreadyInIsland) {
assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
@ -627,22 +616,6 @@ inline void DynamicsComponents::setIsAlreadyInIsland(Entity bodyEntity, bool isA
mIsAlreadyInIsland[mMapEntityToComponentIndex[bodyEntity]] = isAlreadyInIsland;
}
// Return the body type of a body
inline BodyType DynamicsComponents::getBodyType(Entity bodyEntity) {
assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
return mBodyTypes[mMapEntityToComponentIndex[bodyEntity]];
}
// Set the body type of a body
inline void DynamicsComponents::setBodyType(Entity bodyEntity, BodyType bodyType) {
assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
mBodyTypes[mMapEntityToComponentIndex[bodyEntity]] = bodyType;
}
}
#endif

View File

@ -26,6 +26,7 @@
// Libraries
#include "RigidBodyComponents.h"
#include "engine/EntityManager.h"
#include "body/RigidBody.h"
#include <cassert>
#include <random>
@ -35,7 +36,7 @@ using namespace reactphysics3d;
// Constructor
RigidBodyComponents::RigidBodyComponents(MemoryAllocator& allocator)
:Components(allocator, sizeof(Entity) + sizeof(RigidBody*) +
sizeof(bool) + sizeof(bool) + sizeof(decimal) ) {
sizeof(bool) + sizeof(bool) + sizeof(decimal) + sizeof(BodyType)) {
// Allocate memory for the components data
allocate(INIT_NB_ALLOCATED_COMPONENTS);
@ -59,6 +60,7 @@ void RigidBodyComponents::allocate(uint32 nbComponentsToAllocate) {
bool* newIsAllowedToSleep = reinterpret_cast<bool*>(newBodies + nbComponentsToAllocate);
bool* newIsSleeping = reinterpret_cast<bool*>(newIsAllowedToSleep + nbComponentsToAllocate);
decimal* newSleepTimes = reinterpret_cast<decimal*>(newIsSleeping + nbComponentsToAllocate);
BodyType* newBodyTypes = reinterpret_cast<BodyType*>(newSleepTimes + nbComponentsToAllocate);
// If there was already components before
if (mNbComponents > 0) {
@ -69,6 +71,7 @@ void RigidBodyComponents::allocate(uint32 nbComponentsToAllocate) {
memcpy(newIsAllowedToSleep, mIsAllowedToSleep, mNbComponents * sizeof(bool));
memcpy(newIsSleeping, mIsSleeping, mNbComponents * sizeof(bool));
memcpy(newSleepTimes, mSleepTimes, mNbComponents * sizeof(bool));
memcpy(newBodyTypes, mBodyTypes, mNbComponents * sizeof(BodyType));
// Deallocate previous memory
mMemoryAllocator.release(mBuffer, mNbAllocatedComponents * mComponentDataSize);
@ -81,6 +84,7 @@ void RigidBodyComponents::allocate(uint32 nbComponentsToAllocate) {
mIsSleeping = newIsSleeping;
mSleepTimes = newSleepTimes;
mNbAllocatedComponents = nbComponentsToAllocate;
mBodyTypes = newBodyTypes;
}
// Add a component
@ -95,6 +99,7 @@ void RigidBodyComponents::addComponent(Entity bodyEntity, bool isSleeping, const
mIsAllowedToSleep[index] = true;
mIsSleeping[index] = false;
mSleepTimes[index] = decimal(0);
mBodyTypes[index] = component.bodyType;
// Map the entity with the new component lookup index
mMapEntityToComponentIndex.add(Pair<Entity, uint32>(bodyEntity, index));
@ -117,6 +122,7 @@ void RigidBodyComponents::moveComponentToIndex(uint32 srcIndex, uint32 destIndex
mIsAllowedToSleep[destIndex] = mIsAllowedToSleep[srcIndex];
mIsSleeping[destIndex] = mIsSleeping[srcIndex];
mSleepTimes[destIndex] = mSleepTimes[srcIndex];
mBodyTypes[destIndex] = mBodyTypes[srcIndex];
// Destroy the source component
destroyComponent(srcIndex);
@ -138,6 +144,7 @@ void RigidBodyComponents::swapComponents(uint32 index1, uint32 index2) {
bool isAllowedToSleep1 = mIsAllowedToSleep[index1];
bool isSleeping1 = mIsSleeping[index1];
decimal sleepTime1 = mSleepTimes[index1];
BodyType bodyType1 = mBodyTypes[index1];
// Destroy component 1
destroyComponent(index1);
@ -150,6 +157,7 @@ void RigidBodyComponents::swapComponents(uint32 index1, uint32 index2) {
mIsAllowedToSleep[index2] = isAllowedToSleep1;
mIsSleeping[index2] = isSleeping1;
mSleepTimes[index2] = sleepTime1;
mBodyTypes[index2] = bodyType1;
// Update the entity to component index mapping
mMapEntityToComponentIndex.add(Pair<Entity, uint32>(entity1, index2));

View File

@ -39,6 +39,7 @@ namespace reactphysics3d {
class MemoryAllocator;
class EntityManager;
class RigidBody;
enum class BodyType;
// Class RigidBodyComponents
/**
@ -66,6 +67,9 @@ class RigidBodyComponents : public Components {
/// Array with values for elapsed time since the body velocity was below the sleep velocity
decimal* mSleepTimes;
/// Array with the type of bodies (static, kinematic or dynamic)
BodyType* mBodyTypes;
// -------------------- Methods -------------------- //
/// Allocate memory for a given number of components
@ -86,9 +90,10 @@ class RigidBodyComponents : public Components {
struct RigidBodyComponent {
RigidBody* body;
BodyType bodyType;
/// Constructor
RigidBodyComponent(RigidBody* body) : body(body) {
RigidBodyComponent(RigidBody* body, BodyType bodyType) : body(body), bodyType(bodyType) {
}
};
@ -124,6 +129,13 @@ class RigidBodyComponents : public Components {
/// Set the sleep time
void setSleepTime(Entity bodyEntity, decimal sleepTime) const;
/// Return the body type of a body
BodyType getBodyType(Entity bodyEntity);
/// Set the body type of a body
void setBodyType(Entity bodyEntity, BodyType bodyType);
};
// Return a pointer to a body rigid
@ -182,6 +194,23 @@ inline void RigidBodyComponents::setSleepTime(Entity bodyEntity, decimal sleepTi
mSleepTimes[mMapEntityToComponentIndex[bodyEntity]] = sleepTime;
}
// Return the body type of a body
inline BodyType RigidBodyComponents::getBodyType(Entity bodyEntity) {
assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
return mBodyTypes[mMapEntityToComponentIndex[bodyEntity]];
}
// Set the body type of a body
inline void RigidBodyComponents::setBodyType(Entity bodyEntity, BodyType bodyType) {
assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
mBodyTypes[mMapEntityToComponentIndex[bodyEntity]] = bodyType;
}
}
#endif

View File

@ -376,8 +376,7 @@ RigidBody* DynamicsWorld::createRigidBody(const Transform& transform) {
Entity entity = mEntityManager.createEntity();
mTransformComponents.addComponent(entity, false, TransformComponents::TransformComponent(transform));
mDynamicsComponents.addComponent(entity, false, DynamicsComponents::DynamicsComponent(transform.getPosition(),
BodyType::DYNAMIC));
mDynamicsComponents.addComponent(entity, false, DynamicsComponents::DynamicsComponent(transform.getPosition()));
// Create the rigid body
RigidBody* rigidBody = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
@ -387,7 +386,7 @@ RigidBody* DynamicsWorld::createRigidBody(const Transform& transform) {
CollisionBodyComponents::CollisionBodyComponent bodyComponent(rigidBody);
mCollisionBodyComponents.addComponent(entity, false, bodyComponent);
RigidBodyComponents::RigidBodyComponent rigidBodyComponent(rigidBody);
RigidBodyComponents::RigidBodyComponent rigidBodyComponent(rigidBody, BodyType::DYNAMIC);
mRigidBodyComponents.addComponent(entity, false, rigidBodyComponent);
// Add the rigid body to the physics world
@ -660,7 +659,8 @@ void DynamicsWorld::createIslands() {
if (mDynamicsComponents.mIsAlreadyInIsland[b]) continue;
// If the body is static, we go to the next body
if (mDynamicsComponents.mBodyTypes[b] == BodyType::STATIC) continue;
// TODO : Check if we still need this test if we loop over dynamicsComponents and static bodies are not part of them
if (mRigidBodyComponents.getBodyType(mDynamicsComponents.mBodies[b]) == BodyType::STATIC) continue;
// Reset the stack of bodies to visit
bodyEntityIndicesToVisit.clear();
@ -771,7 +771,7 @@ void DynamicsWorld::createIslands() {
// can also be included in the other islands
for (uint j=0; j < mDynamicsComponents.getNbEnabledComponents(); j++) {
if (mDynamicsComponents.mBodyTypes[j] == BodyType::STATIC) {
if (mRigidBodyComponents.getBodyType(mDynamicsComponents.mBodies[j]) == BodyType::STATIC) {
mDynamicsComponents.mIsAlreadyInIsland[j] = false;
}
}
@ -808,7 +808,7 @@ void DynamicsWorld::updateSleepingBodies() {
RigidBody* body = mRigidBodyComponents.getRigidBody(bodyEntity);
// Skip static bodies
if (mDynamicsComponents.getBodyType(body->getEntity()) == BodyType::STATIC) continue;
if (mRigidBodyComponents.getBodyType(bodyEntity) == BodyType::STATIC) continue;
// If the body is velocity is large enough to stay awake
if (mDynamicsComponents.getLinearVelocity(bodyEntity).lengthSquare() > sleepLinearVelocitySquare ||