Merge branch 'logs' into develop
This commit is contained in:
commit
b1e5c029f7
|
@ -21,6 +21,7 @@ ENABLE_TESTING()
|
|||
OPTION(COMPILE_TESTBED "Select this if you want to build the testbed application" OFF)
|
||||
OPTION(COMPILE_TESTS "Select this if you want to build the tests" OFF)
|
||||
OPTION(PROFILING_ENABLED "Select this if you want to compile with enabled profiling" OFF)
|
||||
OPTION(LOGS_ENABLED "Select this if you want to compile with logs enabled during execution" OFF)
|
||||
OPTION(DOUBLE_PRECISION_ENABLED "Select this if you want to compile using double precision floating
|
||||
values" OFF)
|
||||
|
||||
|
@ -45,6 +46,10 @@ IF(PROFILING_ENABLED)
|
|||
ADD_DEFINITIONS(-DIS_PROFILING_ACTIVE)
|
||||
ENDIF(PROFILING_ENABLED)
|
||||
|
||||
IF(LOGS_ENABLED)
|
||||
ADD_DEFINITIONS(-DIS_LOGGING_ACTIVE)
|
||||
ENDIF(LOGS_ENABLED)
|
||||
|
||||
IF(DOUBLE_PRECISION_ENABLED)
|
||||
ADD_DEFINITIONS(-DIS_DOUBLE_PRECISION_ENABLED)
|
||||
ENDIF(DOUBLE_PRECISION_ENABLED)
|
||||
|
@ -164,8 +169,6 @@ SET (REACTPHYSICS3D_SOURCES
|
|||
"src/engine/Material.cpp"
|
||||
"src/engine/OverlappingPair.h"
|
||||
"src/engine/OverlappingPair.cpp"
|
||||
"src/engine/Profiler.h"
|
||||
"src/engine/Profiler.cpp"
|
||||
"src/engine/Timer.h"
|
||||
"src/engine/Timer.cpp"
|
||||
"src/collision/CollisionCallback.h"
|
||||
|
@ -201,6 +204,10 @@ SET (REACTPHYSICS3D_SOURCES
|
|||
"src/containers/Map.h"
|
||||
"src/containers/Set.h"
|
||||
"src/containers/Pair.h"
|
||||
"src/utils/Profiler.h"
|
||||
"src/utils/Profiler.cpp"
|
||||
"src/utils/Logger.h"
|
||||
"src/utils/Logger.cpp"
|
||||
)
|
||||
|
||||
# Create the library
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <stdexcept>
|
||||
#include <cassert>
|
||||
#include "configuration.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
/// Namespace reactphysics3d
|
||||
namespace reactphysics3d {
|
||||
|
@ -75,6 +76,12 @@ class Body {
|
|||
/// Pointer that can be used to attach user data to the body
|
||||
void* mUserData;
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
|
||||
/// Logger
|
||||
Logger* mLogger;
|
||||
#endif
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
@ -92,7 +99,7 @@ class Body {
|
|||
virtual ~Body() = default;
|
||||
|
||||
/// Return the ID of the body
|
||||
bodyindex getID() const;
|
||||
bodyindex getId() const;
|
||||
|
||||
/// Return whether or not the body is allowed to sleep
|
||||
bool isAllowedToSleep() const;
|
||||
|
@ -118,6 +125,12 @@ class Body {
|
|||
/// Attach user data to this body
|
||||
void setUserData(void* userData);
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
|
||||
/// Set the logger
|
||||
void setLogger(Logger* logger);
|
||||
#endif
|
||||
|
||||
/// Smaller than operator
|
||||
bool operator<(const Body& body2) const;
|
||||
|
||||
|
@ -137,9 +150,9 @@ class Body {
|
|||
|
||||
// Return the id of the body
|
||||
/**
|
||||
* @return The ID of the body
|
||||
* @return The id of the body
|
||||
*/
|
||||
inline bodyindex Body::getID() const {
|
||||
inline bodyindex Body::getId() const {
|
||||
return mID;
|
||||
}
|
||||
|
||||
|
@ -159,6 +172,10 @@ inline void Body::setIsAllowedToSleep(bool isAllowedToSleep) {
|
|||
mIsAllowedToSleep = isAllowedToSleep;
|
||||
|
||||
if (!mIsAllowedToSleep) setIsSleeping(false);
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(mID) + ": Set isAllowedToSleep=" +
|
||||
(mIsAllowedToSleep ? "true" : "false"));
|
||||
}
|
||||
|
||||
// Return whether or not the body is sleeping
|
||||
|
@ -183,6 +200,10 @@ inline bool Body::isActive() const {
|
|||
*/
|
||||
inline void Body::setIsActive(bool isActive) {
|
||||
mIsActive = isActive;
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(mID) + ": Set isActive=" +
|
||||
(mIsActive ? "true" : "false"));
|
||||
}
|
||||
|
||||
// Set the variable to know whether or not the body is sleeping
|
||||
|
@ -197,7 +218,14 @@ inline void Body::setIsSleeping(bool isSleeping) {
|
|||
}
|
||||
}
|
||||
|
||||
if (mIsSleeping != isSleeping) {
|
||||
|
||||
mIsSleeping = isSleeping;
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(mID) + ": Set isSleeping=" +
|
||||
(mIsSleeping ? "true" : "false"));
|
||||
}
|
||||
}
|
||||
|
||||
// Return a pointer to the user data attached to this body
|
||||
|
@ -216,6 +244,15 @@ inline void Body::setUserData(void* userData) {
|
|||
mUserData = userData;
|
||||
}
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
|
||||
// Set the logger
|
||||
inline void Body::setLogger(Logger* logger) {
|
||||
mLogger = logger;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Smaller than operator
|
||||
inline bool Body::operator<(const Body& body2) const {
|
||||
return (mID < body2.mID);
|
||||
|
|
|
@ -79,6 +79,13 @@ ProxyShape* CollisionBody::addCollisionShape(CollisionShape* collisionShape,
|
|||
// Set the profiler
|
||||
proxyShape->setProfiler(mProfiler);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
|
||||
// Set the logger
|
||||
proxyShape->setLogger(mLogger);
|
||||
|
||||
#endif
|
||||
|
||||
// Add it to the list of proxy collision shapes of the body
|
||||
|
@ -99,6 +106,13 @@ ProxyShape* CollisionBody::addCollisionShape(CollisionShape* collisionShape,
|
|||
|
||||
mNbCollisionShapes++;
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(mID) + ": Proxy shape " + std::to_string(proxyShape->getBroadPhaseId()) + " added to body");
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::ProxyShape,
|
||||
"ProxyShape " + std::to_string(proxyShape->getBroadPhaseId()) + ": collisionShape=" +
|
||||
proxyShape->getCollisionShape()->to_string());
|
||||
|
||||
// Return a pointer to the collision shape
|
||||
return proxyShape;
|
||||
}
|
||||
|
@ -114,11 +128,14 @@ void CollisionBody::removeCollisionShape(const ProxyShape* proxyShape) {
|
|||
|
||||
ProxyShape* current = mProxyCollisionShapes;
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(mID) + ": Proxy shape " + std::to_string(proxyShape->getBroadPhaseId()) + " removed from body");
|
||||
|
||||
// If the the first proxy shape is the one to remove
|
||||
if (current == proxyShape) {
|
||||
mProxyCollisionShapes = current->mNext;
|
||||
|
||||
if (mIsActive && proxyShape->mBroadPhaseID != -1) {
|
||||
if (mIsActive && proxyShape->getBroadPhaseId() != -1) {
|
||||
mWorld.mCollisionDetection.removeProxyCollisionShape(current);
|
||||
}
|
||||
|
||||
|
@ -138,7 +155,7 @@ void CollisionBody::removeCollisionShape(const ProxyShape* proxyShape) {
|
|||
ProxyShape* elementToRemove = current->mNext;
|
||||
current->mNext = elementToRemove->mNext;
|
||||
|
||||
if (mIsActive && proxyShape->mBroadPhaseID != -1) {
|
||||
if (mIsActive && proxyShape->getBroadPhaseId() != -1) {
|
||||
mWorld.mCollisionDetection.removeProxyCollisionShape(elementToRemove);
|
||||
}
|
||||
|
||||
|
@ -164,7 +181,7 @@ void CollisionBody::removeAllCollisionShapes() {
|
|||
// Remove the proxy collision shape
|
||||
ProxyShape* nextElement = current->mNext;
|
||||
|
||||
if (mIsActive && current->mBroadPhaseID != -1) {
|
||||
if (mIsActive && current->getBroadPhaseId() != -1) {
|
||||
mWorld.mCollisionDetection.removeProxyCollisionShape(current);
|
||||
}
|
||||
|
||||
|
@ -209,7 +226,7 @@ void CollisionBody::updateBroadPhaseState() const {
|
|||
// Update the broad-phase state of a proxy collision shape of the body
|
||||
void CollisionBody::updateProxyShapeInBroadPhase(ProxyShape* proxyShape, bool forceReinsert) const {
|
||||
|
||||
if (proxyShape->mBroadPhaseID != -1) {
|
||||
if (proxyShape->getBroadPhaseId() != -1) {
|
||||
|
||||
// Recompute the world-space AABB of the collision shape
|
||||
AABB aabb;
|
||||
|
@ -250,7 +267,7 @@ void CollisionBody::setIsActive(bool isActive) {
|
|||
// For each proxy shape of the body
|
||||
for (ProxyShape* shape = mProxyCollisionShapes; shape != nullptr; shape = shape->mNext) {
|
||||
|
||||
if (shape->mBroadPhaseID != -1) {
|
||||
if (shape->getBroadPhaseId() != -1) {
|
||||
|
||||
// Remove the proxy shape from the collision detection
|
||||
mWorld.mCollisionDetection.removeProxyCollisionShape(shape);
|
||||
|
@ -260,6 +277,10 @@ void CollisionBody::setIsActive(bool isActive) {
|
|||
// Reset the contact manifold list of the body
|
||||
resetContactManifoldsList();
|
||||
}
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(mID) + ": Set isActive=" +
|
||||
(mIsActive ? "true" : "false"));
|
||||
}
|
||||
|
||||
// Ask the broad-phase to test again the collision shapes of the body for collision
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include "collision/RaycastInfo.h"
|
||||
#include "memory/PoolAllocator.h"
|
||||
#include "configuration.h"
|
||||
#include "engine/Profiler.h"
|
||||
#include "utils/Profiler.h"
|
||||
|
||||
/// Namespace reactphysics3d
|
||||
namespace reactphysics3d {
|
||||
|
@ -231,6 +231,10 @@ inline void CollisionBody::setType(BodyType type) {
|
|||
// Update the broad-phase state of the body
|
||||
updateBroadPhaseState();
|
||||
}
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(mID) + ": Set type=" +
|
||||
(mType == BodyType::STATIC ? "Static" : (mType == BodyType::DYNAMIC ? "Dynamic" : "Kinematic")));
|
||||
}
|
||||
|
||||
// Return the current position and orientation
|
||||
|
@ -254,6 +258,9 @@ inline void CollisionBody::setTransform(const Transform& transform) {
|
|||
|
||||
// Update the broad-phase state of the body
|
||||
updateBroadPhaseState();
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(mID) + ": Set transform=" + mTransform.to_string());
|
||||
}
|
||||
|
||||
// Return the first element of the linked list of contact manifolds involving this body
|
||||
|
|
|
@ -139,6 +139,9 @@ void RigidBody::setInertiaTensorLocal(const Matrix3x3& inertiaTensorLocal) {
|
|||
|
||||
// Update the world inverse inertia tensor
|
||||
updateInertiaTensorInverseWorld();
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(mID) + ": Set inertiaTensorLocal=" + inertiaTensorLocal.to_string());
|
||||
}
|
||||
|
||||
// Set the inverse local inertia tensor of the body (in local-space coordinates)
|
||||
|
@ -160,6 +163,9 @@ void RigidBody::setInverseInertiaTensorLocal(const Matrix3x3& inverseInertiaTens
|
|||
|
||||
// Update the world inverse inertia tensor
|
||||
updateInertiaTensorInverseWorld();
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(mID) + ": Set inverseInertiaTensorLocal=" + inverseInertiaTensorLocal.to_string());
|
||||
}
|
||||
|
||||
// Set the local center of mass of the body (in local-space coordinates)
|
||||
|
@ -183,6 +189,9 @@ void RigidBody::setCenterOfMassLocal(const Vector3& centerOfMassLocal) {
|
|||
|
||||
// Update the linear velocity of the center of mass
|
||||
mLinearVelocity += mAngularVelocity.cross(mCenterOfMassWorld - oldCenterOfMass);
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(mID) + ": Set centerOfMassLocal=" + centerOfMassLocal.to_string());
|
||||
}
|
||||
|
||||
// Set the mass of the rigid body
|
||||
|
@ -202,6 +211,9 @@ void RigidBody::setMass(decimal mass) {
|
|||
mInitMass = decimal(1.0);
|
||||
mMassInverse = decimal(1.0);
|
||||
}
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(mID) + ": Set mass=" + std::to_string(mass));
|
||||
}
|
||||
|
||||
// Remove a joint from the joints list
|
||||
|
@ -264,6 +276,13 @@ ProxyShape* RigidBody::addCollisionShape(CollisionShape* collisionShape,
|
|||
// Set the profiler
|
||||
proxyShape->setProfiler(mProfiler);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
|
||||
// Set the logger
|
||||
proxyShape->setLogger(mLogger);
|
||||
|
||||
#endif
|
||||
|
||||
// Add it to the list of proxy collision shapes of the body
|
||||
|
@ -288,6 +307,13 @@ ProxyShape* RigidBody::addCollisionShape(CollisionShape* collisionShape,
|
|||
// collision shape
|
||||
recomputeMassInformation();
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(mID) + ": Proxy shape " + std::to_string(proxyShape->getBroadPhaseId()) + " added to body");
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::ProxyShape,
|
||||
"ProxyShape " + std::to_string(proxyShape->getBroadPhaseId()) + ": collisionShape=" +
|
||||
proxyShape->getCollisionShape()->to_string());
|
||||
|
||||
// Return a pointer to the proxy collision shape
|
||||
return proxyShape;
|
||||
}
|
||||
|
@ -324,6 +350,9 @@ void RigidBody::setLinearVelocity(const Vector3& linearVelocity) {
|
|||
if (mLinearVelocity.lengthSquare() > decimal(0.0)) {
|
||||
setIsSleeping(false);
|
||||
}
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(mID) + ": Set linearVelocity=" + mLinearVelocity.to_string());
|
||||
}
|
||||
|
||||
// Set the angular velocity.
|
||||
|
@ -342,6 +371,9 @@ void RigidBody::setAngularVelocity(const Vector3& angularVelocity) {
|
|||
if (mAngularVelocity.lengthSquare() > decimal(0.0)) {
|
||||
setIsSleeping(false);
|
||||
}
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(mID) + ": Set angularVelocity=" + mAngularVelocity.to_string());
|
||||
}
|
||||
|
||||
// Set the current position and orientation
|
||||
|
@ -367,6 +399,9 @@ void RigidBody::setTransform(const Transform& transform) {
|
|||
|
||||
// Update the broad-phase state of the body
|
||||
updateBroadPhaseState();
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(mID) + ": Set transform=" + mTransform.to_string());
|
||||
}
|
||||
|
||||
// Recompute the center of mass, total mass and inertia tensor of the body using all
|
||||
|
@ -459,7 +494,7 @@ void RigidBody::recomputeMassInformation() {
|
|||
// Update the broad-phase state for this body (because it has moved for instance)
|
||||
void RigidBody::updateBroadPhaseState() const {
|
||||
|
||||
PROFILE("RigidBody::updateBroadPhaseState()", mProfiler);
|
||||
RP3D_PROFILE("RigidBody::updateBroadPhaseState()", mProfiler);
|
||||
|
||||
DynamicsWorld& world = static_cast<DynamicsWorld&>(mWorld);
|
||||
const Vector3 displacement = world.mTimeStep * mLinearVelocity;
|
||||
|
@ -469,7 +504,7 @@ void RigidBody::updateBroadPhaseState() const {
|
|||
|
||||
// Recompute the world-space AABB of the collision shape
|
||||
AABB aabb;
|
||||
shape->getCollisionShape()->computeAABB(aabb, mTransform *shape->getLocalToBodyTransform());
|
||||
shape->getCollisionShape()->computeAABB(aabb, mTransform * shape->getLocalToBodyTransform());
|
||||
|
||||
// Update the broad-phase state for the proxy collision shape
|
||||
mWorld.mCollisionDetection.updateProxyCollisionShape(shape, aabb, displacement);
|
||||
|
@ -494,4 +529,3 @@ void RigidBody::setProfiler(Profiler* profiler) {
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -325,6 +325,10 @@ inline bool RigidBody::isGravityEnabled() const {
|
|||
*/
|
||||
inline void RigidBody::enableGravity(bool isEnabled) {
|
||||
mIsGravityEnabled = isEnabled;
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(mID) + ": Set isGravityEnabled=" +
|
||||
(mIsGravityEnabled ? "true" : "false"));
|
||||
}
|
||||
|
||||
// Return a reference to the material properties of the rigid body
|
||||
|
@ -341,6 +345,9 @@ inline Material& RigidBody::getMaterial() {
|
|||
*/
|
||||
inline void RigidBody::setMaterial(const Material& material) {
|
||||
mMaterial = material;
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(mID) + ": Set Material" + mMaterial.to_string());
|
||||
}
|
||||
|
||||
// Return the linear velocity damping factor
|
||||
|
@ -359,6 +366,9 @@ inline decimal RigidBody::getLinearDamping() const {
|
|||
inline void RigidBody::setLinearDamping(decimal linearDamping) {
|
||||
assert(linearDamping >= decimal(0.0));
|
||||
mLinearDamping = linearDamping;
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(mID) + ": Set linearDamping=" + std::to_string(mLinearDamping));
|
||||
}
|
||||
|
||||
// Return the angular velocity damping factor
|
||||
|
@ -377,6 +387,9 @@ inline decimal RigidBody::getAngularDamping() const {
|
|||
inline void RigidBody::setAngularDamping(decimal angularDamping) {
|
||||
assert(angularDamping >= decimal(0.0));
|
||||
mAngularDamping = angularDamping;
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(mID) + ": Set angularDamping=" + std::to_string(mAngularDamping));
|
||||
}
|
||||
|
||||
// Return the first element of the linked list of joints involving this body
|
||||
|
|
|
@ -68,7 +68,7 @@ CollisionDetection::CollisionDetection(CollisionWorld* world, MemoryManager& mem
|
|||
// Compute the collision detection
|
||||
void CollisionDetection::computeCollisionDetection() {
|
||||
|
||||
PROFILE("CollisionDetection::computeCollisionDetection()", mProfiler);
|
||||
RP3D_PROFILE("CollisionDetection::computeCollisionDetection()", mProfiler);
|
||||
|
||||
// Compute the broad-phase collision detection
|
||||
computeBroadPhase();
|
||||
|
@ -86,7 +86,7 @@ void CollisionDetection::computeCollisionDetection() {
|
|||
// Compute the broad-phase collision detection
|
||||
void CollisionDetection::computeBroadPhase() {
|
||||
|
||||
PROFILE("CollisionDetection::computeBroadPhase()", mProfiler);
|
||||
RP3D_PROFILE("CollisionDetection::computeBroadPhase()", mProfiler);
|
||||
|
||||
// If new collision shapes have been added to bodies
|
||||
if (mIsCollisionShapesAdded) {
|
||||
|
@ -101,7 +101,7 @@ void CollisionDetection::computeBroadPhase() {
|
|||
// Compute the middle-phase collision detection
|
||||
void CollisionDetection::computeMiddlePhase() {
|
||||
|
||||
PROFILE("CollisionDetection::computeMiddlePhase()", mProfiler);
|
||||
RP3D_PROFILE("CollisionDetection::computeMiddlePhase()", mProfiler);
|
||||
|
||||
// For each possible collision pair of bodies
|
||||
Map<Pair<uint, uint>, OverlappingPair*>::Iterator it;
|
||||
|
@ -118,9 +118,9 @@ void CollisionDetection::computeMiddlePhase() {
|
|||
ProxyShape* shape1 = pair->getShape1();
|
||||
ProxyShape* shape2 = pair->getShape2();
|
||||
|
||||
assert(shape1->mBroadPhaseID != -1);
|
||||
assert(shape2->mBroadPhaseID != -1);
|
||||
assert(shape1->mBroadPhaseID != shape2->mBroadPhaseID);
|
||||
assert(shape1->getBroadPhaseId() != -1);
|
||||
assert(shape2->getBroadPhaseId() != -1);
|
||||
assert(shape1->getBroadPhaseId() != shape2->getBroadPhaseId());
|
||||
|
||||
// Check if the two shapes are still overlapping. Otherwise, we destroy the
|
||||
// overlapping pair
|
||||
|
@ -251,7 +251,7 @@ void CollisionDetection::computeConvexVsConcaveMiddlePhase(OverlappingPair* pair
|
|||
// Compute the narrow-phase collision detection
|
||||
void CollisionDetection::computeNarrowPhase() {
|
||||
|
||||
PROFILE("CollisionDetection::computeNarrowPhase()", mProfiler);
|
||||
RP3D_PROFILE("CollisionDetection::computeNarrowPhase()", mProfiler);
|
||||
|
||||
NarrowPhaseInfo* currentNarrowPhaseInfo = mNarrowPhaseInfoList;
|
||||
while (currentNarrowPhaseInfo != nullptr) {
|
||||
|
@ -308,9 +308,9 @@ void CollisionDetection::computeNarrowPhase() {
|
|||
/// This method is called by the broad-phase collision detection algorithm
|
||||
void CollisionDetection::broadPhaseNotifyOverlappingPair(ProxyShape* shape1, ProxyShape* shape2) {
|
||||
|
||||
assert(shape1->mBroadPhaseID != -1);
|
||||
assert(shape2->mBroadPhaseID != -1);
|
||||
assert(shape1->mBroadPhaseID != shape2->mBroadPhaseID);
|
||||
assert(shape1->getBroadPhaseId() != -1);
|
||||
assert(shape2->getBroadPhaseId() != -1);
|
||||
assert(shape1->getBroadPhaseId() != shape2->getBroadPhaseId());
|
||||
|
||||
// Check if the collision filtering allows collision between the two shapes
|
||||
if ((shape1->getCollideWithMaskBits() & shape2->getCollisionCategoryBits()) == 0 ||
|
||||
|
@ -338,13 +338,13 @@ void CollisionDetection::broadPhaseNotifyOverlappingPair(ProxyShape* shape1, Pro
|
|||
// Remove a body from the collision detection
|
||||
void CollisionDetection::removeProxyCollisionShape(ProxyShape* proxyShape) {
|
||||
|
||||
assert(proxyShape->mBroadPhaseID != -1);
|
||||
assert(proxyShape->getBroadPhaseId() != -1);
|
||||
|
||||
// Remove all the overlapping pairs involving this proxy shape
|
||||
Map<Pair<uint, uint>, OverlappingPair*>::Iterator it;
|
||||
for (it = mOverlappingPairs.begin(); it != mOverlappingPairs.end(); ) {
|
||||
if (it->second->getShape1()->mBroadPhaseID == proxyShape->mBroadPhaseID||
|
||||
it->second->getShape2()->mBroadPhaseID == proxyShape->mBroadPhaseID) {
|
||||
if (it->second->getShape1()->getBroadPhaseId() == proxyShape->getBroadPhaseId()||
|
||||
it->second->getShape2()->getBroadPhaseId() == proxyShape->getBroadPhaseId()) {
|
||||
|
||||
// TODO : Remove all the contact manifold of the overlapping pair from the contact manifolds list of the two bodies involved
|
||||
|
||||
|
@ -364,7 +364,7 @@ void CollisionDetection::removeProxyCollisionShape(ProxyShape* proxyShape) {
|
|||
|
||||
void CollisionDetection::addAllContactManifoldsToBodies() {
|
||||
|
||||
PROFILE("CollisionDetection::addAllContactManifoldsToBodies()", mProfiler);
|
||||
RP3D_PROFILE("CollisionDetection::addAllContactManifoldsToBodies()", mProfiler);
|
||||
|
||||
// For each overlapping pairs in contact during the narrow-phase
|
||||
Map<Pair<uint, uint>, OverlappingPair*>::Iterator it;
|
||||
|
@ -415,7 +415,7 @@ void CollisionDetection::addContactManifoldToBody(OverlappingPair* pair) {
|
|||
/// Convert the potential contact into actual contacts
|
||||
void CollisionDetection::processAllPotentialContacts() {
|
||||
|
||||
PROFILE("CollisionDetection::processAllPotentialContacts()", mProfiler);
|
||||
RP3D_PROFILE("CollisionDetection::processAllPotentialContacts()", mProfiler);
|
||||
|
||||
// For each overlapping pairs in contact during the narrow-phase
|
||||
Map<Pair<uint, uint>, OverlappingPair*>::Iterator it;
|
||||
|
@ -454,7 +454,7 @@ void CollisionDetection::processPotentialContacts(OverlappingPair* pair) {
|
|||
// Report contacts for all the colliding overlapping pairs
|
||||
void CollisionDetection::reportAllContacts() {
|
||||
|
||||
PROFILE("CollisionDetection::reportAllContacts()", mProfiler);
|
||||
RP3D_PROFILE("CollisionDetection::reportAllContacts()", mProfiler);
|
||||
|
||||
// For each overlapping pairs in contact during the narrow-phase
|
||||
Map<Pair<uint, uint>, OverlappingPair*>::Iterator it;
|
||||
|
@ -532,13 +532,13 @@ void CollisionDetection::testAABBOverlap(const AABB& aabb, OverlapCallback* over
|
|||
CollisionBody* overlapBody = proxyShape->getBody();
|
||||
|
||||
// If the proxy shape is from a body that we have not already reported collision
|
||||
if (reportedBodies.find(overlapBody->getID()) == reportedBodies.end()) {
|
||||
if (reportedBodies.find(overlapBody->getId()) == reportedBodies.end()) {
|
||||
|
||||
// Check if the collision filtering allows collision between the two shapes
|
||||
if ((proxyShape->getCollisionCategoryBits() & categoryMaskBits) != 0) {
|
||||
|
||||
// Add the body into the set of reported bodies
|
||||
reportedBodies.add(overlapBody->getID());
|
||||
reportedBodies.add(overlapBody->getId());
|
||||
|
||||
// Notify the overlap to the user
|
||||
overlapCallback->notifyOverlap(overlapBody);
|
||||
|
@ -637,16 +637,16 @@ void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* overl
|
|||
ProxyShape* bodyProxyShape = body->getProxyShapesList();
|
||||
while (bodyProxyShape != nullptr) {
|
||||
|
||||
if (bodyProxyShape->mBroadPhaseID != -1) {
|
||||
if (bodyProxyShape->getBroadPhaseId() != -1) {
|
||||
|
||||
// Get the AABB of the shape
|
||||
const AABB& shapeAABB = mBroadPhaseAlgorithm.getFatAABB(bodyProxyShape->mBroadPhaseID);
|
||||
const AABB& shapeAABB = mBroadPhaseAlgorithm.getFatAABB(bodyProxyShape->getBroadPhaseId());
|
||||
|
||||
// Ask the broad-phase to get all the overlapping shapes
|
||||
LinkedList<int> overlappingNodes(mMemoryManager.getPoolAllocator());
|
||||
mBroadPhaseAlgorithm.reportAllShapesOverlappingWithAABB(shapeAABB, overlappingNodes);
|
||||
|
||||
const bodyindex bodyId = body->getID();
|
||||
const bodyindex bodyId = body->getId();
|
||||
|
||||
// For each overlaping proxy shape
|
||||
LinkedList<int>::ListElement* element = overlappingNodes.getListHead();
|
||||
|
@ -658,8 +658,8 @@ void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* overl
|
|||
|
||||
// If the proxy shape is from a body that we have not already reported collision and the
|
||||
// two proxy collision shapes are not from the same body
|
||||
if (reportedBodies.find(proxyShape->getBody()->getID()) == reportedBodies.end() &&
|
||||
proxyShape->getBody()->getID() != bodyId) {
|
||||
if (reportedBodies.find(proxyShape->getBody()->getId()) == reportedBodies.end() &&
|
||||
proxyShape->getBody()->getId() != bodyId) {
|
||||
|
||||
// Check if the collision filtering allows collision between the two shapes
|
||||
if ((proxyShape->getCollisionCategoryBits() & categoryMaskBits) != 0) {
|
||||
|
@ -711,7 +711,7 @@ void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* overl
|
|||
CollisionBody* overlapBody = proxyShape->getBody();
|
||||
|
||||
// Add the body into the set of reported bodies
|
||||
reportedBodies.add(overlapBody->getID());
|
||||
reportedBodies.add(overlapBody->getId());
|
||||
|
||||
// Notify the overlap to the user
|
||||
overlapCallback->notifyOverlap(overlapBody);
|
||||
|
@ -817,16 +817,16 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c
|
|||
ProxyShape* bodyProxyShape = body->getProxyShapesList();
|
||||
while (bodyProxyShape != nullptr) {
|
||||
|
||||
if (bodyProxyShape->mBroadPhaseID != -1) {
|
||||
if (bodyProxyShape->getBroadPhaseId() != -1) {
|
||||
|
||||
// Get the AABB of the shape
|
||||
const AABB& shapeAABB = mBroadPhaseAlgorithm.getFatAABB(bodyProxyShape->mBroadPhaseID);
|
||||
const AABB& shapeAABB = mBroadPhaseAlgorithm.getFatAABB(bodyProxyShape->getBroadPhaseId());
|
||||
|
||||
// Ask the broad-phase to get all the overlapping shapes
|
||||
LinkedList<int> overlappingNodes(mMemoryManager.getPoolAllocator());
|
||||
mBroadPhaseAlgorithm.reportAllShapesOverlappingWithAABB(shapeAABB, overlappingNodes);
|
||||
|
||||
const bodyindex bodyId = body->getID();
|
||||
const bodyindex bodyId = body->getId();
|
||||
|
||||
// For each overlaping proxy shape
|
||||
LinkedList<int>::ListElement* element = overlappingNodes.getListHead();
|
||||
|
@ -837,7 +837,7 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c
|
|||
ProxyShape* proxyShape = mBroadPhaseAlgorithm.getProxyShapeForBroadPhaseId(broadPhaseId);
|
||||
|
||||
// If the two proxy collision shapes are not from the same body
|
||||
if (proxyShape->getBody()->getID() != bodyId) {
|
||||
if (proxyShape->getBody()->getId() != bodyId) {
|
||||
|
||||
// Check if the collision filtering allows collision between the two shapes
|
||||
if ((proxyShape->getCollisionCategoryBits() & categoryMaskBits) != 0) {
|
||||
|
@ -996,6 +996,6 @@ EventListener* CollisionDetection::getWorldEventListener() {
|
|||
|
||||
// Return the world-space AABB of a given proxy shape
|
||||
const AABB CollisionDetection::getWorldAABB(const ProxyShape* proxyShape) const {
|
||||
assert(proxyShape->mBroadPhaseID > -1);
|
||||
return mBroadPhaseAlgorithm.getFatAABB(proxyShape->mBroadPhaseID);
|
||||
assert(proxyShape->getBroadPhaseId() > -1);
|
||||
return mBroadPhaseAlgorithm.getFatAABB(proxyShape->getBroadPhaseId());
|
||||
}
|
||||
|
|
|
@ -279,8 +279,8 @@ inline void CollisionDetection::removeNoCollisionPair(CollisionBody* body1,
|
|||
/// previous frame so that it is tested for collision again in the broad-phase.
|
||||
inline void CollisionDetection::askForBroadPhaseCollisionCheck(ProxyShape* shape) {
|
||||
|
||||
if (shape->mBroadPhaseID != -1) {
|
||||
mBroadPhaseAlgorithm.addMovedCollisionShape(shape->mBroadPhaseID);
|
||||
if (shape->getBroadPhaseId() != -1) {
|
||||
mBroadPhaseAlgorithm.addMovedCollisionShape(shape->getBroadPhaseId());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -314,7 +314,7 @@ inline void CollisionDetection::raycast(RaycastCallback* raycastCallback,
|
|||
const Ray& ray,
|
||||
unsigned short raycastWithCategoryMaskBits) const {
|
||||
|
||||
PROFILE("CollisionDetection::raycast()", mProfiler);
|
||||
RP3D_PROFILE("CollisionDetection::raycast()", mProfiler);
|
||||
|
||||
RaycastTest rayCastTest(raycastCallback);
|
||||
|
||||
|
|
|
@ -93,6 +93,12 @@ class ProxyShape {
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
|
||||
/// Logger
|
||||
Logger* mLogger;
|
||||
#endif
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Return the collision shape
|
||||
|
@ -169,11 +175,8 @@ class ProxyShape {
|
|||
/// Return the next proxy shape in the linked list of proxy shapes
|
||||
const ProxyShape* getNext() const;
|
||||
|
||||
/// Return the local scaling vector of the collision shape
|
||||
Vector3 getLocalScaling() const;
|
||||
|
||||
/// Set the local scaling vector of the collision shape
|
||||
virtual void setLocalScaling(const Vector3& scaling);
|
||||
/// Return the broad-phase id
|
||||
int getBroadPhaseId() const;
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
|
@ -182,6 +185,12 @@ class ProxyShape {
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
|
||||
/// Set the logger
|
||||
void setLogger(Logger* logger);
|
||||
#endif
|
||||
|
||||
// -------------------- Friendship -------------------- //
|
||||
|
||||
friend class OverlappingPair;
|
||||
|
@ -265,6 +274,10 @@ inline void ProxyShape::setLocalToBodyTransform(const Transform& transform) {
|
|||
|
||||
// Notify the body that the proxy shape has to be updated in the broad-phase
|
||||
mBody->updateProxyShapeInBroadPhase(this, true);
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::ProxyShape,
|
||||
"ProxyShape " + std::to_string(mBroadPhaseID) + ": Set localToBodyTransform=" +
|
||||
mLocalToBodyTransform.to_string());
|
||||
}
|
||||
|
||||
// Return the local to world transform
|
||||
|
@ -316,6 +329,10 @@ inline unsigned short ProxyShape::getCollisionCategoryBits() const {
|
|||
*/
|
||||
inline void ProxyShape::setCollisionCategoryBits(unsigned short collisionCategoryBits) {
|
||||
mCollisionCategoryBits = collisionCategoryBits;
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::ProxyShape,
|
||||
"ProxyShape " + std::to_string(mBroadPhaseID) + ": Set collisionCategoryBits=" +
|
||||
std::to_string(mCollisionCategoryBits));
|
||||
}
|
||||
|
||||
// Return the collision bits mask
|
||||
|
@ -332,29 +349,15 @@ inline unsigned short ProxyShape::getCollideWithMaskBits() const {
|
|||
*/
|
||||
inline void ProxyShape::setCollideWithMaskBits(unsigned short collideWithMaskBits) {
|
||||
mCollideWithMaskBits = collideWithMaskBits;
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::ProxyShape,
|
||||
"ProxyShape " + std::to_string(mBroadPhaseID) + ": Set collideWithMaskBits=" +
|
||||
std::to_string(mCollideWithMaskBits));
|
||||
}
|
||||
|
||||
// Return the local scaling vector of the collision shape
|
||||
/**
|
||||
* @return The local scaling vector
|
||||
*/
|
||||
inline Vector3 ProxyShape::getLocalScaling() const {
|
||||
return mCollisionShape->getLocalScaling();
|
||||
}
|
||||
|
||||
// Set the local scaling vector of the collision shape
|
||||
/**
|
||||
* @param scaling The new local scaling vector
|
||||
*/
|
||||
inline void ProxyShape::setLocalScaling(const Vector3& scaling) {
|
||||
|
||||
// Set the local scaling of the collision shape
|
||||
mCollisionShape->setLocalScaling(scaling);
|
||||
|
||||
mBody->setIsSleeping(false);
|
||||
|
||||
// Notify the body that the proxy shape has to be updated in the broad-phase
|
||||
mBody->updateProxyShapeInBroadPhase(this, true);
|
||||
// Return the broad-phase id
|
||||
inline int ProxyShape::getBroadPhaseId() const {
|
||||
return mBroadPhaseID;
|
||||
}
|
||||
|
||||
/// Test if the proxy shape overlaps with a given AABB
|
||||
|
@ -378,6 +381,16 @@ inline void ProxyShape::setProfiler(Profiler* profiler) {
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
|
||||
// Set the logger
|
||||
inline void ProxyShape::setLogger(Logger* logger) {
|
||||
|
||||
mLogger = logger;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -280,3 +280,55 @@ void TriangleVertexArray::getTriangleVerticesNormals(uint triangleIndex, Vector3
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return a vertex of the array
|
||||
void TriangleVertexArray::getVertex(uint vertexIndex, Vector3* outVertex) {
|
||||
|
||||
assert(vertexIndex < mNbVertices);
|
||||
|
||||
const uchar* vertexPointerChar = mVerticesStart + vertexIndex * mVerticesStride;
|
||||
const void* vertexPointer = static_cast<const void*>(vertexPointerChar);
|
||||
|
||||
// Get the vertices components of the triangle
|
||||
if (mVertexDataType == TriangleVertexArray::VertexDataType::VERTEX_FLOAT_TYPE) {
|
||||
const float* vertices = static_cast<const float*>(vertexPointer);
|
||||
(*outVertex)[0] = decimal(vertices[0]);
|
||||
(*outVertex)[1] = decimal(vertices[1]);
|
||||
(*outVertex)[2] = decimal(vertices[2]);
|
||||
}
|
||||
else if (mVertexDataType == TriangleVertexArray::VertexDataType::VERTEX_DOUBLE_TYPE) {
|
||||
const double* vertices = static_cast<const double*>(vertexPointer);
|
||||
(*outVertex)[0] = decimal(vertices[0]);
|
||||
(*outVertex)[1] = decimal(vertices[1]);
|
||||
(*outVertex)[2] = decimal(vertices[2]);
|
||||
}
|
||||
else {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Return a vertex normal of the array
|
||||
void TriangleVertexArray::getNormal(uint vertexIndex, Vector3* outNormal) {
|
||||
|
||||
assert(vertexIndex < mNbVertices);
|
||||
|
||||
const uchar* vertexNormalPointerChar = mVerticesNormalsStart + vertexIndex * mVerticesNormalsStride;
|
||||
const void* vertexNormalPointer = static_cast<const void*>(vertexNormalPointerChar);
|
||||
|
||||
// Get the normals from the array
|
||||
if (mVertexNormaldDataType == TriangleVertexArray::NormalDataType::NORMAL_FLOAT_TYPE) {
|
||||
const float* normal = static_cast<const float*>(vertexNormalPointer);
|
||||
(*outNormal)[0] = decimal(normal[0]);
|
||||
(*outNormal)[1] = decimal(normal[1]);
|
||||
(*outNormal)[2] = decimal(normal[2]);
|
||||
}
|
||||
else if (mVertexNormaldDataType == TriangleVertexArray::NormalDataType::NORMAL_DOUBLE_TYPE) {
|
||||
const double* normal = static_cast<const double*>(vertexNormalPointer);
|
||||
(*outNormal)[0] = decimal(normal[0]);
|
||||
(*outNormal)[1] = decimal(normal[1]);
|
||||
(*outNormal)[2] = decimal(normal[2]);
|
||||
}
|
||||
else {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,6 +169,12 @@ class TriangleVertexArray {
|
|||
|
||||
/// Return the indices of the three vertices of a given triangle in the array
|
||||
void getTriangleVerticesIndices(uint triangleIndex, uint* outVerticesIndices) const;
|
||||
|
||||
/// Return a vertex of the array
|
||||
void getVertex(uint vertexIndex, Vector3* outVertex);
|
||||
|
||||
/// Return a vertex normal of the array
|
||||
void getNormal(uint vertexIndex, Vector3* outNormal);
|
||||
};
|
||||
|
||||
// Return the vertex data type
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
// Libraries
|
||||
#include "BroadPhaseAlgorithm.h"
|
||||
#include "collision/CollisionDetection.h"
|
||||
#include "engine/Profiler.h"
|
||||
#include "utils/Profiler.h"
|
||||
|
||||
// We want to use the ReactPhysics3D namespace
|
||||
using namespace reactphysics3d;
|
||||
|
@ -140,7 +140,7 @@ void BroadPhaseAlgorithm::removeMovedCollisionShape(int broadPhaseID) {
|
|||
// Add a proxy collision shape into the broad-phase collision detection
|
||||
void BroadPhaseAlgorithm::addProxyCollisionShape(ProxyShape* proxyShape, const AABB& aabb) {
|
||||
|
||||
assert(proxyShape->mBroadPhaseID == -1);
|
||||
assert(proxyShape->getBroadPhaseId() == -1);
|
||||
|
||||
// Add the collision shape into the dynamic AABB tree and get its broad-phase ID
|
||||
int nodeId = mDynamicAABBTree.addObject(aabb, proxyShape);
|
||||
|
@ -150,15 +150,15 @@ void BroadPhaseAlgorithm::addProxyCollisionShape(ProxyShape* proxyShape, const A
|
|||
|
||||
// Add the collision shape into the array of bodies that have moved (or have been created)
|
||||
// during the last simulation step
|
||||
addMovedCollisionShape(proxyShape->mBroadPhaseID);
|
||||
addMovedCollisionShape(proxyShape->getBroadPhaseId());
|
||||
}
|
||||
|
||||
// Remove a proxy collision shape from the broad-phase collision detection
|
||||
void BroadPhaseAlgorithm::removeProxyCollisionShape(ProxyShape* proxyShape) {
|
||||
|
||||
assert(proxyShape->mBroadPhaseID != -1);
|
||||
assert(proxyShape->getBroadPhaseId() != -1);
|
||||
|
||||
int broadPhaseID = proxyShape->mBroadPhaseID;
|
||||
int broadPhaseID = proxyShape->getBroadPhaseId();
|
||||
|
||||
proxyShape->mBroadPhaseID = -1;
|
||||
|
||||
|
@ -174,7 +174,7 @@ void BroadPhaseAlgorithm::removeProxyCollisionShape(ProxyShape* proxyShape) {
|
|||
void BroadPhaseAlgorithm::updateProxyCollisionShape(ProxyShape* proxyShape, const AABB& aabb,
|
||||
const Vector3& displacement, bool forceReinsert) {
|
||||
|
||||
int broadPhaseID = proxyShape->mBroadPhaseID;
|
||||
int broadPhaseID = proxyShape->getBroadPhaseId();
|
||||
|
||||
assert(broadPhaseID >= 0);
|
||||
|
||||
|
@ -257,7 +257,7 @@ void BroadPhaseAlgorithm::computeOverlappingPairs(MemoryManager& memoryManager)
|
|||
ProxyShape* shape2 = static_cast<ProxyShape*>(mDynamicAABBTree.getNodeDataPointer(pair->collisionShape2ID));
|
||||
|
||||
// If the two proxy collision shapes are from the same body, skip it
|
||||
if (shape1->getBody()->getID() != shape2->getBody()->getID()) {
|
||||
if (shape1->getBody()->getId() != shape2->getBody()->getId()) {
|
||||
|
||||
// Notify the collision detection about the overlapping pair
|
||||
mCollisionDetection.broadPhaseNotifyOverlappingPair(shape1, shape2);
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include "body/CollisionBody.h"
|
||||
#include "collision/ProxyShape.h"
|
||||
#include "DynamicAABBTree.h"
|
||||
#include "engine/Profiler.h"
|
||||
#include "utils/Profiler.h"
|
||||
#include "containers/LinkedList.h"
|
||||
|
||||
/// Namespace ReactPhysics3D
|
||||
|
@ -246,11 +246,11 @@ inline bool BroadPhasePair::smallerThan(const BroadPhasePair& pair1, const Broad
|
|||
inline bool BroadPhaseAlgorithm::testOverlappingShapes(const ProxyShape* shape1,
|
||||
const ProxyShape* shape2) const {
|
||||
|
||||
if (shape1->mBroadPhaseID == -1 || shape2->mBroadPhaseID == -1) return false;
|
||||
if (shape1->getBroadPhaseId() == -1 || shape2->getBroadPhaseId() == -1) return false;
|
||||
|
||||
// Get the two AABBs of the collision shapes
|
||||
const AABB& aabb1 = mDynamicAABBTree.getFatAABB(shape1->mBroadPhaseID);
|
||||
const AABB& aabb2 = mDynamicAABBTree.getFatAABB(shape2->mBroadPhaseID);
|
||||
const AABB& aabb1 = mDynamicAABBTree.getFatAABB(shape1->getBroadPhaseId());
|
||||
const AABB& aabb2 = mDynamicAABBTree.getFatAABB(shape2->getBroadPhaseId());
|
||||
|
||||
// Check if the two AABBs are overlapping
|
||||
return aabb1.testCollision(aabb2);
|
||||
|
@ -265,7 +265,7 @@ inline const AABB& BroadPhaseAlgorithm::getFatAABB(int broadPhaseId) const {
|
|||
inline void BroadPhaseAlgorithm::raycast(const Ray& ray, RaycastTest& raycastTest,
|
||||
unsigned short raycastWithCategoryMaskBits) const {
|
||||
|
||||
PROFILE("BroadPhaseAlgorithm::raycast()", mProfiler);
|
||||
RP3D_PROFILE("BroadPhaseAlgorithm::raycast()", mProfiler);
|
||||
|
||||
BroadPhaseRaycastCallback broadPhaseRaycastCallback(mDynamicAABBTree, raycastWithCategoryMaskBits, raycastTest);
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "DynamicAABBTree.h"
|
||||
#include "BroadPhaseAlgorithm.h"
|
||||
#include "containers/Stack.h"
|
||||
#include "engine/Profiler.h"
|
||||
#include "utils/Profiler.h"
|
||||
|
||||
using namespace reactphysics3d;
|
||||
|
||||
|
@ -173,7 +173,7 @@ void DynamicAABBTree::removeObject(int nodeID) {
|
|||
/// (this can be useful if the shape AABB has become much smaller than the previous one for instance).
|
||||
bool DynamicAABBTree::updateObject(int nodeID, const AABB& newAABB, const Vector3& displacement, bool forceReinsert) {
|
||||
|
||||
PROFILE("DynamicAABBTree::updateObject()", mProfiler);
|
||||
RP3D_PROFILE("DynamicAABBTree::updateObject()", mProfiler);
|
||||
|
||||
assert(nodeID >= 0 && nodeID < mNbAllocatedNodes);
|
||||
assert(mNodes[nodeID].isLeaf());
|
||||
|
@ -635,7 +635,7 @@ void DynamicAABBTree::reportAllShapesOverlappingWithAABB(const AABB& aabb,
|
|||
// Ray casting method
|
||||
void DynamicAABBTree::raycast(const Ray& ray, DynamicAABBTreeRaycastCallback &callback) const {
|
||||
|
||||
PROFILE("DynamicAABBTree::raycast()", mProfiler);
|
||||
RP3D_PROFILE("DynamicAABBTree::raycast()", mProfiler);
|
||||
|
||||
decimal maxFraction = ray.maxFraction;
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include "engine/OverlappingPair.h"
|
||||
#include "collision/shapes/TriangleShape.h"
|
||||
#include "configuration.h"
|
||||
#include "engine/Profiler.h"
|
||||
#include "utils/Profiler.h"
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cfloat>
|
||||
|
@ -49,7 +49,7 @@ using namespace reactphysics3d;
|
|||
/// the correct penetration depth and contact points between the enlarged objects.
|
||||
GJKAlgorithm::GJKResult GJKAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) {
|
||||
|
||||
PROFILE("GJKAlgorithm::testCollision()", mProfiler);
|
||||
RP3D_PROFILE("GJKAlgorithm::testCollision()", mProfiler);
|
||||
|
||||
Vector3 suppA; // Support point of object A
|
||||
Vector3 suppB; // Support point of object B
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "engine/OverlappingPair.h"
|
||||
#include "collision/shapes/TriangleShape.h"
|
||||
#include "configuration.h"
|
||||
#include "engine/Profiler.h"
|
||||
#include "utils/Profiler.h"
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cfloat>
|
||||
|
@ -52,7 +52,7 @@ SATAlgorithm::SATAlgorithm(MemoryAllocator& memoryAllocator) : mMemoryAllocator(
|
|||
// Test collision between a sphere and a convex mesh
|
||||
bool SATAlgorithm::testCollisionSphereVsConvexPolyhedron(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) const {
|
||||
|
||||
PROFILE("SATAlgorithm::testCollisionSphereVsConvexPolyhedron()", mProfiler);
|
||||
RP3D_PROFILE("SATAlgorithm::testCollisionSphereVsConvexPolyhedron()", mProfiler);
|
||||
|
||||
bool isSphereShape1 = narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::SPHERE;
|
||||
|
||||
|
@ -127,7 +127,7 @@ bool SATAlgorithm::testCollisionSphereVsConvexPolyhedron(NarrowPhaseInfo* narrow
|
|||
decimal SATAlgorithm::computePolyhedronFaceVsSpherePenetrationDepth(uint faceIndex, const ConvexPolyhedronShape* polyhedron,
|
||||
const SphereShape* sphere, const Vector3& sphereCenter) const {
|
||||
|
||||
PROFILE("SATAlgorithm::computePolyhedronFaceVsSpherePenetrationDepth)", mProfiler);
|
||||
RP3D_PROFILE("SATAlgorithm::computePolyhedronFaceVsSpherePenetrationDepth)", mProfiler);
|
||||
|
||||
// Get the face
|
||||
const HalfEdgeStructure::Face& face = polyhedron->getFace(faceIndex);
|
||||
|
@ -144,7 +144,7 @@ decimal SATAlgorithm::computePolyhedronFaceVsSpherePenetrationDepth(uint faceInd
|
|||
// Test collision between a capsule and a convex mesh
|
||||
bool SATAlgorithm::testCollisionCapsuleVsConvexPolyhedron(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) const {
|
||||
|
||||
PROFILE("SATAlgorithm::testCollisionCapsuleVsConvexPolyhedron()", mProfiler);
|
||||
RP3D_PROFILE("SATAlgorithm::testCollisionCapsuleVsConvexPolyhedron()", mProfiler);
|
||||
|
||||
bool isCapsuleShape1 = narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::CAPSULE;
|
||||
|
||||
|
@ -304,7 +304,7 @@ decimal SATAlgorithm::computeEdgeVsCapsuleInnerSegmentPenetrationDepth(const Con
|
|||
const Vector3& edgeDirectionCapsuleSpace,
|
||||
const Transform& polyhedronToCapsuleTransform, Vector3& outAxis) const {
|
||||
|
||||
PROFILE("SATAlgorithm::computeEdgeVsCapsuleInnerSegmentPenetrationDepth)", mProfiler);
|
||||
RP3D_PROFILE("SATAlgorithm::computeEdgeVsCapsuleInnerSegmentPenetrationDepth)", mProfiler);
|
||||
|
||||
decimal penetrationDepth = DECIMAL_LARGEST;
|
||||
|
||||
|
@ -338,7 +338,7 @@ decimal SATAlgorithm::computePolyhedronFaceVsCapsulePenetrationDepth(uint polyhe
|
|||
const CapsuleShape* capsule, const Transform& polyhedronToCapsuleTransform,
|
||||
Vector3& outFaceNormalCapsuleSpace) const {
|
||||
|
||||
PROFILE("SATAlgorithm::computePolyhedronFaceVsCapsulePenetrationDepth", mProfiler);
|
||||
RP3D_PROFILE("SATAlgorithm::computePolyhedronFaceVsCapsulePenetrationDepth", mProfiler);
|
||||
|
||||
// Get the face
|
||||
const HalfEdgeStructure::Face& face = polyhedron->getFace(polyhedronFaceIndex);
|
||||
|
@ -364,7 +364,7 @@ bool SATAlgorithm::computeCapsulePolyhedronFaceContactPoints(uint referenceFaceI
|
|||
const Vector3& capsuleSegAPolyhedronSpace, const Vector3& capsuleSegBPolyhedronSpace,
|
||||
NarrowPhaseInfo* narrowPhaseInfo, bool isCapsuleShape1) const {
|
||||
|
||||
PROFILE("SATAlgorithm::computeCapsulePolyhedronFaceContactPoints", mProfiler);
|
||||
RP3D_PROFILE("SATAlgorithm::computeCapsulePolyhedronFaceContactPoints", mProfiler);
|
||||
|
||||
const HalfEdgeStructure::Face& face = polyhedron->getFace(referenceFaceIndex);
|
||||
|
||||
|
@ -459,7 +459,7 @@ bool SATAlgorithm::isMinkowskiFaceCapsuleVsEdge(const Vector3& capsuleSegment, c
|
|||
// Test collision between two convex polyhedrons
|
||||
bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts) const {
|
||||
|
||||
PROFILE("SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron()", mProfiler);
|
||||
RP3D_PROFILE("SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron()", mProfiler);
|
||||
|
||||
assert(narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::CONVEX_POLYHEDRON);
|
||||
assert(narrowPhaseInfo->collisionShape2->getType() == CollisionShapeType::CONVEX_POLYHEDRON);
|
||||
|
@ -804,7 +804,7 @@ bool SATAlgorithm::computePolyhedronVsPolyhedronFaceContactPoints(bool isMinPene
|
|||
const Transform& polyhedron1ToPolyhedron2, const Transform& polyhedron2ToPolyhedron1,
|
||||
uint minFaceIndex, NarrowPhaseInfo* narrowPhaseInfo, decimal minPenetrationDepth) const {
|
||||
|
||||
PROFILE("SATAlgorithm::computePolyhedronVsPolyhedronFaceContactPoints", mProfiler);
|
||||
RP3D_PROFILE("SATAlgorithm::computePolyhedronVsPolyhedronFaceContactPoints", mProfiler);
|
||||
|
||||
const ConvexPolyhedronShape* referencePolyhedron = isMinPenetrationFaceNormalPolyhedron1 ? polyhedron1 : polyhedron2;
|
||||
const ConvexPolyhedronShape* incidentPolyhedron = isMinPenetrationFaceNormalPolyhedron1 ? polyhedron2 : polyhedron1;
|
||||
|
@ -919,7 +919,7 @@ decimal SATAlgorithm::computeDistanceBetweenEdges(const Vector3& edge1A, const V
|
|||
const Vector3& edge1Direction, const Vector3& edge2Direction,
|
||||
Vector3& outSeparatingAxisPolyhedron2Space) const {
|
||||
|
||||
PROFILE("SATAlgorithm::computeDistanceBetweenEdges", mProfiler);
|
||||
RP3D_PROFILE("SATAlgorithm::computeDistanceBetweenEdges", mProfiler);
|
||||
|
||||
// If the two edges are parallel
|
||||
if (areParallelVectors(edge1Direction, edge2Direction)) {
|
||||
|
@ -948,7 +948,7 @@ decimal SATAlgorithm::testSingleFaceDirectionPolyhedronVsPolyhedron(const Convex
|
|||
const Transform& polyhedron1ToPolyhedron2,
|
||||
uint faceIndex) const {
|
||||
|
||||
PROFILE("SATAlgorithm::testSingleFaceDirectionPolyhedronVsPolyhedron", mProfiler);
|
||||
RP3D_PROFILE("SATAlgorithm::testSingleFaceDirectionPolyhedronVsPolyhedron", mProfiler);
|
||||
|
||||
const HalfEdgeStructure::Face& face = polyhedron1->getFace(faceIndex);
|
||||
|
||||
|
@ -974,7 +974,7 @@ decimal SATAlgorithm::testFacesDirectionPolyhedronVsPolyhedron(const ConvexPolyh
|
|||
const Transform& polyhedron1ToPolyhedron2,
|
||||
uint& minFaceIndex) const {
|
||||
|
||||
PROFILE("SATAlgorithm::testFacesDirectionPolyhedronVsPolyhedron", mProfiler);
|
||||
RP3D_PROFILE("SATAlgorithm::testFacesDirectionPolyhedronVsPolyhedron", mProfiler);
|
||||
|
||||
decimal minPenetrationDepth = DECIMAL_LARGEST;
|
||||
|
||||
|
@ -1006,7 +1006,7 @@ bool SATAlgorithm::testEdgesBuildMinkowskiFace(const ConvexPolyhedronShape* poly
|
|||
const ConvexPolyhedronShape* polyhedron2, const HalfEdgeStructure::Edge& edge2,
|
||||
const Transform& polyhedron1ToPolyhedron2) const {
|
||||
|
||||
PROFILE("SATAlgorithm::testEdgesBuildMinkowskiFace", mProfiler);
|
||||
RP3D_PROFILE("SATAlgorithm::testEdgesBuildMinkowskiFace", mProfiler);
|
||||
|
||||
const Vector3 a = polyhedron1ToPolyhedron2.getOrientation() * polyhedron1->getFaceNormal(edge1.faceIndex);
|
||||
const Vector3 b = polyhedron1ToPolyhedron2.getOrientation() * polyhedron1->getFaceNormal(polyhedron1->getHalfEdge(edge1.twinEdgeIndex).faceIndex);
|
||||
|
@ -1039,7 +1039,7 @@ bool SATAlgorithm::testEdgesBuildMinkowskiFace(const ConvexPolyhedronShape* poly
|
|||
bool SATAlgorithm::testGaussMapArcsIntersect(const Vector3& a, const Vector3& b, const Vector3& c, const Vector3& d,
|
||||
const Vector3& bCrossA, const Vector3& dCrossC) const {
|
||||
|
||||
PROFILE("SATAlgorithm::testGaussMapArcsIntersect", mProfiler);
|
||||
RP3D_PROFILE("SATAlgorithm::testGaussMapArcsIntersect", mProfiler);
|
||||
|
||||
const decimal cba = c.dot(bCrossA);
|
||||
const decimal dba = d.dot(bCrossA);
|
||||
|
|
|
@ -88,9 +88,6 @@ class BoxShape : public ConvexPolyhedronShape {
|
|||
/// Return the extents of the box
|
||||
Vector3 getExtent() const;
|
||||
|
||||
/// Set the scaling vector of the collision shape
|
||||
virtual void setLocalScaling(const Vector3& scaling) override;
|
||||
|
||||
/// Return the local bounds of the shape in x, y and z directions
|
||||
virtual void getLocalBounds(Vector3& min, Vector3& max) const override;
|
||||
|
||||
|
@ -123,6 +120,9 @@ class BoxShape : public ConvexPolyhedronShape {
|
|||
|
||||
/// Return the centroid of the polyhedron
|
||||
virtual Vector3 getCentroid() const override;
|
||||
|
||||
/// Return the string representation of the shape
|
||||
virtual std::string to_string() const override;
|
||||
};
|
||||
|
||||
// Return the extents of the box
|
||||
|
@ -133,14 +133,6 @@ inline Vector3 BoxShape::getExtent() const {
|
|||
return mExtent;
|
||||
}
|
||||
|
||||
// Set the scaling vector of the collision shape
|
||||
inline void BoxShape::setLocalScaling(const Vector3& scaling) {
|
||||
|
||||
mExtent = (mExtent / mScaling) * scaling;
|
||||
|
||||
CollisionShape::setLocalScaling(scaling);
|
||||
}
|
||||
|
||||
// Return the local bounds of the shape in x, y and z directions
|
||||
/// This method is used to compute the AABB of the box
|
||||
/**
|
||||
|
@ -237,6 +229,11 @@ inline Vector3 BoxShape::getCentroid() const {
|
|||
return Vector3::zero();
|
||||
}
|
||||
|
||||
// Return the string representation of the shape
|
||||
inline std::string BoxShape::to_string() const {
|
||||
return "BoxShape{extents=" + mExtent.to_string() + "}";
|
||||
}
|
||||
|
||||
// Return the number of half-edges of the polyhedron
|
||||
inline uint BoxShape::getNbHalfEdges() const {
|
||||
return 24;
|
||||
|
|
|
@ -94,9 +94,6 @@ class CapsuleShape : public ConvexShape {
|
|||
/// Return the height of the capsule
|
||||
decimal getHeight() const;
|
||||
|
||||
/// Set the scaling vector of the collision shape
|
||||
virtual void setLocalScaling(const Vector3& scaling) override;
|
||||
|
||||
/// Return the local bounds of the shape in x, y and z directions
|
||||
virtual void getLocalBounds(Vector3& min, Vector3& max) const override;
|
||||
|
||||
|
@ -105,6 +102,9 @@ class CapsuleShape : public ConvexShape {
|
|||
|
||||
/// Return the local inertia tensor of the collision shape
|
||||
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const override;
|
||||
|
||||
/// Return the string representation of the shape
|
||||
virtual std::string to_string() const override;
|
||||
};
|
||||
|
||||
// Get the radius of the capsule
|
||||
|
@ -123,15 +123,6 @@ inline decimal CapsuleShape::getHeight() const {
|
|||
return mHalfHeight + mHalfHeight;
|
||||
}
|
||||
|
||||
// Set the scaling vector of the collision shape
|
||||
inline void CapsuleShape::setLocalScaling(const Vector3& scaling) {
|
||||
|
||||
mHalfHeight = (mHalfHeight / mScaling.y) * scaling.y;
|
||||
mMargin = (mMargin / mScaling.x) * scaling.x;
|
||||
|
||||
CollisionShape::setLocalScaling(scaling);
|
||||
}
|
||||
|
||||
// Return the number of bytes used by the collision shape
|
||||
inline size_t CapsuleShape::getSizeInBytes() const {
|
||||
return sizeof(CapsuleShape);
|
||||
|
@ -185,6 +176,11 @@ inline Vector3 CapsuleShape::getLocalSupportPointWithoutMargin(const Vector3& di
|
|||
}
|
||||
}
|
||||
|
||||
// Return the string representation of the shape
|
||||
inline std::string CapsuleShape::to_string() const {
|
||||
return "CapsuleShape{halfHeight=" + std::to_string(mHalfHeight) + ", radius=" + std::to_string(getRadius()) + "}";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
// Libraries
|
||||
#include "CollisionShape.h"
|
||||
#include "engine/Profiler.h"
|
||||
#include "utils/Profiler.h"
|
||||
#include "body/CollisionBody.h"
|
||||
|
||||
// We want to use the ReactPhysics3D namespace
|
||||
|
@ -33,7 +33,7 @@ using namespace reactphysics3d;
|
|||
|
||||
// Constructor
|
||||
CollisionShape::CollisionShape(CollisionShapeName name, CollisionShapeType type)
|
||||
: mType(type), mName(name), mScaling(1.0, 1.0, 1.0), mId(0) {
|
||||
: mType(type), mName(name), mId(0) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ CollisionShape::CollisionShape(CollisionShapeName name, CollisionShapeType type)
|
|||
*/
|
||||
void CollisionShape::computeAABB(AABB& aabb, const Transform& transform) const {
|
||||
|
||||
PROFILE("CollisionShape::computeAABB()", mProfiler);
|
||||
RP3D_PROFILE("CollisionShape::computeAABB()", mProfiler);
|
||||
|
||||
// Get the local bounds in x,y and z direction
|
||||
Vector3 minBounds;
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include "AABB.h"
|
||||
#include "collision/RaycastInfo.h"
|
||||
#include "memory/PoolAllocator.h"
|
||||
#include "engine/Profiler.h"
|
||||
#include "utils/Profiler.h"
|
||||
|
||||
/// ReactPhysics3D namespace
|
||||
namespace reactphysics3d {
|
||||
|
@ -68,9 +68,6 @@ class CollisionShape {
|
|||
/// Name of the colision shape
|
||||
CollisionShapeName mName;
|
||||
|
||||
/// Scaling vector of the collision shape
|
||||
Vector3 mScaling;
|
||||
|
||||
/// Unique identifier of the shape inside an overlapping pair
|
||||
uint mId;
|
||||
|
||||
|
@ -126,9 +123,6 @@ class CollisionShape {
|
|||
/// Return the scaling vector of the collision shape
|
||||
Vector3 getLocalScaling() const;
|
||||
|
||||
/// Set the local scaling vector of the collision shape
|
||||
virtual void setLocalScaling(const Vector3& scaling);
|
||||
|
||||
/// Return the id of the shape
|
||||
uint getId() const;
|
||||
|
||||
|
@ -138,6 +132,9 @@ class CollisionShape {
|
|||
/// Compute the world-space AABB of the collision shape given a transform
|
||||
virtual void computeAABB(AABB& aabb, const Transform& transform) const;
|
||||
|
||||
/// Return the string representation of the shape
|
||||
virtual std::string to_string() const=0;
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
/// Set the profiler
|
||||
|
@ -167,16 +164,6 @@ inline CollisionShapeType CollisionShape::getType() const {
|
|||
return mType;
|
||||
}
|
||||
|
||||
// Return the scaling vector of the collision shape
|
||||
inline Vector3 CollisionShape::getLocalScaling() const {
|
||||
return mScaling;
|
||||
}
|
||||
|
||||
// Set the scaling vector of the collision shape
|
||||
inline void CollisionShape::setLocalScaling(const Vector3& scaling) {
|
||||
mScaling = scaling;
|
||||
}
|
||||
|
||||
// Return the id of the shape
|
||||
inline uint CollisionShape::getId() const {
|
||||
return mId;
|
||||
|
|
|
@ -30,8 +30,9 @@
|
|||
using namespace reactphysics3d;
|
||||
|
||||
// Constructor
|
||||
ConcaveMeshShape::ConcaveMeshShape(TriangleMesh* triangleMesh)
|
||||
: ConcaveShape(CollisionShapeName::TRIANGLE_MESH), mDynamicAABBTree(MemoryManager::getBaseAllocator()) {
|
||||
ConcaveMeshShape::ConcaveMeshShape(TriangleMesh* triangleMesh, const Vector3& scaling)
|
||||
: ConcaveShape(CollisionShapeName::TRIANGLE_MESH), mDynamicAABBTree(MemoryManager::getBaseAllocator()),
|
||||
mScaling(scaling) {
|
||||
mTriangleMesh = triangleMesh;
|
||||
mRaycastTestType = TriangleRaycastSide::FRONT;
|
||||
|
||||
|
@ -114,7 +115,7 @@ void ConcaveMeshShape::testAllTriangles(TriangleCallback& callback, const AABB&
|
|||
/// the ray hits many triangles.
|
||||
bool ConcaveMeshShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, MemoryAllocator& allocator) const {
|
||||
|
||||
PROFILE("ConcaveMeshShape::raycast()", mProfiler);
|
||||
RP3D_PROFILE("ConcaveMeshShape::raycast()", mProfiler);
|
||||
|
||||
// Create the callback object that will compute ray casting against triangles
|
||||
ConcaveMeshRaycastCallback raycastCallback(mDynamicAABBTree, *this, proxyShape, raycastInfo, ray, allocator);
|
||||
|
@ -214,3 +215,68 @@ void ConcaveMeshRaycastCallback::raycastTriangles() {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
// Return the string representation of the shape
|
||||
std::string ConcaveMeshShape::to_string() const {
|
||||
|
||||
std::stringstream ss;
|
||||
|
||||
ss << "ConcaveMeshShape{" << std::endl;
|
||||
ss << "nbSubparts=" << mTriangleMesh->getNbSubparts() << std::endl;
|
||||
|
||||
// Vertices array
|
||||
for (uint subPart=0; subPart<mTriangleMesh->getNbSubparts(); subPart++) {
|
||||
|
||||
// Get the triangle vertex array of the current sub-part
|
||||
TriangleVertexArray* triangleVertexArray = mTriangleMesh->getSubpart(subPart);
|
||||
|
||||
ss << "subpart" << subPart << "={" << std::endl;
|
||||
ss << "nbVertices=" << triangleVertexArray->getNbVertices() << std::endl;
|
||||
ss << "nbTriangles=" << triangleVertexArray->getNbTriangles() << std::endl;
|
||||
|
||||
ss << "vertices=[";
|
||||
|
||||
// For each triangle of the concave mesh
|
||||
for (uint v=0; v<triangleVertexArray->getNbVertices(); v++) {
|
||||
|
||||
Vector3 vertex;
|
||||
triangleVertexArray->getVertex(v, &vertex);
|
||||
|
||||
ss << vertex.to_string() << ", ";
|
||||
}
|
||||
|
||||
ss << "], " << std::endl;
|
||||
|
||||
ss << "normals=[";
|
||||
|
||||
// For each triangle of the concave mesh
|
||||
for (uint v=0; v<triangleVertexArray->getNbVertices(); v++) {
|
||||
|
||||
Vector3 normal;
|
||||
triangleVertexArray->getNormal(v, &normal);
|
||||
|
||||
ss << normal.to_string() << ", ";
|
||||
}
|
||||
|
||||
ss << "], " << std::endl;
|
||||
|
||||
ss << "triangles=[";
|
||||
|
||||
// For each triangle of the concave mesh
|
||||
// For each triangle of the concave mesh
|
||||
for (uint triangleIndex=0; triangleIndex<triangleVertexArray->getNbTriangles(); triangleIndex++) {
|
||||
|
||||
uint indices[3];
|
||||
|
||||
triangleVertexArray->getTriangleVerticesIndices(triangleIndex, indices);
|
||||
|
||||
ss << "(" << indices[0] << "," << indices[1] << "," << indices[2] << "), ";
|
||||
}
|
||||
|
||||
ss << "], " << std::endl;
|
||||
|
||||
ss << "}" << std::endl;
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "collision/TriangleMesh.h"
|
||||
#include "collision/shapes/TriangleShape.h"
|
||||
#include "containers/List.h"
|
||||
#include "engine/Profiler.h"
|
||||
#include "utils/Profiler.h"
|
||||
|
||||
namespace reactphysics3d {
|
||||
|
||||
|
@ -140,6 +140,9 @@ class ConcaveMeshShape : public ConcaveShape {
|
|||
/// if the user did not provide its own vertices normals)
|
||||
Vector3** mComputedVerticesNormals;
|
||||
|
||||
/// Scaling
|
||||
const Vector3 mScaling;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Raycast method with feedback information
|
||||
|
@ -163,7 +166,7 @@ class ConcaveMeshShape : public ConcaveShape {
|
|||
public:
|
||||
|
||||
/// Constructor
|
||||
ConcaveMeshShape(TriangleMesh* triangleMesh);
|
||||
ConcaveMeshShape(TriangleMesh* triangleMesh, const Vector3& scaling = Vector3(1, 1, 1));
|
||||
|
||||
/// Destructor
|
||||
virtual ~ConcaveMeshShape() = default;
|
||||
|
@ -174,18 +177,21 @@ class ConcaveMeshShape : public ConcaveShape {
|
|||
/// Deleted assignment operator
|
||||
ConcaveMeshShape& operator=(const ConcaveMeshShape& shape) = delete;
|
||||
|
||||
/// Return the scaling vector
|
||||
const Vector3& getScaling() const;
|
||||
|
||||
/// Return the local bounds of the shape in x, y and z directions.
|
||||
virtual void getLocalBounds(Vector3& min, Vector3& max) const override;
|
||||
|
||||
/// Set the local scaling vector of the collision shape
|
||||
virtual void setLocalScaling(const Vector3& scaling) override;
|
||||
|
||||
/// Return the local inertia tensor of the collision shape
|
||||
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const override;
|
||||
|
||||
/// Use a callback method on all triangles of the concave shape inside a given AABB
|
||||
virtual void testAllTriangles(TriangleCallback& callback, const AABB& localAABB) const override;
|
||||
|
||||
/// Return the string representation of the shape
|
||||
virtual std::string to_string() const override;
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
/// Set the profiler
|
||||
|
@ -204,6 +210,11 @@ inline size_t ConcaveMeshShape::getSizeInBytes() const {
|
|||
return sizeof(ConcaveMeshShape);
|
||||
}
|
||||
|
||||
// Return the scaling vector
|
||||
inline const Vector3& ConcaveMeshShape::getScaling() const {
|
||||
return mScaling;
|
||||
}
|
||||
|
||||
// Return the local bounds of the shape in x, y and z directions.
|
||||
// This method is used to compute the AABB of the box
|
||||
/**
|
||||
|
@ -219,18 +230,6 @@ inline void ConcaveMeshShape::getLocalBounds(Vector3& min, Vector3& max) const {
|
|||
max = treeAABB.getMax();
|
||||
}
|
||||
|
||||
// Set the local scaling vector of the collision shape
|
||||
inline void ConcaveMeshShape::setLocalScaling(const Vector3& scaling) {
|
||||
|
||||
CollisionShape::setLocalScaling(scaling);
|
||||
|
||||
// Reset the Dynamic AABB Tree
|
||||
mDynamicAABBTree.reset();
|
||||
|
||||
// Rebuild Dynamic AABB Tree here
|
||||
initBVHTree();
|
||||
}
|
||||
|
||||
// Return the local inertia tensor of the shape
|
||||
/**
|
||||
* @param[out] tensor The 3x3 inertia tensor matrix of the shape in local-space
|
||||
|
@ -277,6 +276,7 @@ inline void ConcaveMeshShape::setProfiler(Profiler* profiler) {
|
|||
mDynamicAABBTree.setProfiler(profiler);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
@ -38,8 +38,9 @@ using namespace reactphysics3d;
|
|||
* @param stride Stride between the beginning of two elements in the vertices array
|
||||
* @param margin Collision margin (in meters) around the collision shape
|
||||
*/
|
||||
ConvexMeshShape::ConvexMeshShape(PolyhedronMesh* polyhedronMesh)
|
||||
: ConvexPolyhedronShape(CollisionShapeName::CONVEX_MESH), mPolyhedronMesh(polyhedronMesh), mMinBounds(0, 0, 0), mMaxBounds(0, 0, 0) {
|
||||
ConvexMeshShape::ConvexMeshShape(PolyhedronMesh* polyhedronMesh, const Vector3& scaling)
|
||||
: ConvexPolyhedronShape(CollisionShapeName::CONVEX_MESH), mPolyhedronMesh(polyhedronMesh),
|
||||
mMinBounds(0, 0, 0), mMaxBounds(0, 0, 0), mScaling(scaling) {
|
||||
|
||||
// Recalculate the bounds of the mesh
|
||||
recalculateBounds();
|
||||
|
@ -201,3 +202,47 @@ bool ConvexMeshShape::testPointInside(const Vector3& localPoint, ProxyShape* pro
|
|||
return true;
|
||||
}
|
||||
|
||||
// Return the string representation of the shape
|
||||
std::string ConvexMeshShape::to_string() const {
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "ConvexMeshShape{" << std::endl;
|
||||
ss << "nbVertices=" << mPolyhedronMesh->getNbVertices() << std::endl;
|
||||
ss << "nbFaces=" << mPolyhedronMesh->getNbFaces() << std::endl;
|
||||
|
||||
ss << "vertices=[";
|
||||
|
||||
for (uint v=0; v < mPolyhedronMesh->getNbVertices(); v++) {
|
||||
|
||||
Vector3 vertex = mPolyhedronMesh->getVertex(v);
|
||||
ss << vertex.to_string();
|
||||
if (v != mPolyhedronMesh->getNbVertices() - 1) {
|
||||
ss << ", ";
|
||||
}
|
||||
}
|
||||
|
||||
ss << "], faces=[";
|
||||
|
||||
HalfEdgeStructure halfEdgeStruct = mPolyhedronMesh->getHalfEdgeStructure();
|
||||
for (uint f=0; f < mPolyhedronMesh->getNbFaces(); f++) {
|
||||
|
||||
const HalfEdgeStructure::Face& face = halfEdgeStruct.getFace(f);
|
||||
|
||||
ss << "[";
|
||||
|
||||
for (uint v=0; v < face.faceVertices.size(); v++) {
|
||||
|
||||
ss << face.faceVertices[v];
|
||||
if (v != face.faceVertices.size() - 1) {
|
||||
ss << ",";
|
||||
}
|
||||
}
|
||||
|
||||
ss << "]";
|
||||
}
|
||||
|
||||
ss << "]}";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include "ConvexPolyhedronShape.h"
|
||||
#include "engine/CollisionWorld.h"
|
||||
#include "mathematics/mathematics.h"
|
||||
#include "collision/TriangleMesh.h"
|
||||
|
||||
#include "collision/PolyhedronMesh.h"
|
||||
#include "collision/narrowphase/GJK/GJKAlgorithm.h"
|
||||
|
||||
|
@ -62,6 +62,9 @@ class ConvexMeshShape : public ConvexPolyhedronShape {
|
|||
/// Mesh maximum bounds in the three local x, y and z directions
|
||||
Vector3 mMaxBounds;
|
||||
|
||||
/// Local scaling
|
||||
const Vector3 mScaling;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Recompute the bounds of the mesh
|
||||
|
@ -84,7 +87,7 @@ class ConvexMeshShape : public ConvexPolyhedronShape {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
ConvexMeshShape(PolyhedronMesh* polyhedronMesh);
|
||||
ConvexMeshShape(PolyhedronMesh* polyhedronMesh, const Vector3& scaling = Vector3(1,1,1));
|
||||
|
||||
/// Destructor
|
||||
virtual ~ConvexMeshShape() override = default;
|
||||
|
@ -95,8 +98,8 @@ class ConvexMeshShape : public ConvexPolyhedronShape {
|
|||
/// Deleted assignment operator
|
||||
ConvexMeshShape& operator=(const ConvexMeshShape& shape) = delete;
|
||||
|
||||
/// Set the scaling vector of the collision shape
|
||||
virtual void setLocalScaling(const Vector3& scaling) override;
|
||||
/// Return the scaling vector
|
||||
const Vector3& getScaling() const;
|
||||
|
||||
/// Return the local bounds of the shape in x, y and z directions
|
||||
virtual void getLocalBounds(Vector3& min, Vector3& max) const override;
|
||||
|
@ -130,19 +133,21 @@ class ConvexMeshShape : public ConvexPolyhedronShape {
|
|||
|
||||
/// Return the centroid of the polyhedron
|
||||
virtual Vector3 getCentroid() const override;
|
||||
};
|
||||
|
||||
/// Set the scaling vector of the collision shape
|
||||
inline void ConvexMeshShape::setLocalScaling(const Vector3& scaling) {
|
||||
ConvexShape::setLocalScaling(scaling);
|
||||
recalculateBounds();
|
||||
}
|
||||
/// Return the string representation of the shape
|
||||
virtual std::string to_string() const override;
|
||||
};
|
||||
|
||||
// Return the number of bytes used by the collision shape
|
||||
inline size_t ConvexMeshShape::getSizeInBytes() const {
|
||||
return sizeof(ConvexMeshShape);
|
||||
}
|
||||
|
||||
// Return the scaling vector
|
||||
inline const Vector3& ConvexMeshShape::getScaling() const {
|
||||
return mScaling;
|
||||
}
|
||||
|
||||
// Return the local bounds of the shape in x, y and z directions
|
||||
/**
|
||||
* @param min The minimum bounds of the shape in local-space coordinates
|
||||
|
|
|
@ -41,11 +41,11 @@ using namespace reactphysics3d;
|
|||
*/
|
||||
HeightFieldShape::HeightFieldShape(int nbGridColumns, int nbGridRows, decimal minHeight, decimal maxHeight,
|
||||
const void* heightFieldData, HeightDataType dataType, int upAxis,
|
||||
decimal integerHeightScale)
|
||||
decimal integerHeightScale, const Vector3& scaling)
|
||||
: ConcaveShape(CollisionShapeName::HEIGHTFIELD), mNbColumns(nbGridColumns), mNbRows(nbGridRows),
|
||||
mWidth(nbGridColumns - 1), mLength(nbGridRows - 1), mMinHeight(minHeight),
|
||||
mMaxHeight(maxHeight), mUpAxis(upAxis), mIntegerHeightScale(integerHeightScale),
|
||||
mHeightDataType(dataType) {
|
||||
mHeightDataType(dataType), mScaling(scaling) {
|
||||
|
||||
assert(nbGridColumns >= 2);
|
||||
assert(nbGridRows >= 2);
|
||||
|
@ -217,7 +217,7 @@ bool HeightFieldShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxySh
|
|||
// TODO : Implement raycasting without using an AABB for the ray
|
||||
// but using a dynamic AABB tree or octree instead
|
||||
|
||||
PROFILE("HeightFieldShape::raycast()", mProfiler);
|
||||
RP3D_PROFILE("HeightFieldShape::raycast()", mProfiler);
|
||||
|
||||
TriangleOverlapCallback triangleCallback(ray, proxyShape, raycastInfo, *this, allocator);
|
||||
|
||||
|
@ -297,3 +297,23 @@ void TriangleOverlapCallback::testTriangle(const Vector3* trianglePoints, const
|
|||
mIsHit = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the string representation of the shape
|
||||
std::string HeightFieldShape::to_string() const {
|
||||
|
||||
std::stringstream ss;
|
||||
|
||||
ss << "HeightFieldShape{" << std::endl;
|
||||
|
||||
ss << "nbColumns=" << mNbColumns << std::endl;
|
||||
ss << ", nbRows=" << mNbRows << std::endl;
|
||||
ss << ", width=" << mWidth << std::endl;
|
||||
ss << ", length=" << mLength << std::endl;
|
||||
ss << ", minHeight=" << mMinHeight << std::endl;
|
||||
ss << ", maxHeight=" << mMaxHeight << std::endl;
|
||||
ss << ", upAxis=" << mUpAxis << std::endl;
|
||||
ss << ", integerHeightScale=" << mIntegerHeightScale << std::endl;
|
||||
ss << "}";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
// Libraries
|
||||
#include "ConcaveShape.h"
|
||||
#include "collision/shapes/TriangleShape.h"
|
||||
#include "engine/Profiler.h"
|
||||
#include "utils/Profiler.h"
|
||||
|
||||
namespace reactphysics3d {
|
||||
|
||||
|
@ -141,6 +141,9 @@ class HeightFieldShape : public ConcaveShape {
|
|||
/// Local AABB of the height field (without scaling)
|
||||
AABB mAABB;
|
||||
|
||||
/// Scaling vector
|
||||
const Vector3 mScaling;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Raycast method with feedback information
|
||||
|
@ -177,7 +180,8 @@ class HeightFieldShape : public ConcaveShape {
|
|||
/// Constructor
|
||||
HeightFieldShape(int nbGridColumns, int nbGridRows, decimal minHeight, decimal maxHeight,
|
||||
const void* heightFieldData, HeightDataType dataType,
|
||||
int upAxis = 1, decimal integerHeightScale = 1.0f);
|
||||
int upAxis = 1, decimal integerHeightScale = 1.0f,
|
||||
const Vector3& scaling = Vector3(1,1,1));
|
||||
|
||||
/// Destructor
|
||||
virtual ~HeightFieldShape() override = default;
|
||||
|
@ -188,6 +192,9 @@ class HeightFieldShape : public ConcaveShape {
|
|||
/// Deleted assignment operator
|
||||
HeightFieldShape& operator=(const HeightFieldShape& shape) = delete;
|
||||
|
||||
/// Return the scaling factor
|
||||
const Vector3& getScaling() const;
|
||||
|
||||
/// Return the number of rows in the height field
|
||||
int getNbRows() const;
|
||||
|
||||
|
@ -200,21 +207,26 @@ class HeightFieldShape : public ConcaveShape {
|
|||
/// Return the local bounds of the shape in x, y and z directions.
|
||||
virtual void getLocalBounds(Vector3& min, Vector3& max) const override;
|
||||
|
||||
/// Set the local scaling vector of the collision shape
|
||||
virtual void setLocalScaling(const Vector3& scaling) override;
|
||||
|
||||
/// Return the local inertia tensor of the collision shape
|
||||
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const override;
|
||||
|
||||
/// Use a callback method on all triangles of the concave shape inside a given AABB
|
||||
virtual void testAllTriangles(TriangleCallback& callback, const AABB& localAABB) const override;
|
||||
|
||||
/// Return the string representation of the shape
|
||||
virtual std::string to_string() const override;
|
||||
|
||||
// ---------- Friendship ----------- //
|
||||
|
||||
friend class ConvexTriangleAABBOverlapCallback;
|
||||
friend class ConcaveMeshRaycastCallback;
|
||||
};
|
||||
|
||||
// Return the scaling factor
|
||||
inline const Vector3& HeightFieldShape::getScaling() const {
|
||||
return mScaling;
|
||||
}
|
||||
|
||||
// Return the number of rows in the height field
|
||||
inline int HeightFieldShape::getNbRows() const {
|
||||
return mNbRows;
|
||||
|
@ -235,11 +247,6 @@ inline size_t HeightFieldShape::getSizeInBytes() const {
|
|||
return sizeof(HeightFieldShape);
|
||||
}
|
||||
|
||||
// Set the local scaling vector of the collision shape
|
||||
inline void HeightFieldShape::setLocalScaling(const Vector3& scaling) {
|
||||
CollisionShape::setLocalScaling(scaling);
|
||||
}
|
||||
|
||||
// Return the height of a given (x,y) point in the height field
|
||||
inline decimal HeightFieldShape::getHeightAt(int x, int y) const {
|
||||
|
||||
|
|
|
@ -82,9 +82,6 @@ class SphereShape : public ConvexShape {
|
|||
/// Return true if the collision shape is a polyhedron
|
||||
virtual bool isPolyhedron() const override;
|
||||
|
||||
/// Set the scaling vector of the collision shape
|
||||
virtual void setLocalScaling(const Vector3& scaling) override;
|
||||
|
||||
/// Return the local bounds of the shape in x, y and z directions.
|
||||
virtual void getLocalBounds(Vector3& min, Vector3& max) const override;
|
||||
|
||||
|
@ -93,6 +90,9 @@ class SphereShape : public ConvexShape {
|
|||
|
||||
/// Update the AABB of a body using its collision shape
|
||||
virtual void computeAABB(AABB& aabb, const Transform& transform) const override;
|
||||
|
||||
/// Return the string representation of the shape
|
||||
virtual std::string to_string() const override;
|
||||
};
|
||||
|
||||
// Get the radius of the sphere
|
||||
|
@ -108,14 +108,6 @@ inline bool SphereShape::isPolyhedron() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Set the scaling vector of the collision shape
|
||||
inline void SphereShape::setLocalScaling(const Vector3& scaling) {
|
||||
|
||||
mMargin = (mMargin / mScaling.x) * scaling.x;
|
||||
|
||||
CollisionShape::setLocalScaling(scaling);
|
||||
}
|
||||
|
||||
// Return the number of bytes used by the collision shape
|
||||
inline size_t SphereShape::getSizeInBytes() const {
|
||||
return sizeof(SphereShape);
|
||||
|
@ -181,6 +173,11 @@ inline bool SphereShape::testPointInside(const Vector3& localPoint, ProxyShape*
|
|||
return (localPoint.lengthSquare() < mMargin * mMargin);
|
||||
}
|
||||
|
||||
// Return the string representation of the shape
|
||||
inline std::string SphereShape::to_string() const {
|
||||
return "SphereShape{radius=" + std::to_string(getRadius()) + "}";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "TriangleShape.h"
|
||||
#include "collision/ProxyShape.h"
|
||||
#include "mathematics/mathematics_functions.h"
|
||||
#include "engine/Profiler.h"
|
||||
#include "utils/Profiler.h"
|
||||
#include "configuration.h"
|
||||
#include <cassert>
|
||||
|
||||
|
@ -213,7 +213,7 @@ Vector3 TriangleShape::computeSmoothLocalContactNormalForTriangle(const Vector3&
|
|||
/// Real-time Collision Detection by Christer Ericson.
|
||||
bool TriangleShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, MemoryAllocator& allocator) const {
|
||||
|
||||
PROFILE("TriangleShape::raycast()", mProfiler);
|
||||
RP3D_PROFILE("TriangleShape::raycast()", mProfiler);
|
||||
|
||||
const Vector3 pq = ray.point2 - ray.point1;
|
||||
const Vector3 pa = mPoints[0] - ray.point1;
|
||||
|
|
|
@ -127,9 +127,6 @@ class TriangleShape : public ConvexPolyhedronShape {
|
|||
/// Return the local bounds of the shape in x, y and z directions.
|
||||
virtual void getLocalBounds(Vector3& min, Vector3& max) const override;
|
||||
|
||||
/// Set the local scaling vector of the collision shape
|
||||
virtual void setLocalScaling(const Vector3& scaling) override;
|
||||
|
||||
/// Return the local inertia tensor of the collision shape
|
||||
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const override;
|
||||
|
||||
|
@ -175,6 +172,9 @@ class TriangleShape : public ConvexPolyhedronShape {
|
|||
const Transform& shape1ToWorld, const Transform& shape2ToWorld,
|
||||
decimal penetrationDepth, Vector3& outSmoothVertexNormal);
|
||||
|
||||
/// Return the string representation of the shape
|
||||
virtual std::string to_string() const override;
|
||||
|
||||
// ---------- Friendship ---------- //
|
||||
|
||||
friend class ConcaveMeshRaycastCallback;
|
||||
|
@ -211,16 +211,6 @@ inline void TriangleShape::getLocalBounds(Vector3& min, Vector3& max) const {
|
|||
max += Vector3(mMargin, mMargin, mMargin);
|
||||
}
|
||||
|
||||
// Set the local scaling vector of the collision shape
|
||||
inline void TriangleShape::setLocalScaling(const Vector3& scaling) {
|
||||
|
||||
mPoints[0] = (mPoints[0] / mScaling) * scaling;
|
||||
mPoints[1] = (mPoints[1] / mScaling) * scaling;
|
||||
mPoints[2] = (mPoints[2] / mScaling) * scaling;
|
||||
|
||||
CollisionShape::setLocalScaling(scaling);
|
||||
}
|
||||
|
||||
// Return the local inertia tensor of the triangle shape
|
||||
/**
|
||||
* @param[out] tensor The 3x3 inertia tensor matrix of the shape in local-space
|
||||
|
@ -325,6 +315,12 @@ inline void TriangleShape::setRaycastTestType(TriangleRaycastSide testType) {
|
|||
mRaycastTestType = testType;
|
||||
}
|
||||
|
||||
// Return the string representation of the shape
|
||||
inline std::string TriangleShape::to_string() const {
|
||||
return "TriangleShape{v1=" + mPoints[0].to_string() + ", v2=" + mPoints[1].to_string() + "," +
|
||||
"v3=" + mPoints[2].to_string() + "}";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include <cfloat>
|
||||
#include <utility>
|
||||
#include <cstdint>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include "decimal.h"
|
||||
#include "containers/Pair.h"
|
||||
|
||||
|
@ -104,12 +106,18 @@ constexpr decimal DYNAMIC_TREE_AABB_GAP = decimal(0.1);
|
|||
/// followin constant with the linear velocity and the elapsed time between two frames.
|
||||
constexpr decimal DYNAMIC_TREE_AABB_LIN_GAP_MULTIPLIER = decimal(1.7);
|
||||
|
||||
/// Current version of ReactPhysics3D
|
||||
const std::string RP3D_VERSION = std::string("0.7.0");
|
||||
|
||||
/// Structure WorldSettings
|
||||
/**
|
||||
* This class is used to describe some settings of a physics world.
|
||||
*/
|
||||
struct WorldSettings {
|
||||
|
||||
/// Name of the world
|
||||
std::string worldName = "";
|
||||
|
||||
/// Distance threshold for two contact points for a valid persistent contact (in meters)
|
||||
decimal persistentContactDistanceThreshold = decimal(0.03);
|
||||
|
||||
|
@ -157,6 +165,30 @@ struct WorldSettings {
|
|||
/// merge them. If the cosine of the angle between the normals of the two manifold are larger
|
||||
/// than the value bellow, the manifold are considered to be similar.
|
||||
decimal cosAngleSimilarContactManifold = decimal(0.95);
|
||||
|
||||
/// Return a string with the world settings
|
||||
std::string to_string() const {
|
||||
|
||||
std::stringstream ss;
|
||||
|
||||
ss << "worldName=" << worldName << std::endl;
|
||||
ss << "persistentContactDistanceThreshold=" << persistentContactDistanceThreshold << std::endl;
|
||||
ss << "defaultFrictionCoefficient=" << defaultFrictionCoefficient << std::endl;
|
||||
ss << "defaultBounciness=" << defaultBounciness << std::endl;
|
||||
ss << "restitutionVelocityThreshold=" << restitutionVelocityThreshold << std::endl;
|
||||
ss << "defaultRollingRestistance=" << defaultRollingRestistance << std::endl;
|
||||
ss << "isSleepingEnabled=" << isSleepingEnabled << std::endl;
|
||||
ss << "defaultVelocitySolverNbIterations=" << defaultVelocitySolverNbIterations << std::endl;
|
||||
ss << "defaultPositionSolverNbIterations=" << defaultPositionSolverNbIterations << std::endl;
|
||||
ss << "defaultTimeBeforeSleep=" << defaultTimeBeforeSleep << std::endl;
|
||||
ss << "defaultSleepLinearVelocity=" << defaultSleepLinearVelocity << std::endl;
|
||||
ss << "defaultSleepAngularVelocity=" << defaultSleepAngularVelocity << std::endl;
|
||||
ss << "nbMaxContactManifoldsConvexShape=" << nbMaxContactManifoldsConvexShape << std::endl;
|
||||
ss << "nbMaxContactManifoldsConcaveShape=" << nbMaxContactManifoldsConcaveShape << std::endl;
|
||||
ss << "cosAngleSimilarContactManifold=" << cosAngleSimilarContactManifold << std::endl;
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -33,8 +33,8 @@ using namespace reactphysics3d;
|
|||
const decimal BallAndSocketJoint::BETA = decimal(0.2);
|
||||
|
||||
// Constructor
|
||||
BallAndSocketJoint::BallAndSocketJoint(const BallAndSocketJointInfo& jointInfo)
|
||||
: Joint(jointInfo), mImpulse(Vector3(0, 0, 0)) {
|
||||
BallAndSocketJoint::BallAndSocketJoint(uint id, const BallAndSocketJointInfo& jointInfo)
|
||||
: Joint(id, jointInfo), mImpulse(Vector3(0, 0, 0)) {
|
||||
|
||||
// Compute the local-space anchor point for each body
|
||||
mLocalAnchorPointBody1 = mBody1->getTransform().getInverse() * jointInfo.anchorPointWorldSpace;
|
||||
|
|
|
@ -125,7 +125,7 @@ class BallAndSocketJoint : public Joint {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
BallAndSocketJoint(const BallAndSocketJointInfo& jointInfo);
|
||||
BallAndSocketJoint(uint id, const BallAndSocketJointInfo& jointInfo);
|
||||
|
||||
/// Destructor
|
||||
virtual ~BallAndSocketJoint() override = default;
|
||||
|
@ -133,6 +133,9 @@ class BallAndSocketJoint : public Joint {
|
|||
/// Deleted copy-constructor
|
||||
BallAndSocketJoint(const BallAndSocketJoint& constraint) = delete;
|
||||
|
||||
/// Return a string representation
|
||||
virtual std::string to_string() const override;
|
||||
|
||||
/// Deleted assignment operator
|
||||
BallAndSocketJoint& operator=(const BallAndSocketJoint& constraint) = delete;
|
||||
};
|
||||
|
@ -142,6 +145,12 @@ inline size_t BallAndSocketJoint::getSizeInBytes() const {
|
|||
return sizeof(BallAndSocketJoint);
|
||||
}
|
||||
|
||||
// Return a string representation
|
||||
inline std::string BallAndSocketJoint::to_string() const {
|
||||
return "BallAndSocketJoint{ localAnchorPointBody1=" + mLocalAnchorPointBody1.to_string() +
|
||||
", localAnchorPointBody2=" + mLocalAnchorPointBody2.to_string() + "}";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -33,8 +33,8 @@ using namespace reactphysics3d;
|
|||
const decimal FixedJoint::BETA = decimal(0.2);
|
||||
|
||||
// Constructor
|
||||
FixedJoint::FixedJoint(const FixedJointInfo& jointInfo)
|
||||
: Joint(jointInfo), mImpulseTranslation(0, 0, 0), mImpulseRotation(0, 0, 0) {
|
||||
FixedJoint::FixedJoint(uint id, const FixedJointInfo& jointInfo)
|
||||
: Joint(id, jointInfo), mImpulseTranslation(0, 0, 0), mImpulseRotation(0, 0, 0) {
|
||||
|
||||
// Compute the local-space anchor point for each body
|
||||
const Transform& transform1 = mBody1->getTransform();
|
||||
|
|
|
@ -136,7 +136,7 @@ class FixedJoint : public Joint {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
FixedJoint(const FixedJointInfo& jointInfo);
|
||||
FixedJoint(uint id, const FixedJointInfo& jointInfo);
|
||||
|
||||
/// Destructor
|
||||
virtual ~FixedJoint() override = default;
|
||||
|
@ -144,6 +144,9 @@ class FixedJoint : public Joint {
|
|||
/// Deleted copy-constructor
|
||||
FixedJoint(const FixedJoint& constraint) = delete;
|
||||
|
||||
/// Return a string representation
|
||||
virtual std::string to_string() const override;
|
||||
|
||||
/// Deleted assignment operator
|
||||
FixedJoint& operator=(const FixedJoint& constraint) = delete;
|
||||
};
|
||||
|
@ -153,6 +156,14 @@ inline size_t FixedJoint::getSizeInBytes() const {
|
|||
return sizeof(FixedJoint);
|
||||
}
|
||||
|
||||
// Return a string representation
|
||||
inline std::string FixedJoint::to_string() const {
|
||||
return "FixedJoint{ localAnchorPointBody1=" + mLocalAnchorPointBody1.to_string() +
|
||||
", localAnchorPointBody2=" + mLocalAnchorPointBody2.to_string() +
|
||||
", initOrientationDifferenceInv=" + mInitOrientationDifferenceInv.to_string() +
|
||||
"}";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -34,16 +34,16 @@ using namespace reactphysics3d;
|
|||
const decimal HingeJoint::BETA = decimal(0.2);
|
||||
|
||||
// Constructor
|
||||
HingeJoint::HingeJoint(const HingeJointInfo& jointInfo)
|
||||
: Joint(jointInfo), mImpulseTranslation(0, 0, 0), mImpulseRotation(0, 0),
|
||||
HingeJoint::HingeJoint(uint id, const HingeJointInfo& jointInfo)
|
||||
: Joint(id, jointInfo), mImpulseTranslation(0, 0, 0), mImpulseRotation(0, 0),
|
||||
mImpulseLowerLimit(0), mImpulseUpperLimit(0), mImpulseMotor(0),
|
||||
mIsLimitEnabled(jointInfo.isLimitEnabled), mIsMotorEnabled(jointInfo.isMotorEnabled),
|
||||
mLowerLimit(jointInfo.minAngleLimit), mUpperLimit(jointInfo.maxAngleLimit),
|
||||
mIsLowerLimitViolated(false), mIsUpperLimitViolated(false),
|
||||
mMotorSpeed(jointInfo.motorSpeed), mMaxMotorTorque(jointInfo.maxMotorTorque) {
|
||||
|
||||
assert(mLowerLimit <= 0 && mLowerLimit >= -2.0 * PI);
|
||||
assert(mUpperLimit >= 0 && mUpperLimit <= 2.0 * PI);
|
||||
assert(mLowerLimit <= decimal(0) && mLowerLimit >= decimal(-2.0) * PI);
|
||||
assert(mUpperLimit >= decimal(0) && mUpperLimit <= decimal(2.0) * PI);
|
||||
|
||||
// Compute the local-space anchor point for each body
|
||||
Transform transform1 = mBody1->getTransform();
|
||||
|
|
|
@ -287,7 +287,7 @@ class HingeJoint : public Joint {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
HingeJoint(const HingeJointInfo& jointInfo);
|
||||
HingeJoint(uint id, const HingeJointInfo& jointInfo);
|
||||
|
||||
/// Destructor
|
||||
virtual ~HingeJoint() override = default;
|
||||
|
@ -336,6 +336,9 @@ class HingeJoint : public Joint {
|
|||
|
||||
/// Return the intensity of the current torque applied for the joint motor
|
||||
decimal getMotorTorque(decimal timeStep) const;
|
||||
|
||||
/// Return a string representation
|
||||
virtual std::string to_string() const override;
|
||||
};
|
||||
|
||||
// Return true if the limits of the joint are enabled
|
||||
|
@ -400,6 +403,17 @@ inline size_t HingeJoint::getSizeInBytes() const {
|
|||
return sizeof(HingeJoint);
|
||||
}
|
||||
|
||||
// Return a string representation
|
||||
inline std::string HingeJoint::to_string() const {
|
||||
return "HingeJoint{ lowerLimit=" + std::to_string(mLowerLimit) + ", upperLimit=" + std::to_string(mUpperLimit) +
|
||||
"localAnchorPointBody1=" + mLocalAnchorPointBody1.to_string() + ", localAnchorPointBody2=" +
|
||||
mLocalAnchorPointBody2.to_string() + ", hingeLocalAxisBody1=" + mHingeLocalAxisBody1.to_string() +
|
||||
", hingeLocalAxisBody2=" + mHingeLocalAxisBody2.to_string() + ", initOrientationDifferenceInv=" +
|
||||
mInitOrientationDifferenceInv.to_string() + ", motorSpeed=" + std::to_string(mMotorSpeed) +
|
||||
", maxMotorTorque=" + std::to_string(mMaxMotorTorque) + ", isLimitEnabled=" +
|
||||
(mIsLimitEnabled ? "true" : "false") + ", isMotorEnabled=" + (mIsMotorEnabled ? "true" : "false") + "}";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
using namespace reactphysics3d;
|
||||
|
||||
// Constructor
|
||||
Joint::Joint(const JointInfo& jointInfo)
|
||||
:mBody1(jointInfo.body1), mBody2(jointInfo.body2), mType(jointInfo.type),
|
||||
Joint::Joint(uint id, const JointInfo& jointInfo)
|
||||
:mId(id), mBody1(jointInfo.body1), mBody2(jointInfo.body2), mType(jointInfo.type),
|
||||
mPositionCorrectionTechnique(jointInfo.positionCorrectionTechnique),
|
||||
mIsCollisionEnabled(jointInfo.isCollisionEnabled), mIsAlreadyInIsland(false) {
|
||||
|
||||
|
|
|
@ -120,6 +120,9 @@ class Joint {
|
|||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Id of the joint
|
||||
uint mId;
|
||||
|
||||
/// Pointer to the first body of the joint
|
||||
RigidBody* const mBody1;
|
||||
|
||||
|
@ -144,6 +147,9 @@ class Joint {
|
|||
/// True if the joint has already been added into an island
|
||||
bool mIsAlreadyInIsland;
|
||||
|
||||
/// Total number of joints
|
||||
static uint mNbTotalNbJoints;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Return true if the joint has already been added into an island
|
||||
|
@ -169,7 +175,7 @@ class Joint {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
Joint(const JointInfo& jointInfo);
|
||||
Joint(uint id, const JointInfo& jointInfo);
|
||||
|
||||
/// Destructor
|
||||
virtual ~Joint() = default;
|
||||
|
@ -195,6 +201,12 @@ class Joint {
|
|||
/// Return true if the collision between the two bodies of the joint is enabled
|
||||
bool isCollisionEnabled() const;
|
||||
|
||||
/// Return the id of the joint
|
||||
uint getId() const;
|
||||
|
||||
/// Return a string representation
|
||||
virtual std::string to_string() const=0;
|
||||
|
||||
// -------------------- Friendship -------------------- //
|
||||
|
||||
friend class DynamicsWorld;
|
||||
|
@ -243,6 +255,14 @@ inline bool Joint::isCollisionEnabled() const {
|
|||
return mIsCollisionEnabled;
|
||||
}
|
||||
|
||||
// Return the id of the joint
|
||||
/**
|
||||
* @return The id of the joint
|
||||
*/
|
||||
inline uint Joint::getId() const {
|
||||
return mId;
|
||||
}
|
||||
|
||||
// Return true if the joint has already been added into an island
|
||||
inline bool Joint::isAlreadyInIsland() const {
|
||||
return mIsAlreadyInIsland;
|
||||
|
|
|
@ -32,8 +32,8 @@ using namespace reactphysics3d;
|
|||
const decimal SliderJoint::BETA = decimal(0.2);
|
||||
|
||||
// Constructor
|
||||
SliderJoint::SliderJoint(const SliderJointInfo& jointInfo)
|
||||
: Joint(jointInfo), mImpulseTranslation(0, 0), mImpulseRotation(0, 0, 0),
|
||||
SliderJoint::SliderJoint(uint id, const SliderJointInfo& jointInfo)
|
||||
: Joint(id, jointInfo), mImpulseTranslation(0, 0), mImpulseRotation(0, 0, 0),
|
||||
mImpulseLowerLimit(0), mImpulseUpperLimit(0), mImpulseMotor(0),
|
||||
mIsLimitEnabled(jointInfo.isLimitEnabled), mIsMotorEnabled(jointInfo.isMotorEnabled),
|
||||
mLowerLimit(jointInfo.minTranslationLimit),
|
||||
|
@ -41,9 +41,9 @@ SliderJoint::SliderJoint(const SliderJointInfo& jointInfo)
|
|||
mIsUpperLimitViolated(false), mMotorSpeed(jointInfo.motorSpeed),
|
||||
mMaxMotorForce(jointInfo.maxMotorForce){
|
||||
|
||||
assert(mUpperLimit >= 0.0);
|
||||
assert(mLowerLimit <= 0.0);
|
||||
assert(mMaxMotorForce >= 0.0);
|
||||
assert(mUpperLimit >= decimal(0.0));
|
||||
assert(mLowerLimit <= decimal(0.0));
|
||||
assert(mMaxMotorForce >= decimal(0.0));
|
||||
|
||||
// Compute the local-space anchor point for each body
|
||||
const Transform& transform1 = mBody1->getTransform();
|
||||
|
|
|
@ -285,7 +285,7 @@ class SliderJoint : public Joint {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
SliderJoint(const SliderJointInfo& jointInfo);
|
||||
SliderJoint(uint id, const SliderJointInfo& jointInfo);
|
||||
|
||||
/// Destructor
|
||||
virtual ~SliderJoint() override = default;
|
||||
|
@ -337,6 +337,9 @@ class SliderJoint : public Joint {
|
|||
|
||||
/// Return the intensity of the current force applied for the joint motor
|
||||
decimal getMotorForce(decimal timeStep) const;
|
||||
|
||||
/// Return a string representation
|
||||
virtual std::string to_string() const override;
|
||||
};
|
||||
|
||||
// Return true if the limits or the joint are enabled
|
||||
|
@ -401,6 +404,17 @@ inline size_t SliderJoint::getSizeInBytes() const {
|
|||
return sizeof(SliderJoint);
|
||||
}
|
||||
|
||||
// Return a string representation
|
||||
inline std::string SliderJoint::to_string() const {
|
||||
return "SliderJoint{ lowerLimit=" + std::to_string(mLowerLimit) + ", upperLimit=" + std::to_string(mUpperLimit) +
|
||||
"localAnchorPointBody1=" + mLocalAnchorPointBody1.to_string() + ", localAnchorPointBody2=" +
|
||||
mLocalAnchorPointBody2.to_string() + ", sliderAxisBody1=" + mSliderAxisBody1.to_string() +
|
||||
", initOrientationDifferenceInv=" +
|
||||
mInitOrientationDifferenceInv.to_string() + ", motorSpeed=" + std::to_string(mMotorSpeed) +
|
||||
", maxMotorForce=" + std::to_string(mMaxMotorForce) + ", isLimitEnabled=" +
|
||||
(mIsLimitEnabled ? "true" : "false") + ", isMotorEnabled=" + (mIsMotorEnabled ? "true" : "false") + "}";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
// Libraries
|
||||
#include "configuration.h"
|
||||
#include "memory/MemoryAllocator.h"
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ class Pair {
|
|||
|
||||
}
|
||||
|
||||
// Hash function for struct VerticesPair
|
||||
// Hash function for a reactphysics3d Pair
|
||||
namespace std {
|
||||
|
||||
template <typename T1, typename T2> struct hash<reactphysics3d::Pair<T1, T2>> {
|
||||
|
|
|
@ -26,33 +26,104 @@
|
|||
// Libraries
|
||||
#include "CollisionWorld.h"
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
// Namespaces
|
||||
using namespace reactphysics3d;
|
||||
using namespace std;
|
||||
|
||||
// Initialization of static fields
|
||||
uint CollisionWorld::mNbWorlds = 0;
|
||||
|
||||
// Constructor
|
||||
CollisionWorld::CollisionWorld(const WorldSettings& worldSettings)
|
||||
: mConfig(worldSettings), mCollisionDetection(this, mMemoryManager), mBodies(mMemoryManager.getPoolAllocator()), mCurrentBodyID(0),
|
||||
mFreeBodiesIDs(mMemoryManager.getPoolAllocator()), mEventListener(nullptr) {
|
||||
CollisionWorld::CollisionWorld(const WorldSettings& worldSettings, Logger* logger, Profiler* profiler)
|
||||
: mConfig(worldSettings), mCollisionDetection(this, mMemoryManager), mBodies(mMemoryManager.getPoolAllocator()), mCurrentBodyId(0),
|
||||
mFreeBodiesIds(mMemoryManager.getPoolAllocator()), mEventListener(nullptr), mName(worldSettings.worldName),
|
||||
mProfiler(profiler), mLogger(logger), mIsProfilerCreatedByUser(profiler != nullptr),
|
||||
mIsLoggerCreatedByUser(logger != nullptr) {
|
||||
|
||||
// Automatically generate a name for the world
|
||||
if (mName == "") {
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "world";
|
||||
|
||||
if (mNbWorlds > 0) {
|
||||
ss << mNbWorlds;
|
||||
}
|
||||
|
||||
mName = ss.str();
|
||||
}
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
// If the user has not provided its own profiler, we create one
|
||||
if (mProfiler == nullptr) {
|
||||
|
||||
mProfiler = new Profiler();
|
||||
|
||||
// Add a destination file for the profiling data
|
||||
mProfiler->addFileDestination("rp3d_profiling_" + mName + ".txt", Profiler::Format::Text);
|
||||
}
|
||||
|
||||
|
||||
// Set the profiler
|
||||
mCollisionDetection.setProfiler(&mProfiler);
|
||||
mCollisionDetection.setProfiler(mProfiler);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
|
||||
// If the user has not provided its own logger, we create one
|
||||
if (mLogger == nullptr) {
|
||||
|
||||
mLogger = new Logger();
|
||||
|
||||
// Add a log destination file
|
||||
uint logLevel = static_cast<uint>(Logger::Level::Information) | static_cast<uint>(Logger::Level::Warning) |
|
||||
static_cast<uint>(Logger::Level::Error);
|
||||
mLogger->addFileDestination("rp3d_log_" + mName + ".html", logLevel, Logger::Format::HTML);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
mNbWorlds++;
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
|
||||
"Collision World: Collision world " + mName + " has been created");
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
|
||||
"Collision World: Initial world settings: " + worldSettings.to_string());
|
||||
}
|
||||
|
||||
// Destructor
|
||||
CollisionWorld::~CollisionWorld() {
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
|
||||
"Collision World: Collision world " + mName + " has been destroyed");
|
||||
|
||||
// Destroy all the collision bodies that have not been removed
|
||||
for (int i=mBodies.size() - 1 ; i >= 0; i--) {
|
||||
destroyCollisionBody(mBodies[i]);
|
||||
}
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
/// Delete the profiler
|
||||
if (!mIsProfilerCreatedByUser) {
|
||||
delete mProfiler;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
|
||||
/// Delete the logger
|
||||
if (!mIsLoggerCreatedByUser) {
|
||||
delete mLogger;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
assert(mBodies.size() == 0);
|
||||
}
|
||||
|
||||
|
@ -64,7 +135,7 @@ CollisionWorld::~CollisionWorld() {
|
|||
CollisionBody* CollisionWorld::createCollisionBody(const Transform& transform) {
|
||||
|
||||
// Get the next available body ID
|
||||
bodyindex bodyID = computeNextAvailableBodyID();
|
||||
bodyindex bodyID = computeNextAvailableBodyId();
|
||||
|
||||
// Largest index cannot be used (it is used for invalid index)
|
||||
assert(bodyID < std::numeric_limits<reactphysics3d::bodyindex>::max());
|
||||
|
@ -81,10 +152,17 @@ CollisionBody* CollisionWorld::createCollisionBody(const Transform& transform) {
|
|||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
collisionBody->setProfiler(&mProfiler);
|
||||
collisionBody->setProfiler(mProfiler);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
collisionBody->setLogger(mLogger);
|
||||
#endif
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(bodyID) + ": New collision body created");
|
||||
|
||||
// Return the pointer to the rigid body
|
||||
return collisionBody;
|
||||
}
|
||||
|
@ -95,11 +173,14 @@ CollisionBody* CollisionWorld::createCollisionBody(const Transform& transform) {
|
|||
*/
|
||||
void CollisionWorld::destroyCollisionBody(CollisionBody* collisionBody) {
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(collisionBody->getId()) + ": collision body destroyed");
|
||||
|
||||
// Remove all the collision shapes of the body
|
||||
collisionBody->removeAllCollisionShapes();
|
||||
|
||||
// Add the body ID to the list of free IDs
|
||||
mFreeBodiesIDs.add(collisionBody->getID());
|
||||
mFreeBodiesIds.add(collisionBody->getId());
|
||||
|
||||
// Call the destructor of the collision body
|
||||
collisionBody->~CollisionBody();
|
||||
|
@ -112,17 +193,17 @@ void CollisionWorld::destroyCollisionBody(CollisionBody* collisionBody) {
|
|||
}
|
||||
|
||||
// Return the next available body ID
|
||||
bodyindex CollisionWorld::computeNextAvailableBodyID() {
|
||||
bodyindex CollisionWorld::computeNextAvailableBodyId() {
|
||||
|
||||
// Compute the body ID
|
||||
bodyindex bodyID;
|
||||
if (mFreeBodiesIDs.size() != 0) {
|
||||
bodyID = mFreeBodiesIDs[mFreeBodiesIDs.size() - 1];
|
||||
mFreeBodiesIDs.removeAt(mFreeBodiesIDs.size() - 1);
|
||||
if (mFreeBodiesIds.size() != 0) {
|
||||
bodyID = mFreeBodiesIds[mFreeBodiesIds.size() - 1];
|
||||
mFreeBodiesIds.removeAt(mFreeBodiesIds.size() - 1);
|
||||
}
|
||||
else {
|
||||
bodyID = mCurrentBodyID;
|
||||
mCurrentBodyID++;
|
||||
bodyID = mCurrentBodyId;
|
||||
mCurrentBodyId++;
|
||||
}
|
||||
|
||||
return bodyID;
|
||||
|
@ -178,7 +259,7 @@ bool CollisionWorld::testOverlap(CollisionBody* body1, CollisionBody* body2) {
|
|||
// Return the current world-space AABB of given proxy shape
|
||||
AABB CollisionWorld::getWorldAABB(const ProxyShape* proxyShape) const {
|
||||
|
||||
if (proxyShape->mBroadPhaseID == -1) {
|
||||
if (proxyShape->getBroadPhaseId() == -1) {
|
||||
return AABB();
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
#include <algorithm>
|
||||
#include "mathematics/mathematics.h"
|
||||
#include "containers/List.h"
|
||||
#include "Profiler.h"
|
||||
#include "utils/Profiler.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "body/CollisionBody.h"
|
||||
#include "collision/RaycastInfo.h"
|
||||
#include "OverlappingPair.h"
|
||||
|
@ -71,25 +72,43 @@ class CollisionWorld {
|
|||
/// All the bodies (rigid and soft) of the world
|
||||
List<CollisionBody*> mBodies;
|
||||
|
||||
/// Current body ID
|
||||
bodyindex mCurrentBodyID;
|
||||
/// Current body id
|
||||
bodyindex mCurrentBodyId;
|
||||
|
||||
/// List of free ID for rigid bodies
|
||||
List<luint> mFreeBodiesIDs;
|
||||
/// List of free ids for rigid bodies
|
||||
List<luint> mFreeBodiesIds;
|
||||
|
||||
/// Pointer to an event listener object
|
||||
EventListener* mEventListener;
|
||||
|
||||
/// Name of the collision world
|
||||
std::string mName;
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
/// Real-time hierarchical profiler
|
||||
Profiler mProfiler;
|
||||
Profiler* mProfiler;
|
||||
#endif
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
|
||||
/// Logger
|
||||
Logger* mLogger;
|
||||
#endif
|
||||
|
||||
/// True if the profiler has been created by the user
|
||||
bool mIsProfilerCreatedByUser;
|
||||
|
||||
/// True if the logger has been created by the user
|
||||
bool mIsLoggerCreatedByUser;
|
||||
|
||||
/// Total number of worlds
|
||||
static uint mNbWorlds;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Return the next available body ID
|
||||
bodyindex computeNextAvailableBodyID();
|
||||
/// Return the next available body id
|
||||
bodyindex computeNextAvailableBodyId();
|
||||
|
||||
/// Reset all the contact manifolds linked list of each body
|
||||
void resetContactManifoldListsOfBodies();
|
||||
|
@ -99,7 +118,8 @@ class CollisionWorld {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
CollisionWorld(const WorldSettings& worldSettings = WorldSettings());
|
||||
CollisionWorld(const WorldSettings& worldSettings = WorldSettings(), Logger* logger = nullptr,
|
||||
Profiler* profiler = nullptr);
|
||||
|
||||
/// Destructor
|
||||
virtual ~CollisionWorld();
|
||||
|
@ -147,13 +167,24 @@ class CollisionWorld {
|
|||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
/// Set the name of the profiler
|
||||
void setProfilerName(std::string name);
|
||||
/// Return a reference to the profiler
|
||||
Profiler* getProfiler();
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
|
||||
/// Return a reference to the logger
|
||||
Logger* getLogger();
|
||||
|
||||
#endif
|
||||
|
||||
/// Return the current world-space AABB of given proxy shape
|
||||
AABB getWorldAABB(const ProxyShape* proxyShape) const;
|
||||
|
||||
/// Return the name of the world
|
||||
const std::string& getName() const;
|
||||
|
||||
// -------------------- Friendship -------------------- //
|
||||
|
||||
friend class CollisionDetection;
|
||||
|
@ -224,11 +255,25 @@ inline void CollisionWorld::testOverlap(CollisionBody* body, OverlapCallback* ov
|
|||
mCollisionDetection.testOverlap(body, overlapCallback, categoryMaskBits);
|
||||
}
|
||||
|
||||
// Return the name of the world
|
||||
inline const std::string& CollisionWorld::getName() const {
|
||||
return mName;
|
||||
}
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
// Set the name of the profiler
|
||||
inline void CollisionWorld::setProfilerName(std::string name) {
|
||||
mProfiler.setName(name);
|
||||
// Return a pointer to the profiler
|
||||
inline Profiler* CollisionWorld::getProfiler() {
|
||||
return mProfiler;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
|
||||
// Return a pointer to the logger
|
||||
inline Logger* CollisionWorld::getLogger() {
|
||||
return mLogger;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
// Libraries
|
||||
#include "ConstraintSolver.h"
|
||||
#include "Profiler.h"
|
||||
#include "utils/Profiler.h"
|
||||
|
||||
using namespace reactphysics3d;
|
||||
|
||||
|
@ -43,7 +43,7 @@ ConstraintSolver::ConstraintSolver() : mIsWarmStartingActive(true) {
|
|||
// Initialize the constraint solver for a given island
|
||||
void ConstraintSolver::initializeForIsland(decimal dt, Island* island) {
|
||||
|
||||
PROFILE("ConstraintSolver::initializeForIsland()", mProfiler);
|
||||
RP3D_PROFILE("ConstraintSolver::initializeForIsland()", mProfiler);
|
||||
|
||||
assert(island != nullptr);
|
||||
assert(island->getNbBodies() > 0);
|
||||
|
@ -73,7 +73,7 @@ void ConstraintSolver::initializeForIsland(decimal dt, Island* island) {
|
|||
// Solve the velocity constraints
|
||||
void ConstraintSolver::solveVelocityConstraints(Island* island) {
|
||||
|
||||
PROFILE("ConstraintSolver::solveVelocityConstraints()", mProfiler);
|
||||
RP3D_PROFILE("ConstraintSolver::solveVelocityConstraints()", mProfiler);
|
||||
|
||||
assert(island != nullptr);
|
||||
assert(island->getNbJoints() > 0);
|
||||
|
@ -90,7 +90,7 @@ void ConstraintSolver::solveVelocityConstraints(Island* island) {
|
|||
// Solve the position constraints
|
||||
void ConstraintSolver::solvePositionConstraints(Island* island) {
|
||||
|
||||
PROFILE("ConstraintSolver::solvePositionConstraints()", mProfiler);
|
||||
RP3D_PROFILE("ConstraintSolver::solvePositionConstraints()", mProfiler);
|
||||
|
||||
assert(island != nullptr);
|
||||
assert(island->getNbJoints() > 0);
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "ContactSolver.h"
|
||||
#include "DynamicsWorld.h"
|
||||
#include "body/RigidBody.h"
|
||||
#include "Profiler.h"
|
||||
#include "utils/Profiler.h"
|
||||
#include <limits>
|
||||
|
||||
using namespace reactphysics3d;
|
||||
|
@ -50,7 +50,7 @@ ContactSolver::ContactSolver(MemoryManager& memoryManager, const WorldSettings&
|
|||
// Initialize the contact constraints
|
||||
void ContactSolver::init(Island** islands, uint nbIslands, decimal timeStep) {
|
||||
|
||||
PROFILE("ContactSolver::init()", mProfiler);
|
||||
RP3D_PROFILE("ContactSolver::init()", mProfiler);
|
||||
|
||||
mTimeStep = timeStep;
|
||||
|
||||
|
@ -98,7 +98,7 @@ void ContactSolver::init(Island** islands, uint nbIslands, decimal timeStep) {
|
|||
// Initialize the constraint solver for a given island
|
||||
void ContactSolver::initializeForIsland(Island* island) {
|
||||
|
||||
PROFILE("ContactSolver::initializeForIsland()", mProfiler);
|
||||
RP3D_PROFILE("ContactSolver::initializeForIsland()", mProfiler);
|
||||
|
||||
assert(island != nullptr);
|
||||
assert(island->getNbBodies() > 0);
|
||||
|
@ -326,7 +326,7 @@ void ContactSolver::initializeForIsland(Island* island) {
|
|||
/// the solution of the linear system
|
||||
void ContactSolver::warmStart() {
|
||||
|
||||
PROFILE("ContactSolver::warmStart()", mProfiler);
|
||||
RP3D_PROFILE("ContactSolver::warmStart()", mProfiler);
|
||||
|
||||
uint contactPointIndex = 0;
|
||||
|
||||
|
@ -479,7 +479,7 @@ void ContactSolver::warmStart() {
|
|||
// Solve the contacts
|
||||
void ContactSolver::solve() {
|
||||
|
||||
PROFILE("ContactSolver::solve()", mProfiler);
|
||||
RP3D_PROFILE("ContactSolver::solve()", mProfiler);
|
||||
|
||||
decimal deltaLambda;
|
||||
decimal lambdaTemp;
|
||||
|
@ -758,7 +758,7 @@ void ContactSolver::solve() {
|
|||
// warm start the solver at the next iteration
|
||||
void ContactSolver::storeImpulses() {
|
||||
|
||||
PROFILE("ContactSolver::storeImpulses()", mProfiler);
|
||||
RP3D_PROFILE("ContactSolver::storeImpulses()", mProfiler);
|
||||
|
||||
uint contactPointIndex = 0;
|
||||
|
||||
|
@ -786,7 +786,7 @@ void ContactSolver::storeImpulses() {
|
|||
void ContactSolver::computeFrictionVectors(const Vector3& deltaVelocity,
|
||||
ContactManifoldSolver& contact) const {
|
||||
|
||||
PROFILE("ContactSolver::computeFrictionVectors()", mProfiler);
|
||||
RP3D_PROFILE("ContactSolver::computeFrictionVectors()", mProfiler);
|
||||
|
||||
assert(contact.normal.length() > decimal(0.0));
|
||||
|
||||
|
|
|
@ -39,8 +39,9 @@ using namespace std;
|
|||
/**
|
||||
* @param gravity Gravity vector in the world (in meters per second squared)
|
||||
*/
|
||||
DynamicsWorld::DynamicsWorld(const Vector3 &gravity, const WorldSettings& worldSettings)
|
||||
: CollisionWorld(worldSettings),
|
||||
DynamicsWorld::DynamicsWorld(const Vector3& gravity, const WorldSettings& worldSettings,
|
||||
Logger* logger, Profiler* profiler)
|
||||
: CollisionWorld(worldSettings, logger, profiler),
|
||||
mContactSolver(mMemoryManager, mConfig),
|
||||
mNbVelocitySolverIterations(mConfig.defaultVelocitySolverNbIterations),
|
||||
mNbPositionSolverIterations(mConfig.defaultPositionSolverNbIterations),
|
||||
|
@ -52,16 +53,20 @@ DynamicsWorld::DynamicsWorld(const Vector3 &gravity, const WorldSettings& worldS
|
|||
mConstrainedOrientations(nullptr), mNbIslands(0), mIslands(nullptr),
|
||||
mSleepLinearVelocity(mConfig.defaultSleepLinearVelocity),
|
||||
mSleepAngularVelocity(mConfig.defaultSleepAngularVelocity),
|
||||
mTimeBeforeSleep(mConfig.defaultTimeBeforeSleep) {
|
||||
mTimeBeforeSleep(mConfig.defaultTimeBeforeSleep),
|
||||
mFreeJointsIDs(mMemoryManager.getPoolAllocator()), mCurrentJointId(0) {
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
// Set the profiler
|
||||
mConstraintSolver.setProfiler(&mProfiler);
|
||||
mContactSolver.setProfiler(&mProfiler);
|
||||
mConstraintSolver.setProfiler(mProfiler);
|
||||
mContactSolver.setProfiler(mProfiler);
|
||||
|
||||
#endif
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
|
||||
"Dynamics World: Dynamics world " + mName + " has been created");
|
||||
|
||||
}
|
||||
|
||||
// Destructor
|
||||
|
@ -82,13 +87,12 @@ DynamicsWorld::~DynamicsWorld() {
|
|||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
// Print the profiling report
|
||||
ofstream myfile;
|
||||
myfile.open(mProfiler.getName() + ".txt");
|
||||
mProfiler.printReport(myfile);
|
||||
myfile.close();
|
||||
// Print the profiling report into the destinations
|
||||
mProfiler->printReport();
|
||||
#endif
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
|
||||
"Dynamics World: Dynamics world " + mName + " has been destroyed");
|
||||
}
|
||||
|
||||
// Update the physics simulation
|
||||
|
@ -99,10 +103,10 @@ void DynamicsWorld::update(decimal timeStep) {
|
|||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
// Increment the frame counter of the profiler
|
||||
mProfiler.incrementFrameCounter();
|
||||
mProfiler->incrementFrameCounter();
|
||||
#endif
|
||||
|
||||
PROFILE("DynamicsWorld::update()", &mProfiler);
|
||||
RP3D_PROFILE("DynamicsWorld::update()", mProfiler);
|
||||
|
||||
mTimeStep = timeStep;
|
||||
|
||||
|
@ -150,7 +154,7 @@ void DynamicsWorld::update(decimal timeStep) {
|
|||
/// the sympletic Euler time stepping scheme.
|
||||
void DynamicsWorld::integrateRigidBodiesPositions() {
|
||||
|
||||
PROFILE("DynamicsWorld::integrateRigidBodiesPositions()", &mProfiler);
|
||||
RP3D_PROFILE("DynamicsWorld::integrateRigidBodiesPositions()", mProfiler);
|
||||
|
||||
// For each island of the world
|
||||
for (uint i=0; i < mNbIslands; i++) {
|
||||
|
@ -189,7 +193,7 @@ void DynamicsWorld::integrateRigidBodiesPositions() {
|
|||
// Update the postion/orientation of the bodies
|
||||
void DynamicsWorld::updateBodiesState() {
|
||||
|
||||
PROFILE("DynamicsWorld::updateBodiesState()", &mProfiler);
|
||||
RP3D_PROFILE("DynamicsWorld::updateBodiesState()", mProfiler);
|
||||
|
||||
// For each island of the world
|
||||
for (uint islandIndex = 0; islandIndex < mNbIslands; islandIndex++) {
|
||||
|
@ -226,7 +230,7 @@ void DynamicsWorld::updateBodiesState() {
|
|||
// Initialize the bodies velocities arrays for the next simulation step.
|
||||
void DynamicsWorld::initVelocityArrays() {
|
||||
|
||||
PROFILE("DynamicsWorld::initVelocityArrays()", &mProfiler);
|
||||
RP3D_PROFILE("DynamicsWorld::initVelocityArrays()", mProfiler);
|
||||
|
||||
// Allocate memory for the bodies velocity arrays
|
||||
uint nbBodies = mRigidBodies.size();
|
||||
|
@ -268,7 +272,7 @@ void DynamicsWorld::initVelocityArrays() {
|
|||
/// contact solver.
|
||||
void DynamicsWorld::integrateRigidBodiesVelocities() {
|
||||
|
||||
PROFILE("DynamicsWorld::integrateRigidBodiesVelocities()", &mProfiler);
|
||||
RP3D_PROFILE("DynamicsWorld::integrateRigidBodiesVelocities()", mProfiler);
|
||||
|
||||
// Initialize the bodies velocity arrays
|
||||
initVelocityArrays();
|
||||
|
@ -330,7 +334,7 @@ void DynamicsWorld::integrateRigidBodiesVelocities() {
|
|||
// Solve the contacts and constraints
|
||||
void DynamicsWorld::solveContactsAndConstraints() {
|
||||
|
||||
PROFILE("DynamicsWorld::solveContactsAndConstraints()", &mProfiler);
|
||||
RP3D_PROFILE("DynamicsWorld::solveContactsAndConstraints()", mProfiler);
|
||||
|
||||
// Set the velocities arrays
|
||||
mContactSolver.setSplitVelocitiesArrays(mSplitLinearVelocities, mSplitAngularVelocities);
|
||||
|
@ -380,7 +384,7 @@ void DynamicsWorld::solveContactsAndConstraints() {
|
|||
// Solve the position error correction of the constraints
|
||||
void DynamicsWorld::solvePositionCorrection() {
|
||||
|
||||
PROFILE("DynamicsWorld::solvePositionCorrection()", &mProfiler);
|
||||
RP3D_PROFILE("DynamicsWorld::solvePositionCorrection()", mProfiler);
|
||||
|
||||
// Do not continue if there is no constraints
|
||||
if (mJoints.size() == 0) return;
|
||||
|
@ -407,7 +411,7 @@ void DynamicsWorld::solvePositionCorrection() {
|
|||
RigidBody* DynamicsWorld::createRigidBody(const Transform& transform) {
|
||||
|
||||
// Compute the body ID
|
||||
bodyindex bodyID = computeNextAvailableBodyID();
|
||||
bodyindex bodyID = computeNextAvailableBodyId();
|
||||
|
||||
// Largest index cannot be used (it is used for invalid index)
|
||||
assert(bodyID < std::numeric_limits<reactphysics3d::bodyindex>::max());
|
||||
|
@ -422,11 +426,16 @@ RigidBody* DynamicsWorld::createRigidBody(const Transform& transform) {
|
|||
mRigidBodies.add(rigidBody);
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
rigidBody->setProfiler(&mProfiler);
|
||||
|
||||
rigidBody->setProfiler(mProfiler);
|
||||
#endif
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
rigidBody->setLogger(mLogger);
|
||||
#endif
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(bodyID) + ": New collision body created");
|
||||
|
||||
// Return the pointer to the rigid body
|
||||
return rigidBody;
|
||||
}
|
||||
|
@ -437,11 +446,14 @@ RigidBody* DynamicsWorld::createRigidBody(const Transform& transform) {
|
|||
*/
|
||||
void DynamicsWorld::destroyRigidBody(RigidBody* rigidBody) {
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(rigidBody->getId()) + ": rigid body destroyed");
|
||||
|
||||
// Remove all the collision shapes of the body
|
||||
rigidBody->removeAllCollisionShapes();
|
||||
|
||||
// Add the body ID to the list of free IDs
|
||||
mFreeBodiesIDs.add(rigidBody->getID());
|
||||
mFreeBodiesIds.add(rigidBody->getId());
|
||||
|
||||
// Destroy all the joints in which the rigid body to be destroyed is involved
|
||||
JointListElement* element;
|
||||
|
@ -472,6 +484,9 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
|
|||
|
||||
Joint* newJoint = nullptr;
|
||||
|
||||
// Get the next available joint ID
|
||||
uint jointId = computeNextAvailableJointId();
|
||||
|
||||
// Allocate memory to create the new joint
|
||||
switch(jointInfo.type) {
|
||||
|
||||
|
@ -482,7 +497,7 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
|
|||
sizeof(BallAndSocketJoint));
|
||||
const BallAndSocketJointInfo& info = static_cast<const BallAndSocketJointInfo&>(
|
||||
jointInfo);
|
||||
newJoint = new (allocatedMemory) BallAndSocketJoint(info);
|
||||
newJoint = new (allocatedMemory) BallAndSocketJoint(jointId, info);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -492,7 +507,7 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
|
|||
void* allocatedMemory = mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
|
||||
sizeof(SliderJoint));
|
||||
const SliderJointInfo& info = static_cast<const SliderJointInfo&>(jointInfo);
|
||||
newJoint = new (allocatedMemory) SliderJoint(info);
|
||||
newJoint = new (allocatedMemory) SliderJoint(jointId, info);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -502,7 +517,7 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
|
|||
void* allocatedMemory = mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
|
||||
sizeof(HingeJoint));
|
||||
const HingeJointInfo& info = static_cast<const HingeJointInfo&>(jointInfo);
|
||||
newJoint = new (allocatedMemory) HingeJoint(info);
|
||||
newJoint = new (allocatedMemory) HingeJoint(jointId, info);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -512,7 +527,7 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
|
|||
void* allocatedMemory = mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
|
||||
sizeof(FixedJoint));
|
||||
const FixedJointInfo& info = static_cast<const FixedJointInfo&>(jointInfo);
|
||||
newJoint = new (allocatedMemory) FixedJoint(info);
|
||||
newJoint = new (allocatedMemory) FixedJoint(jointId, info);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -533,6 +548,11 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
|
|||
// Add the joint into the world
|
||||
mJoints.add(newJoint);
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Joint,
|
||||
"Joint " + std::to_string(newJoint->getId()) + ": New joint created");
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Joint,
|
||||
"Joint " + std::to_string(newJoint->getId()) + ": " + newJoint->to_string());
|
||||
|
||||
// Add the joint into the joint list of the bodies involved in the joint
|
||||
addJointToBody(newJoint);
|
||||
|
||||
|
@ -548,6 +568,9 @@ void DynamicsWorld::destroyJoint(Joint* joint) {
|
|||
|
||||
assert(joint != nullptr);
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Joint,
|
||||
"Joint " + std::to_string(joint->getId()) + ": joint destroyed");
|
||||
|
||||
// If the collision between the two bodies of the constraint was disabled
|
||||
if (!joint->isCollisionEnabled()) {
|
||||
|
||||
|
@ -568,9 +591,15 @@ void DynamicsWorld::destroyJoint(Joint* joint) {
|
|||
|
||||
size_t nbBytes = joint->getSizeInBytes();
|
||||
|
||||
// Add the joint ID to the list of free IDs
|
||||
mFreeJointsIDs.add(joint->getId());
|
||||
|
||||
// Call the destructor of the joint
|
||||
joint->~Joint();
|
||||
|
||||
// Add the joint ID to the list of free IDs
|
||||
mFreeJointsIDs.add(joint->getId());
|
||||
|
||||
// Release the allocated memory
|
||||
mMemoryManager.release(MemoryManager::AllocationType::Pool, joint, nbBytes);
|
||||
}
|
||||
|
@ -587,12 +616,37 @@ void DynamicsWorld::addJointToBody(Joint* joint) {
|
|||
joint->mBody1->mJointsList);
|
||||
joint->mBody1->mJointsList = jointListElement1;
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(joint->mBody1->getId()) + ": Joint " + std::to_string(joint->getId()) +
|
||||
" added to body");
|
||||
|
||||
// Add the joint at the beginning of the linked list of joints of the second body
|
||||
void* allocatedMemory2 = mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
|
||||
sizeof(JointListElement));
|
||||
JointListElement* jointListElement2 = new (allocatedMemory2) JointListElement(joint,
|
||||
joint->mBody2->mJointsList);
|
||||
joint->mBody2->mJointsList = jointListElement2;
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
|
||||
"Body " + std::to_string(joint->mBody2->getId()) + ": Joint " + std::to_string(joint->getId()) +
|
||||
" added to body");
|
||||
}
|
||||
|
||||
// Return the next available joint Id
|
||||
uint DynamicsWorld::computeNextAvailableJointId() {
|
||||
|
||||
// Compute the joint ID
|
||||
uint jointId;
|
||||
if (mFreeJointsIDs.size() != 0) {
|
||||
jointId = mFreeJointsIDs[mFreeJointsIDs.size() - 1];
|
||||
mFreeJointsIDs.removeAt(mFreeJointsIDs.size() - 1);
|
||||
}
|
||||
else {
|
||||
jointId = mCurrentJointId;
|
||||
mCurrentJointId++;
|
||||
}
|
||||
|
||||
return jointId;
|
||||
}
|
||||
|
||||
// Compute the islands of awake bodies.
|
||||
|
@ -604,7 +658,7 @@ void DynamicsWorld::addJointToBody(Joint* joint) {
|
|||
/// it). Then, we create an island with this group of connected bodies.
|
||||
void DynamicsWorld::computeIslands() {
|
||||
|
||||
PROFILE("DynamicsWorld::computeIslands()", &mProfiler);
|
||||
RP3D_PROFILE("DynamicsWorld::computeIslands()", mProfiler);
|
||||
|
||||
uint nbBodies = mRigidBodies.size();
|
||||
|
||||
|
@ -693,7 +747,7 @@ void DynamicsWorld::computeIslands() {
|
|||
// Get the other body of the contact manifold
|
||||
RigidBody* body1 = static_cast<RigidBody*>(contactManifold->getBody1());
|
||||
RigidBody* body2 = static_cast<RigidBody*>(contactManifold->getBody2());
|
||||
RigidBody* otherBody = (body1->getID() == bodyToVisit->getID()) ? body2 : body1;
|
||||
RigidBody* otherBody = (body1->getId() == bodyToVisit->getId()) ? body2 : body1;
|
||||
|
||||
// Check if the other body has already been added to the island
|
||||
if (otherBody->mIsAlreadyInIsland) continue;
|
||||
|
@ -721,7 +775,7 @@ void DynamicsWorld::computeIslands() {
|
|||
// Get the other body of the contact manifold
|
||||
RigidBody* body1 = static_cast<RigidBody*>(joint->getBody1());
|
||||
RigidBody* body2 = static_cast<RigidBody*>(joint->getBody2());
|
||||
RigidBody* otherBody = (body1->getID() == bodyToVisit->getID()) ? body2 : body1;
|
||||
RigidBody* otherBody = (body1->getId() == bodyToVisit->getId()) ? body2 : body1;
|
||||
|
||||
// Check if the other body has already been added to the island
|
||||
if (otherBody->mIsAlreadyInIsland) continue;
|
||||
|
@ -751,7 +805,7 @@ void DynamicsWorld::computeIslands() {
|
|||
/// time, we put all the bodies of the island to sleep.
|
||||
void DynamicsWorld::updateSleepingBodies() {
|
||||
|
||||
PROFILE("DynamicsWorld::updateSleepingBodies()", &mProfiler);
|
||||
RP3D_PROFILE("DynamicsWorld::updateSleepingBodies()", mProfiler);
|
||||
|
||||
const decimal sleepLinearVelocitySquare = mSleepLinearVelocity * mSleepLinearVelocity;
|
||||
const decimal sleepAngularVelocitySquare = mSleepAngularVelocity * mSleepAngularVelocity;
|
||||
|
@ -820,6 +874,9 @@ void DynamicsWorld::enableSleeping(bool isSleepingEnabled) {
|
|||
(*it)->setIsSleeping(false);
|
||||
}
|
||||
}
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
|
||||
"Dynamics World: isSleepingEnabled=" + (isSleepingEnabled ? std::string("true") : std::string("false")) );
|
||||
}
|
||||
|
||||
/// Return the list of all contacts of the world
|
||||
|
|
|
@ -116,6 +116,12 @@ class DynamicsWorld : public CollisionWorld {
|
|||
/// becomes smaller than the sleep velocity.
|
||||
decimal mTimeBeforeSleep;
|
||||
|
||||
/// List of free ID for joints
|
||||
List<luint> mFreeJointsIDs;
|
||||
|
||||
/// Current joint id
|
||||
uint mCurrentJointId;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Integrate the positions and orientations of rigid bodies.
|
||||
|
@ -148,12 +154,16 @@ class DynamicsWorld : public CollisionWorld {
|
|||
/// Add the joint to the list of joints of the two bodies involved in the joint
|
||||
void addJointToBody(Joint* joint);
|
||||
|
||||
/// Return the next available joint id
|
||||
uint computeNextAvailableJointId();
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
DynamicsWorld(const Vector3& mGravity, const WorldSettings& worldSettings = WorldSettings());
|
||||
DynamicsWorld(const Vector3& mGravity, const WorldSettings& worldSettings = WorldSettings(),
|
||||
Logger* logger = nullptr, Profiler* profiler = nullptr);
|
||||
|
||||
/// Destructor
|
||||
virtual ~DynamicsWorld() override;
|
||||
|
@ -272,6 +282,9 @@ inline uint DynamicsWorld::getNbIterationsVelocitySolver() const {
|
|||
*/
|
||||
inline void DynamicsWorld::setNbIterationsVelocitySolver(uint nbIterations) {
|
||||
mNbVelocitySolverIterations = nbIterations;
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
|
||||
"Dynamics World: Set nb iterations velocity solver to " + std::to_string(nbIterations));
|
||||
}
|
||||
|
||||
// Get the number of iterations for the position constraint solver
|
||||
|
@ -285,6 +298,9 @@ inline uint DynamicsWorld::getNbIterationsPositionSolver() const {
|
|||
*/
|
||||
inline void DynamicsWorld::setNbIterationsPositionSolver(uint nbIterations) {
|
||||
mNbPositionSolverIterations = nbIterations;
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
|
||||
"Dynamics World: Set nb iterations position solver to " + std::to_string(nbIterations));
|
||||
}
|
||||
|
||||
// Set the position correction technique used for contacts
|
||||
|
@ -329,6 +345,9 @@ inline Vector3 DynamicsWorld::getGravity() const {
|
|||
*/
|
||||
inline void DynamicsWorld::setGravity(Vector3& gravity) {
|
||||
mGravity = gravity;
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
|
||||
"Dynamics World: Set gravity vector to " + gravity.to_string());
|
||||
}
|
||||
|
||||
// Return if the gravity is enaled
|
||||
|
@ -346,6 +365,9 @@ inline bool DynamicsWorld::isGravityEnabled() const {
|
|||
*/
|
||||
inline void DynamicsWorld::setIsGratityEnabled(bool isGravityEnabled) {
|
||||
mIsGravityEnabled = isGravityEnabled;
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
|
||||
"Dynamics World: isGravityEnabled= " + (isGravityEnabled ? std::string("true") : std::string("false")));
|
||||
}
|
||||
|
||||
// Return the number of rigid bodies in the world
|
||||
|
@ -390,6 +412,9 @@ inline decimal DynamicsWorld::getSleepLinearVelocity() const {
|
|||
inline void DynamicsWorld::setSleepLinearVelocity(decimal sleepLinearVelocity) {
|
||||
assert(sleepLinearVelocity >= decimal(0.0));
|
||||
mSleepLinearVelocity = sleepLinearVelocity;
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
|
||||
"Dynamics World: sleepLinearVelocity= " + std::to_string(sleepLinearVelocity));
|
||||
}
|
||||
|
||||
// Return the current sleep angular velocity
|
||||
|
@ -410,6 +435,9 @@ inline decimal DynamicsWorld::getSleepAngularVelocity() const {
|
|||
inline void DynamicsWorld::setSleepAngularVelocity(decimal sleepAngularVelocity) {
|
||||
assert(sleepAngularVelocity >= decimal(0.0));
|
||||
mSleepAngularVelocity = sleepAngularVelocity;
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
|
||||
"Dynamics World: sleepAngularVelocity= " + std::to_string(sleepAngularVelocity));
|
||||
}
|
||||
|
||||
// Return the time a body is required to stay still before sleeping
|
||||
|
@ -428,6 +456,9 @@ inline decimal DynamicsWorld::getTimeBeforeSleep() const {
|
|||
inline void DynamicsWorld::setTimeBeforeSleep(decimal timeBeforeSleep) {
|
||||
assert(timeBeforeSleep >= decimal(0.0));
|
||||
mTimeBeforeSleep = timeBeforeSleep;
|
||||
|
||||
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
|
||||
"Dynamics World: timeBeforeSleep= " + std::to_string(timeBeforeSleep));
|
||||
}
|
||||
|
||||
// Set an event listener object to receive events callbacks.
|
||||
|
|
|
@ -84,6 +84,9 @@ class Material {
|
|||
/// Set the rolling resistance factor
|
||||
void setRollingResistance(decimal rollingResistance);
|
||||
|
||||
/// Return a string representation for the material
|
||||
std::string to_string() const;
|
||||
|
||||
/// Overloaded assignment operator
|
||||
Material& operator=(const Material& material);
|
||||
};
|
||||
|
@ -147,6 +150,18 @@ inline void Material::setRollingResistance(decimal rollingResistance) {
|
|||
mRollingResistance = rollingResistance;
|
||||
}
|
||||
|
||||
// Return a string representation for the material
|
||||
inline std::string Material::to_string() const {
|
||||
|
||||
std::stringstream ss;
|
||||
|
||||
ss << "frictionCoefficient=" << mFrictionCoefficient << std::endl;
|
||||
ss << "rollingResistance=" << mRollingResistance << std::endl;
|
||||
ss << "bounciness=" << mBounciness << std::endl;
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// Overloaded assignment operator
|
||||
inline Material& Material::operator=(const Material& material) {
|
||||
|
||||
|
|
|
@ -248,12 +248,12 @@ inline void OverlappingPair::makeContactsObsolete() {
|
|||
|
||||
// Return the pair of bodies index
|
||||
inline OverlappingPair::OverlappingPairId OverlappingPair::computeID(ProxyShape* shape1, ProxyShape* shape2) {
|
||||
assert(shape1->mBroadPhaseID >= 0 && shape2->mBroadPhaseID >= 0);
|
||||
assert(shape1->getBroadPhaseId() >= 0 && shape2->getBroadPhaseId() >= 0);
|
||||
|
||||
// Construct the pair of body index
|
||||
OverlappingPairId pairID = shape1->mBroadPhaseID < shape2->mBroadPhaseID ?
|
||||
OverlappingPairId(shape1->mBroadPhaseID, shape2->mBroadPhaseID) :
|
||||
OverlappingPairId(shape2->mBroadPhaseID, shape1->mBroadPhaseID);
|
||||
OverlappingPairId pairID = shape1->getBroadPhaseId() < shape2->getBroadPhaseId() ?
|
||||
OverlappingPairId(shape1->getBroadPhaseId(), shape2->getBroadPhaseId()) :
|
||||
OverlappingPairId(shape2->getBroadPhaseId(), shape1->getBroadPhaseId());
|
||||
assert(pairID.first != pairID.second);
|
||||
return pairID;
|
||||
}
|
||||
|
@ -263,9 +263,9 @@ inline bodyindexpair OverlappingPair::computeBodiesIndexPair(CollisionBody* body
|
|||
CollisionBody* body2) {
|
||||
|
||||
// Construct the pair of body index
|
||||
bodyindexpair indexPair = body1->getID() < body2->getID() ?
|
||||
bodyindexpair(body1->getID(), body2->getID()) :
|
||||
bodyindexpair(body2->getID(), body1->getID());
|
||||
bodyindexpair indexPair = body1->getId() < body2->getId() ?
|
||||
bodyindexpair(body1->getId(), body2->getId()) :
|
||||
bodyindexpair(body2->getId(), body1->getId());
|
||||
assert(indexPair.first != indexPair.second);
|
||||
return indexPair;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
// Libraries
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include "Vector2.h"
|
||||
|
||||
/// ReactPhysics3D namespace
|
||||
|
@ -145,6 +146,9 @@ class Matrix2x2 {
|
|||
|
||||
/// Overloaded operator to read/write element of the matrix.
|
||||
Vector2& operator[](int row);
|
||||
|
||||
/// Return the string representation
|
||||
std::string to_string() const;
|
||||
};
|
||||
|
||||
// Constructor of the class Matrix2x2
|
||||
|
@ -340,6 +344,12 @@ inline Vector2& Matrix2x2::operator[](int row) {
|
|||
return mRows[row];
|
||||
}
|
||||
|
||||
// Get the string representation
|
||||
inline std::string Matrix2x2::to_string() const {
|
||||
return "Matrix2x2(" + std::to_string(mRows[0][0]) + "," + std::to_string(mRows[0][1]) + "," +
|
||||
std::to_string(mRows[1][0]) + "," + std::to_string(mRows[1][1]) + ")";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
// Libraries
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include "Vector3.h"
|
||||
|
||||
/// ReactPhysics3D namespace
|
||||
|
@ -153,6 +154,9 @@ class Matrix3x3 {
|
|||
|
||||
/// Overloaded operator to read/write element of the matrix.
|
||||
Vector3& operator[](int row);
|
||||
|
||||
/// Return the string representation
|
||||
std::string to_string() const;
|
||||
};
|
||||
|
||||
// Constructor of the class Matrix3x3
|
||||
|
@ -392,6 +396,13 @@ inline Vector3& Matrix3x3::operator[](int row) {
|
|||
return mRows[row];
|
||||
}
|
||||
|
||||
// Get the string representation
|
||||
inline std::string Matrix3x3::to_string() const {
|
||||
return "Matrix3x3(" + std::to_string(mRows[0][0]) + "," + std::to_string(mRows[0][1]) + "," + std::to_string(mRows[0][2]) + "," +
|
||||
std::to_string(mRows[1][0]) + "," + std::to_string(mRows[1][1]) + "," + std::to_string(mRows[1][2]) + "," +
|
||||
std::to_string(mRows[2][0]) + "," + std::to_string(mRows[2][1]) + "," + std::to_string(mRows[2][2]) + ")";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -163,6 +163,9 @@ struct Quaternion {
|
|||
/// Overloaded operator for equality condition
|
||||
bool operator==(const Quaternion& quaternion) const;
|
||||
|
||||
/// Return the string representation
|
||||
std::string to_string() const;
|
||||
|
||||
private:
|
||||
|
||||
/// Initialize the quaternion using Euler angles
|
||||
|
@ -379,6 +382,12 @@ inline bool Quaternion::operator==(const Quaternion& quaternion) const {
|
|||
z == quaternion.z && w == quaternion.w);
|
||||
}
|
||||
|
||||
// Get the string representation
|
||||
inline std::string Quaternion::to_string() const {
|
||||
return "Quaternion(" + std::to_string(x) + "," + std::to_string(y) + "," + std::to_string(z) + "," +
|
||||
std::to_string(w) + ")";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -116,6 +116,9 @@ class Transform {
|
|||
|
||||
/// Assignment operator
|
||||
Transform& operator=(const Transform& transform);
|
||||
|
||||
/// Return the string representation
|
||||
std::string to_string() const;
|
||||
};
|
||||
|
||||
// Constructor
|
||||
|
@ -268,6 +271,11 @@ inline Transform& Transform::operator=(const Transform& transform) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
// Get the string representation
|
||||
inline std::string Transform::to_string() const {
|
||||
return "Transform(" + mPosition.to_string() + "," + mOrientation.to_string() + ")";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
// Libraries
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include "mathematics_functions.h"
|
||||
#include "decimal.h"
|
||||
|
||||
|
@ -135,6 +136,9 @@ struct Vector2 {
|
|||
/// Overloaded less than operator for ordering to be used inside std::set for instance
|
||||
bool operator<(const Vector2& vector) const;
|
||||
|
||||
/// Return the string representation
|
||||
std::string to_string() const;
|
||||
|
||||
/// Return a vector taking the minimum components of two vectors
|
||||
static Vector2 min(const Vector2& vector1, const Vector2& vector2);
|
||||
|
||||
|
@ -352,6 +356,11 @@ inline Vector2 Vector2::max(const Vector2& vector1, const Vector2& vector2) {
|
|||
std::max(vector1.y, vector2.y));
|
||||
}
|
||||
|
||||
// Get the string representation
|
||||
inline std::string Vector2::to_string() const {
|
||||
return "Vector2(" + std::to_string(x) + "," + std::to_string(y) + ")";
|
||||
}
|
||||
|
||||
// Return the zero vector
|
||||
inline Vector2 Vector2::zero() {
|
||||
return Vector2(0, 0);
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
// Libraries
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include "mathematics_functions.h"
|
||||
#include "decimal.h"
|
||||
|
||||
|
@ -147,6 +148,9 @@ struct Vector3 {
|
|||
/// Overloaded less than operator for ordering to be used inside std::set for instance
|
||||
bool operator<(const Vector3& vector) const;
|
||||
|
||||
/// Get the string representation
|
||||
std::string to_string() const;
|
||||
|
||||
/// Return a vector taking the minimum components of two vectors
|
||||
static Vector3 min(const Vector3& vector1, const Vector3& vector2);
|
||||
|
||||
|
@ -391,6 +395,11 @@ inline decimal Vector3::getMaxValue() const {
|
|||
return std::max(std::max(x, y), z);
|
||||
}
|
||||
|
||||
// Get the string representation
|
||||
inline std::string Vector3::to_string() const {
|
||||
return "Vector3(" + std::to_string(x) + "," + std::to_string(y) + "," + std::to_string(z) + ")";
|
||||
}
|
||||
|
||||
// Return the zero vector
|
||||
inline Vector3 Vector3::zero() {
|
||||
return Vector3(0, 0, 0);
|
||||
|
|
110
src/utils/Logger.cpp
Normal file
110
src/utils/Logger.cpp
Normal file
|
@ -0,0 +1,110 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
||||
* Copyright (c) 2010-2016 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. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
|
||||
// Libraries
|
||||
#include "Logger.h"
|
||||
#include "memory/MemoryManager.h"
|
||||
|
||||
using namespace reactphysics3d;
|
||||
|
||||
// Constructor
|
||||
Logger::Logger()
|
||||
: mDestinations(MemoryManager::getBaseAllocator()), mFormatters(MemoryManager::getBaseAllocator())
|
||||
{
|
||||
|
||||
// Create the log formatters
|
||||
mFormatters.add(Pair<Format, Formatter*>(Format::Text, new TextFormatter()));
|
||||
mFormatters.add(Pair<Format, Formatter*>(Format::HTML, new HtmlFormatter()));
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Logger::~Logger() {
|
||||
|
||||
removeAllDestinations();
|
||||
|
||||
// Remove all the loggers
|
||||
for (auto it = mFormatters.begin(); it != mFormatters.end(); ++it) {
|
||||
|
||||
delete it->second;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the corresponding formatter
|
||||
Logger::Formatter* Logger::getFormatter(Format format) const {
|
||||
|
||||
auto it = mFormatters.find(format);
|
||||
if (it != mFormatters.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Add a log file destination to the logger
|
||||
void Logger::addFileDestination(const std::string& filePath, uint logLevelFlag, Format format) {
|
||||
|
||||
FileDestination* destination = new FileDestination(filePath, logLevelFlag, getFormatter(format));
|
||||
mDestinations.add(destination);
|
||||
}
|
||||
|
||||
/// Add a stream destination to the logger
|
||||
void Logger::addStreamDestination(std::ostream& outputStream, uint logLevelFlag, Format format) {
|
||||
|
||||
StreamDestination* destination = new StreamDestination(outputStream, logLevelFlag, getFormatter(format));
|
||||
mDestinations.add(destination);
|
||||
}
|
||||
|
||||
// Remove all logs destination previously set
|
||||
void Logger::removeAllDestinations() {
|
||||
|
||||
// Delete all the destinations
|
||||
for (uint i=0; i<mDestinations.size(); i++) {
|
||||
delete mDestinations[i];
|
||||
}
|
||||
|
||||
mDestinations.clear();
|
||||
}
|
||||
|
||||
// Log something
|
||||
void Logger::log(Level level, Category category, const std::string& message) {
|
||||
|
||||
// Get current time
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto time = std::chrono::system_clock::to_time_t(now);
|
||||
|
||||
mMutex.lock();
|
||||
|
||||
// For each destination
|
||||
for (auto it = mDestinations.begin(); it != mDestinations.end(); ++it) {
|
||||
|
||||
(*it)->write(time, message, level, category);
|
||||
}
|
||||
|
||||
mMutex.unlock();
|
||||
}
|
||||
|
||||
#endif
|
482
src/utils/Logger.h
Normal file
482
src/utils/Logger.h
Normal file
|
@ -0,0 +1,482 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
||||
* Copyright (c) 2010-2016 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_LOGGER_H
|
||||
#define REACTPHYSICS3D_LOGGER_H
|
||||
|
||||
|
||||
// Libraries
|
||||
#include "containers/List.h"
|
||||
#include "containers/Map.h"
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <mutex>
|
||||
|
||||
/// ReactPhysics3D namespace
|
||||
namespace reactphysics3d {
|
||||
|
||||
// Class Logger
|
||||
/**
|
||||
* This class is used to log information, warnings or errors during the execution of the
|
||||
* library code for easier debugging.
|
||||
*/
|
||||
class Logger {
|
||||
|
||||
public:
|
||||
|
||||
/// Log verbosity levels
|
||||
enum class Level {Error = 1, Warning = 2, Information = 4};
|
||||
|
||||
/// Log categories
|
||||
enum class Category {World, Body, Joint, ProxyShape};
|
||||
|
||||
/// Log verbosity level
|
||||
enum class Format {Text, HTML};
|
||||
|
||||
/// Return the name of a category
|
||||
static std::string getCategoryName(Category category) {
|
||||
|
||||
switch(category) {
|
||||
case Category::World: return "World";
|
||||
case Category::Body: return "Body";
|
||||
case Category::Joint: return "Joint";
|
||||
case Category::ProxyShape: return "ProxyShape";
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the name of a level
|
||||
static std::string getLevelName(Level level) {
|
||||
|
||||
switch(level) {
|
||||
case Level::Information: return "Information";
|
||||
case Level::Warning: return "Warning";
|
||||
case Level::Error: return "Error";
|
||||
}
|
||||
}
|
||||
|
||||
/// Log formatter
|
||||
class Formatter {
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
Formatter() {
|
||||
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
virtual ~Formatter() {
|
||||
|
||||
}
|
||||
|
||||
/// Return the header to write at the beginning of the stream
|
||||
virtual std::string getHeader() const {
|
||||
return "";
|
||||
}
|
||||
|
||||
/// Return the tail to write at the end of the stream
|
||||
virtual std::string getTail() const {
|
||||
return "";
|
||||
}
|
||||
|
||||
/// Format a log message
|
||||
virtual std::string format(const time_t& time, const std::string& message, Level level, Category category) = 0;
|
||||
};
|
||||
|
||||
class TextFormatter : public Formatter {
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
TextFormatter() {
|
||||
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
virtual ~TextFormatter() {
|
||||
|
||||
}
|
||||
|
||||
/// Return the header to write at the beginning of the stream
|
||||
virtual std::string getHeader() const override {
|
||||
|
||||
// Get current date
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto time = std::chrono::system_clock::to_time_t(now);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "ReactPhysics3D Logs" << std::endl;
|
||||
ss << "ReactPhysics3D Version: " << RP3D_VERSION << std::endl;
|
||||
ss << "Date: " << std::put_time(std::localtime(&time), "%Y-%m-%d") << std::endl;
|
||||
ss << "---------------------------------------------------------" << std::endl;
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
/// Format a log message
|
||||
virtual std::string format(const time_t& time, const std::string& message,
|
||||
Level level, Category category) override {
|
||||
std::stringstream ss;
|
||||
|
||||
// Time
|
||||
ss << std::put_time(std::localtime(&time), "%X") << " ";
|
||||
|
||||
// Level
|
||||
ss << getLevelName(level) << " ";
|
||||
|
||||
// Category
|
||||
ss << getCategoryName(category) << " ";
|
||||
|
||||
// Message
|
||||
ss << message << std::endl;
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
|
||||
class HtmlFormatter : public Formatter {
|
||||
|
||||
private:
|
||||
|
||||
/// Return the header to write at the beginning of the stream
|
||||
virtual std::string getHeader() const override {
|
||||
|
||||
// Get current date
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto time = std::chrono::system_clock::to_time_t(now);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "<!DOCTYPE HTML>" << std::endl;
|
||||
ss << "<html>" << std::endl;
|
||||
ss << "<head>" << std::endl;
|
||||
ss << "<title>ReactPhysics3D Logs</title>" << std::endl;
|
||||
ss << "<style>" << generateCSS() << "</style>" << std::endl;
|
||||
ss << "</head>" << std::endl;
|
||||
ss << "<body>" << std::endl;
|
||||
ss << "<h1>ReactPhysics3D Logs</h1>" << std::endl;
|
||||
ss << "<div class='general_info'>" << std::endl;
|
||||
ss << "<p>ReactPhysics3D version: " << RP3D_VERSION << "</p>" << std::endl;
|
||||
ss << "<p>Date: " << std::put_time(std::localtime(&time), "%Y-%m-%d") << "</p>" << std::endl;
|
||||
ss << "</div>" << std::endl;
|
||||
ss << "<hr>";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
/// Return the tail to write at the end of the stream
|
||||
virtual std::string getTail() const override {
|
||||
|
||||
std::stringstream ss;
|
||||
|
||||
ss << "</body>" << std::endl;
|
||||
ss << "</html>" << std::endl;
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string generateCSS() const {
|
||||
return "body {"
|
||||
" background-color: #e6e6e6;"
|
||||
" font-family: SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace; "
|
||||
"} "
|
||||
"body > div { clear:both; } "
|
||||
"body > div > div { float: left; } "
|
||||
"h1 {"
|
||||
" margin: 5px 5px 5px 5px;"
|
||||
"} "
|
||||
".general_info > p {"
|
||||
"margin: 5px;"
|
||||
"font-weight: bold;"
|
||||
"} "
|
||||
".line { "
|
||||
"font-size: 13px; "
|
||||
"color: #212529; "
|
||||
"margin: 0px 5px 2px 5px; "
|
||||
"} "
|
||||
".time { "
|
||||
"margin-right: 20px; "
|
||||
"width:80px; "
|
||||
"} "
|
||||
".level { "
|
||||
"margin-right: 20px; "
|
||||
"width: 90px; "
|
||||
"}"
|
||||
".category { "
|
||||
"margin-right: 20px; "
|
||||
"width: 100px; "
|
||||
"font-weight: bold; "
|
||||
"}"
|
||||
".message { "
|
||||
"color: #2e2e2e; "
|
||||
"word-wrap: break-word; "
|
||||
"max-width: 800px; "
|
||||
"} "
|
||||
".body > .category, .body > .message { "
|
||||
"color: #00994d;"
|
||||
"} "
|
||||
".world > .category, .world > .message { "
|
||||
"color: #3477DB; "
|
||||
"} "
|
||||
".joint .category, .joint > .message { "
|
||||
"color: #bf8040; "
|
||||
"} "
|
||||
".proxyshape .category, .proxyshape > .message { "
|
||||
"color: #9933ff; "
|
||||
"} "
|
||||
".warning { "
|
||||
"color: #ff9900 !important; "
|
||||
"} "
|
||||
".error { "
|
||||
"color: red !important; "
|
||||
"} ";
|
||||
}
|
||||
|
||||
/// Convert a string to lower case
|
||||
std::string toLowerCase(const std::string& text) {
|
||||
std::string textLower = text;
|
||||
std::transform(textLower.begin(), textLower.end(), textLower.begin(), ::tolower);
|
||||
return textLower;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
HtmlFormatter() {
|
||||
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
virtual ~HtmlFormatter() {
|
||||
|
||||
}
|
||||
|
||||
/// Format a log message
|
||||
virtual std::string format(const time_t& time, const std::string& message,
|
||||
Level level, Category category) override {
|
||||
|
||||
std::stringstream ss;
|
||||
|
||||
ss << "<div class='line " + toLowerCase(getCategoryName(category)) + " " + toLowerCase(getLevelName(level)) + "'>";
|
||||
|
||||
// Time
|
||||
ss << "<div class='time'>";
|
||||
ss << std::put_time(std::localtime(&time), "%X");
|
||||
ss << "</div>";
|
||||
|
||||
// Level
|
||||
ss << "<div class='level'>";
|
||||
ss << getLevelName(level);
|
||||
ss << "</div>";
|
||||
|
||||
// Category
|
||||
ss << "<div class='category'>";
|
||||
ss << getCategoryName(category);
|
||||
ss << "</div>";
|
||||
|
||||
// Message
|
||||
ss << "<div class='message " << toLowerCase(getCategoryName(category)) <<
|
||||
" " + toLowerCase(getLevelName(level)) << "'>" << std::endl;
|
||||
ss << message;
|
||||
ss << "</div>";
|
||||
|
||||
ss << "</div>";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// Log destination
|
||||
class Destination {
|
||||
|
||||
public:
|
||||
|
||||
/// Log level flag for this destination
|
||||
uint levelFlag;
|
||||
|
||||
/// Pointer to the formatter
|
||||
Formatter* formatter;
|
||||
|
||||
/// Constructor
|
||||
Destination(uint levelFlag, Formatter* logFormatter)
|
||||
: levelFlag(levelFlag), formatter(logFormatter) {
|
||||
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
virtual ~Destination() {
|
||||
|
||||
}
|
||||
|
||||
/// Write a message into the output stream
|
||||
virtual void write(const time_t& time, const std::string& message, Level level, Category category) = 0;
|
||||
};
|
||||
|
||||
class FileDestination : public Destination {
|
||||
|
||||
private:
|
||||
|
||||
std::string mFilePath;
|
||||
|
||||
/// Output file stream
|
||||
std::ofstream mFileStream;
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
FileDestination(const std::string& filePath, uint levelFlag, Formatter* formatter)
|
||||
:Destination(levelFlag, formatter), mFilePath(filePath),
|
||||
mFileStream(filePath, std::ios::binary) {
|
||||
|
||||
if(!mFileStream.is_open()) {
|
||||
throw(std::runtime_error("ReactPhysics3D Logger: Unable to open an output stream to file " + mFilePath));
|
||||
}
|
||||
|
||||
// Writer the head
|
||||
mFileStream << formatter->getHeader() << std::endl;
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
virtual ~FileDestination() override {
|
||||
|
||||
// Writer the tail
|
||||
mFileStream << formatter->getTail() << std::endl;
|
||||
|
||||
if (mFileStream.is_open()) {
|
||||
|
||||
// Close the stream
|
||||
mFileStream.close();
|
||||
}
|
||||
}
|
||||
|
||||
/// Write a message into the output stream
|
||||
virtual void write(const time_t& time, const std::string& message, Level level, Category category) override {
|
||||
mFileStream << formatter->format(time, message, level, category) << std::endl << std::flush;
|
||||
}
|
||||
};
|
||||
|
||||
/// Stream destination to output the logs into a stream
|
||||
class StreamDestination : public Destination {
|
||||
|
||||
private:
|
||||
|
||||
/// Output stream
|
||||
std::ostream& mOutputStream;
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
StreamDestination(std::ostream& outputStream, uint levelFlag, Formatter* formatter)
|
||||
:Destination(levelFlag, formatter), mOutputStream(outputStream) {
|
||||
|
||||
// Writer the head
|
||||
mOutputStream << formatter->getHeader() << std::endl;
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
virtual ~StreamDestination() override {
|
||||
|
||||
// Writer the tail
|
||||
mOutputStream << formatter->getTail() << std::endl;
|
||||
}
|
||||
|
||||
/// Write a message into the output stream
|
||||
virtual void write(const time_t& time, const std::string& message, Level level, Category category) override {
|
||||
mOutputStream << formatter->format(time, message, level, category) << std::endl << std::flush;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// All the log destinations
|
||||
List<Destination*> mDestinations;
|
||||
|
||||
/// Map a log format to the given formatter object
|
||||
Map<Format, Formatter*> mFormatters;
|
||||
|
||||
/// Mutex
|
||||
std::mutex mMutex;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Return the corresponding formatter
|
||||
Formatter* getFormatter(Format format) const;
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
Logger();
|
||||
|
||||
/// Destructor
|
||||
~Logger();
|
||||
|
||||
/// Add a file destination to the logger
|
||||
void addFileDestination(const std::string& filePath, uint logLevelFlag, Format format);
|
||||
|
||||
/// Add a stream destination to the logger
|
||||
void addStreamDestination(std::ostream& outputStream, uint logLevelFlag, Format format);
|
||||
|
||||
/// Remove all logs destination previously set
|
||||
void removeAllDestinations();
|
||||
|
||||
/// Log something
|
||||
void log(Level level, Category category, const std::string& message);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#ifdef IS_LOGGING_ACTIVE
|
||||
|
||||
// Use this macro to log something
|
||||
#define RP3D_LOG(logger, level, category, message) logger->log(level, category, message)
|
||||
|
||||
#else // If logger is not active
|
||||
|
||||
// Empty macro in case logs are not enabled
|
||||
#define RP3D_LOG(logger, level, message)
|
||||
|
||||
#endif
|
||||
|
||||
// Hash function for struct VerticesPair
|
||||
namespace std {
|
||||
|
||||
template<> struct hash<reactphysics3d::Logger::Format> {
|
||||
|
||||
size_t operator()(const reactphysics3d::Logger::Format format) const {
|
||||
|
||||
return static_cast<size_t>(format);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -28,12 +28,10 @@
|
|||
// Libraries
|
||||
#include "Profiler.h"
|
||||
#include <string>
|
||||
#include "memory/MemoryManager.h"
|
||||
|
||||
using namespace reactphysics3d;
|
||||
|
||||
// Initialization of static variables
|
||||
int Profiler::mNbProfilers = 0;
|
||||
|
||||
// Constructor
|
||||
ProfileNode::ProfileNode(const char* name, ProfileNode* parentNode)
|
||||
:mName(name), mNbTotalCalls(0), mStartingTime(0), mTotalTime(0),
|
||||
|
@ -79,7 +77,7 @@ void ProfileNode::enterBlockOfCode() {
|
|||
|
||||
// Get the current system time to initialize the starting time of
|
||||
// the profiling of the current block of code
|
||||
mStartingTime = Timer::getCurrentSystemTime() * 1000.0;
|
||||
mStartingTime = Timer::getCurrentSystemTime() * 1000.0L;
|
||||
}
|
||||
|
||||
mRecursionCounter++;
|
||||
|
@ -92,7 +90,7 @@ bool ProfileNode::exitBlockOfCode() {
|
|||
if (mRecursionCounter == 0 && mNbTotalCalls != 0) {
|
||||
|
||||
// Get the current system time
|
||||
long double currentTime = Timer::getCurrentSystemTime() * 1000.0;
|
||||
long double currentTime = Timer::getCurrentSystemTime() * 1000.0L;
|
||||
|
||||
// Increase the total elasped time in the current block of code
|
||||
mTotalTime += currentTime - mStartingTime;
|
||||
|
@ -105,7 +103,7 @@ bool ProfileNode::exitBlockOfCode() {
|
|||
// Reset the profiling of the node
|
||||
void ProfileNode::reset() {
|
||||
mNbTotalCalls = 0;
|
||||
mTotalTime = 0.0;
|
||||
mTotalTime = 0.0L;
|
||||
|
||||
// Reset the child node
|
||||
if (mChildNode != nullptr) {
|
||||
|
@ -156,27 +154,11 @@ void ProfileNodeIterator::enterParent() {
|
|||
}
|
||||
|
||||
// Constructor
|
||||
Profiler::Profiler(std::string name) :mRootNode("Root", nullptr) {
|
||||
|
||||
// Set the name of the profiler
|
||||
if (name == "") {
|
||||
|
||||
if (mNbProfilers == 0) {
|
||||
mName = "profiler";
|
||||
}
|
||||
else {
|
||||
mName = std::string("profiler") + std::to_string(mNbProfilers);
|
||||
}
|
||||
}
|
||||
else {
|
||||
mName = name;
|
||||
}
|
||||
Profiler::Profiler() :mRootNode("Root", nullptr), mDestinations(MemoryManager::getBaseAllocator()) {
|
||||
|
||||
mCurrentNode = &mRootNode;
|
||||
mProfilingStartTime = Timer::getCurrentSystemTime() * 1000.0;
|
||||
mProfilingStartTime = Timer::getCurrentSystemTime() * 1000.0L;
|
||||
mFrameCounter = 0;
|
||||
|
||||
mNbProfilers++;
|
||||
}
|
||||
|
||||
// Destructor
|
||||
|
@ -213,18 +195,48 @@ void Profiler::reset() {
|
|||
mRootNode.reset();
|
||||
mRootNode.enterBlockOfCode();
|
||||
mFrameCounter = 0;
|
||||
mProfilingStartTime = Timer::getCurrentSystemTime() * 1000.0;
|
||||
mProfilingStartTime = Timer::getCurrentSystemTime() * 1000.0L;
|
||||
}
|
||||
|
||||
// Print the report of the profiler in a given output stream
|
||||
void Profiler::printReport(std::ostream& outputStream) {
|
||||
void Profiler::printReport() {
|
||||
|
||||
// For each destination
|
||||
for (auto it = mDestinations.begin(); it != mDestinations.end(); ++it) {
|
||||
|
||||
ProfileNodeIterator* iterator = Profiler::getIterator();
|
||||
|
||||
// Recursively print the report of each node of the profiler tree
|
||||
printRecursiveNodeReport(iterator, 0, outputStream);
|
||||
printRecursiveNodeReport(iterator, 0, (*it)->getOutputStream());
|
||||
|
||||
// Destroy the iterator
|
||||
destroyIterator(iterator);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all output profiling destinations previously set
|
||||
void Profiler::removeAllDestinations() {
|
||||
|
||||
// Delete all the destinations
|
||||
for (size_t i=0; i<mDestinations.size(); i++) {
|
||||
delete mDestinations[i];
|
||||
}
|
||||
|
||||
mDestinations.clear();
|
||||
}
|
||||
|
||||
// Add a file destination to the profiler
|
||||
void Profiler::addFileDestination(const std::string& filePath, Format format) {
|
||||
|
||||
FileDestination* destination = new FileDestination(filePath, format);
|
||||
mDestinations.add(destination);
|
||||
}
|
||||
|
||||
// Add a stream destination to the profiler
|
||||
void Profiler::addStreamDestination(std::ostream& outputStream, Format format) {
|
||||
|
||||
StreamDestination* destination = new StreamDestination(outputStream, format);
|
||||
mDestinations.add(destination);
|
||||
}
|
||||
|
||||
// Recursively print the report of a given node of the profiler tree
|
||||
|
@ -240,14 +252,14 @@ void Profiler::printRecursiveNodeReport(ProfileNodeIterator* iterator,
|
|||
|
||||
long double parentTime = iterator->isRoot() ? getElapsedTimeSinceStart() :
|
||||
iterator->getCurrentParentTotalTime();
|
||||
long double accumulatedTime = 0.0;
|
||||
long double accumulatedTime = 0.0L;
|
||||
uint nbFrames = Profiler::getNbFrames();
|
||||
for (int i=0; i<spacing; i++) outputStream << " ";
|
||||
outputStream << "---------------" << std::endl;
|
||||
for (int i=0; i<spacing; i++) outputStream << " ";
|
||||
outputStream << "| Profiling : " << iterator->getCurrentParentName() <<
|
||||
" (total running time : " << parentTime << " ms) ---" << std::endl;
|
||||
long double totalTime = 0.0;
|
||||
long double totalTime = 0.0L;
|
||||
|
||||
// Recurse over the children of the current node
|
||||
int nbChildren = 0;
|
||||
|
@ -256,7 +268,7 @@ void Profiler::printRecursiveNodeReport(ProfileNodeIterator* iterator,
|
|||
long double currentTotalTime = iterator->getCurrentTotalTime();
|
||||
accumulatedTime += currentTotalTime;
|
||||
long double fraction = parentTime > std::numeric_limits<long double>::epsilon() ?
|
||||
(currentTotalTime / parentTime) * 100.0 : 0.0;
|
||||
(currentTotalTime / parentTime) * 100.0L : 0.0L;
|
||||
for (int j=0; j<spacing; j++) outputStream << " ";
|
||||
outputStream << "| " << i << " -- " << iterator->getCurrentName() << " : " <<
|
||||
fraction << " % | " << (currentTotalTime / (long double) (nbFrames)) <<
|
||||
|
@ -270,7 +282,7 @@ void Profiler::printRecursiveNodeReport(ProfileNodeIterator* iterator,
|
|||
}
|
||||
for (int i=0; i<spacing; i++) outputStream << " ";
|
||||
long double percentage = parentTime > std::numeric_limits<long double>::epsilon() ?
|
||||
((parentTime - accumulatedTime) / parentTime) * 100.0 : 0.0;
|
||||
((parentTime - accumulatedTime) / parentTime) * 100.0L : 0.0L;
|
||||
long double difference = parentTime - accumulatedTime;
|
||||
outputStream << "| Unaccounted : " << difference << " ms (" << percentage << " %)" << std::endl;
|
||||
|
|
@ -30,7 +30,9 @@
|
|||
|
||||
// Libraries
|
||||
#include "configuration.h"
|
||||
#include "Timer.h"
|
||||
#include "engine/Timer.h"
|
||||
#include <fstream>
|
||||
#include "containers/List.h"
|
||||
|
||||
/// ReactPhysics3D namespace
|
||||
namespace reactphysics3d {
|
||||
|
@ -180,16 +182,102 @@ class ProfileNodeIterator {
|
|||
*/
|
||||
class Profiler {
|
||||
|
||||
public:
|
||||
|
||||
/// Format of the profiling data (text, ...)
|
||||
enum class Format {Text};
|
||||
|
||||
/// Profile destination
|
||||
class Destination {
|
||||
|
||||
public:
|
||||
|
||||
/// Log format (text, ...)
|
||||
Format format;
|
||||
|
||||
/// Constructor
|
||||
Destination(Format logFormat) : format(logFormat) {
|
||||
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
virtual ~Destination() {
|
||||
|
||||
}
|
||||
|
||||
/// Return the current output stream
|
||||
virtual std::ostream& getOutputStream() = 0;
|
||||
};
|
||||
|
||||
/// File destination to output profiling data into a file
|
||||
class FileDestination : public Destination {
|
||||
|
||||
private:
|
||||
|
||||
std::string mFilePath;
|
||||
|
||||
/// Output file stream
|
||||
std::ofstream mFileStream;
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
FileDestination(const std::string& filePath, Format format)
|
||||
:Destination(format), mFilePath(filePath),
|
||||
mFileStream(filePath, std::ios::binary) {
|
||||
|
||||
if(!mFileStream.is_open()) {
|
||||
throw(std::runtime_error("ReactPhysics3D Logger: Unable to open an output stream to file " + mFilePath));
|
||||
}
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
virtual ~FileDestination() override {
|
||||
|
||||
if (mFileStream.is_open()) {
|
||||
|
||||
// Close the stream
|
||||
mFileStream.close();
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the current output stream
|
||||
virtual std::ostream& getOutputStream() override {
|
||||
return mFileStream;
|
||||
}
|
||||
};
|
||||
|
||||
/// Stream destination to output profiling data into a stream
|
||||
class StreamDestination : public Destination {
|
||||
|
||||
private:
|
||||
|
||||
/// Output stream
|
||||
std::ostream& mOutputStream;
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
StreamDestination(std::ostream& outputStream, Format format)
|
||||
:Destination(format), mOutputStream(outputStream) {
|
||||
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
virtual ~StreamDestination() override {
|
||||
|
||||
}
|
||||
|
||||
/// Return the current output stream
|
||||
virtual std::ostream& getOutputStream() override {
|
||||
return mOutputStream;
|
||||
}
|
||||
};
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Profiler name
|
||||
std::string mName;
|
||||
|
||||
/// Total number of profilers
|
||||
static int mNbProfilers;
|
||||
|
||||
/// Root node of the profiler tree
|
||||
ProfileNode mRootNode;
|
||||
|
||||
|
@ -202,8 +290,12 @@ class Profiler {
|
|||
/// Starting profiling time
|
||||
long double mProfilingStartTime;
|
||||
|
||||
/// All the output destinations
|
||||
List<Destination*> mDestinations;
|
||||
|
||||
/// Recursively print the report of a given node of the profiler tree
|
||||
void printRecursiveNodeReport(ProfileNodeIterator* iterator, int spacing, std::ostream& outputStream);
|
||||
void printRecursiveNodeReport(ProfileNodeIterator* iterator, int spacing,
|
||||
std::ostream &outputStream);
|
||||
|
||||
/// Destroy a previously allocated iterator
|
||||
void destroyIterator(ProfileNodeIterator* iterator);
|
||||
|
@ -216,7 +308,7 @@ class Profiler {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
Profiler(std::string name = "");
|
||||
Profiler();
|
||||
|
||||
/// Destructor
|
||||
~Profiler();
|
||||
|
@ -234,12 +326,6 @@ class Profiler {
|
|||
/// Return the number of frames
|
||||
uint getNbFrames();
|
||||
|
||||
/// Get the name of the profiler
|
||||
std::string getName() const;
|
||||
|
||||
/// Set the name of the profiler
|
||||
void setName(std::string name);
|
||||
|
||||
/// Return the elasped time since the start/reset of the profiling
|
||||
long double getElapsedTimeSinceStart();
|
||||
|
||||
|
@ -249,8 +335,17 @@ class Profiler {
|
|||
/// Return an iterator over the profiler tree starting at the root
|
||||
ProfileNodeIterator* getIterator();
|
||||
|
||||
/// Print the report of the profiler in a given output stream
|
||||
void printReport(std::ostream& outputStream);
|
||||
// Add a file destination to the profiler
|
||||
void addFileDestination(const std::string& filePath, Format format);
|
||||
|
||||
// Add a stream destination to the profiler
|
||||
void addStreamDestination(std::ostream& outputStream, Format format);
|
||||
|
||||
/// Remove all logs destination previously set
|
||||
void removeAllDestinations();
|
||||
|
||||
/// Print the report of the profiler in every output destinations
|
||||
void printReport();
|
||||
};
|
||||
|
||||
// Class ProfileSample
|
||||
|
@ -287,7 +382,7 @@ class ProfileSample {
|
|||
};
|
||||
|
||||
// Use this macro to start profile a block of code
|
||||
#define PROFILE(name, profiler) ProfileSample profileSample(name, profiler)
|
||||
#define RP3D_PROFILE(name, profiler) ProfileSample profileSample(name, profiler)
|
||||
|
||||
// Return true if we are at the root of the profiler tree
|
||||
inline bool ProfileNodeIterator::isRoot() {
|
||||
|
@ -374,19 +469,9 @@ inline uint Profiler::getNbFrames() {
|
|||
return mFrameCounter;
|
||||
}
|
||||
|
||||
// Get the name of the profiler
|
||||
inline std::string Profiler::getName() const {
|
||||
return mName;
|
||||
}
|
||||
|
||||
// Set the name of the profiler
|
||||
inline void Profiler::setName(std::string name) {
|
||||
mName = name;
|
||||
}
|
||||
|
||||
// Return the elasped time since the start/reset of the profiling
|
||||
inline long double Profiler::getElapsedTimeSinceStart() {
|
||||
long double currentTime = Timer::getCurrentSystemTime() * 1000.0;
|
||||
long double currentTime = Timer::getCurrentSystemTime() * 1000.0L;
|
||||
return currentTime - mProfilingStartTime;
|
||||
}
|
||||
|
||||
|
@ -412,10 +497,10 @@ inline void Profiler::destroy() {
|
|||
|
||||
}
|
||||
|
||||
#else // In profile is not active
|
||||
#else // If profile is not active
|
||||
|
||||
// Empty macro in case profiling is not active
|
||||
#define PROFILE(name, profiler)
|
||||
#define RP3D_PROFILE(name, profiler)
|
||||
|
||||
#endif
|
||||
|
|
@ -639,7 +639,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
Vector3 localBody1Point(3, 0, 0);
|
||||
|
@ -663,7 +663,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -684,7 +684,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -705,7 +705,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -759,7 +759,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
Vector3 localBody1Point(3, 0, 0);
|
||||
|
@ -783,7 +783,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -804,7 +804,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -825,7 +825,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -869,7 +869,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
localBody1Point = std::sqrt(4.5f) * Vector3(1, -1, 0);
|
||||
|
@ -893,7 +893,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -914,7 +914,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -935,7 +935,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -979,7 +979,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
localBody1Point = std::sqrt(9.0f / 3.0f) * Vector3(1, -1, -1);
|
||||
|
@ -1003,7 +1003,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -1024,7 +1024,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -1045,7 +1045,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -1099,7 +1099,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
Vector3 localBody1Point(0, -3, 0);
|
||||
|
@ -1123,7 +1123,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -1144,7 +1144,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -1165,7 +1165,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -1209,7 +1209,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
localBody1Point = Vector3(3, 0, 0);
|
||||
|
@ -1233,7 +1233,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -1254,7 +1254,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -1275,7 +1275,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -1329,7 +1329,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
Vector3 localBody1Point(3, 0, 0);
|
||||
|
@ -1353,7 +1353,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -1374,7 +1374,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -1395,7 +1395,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -1439,7 +1439,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
localBody1Point = std::sqrt(4.5f) * Vector3(1, -1, 0);
|
||||
|
@ -1463,7 +1463,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -1484,7 +1484,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -1505,7 +1505,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -1549,7 +1549,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
localBody1Point = std::sqrt(9.0f / 3.0f) * Vector3(1, -1, -1);
|
||||
|
@ -1573,7 +1573,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -1594,7 +1594,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -1615,7 +1615,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -1669,7 +1669,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
Vector3 localBody1Point(0, -3, 0);
|
||||
|
@ -1693,7 +1693,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -1714,7 +1714,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -1735,7 +1735,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mSphereBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mSphereBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -1789,7 +1789,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 4);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID();
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
Vector3 localBody1Point1(-3, -2, -2);
|
||||
|
@ -1831,7 +1831,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 4);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1,
|
||||
|
@ -1860,7 +1860,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 4);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1,
|
||||
|
@ -1890,7 +1890,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 4);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1,
|
||||
|
@ -1953,7 +1953,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 4);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID();
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
Vector3 localBody1Point1(-3, -2, -2);
|
||||
|
@ -1995,7 +1995,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 4);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1,
|
||||
|
@ -2024,7 +2024,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 4);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1,
|
||||
|
@ -2054,7 +2054,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 4);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1,
|
||||
|
@ -2117,7 +2117,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 4);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID();
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
Vector3 localBody1Point1(-3, -2, -2);
|
||||
|
@ -2159,7 +2159,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 4);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1,
|
||||
|
@ -2188,7 +2188,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 4);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1,
|
||||
|
@ -2218,7 +2218,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 4);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1,
|
||||
|
@ -2281,7 +2281,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID();
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
Vector3 localBody1Point1(3, 1, 0);
|
||||
|
@ -2304,7 +2304,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1,
|
||||
|
@ -2325,7 +2325,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1,
|
||||
|
@ -2346,7 +2346,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1,
|
||||
|
@ -2400,7 +2400,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID();
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
Vector3 localBody1Point1(3, 1, 0);
|
||||
|
@ -2423,7 +2423,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1,
|
||||
|
@ -2444,7 +2444,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1,
|
||||
|
@ -2465,7 +2465,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point1 : localBody1Point1,
|
||||
|
@ -2519,7 +2519,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 4);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID();
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId();
|
||||
|
||||
for (int i=0; i<collisionData->contactManifolds[0].contactPoints.size(); i++) {
|
||||
test(approxEqual(collisionData->contactManifolds[0].contactPoints[i].penetrationDepth, 1.0f));
|
||||
|
@ -2539,7 +2539,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 4);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId();
|
||||
|
||||
for (int i=0; i<collisionData->contactManifolds[0].contactPoints.size(); i++) {
|
||||
test(approxEqual(collisionData->contactManifolds[0].contactPoints[i].penetrationDepth, 1.0f));
|
||||
|
@ -2559,7 +2559,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 4);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId();
|
||||
|
||||
for (int i=0; i<collisionData->contactManifolds[0].contactPoints.size(); i++) {
|
||||
test(approxEqual(collisionData->contactManifolds[0].contactPoints[i].penetrationDepth, 1.0f));
|
||||
|
@ -2579,7 +2579,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 4);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mBoxBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mBoxBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
for (int i=0; i<collisionData->contactManifolds[0].contactPoints.size(); i++) {
|
||||
|
@ -2633,7 +2633,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 4);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID();
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId();
|
||||
|
||||
for (int i=0; i<collisionData->contactManifolds[0].contactPoints.size(); i++) {
|
||||
test(approxEqual(collisionData->contactManifolds[0].contactPoints[i].penetrationDepth, 1.0f));
|
||||
|
@ -2653,7 +2653,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 4);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId();
|
||||
|
||||
for (int i=0; i<collisionData->contactManifolds[0].contactPoints.size(); i++) {
|
||||
test(approxEqual(collisionData->contactManifolds[0].contactPoints[i].penetrationDepth, 1.0f));
|
||||
|
@ -2673,7 +2673,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 4);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId();
|
||||
|
||||
for (int i=0; i<collisionData->contactManifolds[0].contactPoints.size(); i++) {
|
||||
test(approxEqual(collisionData->contactManifolds[0].contactPoints[i].penetrationDepth, 1.0f));
|
||||
|
@ -2693,7 +2693,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 4);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mConvexMeshBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mConvexMeshBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
for (int i=0; i<collisionData->contactManifolds[0].contactPoints.size(); i++) {
|
||||
|
@ -2747,7 +2747,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID();
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
Vector3 localBody1Point(2, 3, 0);
|
||||
|
@ -2771,7 +2771,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -2792,7 +2792,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -2813,7 +2813,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -2857,7 +2857,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
localBody1Point = Vector3(0, 5, 0);
|
||||
|
@ -2881,7 +2881,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -2902,7 +2902,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -2923,7 +2923,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -2977,7 +2977,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID();
|
||||
bool swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
Vector3 localBody1Point(0, -5, 0);
|
||||
|
@ -3001,7 +3001,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -3022,7 +3022,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
@ -3043,7 +3043,7 @@ class TestCollisionWorld : public Test {
|
|||
test(collisionData->getTotalNbContactPoints() == 1);
|
||||
|
||||
// True if the bodies are swapped in the collision callback response
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getID() != mCapsuleBody1->getID();
|
||||
swappedBodiesCollisionData = collisionData->getBody1()->getId() != mCapsuleBody1->getId();
|
||||
|
||||
// Test contact points
|
||||
test(collisionData->hasContactPointSimilarTo(swappedBodiesCollisionData ? localBody2Point : localBody1Point,
|
||||
|
|
|
@ -63,7 +63,7 @@ class WorldRaycastCallback : public RaycastCallback {
|
|||
|
||||
virtual decimal notifyRaycastHit(const RaycastInfo& info) override {
|
||||
|
||||
if (shapeToTest->getBody()->getID() == info.body->getID()) {
|
||||
if (shapeToTest->getBody()->getId() == info.body->getId()) {
|
||||
raycastInfo.body = info.body;
|
||||
raycastInfo.hitFraction = info.hitFraction;
|
||||
raycastInfo.proxyShape = info.proxyShape;
|
||||
|
@ -1303,14 +1303,12 @@ class TestRaycast : public Test {
|
|||
Vector3 point2 = mLocalShapeToWorld * Vector3(1, 2, -4);
|
||||
Ray ray(point1, point2);
|
||||
Vector3 hitPoint = mLocalShapeToWorld * Vector3(1, 2, 4);
|
||||
Transform inverse = mLocalShapeToWorld.getInverse();
|
||||
|
||||
mCallback.shapeToTest = mConvexMeshProxyShape;
|
||||
|
||||
// CollisionWorld::raycast()
|
||||
mCallback.reset();
|
||||
mWorld->raycast(ray, &mCallback);
|
||||
Vector3 localTest = inverse * mCallback.raycastInfo.worldPoint;
|
||||
test(mCallback.isHit);
|
||||
test(mCallback.raycastInfo.body == mConvexMeshBody);
|
||||
test(mCallback.raycastInfo.proxyShape == mConvexMeshProxyShape);
|
||||
|
|
|
@ -255,16 +255,3 @@ void Box::createVBOAndVAO() {
|
|||
// Unbind the VAO
|
||||
mVAO.unbind();
|
||||
}
|
||||
|
||||
// Set the scaling of the object
|
||||
void Box::setScaling(const openglframework::Vector3& scaling) {
|
||||
|
||||
// Scale the collision shape
|
||||
mProxyShape->setLocalScaling(rp3d::Vector3(scaling.x, scaling.y, scaling.z));
|
||||
|
||||
// Scale the graphics object
|
||||
mScalingMatrix = openglframework::Matrix4(mSize[0] * scaling.x, 0, 0, 0,
|
||||
0, mSize[1] * scaling.y, 0, 0,
|
||||
0, 0, mSize[2] * scaling.z, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
|
|
@ -88,9 +88,6 @@ class Box : public PhysicsObject {
|
|||
|
||||
/// Update the transform matrix of the object
|
||||
virtual void updateTransform(float interpolationFactor) override;
|
||||
|
||||
/// Set the scaling of the object
|
||||
void setScaling(const openglframework::Vector3& scaling) override;
|
||||
};
|
||||
|
||||
// Update the transform matrix of the object
|
||||
|
|
|
@ -235,16 +235,3 @@ void Capsule::createVBOAndVAO() {
|
|||
// Unbind the VAO
|
||||
mVAO.unbind();
|
||||
}
|
||||
|
||||
// Set the scaling of the object
|
||||
void Capsule::setScaling(const openglframework::Vector3& scaling) {
|
||||
|
||||
// Scale the collision shape
|
||||
mProxyShape->setLocalScaling(rp3d::Vector3(scaling.x, scaling.y, scaling.z));
|
||||
|
||||
// Scale the graphics object
|
||||
mScalingMatrix = openglframework::Matrix4(mRadius * scaling.x, 0, 0, 0,
|
||||
0, (mHeight * scaling.y + 2.0f * mRadius * scaling.x) / 3, 0,0,
|
||||
0, 0, mRadius * scaling.x, 0,
|
||||
0, 0, 0, 1.0f);
|
||||
}
|
||||
|
|
|
@ -96,9 +96,6 @@ class Capsule : public PhysicsObject {
|
|||
|
||||
/// Update the transform matrix of the object
|
||||
virtual void updateTransform(float interpolationFactor) override;
|
||||
|
||||
/// Set the scaling of the object
|
||||
void setScaling(const openglframework::Vector3& scaling) override;
|
||||
};
|
||||
|
||||
// Update the transform matrix of the object
|
||||
|
|
|
@ -244,17 +244,3 @@ void ConcaveMesh::createVBOAndVAO() {
|
|||
// Unbind the VAO
|
||||
mVAO.unbind();
|
||||
}
|
||||
|
||||
// Set the scaling of the object
|
||||
void ConcaveMesh::setScaling(const openglframework::Vector3& scaling) {
|
||||
|
||||
// Scale the collision shape
|
||||
mProxyShape->setLocalScaling(rp3d::Vector3(scaling.x, scaling.y, scaling.z));
|
||||
|
||||
// Scale the graphics object
|
||||
mScalingMatrix = openglframework::Matrix4(scaling.x, 0, 0, 0,
|
||||
0, scaling.y, 0,0,
|
||||
0, 0, scaling.z, 0,
|
||||
0, 0, 0, 1.0f);
|
||||
}
|
||||
|
||||
|
|
|
@ -90,9 +90,6 @@ class ConcaveMesh : public PhysicsObject {
|
|||
|
||||
/// Update the transform matrix of the object
|
||||
virtual void updateTransform(float interpolationFactor) override;
|
||||
|
||||
/// Set the scaling of the object
|
||||
void setScaling(const openglframework::Vector3& scaling) override;
|
||||
};
|
||||
|
||||
// Update the transform matrix of the object
|
||||
|
|
|
@ -254,16 +254,3 @@ void ConvexMesh::createVBOAndVAO() {
|
|||
// Unbind the VAO
|
||||
mVAO.unbind();
|
||||
}
|
||||
|
||||
// Set the scaling of the object
|
||||
void ConvexMesh::setScaling(const openglframework::Vector3& scaling) {
|
||||
|
||||
// Scale the collision shape
|
||||
mProxyShape->setLocalScaling(rp3d::Vector3(scaling.x, scaling.y, scaling.z));
|
||||
|
||||
// Scale the graphics object
|
||||
mScalingMatrix = openglframework::Matrix4(scaling.x, 0, 0, 0,
|
||||
0, scaling.y, 0, 0,
|
||||
0, 0, scaling.z, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
|
|
@ -92,9 +92,6 @@ class ConvexMesh : public PhysicsObject {
|
|||
|
||||
/// Update the transform matrix of the object
|
||||
virtual void updateTransform(float interpolationFactor) override;
|
||||
|
||||
/// Set the scaling of the object
|
||||
void setScaling(const openglframework::Vector3& scaling) override;
|
||||
};
|
||||
|
||||
// Update the transform matrix of the object
|
||||
|
|
|
@ -272,30 +272,3 @@ void Dumbbell::createVBOAndVAO() {
|
|||
// Unbind the VAO
|
||||
mVAO.unbind();
|
||||
}
|
||||
|
||||
// Set the scaling of the object
|
||||
void Dumbbell::setScaling(const openglframework::Vector3& scaling) {
|
||||
|
||||
// Scale the collision shape
|
||||
rp3d::Vector3 newScaling(scaling.x, scaling.y, scaling.z);
|
||||
mProxyShapeCapsule->setLocalScaling(newScaling);
|
||||
mProxyShapeSphere1->setLocalScaling(newScaling);
|
||||
mProxyShapeSphere2->setLocalScaling(newScaling);
|
||||
|
||||
mDistanceBetweenSphere = (mDistanceBetweenSphere / mScalingMatrix.getValue(1, 1)) * scaling.y;
|
||||
|
||||
// Initial transform of the first sphere collision shape of the dumbbell (in local-space)
|
||||
rp3d::Transform transformSphereShape1(rp3d::Vector3(0, mDistanceBetweenSphere / 2.0f, 0), rp3d::Quaternion::identity());
|
||||
|
||||
// Initial transform of the second sphere collision shape of the dumbell (in local-space)
|
||||
rp3d::Transform transformSphereShape2(rp3d::Vector3(0, -mDistanceBetweenSphere / 2.0f, 0), rp3d::Quaternion::identity());
|
||||
|
||||
mProxyShapeSphere1->setLocalToBodyTransform(transformSphereShape1);
|
||||
mProxyShapeSphere2->setLocalToBodyTransform(transformSphereShape2);
|
||||
|
||||
// Scale the graphics object
|
||||
mScalingMatrix = openglframework::Matrix4(scaling.x, 0, 0, 0,
|
||||
0, scaling.y, 0, 0,
|
||||
0, 0, scaling.z, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
|
|
@ -95,9 +95,6 @@ class Dumbbell : public PhysicsObject {
|
|||
|
||||
/// Update the transform matrix of the object
|
||||
virtual void updateTransform(float interpolationFactor) override;
|
||||
|
||||
/// Set the scaling of the object
|
||||
void setScaling(const openglframework::Vector3& scaling) override;
|
||||
};
|
||||
|
||||
// Update the transform matrix of the object
|
||||
|
|
|
@ -303,16 +303,3 @@ void HeightField::createVBOAndVAO() {
|
|||
// Unbind the VAO
|
||||
mVAO.unbind();
|
||||
}
|
||||
|
||||
// Set the scaling of the object
|
||||
void HeightField::setScaling(const openglframework::Vector3& scaling) {
|
||||
|
||||
// Scale the collision shape
|
||||
mProxyShape->setLocalScaling(rp3d::Vector3(scaling.x, scaling.y, scaling.z));
|
||||
|
||||
// Scale the graphics object
|
||||
mScalingMatrix = openglframework::Matrix4(scaling.x, 0, 0, 0,
|
||||
0, scaling.y, 0,0,
|
||||
0, 0, scaling.z, 0,
|
||||
0, 0, 0, 1.0f);
|
||||
}
|
||||
|
|
|
@ -103,9 +103,6 @@ class HeightField : public PhysicsObject {
|
|||
|
||||
/// Update the transform matrix of the object
|
||||
virtual void updateTransform(float interpolationFactor) override;
|
||||
|
||||
/// Set the scaling of the object
|
||||
void setScaling(const openglframework::Vector3& scaling) override;
|
||||
};
|
||||
|
||||
// Update the transform matrix of the object
|
||||
|
|
|
@ -82,9 +82,6 @@ class PhysicsObject : public openglframework::Mesh {
|
|||
|
||||
/// Return a pointer to the rigid body of the box
|
||||
reactphysics3d::RigidBody* getRigidBody();
|
||||
|
||||
/// Set the scaling of the object
|
||||
virtual void setScaling(const openglframework::Vector3& scaling)=0;
|
||||
};
|
||||
|
||||
// Set the color of the box
|
||||
|
|
|
@ -234,16 +234,3 @@ void Sphere::createVBOAndVAO() {
|
|||
// Unbind the VAO
|
||||
mVAO.unbind();
|
||||
}
|
||||
|
||||
// Set the scaling of the object
|
||||
void Sphere::setScaling(const openglframework::Vector3& scaling) {
|
||||
|
||||
// Scale the collision shape
|
||||
mProxyShape->setLocalScaling(rp3d::Vector3(scaling.x, scaling.y, scaling.z));
|
||||
|
||||
// Scale the graphics object
|
||||
mScalingMatrix = openglframework::Matrix4(mRadius * scaling.x, 0, 0, 0,
|
||||
0, mRadius * scaling.y, 0, 0,
|
||||
0, 0, mRadius * scaling.z, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
|
|
@ -92,9 +92,6 @@ class Sphere : public PhysicsObject {
|
|||
|
||||
/// Update the transform matrix of the object
|
||||
virtual void updateTransform(float interpolationFactor) override;
|
||||
|
||||
/// Set the scaling of the object
|
||||
void setScaling(const openglframework::Vector3& scaling) override;
|
||||
};
|
||||
|
||||
// Update the transform matrix of the object
|
||||
|
|
|
@ -46,14 +46,11 @@ CollisionDetectionScene::CollisionDetectionScene(const std::string& name, Engine
|
|||
// Set the center of the scene
|
||||
setScenePosition(center, SCENE_RADIUS);
|
||||
|
||||
rp3d::WorldSettings worldSettings;
|
||||
worldSettings.worldName = name;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mPhysicsWorld = new rp3d::CollisionWorld();
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
mPhysicsWorld->setProfilerName(name + "_profiler");
|
||||
|
||||
#endif
|
||||
mPhysicsWorld = new rp3d::CollisionWorld(worldSettings);
|
||||
|
||||
// ---------- Sphere 1 ---------- //
|
||||
|
||||
|
|
|
@ -45,15 +45,11 @@ CollisionShapesScene::CollisionShapesScene(const std::string& name, EngineSettin
|
|||
// Gravity vector in the dynamics world
|
||||
rp3d::Vector3 gravity(0, -9.81f, 0);
|
||||
|
||||
rp3d::WorldSettings worldSettings;
|
||||
worldSettings.worldName = name;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity);
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
mPhysicsWorld->setProfilerName(name + "_profiler");
|
||||
|
||||
#endif
|
||||
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
|
||||
for (int i=0; i<NB_COMPOUND_SHAPES; i++) {
|
||||
|
||||
|
|
|
@ -45,14 +45,11 @@ ConcaveMeshScene::ConcaveMeshScene(const std::string& name, EngineSettings& sett
|
|||
// Gravity vector in the dynamics world
|
||||
rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
|
||||
|
||||
rp3d::WorldSettings worldSettings;
|
||||
worldSettings.worldName = name;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity);
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
mPhysicsWorld->setProfilerName(name + "_profiler");
|
||||
|
||||
#endif
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
|
||||
// ---------- Create the boxes ----------- //
|
||||
for (int i = 0; i<NB_COMPOUND_SHAPES; i++) {
|
||||
|
|
|
@ -43,14 +43,11 @@ CubesScene::CubesScene(const std::string& name, EngineSettings& settings)
|
|||
// Gravity vector in the dynamics world
|
||||
rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
|
||||
|
||||
rp3d::WorldSettings worldSettings;
|
||||
worldSettings.worldName = name;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity);
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
mPhysicsWorld->setProfilerName(name + "_profiler");
|
||||
|
||||
#endif
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
|
||||
// Create all the cubes of the scene
|
||||
for (int i=0; i<NB_CUBES; i++) {
|
||||
|
|
|
@ -43,14 +43,11 @@ CubeStackScene::CubeStackScene(const std::string& name, EngineSettings& settings
|
|||
// Gravity vector in the dynamics world
|
||||
rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
|
||||
|
||||
rp3d::WorldSettings worldSettings;
|
||||
worldSettings.worldName = name;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity);
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
mPhysicsWorld->setProfilerName(name + "_profiler");
|
||||
|
||||
#endif
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
|
||||
// Create all the cubes of the scene
|
||||
for (int i=1; i<=NB_FLOORS; i++) {
|
||||
|
|
|
@ -45,15 +45,11 @@ HeightFieldScene::HeightFieldScene(const std::string& name, EngineSettings& sett
|
|||
// Gravity vector in the dynamics world
|
||||
rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
|
||||
|
||||
rp3d::WorldSettings worldSettings;
|
||||
worldSettings.worldName = name;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity);
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
mPhysicsWorld->setProfilerName(name + "_profiler");
|
||||
|
||||
#endif
|
||||
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
|
||||
for (int i = 0; i<NB_COMPOUND_SHAPES; i++) {
|
||||
|
||||
|
|
|
@ -44,14 +44,11 @@ JointsScene::JointsScene(const std::string& name, EngineSettings& settings)
|
|||
// Gravity vector in the dynamics world
|
||||
rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
|
||||
|
||||
rp3d::WorldSettings worldSettings;
|
||||
worldSettings.worldName = name;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity);
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
mPhysicsWorld->setProfilerName(name + "_profiler");
|
||||
|
||||
#endif
|
||||
mPhysicsWorld = new rp3d::DynamicsWorld(gravity, worldSettings);
|
||||
|
||||
// Create the Ball-and-Socket joint
|
||||
createBallAndSocketJoints();
|
||||
|
|
|
@ -44,14 +44,11 @@ RaycastScene::RaycastScene(const std::string& name, EngineSettings& settings)
|
|||
// Set the center of the scene
|
||||
setScenePosition(center, SCENE_RADIUS);
|
||||
|
||||
rp3d::WorldSettings worldSettings;
|
||||
worldSettings.worldName = name;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mPhysicsWorld = new rp3d::CollisionWorld();
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
mPhysicsWorld->setProfilerName(name + "_profiler");
|
||||
|
||||
#endif
|
||||
mPhysicsWorld = new rp3d::CollisionWorld(worldSettings);
|
||||
|
||||
// ---------- Dumbbell ---------- //
|
||||
|
||||
|
|
|
@ -170,6 +170,7 @@ void Gui::createSettingsPanel() {
|
|||
checkboxSleeping->setChecked(mApp->mEngineSettings.isSleepingEnabled);
|
||||
checkboxSleeping->setCallback([&](bool value) {
|
||||
mApp->mEngineSettings.isSleepingEnabled = value;
|
||||
mApp->notifyEngineSetttingsChanged();
|
||||
});
|
||||
|
||||
// Enabled/Disable Gravity
|
||||
|
@ -177,6 +178,7 @@ void Gui::createSettingsPanel() {
|
|||
checkboxGravity->setChecked(mApp->mEngineSettings.isGravityEnabled);
|
||||
checkboxGravity->setCallback([&](bool value) {
|
||||
mApp->mEngineSettings.isGravityEnabled = value;
|
||||
mApp->notifyEngineSetttingsChanged();
|
||||
});
|
||||
|
||||
// Timestep
|
||||
|
@ -202,6 +204,7 @@ void Gui::createSettingsPanel() {
|
|||
if (finalValue < 1 || finalValue > 1000) return false;
|
||||
|
||||
mApp->mEngineSettings.timeStep = finalValue / 1000.0f;
|
||||
mApp->notifyEngineSetttingsChanged();
|
||||
textboxTimeStep->setValue(out.str());
|
||||
}
|
||||
catch (...) {
|
||||
|
@ -233,6 +236,7 @@ void Gui::createSettingsPanel() {
|
|||
if (value < 1 || value > 1000) return false;
|
||||
|
||||
mApp->mEngineSettings.nbVelocitySolverIterations = value;
|
||||
mApp->notifyEngineSetttingsChanged();
|
||||
textboxVelocityIterations->setValue(out.str());
|
||||
}
|
||||
catch (...) {
|
||||
|
@ -264,6 +268,7 @@ void Gui::createSettingsPanel() {
|
|||
if (value < 1 || value > 1000) return false;
|
||||
|
||||
mApp->mEngineSettings.nbPositionSolverIterations = value;
|
||||
mApp->notifyEngineSetttingsChanged();
|
||||
textboxPositionIterations->setValue(out.str());
|
||||
}
|
||||
catch (...) {
|
||||
|
@ -298,6 +303,7 @@ void Gui::createSettingsPanel() {
|
|||
if (finalValue < 1 || finalValue > 100000) return false;
|
||||
|
||||
mApp->mEngineSettings.timeBeforeSleep = finalValue / 1000.0f;
|
||||
mApp->notifyEngineSetttingsChanged();
|
||||
textboxTimeSleep->setValue(out.str());
|
||||
}
|
||||
catch (...) {
|
||||
|
@ -332,6 +338,7 @@ void Gui::createSettingsPanel() {
|
|||
if (finalValue < 0 || finalValue > 10000) return false;
|
||||
|
||||
mApp->mEngineSettings.sleepLinearVelocity = finalValue;
|
||||
mApp->notifyEngineSetttingsChanged();
|
||||
textboxSleepLinearVel->setValue(out.str());
|
||||
}
|
||||
catch (...) {
|
||||
|
@ -366,6 +373,7 @@ void Gui::createSettingsPanel() {
|
|||
if (finalValue < 0 || finalValue > 10000) return false;
|
||||
|
||||
mApp->mEngineSettings.sleepAngularVelocity = finalValue;
|
||||
mApp->notifyEngineSetttingsChanged();
|
||||
textboxSleepAngularVel->setValue(out.str());
|
||||
}
|
||||
catch (...) {
|
||||
|
|
|
@ -232,6 +232,9 @@ class Scene {
|
|||
|
||||
/// Return all the contact points of the scene
|
||||
std::vector<ContactPoint> virtual getContactPoints();
|
||||
|
||||
/// Update the engine settings
|
||||
virtual void updateEngineSettings() = 0;
|
||||
};
|
||||
|
||||
// Called when a keyboard event occurs
|
||||
|
|
|
@ -123,18 +123,6 @@ void SceneDemo::updatePhysics() {
|
|||
|
||||
if (getDynamicsWorld() != nullptr) {
|
||||
|
||||
// Update the physics engine parameters
|
||||
getDynamicsWorld()->setIsGratityEnabled(mEngineSettings.isGravityEnabled);
|
||||
rp3d::Vector3 gravity(mEngineSettings.gravity.x, mEngineSettings.gravity.y,
|
||||
mEngineSettings.gravity.z);
|
||||
getDynamicsWorld()->setGravity(gravity);
|
||||
getDynamicsWorld()->enableSleeping(mEngineSettings.isSleepingEnabled);
|
||||
getDynamicsWorld()->setSleepLinearVelocity(mEngineSettings.sleepLinearVelocity);
|
||||
getDynamicsWorld()->setSleepAngularVelocity(mEngineSettings.sleepAngularVelocity);
|
||||
getDynamicsWorld()->setNbIterationsPositionSolver(mEngineSettings.nbPositionSolverIterations);
|
||||
getDynamicsWorld()->setNbIterationsVelocitySolver(mEngineSettings.nbVelocitySolverIterations);
|
||||
getDynamicsWorld()->setTimeBeforeSleep(mEngineSettings.timeBeforeSleep);
|
||||
|
||||
// Take a simulation step
|
||||
getDynamicsWorld()->update(mEngineSettings.timeStep);
|
||||
}
|
||||
|
@ -448,3 +436,22 @@ std::vector<ContactPoint> SceneDemo::computeContactPointsOfWorld(rp3d::DynamicsW
|
|||
|
||||
return contactPoints;
|
||||
}
|
||||
|
||||
// Update the engine settings
|
||||
void SceneDemo::updateEngineSettings() {
|
||||
|
||||
if (getDynamicsWorld() != nullptr) {
|
||||
|
||||
// Update the physics engine parameters
|
||||
getDynamicsWorld()->setIsGratityEnabled(mEngineSettings.isGravityEnabled);
|
||||
rp3d::Vector3 gravity(mEngineSettings.gravity.x, mEngineSettings.gravity.y,
|
||||
mEngineSettings.gravity.z);
|
||||
getDynamicsWorld()->setGravity(gravity);
|
||||
getDynamicsWorld()->enableSleeping(mEngineSettings.isSleepingEnabled);
|
||||
getDynamicsWorld()->setSleepLinearVelocity(mEngineSettings.sleepLinearVelocity);
|
||||
getDynamicsWorld()->setSleepAngularVelocity(mEngineSettings.sleepAngularVelocity);
|
||||
getDynamicsWorld()->setNbIterationsPositionSolver(mEngineSettings.nbPositionSolverIterations);
|
||||
getDynamicsWorld()->setNbIterationsVelocitySolver(mEngineSettings.nbVelocitySolverIterations);
|
||||
getDynamicsWorld()->setTimeBeforeSleep(mEngineSettings.timeBeforeSleep);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,6 +151,9 @@ class SceneDemo : public Scene {
|
|||
/// Render the scene (possibly in multiple passes for shadow mapping)
|
||||
virtual void render() override;
|
||||
|
||||
/// Update the engine settings
|
||||
virtual void updateEngineSettings() override;
|
||||
|
||||
/// Render the scene in a single pass
|
||||
virtual void renderSinglePass(openglframework::Shader& shader, const openglframework::Matrix4& worldToCameraMatrix);
|
||||
|
||||
|
|
|
@ -271,9 +271,16 @@ void TestbedApplication::switchScene(Scene* newScene) {
|
|||
// Reset the scene
|
||||
mCurrentScene->reset();
|
||||
|
||||
mCurrentScene->updateEngineSettings();
|
||||
|
||||
resizeEvent(Vector2i(0, 0));
|
||||
}
|
||||
|
||||
// Notify that the engine settings have changed
|
||||
void TestbedApplication::notifyEngineSetttingsChanged() {
|
||||
mCurrentScene->updateEngineSettings();
|
||||
}
|
||||
|
||||
// Check the OpenGL errors
|
||||
void TestbedApplication::checkOpenGLErrorsInternal(const char* file, int line) {
|
||||
GLenum glError;
|
||||
|
|
|
@ -199,6 +199,9 @@ class TestbedApplication : public Screen {
|
|||
/// Enable/Disable Vertical synchronization
|
||||
void enableVSync(bool enable);
|
||||
|
||||
/// Notify that the engine settings have changed
|
||||
void notifyEngineSetttingsChanged();
|
||||
|
||||
// -------------------- Friendship -------------------- //
|
||||
|
||||
friend class Gui;
|
||||
|
|
Loading…
Reference in New Issue
Block a user