Remove Body class

This commit is contained in:
Daniel Chappuis 2019-07-15 17:38:20 +02:00
parent 16f564edea
commit 569964e365
29 changed files with 329 additions and 461 deletions

View File

@ -77,7 +77,6 @@ SET (REACTPHYSICS3D_HEADERS
"src/configuration.h"
"src/decimal.h"
"src/reactphysics3d.h"
"src/body/Body.h"
"src/body/CollisionBody.h"
"src/body/RigidBody.h"
"src/collision/ContactPointInfo.h"
@ -175,7 +174,6 @@ SET (REACTPHYSICS3D_HEADERS
# Source files
SET (REACTPHYSICS3D_SOURCES
"src/body/Body.cpp"
"src/body/CollisionBody.cpp"
"src/body/RigidBody.cpp"
"src/collision/broadphase/DynamicAABBTree.cpp"

View File

@ -1,153 +0,0 @@
/********************************************************************************
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
* Copyright (c) 2010-2018 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
// Libraries
#include "Body.h"
#include "engine/CollisionWorld.h"
#include "collision/shapes/CollisionShape.h"
#include "utils/Logger.h"
// We want to use the ReactPhysics3D namespace
using namespace reactphysics3d;
// Constructor
/**
* @param id ID of the new body
*/
Body::Body(Entity entity, CollisionWorld& world)
: mEntity(entity), mWorld(world) {
#ifdef IS_LOGGING_ACTIVE
mLogger = nullptr;
#endif
}
// 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) {
setIsSleeping(!isActive);
mWorld.mBodyComponents.setIsActive(mEntity, isActive);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set isActive=" +
(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 (!mWorld.mBodyComponents.getIsActive(mEntity)) {
assert(isBodySleeping);
return;
}
if (isSleeping) {
mWorld.mBodyComponents.setSleepTime(mEntity, decimal(0.0));
}
else {
if (isBodySleeping) {
mWorld.mBodyComponents.setSleepTime(mEntity, decimal(0.0));
}
}
if (isBodySleeping != isSleeping) {
mWorld.mBodyComponents.setIsSleeping(mEntity, isSleeping);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set isSleeping=" +
(isSleeping ? "true" : "false"));
}
}
// Set whether or not the body is allowed to go to sleep
/**
* @param isAllowedToSleep True if the body is allowed to sleep
*/
void Body::setIsAllowedToSleep(bool isAllowedToSleep) {
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=" +
(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);
}

View File

@ -1,141 +0,0 @@
/********************************************************************************
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
* Copyright (c) 2010-2018 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
#ifndef REACTPHYSICS3D_BODY_H
#define REACTPHYSICS3D_BODY_H
// Libraries
#include <cassert>
#include "configuration.h"
#include "engine/Entity.h"
/// Namespace reactphysics3d
namespace reactphysics3d {
// Declarations
class Logger;
class CollisionWorld;
// TODO : Make this class abstract
// Class Body
/**
* This class to represent a body of the physics engine. You should not
* instantiante this class but instantiate the CollisionBody or RigidBody
* classes instead.
*/
class Body {
protected :
// -------------------- Attributes -------------------- //
/// Identifier of the entity in the ECS
Entity mEntity;
/// Reference to the world the body belongs to
CollisionWorld& mWorld;
#ifdef IS_LOGGING_ACTIVE
/// Logger
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, CollisionWorld& world);
/// Deleted copy-constructor
Body(const Body& body) = delete;
/// Deleted assignment operator
Body& operator=(const Body& body) = delete;
/// Destructor
virtual ~Body() = default;
/// Return the corresponding entity of the body
Entity getEntity() const;
/// Return whether or not the body is allowed to sleep
bool isAllowedToSleep() const;
/// Set whether or not the body is allowed to go to sleep
void setIsAllowedToSleep(bool isAllowedToSleep);
/// Return whether or not the body is sleeping
bool isSleeping() const;
/// Return true if the body is active
bool isActive() const;
/// Set whether or not the body is active
virtual void setIsActive(bool isActive);
/// Return a pointer to the user data attached to this body
void* getUserData() const;
/// Attach user data to this body
void setUserData(void* userData);
#ifdef IS_LOGGING_ACTIVE
/// Set the logger
void setLogger(Logger* logger);
#endif
// -------------------- Friendship -------------------- //
friend class DynamicsWorld;
};
// Return the corresponding entity of the body
/**
* @return The entity of the body
*/
inline Entity Body::getEntity() const {
return mEntity;
}
#ifdef IS_LOGGING_ACTIVE
// Set the logger
inline void Body::setLogger(Logger* logger) {
mLogger = logger;
}
#endif
}
#endif

View File

