diff --git a/src/body/Body.cpp b/src/body/Body.cpp index f1f80b0a..f0d362a9 100644 --- a/src/body/Body.cpp +++ b/src/body/Body.cpp @@ -25,6 +25,7 @@ // Libraries #include "Body.h" +#include "engine/CollisionWorld.h" #include "collision/shapes/CollisionShape.h" #include "utils/Logger.h" @@ -35,9 +36,8 @@ using namespace reactphysics3d; /** * @param id ID of the new body */ -Body::Body(Entity entity) - : mEntity(entity), mIsAllowedToSleep(true), mIsActive(true), - mIsSleeping(false), mSleepTime(0), mUserData(nullptr) { +Body::Body(Entity entity, CollisionWorld& world) + : mEntity(entity), mWorld(world) { #ifdef IS_LOGGING_ACTIVE mLogger = nullptr; @@ -46,44 +46,54 @@ Body::Body(Entity entity) } // Set whether or not the body is active +/// An inactive body does not participate in collision detection, +/// is not simulated and will not be hit in a ray casting query. +/// A body is active by default. If you set this +/// value to "false", all the proxy shapes of this body will be +/// removed from the broad-phase. If you set this value to "true", +/// all the proxy shapes will be added to the broad-phase. A joint +/// connected to an inactive body will also be inactive. /** * @param isActive True if you want to activate the body */ void Body::setIsActive(bool isActive) { - mIsActive = isActive; - setIsSleeping(isActive); + setIsSleeping(!isActive); + + mWorld.mBodyComponents.setIsActive(mEntity, isActive); RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, "Body " + std::to_string(mEntity.id) + ": Set isActive=" + - (mIsActive ? "true" : "false")); + (isActive ? "true" : "false")); } // Set the variable to know whether or not the body is sleeping void Body::setIsSleeping(bool isSleeping) { + bool isBodySleeping = mWorld.mBodyComponents.getIsSleeping(mEntity); + // If the body is not active, do nothing (it is sleeping) - if (!mIsActive) { - assert(mIsSleeping); + if (!mWorld.mBodyComponents.getIsActive(mEntity)) { + assert(isBodySleeping); return; } if (isSleeping) { - mSleepTime = decimal(0.0); + mWorld.mBodyComponents.setSleepTime(mEntity, decimal(0.0)); } else { - if (mIsSleeping) { - mSleepTime = decimal(0.0); + if (isBodySleeping) { + mWorld.mBodyComponents.setSleepTime(mEntity, decimal(0.0)); } } - if (mIsSleeping != isSleeping) { + if (isBodySleeping != isSleeping) { - mIsSleeping = isSleeping; + mWorld.mBodyComponents.setIsSleeping(mEntity, isSleeping); RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, "Body " + std::to_string(mEntity.id) + ": Set isSleeping=" + - (mIsSleeping ? "true" : "false")); + (isSleeping ? "true" : "false")); } } @@ -92,12 +102,52 @@ void Body::setIsSleeping(bool isSleeping) { * @param isAllowedToSleep True if the body is allowed to sleep */ void Body::setIsAllowedToSleep(bool isAllowedToSleep) { - mIsAllowedToSleep = isAllowedToSleep; - if (!mIsAllowedToSleep) setIsSleeping(false); + mWorld.mBodyComponents.setIsAllowedToSleep(mEntity, isAllowedToSleep); + + if (!isAllowedToSleep) setIsSleeping(false); RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, "Body " + std::to_string(mEntity.id) + ": Set isAllowedToSleep=" + - (mIsAllowedToSleep ? "true" : "false")); + (isAllowedToSleep ? "true" : "false")); } +// Return whether or not the body is allowed to sleep +/** + * @return True if the body is allowed to sleep and false otherwise + */ +bool Body::isAllowedToSleep() const { + return mWorld.mBodyComponents.getIsAllowedToSleep(mEntity); +} + +// Return whether or not the body is sleeping +/** + * @return True if the body is currently sleeping and false otherwise + */ +bool Body::isSleeping() const { + return mWorld.mBodyComponents.getIsSleeping(mEntity); +} + +// Return true if the body is active +/** + * @return True if the body currently active and false otherwise + */ +bool Body::isActive() const { + return mWorld.mBodyComponents.getIsActive(mEntity); +} + +// Return a pointer to the user data attached to this body +/** + * @return A pointer to the user data you have attached to the body + */ +void* Body::getUserData() const { + return mWorld.mBodyComponents.getUserData(mEntity); +} + +// Attach user data to this body +/** + * @param userData A pointer to the user data you want to attach to the body + */ +void Body::setUserData(void* userData) { + mWorld.mBodyComponents.setUserData(mEntity, userData); +} diff --git a/src/body/Body.h b/src/body/Body.h index 39093dd6..6edbf3c5 100644 --- a/src/body/Body.h +++ b/src/body/Body.h @@ -36,6 +36,7 @@ namespace reactphysics3d { // Declarations class Logger; +class CollisionWorld; // TODO : Make this class abstract // Class Body @@ -53,30 +54,8 @@ class Body { /// Identifier of the entity in the ECS Entity mEntity; - /// True if the body is allowed to go to sleep for better efficiency - bool mIsAllowedToSleep; - - /// True if the body is active. - /// An inactive body does not participate in collision detection, - /// is not simulated and will not be hit in a ray casting query. - /// A body is active by default. If you set this - /// value to "false", all the proxy shapes of this body will be - /// removed from the broad-phase. If you set this value to "true", - /// all the proxy shapes will be added to the broad-phase. A joint - /// connected to an inactive body will also be inactive. - // TODO : Make sure we correctly use this field with ECS - bool mIsActive; - - /// True if the body is sleeping (for sleeping technique) - // TODO : DELETE THIS - bool mIsSleeping; - - // TODO : Move this into the body components - /// Elapsed time since the body velocity was bellow the sleep velocity - decimal mSleepTime; - - /// Pointer that can be used to attach user data to the body - void* mUserData; + /// Reference to the world the body belongs to + CollisionWorld& mWorld; #ifdef IS_LOGGING_ACTIVE @@ -84,12 +63,17 @@ class Body { Logger* mLogger; #endif + // -------------------- Methods -------------------- // + + /// Set the variable to know whether or not the body is sleeping + virtual void setIsSleeping(bool isSleeping); + public : // -------------------- Methods -------------------- // /// Constructor - Body(Entity entity); + Body(Entity entity, CollisionWorld& world); /// Deleted copy-constructor Body(const Body& body) = delete; @@ -109,9 +93,6 @@ class Body { /// Set whether or not the body is allowed to go to sleep void setIsAllowedToSleep(bool isAllowedToSleep); - /// Set the variable to know whether or not the body is sleeping - virtual void setIsSleeping(bool isSleeping); - /// Return whether or not the body is sleeping bool isSleeping() const; @@ -133,22 +114,6 @@ class Body { void setLogger(Logger* logger); #endif - // TODO : Check if those operators are still used - - /* - /// Smaller than operator - bool operator<(const Body& body2) const; - - /// Larger than operator - bool operator>(const Body& body2) const; - - /// Equal operator - bool operator==(const Body& body2) const; - - /// Not equal operator - bool operator!=(const Body& body2) const; - */ - // -------------------- Friendship -------------------- // friend class DynamicsWorld; @@ -162,46 +127,6 @@ inline Entity Body::getEntity() const { return mEntity; } -// Return whether or not the body is allowed to sleep -/** - * @return True if the body is allowed to sleep and false otherwise - */ -inline bool Body::isAllowedToSleep() const { - return mIsAllowedToSleep; -} - -// Return whether or not the body is sleeping -/** - * @return True if the body is currently sleeping and false otherwise - */ -inline bool Body::isSleeping() const { - return mIsSleeping; -} - -// Return true if the body is active -/** - * @return True if the body currently active and false otherwise - */ -inline bool Body::isActive() const { - return mIsActive; -} - -// Return a pointer to the user data attached to this body -/** - * @return A pointer to the user data you have attached to the body - */ -inline void* Body::getUserData() const { - return mUserData; -} - -// Attach user data to this body -/** - * @param userData A pointer to the user data you want to attach to the body - */ -inline void Body::setUserData(void* userData) { - mUserData = userData; -} - #ifdef IS_LOGGING_ACTIVE // Set the logger @@ -211,28 +136,6 @@ inline void Body::setLogger(Logger* logger) { #endif -/* -// Smaller than operator -inline bool Body::operator<(const Body& body2) const { - return (mID < body2.mID); -} - -// Larger than operator -inline bool Body::operator>(const Body& body2) const { - return (mID > body2.mID); -} - -// Equal operator -inline bool Body::operator==(const Body& body2) const { - return (mID == body2.mID); -} - -// Not equal operator -inline bool Body::operator!=(const Body& body2) const { - return (mID != body2.mID); -} -*/ - } #endif diff --git a/src/body/CollisionBody.cpp b/src/body/CollisionBody.cpp index 64d4323e..9b99cde1 100644 --- a/src/body/CollisionBody.cpp +++ b/src/body/CollisionBody.cpp @@ -40,7 +40,7 @@ using namespace reactphysics3d; * @param id ID of the body */ CollisionBody::CollisionBody(CollisionWorld& world, Entity entity) - : Body(entity), mType(BodyType::DYNAMIC), mWorld(world) { + : Body(entity, world), mType(BodyType::DYNAMIC) { #ifdef IS_PROFILING_ACTIVE mProfiler = nullptr; @@ -68,8 +68,7 @@ CollisionBody::~CollisionBody() { * @return A pointer to the proxy shape that has been created to link the body to * the new collision shape you have added. */ -ProxyShape* CollisionBody::addCollisionShape(CollisionShape* collisionShape, - const Transform& transform) { +ProxyShape* CollisionBody::addCollisionShape(CollisionShape* collisionShape, const Transform& transform) { // Create a new entity for the proxy-shape Entity proxyShapeEntity = mWorld.mEntityManager.createEntity(); @@ -86,7 +85,8 @@ ProxyShape* CollisionBody::addCollisionShape(CollisionShape* collisionShape, ProxyShapeComponents::ProxyShapeComponent proxyShapeComponent(mEntity, proxyShape, -1, AABB(localBoundsMin, localBoundsMax), transform, collisionShape, decimal(1), 0x0001, 0xFFFF); - mWorld.mProxyShapesComponents.addComponent(proxyShapeEntity, mIsSleeping, proxyShapeComponent); + bool isSleeping = mWorld.mBodyComponents.getIsSleeping(mEntity); + mWorld.mProxyShapesComponents.addComponent(proxyShapeEntity, isSleeping, proxyShapeComponent); mWorld.mBodyComponents.addProxyShapeToBody(mEntity, proxyShapeEntity); @@ -228,7 +228,7 @@ void CollisionBody::updateBroadPhaseState() const { void CollisionBody::setIsActive(bool isActive) { // If the state does not change - if (mIsActive == isActive) return; + if (mWorld.mBodyComponents.getIsActive(mEntity) == isActive) return; Body::setIsActive(isActive); @@ -269,7 +269,7 @@ void CollisionBody::setIsActive(bool isActive) { RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, "Body " + std::to_string(mEntity.id) + ": Set isActive=" + - (mIsActive ? "true" : "false")); + (isActive ? "true" : "false")); } // Ask the broad-phase to test again the collision shapes of the body for collision @@ -318,7 +318,7 @@ bool CollisionBody::testPointInside(const Vector3& worldPoint) const { bool CollisionBody::raycast(const Ray& ray, RaycastInfo& raycastInfo) { // If the body is not active, it cannot be hit by rays - if (!mIsActive) return false; + if (!mWorld.mBodyComponents.getIsActive(mEntity)) return false; bool isHit = false; Ray rayTemp(ray); @@ -398,7 +398,7 @@ void CollisionBody::setTransform(const Transform& transform) { // Set the variable to know whether or not the body is sleeping void CollisionBody::setIsSleeping(bool isSleeping) { - if (mIsSleeping == isSleeping) return; + if (mWorld.mBodyComponents.getIsSleeping(mEntity) == isSleeping) return; Body::setIsSleeping(isSleeping); diff --git a/src/body/CollisionBody.h b/src/body/CollisionBody.h index 846e593c..a2b802dd 100644 --- a/src/body/CollisionBody.h +++ b/src/body/CollisionBody.h @@ -71,9 +71,6 @@ class CollisionBody : public Body { /// Type of body (static, kinematic or dynamic) BodyType mType; - /// Reference to the world the body belongs to - CollisionWorld& mWorld; - #ifdef IS_PROFILING_ACTIVE /// Pointer to the profiler diff --git a/src/body/RigidBody.cpp b/src/body/RigidBody.cpp index 39876931..158da8d4 100644 --- a/src/body/RigidBody.cpp +++ b/src/body/RigidBody.cpp @@ -162,7 +162,7 @@ void RigidBody::applyForce(const Vector3& force, const Vector3& point) { if (mType != BodyType::DYNAMIC) return; // Awake the body if it was sleeping - if (mIsSleeping) { + if (mWorld.mBodyComponents.getIsSleeping(mEntity)) { setIsSleeping(false); } @@ -214,7 +214,7 @@ void RigidBody::applyForceToCenterOfMass(const Vector3& force) { if (mType != BodyType::DYNAMIC) return; // Awake the body if it was sleeping - if (mIsSleeping) { + if (mWorld.mBodyComponents.getIsSleeping(mEntity)) { setIsSleeping(false); } @@ -399,7 +399,8 @@ ProxyShape* RigidBody::addCollisionShape(CollisionShape* collisionShape, ProxyShapeComponents::ProxyShapeComponent proxyShapeComponent(mEntity, proxyShape, -1, AABB(localBoundsMin, localBoundsMax), transform, collisionShape, mass, 0x0001, 0xFFFF); - mWorld.mProxyShapesComponents.addComponent(proxyShapeEntity, mIsSleeping, proxyShapeComponent); + bool isSleeping = mWorld.mBodyComponents.getIsSleeping(mEntity); + mWorld.mProxyShapesComponents.addComponent(proxyShapeEntity, isSleeping, proxyShapeComponent); mWorld.mBodyComponents.addProxyShapeToBody(mEntity, proxyShapeEntity); @@ -725,7 +726,7 @@ void RigidBody::applyTorque(const Vector3& torque) { if (mType != BodyType::DYNAMIC) return; // Awake the body if it was sleeping - if (mIsSleeping) { + if (mWorld.mBodyComponents.getIsSleeping(mEntity)) { setIsSleeping(false); } diff --git a/src/body/RigidBody.h b/src/body/RigidBody.h index 2c9222bf..022bea9c 100644 --- a/src/body/RigidBody.h +++ b/src/body/RigidBody.h @@ -81,6 +81,9 @@ class RigidBody : public CollisionBody { /// Update the world inverse inertia tensor of the body void updateInertiaTensorInverseWorld(); + /// Set the variable to know whether or not the body is sleeping + virtual void setIsSleeping(bool isSleeping) override; + public : // -------------------- Methods -------------------- // @@ -118,9 +121,6 @@ class RigidBody : public CollisionBody { /// Set the angular velocity. void setAngularVelocity(const Vector3& angularVelocity); - /// Set the variable to know whether or not the body is sleeping - virtual void setIsSleeping(bool isSleeping) override; - /// Set the local inertia tensor of the body (in body coordinates) void setInertiaTensorLocal(const Matrix3x3& inertiaTensorLocal); diff --git a/src/components/BodyComponents.cpp b/src/components/BodyComponents.cpp index 8187492c..bf49cc62 100644 --- a/src/components/BodyComponents.cpp +++ b/src/components/BodyComponents.cpp @@ -34,7 +34,9 @@ using namespace reactphysics3d; // Constructor BodyComponents::BodyComponents(MemoryAllocator& allocator) - :Components(allocator, sizeof(Entity) + sizeof(Body*) + sizeof(List)) { + :Components(allocator, sizeof(Entity) + sizeof(Body*) + sizeof(List) + + sizeof(bool) + sizeof(bool) + sizeof(bool) + sizeof(decimal) + + sizeof(void*)) { // Allocate memory for the components data allocate(INIT_NB_ALLOCATED_COMPONENTS); @@ -56,6 +58,11 @@ void BodyComponents::allocate(uint32 nbComponentsToAllocate) { Entity* newBodiesEntities = static_cast(newBuffer); Body** newBodies = reinterpret_cast(newBodiesEntities + nbComponentsToAllocate); List* newProxyShapes = reinterpret_cast*>(newBodies + nbComponentsToAllocate); + bool* newIsAllowedToSleep = reinterpret_cast(newProxyShapes + nbComponentsToAllocate); + bool* newIsActive = reinterpret_cast(newIsAllowedToSleep + nbComponentsToAllocate); + bool* newIsSleeping = reinterpret_cast(newIsActive + nbComponentsToAllocate); + decimal* newSleepTimes = reinterpret_cast(newIsSleeping + nbComponentsToAllocate); + void** newUserData = reinterpret_cast(newIsSleeping + nbComponentsToAllocate); // If there was already components before if (mNbComponents > 0) { @@ -64,6 +71,11 @@ void BodyComponents::allocate(uint32 nbComponentsToAllocate) { memcpy(newBodiesEntities, mBodiesEntities, mNbComponents * sizeof(Entity)); memcpy(newBodies, mBodies, mNbComponents * sizeof(Body*)); memcpy(newProxyShapes, mProxyShapes, mNbComponents * sizeof(List)); + memcpy(newIsAllowedToSleep, mIsAllowedToSleep, mNbComponents * sizeof(bool)); + memcpy(newIsActive, mIsActive, mNbComponents * sizeof(bool)); + memcpy(newIsSleeping, mIsSleeping, mNbComponents * sizeof(bool)); + memcpy(newSleepTimes, mSleepTimes, mNbComponents * sizeof(bool)); + memcpy(newUserData, mUserData, mNbComponents * sizeof(void*)); // Deallocate previous memory mMemoryAllocator.release(mBuffer, mNbAllocatedComponents * mComponentDataSize); @@ -73,6 +85,11 @@ void BodyComponents::allocate(uint32 nbComponentsToAllocate) { mBodiesEntities = newBodiesEntities; mBodies = newBodies; mProxyShapes = newProxyShapes; + mIsAllowedToSleep = newIsAllowedToSleep; + mIsActive = newIsActive; + mIsSleeping = newIsSleeping; + mSleepTimes = newSleepTimes; + mUserData = newUserData; mNbAllocatedComponents = nbComponentsToAllocate; } @@ -86,6 +103,11 @@ void BodyComponents::addComponent(Entity bodyEntity, bool isSleeping, const Body new (mBodiesEntities + index) Entity(bodyEntity); mBodies[index] = component.body; new (mProxyShapes + index) List(mMemoryAllocator); + mIsAllowedToSleep[index] = true; + mIsActive[index] = true; + mIsSleeping[index] = false; + mSleepTimes[index] = decimal(0); + mUserData[index] = nullptr; // Map the entity with the new component lookup index mMapEntityToComponentIndex.add(Pair(bodyEntity, index)); @@ -106,6 +128,11 @@ void BodyComponents::moveComponentToIndex(uint32 srcIndex, uint32 destIndex) { new (mBodiesEntities + destIndex) Entity(mBodiesEntities[srcIndex]); mBodies[destIndex] = mBodies[srcIndex]; new (mProxyShapes + destIndex) List(mProxyShapes[srcIndex]); + mIsAllowedToSleep[destIndex] = mIsAllowedToSleep[srcIndex]; + mIsActive[destIndex] = mIsActive[srcIndex]; + mIsSleeping[destIndex] = mIsSleeping[srcIndex]; + mSleepTimes[destIndex] = mSleepTimes[srcIndex]; + mUserData[destIndex] = mUserData[srcIndex]; // Destroy the source component destroyComponent(srcIndex); @@ -125,6 +152,11 @@ void BodyComponents::swapComponents(uint32 index1, uint32 index2) { Entity entity1(mBodiesEntities[index1]); Body* body1 = mBodies[index1]; List proxyShapes1(mProxyShapes[index1]); + bool isAllowedToSleep1 = mIsAllowedToSleep[index1]; + bool isActive1 = mIsActive[index1]; + bool isSleeping1 = mIsSleeping[index1]; + decimal sleepTime1 = mSleepTimes[index1]; + void* userData1 = mUserData[index1]; // Destroy component 1 destroyComponent(index1); @@ -135,6 +167,10 @@ void BodyComponents::swapComponents(uint32 index1, uint32 index2) { new (mBodiesEntities + index2) Entity(entity1); new (mProxyShapes + index2) List(proxyShapes1); mBodies[index2] = body1; + mIsAllowedToSleep[index2] = isAllowedToSleep1; + mIsActive[index2] = isActive1; + mIsSleeping[index2] = isSleeping1; + mUserData[index2] = userData1; // Update the entity to component index mapping mMapEntityToComponentIndex.add(Pair(entity1, index2)); @@ -156,4 +192,5 @@ void BodyComponents::destroyComponent(uint32 index) { mBodiesEntities[index].~Entity(); mBodies[index] = nullptr; mProxyShapes[index].~List(); + mUserData[index] = nullptr; } diff --git a/src/components/BodyComponents.h b/src/components/BodyComponents.h index 88edaa57..e84e4f88 100644 --- a/src/components/BodyComponents.h +++ b/src/components/BodyComponents.h @@ -60,6 +60,21 @@ class BodyComponents : public Components { /// Array with the list of proxy-shapes of each body List* mProxyShapes; + /// Array of boolean values to know if the body is allowed to go to sleep + bool* mIsAllowedToSleep; + + /// Array of boolean values to know if the body is active. + bool* mIsActive; + + /// Array of boolean values to know if the body is sleeping + bool* mIsSleeping; + + /// Array with values for elapsed time since the body velocity was bellow the sleep velocity + decimal* mSleepTimes; + + /// Array of pointers that can be used to attach user data to the body + void** mUserData; + // -------------------- Methods -------------------- // /// Allocate memory for a given number of components @@ -109,6 +124,36 @@ class BodyComponents : public Components { /// Return the list of proxy-shapes of a body const List& getProxyShapes(Entity bodyEntity) const; + + /// Return true if the body is allowed to sleep + bool getIsAllowedToSleep(Entity bodyEntity) const; + + /// Set the value to know if the body is allowed to sleep + void setIsAllowedToSleep(Entity bodyEntity, bool isAllowedToSleep) const; + + /// Return true if the body is active + bool getIsActive(Entity bodyEntity) const; + + /// Set the value to know if the body is active + void setIsActive(Entity bodyEntity, bool isActive) const; + + /// Return true if the body is sleeping + bool getIsSleeping(Entity bodyEntity) const; + + /// Set the value to know if the body is sleeping + void setIsSleeping(Entity bodyEntity, bool isSleeping) const; + + /// Return the sleep time + decimal getSleepTime(Entity bodyEntity) const; + + /// Set the sleep time + void setSleepTime(Entity bodyEntity, decimal sleepTime) const; + + /// Return the user data associated with the body + void* getUserData(Entity bodyEntity) const; + + /// Set the user data associated with the body + void setUserData(Entity bodyEntity, void* userData) const; }; // Add a proxy-shape to a body component @@ -143,6 +188,86 @@ inline const List& BodyComponents::getProxyShapes(Entity bodyEntity) con return mProxyShapes[mMapEntityToComponentIndex[bodyEntity]]; } +// Return true if the body is allowed to sleep +inline bool BodyComponents::getIsAllowedToSleep(Entity bodyEntity) const { + + assert(mMapEntityToComponentIndex.containsKey(bodyEntity)); + + return mIsAllowedToSleep[mMapEntityToComponentIndex[bodyEntity]]; +} + +// Set the value to know if the body is allowed to sleep +inline void BodyComponents::setIsAllowedToSleep(Entity bodyEntity, bool isAllowedToSleep) const { + + assert(mMapEntityToComponentIndex.containsKey(bodyEntity)); + + mIsAllowedToSleep[mMapEntityToComponentIndex[bodyEntity]] = isAllowedToSleep; +} + +// Return true if the body is active +inline bool BodyComponents::getIsActive(Entity bodyEntity) const { + + assert(mMapEntityToComponentIndex.containsKey(bodyEntity)); + + return mIsActive[mMapEntityToComponentIndex[bodyEntity]]; +} + +// Set the value to know if the body is active +inline void BodyComponents::setIsActive(Entity bodyEntity, bool isActive) const { + + assert(mMapEntityToComponentIndex.containsKey(bodyEntity)); + + mIsActive[mMapEntityToComponentIndex[bodyEntity]] = isActive; +} + +// Return true if the body is sleeping +inline bool BodyComponents::getIsSleeping(Entity bodyEntity) const { + + assert(mMapEntityToComponentIndex.containsKey(bodyEntity)); + + return mIsSleeping[mMapEntityToComponentIndex[bodyEntity]]; +} + +// Set the value to know if the body is sleeping +inline void BodyComponents::setIsSleeping(Entity bodyEntity, bool isSleeping) const { + + assert(mMapEntityToComponentIndex.containsKey(bodyEntity)); + + mIsSleeping[mMapEntityToComponentIndex[bodyEntity]] = isSleeping; +} + +// Return the sleep time +inline decimal BodyComponents::getSleepTime(Entity bodyEntity) const { + + assert(mMapEntityToComponentIndex.containsKey(bodyEntity)); + + return mSleepTimes[mMapEntityToComponentIndex[bodyEntity]]; +} + +// Set the sleep time +inline void BodyComponents::setSleepTime(Entity bodyEntity, decimal sleepTime) const { + + assert(mMapEntityToComponentIndex.containsKey(bodyEntity)); + + mSleepTimes[mMapEntityToComponentIndex[bodyEntity]] = sleepTime; +} + +// Return the user data associated with the body +inline void* BodyComponents::getUserData(Entity bodyEntity) const { + + assert(mMapEntityToComponentIndex.containsKey(bodyEntity)); + + return mUserData[mMapEntityToComponentIndex[bodyEntity]]; +} + +// Set the user data associated with the body +inline void BodyComponents::setUserData(Entity bodyEntity, void* userData) const { + + assert(mMapEntityToComponentIndex.containsKey(bodyEntity)); + + mUserData[mMapEntityToComponentIndex[bodyEntity]] = userData; +} + } #endif diff --git a/src/components/Components.cpp b/src/components/Components.cpp index 87e06e80..ea3e3521 100644 --- a/src/components/Components.cpp +++ b/src/components/Components.cpp @@ -150,7 +150,7 @@ void Components::removeComponent(Entity entity) { assert(mNbComponents == static_cast(mMapEntityToComponentIndex.size())); } -// Notify if a given entity is disabled (sleeping or inactive) or not +// Notify if a given entity is disabled (sleeping) or not void Components::setIsEntityDisabled(Entity entity, bool isDisabled) { const uint32 index = mMapEntityToComponentIndex[entity]; diff --git a/src/components/Components.h b/src/components/Components.h index 320104a3..a7a04fb8 100644 --- a/src/components/Components.h +++ b/src/components/Components.h @@ -107,10 +107,10 @@ class Components { /// Remove a component void removeComponent(Entity entity); - /// Return true if an entity is sleeping + /// Return true if an entity is disabled bool getIsEntityDisabled(Entity entity) const; - /// Notify if a given entity is sleeping + /// Notify if a given entity is disabled void setIsEntityDisabled(Entity entity, bool isDisabled); /// Return true if there is a component for a given entity diff --git a/src/engine/CollisionWorld.cpp b/src/engine/CollisionWorld.cpp index 20c08fb8..4476dae5 100644 --- a/src/engine/CollisionWorld.cpp +++ b/src/engine/CollisionWorld.cpp @@ -206,7 +206,7 @@ void CollisionWorld::destroyCollisionBody(CollisionBody* collisionBody) { mMemoryManager.release(MemoryManager::AllocationType::Pool, collisionBody, sizeof(CollisionBody)); } -// Notify the world if a body is disabled (sleeping or inactive) or not +// Notify the world if a body is disabled (sleeping) or not void CollisionWorld::notifyBodyDisabled(Entity bodyEntity, bool isDisabled) { if (isDisabled == mBodyComponents.getIsEntityDisabled(bodyEntity)) return; diff --git a/src/engine/CollisionWorld.h b/src/engine/CollisionWorld.h index aef8201d..6868d26e 100644 --- a/src/engine/CollisionWorld.h +++ b/src/engine/CollisionWorld.h @@ -196,6 +196,7 @@ class CollisionWorld { // -------------------- Friendship -------------------- // friend class CollisionDetection; + friend class Body; friend class CollisionBody; friend class RigidBody; friend class ProxyShape; diff --git a/src/engine/DynamicsWorld.cpp b/src/engine/DynamicsWorld.cpp index afa5fe3b..c27661bc 100644 --- a/src/engine/DynamicsWorld.cpp +++ b/src/engine/DynamicsWorld.cpp @@ -817,15 +817,17 @@ void DynamicsWorld::updateSleepingBodies() { !body->isAllowedToSleep()) { // Reset the sleep time of the body - body->mSleepTime = decimal(0.0); + mBodyComponents.setSleepTime(body->getEntity(), decimal(0.0)); minSleepTime = decimal(0.0); } else { // If the body velocity is below the sleeping velocity threshold // Increase the sleep time - body->mSleepTime += mTimeStep; - if (body->mSleepTime < minSleepTime) { - minSleepTime = body->mSleepTime; + decimal sleepTime = mBodyComponents.getSleepTime(body->getEntity()); + mBodyComponents.setSleepTime(body->getEntity(), sleepTime + mTimeStep); + sleepTime = mBodyComponents.getSleepTime(body->getEntity()); + if (sleepTime < minSleepTime) { + minSleepTime = sleepTime; } } }