3D Physics Engine
Project Overview
- This project is a comprehensive 3D physics engine built from the ground up in C++ with DirectX 12.
- It was developed as a deep dive into the core principles of rigid body dynamics, collision detection, and constraint resolution common in modern game development.
- The engine features a robust physics pipeline, a flexible constraint solver, and a powerful suite of visual debugging tools designed to analyze and validate complex physical interactions.
Core Engine Architecture & Features
- The engine is built on a modular architecture, separating the core physics simulation from the rendering and debugging layers.
- Key technical features include:
1. Physics Pipeline & Collision
-
The engine’s simulation loop features a robust and flexible pipeline, allowing for clear separation of detection and resolution, as well as runtime performance comparisons.
- Dual-Mode Collision Detection:
- Basic Path (N-Squared): A foundational $O(N^2)$ all-pairs check is also implemented.
- This “brute force” method can be toggled on for debugging and to clearly demonstrate the significant performance gains of the broad-phase optimization.
- Optimized Path (Broad/Narrow Phase): The primary detection path is a high-performance, two-stage process.
- Broad Phase: Utilizes the Sweep and Prune (SAP) algorithm, implemented by sorting object AABBs along each axis, to efficiently cull potential collision pairs.
- This significantly reduces the $O(N^2)$ problem space.
- Narrow Phase: Employs the GJK algorithm on the remaining pairs to perform precise intersection tests for sphere-to-sphere and convex-to-convex shapes.
- Broad Phase: Utilizes the Sweep and Prune (SAP) algorithm, implemented by sorting object AABBs along each axis, to efficiently cull potential collision pairs.
- Basic Path (N-Squared): A foundational $O(N^2)$ all-pairs check is also implemented.
- Hybrid Collision Resolution:
- The engine intelligently dispatches detected contacts to two different solvers based on their nature:
- 1. Dynamic Contacts (Time-of-Impact Resolver): For contacts detected before they happen ($TimeOfImpact > 0$), the engine uses a predictive impulse-based solver.
- It then sorts all dynamic contacts by their time of impact, advances the simulation to the earliest collision, resolves it with a “normal” impulse, and repeats this process until the frame’s time step is complete.
- 2. Static & Resting Contacts (Constraint Solver): For contacts that are already penetrating or resting ($TimeOfImpact = 0$), the engine uses a more robust iterative constraint solver.
- These contacts are added to manifolds and solved over several iterations to ensure stable and physically plausible stacking, resting, and other complex multi-body interactions.
2. Powerful Debugging Suite
- A significant focus of the project was the development of runtime debugging tools, which are critical for physics programming.

