From 1bc50de2c930e1cdb8a061c5cfa6205877ed2d31 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Mon, 19 Mar 2018 23:02:13 +0100 Subject: [PATCH] Working on logger --- src/body/Body.h | 34 +++++++++ src/body/CollisionBody.cpp | 27 +++++-- src/body/CollisionBody.h | 7 ++ src/body/RigidBody.cpp | 34 ++++++++- src/body/RigidBody.h | 13 ++++ src/collision/CollisionDetection.cpp | 30 ++++---- src/collision/CollisionDetection.h | 4 +- src/collision/ProxyShape.h | 48 ++++++++++++ src/collision/TriangleVertexArray.cpp | 52 +++++++++++++ src/collision/TriangleVertexArray.h | 6 ++ .../broadphase/BroadPhaseAlgorithm.cpp | 10 +-- .../broadphase/BroadPhaseAlgorithm.h | 6 +- src/collision/shapes/BoxShape.h | 8 ++ src/collision/shapes/CapsuleShape.h | 8 ++ src/collision/shapes/CollisionShape.h | 3 + src/collision/shapes/ConcaveMeshShape.cpp | 65 ++++++++++++++++ src/collision/shapes/ConcaveMeshShape.h | 4 + src/collision/shapes/ConvexMeshShape.cpp | 44 +++++++++++ src/collision/shapes/ConvexMeshShape.h | 3 + src/collision/shapes/HeightFieldShape.cpp | 20 +++++ src/collision/shapes/HeightFieldShape.h | 3 + src/collision/shapes/SphereShape.h | 8 ++ src/collision/shapes/TriangleShape.h | 9 +++ src/configuration.h | 28 +++++++ src/engine/CollisionWorld.cpp | 22 ++++-- src/engine/DynamicsWorld.cpp | 24 +++--- src/engine/DynamicsWorld.h | 14 ++-- src/engine/Material.h | 15 ++++ src/engine/OverlappingPair.h | 8 +- src/utils/Logger.h | 75 ++++++++++++++----- 30 files changed, 551 insertions(+), 81 deletions(-) diff --git a/src/body/Body.h b/src/body/Body.h index 4a46e83f..dbacc55d 100644 --- a/src/body/Body.h +++ b/src/body/Body.h @@ -30,6 +30,7 @@ #include #include #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 -------------------- // @@ -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; @@ -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 @@ -198,6 +219,10 @@ inline void Body::setIsSleeping(bool 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 +241,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); diff --git a/src/body/CollisionBody.cpp b/src/body/CollisionBody.cpp index bb8b0408..f7e7fe1d 100644 --- a/src/body/CollisionBody.cpp +++ b/src/body/CollisionBody.cpp @@ -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,9 @@ 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"); + // Return a pointer to the collision shape return proxyShape; } @@ -114,11 +124,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 +151,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 +177,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 +222,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 +263,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 +273,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 diff --git a/src/body/CollisionBody.h b/src/body/CollisionBody.h index 2520cab4..e98b9a7d 100644 --- a/src/body/CollisionBody.h +++ b/src/body/CollisionBody.h @@ -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 diff --git a/src/body/RigidBody.cpp b/src/body/RigidBody.cpp index ab4b0c8e..3791c9d9 100644 --- a/src/body/RigidBody.cpp +++ b/src/body/RigidBody.cpp @@ -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,9 @@ 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"); + // Return a pointer to the proxy collision shape return proxyShape; } @@ -324,6 +346,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 +367,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 +395,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 @@ -469,7 +500,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 +525,3 @@ void RigidBody::setProfiler(Profiler* profiler) { } #endif - diff --git a/src/body/RigidBody.h b/src/body/RigidBody.h index 22c784ef..ad794513 100644 --- a/src/body/RigidBody.h +++ b/src/body/RigidBody.h @@ -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 diff --git a/src/collision/CollisionDetection.cpp b/src/collision/CollisionDetection.cpp index dc2272f9..f56672ca 100644 --- a/src/collision/CollisionDetection.cpp +++ b/src/collision/CollisionDetection.cpp @@ -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 @@ -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, 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 @@ -637,10 +637,10 @@ 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 overlappingNodes(mMemoryManager.getPoolAllocator()); @@ -817,10 +817,10 @@ 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 overlappingNodes(mMemoryManager.getPoolAllocator()); @@ -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()); } diff --git a/src/collision/CollisionDetection.h b/src/collision/CollisionDetection.h index d8f5240a..ecfa766d 100644 --- a/src/collision/CollisionDetection.h +++ b/src/collision/CollisionDetection.h @@ -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()); } } diff --git a/src/collision/ProxyShape.h b/src/collision/ProxyShape.h index 0da79e28..61118d45 100644 --- a/src/collision/ProxyShape.h +++ b/src/collision/ProxyShape.h @@ -93,6 +93,12 @@ class ProxyShape { #endif +#ifdef IS_LOGGING_ACTIVE + + /// Logger + Logger* mLogger; +#endif + // -------------------- Methods -------------------- // /// Return the collision shape @@ -175,6 +181,9 @@ class ProxyShape { /// 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 /// Set the profiler @@ -182,6 +191,12 @@ class ProxyShape { #endif +#ifdef IS_LOGGING_ACTIVE + + /// Set the logger + void setLogger(Logger* logger); +#endif + // -------------------- Friendship -------------------- // friend class OverlappingPair; @@ -265,6 +280,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 +335,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,6 +355,10 @@ 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 @@ -348,6 +375,8 @@ inline Vector3 ProxyShape::getLocalScaling() const { */ inline void ProxyShape::setLocalScaling(const Vector3& scaling) { + // TODO : Do not use a local of the collision shape in case of shared collision shapes + // Set the local scaling of the collision shape mCollisionShape->setLocalScaling(scaling); @@ -355,6 +384,15 @@ inline void ProxyShape::setLocalScaling(const Vector3& scaling) { // 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 localScaling=" + + mCollisionShape->getLocalScaling().to_string()); +} + +// Return the broad-phase id +inline int ProxyShape::getBroadPhaseId() const { + return mBroadPhaseID; } /// Test if the proxy shape overlaps with a given AABB @@ -378,6 +416,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 diff --git a/src/collision/TriangleVertexArray.cpp b/src/collision/TriangleVertexArray.cpp index 7cfb2076..a54ad425 100644 --- a/src/collision/TriangleVertexArray.cpp +++ b/src/collision/TriangleVertexArray.cpp @@ -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(vertexPointerChar); + + // Get the vertices components of the triangle + if (mVertexDataType == TriangleVertexArray::VertexDataType::VERTEX_FLOAT_TYPE) { + const float* vertices = static_cast(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(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(vertexNormalPointerChar); + + // Get the normals from the array + if (mVertexNormaldDataType == TriangleVertexArray::NormalDataType::NORMAL_FLOAT_TYPE) { + const float* normal = static_cast(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(vertexNormalPointer); + (*outNormal)[0] = decimal(normal[0]); + (*outNormal)[1] = decimal(normal[1]); + (*outNormal)[2] = decimal(normal[2]); + } + else { + assert(false); + } +} diff --git a/src/collision/TriangleVertexArray.h b/src/collision/TriangleVertexArray.h index 3a48c2e3..4fe2fe07 100644 --- a/src/collision/TriangleVertexArray.h +++ b/src/collision/TriangleVertexArray.h @@ -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 diff --git a/src/collision/broadphase/BroadPhaseAlgorithm.cpp b/src/collision/broadphase/BroadPhaseAlgorithm.cpp index fbad0cfd..0d722a0a 100644 --- a/src/collision/broadphase/BroadPhaseAlgorithm.cpp +++ b/src/collision/broadphase/BroadPhaseAlgorithm.cpp @@ -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); diff --git a/src/collision/broadphase/BroadPhaseAlgorithm.h b/src/collision/broadphase/BroadPhaseAlgorithm.h index df642677..4e8360b9 100644 --- a/src/collision/broadphase/BroadPhaseAlgorithm.h +++ b/src/collision/broadphase/BroadPhaseAlgorithm.h @@ -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); diff --git a/src/collision/shapes/BoxShape.h b/src/collision/shapes/BoxShape.h index 2ebcdce1..0c261a6f 100644 --- a/src/collision/shapes/BoxShape.h +++ b/src/collision/shapes/BoxShape.h @@ -123,6 +123,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 @@ -237,6 +240,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; diff --git a/src/collision/shapes/CapsuleShape.h b/src/collision/shapes/CapsuleShape.h index 7843f139..6a58f115 100644 --- a/src/collision/shapes/CapsuleShape.h +++ b/src/collision/shapes/CapsuleShape.h @@ -105,6 +105,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 @@ -185,6 +188,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 diff --git a/src/collision/shapes/CollisionShape.h b/src/collision/shapes/CollisionShape.h index 3fdf4470..a7b07fc3 100644 --- a/src/collision/shapes/CollisionShape.h +++ b/src/collision/shapes/CollisionShape.h @@ -138,6 +138,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 diff --git a/src/collision/shapes/ConcaveMeshShape.cpp b/src/collision/shapes/ConcaveMeshShape.cpp index 768f7c2e..bde756e4 100644 --- a/src/collision/shapes/ConcaveMeshShape.cpp +++ b/src/collision/shapes/ConcaveMeshShape.cpp @@ -214,3 +214,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; subPartgetNbSubparts(); 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; vgetNbVertices(); 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; vgetNbVertices(); 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; triangleIndexgetNbTriangles(); triangleIndex++) { + + uint indices[3]; + + triangleVertexArray->getTriangleVerticesIndices(triangleIndex, indices); + + ss << "(" << indices[0] << "," << indices[1] << "," << indices[2] << "), "; + } + + ss << "], " << std::endl; + + ss << "}" << std::endl; + } + + return ss.str(); +} diff --git a/src/collision/shapes/ConcaveMeshShape.h b/src/collision/shapes/ConcaveMeshShape.h index d35c9d23..ccafbba9 100644 --- a/src/collision/shapes/ConcaveMeshShape.h +++ b/src/collision/shapes/ConcaveMeshShape.h @@ -186,6 +186,9 @@ class ConcaveMeshShape : public ConcaveShape { /// 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 @@ -277,6 +280,7 @@ inline void ConcaveMeshShape::setProfiler(Profiler* profiler) { mDynamicAABBTree.setProfiler(profiler); } + #endif } diff --git a/src/collision/shapes/ConvexMeshShape.cpp b/src/collision/shapes/ConvexMeshShape.cpp index d4037a8c..1c47b4d9 100644 --- a/src/collision/shapes/ConvexMeshShape.cpp +++ b/src/collision/shapes/ConvexMeshShape.cpp @@ -201,3 +201,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(); +} + diff --git a/src/collision/shapes/ConvexMeshShape.h b/src/collision/shapes/ConvexMeshShape.h index 49d3f773..ebec6a09 100644 --- a/src/collision/shapes/ConvexMeshShape.h +++ b/src/collision/shapes/ConvexMeshShape.h @@ -130,6 +130,9 @@ class ConvexMeshShape : 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; }; /// Set the scaling vector of the collision shape diff --git a/src/collision/shapes/HeightFieldShape.cpp b/src/collision/shapes/HeightFieldShape.cpp index df2019c0..0b3a4044 100644 --- a/src/collision/shapes/HeightFieldShape.cpp +++ b/src/collision/shapes/HeightFieldShape.cpp @@ -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(); +} diff --git a/src/collision/shapes/HeightFieldShape.h b/src/collision/shapes/HeightFieldShape.h index 7b834e2b..e796e208 100644 --- a/src/collision/shapes/HeightFieldShape.h +++ b/src/collision/shapes/HeightFieldShape.h @@ -209,6 +209,9 @@ class HeightFieldShape : public ConcaveShape { /// 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; diff --git a/src/collision/shapes/SphereShape.h b/src/collision/shapes/SphereShape.h index 90b20d2d..a0010b06 100644 --- a/src/collision/shapes/SphereShape.h +++ b/src/collision/shapes/SphereShape.h @@ -93,6 +93,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 @@ -181,6 +184,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 diff --git a/src/collision/shapes/TriangleShape.h b/src/collision/shapes/TriangleShape.h index 23f26adc..5a5a49b2 100644 --- a/src/collision/shapes/TriangleShape.h +++ b/src/collision/shapes/TriangleShape.h @@ -175,6 +175,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; @@ -325,6 +328,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 diff --git a/src/configuration.h b/src/configuration.h index aa71e88a..aa8a0535 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "decimal.h" #include "containers/Pair.h" @@ -105,6 +106,9 @@ 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. @@ -161,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(); + } }; } diff --git a/src/engine/CollisionWorld.cpp b/src/engine/CollisionWorld.cpp index 1dbf1b6f..d9b5f258 100644 --- a/src/engine/CollisionWorld.cpp +++ b/src/engine/CollisionWorld.cpp @@ -80,7 +80,7 @@ CollisionWorld::CollisionWorld(const WorldSettings& worldSettings, Logger* logge mLogger = new Logger(); // Add a log destination file - uint logLevel = static_cast(Logger::Level::Info) | static_cast(Logger::Level::Warning) | + uint logLevel = static_cast(Logger::Level::Information) | static_cast(Logger::Level::Warning) | static_cast(Logger::Level::Error); mLogger->addFileDestination("rp3d_log_" + mName + ".html", logLevel, Logger::Format::HTML); } @@ -89,14 +89,16 @@ CollisionWorld::CollisionWorld(const WorldSettings& worldSettings, Logger* logge mNbWorlds++; - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + 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::Info, Logger::Category::World, + 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 @@ -154,8 +156,12 @@ CollisionBody* CollisionWorld::createCollisionBody(const Transform& transform) { #endif - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::Body, - "Collision Body " + std::to_string(bodyID) + ": New collision body created"); +#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; @@ -167,8 +173,8 @@ CollisionBody* CollisionWorld::createCollisionBody(const Transform& transform) { */ void CollisionWorld::destroyCollisionBody(CollisionBody* collisionBody) { - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::Body, - "Collision Body " + std::to_string(collisionBody->getId()) + ": collision body destroyed"); + 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(); @@ -253,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(); } diff --git a/src/engine/DynamicsWorld.cpp b/src/engine/DynamicsWorld.cpp index 7164458d..8fb71e08 100644 --- a/src/engine/DynamicsWorld.cpp +++ b/src/engine/DynamicsWorld.cpp @@ -64,7 +64,7 @@ DynamicsWorld::DynamicsWorld(const Vector3& gravity, const WorldSettings& worldS #endif - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, "Dynamics World: Dynamics world " + mName + " has been created"); } @@ -91,7 +91,7 @@ DynamicsWorld::~DynamicsWorld() { mProfiler->printReport(); #endif - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, "Dynamics World: Dynamics world " + mName + " has been destroyed"); } @@ -426,13 +426,15 @@ RigidBody* DynamicsWorld::createRigidBody(const Transform& transform) { mRigidBodies.add(rigidBody); #ifdef IS_PROFILING_ACTIVE - rigidBody->setProfiler(mProfiler); - #endif - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::Body, - "Rigid Body " + std::to_string(bodyID) + ": New collision body created"); +#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; @@ -444,8 +446,8 @@ RigidBody* DynamicsWorld::createRigidBody(const Transform& transform) { */ void DynamicsWorld::destroyRigidBody(RigidBody* rigidBody) { - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::Body, - "Rigid Body " + std::to_string(rigidBody->getId()) + ": rigid body destroyed"); + 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(); @@ -549,7 +551,7 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) { // Add the joint into the joint list of the bodies involved in the joint addJointToBody(newJoint); - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::Joint, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Joint, "Joint " + std::to_string(newJoint->getId()) + ": New joint created"); // Return the pointer to the created joint @@ -564,7 +566,7 @@ void DynamicsWorld::destroyJoint(Joint* joint) { assert(joint != nullptr); - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::Joint, + 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 @@ -863,7 +865,7 @@ void DynamicsWorld::enableSleeping(bool isSleepingEnabled) { } } - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, "Dynamics World: isSleepingEnabled=" + (isSleepingEnabled ? std::string("true") : std::string("false")) ); } diff --git a/src/engine/DynamicsWorld.h b/src/engine/DynamicsWorld.h index f435f4b9..53ef8d9e 100644 --- a/src/engine/DynamicsWorld.h +++ b/src/engine/DynamicsWorld.h @@ -283,7 +283,7 @@ inline uint DynamicsWorld::getNbIterationsVelocitySolver() const { inline void DynamicsWorld::setNbIterationsVelocitySolver(uint nbIterations) { mNbVelocitySolverIterations = nbIterations; - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, "Dynamics World: Set nb iterations velocity solver to " + std::to_string(nbIterations)); } @@ -299,7 +299,7 @@ inline uint DynamicsWorld::getNbIterationsPositionSolver() const { inline void DynamicsWorld::setNbIterationsPositionSolver(uint nbIterations) { mNbPositionSolverIterations = nbIterations; - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, "Dynamics World: Set nb iterations position solver to " + std::to_string(nbIterations)); } @@ -346,7 +346,7 @@ inline Vector3 DynamicsWorld::getGravity() const { inline void DynamicsWorld::setGravity(Vector3& gravity) { mGravity = gravity; - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, "Dynamics World: Set gravity vector to " + gravity.to_string()); } @@ -366,7 +366,7 @@ inline bool DynamicsWorld::isGravityEnabled() const { inline void DynamicsWorld::setIsGratityEnabled(bool isGravityEnabled) { mIsGravityEnabled = isGravityEnabled; - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, "Dynamics World: isGravityEnabled= " + (isGravityEnabled ? std::string("true") : std::string("false"))); } @@ -413,7 +413,7 @@ inline void DynamicsWorld::setSleepLinearVelocity(decimal sleepLinearVelocity) { assert(sleepLinearVelocity >= decimal(0.0)); mSleepLinearVelocity = sleepLinearVelocity; - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, "Dynamics World: sleepLinearVelocity= " + std::to_string(sleepLinearVelocity)); } @@ -436,7 +436,7 @@ inline void DynamicsWorld::setSleepAngularVelocity(decimal sleepAngularVelocity) assert(sleepAngularVelocity >= decimal(0.0)); mSleepAngularVelocity = sleepAngularVelocity; - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, "Dynamics World: sleepAngularVelocity= " + std::to_string(sleepAngularVelocity)); } @@ -457,7 +457,7 @@ inline void DynamicsWorld::setTimeBeforeSleep(decimal timeBeforeSleep) { assert(timeBeforeSleep >= decimal(0.0)); mTimeBeforeSleep = timeBeforeSleep; - RP3D_LOG(mLogger, Logger::Level::Info, Logger::Category::World, + RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World, "Dynamics World: timeBeforeSleep= " + std::to_string(timeBeforeSleep)); } diff --git a/src/engine/Material.h b/src/engine/Material.h index d55724a1..ffe6b1e9 100644 --- a/src/engine/Material.h +++ b/src/engine/Material.h @@ -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) { diff --git a/src/engine/OverlappingPair.h b/src/engine/OverlappingPair.h index 3fa083a1..a16ea84e 100644 --- a/src/engine/OverlappingPair.h +++ b/src/engine/OverlappingPair.h @@ -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; } diff --git a/src/utils/Logger.h b/src/utils/Logger.h index 908da806..8ce51fb3 100644 --- a/src/utils/Logger.h +++ b/src/utils/Logger.h @@ -49,10 +49,10 @@ class Logger { public: /// Log verbosity levels - enum class Level {Error = 1, Warning = 2, Info = 4}; + enum class Level {Error = 1, Warning = 2, Information = 4}; /// Log categories - enum class Category {World, Body, Joint}; + enum class Category {World, Body, Joint, ProxyShape}; /// Log verbosity level enum class Format {Text, HTML}; @@ -64,6 +64,7 @@ class Logger { case Category::World: return "World"; case Category::Body: return "Body"; case Category::Joint: return "Joint"; + case Category::ProxyShape: return "ProxyShape"; } } @@ -71,7 +72,7 @@ class Logger { static std::string getLevelName(Level level) { switch(level) { - case Level::Info: return "Information"; + case Level::Information: return "Information"; case Level::Warning: return "Warning"; case Level::Error: return "Error"; } @@ -120,6 +121,22 @@ class Logger { } + /// 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 { @@ -134,8 +151,11 @@ class Logger { /// Return the header to write at the beginning of the stream virtual std::string getHeader() const override { - std::stringstream ss; + // Get current date + auto now = std::chrono::system_clock::now(); + auto time = std::chrono::system_clock::to_time_t(now); + std::stringstream ss; ss << "" << std::endl; ss << "" << std::endl; ss << "" << std::endl; @@ -143,6 +163,12 @@ class Logger { ss << "" << std::endl; ss << "" << std::endl; ss << "" << std::endl; + ss << "

