Handle disabled components

This commit is contained in:
Daniel Chappuis 2019-03-16 08:40:50 +01:00
parent 91416ae5ba
commit ae076ad815
10 changed files with 66 additions and 68 deletions

View File

@ -268,6 +268,9 @@ void CollisionBody::setIsActive(bool isActive) {
Body::setIsActive(isActive); Body::setIsActive(isActive);
// Enable the components
mWorld.notifyBodyDisabled(mEntity, !isActive);
// If we have to activate the body // If we have to activate the body
if (isActive) { if (isActive) {
@ -453,10 +456,12 @@ void CollisionBody::setTransform(const Transform& transform) {
// Set the variable to know whether or not the body is sleeping // Set the variable to know whether or not the body is sleeping
void CollisionBody::setIsSleeping(bool isSleeping) { void CollisionBody::setIsSleeping(bool isSleeping) {
if (mIsSleeping == isSleeping) return;
Body::setIsSleeping(isSleeping); Body::setIsSleeping(isSleeping);
// Notify all the components // Notify all the components
mWorld.notifyBodySleeping(mEntity, isSleeping); mWorld.notifyBodyDisabled(mEntity, isSleeping);
} }
// Return the world-space coordinates of a point given the local-space coordinates of the body // Return the world-space coordinates of a point given the local-space coordinates of the body

View File

@ -70,12 +70,6 @@ class CollisionBody : public Body {
/// Type of body (static, kinematic or dynamic) /// Type of body (static, kinematic or dynamic)
BodyType mType; BodyType mType;
/// First element of the linked list of proxy collision shapes of this body
//ProxyShape* mProxyCollisionShapes;
/// Number of collision shapes
//uint mNbCollisionShapes;
/// First element of the linked list of contact manifolds involving this body /// First element of the linked list of contact manifolds involving this body
ContactManifoldListElement* mContactManifoldsList; ContactManifoldListElement* mContactManifoldsList;

View File

@ -92,7 +92,7 @@ void BodyComponents::addComponent(Entity bodyEntity, bool isSleeping, const Body
mNbComponents++; mNbComponents++;
assert(mSleepingStartIndex <= mNbComponents); assert(mDisabledStartIndex <= mNbComponents);
assert(mNbComponents == static_cast<uint32>(mMapEntityToComponentIndex.size())); assert(mNbComponents == static_cast<uint32>(mMapEntityToComponentIndex.size()));
} }

View File

@ -109,9 +109,6 @@ class BodyComponents : public Components {
/// Return the list of proxy-shapes of a body /// Return the list of proxy-shapes of a body
const List<Entity>& getProxyShapes(Entity bodyEntity) const; const List<Entity>& getProxyShapes(Entity bodyEntity) const;
/// Notify if a given entity is sleeping or not
void setIsEntitySleeping(Entity bodyEntity, bool isSleeping);
}; };
// Add a proxy-shape to a body component // Add a proxy-shape to a body component

View File

@ -34,7 +34,7 @@ using namespace reactphysics3d;
Components::Components(MemoryAllocator& allocator, size_t componentDataSize) Components::Components(MemoryAllocator& allocator, size_t componentDataSize)
: mMemoryAllocator(allocator), mNbComponents(0), mComponentDataSize(componentDataSize), : mMemoryAllocator(allocator), mNbComponents(0), mComponentDataSize(componentDataSize),
mNbAllocatedComponents(0), mBuffer(nullptr), mMapEntityToComponentIndex(allocator), mNbAllocatedComponents(0), mBuffer(nullptr), mMapEntityToComponentIndex(allocator),
mSleepingStartIndex(0) { mDisabledStartIndex(0) {
} }
@ -67,27 +67,27 @@ uint32 Components::prepareAddComponent(bool isSleeping) {
uint32 index; uint32 index;
// If the component to add is part of a sleeping entity or there are no sleeping entity // If the component to add is part of a disabled entity or there are no disabled entity
if (isSleeping) { if (isSleeping) {
// Add the component at the end of the array // Add the component at the end of the array
index = mNbComponents; index = mNbComponents;
mSleepingStartIndex = index; mDisabledStartIndex = index;
} }
// If the component to add is not part of a sleeping entity // If the component to add is not part of a disabled entity
else { else {
// If there already are sleeping components // If there already are disabled components
if (mSleepingStartIndex != mNbComponents) { if (mDisabledStartIndex != mNbComponents) {
// Move the first sleeping component to the end of the array // Move the first disabled component to the end of the array
moveComponentToIndex(mSleepingStartIndex, mNbComponents); moveComponentToIndex(mDisabledStartIndex, mNbComponents);
} }
index = mSleepingStartIndex; index = mDisabledStartIndex;
mSleepingStartIndex++; mDisabledStartIndex++;
} }
return index; return index;
@ -109,81 +109,81 @@ void Components::removeComponent(Entity entity) {
assert(index < mNbComponents); assert(index < mNbComponents);
// We want to keep the arrays tightly packed. Therefore, when a component is removed, // We want to keep the arrays tightly packed. Therefore, when a component is removed,
// we replace it with the last element of the array. But we need to make sure that sleeping // we replace it with the last element of the array. But we need to make sure that enabled
// and non-sleeping components stay grouped together. // and disabled components stay grouped together.
// Destroy the component // Destroy the component
destroyComponent(index); destroyComponent(index);
// If the component to remove is sleeping // If the component to remove is disabled
if (index >= mSleepingStartIndex) { if (index >= mDisabledStartIndex) {
// If the component is not the last one // If the component is not the last one
if (index != mNbComponents - 1) { if (index != mNbComponents - 1) {
// We replace it by the last sleeping component // We replace it by the last disabled component
moveComponentToIndex(mNbComponents - 1, index); moveComponentToIndex(mNbComponents - 1, index);
} }
} }
else { // If the component to remove is not sleeping else { // If the component to remove is enabled
// If it not the last awake component // If it not the last enabled component
if (index != mSleepingStartIndex - 1) { if (index != mDisabledStartIndex - 1) {
// We replace it by the last awake component // We replace it by the last enabled component
moveComponentToIndex(mSleepingStartIndex - 1, index); moveComponentToIndex(mDisabledStartIndex - 1, index);
} }
// If there are sleeping components at the end // If there are disabled components at the end
if (mSleepingStartIndex != mNbComponents) { if (mDisabledStartIndex != mNbComponents) {
// We replace the last awake component by the last sleeping component // We replace the last enabled component by the last disabled component
moveComponentToIndex(mNbComponents - 1, mSleepingStartIndex - 1); moveComponentToIndex(mNbComponents - 1, mDisabledStartIndex - 1);
} }
mSleepingStartIndex--; mDisabledStartIndex--;
} }
mNbComponents--; mNbComponents--;
assert(mSleepingStartIndex <= mNbComponents); assert(mDisabledStartIndex <= mNbComponents);
assert(mNbComponents == static_cast<uint32>(mMapEntityToComponentIndex.size())); assert(mNbComponents == static_cast<uint32>(mMapEntityToComponentIndex.size()));
} }
// Notify if a given entity is sleeping or not // Notify if a given entity is disabled (sleeping or inactive) or not
void Components::setIsEntitySleeping(Entity entity, bool isSleeping) { void Components::setIsEntityDisabled(Entity entity, bool isDisabled) {
const uint32 index = mMapEntityToComponentIndex[entity]; const uint32 index = mMapEntityToComponentIndex[entity];
// If the component was sleeping and is not sleeping anymore // If the component was disabled and is not disabled anymore
if (!isSleeping && index >= mSleepingStartIndex) { if (!isDisabled && index >= mDisabledStartIndex) {
assert(mSleepingStartIndex < mNbComponents); assert(mDisabledStartIndex < mNbComponents);
// If the sleeping component is not the first sleeping component // If the disabled component is not the first disabled component
if (mSleepingStartIndex != index) { if (mDisabledStartIndex != index) {
// Swap the first sleeping component with the one we need to wake up // Swap the first disabled component with the one we need to enable it
swapComponents(index, mSleepingStartIndex); swapComponents(index, mDisabledStartIndex);
} }
mSleepingStartIndex++; mDisabledStartIndex++;
} }
// If the component was awake and must now go to sleep // If the component was enabled and must now be disabled
else if (isSleeping && index < mSleepingStartIndex) { else if (isDisabled && index < mDisabledStartIndex) {
assert(mSleepingStartIndex > 0); assert(mDisabledStartIndex > 0);
// If the awake component is not the only awake component // If the enabled component is not the only enabled component
if (index != mSleepingStartIndex - 1) { if (index != mDisabledStartIndex - 1) {
// Swap the last awake component with the one we need to put to sleep // Swap the last enabled component with the one we need to disable
swapComponents(index, mSleepingStartIndex - 1); swapComponents(index, mDisabledStartIndex - 1);
} }
mSleepingStartIndex--; mDisabledStartIndex--;
} }
assert(mSleepingStartIndex <= mNbComponents); assert(mDisabledStartIndex <= mNbComponents);
assert(mNbComponents == static_cast<uint32>(mMapEntityToComponentIndex.size())); assert(mNbComponents == static_cast<uint32>(mMapEntityToComponentIndex.size()));
} }

View File

@ -75,8 +75,9 @@ class Components {
/// Map an entity to the index of its component in the array /// Map an entity to the index of its component in the array
Map<Entity, uint32> mMapEntityToComponentIndex; Map<Entity, uint32> mMapEntityToComponentIndex;
/// Index of the first component of a sleeping entity (sleeping components are stored at the end) /// Index of the first component of a disabled (sleeping or inactive) entity
uint32 mSleepingStartIndex; /// Disabled components are stored at the end of the components array
uint32 mDisabledStartIndex;
/// Compute the index where we need to insert the new component /// Compute the index where we need to insert the new component
uint32 prepareAddComponent(bool isSleeping); uint32 prepareAddComponent(bool isSleeping);
@ -106,8 +107,8 @@ class Components {
/// Remove a component /// Remove a component
void removeComponent(Entity entity); void removeComponent(Entity entity);
// Notify if a given entity is sleeping or not // Notify if a given entity is disabled (sleeping or inactive) or not
void setIsEntitySleeping(Entity entity, bool isSleeping); void setIsEntityDisabled(Entity entity, bool isDisabled);
/// Return the number of components /// Return the number of components
uint32 getNbComponents() const; uint32 getNbComponents() const;

View File

@ -125,7 +125,7 @@ void ProxyShapesComponents::addComponent(Entity proxyShapeEntity, bool isSleepin
mNbComponents++; mNbComponents++;
assert(mSleepingStartIndex <= mNbComponents); assert(mDisabledStartIndex <= mNbComponents);
} }
// Move a component from a source to a destination index in the components array // Move a component from a source to a destination index in the components array

View File

@ -89,7 +89,7 @@ void TransformComponents::addComponent(Entity bodyEntity, bool isSleeping, const
mNbComponents++; mNbComponents++;
assert(mSleepingStartIndex <= mNbComponents); assert(mDisabledStartIndex <= mNbComponents);
assert(mNbComponents == static_cast<uint32>(mMapEntityToComponentIndex.size())); assert(mNbComponents == static_cast<uint32>(mMapEntityToComponentIndex.size()));
} }

View File

@ -246,19 +246,20 @@ void CollisionWorld::resetContactManifoldListsOfBodies() {
} }
} }
// Notify the world if a body is sleeping or not // Notify the world if a body is disabled (sleeping or inactive) or not
void CollisionWorld::notifyBodySleeping(Entity bodyEntity, bool isSleeping) { void CollisionWorld::notifyBodyDisabled(Entity bodyEntity, bool isDisabled) {
// TODO : Make sure we notify all the components here ... // TODO : Make sure we notify all the components here ...
// Notify all the components // Notify all the components
mTransformComponents.setIsEntitySleeping(bodyEntity, isSleeping); mBodyComponents.setIsEntityDisabled(bodyEntity, isDisabled);
mTransformComponents.setIsEntityDisabled(bodyEntity, isDisabled);
// For each proxy-shape of the body // For each proxy-shape of the body
const List<Entity>& proxyShapesEntities = mBodyComponents.getProxyShapes(bodyEntity); const List<Entity>& proxyShapesEntities = mBodyComponents.getProxyShapes(bodyEntity);
for (uint i=0; i < proxyShapesEntities.size(); i++) { for (uint i=0; i < proxyShapesEntities.size(); i++) {
mProxyShapesComponents.setIsEntitySleeping(proxyShapesEntities[i], isSleeping); mProxyShapesComponents.setIsEntityDisabled(proxyShapesEntities[i], isDisabled);
} }
} }

View File

@ -129,8 +129,8 @@ class CollisionWorld {
/// Reset all the contact manifolds linked list of each body /// Reset all the contact manifolds linked list of each body
void resetContactManifoldListsOfBodies(); void resetContactManifoldListsOfBodies();
/// Notify the world if a body is sleeping or not /// Notify the world if a body is disabled (slepping or inactive) or not
void notifyBodySleeping(Entity entity, bool isSleeping); void notifyBodyDisabled(Entity entity, bool isDisabled);
public : public :