Move Body attributes to BodyComponents
This commit is contained in:
parent
236a855c8d
commit
16f564edea
|
@ -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);
|
||||
}
|
||||
|
|
115
src/body/Body.h
115
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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -34,7 +34,9 @@ using namespace reactphysics3d;
|
|||
|
||||
// Constructor
|
||||
BodyComponents::BodyComponents(MemoryAllocator& allocator)
|
||||
:Components(allocator, sizeof(Entity) + sizeof(Body*) + sizeof(List<Entity>)) {
|
||||
:Components(allocator, sizeof(Entity) + sizeof(Body*) + sizeof(List<Entity>) +
|
||||
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<Entity*>(newBuffer);
|
||||
Body** newBodies = reinterpret_cast<Body**>(newBodiesEntities + nbComponentsToAllocate);
|
||||
List<Entity>* newProxyShapes = reinterpret_cast<List<Entity>*>(newBodies + nbComponentsToAllocate);
|
||||
bool* newIsAllowedToSleep = reinterpret_cast<bool*>(newProxyShapes + nbComponentsToAllocate);
|
||||
bool* newIsActive = reinterpret_cast<bool*>(newIsAllowedToSleep + nbComponentsToAllocate);
|
||||
bool* newIsSleeping = reinterpret_cast<bool*>(newIsActive + nbComponentsToAllocate);
|
||||
decimal* newSleepTimes = reinterpret_cast<decimal*>(newIsSleeping + nbComponentsToAllocate);
|
||||
void** newUserData = reinterpret_cast<void**>(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<Entity>));
|
||||
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<Entity>(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<Entity, uint32>(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<Entity>(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<Entity> 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<Entity>(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<Entity, uint32>(entity1, index2));
|
||||
|
@ -156,4 +192,5 @@ void BodyComponents::destroyComponent(uint32 index) {
|
|||
mBodiesEntities[index].~Entity();
|
||||
mBodies[index] = nullptr;
|
||||
mProxyShapes[index].~List<Entity>();
|
||||
mUserData[index] = nullptr;
|
||||
}
|
||||
|
|
|
@ -60,6 +60,21 @@ class BodyComponents : public Components {
|
|||
/// Array with the list of proxy-shapes of each body
|
||||
List<Entity>* 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<Entity>& 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<Entity>& 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
|
||||
|
|
|
@ -150,7 +150,7 @@ void Components::removeComponent(Entity entity) {
|
|||
assert(mNbComponents == static_cast<uint32>(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];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -196,6 +196,7 @@ class CollisionWorld {
|
|||
// -------------------- Friendship -------------------- //
|
||||
|
||||
friend class CollisionDetection;
|
||||
friend class Body;
|
||||
friend class CollisionBody;
|
||||
friend class RigidBody;
|
||||
friend class ProxyShape;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user