Skip to content

timo-eberl/tics

Repository files navigation

Tics Physics

Tics is a Rigid Body Physics Library.

If you came here from my thesis and want to look at the Geometric Algebra implementation, you should go back to commit 2bb376a0e6475f3ed2ead2e03fb818270a6aa55d .

Development Build

cmake -S . -B build/
cmake --build build/

# Run demos
cd build/bin/
./playground

Release Build

Compiler choice: clang is sometimes faster with OpenMP. gcc is faster for SIMD. gcc seems to be the better choice.

cmake -S . -B build_release/ -DCMAKE_BUILD_TYPE=Release -DTICS_ENABLE_DEBUG_VIEW=OFF -DCMAKE_C_COMPILER=gcc
cmake --build build_release/ --config Release

# Run demos
cd build_release/bin
./playground

Library-Only Build

To build the tics static library without any extra stuff:

cmake -S . -B build_lib/ -DTICS_BUILD_DEMOS=OFF -DTICS_BUILD_TESTS=OFF -DTICS_ENABLE_DEBUG_VIEW=OFF -DTICS_ENABLE_PROFILER=OFF -DTICS_BUILD_TOOL_GLB2C=OFF
cmake --build build_lib/

Testing

see tests/README.md

Debug Visualization (Blick)

Blick is Tics' debug visualization tool. It is enabled by default and automatically spawns a separate window with its own debug view into the physics world. It can draw many debug primitives (like points, arrows, AABBs) that can be used to visualize positions, velocities, intersections. Unlike traditional debug drawing, Blick runs as a separate process, communicating via shared memory. This solves debugging frustrations:

  • You can pause the simulation in a conventional debugger and the Blick window remains responsive and you can move the camera around and inspect the frozen scene. You can even step through your application and, for example, watch the bounding volume hierarchy grow.
  • If the physics engine crashes, Blick stays open, preserving the final state. You can inspect the "crime scene" to understand exactly what caused the crash.
  • You can visualize simulations that don't include a graphics context themself, such as tests.
  • Rendering debug primitives happens asynchronously. The simulation is not slowed down by the rendering overhead of drawing thousands of contact points or AABBs.

It's created for Tics, but could be used to debug other 3D applications too.

Unfortunately, Blick is currently Unix-only

glb2c

glb2c is a tool that converts a glb file into a bunch of arrays in C syntax that can be pasted into your source code. Allows quickly embedding models without loading models at runtime.

cmake -S . -B build/ -DTICS_BUILD_TOOL_GLB2C=ON
cmake --build build/

# Run. You can also specify multiple glb files
./build/bin/glb2c models/cube.glb

To-Do

  • Remove TICS_GA (Rip)
  • Port to C
    • Create wrapper tics_math.h
    • Replace Terathon math with own implementation
    • Update the public interface to a C API and create wrapper around the C++ implementation
    • Rewrite (gradually rot out the C++ internals from the inside)
      • Data-Oriented tics_world
        • Replace std::vector with stb_ds.h or manual malloc
        • "Swap and Pop"
      • world step
        • Port dynamics
        • Port collision detection
        • Port collision response
          • Impulse solver
          • Position solver
  • Tooling
    • Debug Visualizer that runs as a separate process and inspects the running simulation using POSIX shared memory. Enables live viewing of debug data with a controllable camera while the physics process is being debugged with a conventional debugger.
      • Add protocol for it (inter process communication)
      • Create a fake debug drawer to test it with
      • Actually make it draw stuff (points and lines)
      • Make it a standalone tool (Blick)
      • Implement all primitives
      • Add functionality to assign meshes to shape ids (called by application code). Otherwise we can't really render meshes, because tics only stores points
      • Layers: Objects have a layer that can be toggled in the viewer
      • Draw transparent shapes correctly without z-buffering (and with add alpha blending?)
      • Configuration if it should auto-close on crash of main app
      • Make it platform independent
      • Toggle between face culling options
    • tool that can convert glb to c arrays
    • Simple text-only profiler using macros to define zones in the code
  • Improve collision response to be more stable
    • no sudden jumping objects, no spinning
    • Sort collisions so the result is deterministic (even with Multi-Threading)
    • Change to this loop
      • 1. Apply forces (gravity, friction) to velocity.
      • 2. Collision detection
      • 3. Collision response. Calculate impulses required to correct velocity. Apply impulses immediately to velocity.
      • 4. Position integration (kinematics, as in not based on forces or impulses but only on velocity).
      • do resolve_penetrations after applying velocites so we don't double correct. needs check if objects are still penetrating by storing local a and b and transforming again.
        • Is this a good idea? since we are teleporting we might break stuff. maybe baumgarte stabilization is better.
  • Improve resting contacts
    • Add Iteration loop (sequential impulses) to improve objects in touch with multiple objects (stack boxes)
    • Add Warm Starting? Would improve resting contacts, but requires storing collisions across steps.
    • Add restitution threshold: collisions with a low relative velocity are treated as resting -> velocity = 0
    • On certain collision cases report multiple collisions (improves resting collisions). All cases:
      • edge vs edge (parallel): 2 points. project one edge onto the other and find overlapping segment endpoints.
      • edge vs face: 2 points. clip edge against boundaries of face (Sutherland-Hodgman?)
      • face vs face: 3+ points (polygon, maybe limit to some number?). clip one face against other (Sutherland-Hodgman)
  • Testing
    • Setup
    • Test public API
    • Test dynamics
    • Test collision detection
    • More collision detection tests
      • edge vs edge
      • parallel face vs face (resting contact, should this return multiple contact points?)
      • touching: objects only touch - should consistently report a hit (implemented with skin width)
      • shape completely inside another
      • needle-plate: a very tiny object against another very big object
    • Test collision response
  • Portability
    • Remove explicit SIMD (its not faster than autovec anyways)
    • Use Function Multiversioning for autovectorized functions __attribute__((target_clones("avx2","sse2","default")))
    • compmile with -march=x86-64 to be explicit about compatibility (guarantees SSE, but function multiversioning also provides AVX versions)
  • Performance Optimization
    • Separate list for static and rigid bodies (beneficial for broadphase integration, only update AABBs for rigid bodies)
    • On convex hull import, remove duplicate vertices. Enables importing flat shaded geometry without performance penalty.
    • tightly packed vertex data for shapes
    • SoA instead of AoS for bodies
    • Broadphase
      • structure of array for AABBs (cache-locality)
    • SIMD
      • individual arrays for min_x, min_y, min_z, max_x, max_y, max_z
      • check 1 obj against 8 in 1 cycle
    • list of dynamic indices -> outer loop: dynamic indices, inner loop: all indices
      • first: dynamic = rigid bodies
      • then: dynamic = objects that actually moved
    • Multi-Threading Narrow Phase
    • Improve GJK
      • https://dl.acm.org/doi/10.1145/3072959.3083724
      • "GJK algorithms are often used incrementally in simulation systems and video games. In this mode, the final simplex from a previous solution is used as the initial guess in the next iteration"
  • Features
    • collision shapes
      • sphere
        • sphere vs sphere
        • sphere vs convex: use gjk for point (sphere center) vs convex, then use the result to find collision points (instead of EPA). or if center is inside convex shape, use EPA.
    • combine shapes (enables concave shapes)
    • apply_impulse function that applies impulse at specific location
    • setters and getters for rigid body and static body properties
    • on_collision_enter + on_collision_exit
    • Areas (only detect collisions)
    • Bodies that are moved externally, but can push rigid bodies
    • Teleporting and swapping shapes -> check for intersection and reposition if required (position solver?)
    • physics materials

About

Rigid Body Physics Library

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published