ReactPhysics3D Logs

" << std::endl; + ss << "
" << 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; + ss << "
"; return ss.str(); } @@ -161,26 +187,33 @@ class Logger { std::string generateCSS() const { return "body {" " background-color: #f7f7f9;" + " 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-family: SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace; " "font-size: 13px; " "color: #212529; " "margin: 0px 5px 2px 5px; " "} " ".time { " - "margin-right: 10px; " - "width:100px; " + "margin-right: 20px; " + "width:80px; " "} " ".level { " - "margin-right: 10px; " - "width: 110px; " + "margin-right: 20px; " + "width: 90px; " "}" ".category { " - "margin-right: 10px; " - "width: 120px; " + "margin-right: 20px; " + "width: 100px; " "font-weight: bold; " "}" ".message { " @@ -188,20 +221,23 @@ class Logger { "word-wrap: break-word; " "max-width: 800px; " "} " - ".body > .category { " - "color: #007bff; " + ".body > .category, .body > .message { " + "color: #8bc34a;" "} " - ".world > .category { " + ".world > .category, .world > .message { " "color: #4f9fcf; " "} " - ".joint > .category { " - "color: #6c757d; " + ".joint .category, .joint > .message { " + "color: #aa00ff; " + "} " + ".proxyshape .category, .proxyshape > .message { " + "color: #009933; " "} " ".warning { " - "color: #f0ad4e; " + "color: #ff9900 !important; " "} " ".error { " - "color: #d44950; " + "color: red !important; " "} "; } @@ -248,7 +284,8 @@ class Logger { ss << ""; // Message - ss << "
"; + ss << "
" << std::endl; ss << message; ss << "
";