Remove Body class
This commit is contained in:
parent
16f564edea
commit
569964e365
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
}
|
141
src/body/Body.h
141
src/body/Body.h
|
@ -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
|
|
@ -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")));
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -35,7 +35,6 @@ namespace reactphysics3d {
|
|||
|
||||
// Declarations
|
||||
struct CapsuleVsCapsuleNarrowPhaseInfoBatch;
|
||||
class Body;
|
||||
class ContactPoint;
|
||||
|
||||
// Class CapsuleVsCapsuleAlgorithm
|
||||
|
|
|
@ -34,7 +34,6 @@ namespace reactphysics3d {
|
|||
|
||||
// Declarations
|
||||
class ContactPoint;
|
||||
class Body;
|
||||
|
||||
// Class CapsuleVsConvexPolyhedronAlgorithm
|
||||
/**
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
namespace reactphysics3d {
|
||||
|
||||
// Declarations
|
||||
class Body;
|
||||
class ContactPoint;
|
||||
|
||||
// Class ConvexPolyhedronVsConvexPolyhedronAlgorithm
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
namespace reactphysics3d {
|
||||
|
||||
class CollisionDetection;
|
||||
class Body;
|
||||
class ContactManifoldInfo;
|
||||
class PoolAllocator;
|
||||
class OverlappingPair;
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
namespace reactphysics3d {
|
||||
|
||||
// Declarations
|
||||
class Body;
|
||||
class ContactPoint;
|
||||
struct SphereVsCapsuleNarrowPhaseInfoBatch;
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@ namespace reactphysics3d {
|
|||
|
||||
// Declarations
|
||||
class ContactPoint;
|
||||
class Body;
|
||||
|
||||
// Class SphereVsConvexPolyhedronAlgorithm
|
||||
/**
|
||||
|
|
|
@ -35,7 +35,6 @@ namespace reactphysics3d {
|
|||
// Declarations
|
||||
class ContactPoint;
|
||||
struct SphereVsSphereNarrowPhaseInfoBatch;
|
||||
class Body;
|
||||
|
||||
// Class SphereVsSphereAlgorithm
|
||||
/**
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -196,7 +196,6 @@ class CollisionWorld {
|
|||
// -------------------- Friendship -------------------- //
|
||||
|
||||
friend class CollisionDetection;
|
||||
friend class Body;
|
||||
friend class CollisionBody;
|
||||
friend class RigidBody;
|
||||
friend class ProxyShape;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue
Block a user