diff --git a/src/body/Body.h b/src/body/Body.h index dbacc55d..337b9df1 100644 --- a/src/body/Body.h +++ b/src/body/Body.h @@ -218,11 +218,14 @@ inline void Body::setIsSleeping(bool isSleeping) { } } - mIsSleeping = isSleeping; + if (mIsSleeping != isSleeping) { - RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, + 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 diff --git a/src/body/CollisionBody.cpp b/src/body/CollisionBody.cpp index f7e7fe1d..62c035ff 100644 --- a/src/body/CollisionBody.cpp +++ b/src/body/CollisionBody.cpp @@ -109,6 +109,10 @@ ProxyShape* CollisionBody::addCollisionShape(CollisionShape* collisionShape, 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; } diff --git a/src/body/RigidBody.cpp b/src/body/RigidBody.cpp index 3791c9d9..4a05010b 100644 --- a/src/body/RigidBody.cpp +++ b/src/body/RigidBody.cpp @@ -310,6 +310,10 @@ ProxyShape* RigidBody::addCollisionShape(CollisionShape* collisionShape, 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; } diff --git a/src/collision/shapes/BoxShape.h b/src/collision/shapes/BoxShape.h index b1128582..7e5fba31 100644 --- a/src/collision/shapes/BoxShape.h +++ b/src/collision/shapes/BoxShape.h @@ -231,7 +231,7 @@ inline Vector3 BoxShape::getCentroid() const { // Return the string representation of the shape inline std::string BoxShape::to_string() const { - return "BoxShape {extents=" + mExtent.to_string() + "}"; + return "BoxShape{extents=" + mExtent.to_string() + "}"; } // Return the number of half-edges of the polyhedron diff --git a/src/collision/shapes/CapsuleShape.h b/src/collision/shapes/CapsuleShape.h index decf6474..c595da77 100644 --- a/src/collision/shapes/CapsuleShape.h +++ b/src/collision/shapes/CapsuleShape.h @@ -178,7 +178,7 @@ 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()) + "}"; + return "CapsuleShape{halfHeight=" + std::to_string(mHalfHeight) + ", radius=" + std::to_string(getRadius()) + "}"; } } diff --git a/src/collision/shapes/ConcaveMeshShape.cpp b/src/collision/shapes/ConcaveMeshShape.cpp index a6cfcb9c..21677154 100644 --- a/src/collision/shapes/ConcaveMeshShape.cpp +++ b/src/collision/shapes/ConcaveMeshShape.cpp @@ -221,7 +221,7 @@ std::string ConcaveMeshShape::to_string() const { std::stringstream ss; - ss << "ConcaveMeshShape {" << std::endl; + ss << "ConcaveMeshShape{" << std::endl; ss << "nbSubparts=" << mTriangleMesh->getNbSubparts() << std::endl; // Vertices array diff --git a/src/collision/shapes/ConvexMeshShape.cpp b/src/collision/shapes/ConvexMeshShape.cpp index 3dadfee4..01cb9dc6 100644 --- a/src/collision/shapes/ConvexMeshShape.cpp +++ b/src/collision/shapes/ConvexMeshShape.cpp @@ -206,7 +206,7 @@ bool ConvexMeshShape::testPointInside(const Vector3& localPoint, ProxyShape* pro std::string ConvexMeshShape::to_string() const { std::stringstream ss; - ss << "ConvexMeshShape {" << std::endl; + ss << "ConvexMeshShape{" << std::endl; ss << "nbVertices=" << mPolyhedronMesh->getNbVertices() << std::endl; ss << "nbFaces=" << mPolyhedronMesh->getNbFaces() << std::endl; diff --git a/src/collision/shapes/HeightFieldShape.cpp b/src/collision/shapes/HeightFieldShape.cpp index 0136c881..37d73005 100644 --- a/src/collision/shapes/HeightFieldShape.cpp +++ b/src/collision/shapes/HeightFieldShape.cpp @@ -303,16 +303,16 @@ std::string HeightFieldShape::to_string() const { std::stringstream ss; - ss << "HeightFieldShape {" << std::endl; + 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 << ", 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/SphereShape.h b/src/collision/shapes/SphereShape.h index 01e2001e..baebf6e1 100644 --- a/src/collision/shapes/SphereShape.h +++ b/src/collision/shapes/SphereShape.h @@ -175,7 +175,7 @@ inline bool SphereShape::testPointInside(const Vector3& localPoint, ProxyShape* // Return the string representation of the shape inline std::string SphereShape::to_string() const { - return "SphereShape { radius=" + std::to_string(getRadius()) + "}"; + return "SphereShape{radius=" + std::to_string(getRadius()) + "}"; } } diff --git a/src/collision/shapes/TriangleShape.h b/src/collision/shapes/TriangleShape.h index 23a55c38..87ae5398 100644 --- a/src/collision/shapes/TriangleShape.h +++ b/src/collision/shapes/TriangleShape.h @@ -317,7 +317,7 @@ inline void TriangleShape::setRaycastTestType(TriangleRaycastSide 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() + "," + + return "TriangleShape{v1=" + mPoints[0].to_string() + ", v2=" + mPoints[1].to_string() + "," + "v3=" + mPoints[2].to_string() + "}"; } diff --git a/src/constraint/BallAndSocketJoint.h b/src/constraint/BallAndSocketJoint.h index ed66320f..33260bfb 100644 --- a/src/constraint/BallAndSocketJoint.h +++ b/src/constraint/BallAndSocketJoint.h @@ -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 diff --git a/src/constraint/FixedJoint.h b/src/constraint/FixedJoint.h index 45fe1185..bc472cfa 100644 --- a/src/constraint/FixedJoint.h +++ b/src/constraint/FixedJoint.h @@ -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 diff --git a/src/constraint/HingeJoint.cpp b/src/constraint/HingeJoint.cpp index 990e7be1..bccd0cb1 100644 --- a/src/constraint/HingeJoint.cpp +++ b/src/constraint/HingeJoint.cpp @@ -42,8 +42,8 @@ HingeJoint::HingeJoint(uint id, const HingeJointInfo& jointInfo) 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(); diff --git a/src/constraint/HingeJoint.h b/src/constraint/HingeJoint.h index fbcfeacf..435064d2 100644 --- a/src/constraint/HingeJoint.h +++ b/src/constraint/HingeJoint.h @@ -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") + "}"; +} + } diff --git a/src/constraint/Joint.h b/src/constraint/Joint.h index 10d1680e..92c413da 100644 --- a/src/constraint/Joint.h +++ b/src/constraint/Joint.h @@ -204,6 +204,9 @@ class Joint { /// Return the id of the joint uint getId() const; + /// Return a string representation + virtual std::string to_string() const=0; + // -------------------- Friendship -------------------- // friend class DynamicsWorld; diff --git a/src/constraint/SliderJoint.cpp b/src/constraint/SliderJoint.cpp index 174ddb67..839cc4dc 100644 --- a/src/constraint/SliderJoint.cpp +++ b/src/constraint/SliderJoint.cpp @@ -41,9 +41,9 @@ SliderJoint::SliderJoint(uint id, 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(); diff --git a/src/constraint/SliderJoint.h b/src/constraint/SliderJoint.h index 3fd0035e..e6ae05dd 100644 --- a/src/constraint/SliderJoint.h +++ b/src/constraint/SliderJoint.h @@ -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 diff --git a/src/engine/DynamicsWorld.cpp b/src/engine/DynamicsWorld.cpp index 8fb71e08..8f06ca74 100644 --- a/src/engine/DynamicsWorld.cpp +++ b/src/engine/DynamicsWorld.cpp @@ -548,11 +548,13 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) { // Add the joint into the world mJoints.add(newJoint); - // Add the joint into the joint list of the bodies involved in the joint - addJointToBody(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); // Return the pointer to the created joint return newJoint; @@ -614,12 +616,20 @@ 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 diff --git a/src/utils/Logger.cpp b/src/utils/Logger.cpp index 9410cc29..2b213020 100644 --- a/src/utils/Logger.cpp +++ b/src/utils/Logger.cpp @@ -96,11 +96,15 @@ void Logger::log(Level level, Category category, const std::string& message) { 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 diff --git a/src/utils/Logger.h b/src/utils/Logger.h index 8ce51fb3..879909c7 100644 --- a/src/utils/Logger.h +++ b/src/utils/Logger.h @@ -35,6 +35,7 @@ #include #include #include +#include /// ReactPhysics3D namespace namespace reactphysics3d { @@ -140,7 +141,21 @@ class Logger { /// Format a log message virtual std::string format(const time_t& time, const std::string& message, Level level, Category category) override { - return message; + 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(); } }; @@ -186,7 +201,7 @@ class Logger { std::string generateCSS() const { return "body {" - " background-color: #f7f7f9;" + " background-color: #e6e6e6;" " font-family: SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace; " "} " "body > div { clear:both; } " @@ -222,16 +237,16 @@ class Logger { "max-width: 800px; " "} " ".body > .category, .body > .message { " - "color: #8bc34a;" + "color: #00994d;" "} " ".world > .category, .world > .message { " - "color: #4f9fcf; " + "color: #3477DB; " "} " ".joint .category, .joint > .message { " - "color: #aa00ff; " + "color: #bf8040; " "} " ".proxyshape .category, .proxyshape > .message { " - "color: #009933; " + "color: #9933ff; " "} " ".warning { " "color: #ff9900 !important; " @@ -392,8 +407,7 @@ class Logger { /// Write a message into the output stream virtual void write(const time_t& time, const std::string& message, Level level, Category category) override { - mOutputStream << std::put_time(std::localtime(&time), "%Y-%m-%d %X") << ": "; - mOutputStream << message << std::endl << std::flush; + mOutputStream << formatter->format(time, message, level, category) << std::endl << std::flush; } }; @@ -408,6 +422,9 @@ class Logger { /// Map a log format to the given formatter object Map mFormatters; + /// Mutex + std::mutex mMutex; + // -------------------- Methods -------------------- // /// Return the corresponding formatter