Metadata-Version: 2.2
Name: culverin
Version: 0.3.1b1
Summary: High-performance Jolt Physics bindings for Python featuring Shadow Buffers and Free-Threading support.
Keywords: physics,jolt,gamedev,free-threading,3d,simulation,robotics
Author: Mai Huy Hiếu
License: MIT
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: C
Classifier: Programming Language :: C++
Classifier: Topic :: Games/Entertainment
Classifier: Topic :: Scientific/Engineering :: Physics
Project-URL: Homepage, https://github.com/Evilpasture/culverin
Project-URL: Documentation, https://github.com/Evilpasture/culverin/tree/master/docs
Project-URL: Repository, https://github.com/Evilpasture/culverin.git
Project-URL: Bug Tracker, https://github.com/Evilpasture/culverin/issues
Requires-Python: >=3.13
Description-Content-Type: text/markdown

# Culverin Physics

[![PyPI - Version](https://img.shields.io/pypi/v/culverin)](https://pypi.org/project/culverin/)
[![Python Version](https://img.shields.io/pypi/pyversions/culverin)](https://pypi.org/project/culverin/)

Culverin is a Python wrapper for the **Jolt Physics** engine. It is designed for 3D games and simulations that require high performance and multi-threaded execution.

### Key Concepts

*   **Free-Threading Support:** Designed for Python 3.13t and 3.14t. The engine releases the Global Interpreter Lock (GIL) during physics updates and raycast batches.
*   **Shadow Buffers:** All body positions, rotations, and velocities are stored in contiguous C-arrays. You can access this data via `memoryview` or `numpy` without the overhead of creating Python objects for every body.
*   **Thread-Safe API:** The engine uses a priority-based locking system. Simulation steps, state mutations, and queries can run on different threads without causing deadlocks or memory corruption.
*   **Generational Handles:** Bodies are referenced by 64-bit handles rather than pointers. This ensures that using a handle for a deleted object will not crash the program.
*   **Double-Precision Internal:** Uses double-precision floats for world positions to prevent physics jitter in large environments, while mirroring data to float32 buffers for rendering efficiency.

### Features

*   **Standard Primitives:** Box, Sphere, Capsule, Cylinder, and Plane shapes.
*   **Complex Shapes:** Support for Convex Hulls, Heightfields (Terrain), and static Meshes.
*   **Compound Bodies:** Create single bodies composed of multiple child shapes.
*   **Character Controller:** A virtual character controller with built-in support for climbing stairs, sliding down slopes, and pushing objects.
*   **Vehicles:** Support for wheeled vehicles and tracked vehicles (tanks) with physical treads and skid-steering.
*   **Constraints:** Fixed, Point, Hinge, Slider, Distance, and Cone constraints.
*   **Queries:** Efficient single and batch Raycasting, Shapecasting (sweeps), and Overlap queries.
*   **Collision Events:** Native event buffer for contact added, persisted, and removed events.

### Installation

Building from source requires CMake and a C++ compiler (Visual Studio on Windows, GCC or Clang on Linux/macOS).

```bash
# Clone the repository including submodules
git clone --recursive https://github.com/Evilpasture/culverin.git
cd culverin

# Install the package
pip install .
```

If you want Python 3.14t:
```bash
# Please install build module
pip install build

# Then build your wheel. Keyword: python3.14t, and have your 3.14t interpreter activated or available in PATH. usually the Python installer manages it for you.
python3.14t -m build --wheel

# then install via the wheel. please use your actual file name.
pip install culverin-*-win_amd64.whl
```

### Quick Start

```python
import culverin
import numpy as np

# Initialize the world with 500 bodies capacity
world = culverin.PhysicsWorld(settings={"gravity": (0, -9.81, 0), "max_bodies": 1000})

# Create a ground plane
world.create_body(pos=(0, 0, 0), shape=culverin.SHAPE_PLANE, motion=culverin.MOTION_STATIC)

# Create a dynamic box
handle = world.create_body(pos=(0, 10, 0), size=(1, 1, 1), shape=culverin.SHAPE_BOX, motion=culverin.MOTION_DYNAMIC)

# Simulation loop
for _ in range(1000):
    world.step(1/60)
    
    # Access position directly from the shadow buffer
    idx = world.get_index(handle)
    pos = world.positions[idx * 4 : idx * 4 + 3]
    print(f"Box Height: {pos[1]}")
```

### Technical Specifications

| Spec | Standard |
| :--- | :--- |
| **Units** | Metric (1.0 = 1 meter) |
| **Coordinate System** | Right-Handed (Y-Up) |
| **Angle Units** | Radians |
| **Quaternion Format** | `(x, y, z, w)` |
| **Internal Precision** | Float64 (Double) |
| **Buffer Precision** | Float32 |
| **Minimum Python** | 3.11 (3.13+ recommended for multi-threading) |

### Performance Note
For maximum performance when reading state, use the `world.positions` and `world.rotations` attributes. These return `memoryview` objects that point directly to the engine's internal memory. Use `numpy.frombuffer(world.positions, dtype=np.float32)` to wrap them in a NumPy array without copying the data.