### Install ReactPhysics3D with make (Linux/macOS) Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Install the compiled ReactPhysics3D library on Linux or macOS using 'sudo make install'. This places library and header files in standard system locations. ```bash sudo make install ``` -------------------------------- ### Example CMakeLists.txt for Hello World Project Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md This is a complete example CMakeLists.txt file for a 'Hello World' project demonstrating how to integrate ReactPhysics3D. ```cmake # Minimum cmake version required cmake_minimum_required(VERSION 3.8) # Help CMake to find the installed library on Windows or Mac OS X if(WIN32) list(APPEND CMAKE_PREFIX_PATH "C:\\Program Files (x86)\\ReactPhysics3D") elseif(APPLE) list(APPEND CMAKE_PREFIX_PATH "/usr/local/lib/cmake/ReactPhysics3D") endif() # Import the ReactPhysics3D library find_package(ReactPhysics3D REQUIRED) # Project project(HelloWorld) # Create the executable add_executable(helloworld Main.cpp) ``` -------------------------------- ### Hello World Project Implementation Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md A complete example demonstrating physics world creation, rigid body initialization, and simulation stepping. ```cpp // Libraries #include #include // ReactPhysics3D namespace using namespace reactphysics3d; // Main function int main(int argc, char** argv) { // First you need to create the PhysicsCommon object. // This is a factory module that you can use to create physics // world and other objects. It is also responsible for // logging and memory management PhysicsCommon physicsCommon; // Create a physics world PhysicsWorld* world = physicsCommon.createPhysicsWorld(); // Create a rigid body in the world Vector3 position(0, 20, 0); Quaternion orientation = Quaternion::identity(); Transform transform(position, orientation); RigidBody* body = world->createRigidBody(transform); const decimal timeStep = 1.0f / 60.0f; // Step the simulation a few steps for (int i=0; i < 20; i++) { world->update(timeStep); // Get the updated position of the body const Transform& transform = body->getTransform(); const Vector3& position = transform.getPosition(); // Display the position of the body std::cout << "Body Position: (" << position.x << ", " << position.y << ", " << position.z << ")" << std::endl; } return 0; } ``` -------------------------------- ### Implement Falling Boxes Simulation Source: https://context7.com/danielchappuis/reactphysics3d/llms.txt A complete example demonstrating the initialization of a physics world, creation of static and dynamic bodies, and the execution of a simulation loop. ```cpp #include #include using namespace reactphysics3d; int main() { // Create physics common (factory) PhysicsCommon physicsCommon; // Create world with custom settings PhysicsWorld::WorldSettings settings; settings.gravity = Vector3(0, -9.81f, 0); PhysicsWorld* world = physicsCommon.createPhysicsWorld(settings); // Create ground (static box) BoxShape* groundShape = physicsCommon.createBoxShape(Vector3(10.0f, 0.5f, 10.0f)); RigidBody* ground = world->createRigidBody(Transform(Vector3(0, -0.5f, 0), Quaternion::identity())); ground->setType(BodyType::STATIC); ground->addCollider(groundShape, Transform::identity()); // Create falling boxes BoxShape* boxShape = physicsCommon.createBoxShape(Vector3(0.5f, 0.5f, 0.5f)); std::vector boxes; for (int i = 0; i < 5; i++) { Vector3 position(0, 2.0f + i * 1.5f, 0); RigidBody* box = world->createRigidBody(Transform(position, Quaternion::identity())); box->setType(BodyType::DYNAMIC); Collider* collider = box->addCollider(boxShape, Transform::identity()); collider->getMaterial().setBounciness(0.3f); collider->getMaterial().setFrictionCoefficient(0.5f); box->updateMassPropertiesFromColliders(); boxes.push_back(box); } // Simulation loop const decimal timeStep = 1.0f / 60.0f; for (int frame = 0; frame < 300; frame++) { // 5 seconds world->update(timeStep); // Print positions every 60 frames (1 second) if (frame % 60 == 0) { std::cout << "Frame " << frame << ":" << std::endl; for (size_t i = 0; i < boxes.size(); i++) { const Vector3& pos = boxes[i]->getTransform().getPosition(); std::cout << " Box " << i << ": (" << pos.x << ", " << pos.y << ", " << pos.z << ")" << std::endl; } } } // Cleanup physicsCommon.destroyPhysicsWorld(world); return 0; } ``` -------------------------------- ### Physics Simulation Loop with Interpolation Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md A complete simulation loop example demonstrating physics updates, time accumulation, and transform interpolation for rendering. ```cpp // Constant physics time step const float timeStep = 1.0 / 60.0; // Get the current system time long double currentFrameTime = getCurrentSystemTime(); // Compute the time difference between the two frames long double deltaTime = currentFrameTime - previousFrameTime; // Update the previous time previousFrameTime = currentFrameTime; // Add the time difference in the accumulator accumulator += mDeltaTime; // While there is enough accumulated time to take // one or several physics steps while (accumulator >= timeStep) { // Update the physics world with a constant time step physicsWorld->update(timeStep); // Decrease the accumulated time accumulator -= timeStep; } // Compute the time interpolation factor decimal factor = accumulator / timeStep; // Get the updated transform of the body Transform currTransform = body->getTransform(); // Compute the interpolated transform of the rigid body Transform interpolatedTransform = Transform::interpolateTransforms(prevTransform, currTransform, factor); // Now you can render your body using the interpolated transform here // Update the previous transform prevTransform = currTranform; ``` -------------------------------- ### Configure CMake for ReactPhysics3D Source: https://github.com/danielchappuis/reactphysics3d/blob/master/helloworld/CMakeLists.txt This CMakeLists.txt file sets up a project to use the ReactPhysics3D library. It includes logic to help CMake find the installed library on Windows and macOS, defines the project, creates an executable, and links it with the ReactPhysics3D library. ```cmake cmake_minimum_required(VERSION 3.8) # Help CMake to find the installed library on Windows if(WIN32) list(APPEND CMAKE_PREFIX_PATH "C:\\Program Files (x86)\\ReactPhysics3D") list(APPEND CMAKE_PREFIX_PATH "C:\\Program Files\\ReactPhysics3D") elseif(APPLE) list(APPEND CMAKE_PREFIX_PATH "/usr/local/lib/cmake/ReactPhysics3D") endif() # Import the ReactPhysics3D library that you have installed on your computer using # the "make install" command find_package(ReactPhysics3D REQUIRED) # Project project(HelloWorld) # Create the executable add_executable(helloworld Main.cpp) # Link with the ReactPhysics3D library target_link_libraries(helloworld ReactPhysics3D::ReactPhysics3D) ``` -------------------------------- ### Create a Ray Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Define a ray by specifying its start and end points in world-space coordinates. ```cpp // Start and end points of the ray Vector3 startPoint(0.0, 5.0, 1.0); Vector3 endPoint(0.0, 5.0, 30); // Create the ray Ray ray(startPoint, endPoint); ``` -------------------------------- ### Find ReactPhysics3D Package Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Use this line in your CMakeLists.txt to find the installed ReactPhysics3D library and import its files. ```cmake find_package(ReactPhysics3D REQUIRED) ``` -------------------------------- ### Configure Library Path for Windows/Mac Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md On Windows or Mac OS X, you may need to add this code before find_package to help CMake locate the installed ReactPhysics3D library. ```cmake if(WIN32) list(APPEND CMAKE_PREFIX_PATH "C:\\Program Files (x86)\\ReactPhysics3D") elseif(APPLE) list(APPEND CMAKE_PREFIX_PATH "/usr/local/lib/cmake/ReactPhysics3D") endif() ``` -------------------------------- ### Create and Configure Default Logger Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md This snippet demonstrates how to create a default logger, set the log level to warnings and errors, and configure it to output logs in HTML to a file and in raw text to the standard output. Finally, it sets the configured logger for the physics common instance. ```cpp // Create the default logger DefaultLogger* logger = physicsCommon.createDefaultLogger(); // Log level (warnings and errors) uint logLevel = static_cast(static_cast(Logger::Level::Warning) | static_cast(Logger::Level::Error); // Output the logs into an HTML file logger->addFileDestination("rp3d_log_" + name + ".html", logLevel, DefaultLogger::Format::HTML); // Output the logs into the standard output logger->addStreamDestination(std::cout, logLevel, DefaultLogger::Format::Text); // Set the logger physicsCommon.setLogger(logger); ``` -------------------------------- ### Create Physics World Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Basic initialization of a physics world instance. ```cpp // Create the physics world PhysicsWorld* world = physicsCommon.createPhysicsWorld(); ``` -------------------------------- ### Build ReactPhysics3D with Visual Studio (Windows) Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Compile the ReactPhysics3D library on Windows using Visual Studio. Open the generated .sln file, set the build mode to 'Release', and build the 'reactphysics' project. ```csharp Build ``` -------------------------------- ### Create Physics Objects Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Demonstrates the instantiation of a physics world and a rigid body using the PhysicsCommon object. ```cpp // Create a physics world PhysicsWorld* world = physicsCommon.createPhysicsWorld(); ... // Create a rigid body RigidBody* body = world->createRigidBody(transform); ``` -------------------------------- ### Create HeightField Instance Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Demonstrates initializing a HeightField with height data and processing potential creation messages. ```cpp const int nbRows = 40; const int nbColumns = 50; float minHeight = 100; float maxHeight = 500; // Height values float heightValues[nbRows * nbColumns] = ...; std::vector messages; HeightField* heightField = physicsCommon.createHeightField(NB_POINTS_WIDTH, NB_POINTS_LENGTH, heightValues, rp3d::HeightField::HeightDataType::HEIGHT_FLOAT_TYPE, messages); // Display the messages (info, warning and errors) if (messages.size() > 0) { for (const rp3d::Message& message: messages) { std::string messageType; switch(message.type) { case rp3d::Message::Type::Information: messageType = "info"; break; case rp3d::Message::Type::Warning: messageType = "warning"; break; case rp3d::Message::Type::Error: messageType = "error"; break; } std::cout << "Message (" << messageType << "): " << message.text << std::endl; } } // Make sure there was no errors during the height field creation assert(heightField != nullptr); ``` -------------------------------- ### Initialize PhysicsCommon and Create World Source: https://context7.com/danielchappuis/reactphysics3d/llms.txt Instantiate PhysicsCommon as the central factory object. Use it to create physics worlds and collision shapes. Remember to destroy the world when done. ```cpp #include using namespace reactphysics3d; // Create the main PhysicsCommon object (required first step) PhysicsCommon physicsCommon; // Create a physics world with default settings PhysicsWorld* world = physicsCommon.createPhysicsWorld(); // Create collision shapes using the factory SphereShape* sphereShape = physicsCommon.createSphereShape(2.0f); BoxShape* boxShape = physicsCommon.createBoxShape(Vector3(1.0f, 2.0f, 3.0f)); CapsuleShape* capsuleShape = physicsCommon.createCapsuleShape(1.0f, 2.0f); // Cleanup: destroy the physics world when done physicsCommon.destroyPhysicsWorld(world); ``` -------------------------------- ### Clone the ReactPhysics3D Repository Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Use this command to download the source code repository from GitHub. ```bash git clone https://github.com/DanielChappuis/reactphysics3d.git ``` -------------------------------- ### Initialize PhysicsCommon Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Instantiate the PhysicsCommon object to manage memory and factory operations. ```cpp // First you need to create the PhysicsCommon object. PhysicsCommon physicsCommon; ``` -------------------------------- ### Create and Configure RigidBody Source: https://context7.com/danielchappuis/reactphysics3d/llms.txt Initializes a rigid body with a transform and configures its physical properties such as mass, damping, and gravity. ```cpp // Create a rigid body at a specific position Vector3 position(0.0f, 10.0f, 0.0f); Quaternion orientation = Quaternion::identity(); Transform transform(position, orientation); RigidBody* body = world->createRigidBody(transform); // Set body type (STATIC, KINEMATIC, or DYNAMIC) body->setType(BodyType::DYNAMIC); // Default // Configure mass properties body->setMass(5.0f); // 5 kg // Or compute mass from colliders (after adding colliders) body->updateMassFromColliders(); body->updateLocalCenterOfMassFromColliders(); body->updateLocalInertiaTensorFromColliders(); // Or all at once: body->updateMassPropertiesFromColliders(); // Disable gravity for this specific body body->enableGravity(false); // Set velocity damping (air friction) body->setLinearDamping(0.1f); body->setAngularDamping(0.1f); // Prevent sleeping for always-active objects body->setIsAllowedToSleep(false); // Destroy when no longer needed world->destroyRigidBody(body); ``` -------------------------------- ### Build ReactPhysics3D with make (Linux/macOS) Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Compile the ReactPhysics3D library on Linux or macOS using the 'make' command. Ensure you are in the directory where native build tool files were generated. ```bash make ``` -------------------------------- ### Configure Physics World Settings Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Customizes physics world behavior by passing a WorldSettings object during creation. ```cpp // Create the world settings PhysicsWorld::WorldSettings settings; settings.defaultVelocitySolverNbIterations = 20; settings.isSleepingEnabled = false; settings.gravity = Vector3(0, -9.81, 0); // Create the physics world with your settings PhysicsWorld* world = physicsCommon.createPhysicsWorld(settings); ``` -------------------------------- ### Configure CMake via Command Line Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Run this command within a dedicated build directory to launch the CMake configuration interface. ```bash ccmake path_to_library_source ``` -------------------------------- ### Create Physics World Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Use the PhysicsCommon instance to create a new physics world. ```cpp // Create a physics world PhysicsWorld* world = physicsCommon.createPhysicsWorld(); ``` -------------------------------- ### Create a Rigid Body Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Initializes a rigid body with a specific position and orientation using the PhysicsWorld::createRigidBody method. ```cpp // Initial position and orientation of the rigid body Vector3 position(0.0, 3.0, 0.0); Quaternion orientation = Quaternion::identity(); Transform transform(position, orientation); // Create a rigid body in the world RigidBody* body = world->createRigidBody(transform); ``` -------------------------------- ### Advance Physics Simulation with update() Source: https://context7.com/danielchappuis/reactphysics3d/llms.txt Step the physics simulation using a fixed time step within a game loop. Accumulate frame time and interpolate for smooth rendering. ```cpp // Constant physics time step (60 Hz) const float timeStep = 1.0f / 60.0f; float accumulator = 0.0f; float previousFrameTime = getCurrentTime(); // Game loop while (running) { float currentFrameTime = getCurrentTime(); float deltaTime = currentFrameTime - previousFrameTime; previousFrameTime = currentFrameTime; accumulator += deltaTime; // Process physics in fixed time steps while (accumulator >= timeStep) { world->update(timeStep); accumulator -= timeStep; } // Interpolate for rendering float factor = accumulator / timeStep; Transform interpolated = Transform::interpolateTransforms(prevTransform, body->getTransform(), factor); // Get OpenGL matrix for rendering float matrix[16]; interpolated.getOpenGLMatrix(matrix); } ``` -------------------------------- ### Include ReactPhysics3D Header Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Include the main header file to access library functionality. ```cpp // Include the main ReactPhysics3D header file #include ``` -------------------------------- ### Use ReactPhysics3D Namespace Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Declare the namespace to simplify access to library classes. ```cpp // Use the ReactPhysics3D namespace using namespace reactphysics3d; ``` -------------------------------- ### Apply Forces and Torques to Rigid Bodies in C++ Source: https://context7.com/danielchappuis/reactphysics3d/llms.txt Illustrates applying various forces and torques to dynamic rigid bodies to control their movement. Includes applying forces at different points and setting velocities directly. Motion can be restricted using lock axis factors. ```cpp RigidBody* body = world->createRigidBody(Transform::identity()); body->setType(BodyType::DYNAMIC); body->setMass(10.0f); // Apply force at center of mass (no torque generated) Vector3 force(100.0f, 0.0f, 0.0f); // 100 Newtons in X direction body->applyForceToCenterOfMass(force); // Apply force at a world position (generates torque if not at COM) Vector3 forcePoint(0.0f, 50.0f, 0.0f); Vector3 worldPoint(1.0f, 2.0f, 0.0f); body->applyForceAtWorldPosition(forcePoint, worldPoint); // Apply force at local position Vector3 localPoint(0.5f, 0.0f, 0.0f); body->applyForceAtLocalPosition(force, localPoint); // Apply torque directly (Newton-meters) Vector3 torque(0.0f, 50.0f, 0.0f); // Rotate around Y axis body->applyTorque(torque); // Set velocities directly body->setLinearVelocity(Vector3(5.0f, 0.0f, 0.0f)); body->setAngularVelocity(Vector3(0.0f, 1.0f, 0.0f)); // Restrict motion to specific axes body->setLinearLockAxisFactor(Vector3(1, 0, 1)); // Disable Y movement body->setAngularLockAxisFactor(Vector3(0, 1, 0)); // Only allow Y rotation ``` -------------------------------- ### Create TriangleVertexArray and TriangleMesh Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md This snippet demonstrates creating a TriangleVertexArray with vertex and index data, then using it to create a TriangleMesh. It also shows how to process messages returned during mesh creation. Ensure vertices are in counter-clockwise order. The TriangleVertexArray can be released after TriangleMesh creation. ```cpp // Create the TriangleVertexArray const int nbVertices = 8; const int nbTriangles = 12; float vertices[3 * nbVertices] = ...; int indices[3 * nbTriangles] = ...; TriangleVertexArray* triangleArray = new TriangleVertexArray(nbVertices, vertices, 3 * sizeof(float), nbTriangles, indices, 3 * sizeof(int), TriangleVertexArray::VertexDataType::VERTEX_FLOAT_TYPE, TriangleVertexArray::IndexDataType::INDEX_INTEGER_TYPE); // Create the TriangleMesh std::vector messages; TriangleMesh* triangleMesh = physicsCommon.createTriangleMesh(vertexArray, messages); // Display the messages (info, warning and errors) if (messages.size() > 0) { for (const rp3d::Message& message: messages) { std::string messageType; switch(message.type) { case rp3d::Message::Type::Information: messageType = "info"; break; case rp3d::Message::Type::Warning: messageType = "warning"; break; case rp3d::Message::Type::Error: messageType = "error"; break; } std::cout << "Message (" << messageType << "): " << message.text << std::endl; } } // Make sure there was no errors during mesh creation assert(triangleMesh != nullptr); ``` -------------------------------- ### Configure PhysicsWorld Settings Source: https://context7.com/danielchappuis/reactphysics3d/llms.txt Customize physics world properties like gravity, solver iterations, and sleeping behavior. Settings can be applied during creation or modified afterward. ```cpp // Create world with custom settings PhysicsWorld::WorldSettings settings; settings.gravity = Vector3(0, -9.81f, 0); settings.defaultVelocitySolverNbIterations = 20; settings.defaultPositionSolverNbIterations = 5; settings.isSleepingEnabled = true; settings.worldName = "MyGameWorld"; PhysicsWorld* world = physicsCommon.createPhysicsWorld(settings); // Modify settings after creation world->setGravity(Vector3(0, -10.0f, 0)); world->setNbIterationsVelocitySolver(15); world->setNbIterationsPositionSolver(8); world->enableSleeping(true); world->setSleepLinearVelocity(0.02f); world->setSleepAngularVelocity(3.0f * (3.14159f / 180.0f)); world->setTimeBeforeSleep(1.0f); ``` -------------------------------- ### Configure and Retrieve Debug Visualization Source: https://context7.com/danielchappuis/reactphysics3d/llms.txt Enable debug rendering on the world and specific bodies, then iterate through the debug renderer's lines and triangles after a simulation update. ```cpp // Enable debug rendering world->setIsDebugRenderingEnabled(true); // Enable debugging for specific bodies for (uint32 i = 0; i < world->getNbRigidBodies(); i++) { world->getRigidBody(i)->setIsDebugEnabled(true); } // Get debug renderer reference DebugRenderer& debugRenderer = world->getDebugRenderer(); // Select what to display debugRenderer.setIsDebugItemDisplayed(DebugRenderer::DebugItem::COLLISION_SHAPE, true); debugRenderer.setIsDebugItemDisplayed(DebugRenderer::DebugItem::COLLIDER_AABB, true); debugRenderer.setIsDebugItemDisplayed(DebugRenderer::DebugItem::COLLIDER_BROADPHASE_AABB, false); debugRenderer.setIsDebugItemDisplayed(DebugRenderer::DebugItem::CONTACT_POINT, true); debugRenderer.setIsDebugItemDisplayed(DebugRenderer::DebugItem::CONTACT_NORMAL, true); // After world->update(), retrieve debug geometry uint32 nbLines = debugRenderer.getNbLines(); uint32 nbTriangles = debugRenderer.getNbTriangles(); // Get arrays for rendering (vertices in world space) const DebugRenderer::DebugLine* lines = debugRenderer.getLinesArray(); const DebugRenderer::DebugTriangle* triangles = debugRenderer.getTrianglesArray(); // Render lines for (uint32 i = 0; i < nbLines; i++) { Vector3 p1 = lines[i].point1; Vector3 p2 = lines[i].point2; uint32 color1 = lines[i].color1; uint32 color2 = lines[i].color2; // Draw line from p1 to p2 with OpenGL/DirectX } // Render triangles for (uint32 i = 0; i < nbTriangles; i++) { Vector3 v1 = triangles[i].point1; Vector3 v2 = triangles[i].point2; Vector3 v3 = triangles[i].point3; uint32 color = triangles[i].color1; // Draw triangle with OpenGL/DirectX } ``` -------------------------------- ### Create Concave Mesh Shape in C++ Source: https://context7.com/danielchappuis/reactphysics3d/llms.txt Demonstrates creating a concave mesh shape from triangle data for static environments. Ensure the mesh data is correctly formatted and use with a STATIC rigid body. ```cpp // Triangle mesh data const int nbVertices = 4; const int nbTriangles = 2; float vertices[3 * nbVertices] = { 0, 0, 0, 10, 0, 0, 10, 0, 10, 0, 0, 10 }; int indices[3 * nbTriangles] = { 0, 1, 2, // First triangle 0, 2, 3 // Second triangle }; // Create triangle vertex array TriangleVertexArray* triangleArray = new TriangleVertexArray( nbVertices, vertices, 3 * sizeof(float), nbTriangles, indices, 3 * sizeof(int), TriangleVertexArray::VertexDataType::VERTEX_FLOAT_TYPE, TriangleVertexArray::IndexDataType::INDEX_INTEGER_TYPE ); // Create triangle mesh std::vector messages; TriangleMesh* triangleMesh = physicsCommon.createTriangleMesh(triangleArray, messages); // Create concave mesh shape with scaling Vector3 scaling(1.0f, 1.0f, 1.0f); ConcaveMeshShape* concaveShape = physicsCommon.createConcaveMeshShape(triangleMesh, scaling); // Use with STATIC body only RigidBody* ground = world->createRigidBody(Transform::identity()); ground->setType(BodyType::STATIC); ground->addCollider(concaveShape, Transform::identity()); delete triangleArray; ``` -------------------------------- ### Link ReactPhysics3D Library to Executable Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md After finding the package, use this line to link your project's executable against the ReactPhysics3D library. ```cmake target_link_libraries(helloworld ReactPhysics3D::ReactPhysics3D) ``` -------------------------------- ### Create FixedJointInfo Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Initialize a FixedJointInfo object by specifying the anchor point in world-space. ```cpp // Anchor point in world-space Vector3 anchorPoint(2.0, 3.0, 4.0); // Create the joint info object FixedJointInfo jointInfo1(body1, body2, anchorPoint); ``` -------------------------------- ### Enable Debug Rendering in C++ Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Configures the physics world and bodies to generate debug primitives for contact points and normals. ```cpp // Enable debug rendering physicsWorld->setIsDebugRenderingEnabled(true); // Enable debugging for each rigid body that we want to display for (RigidBody* body: rigidBodies) { body->setIsDebugEnabled(true); } // Get a reference to the debug renderer DebugRenderer& debugRenderer = physicsWorld->getDebugRenderer(); // Select the contact points and contact normals to be displayed debugRenderer.setIsDebugItemDisplayed(DebugRenderer::DebugItem::CONTACT_POINT, true); debugRenderer.setIsDebugItemDisplayed(DebugRenderer::DebugItem::CONTACT_NORMAL, true); ``` -------------------------------- ### Create Ball and Socket Joint Info Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Initialize a BallAndSocketJointInfo object with two rigid bodies and an anchor point in world-space coordinates. Ensure bodies are in a valid position relative to the constraint. ```cpp // Anchor point in world-space const Vector3 anchorPoint(2.0, 4.0, 0.0); // Create the joint info object BallAndSocketJointInfo jointInfo(body1, body2, anchorPoint); ``` -------------------------------- ### Implement Collision and Trigger Callbacks Source: https://context7.com/danielchappuis/reactphysics3d/llms.txt Extend the EventListener class to handle contact and trigger events. Register the listener instance with the physics world to receive updates. ```cpp class GameEventListener : public EventListener { public: // Called when contacts occur virtual void onContact(const CollisionCallback::CallbackData& callbackData) override { for (uint32 p = 0; p < callbackData.getNbContactPairs(); p++) { CollisionCallback::ContactPair pair = callbackData.getContactPair(p); // Get event type CollisionCallback::ContactPair::EventType eventType = pair.getEventType(); if (eventType == CollisionCallback::ContactPair::EventType::ContactStart) { std::cout << "Collision started!" << std::endl; } else if (eventType == CollisionCallback::ContactPair::EventType::ContactStay) { std::cout << "Collision ongoing..." << std::endl; } else if (eventType == CollisionCallback::ContactPair::EventType::ContactExit) { std::cout << "Collision ended!" << std::endl; } // Get bodies and colliders Body* body1 = pair.getBody1(); Body* body2 = pair.getBody2(); Collider* collider1 = pair.getCollider1(); Collider* collider2 = pair.getCollider2(); // Process contact points (not available for ContactExit) if (eventType != CollisionCallback::ContactPair::EventType::ContactExit) { for (uint32 c = 0; c < pair.getNbContactPoints(); c++) { CollisionCallback::ContactPoint point = pair.getContactPoint(c); // Convert local point to world space Vector3 worldPoint = collider1->getLocalToWorldTransform() * point.getLocalPointOnCollider1(); Vector3 normal = point.getWorldNormal(); decimal depth = point.getPenetrationDepth(); } } } } // Called when trigger overlaps occur virtual void onTrigger(const OverlapCallback::CallbackData& callbackData) override { for (uint32 i = 0; i < callbackData.getNbOverlappingPairs(); i++) { OverlapCallback::OverlapPair pair = callbackData.getOverlappingPair(i); OverlapCallback::OverlapPair::EventType eventType = pair.getEventType(); if (eventType == OverlapCallback::OverlapPair::EventType::OverlapStart) { std::cout << "Entered trigger zone!" << std::endl; } else if (eventType == OverlapCallback::OverlapPair::EventType::OverlapExit) { std::cout << "Left trigger zone!" << std::endl; } Body* triggerBody = pair.getBody1(); Body* enteringBody = pair.getBody2(); } } }; // Register the event listener GameEventListener eventListener; world->setEventListener(&eventListener); ``` -------------------------------- ### Destroy Physics Objects Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Shows the correct methods to manually release memory for rigid bodies and physics worlds. ```cpp // Destroy a rigid body world->destroyRigidBody(body); ... // Destroy a physics world physicsCommon.destroyPhysicsWorld(world); ``` -------------------------------- ### Implement a Custom RaycastCallback Class Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Inherit from RaycastCallback and override notifyRaycastHit to process hit information. Return a fraction to control ray continuation. ```cpp // Class WorldRaycastCallback class MyCallbackClass : public RaycastCallback { public: virtual decimal notifyRaycastHit(const RaycastInfo& info) { // Display the world hit point coordinates std::cout << "Hit point : " << info.worldPoint.x << info.worldPoint.y << info.worldPoint.z << std::endl; // Return a fraction of 1.0 to gather all hits return decimal(1.0); } }; ``` -------------------------------- ### Create HingeJointInfo object Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Initializes the configuration object required to create a hinge joint, specifying anchor points and rotation axes in world-space. ```cpp // Anchor point in world-space const Vector3 anchorPoint(2.0, 4.0, 0.0); // Hinge rotation axis in world-space const Vector3 axis(0.0, 0.0, 1.0); // Create the joint info object HingeJointInfo jointInfo(body1, body2, anchorPoint, axis); ``` -------------------------------- ### Configure Physics Engine Logging Source: https://context7.com/danielchappuis/reactphysics3d/llms.txt Use the DefaultLogger to output warnings and errors to files or streams, or implement a custom Logger class for specific output requirements. ```cpp // Create default logger DefaultLogger* logger = physicsCommon.createDefaultLogger(); // Configure log levels uint logLevel = static_cast(Logger::Level::Warning) | static_cast(Logger::Level::Error); // Output to file in HTML format logger->addFileDestination("physics_log.html", logLevel, DefaultLogger::Format::HTML); // Output to console in text format logger->addStreamDestination(std::cout, logLevel, DefaultLogger::Format::Text); // Set the logger physicsCommon.setLogger(logger); // Custom logger implementation class MyLogger : public Logger { public: virtual void log(Level level, const std::string& physicsWorldName, Category category, const std::string& message, const char* filename, int lineNumber) override { std::string levelStr; switch (level) { case Level::Information: levelStr = "INFO"; break; case Level::Warning: levelStr = "WARNING"; break; case Level::Error: levelStr = "ERROR"; break; } std::cout << "[" << levelStr << "] " << physicsWorldName << ": " << message << std::endl; } }; MyLogger customLogger; physicsCommon.setLogger(&customLogger); ``` -------------------------------- ### Configure Solver Iterations Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Adjust the number of iterations for the velocity and position solvers to balance simulation precision and computational cost. ```cpp // Change the number of iterations of the velocity solver world->setNbIterationsVelocitySolver(15); // Change the number of iterations of the position solver world->setNbIterationsPositionSolver(8); ``` -------------------------------- ### Perform a Raycast Query in the World Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Use PhysicsWorld::raycast with a Ray object and a custom callback instance to test intersections across the physics world. ```cpp // Create the ray Vector3 startPoint(1 , 2, 10); Vector3 endPoint(1, 2, -20); Ray ray(startPoint, endPoint); // Create an instance of your callback class MyCallbackClass callbackObject; // Raycast test world->raycast(ray, &callbackObject); ``` -------------------------------- ### Create Convex Mesh from Vertices Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Use this method when you only have vertex data and not face information. The library computes the convex hull using the QuickHull algorithm. Ensure to check the messages vector for any errors during creation. ```cpp float vertices[24] = {-3, -3, 3, 3, -3, 3, 3, -3, -3, -3, -3, -3, -3, 3, 3, 3, 3, 3, 3, 3, -3, -3, 3, -3}; rp3d::VertexArray vertexArray(vertices, 3 * sizeof(float), 8, rp3d::VertexArray::DataType::VERTEX_FLOAT_TYPE); std::vector messages; ConvexMesh* convexMesh = physicsCommon.createConvexMesh(vertexArray, messages); if (messages.size() > 0) { for (const rp3d::Message& message: messages) { std::string messageType; switch(message.type) { case rp3d::Message::Type::Information: messageType = "info"; break; case rp3d::Message::Type::Warning: messageType = "warning"; break; case rp3d::Message::Type::Error: messageType = "error"; break; } std::cout << "Message (" << messageType << "): " << message.text << std::endl; } } assert(convexMesh != nullptr); ``` -------------------------------- ### Create ConcaveMeshShape Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md This snippet shows how to create a ConcaveMeshShape using a previously created TriangleMesh and a scaling factor. The same TriangleMesh can be reused to create multiple ConcaveMeshShapes with different scaling. ```cpp const Vector3 scaling(1, 1, 1); // Create the ConcaveMeshShape using the TriangleMesh ConcaveMeshShape* concaveMeshShape = physicsCommon.createConcaveMeshShape(triangleMesh, scaling); ``` -------------------------------- ### Update Physics World with Fixed Time Step Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Use this technique to ensure a stable physics simulation by accumulating time differences and applying fixed time steps. This method is crucial for real-time applications to maintain consistent simulation speed regardless of frame rate. ```cpp // Constant physics time step const float timeStep = 1.0f / 60.0f; // Get the current system time long double currentFrameTime = getCurrentSystemTime(); // Compute the time difference between the two frames long double deltaTime = currentFrameTime - previousFrameTime; // Update the previous time previousFrameTime = currentFrameTime; // Add the time difference in the accumulator accumulator += mDeltaTime; // While there is enough accumulated time to take // one or several physics steps while (accumulator >= timeStep) { // Update the Dynamics world with a constant time step world->update(timeStep); // Decrease the accumulated time accumulator -= timeStep; } ``` -------------------------------- ### Collision Filtering with Categories and Masks in C++ Source: https://context7.com/danielchappuis/reactphysics3d/llms.txt Explains how to configure collision filtering for rigid bodies using bit flags for categories and masks. This allows fine-grained control over which objects can interact with each other. Ensure categories and masks are set appropriately for each collider. ```cpp // Define collision categories as bit flags enum CollisionCategory { CATEGORY_PLAYER = 0x0001, CATEGORY_ENEMY = 0x0002, CATEGORY_PROJECTILE = 0x0004, CATEGORY_ENVIRONMENT = 0x0008 }; // Player collider setup Collider* playerCollider = playerBody->addCollider(capsuleShape, Transform::identity()); playerCollider->setCollisionCategoryBits(CATEGORY_PLAYER); playerCollider->setCollideWithMaskBits(CATEGORY_ENEMY | CATEGORY_ENVIRONMENT); // Enemy collider setup Collider* enemyCollider = enemyBody->addCollider(boxShape, Transform::identity()); enemyCollider->setCollisionCategoryBits(CATEGORY_ENEMY); enemyCollider->setCollideWithMaskBits(CATEGORY_PLAYER | CATEGORY_PROJECTILE | CATEGORY_ENVIRONMENT); // Projectile setup - collides with enemies and environment, not player Collider* bulletCollider = bulletBody->addCollider(sphereShape, Transform::identity()); bulletCollider->setCollisionCategoryBits(CATEGORY_PROJECTILE); bulletCollider->setCollideWithMaskBits(CATEGORY_ENEMY | CATEGORY_ENVIRONMENT); // Environment (static) Collider* wallCollider = wallBody->addCollider(boxShape, Transform::identity()); wallCollider->setCollisionCategoryBits(CATEGORY_ENVIRONMENT); wallCollider->setCollideWithMaskBits(CATEGORY_PLAYER | CATEGORY_ENEMY | CATEGORY_PROJECTILE); ``` -------------------------------- ### Retrieve OpenGL Transformation Matrix Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Converts a physics transform into a 4x4 OpenGL-compatible matrix array. ```cpp // Get the OpenGL matrix array of the transform float matrix[16]; transform.getOpenGLMatrix(matrix); ``` -------------------------------- ### Register Event Listener Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Register a custom event listener class with the physics world. Ensure your class inherits from EventListener and is instantiated before registration. ```cpp // Your event listener class class YourEventListener : public EventListener { ... }; YourEventListener listener; // Register your event listener class world->setEventListener(&listener); ``` -------------------------------- ### Create and Configure HingeJoint Source: https://context7.com/danielchappuis/reactphysics3d/llms.txt Creates a hinge joint allowing rotation around a single axis, like a door hinge. Configure limits and motor for automatic movement. ```cpp // Create door frame (static) and door (dynamic) RigidBody* doorFrame = world->createRigidBody(Transform(Vector3(0, 2, 0), Quaternion::identity())); RigidBody* door = world->createRigidBody(Transform(Vector3(1, 2, 0), Quaternion::identity())); doorFrame->setType(BodyType::STATIC); door->setType(BodyType::DYNAMIC); // Hinge at door edge, rotating around Y axis Vector3 anchorPoint(0.0f, 2.0f, 0.0f); Vector3 hingeAxis(0.0f, 1.0f, 0.0f); HingeJointInfo jointInfo(doorFrame, door, anchorPoint, hingeAxis); // Enable angle limits (door opens 0 to 90 degrees) jointInfo.isLimitEnabled = true; jointInfo.minAngleLimit = 0.0f; jointInfo.maxAngleLimit = 3.14159f / 2.0f; // 90 degrees // Enable motor to automatically close door jointInfo.isMotorEnabled = true; jointInfo.motorSpeed = -0.5f; // Radians per second (negative = closing) jointInfo.maxMotorTorque = 10.0f; // Newton-meters jointInfo.isCollisionEnabled = false; HingeJoint* hingeJoint = dynamic_cast(world->createJoint(jointInfo)); // Modify limits/motor after creation hingeJoint->enableLimit(true); hingeJoint->setMinAngleLimit(-3.14159f / 4.0f); hingeJoint->setMaxAngleLimit(3.14159f / 2.0f); hingeJoint->enableMotor(true); hingeJoint->setMotorSpeed(1.0f); hingeJoint->setMaxMotorTorque(20.0f); ``` -------------------------------- ### Create Joint in PhysicsWorld Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Use the PhysicsWorld::createJoint method to instantiate a joint and retrieve a pointer to the resulting object. ```cpp // Create the fixed joint in the physics world FixedJoint* joint; joint = dynamic_cast(world->createJoint(jointInfo)); ``` -------------------------------- ### Perform Raycast Queries Source: https://context7.com/danielchappuis/reactphysics3d/llms.txt Use raycasting to detect intersections with colliders in the world. Define a callback to handle hit information, including point, normal, and fraction. Optionally filter by category or raycast against a single body/collider. ```cpp // Define a ray callback class class MyRaycastCallback : public RaycastCallback { public: std::vector hits; virtual decimal notifyRaycastHit(const RaycastInfo& info) override { hits.push_back(info); // Access hit information Vector3 hitPoint = info.worldPoint; Vector3 hitNormal = info.worldNormal; decimal hitFraction = info.hitFraction; RigidBody* hitBody = dynamic_cast(info.body); Collider* hitCollider = info.collider; std::cout << "Hit at: " << hitPoint.x << ", " << hitPoint.y << ", " << hitPoint.z << std::endl; // Return values: // 1.0 = continue raycast, gather all hits // 0.0 = stop raycast // hitFraction = clip ray to this hit // -1.0 = ignore this hit, continue return decimal(1.0); } }; // Perform raycast Vector3 startPoint(0.0f, 10.0f, 0.0f); Vector3 endPoint(0.0f, -10.0f, 0.0f); Ray ray(startPoint, endPoint); MyRaycastCallback callback; world->raycast(ray, &callback); // Raycast with category filter (only hit specific categories) unsigned short categoryMask = CATEGORY_ENEMY | CATEGORY_ENVIRONMENT; world->raycast(ray, &callback, categoryMask); // Raycast against single body RaycastInfo singleHitInfo; bool hit = body->raycast(ray, singleHitInfo); // Raycast against single collider bool colliderHit = collider->raycast(ray, singleHitInfo); ``` -------------------------------- ### Create Primitive Collision Shapes Source: https://context7.com/danielchappuis/reactphysics3d/llms.txt Instantiates basic geometric shapes including spheres, boxes, and capsules for collision detection. ```cpp // Sphere shape - specify radius float radius = 2.5f; SphereShape* sphereShape = physicsCommon.createSphereShape(radius); // Box shape - specify half extents (half width, height, depth) Vector3 halfExtents(1.0f, 2.0f, 1.5f); // Creates 2x4x3 box BoxShape* boxShape = physicsCommon.createBoxShape(halfExtents); // Capsule shape - radius and height (distance between sphere centers) float capsuleRadius = 0.5f; float capsuleHeight = 2.0f; // Total height = 2*radius + height = 3.0 CapsuleShape* capsuleShape = physicsCommon.createCapsuleShape(capsuleRadius, capsuleHeight); // Add to body RigidBody* player = world->createRigidBody(Transform::identity()); player->addCollider(capsuleShape, Transform::identity()); ``` -------------------------------- ### Create and Add a Collider to a Body Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Instantiate a sphere collision shape via PhysicsCommon and attach it to a rigid body with a specific transform. ```cpp // Instantiate a sphere collision shape float radius = 3.0f; SphereShape* sphereShape = physicsCommon.createSphereCollisionShape(radius); // Relative transform of the collider relative to the body origin Transform transform = Transform::identity(); // Add the collider to the rigid body Collider* collider; collider = body->addCollider(&shape, transform); ``` -------------------------------- ### Create Sphere Collision Shape Source: https://github.com/danielchappuis/reactphysics3d/blob/master/documentation/UserDocumentation.md Use the PhysicsCommon factory to instantiate a sphere collision shape. ```cpp // Instanciate a sphere collision shape SphereShape* sphereShape = physicsCommon.createSphereShape(radius); ```