- Interactive Object Inspector (Picking):
- At runtime, the simulation can be paused.
- Objects in the scene can be selected via mouse click.
- Upon selection, a UI panel displays critical state information:
- Object ID
- Position and Orientation
- Linear Velocity and Angular Velocity.
- Runtime Gizmo:
- Selected objects can be directly manipulated (translated and rotated) using a 3D gizmo.
- This manipulation has a specialized physics implementation: the moved object pushes other dynamic objects, but is not subject to gravity.
- Its velocity is reset to zero upon resolving contacts to maintain a stable state for debugging.
- When paused, the engine saves the velocity state of all objects, and this state is restored upon resuming the simulation.
- The inspector panel continues to display the stored velocities for the picked item, allowing for clear analysis of the pre-pause state.
- Contact Point Visualization:
- When an object is selected, all of its current contact points are rendered as small, pickable (yellow) spheres.
- Selecting a contact point sphere displays detailed information about the collision:
- the IDs of the two bodies involved, the collision normal
- the time of impact (TOI)
- and the contact position in both local and world space for each body.
- Frame-by-Frame History:
- The engine records the state (position, rotation, etc.) of all objects for the last 60 frames.
- A UI slider allows the user to scrub backward and forward through this history, providing a powerful tool for analyzing high-speed events or finding the exact moment a simulation bug occurs.
3. General UI, Simulation Controls, and Visualization Tools
- A key design goal was to provide an accessible and powerful interface for controlling and inspecting the simulation.
- The application utilizes a persistent, three-panel UI structure to manage runtime controls, performance monitoring, and advanced visual debugging.
A. General Engine Controls (Top-Left Panel)
- This panel provides immediate control over the scene state:
- Core Control Functions: Dedicated buttons and corresponding keyboard shortcuts are implemented for fundamental operations:
- Pause/Resume (Shortcut: $\text{P}$)
- Scene Restart (Shortcut: $\text{R}$)
- Return to Main Menu (Shortcut: $\text{Esc}$)
B. Visual Debugger (Bottom-Left Panel)
- This dynamic panel is the core interface for the Picking Feature (detailed previously in Section 2).
- State-Driven Display: When no object is selected, the panel defaults to a status message (“Object is not picked”).
- Object Inspection: Upon selecting a rigid body, the panel dynamically populates with its critical data (ID, Position, Orientation, Linear Velocity, Angular Velocity).
- Contact Point Analysis: When a contact point sphere is picked, the panel displays detailed collision data (IDs of the two contacting bodies, Collision Normal, Time of Impact, and local/global contact coordinates).
- State Reset: The display automatically resets upon resuming the simulation to ensure the data presented is always current with the paused state.
C. Information Panel & Simulation Monitoring (Right-Side Panel)
- This persistent panel consolidates all performance metrics and specialized scene controls.
- Performance Monitoring:
- A dedicated widget plots a real-time graph of the current Frames Per Second (FPS), allowing for immediate performance bottleneck identification.
- Frame Controller (Rewind/Scrubbing):
- The simulation history for the past 60 frames is stored.
- A specialized slider widget enables users to scrub backward and forward through this saved data, effectively rewinding and replaying the physics state for precise event analysis.
- Scene-Specific Configuration: The remaining widgets are dynamically tailored to the loaded scene:
- Stress Test Scene:
- Controls include toggles for the Broad/Narrow phase (SAP) algorithms
- Shape selection (spheres vs. convex)
- Sliders for the Stress Level (object count) and Initial Height.
- Sandbox Scene:
- Buttons are available to instantly load various predefined scenarios, such as Stacking Boxes, Ragdolls, and Moving Platforms.
- Stress Test Scene:
- Performance Monitoring:
Demonstration 1: Performance & Stress Test
- This demonstration tests the engine’s stability and performance under heavy load.
- The scene spawns a large number of dynamic objects (spheres and convex shapes) and drops them into a container. [Embedded Video/GIF of Stress Test]
Key Features Demonstrated:
- High-Volume Object Handling: The simulation remains stable while processing hundreds of active rigid bodies.
- Dynamic UI Controls: A dedicated UI panel for this scene allows for runtime configuration:
- Algorithm Toggling: Buttons to enable or disable the broad and narrow collision phases, clearly demonstrating their performance impact.
- Shape Selection: Toggles for spawning either spheres or more complex convex shapes (e.g., diamonds).
- Stress Level: A slider (1-10) controls the number of objects spawned.
- Initial Height: A slider adjusts the starting drop height for all objects.
Demonstration 2: Sandbox & Constraint Scenarios
- This demonstration showcases the robustness of the physics solver in handling complex, constraint-based interactions common in games. [Embedded Video/GIF of Sandbox Scenarios]
Key Scenarios Demonstrated:
- The UI for this scene features buttons to load each pre-defined scenario instantly.
- Stacking: Objects are stacked to test the solver’s ability to handle resting contact and stability.
- Ragdolls: A simple ragdoll demonstrates joint constraints and complex compound body interactions.
- Moving Platforms: Dynamic objects correctly interact with kinematically-driven platforms.
- [Other Scenarios]: e.g., “A pendulum,” “A chain,” etc.
- revise this part!
Challenges & Future Development
- This project provided significant technical challenges, particularly in implementing a stable and efficient constraint solver and managing engine state for the debugging tools.
- Future development could include:
- Expanding the shapes of convex shapes (e.g., cylinder, pyramid).
- Optimizing the solver for better performance with high-contact scenarios.
Leave a comment