@ -40,7 +40,11 @@ using namespace reactphysics3d;
* @param id ID of the body
*/
CollisionBody::CollisionBody(CollisionWorld& world, Entity entity)
: Body(entity, world), mType(BodyType::DYNAMIC) {
: mEntity(entity), mWorld(world) {
#ifdef IS_LOGGING_ACTIVE
mLogger = nullptr;
#endif
#ifdef IS_PROFILING_ACTIVE
mProfiler = nullptr;
@ -230,7 +234,7 @@ void CollisionBody::setIsActive(bool isActive) {
// If the state does not change
if (mWorld.mBodyComponents.getIsActive(mEntity) == isActive) return;
Body::setIsActive(isActive);
mWorld.mBodyComponents.setIsActive(mEntity, isActive);
// If we have to activate the body
if (isActive) {
@ -382,9 +386,6 @@ void CollisionBody::setTransform(const Transform& transform) {
// TODO : Make sure this method is never called from the internal physics engine
// Awake the body if it is sleeping
setIsSleeping(false);
// Update the transform of the body
mWorld.mTransformComponents.setTransform(mEntity, transform);
@ -395,15 +396,28 @@ void CollisionBody::setTransform(const Transform& transform) {
"Body " + std::to_string(mEntity.id) + ": Set transform=" + transform.to_string());
}
// Set the variable to know whether or not the body is sleeping
void CollisionBody::setIsSleeping(bool isSleeping) {
// Return true if the body is active
/**
* @return True if the body currently active and false otherwise
*/
bool CollisionBody::isActive() const {
return mWorld.mBodyComponents.getIsActive(mEntity);
}
if (mWorld.mBodyComponents.getIsSleeping(mEntity) == isSleeping) return;
// 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* CollisionBody::getUserData() const {
return mWorld.mBodyComponents.getUserData(mEntity);
}
Body::setIsSleeping(isSleeping);
// Notify all the components
mWorld.notifyBodyDisabled(mEntity, isSleeping);
// Attach user data to this body
/**
* @param userData A pointer to the user data you want to attach to the body
*/
void CollisionBody::setUserData(void* userData) {
mWorld.mBodyComponents.setUserData(mEntity, userData);
}
// Return the world-space coordinates of a point given the local-space coordinates of the body
@ -441,31 +455,3 @@ Vector3 CollisionBody::getLocalPoint(const Vector3& worldPoint) const {
Vector3 CollisionBody::getLocalVector(const Vector3& worldVector) const {
return mWorld.mTransformComponents.getTransform(mEntity).getOrientation().getInverse() * worldVector;
}
// Set the type of the body
/// The type of the body can either STATIC, KINEMATIC or DYNAMIC as described bellow:
/// STATIC : A static body has infinite mass, zero velocity but the position can be
/// changed manually. A static body does not collide with other static or kinematic bodies.
/// KINEMATIC : A kinematic body has infinite mass, the velocity can be changed manually and its
/// position is computed by the physics engine. A kinematic body does not collide with
/// other static or kinematic bodies.
/// DYNAMIC : A dynamic body has non-zero mass, non-zero velocity determined by forces and its
/// position is determined by the physics engine. A dynamic body can collide with other
/// dynamic, static or kinematic bodies.
/**
* @param type The type of the body (STATIC, KINEMATIC, DYNAMIC)
*/
void CollisionBody::setType(BodyType type) {
mType = type;
if (mType == BodyType::STATIC) {
// Update the broad-phase state of the body
updateBroadPhaseState();
}
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set type=" +
(mType == BodyType::STATIC ? "Static" : (mType == BodyType::DYNAMIC ? "Dynamic" : "Kinematic")));
}

View File

@ -28,7 +28,7 @@
// Libraries
#include <cassert>
#include "Body.h"
#include "engine/Entity.h"
#include "collision/shapes/AABB.h"
#include "mathematics/Transform.h"
#include "configuration.h"
@ -44,32 +44,30 @@ class CollisionShape;
struct RaycastInfo;
class PoolAllocator;
class Profiler;
/// Enumeration for the type of a body
/// STATIC : A static body has infinite mass, zero velocity but the position can be
/// changed manually. A static body does not collide with other static or kinematic bodies.
/// KINEMATIC : A kinematic body has infinite mass, the velocity can be changed manually and its
/// position is computed by the physics engine. A kinematic body does not collide with
/// other static or kinematic bodies.
/// DYNAMIC : A dynamic body has non-zero mass, non-zero velocity determined by forces and its
/// position is determined by the physics engine. A dynamic body can collide with other
/// dynamic, static or kinematic bodies.
enum class BodyType {STATIC, KINEMATIC, DYNAMIC};
class Logger;
// Class CollisionBody
/**
* This class represents a body that is able to collide with others
* bodies. This class inherits from the Body class.
* bodies.
*/
class CollisionBody : public Body {
class CollisionBody {
protected :
// -------------------- Attributes -------------------- //
// TODO : Move this into the dynamics components
/// Type of body (static, kinematic or dynamic)
BodyType mType;
/// Identifier of the entity in the ECS
Entity mEntity;
/// Reference to the world the body belongs to
CollisionWorld& mWorld;
#ifdef IS_LOGGING_ACTIVE
/// Logger
Logger* mLogger;
#endif
#ifdef IS_PROFILING_ACTIVE
@ -90,9 +88,6 @@ class CollisionBody : public Body {
/// (as if the body has moved).
void askForBroadPhaseCollisionCheck() const;
/// Set the variable to know whether or not the body is sleeping
virtual void setIsSleeping(bool isSleeping) override;
public :
// -------------------- Methods -------------------- //
@ -101,7 +96,7 @@ class CollisionBody : public Body {
CollisionBody(CollisionWorld& world, Entity entity);
/// Destructor
virtual ~CollisionBody() override;
virtual ~CollisionBody();
/// Deleted copy-constructor
CollisionBody(const CollisionBody& body) = delete;
@ -109,14 +104,20 @@ class CollisionBody : public Body {
/// Deleted assignment operator
CollisionBody& operator=(const CollisionBody& body) = delete;
/// Return the type of the body
BodyType getType() const;
/// Return the corresponding entity of the body
Entity getEntity() const;
/// Set the type of the body
void setType(BodyType type);
/// Return true if the body is active
bool isActive() const;
/// Return a pointer to the user data attached to this body
void* getUserData() const;
/// Attach user data to this body
void setUserData(void* userData);
/// Set whether or not the body is active
virtual void setIsActive(bool isActive) override;
virtual void setIsActive(bool isActive);
/// Return the current position and orientation
const Transform& getTransform() const;
@ -125,8 +126,7 @@ class CollisionBody : public Body {
virtual void setTransform(const Transform& transform);
/// Add a collision shape to the body.
virtual ProxyShape* addCollisionShape(CollisionShape* collisionShape,
const Transform& transform);
virtual ProxyShape* addCollisionShape(CollisionShape* collisionShape, const Transform& transform);
/// Remove a collision shape from the body
virtual void removeCollisionShape(ProxyShape *proxyShape);
@ -164,6 +164,12 @@ class CollisionBody : public Body {
/// Return the body local-space coordinates of a vector given in the world-space coordinates
Vector3 getLocalVector(const Vector3& worldVector) const;
#ifdef IS_LOGGING_ACTIVE
/// Set the logger
void setLogger(Logger* logger);
#endif
#ifdef IS_PROFILING_ACTIVE
/// Set the profiler
@ -181,14 +187,6 @@ class CollisionBody : public Body {
friend class ProxyShape;
};
// Return the type of the body
/**
* @return the type of the body (STATIC, KINEMATIC, DYNAMIC)
*/
inline BodyType CollisionBody::getType() const {
return mType;
}
/// Test if the collision body overlaps with a given AABB
/**
* @param worldAABB The AABB (in world-space coordinates) that will be used to test overlap
@ -198,6 +196,23 @@ inline bool CollisionBody::testAABBOverlap(const AABB& worldAABB) const {
return worldAABB.testCollision(getAABB());
}
// Return the corresponding entity of the body
/**
* @return The entity of the body
*/
inline Entity CollisionBody::getEntity() const {
return mEntity;
}
#ifdef IS_LOGGING_ACTIVE
// Set the logger
inline void CollisionBody::setLogger(Logger* logger) {
mLogger = logger;
}
#endif
#ifdef IS_PROFILING_ACTIVE
// Set the profiler

View File

@ -55,6 +55,11 @@ RigidBody::~RigidBody() {
assert(mJointsList == nullptr);
}
// Return the type of the body
BodyType RigidBody::getType() const {
return mWorld.mDynamicsComponents.getBodyType(mEntity);
}
// Set the type of the body
/// The type of the body can either STATIC, KINEMATIC or DYNAMIC as described bellow:
/// STATIC : A static body has infinite mass, zero velocity but the position can be
@ -70,15 +75,15 @@ RigidBody::~RigidBody() {
*/
void RigidBody::setType(BodyType type) {
if (mType == type) return;
if (mWorld.mDynamicsComponents.getBodyType(mEntity) == type) return;
CollisionBody::setType(type);
mWorld.mDynamicsComponents.setBodyType(mEntity, type);
// Recompute the total mass, center of mass and inertia tensor
recomputeMassInformation();
// If it is a static body
if (mType == BodyType::STATIC) {
if (type == BodyType::STATIC) {
// Reset the velocity to zero
mWorld.mDynamicsComponents.setLinearVelocity(mEntity, Vector3::zero());
@ -86,7 +91,7 @@ void RigidBody::setType(BodyType type) {
}
// If it is a static or a kinematic body
if (mType == BodyType::STATIC || mType == BodyType::KINEMATIC) {
if (type == BodyType::STATIC || type == BodyType::KINEMATIC) {
// Reset the inverse mass and inverse inertia tensor to zero
mWorld.mDynamicsComponents.setMassInverse(mEntity, decimal(0));
@ -114,6 +119,10 @@ void RigidBody::setType(BodyType type) {
// Reset the force and torque on the body
mWorld.mDynamicsComponents.setExternalForce(mEntity, Vector3::zero());
mWorld.mDynamicsComponents.setExternalTorque(mEntity, Vector3::zero());
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set type=" +
(type == BodyType::STATIC ? "Static" : (type == BodyType::DYNAMIC ? "Dynamic" : "Kinematic")));
}
// Get the inverse local inertia tensor of the body (in body coordinates)
@ -159,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 (mType != BodyType::DYNAMIC) return;
if (mWorld.mDynamicsComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
// Awake the body if it was sleeping
if (mWorld.mBodyComponents.getIsSleeping(mEntity)) {
@ -188,7 +197,7 @@ void RigidBody::setInertiaTensorLocal(const Matrix3x3& inertiaTensorLocal) {
mUserInertiaTensorLocalInverse = inertiaTensorLocal.getInverse();
mIsInertiaTensorSetByUser = true;
if (mType != BodyType::DYNAMIC) return;
if (mWorld.mDynamicsComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
// Compute the inverse local inertia tensor
mWorld.mDynamicsComponents.setInverseInertiaTensorLocal(mEntity, mUserInertiaTensorLocalInverse);
@ -211,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 (mType != BodyType::DYNAMIC) return;
if (mWorld.mDynamicsComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
// Awake the body if it was sleeping
if (mWorld.mBodyComponents.getIsSleeping(mEntity)) {
@ -251,7 +260,7 @@ void RigidBody::setInverseInertiaTensorLocal(const Matrix3x3& inverseInertiaTens
mUserInertiaTensorLocalInverse = inverseInertiaTensorLocal;
mIsInertiaTensorSetByUser = true;
if (mType != BodyType::DYNAMIC) return;
if (mWorld.mDynamicsComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
// Compute the inverse local inertia tensor
mWorld.mDynamicsComponents.setInverseInertiaTensorLocal(mEntity, mUserInertiaTensorLocalInverse);
@ -274,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 (mType != BodyType::DYNAMIC) return;
if (mWorld.mDynamicsComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
mIsCenterOfMassSetByUser = true;
@ -302,7 +311,7 @@ void RigidBody::setCenterOfMassLocal(const Vector3& centerOfMassLocal) {
*/
void RigidBody::setMass(decimal mass) {
if (mType != BodyType::DYNAMIC) return;
if (mWorld.mDynamicsComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
mWorld.mDynamicsComponents.setInitMass(mEntity, mass);
@ -524,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 (mType == BodyType::STATIC) return;
if (mWorld.mDynamicsComponents.getBodyType(mEntity) == BodyType::STATIC) return;
// Update the linear velocity of the current body state
mWorld.mDynamicsComponents.setLinearVelocity(mEntity, linearVelocity);
@ -547,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 (mType == BodyType::STATIC) return;
if (mWorld.mDynamicsComponents.getBodyType(mEntity) == BodyType::STATIC) return;
// Set the angular velocity
mWorld.mDynamicsComponents.setAngularVelocity(mEntity, angularVelocity);
@ -588,6 +597,9 @@ void RigidBody::setTransform(const Transform& transform) {
// Update the world inverse inertia tensor
updateInertiaTensorInverseWorld();
// Awake the body if it is sleeping
setIsSleeping(false);
}
// Recompute the center of mass, total mass and inertia tensor of the body using all
@ -605,12 +617,13 @@ void RigidBody::recomputeMassInformation() {
const Transform& transform = mWorld.mTransformComponents.getTransform(mEntity);
// If it is a STATIC or a KINEMATIC body
if (mType == BodyType::STATIC || mType == BodyType::KINEMATIC) {
BodyType type = mWorld.mDynamicsComponents.getBodyType(mEntity);
if (type == BodyType::STATIC || type == BodyType::KINEMATIC) {
mWorld.mDynamicsComponents.setCenterOfMassWorld(mEntity, transform.getPosition());
return;
}
assert(mType == BodyType::DYNAMIC);
assert(mWorld.mDynamicsComponents.getBodyType(mEntity) == BodyType::DYNAMIC);
// Compute the total mass of the body
const List<Entity>& proxyShapesEntities = mWorld.mBodyComponents.getProxyShapes(mEntity);
@ -723,7 +736,7 @@ bool RigidBody::isGravityEnabled() const {
void RigidBody::applyTorque(const Vector3& torque) {
// If it is not a dynamic body, we do nothing
if (mType != BodyType::DYNAMIC) return;
if (mWorld.mDynamicsComponents.getBodyType(mEntity) != BodyType::DYNAMIC) return;
// Awake the body if it was sleeping
if (mWorld.mBodyComponents.getIsSleeping(mEntity)) {
@ -738,7 +751,29 @@ void RigidBody::applyTorque(const Vector3& torque) {
// Set the variable to know whether or not the body is sleeping
void RigidBody::setIsSleeping(bool isSleeping) {
CollisionBody::setIsSleeping(isSleeping);
bool isBodySleeping = mWorld.mBodyComponents.getIsSleeping(mEntity);
if (isBodySleeping == isSleeping) return;
// If the body is not active, do nothing (it is sleeping)
if (!mWorld.mBodyComponents.getIsActive(mEntity)) {
assert(isBodySleeping);
return;
}
if (isSleeping) {
mWorld.mBodyComponents.setSleepTime(mEntity, decimal(0.0));
}
else {
if (isBodySleeping) {
mWorld.mBodyComponents.setSleepTime(mEntity, decimal(0.0));
}
}
mWorld.mBodyComponents.setIsSleeping(mEntity, isSleeping);
// Notify all the components
mWorld.notifyBodyDisabled(mEntity, isSleeping);
if (isSleeping) {
@ -747,6 +782,56 @@ void RigidBody::setIsSleeping(bool isSleeping) {
mWorld.mDynamicsComponents.setExternalForce(mEntity, Vector3::zero());
mWorld.mDynamicsComponents.setExternalTorque(mEntity, Vector3::zero());
}
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set isSleeping=" +
(isSleeping ? "true" : "false"));
}
// Set whether or not the body is allowed to go to sleep
/**
* @param isAllowedToSleep True if the body is allowed to sleep
*/
void RigidBody::setIsAllowedToSleep(bool isAllowedToSleep) {
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=" +
(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 RigidBody::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 RigidBody::isSleeping() const {
return mWorld.mBodyComponents.getIsSleeping(mEntity);
}
// Set whether or not the body is active
/**
* @param isActive True if you want to activate the body
*/
void RigidBody::setIsActive(bool isActive) {
// If the state does not change
if (mWorld.mBodyComponents.getIsActive(mEntity) == isActive) return;
setIsSleeping(!isActive);
CollisionBody::setIsActive(isActive);
}
#ifdef IS_PROFILING_ACTIVE

View File

@ -40,6 +40,7 @@ struct JointListElement;
class Joint;
class DynamicsWorld;
class MemoryManager;
enum class BodyType;
// Class RigidBody
/**
@ -82,7 +83,7 @@ class RigidBody : public CollisionBody {
void updateInertiaTensorInverseWorld();
/// Set the variable to know whether or not the body is sleeping
virtual void setIsSleeping(bool isSleeping) override;
void setIsSleeping(bool isSleeping);
public :
@ -100,9 +101,6 @@ class RigidBody : public CollisionBody {
/// Deleted assignment operator
RigidBody& operator=(const RigidBody& body) = delete;
/// Set the type of the body (static, kinematic or dynamic)
void setType(BodyType type);
/// Set the current position and orientation
virtual void setTransform(const Transform& transform) override;
@ -139,6 +137,12 @@ class RigidBody : public CollisionBody {
/// Set the mass of the rigid body
void setMass(decimal mass);
/// Return the type of the body
BodyType getType() const;
/// Set the type of the body
void setType(BodyType type);
/// Return true if the gravity needs to be applied to this rigid body
bool isGravityEnabled() const;
@ -178,6 +182,18 @@ class RigidBody : public CollisionBody {
/// Apply an external torque to the body.
void applyTorque(const Vector3& torque);
/// Return whether or not the body is allowed to sleep
bool isAllowedToSleep() const;
/// Set whether or not the body is allowed to go to sleep
void setIsAllowedToSleep(bool isAllowedToSleep);
/// Return whether or not the body is sleeping
bool isSleeping() const;
/// Set whether or not the body is active
virtual void setIsActive(bool isActive) override;
/// Add a collision shape to the body.
virtual ProxyShape* addCollisionShape(CollisionShape* collisionShape,
const Transform& transform,

View File

@ -27,7 +27,6 @@
#include "CollisionDetection.h"
#include "engine/CollisionWorld.h"
#include "collision/OverlapCallback.h"
#include "body/Body.h"
#include "collision/shapes/BoxShape.h"
#include "collision/shapes/ConcaveShape.h"
#include "collision/ContactManifoldInfo.h"
@ -238,9 +237,14 @@ 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;
// Check that at least one body is enabled (active and awake) and not static
bool isBody1Active = !mWorld->mBodyComponents.getIsEntityDisabled(body1Entity) && body1->getType() != BodyType::STATIC;
bool isBody2Active = !mWorld->mBodyComponents.getIsEntityDisabled(body2Entity) && body2->getType() != BodyType::STATIC;
bool isBody1Active = !mWorld->mBodyComponents.getIsEntityDisabled(body1Entity) && !isStaticRigidBody1;
bool isBody2Active = !mWorld->mBodyComponents.getIsEntityDisabled(body2Entity) && !isStaticRigidBody2;
if (!isBody1Active && !isBody2Active) continue;
// Check if the bodies are in the set of bodies that cannot collide between each other

View File

@ -115,10 +115,12 @@ void ProxyShape::setLocalToBodyTransform(const Transform& transform) {
// TODO : Make sure this method is never called by the internal physics engine
//mLocalToBodyTransform = transform;
mBody->mWorld.mProxyShapesComponents.setLocalToBodyTransform(mEntity, transform);
mBody->setIsSleeping(false);
RigidBody* rigidBody = static_cast<RigidBody*>(mBody);
if (rigidBody != nullptr) {
mBody->mWorld.mBodyComponents.setIsSleeping(mBody->getEntity(), false);
}
mBody->mWorld.mCollisionDetection.updateProxyShape(mEntity);

View File

@ -35,7 +35,6 @@ namespace reactphysics3d {
// Declarations
struct CapsuleVsCapsuleNarrowPhaseInfoBatch;
class Body;
class ContactPoint;
// Class CapsuleVsCapsuleAlgorithm

View File

@ -34,7 +34,6 @@ namespace reactphysics3d {
// Declarations
class ContactPoint;
class Body;
// Class CapsuleVsConvexPolyhedronAlgorithm
/**

View File

@ -33,7 +33,6 @@
namespace reactphysics3d {
// Declarations
class Body;
class ContactPoint;
// Class ConvexPolyhedronVsConvexPolyhedronAlgorithm

View File

@ -33,7 +33,6 @@
namespace reactphysics3d {
class CollisionDetection;
class Body;
class ContactManifoldInfo;
class PoolAllocator;
class OverlappingPair;

View File

@ -34,7 +34,6 @@
namespace reactphysics3d {
// Declarations
class Body;
class ContactPoint;
struct SphereVsCapsuleNarrowPhaseInfoBatch;

View File

@ -34,7 +34,6 @@ namespace reactphysics3d {
// Declarations
class ContactPoint;
class Body;
// Class SphereVsConvexPolyhedronAlgorithm
/**

View File

@ -35,7 +35,6 @@ namespace reactphysics3d {
// Declarations
class ContactPoint;
struct SphereVsSphereNarrowPhaseInfoBatch;
class Body;
// Class SphereVsSphereAlgorithm
/**

View File

@ -34,7 +34,7 @@ using namespace reactphysics3d;
// Constructor
BodyComponents::BodyComponents(MemoryAllocator& allocator)
:Components(allocator, sizeof(Entity) + sizeof(Body*) + sizeof(List<Entity>) +
:Components(allocator, sizeof(Entity) + sizeof(CollisionBody*) + sizeof(List<Entity>) +
sizeof(bool) + sizeof(bool) + sizeof(bool) + sizeof(decimal) +
sizeof(void*)) {
@ -56,7 +56,7 @@ void BodyComponents::allocate(uint32 nbComponentsToAllocate) {
// New pointers to components data
Entity* newBodiesEntities = static_cast<Entity*>(newBuffer);
Body** newBodies = reinterpret_cast<Body**>(newBodiesEntities + nbComponentsToAllocate);
CollisionBody** newBodies = reinterpret_cast<CollisionBody**>(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);
@ -69,7 +69,7 @@ void BodyComponents::allocate(uint32 nbComponentsToAllocate) {
// Copy component data from the previous buffer to the new one
memcpy(newBodiesEntities, mBodiesEntities, mNbComponents * sizeof(Entity));
memcpy(newBodies, mBodies, mNbComponents * sizeof(Body*));
memcpy(newBodies, mBodies, mNbComponents * sizeof(CollisionBody*));
memcpy(newProxyShapes, mProxyShapes, mNbComponents * sizeof(List<Entity>));
memcpy(newIsAllowedToSleep, mIsAllowedToSleep, mNbComponents * sizeof(bool));
memcpy(newIsActive, mIsActive, mNbComponents * sizeof(bool));
@ -150,7 +150,7 @@ void BodyComponents::swapComponents(uint32 index1, uint32 index2) {
// Copy component 1 data
Entity entity1(mBodiesEntities[index1]);
Body* body1 = mBodies[index1];
CollisionBody* body1 = mBodies[index1];
List<Entity> proxyShapes1(mProxyShapes[index1]);
bool isAllowedToSleep1 = mIsAllowedToSleep[index1];
bool isActive1 = mIsActive[index1];

View File

@ -38,7 +38,7 @@ namespace reactphysics3d {
// Class declarations
class MemoryAllocator;
class EntityManager;
class Body;
class CollisionBody;
// Class BodyComponents
/**
@ -55,7 +55,7 @@ class BodyComponents : public Components {
Entity* mBodiesEntities;
/// Array of pointers to the corresponding bodies
Body** mBodies;
CollisionBody** mBodies;
/// Array with the list of proxy-shapes of each body
List<Entity>* mProxyShapes;
@ -69,7 +69,7 @@ class BodyComponents : public Components {
/// 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
/// Array with values for elapsed time since the body velocity was below the sleep velocity
decimal* mSleepTimes;
/// Array of pointers that can be used to attach user data to the body
@ -94,10 +94,10 @@ class BodyComponents : public Components {
/// Structure for the data of a body component
struct BodyComponent {
Body* body;
CollisionBody* body;
/// Constructor
BodyComponent(Body* body) : body(body) {
BodyComponent(CollisionBody* body) : body(body) {
}
};
@ -120,7 +120,7 @@ class BodyComponents : public Components {
void removeProxyShapeFromBody(Entity bodyEntity, Entity proxyShapeEntity);
/// Return a pointer to a body
Body* getBody(Entity bodyEntity);
CollisionBody* getBody(Entity bodyEntity);
/// Return the list of proxy-shapes of a body
const List<Entity>& getProxyShapes(Entity bodyEntity) const;
@ -173,7 +173,7 @@ inline void BodyComponents::removeProxyShapeFromBody(Entity bodyEntity, Entity p
}
// Return a pointer to a body
inline Body* BodyComponents::getBody(Entity bodyEntity) {
inline CollisionBody *BodyComponents::getBody(Entity bodyEntity) {
assert(mMapEntityToComponentIndex.containsKey(bodyEntity));

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(bool) + sizeof(BodyType)) {
// Allocate memory for the components data
allocate(INIT_NB_ALLOCATED_COMPONENTS);
@ -79,6 +79,7 @@ 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) {
@ -105,6 +106,7 @@ 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);
@ -132,6 +134,8 @@ void DynamicsComponents::allocate(uint32 nbComponentsToAllocate) {
mCentersOfMassWorld = newCentersOfMassWorld;
mIsGravityEnabled = newIsGravityEnabled;
mIsAlreadyInIsland = newIsAlreadyInIsland;
mBodyTypes = newBodyTypes;
mNbAllocatedComponents = nbComponentsToAllocate;
}
@ -163,6 +167,7 @@ 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));
@ -201,6 +206,7 @@ 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);
@ -241,6 +247,7 @@ 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);
@ -269,6 +276,7 @@ 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

@ -40,10 +40,22 @@ namespace reactphysics3d {
class MemoryAllocator;
class EntityManager;
/// Enumeration for the type of a body
/// STATIC : A static body has infinite mass, zero velocity but the position can be
/// changed manually. A static body does not collide with other static or kinematic bodies.
/// KINEMATIC : A kinematic body has infinite mass, the velocity can be changed manually and its
/// position is computed by the physics engine. A kinematic body does not collide with
/// other static or kinematic bodies.
/// DYNAMIC : A dynamic body has non-zero mass, non-zero velocity determined by forces and its
/// position is determined by the physics engine. A dynamic body can collide with other
/// dynamic, static or kinematic bodies.
enum class BodyType {STATIC, KINEMATIC, DYNAMIC};
// Class DynamicsComponents
/**
* This class represent the component of the ECS that contains the variables concerning dynamics
* like velocities.
* like velocities. A rigid body that is not static always has a dynamics component. A rigid body
* that is static does not have one because it is not simulated by dynamics.
*/
class DynamicsComponents : public Components {
@ -114,6 +126,9 @@ 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
@ -135,9 +150,11 @@ class DynamicsComponents : public Components {
const Vector3& worldPosition;
BodyType bodyType;
/// Constructor
DynamicsComponent(const Vector3& worldPosition)
: worldPosition(worldPosition) {
DynamicsComponent(const Vector3& worldPosition, BodyType bodyType)
: worldPosition(worldPosition), bodyType(bodyType) {
}
};
@ -268,10 +285,16 @@ class DynamicsComponents : public Components {
void setCenterOfMassWorld(Entity bodyEntity, const Vector3& centerOfMassWorld);
/// Set the value to know if the gravity is enabled for this entity
bool setIsGravityEnabled(Entity bodyEntity, bool isGravityEnabled);
void setIsGravityEnabled(Entity bodyEntity, bool isGravityEnabled);
/// Set the value to know if the entity is already in an island
bool setIsAlreadyInIsland(Entity bodyEntity, bool isAlreadyInIsland);
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 -------------------- //
@ -282,7 +305,6 @@ class DynamicsComponents : public Components {
friend class FixedJoint;
friend class HingeJoint;
friend class SliderJoint;
};
// Return the linear velocity of an entity
@ -590,7 +612,7 @@ inline bool DynamicsComponents::getIsAlreadyInIsland(Entity bodyEntity) const {
}
// Set the value to know if the gravity is enabled for this entity
inline bool DynamicsComponents::setIsGravityEnabled(Entity bodyEntity, bool isGravityEnabled) {
inline void DynamicsComponents::setIsGravityEnabled(Entity bodyEntity, bool isGravityEnabled) {
assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
@ -598,13 +620,29 @@ inline bool DynamicsComponents::setIsGravityEnabled(Entity bodyEntity, bool isGr
}
/// Set the value to know if the entity is already in an island
inline bool DynamicsComponents::setIsAlreadyInIsland(Entity bodyEntity, bool isAlreadyInIsland) {
inline void DynamicsComponents::setIsAlreadyInIsland(Entity bodyEntity, bool isAlreadyInIsland) {
assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
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

@ -196,7 +196,6 @@ class CollisionWorld {
// -------------------- Friendship -------------------- //
friend class CollisionDetection;
friend class Body;
friend class CollisionBody;
friend class RigidBody;
friend class ProxyShape;

View File

@ -376,7 +376,8 @@ 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()));
mDynamicsComponents.addComponent(entity, false, DynamicsComponents::DynamicsComponent(transform.getPosition(),
BodyType::DYNAMIC));
// Create the rigid body
RigidBody* rigidBody = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
@ -655,9 +656,7 @@ void DynamicsWorld::createIslands() {
if (mDynamicsComponents.mIsAlreadyInIsland[b]) continue;
// If the body is static, we go to the next body
// TODO : Do not use pointer to rigid body here (maybe move getType() into a component)
CollisionBody* body = static_cast<CollisionBody*>(mBodyComponents.getBody(mDynamicsComponents.mBodies[b]));
if (body->getType() == BodyType::STATIC) continue;
if (mDynamicsComponents.mBodyTypes[b] == BodyType::STATIC) continue;
// Reset the stack of bodies to visit
bodyEntityIndicesToVisit.clear();
@ -678,14 +677,14 @@ void DynamicsWorld::createIslands() {
// Add the body into the island
mIslands.bodyEntities[islandIndex].add(bodyToVisitEntity);
// If the current body is static, we do not want to perform the DFS
// search across that body
// TODO : Do not use pointer to rigid body here (maybe move getType() into a component)
RigidBody* rigidBodyToVisit = static_cast<RigidBody*>(mBodyComponents.getBody(bodyToVisitEntity));
// Awake the body if it is sleeping
rigidBodyToVisit->setIsSleeping(false);
// If the current body is static, we do not want to perform the DFS
// search across that body
if (rigidBodyToVisit->getType() == BodyType::STATIC) continue;
// If the body is involved in contacts with other bodies
@ -768,10 +767,7 @@ void DynamicsWorld::createIslands() {
// can also be included in the other islands
for (uint j=0; j < mDynamicsComponents.getNbEnabledComponents(); j++) {
// If the body is static, we go to the next body
// TODO : Do not use pointer to rigid body here (maybe move getType() into a component)
CollisionBody* body = static_cast<CollisionBody*>(mBodyComponents.getBody(mDynamicsComponents.mBodies[j]));
if (body->getType() == BodyType::STATIC) {
if (mDynamicsComponents.mBodyTypes[j] == BodyType::STATIC) {
mDynamicsComponents.mIsAlreadyInIsland[j] = false;
}
}
@ -805,16 +801,16 @@ void DynamicsWorld::updateSleepingBodies() {
const Entity bodyEntity = mIslands.bodyEntities[i][b];
// TODO : We should not have to do this cast here to get type of body
CollisionBody* body = static_cast<CollisionBody*>(mBodyComponents.getBody(bodyEntity));
// TODO : We should use a RigidBody* type here
CollisionBody* body = mBodyComponents.getBody(bodyEntity);
// Skip static bodies
if (body->getType() == BodyType::STATIC) continue;
if (mDynamicsComponents.getBodyType(body->getEntity()) == BodyType::STATIC) continue;
// If the body is velocity is large enough to stay awake
if (mDynamicsComponents.getLinearVelocity(bodyEntity).lengthSquare() > sleepLinearVelocitySquare ||
mDynamicsComponents.getAngularVelocity(bodyEntity).lengthSquare() > sleepAngularVelocitySquare ||
!body->isAllowedToSleep()) {
!mBodyComponents.getIsAllowedToSleep(body->getEntity())) {
// Reset the sleep time of the body
mBodyComponents.setSleepTime(body->getEntity(), decimal(0.0));
@ -840,8 +836,9 @@ void DynamicsWorld::updateSleepingBodies() {
// Put all the bodies of the island to sleep
for (uint b=0; b < mIslands.bodyEntities[i].size(); b++) {
// TODO : We should use a RigidBody* type here (remove the cast)
const Entity bodyEntity = mIslands.bodyEntities[i][b];
CollisionBody* body = static_cast<CollisionBody*>(mBodyComponents.getBody(bodyEntity));
RigidBody* body = static_cast<RigidBody*>(mBodyComponents.getBody(bodyEntity));
body->setIsSleeping(true);
}
}

View File

@ -160,9 +160,12 @@ void Box::render(openglframework::Shader& shader, const openglframework::Matrix4
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
// Set the vertex color
openglframework::Color currentColor = mBody->isSleeping() ? mSleepingColor : mColor;
rp3d::RigidBody* rigidBody = static_cast<rp3d::RigidBody*>(mBody);
if (rigidBody != nullptr) {
openglframework::Color currentColor = rigidBody->isSleeping() ? mSleepingColor : mColor;
openglframework::Vector4 color(currentColor.r, currentColor.g, currentColor.b, currentColor.a);
shader.setVector4Uniform("vertexColor", color, false);
}
// Bind the VAO
mVAO.bind();

View File

@ -141,9 +141,12 @@ void Capsule::render(openglframework::Shader& shader,
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
// Set the vertex color
openglframework::Color currentColor = mBody->isSleeping() ? mSleepingColor : mColor;
rp3d::RigidBody* rigidBody = static_cast<rp3d::RigidBody*>(mBody);
if (rigidBody != nullptr) {
openglframework::Color currentColor = rigidBody->isSleeping() ? mSleepingColor : mColor;
openglframework::Vector4 color(currentColor.r, currentColor.g, currentColor.b, currentColor.a);
shader.setVector4Uniform("vertexColor", color, false);
}
// Bind the VAO
mVAO.bind();

View File

@ -150,9 +150,12 @@ void ConcaveMesh::render(openglframework::Shader& shader,
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
// Set the vertex color
openglframework::Color currentColor = mBody->isSleeping() ? mSleepingColor : mColor;
rp3d::RigidBody* rigidBody = static_cast<rp3d::RigidBody*>(mBody);
if (rigidBody != nullptr) {
openglframework::Color currentColor = rigidBody->isSleeping() ? mSleepingColor : mColor;
openglframework::Vector4 color(currentColor.r, currentColor.g, currentColor.b, currentColor.a);
shader.setVector4Uniform("vertexColor", color, false);
}
// Bind the VAO
mVAO.bind();

View File

@ -160,9 +160,12 @@ void ConvexMesh::render(openglframework::Shader& shader,
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
// Set the vertex color
openglframework::Color currentColor = mBody->isSleeping() ? mSleepingColor : mColor;
rp3d::RigidBody* rigidBody = static_cast<rp3d::RigidBody*>(mBody);
if (rigidBody != nullptr) {
openglframework::Color currentColor = rigidBody->isSleeping() ? mSleepingColor : mColor;
openglframework::Vector4 color(currentColor.r, currentColor.g, currentColor.b, currentColor.a);
shader.setVector4Uniform("vertexColor", color, false);
}
// Bind the VAO
mVAO.bind();

View File

@ -178,9 +178,12 @@ void Dumbbell::render(openglframework::Shader& shader,
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
// Set the vertex color
openglframework::Color currentColor = mBody->isSleeping() ? mSleepingColor : mColor;
rp3d::RigidBody* rigidBody = static_cast<rp3d::RigidBody*>(mBody);
if (rigidBody != nullptr) {
openglframework::Color currentColor = rigidBody->isSleeping() ? mSleepingColor : mColor;
openglframework::Vector4 color(currentColor.r, currentColor.g, currentColor.b, currentColor.a);
shader.setVector4Uniform("vertexColor", color, false);
}
// Bind the VAO
mVAO.bind();

View File

@ -132,9 +132,12 @@ void HeightField::render(openglframework::Shader& shader,
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
// Set the vertex color
openglframework::Color currentColor = mBody->isSleeping() ? mSleepingColor : mColor;
rp3d::RigidBody* rigidBody = static_cast<rp3d::RigidBody*>(mBody);
if (rigidBody != nullptr) {
openglframework::Color currentColor = rigidBody->isSleeping() ? mSleepingColor : mColor;
openglframework::Vector4 color(currentColor.r, currentColor.g, currentColor.b, currentColor.a);
shader.setVector4Uniform("vertexColor", color, false);
}
// Bind the VAO
mVAO.bind();

View File

@ -140,9 +140,12 @@ void Sphere::render(openglframework::Shader& shader, const openglframework::Matr
shader.setMatrix3x3Uniform("normalMatrix", normalMatrix, false);
// Set the vertex color
openglframework::Color currentColor = mBody->isSleeping() ? mSleepingColor : mColor;
rp3d::RigidBody* rigidBody = static_cast<rp3d::RigidBody*>(mBody);
if (rigidBody != nullptr) {
openglframework::Color currentColor = rigidBody->isSleeping() ? mSleepingColor : mColor;
openglframework::Vector4 color(currentColor.r, currentColor.g, currentColor.b, currentColor.a);
shader.setVector4Uniform("vertexColor", color, false);
}
// Bind the VAO
mVAO.bind();