Metadata-Version: 2.5
Name: reality
Version: 0.1.0
Summary: A backend-neutral foundation for programmable physical 3D worlds.
Project-URL: Homepage, https://github.com/andaniayan-jpg/reality
Project-URL: Repository, https://github.com/andaniayan-jpg/reality
Project-URL: Issues, https://github.com/andaniayan-jpg/reality/issues
Author: Reality contributors
License: Apache-2.0
License-File: LICENSE
Keywords: 3d,geometry,spatial,trimesh
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: numpy>=1.26
Requires-Dist: trimesh>=4.0
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == 'dev'
Requires-Dist: mypy==1.17.1; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff==0.12.10; extra == 'dev'
Provides-Extra: gpu
Requires-Dist: warp-lang>=1.9; extra == 'gpu'
Provides-Extra: learn
Requires-Dist: scikit-learn>=1.4; extra == 'learn'
Provides-Extra: physics
Requires-Dist: mujoco>=3.2; extra == 'physics'
Description-Content-Type: text/markdown

# reality

`reality` is a small, typed foundation for treating a physical 3D scene as a Python object. It loads common mesh formats today and exposes deterministic spatial queries without committing the public API to a physics or rendering engine.

## 60-second start

```bash
python -m pip install reality
```

After installation, run `reality` (or `python -m reality`) for the package greeting.

```python
import reality

world = reality.load("room.glb")

distance = world.distance("Chair", "Table")
print(distance.value, distance.units)  # 0.82 m

if world.near("Chair", "Table", within=1.0).value:
    print("The chair is within one metre of the table.")

visibility = world.visible("Television", from_="Sofa")
print(visibility.value, visibility.visibility_fraction)

for relationship in world.relationships("Chair"):
    print(relationship.type.value, relationship.target.name)

future = world.branch()
future.move("Table", x=1.0)

for consequence in future.consequences():
    print(consequence)
```

For deterministic alternate-world searches, use one shared snapshot and compact deltas:

```python
from reality.predicates import collision, distance, maximize, no_collision

futures = world.futures(10_000).randomize_position(
    "Table", x=(-1.0, 1.0), y=(-0.5, 0.5), z=(0.0, 0.0), seed=7
)
ranked = futures.evaluate([collision("Table", "Sofa"), distance("Table", "Sofa")]).rank(
    constraints=[no_collision("Table", "Sofa")],
    objectives=[maximize(distance("Table", "Sofa"))],
)
selected = ranked.best(5)[0].materialize()  # only this candidate becomes a branch
```

`World.explore()` is the higher-level deterministic search API. It creates compact
futures, applies hard constraints, ranks exact predicate results, and materializes only
the returned candidates. Its default backend is CUDA when a validated CUDA device is
available, otherwise the same CPU reference semantics are used.

```python
from reality.predicates import distance, maximize, no_collision

result = world.explore(
    possibilities=100_000,
    changes=[reality.position("Table", x=(-1.0, 1.0), y=(-1.0, 1.0))],
    constraints=[no_collision("Table", "Sofa")],
    objectives=[maximize(distance("Table", "Sofa"))],
    seed=42,
)
print(result.backend, result.best(1)[0].score)
print(result.to_json())
```

Every query returns a `PredicateResult`, so callers can inspect `value`, `measurement`, `units`, `reason`, `evidence`, and the involved `objects`.

## Current scope

- Python 3.11+ and typed public APIs
- GLB, glTF, and OBJ loading through Trimesh
- `World`, `WorldObject`, `Transform`, `Bounds`, and `PredicateResult`
- Deterministic AABB-based `distance`, `intersects`, `above`, `below`, `inside`, and `near` queries
- An incrementally maintainable `RealityGraph` with `near`, `above`, `below`,
  `inside`, `contains`, `intersects`, `touching`, and queried `visible_from` edges
- Deterministic AABB ray visibility through `world.visible(target, from_=viewer)`
- Immutable snapshots, copy-on-write world branches, typed transform changes,
  dependency-aware recomputation, and serializable consequence reports
- Compact `World.futures()` batches with deterministic CPU collision, distance, and
  AABB visibility predicates, filtering, ranking, and lazy materialization
- `World.explore()` for seeded, exact constraint search with structured scores,
  deltas, constraints, evidence, and selected future materialization
- Optional Warp CUDA batch transforms, collision, distance, and centre-ray AABB
  visibility, always checked against NumPy CPU oracles on CUDA-capable test hosts
- Dimensioned agents with deterministic CPU occupancy grids, A* paths,
  reachability, passage checks, clearance evidence, and SVG debug export

## Agents and navigation

```python
person = world.agent(name="Person", height=1.75, radius=0.30)

path = person.path_to("Exit")
print(path.reachable, path.distance, path.minimum_clearance)
print([object_.name for object_ in path.blocked_by])

person.can_reach("Kitchen")
person.can_pass("Door")
person.clearance_to("Exit")
```

See `examples/navigation.py` and `examples/navigation_branch.py` for runnable programmatic scenes.

## Runnable v0.1 demos

All demos construct a scene programmatically and write a single JSON document to stdout:

```bash
python examples/room_layout_optimization.py
python examples/game_level_clearance.py
python examples/mechanism_feasibility.py
python examples/robot_planning.py
```

The optional learned candidate prioritizer is intentionally isolated behind
`pip install "reality[learn]"`. It can only propose ordering; final candidates are
always checked using the exact Reality predicate/physics path. See
`tools/generate_explore_dataset.py` and `tools/train_explore_predictor.py`.

The current geometry layer intentionally uses world-axis-aligned bounding boxes. This is predictable, fast, and backend-neutral; it is not an exact triangle-mesh collision system.

Run the examples with `python examples/query_room.py`, `python examples/visibility.py`, and `python examples/relationships.py` after substituting your scene path and object names.

## Development

```bash
python -m pip install -e ".[dev]"
ruff format --check .
ruff check .
python -m mypy src/reality
pytest -q
```

See [PROJECT.md](PROJECT.md), [ARCHITECTURE.md](ARCHITECTURE.md), [API_DESIGN.md](API_DESIGN.md), [ROADMAP.md](ROADMAP.md), and [CONTRIBUTING.md](CONTRIBUTING.md).

Licensed under [Apache-2.0](LICENSE).

## Articulation, physics, and batch branches

Joints are explicit. Reality samples the entire swept AABB path and refines the first
collision boundary; it does not infer hinges from arbitrary meshes.

```python
door = world.articulate(
    "Door", joint="revolute", pivot=(0, 0, 0), axis=(0, 0, 1), limits=(0, 110)
)
print(door.can_rotate(90).reason)
```

### Import explicit metadata

For a portable imported scene, place a `room.reality.json` file next to
`room.glb`/`room.gltf` (or use `extras.reality` in glTF/GLB). Metadata is explicit;
Reality does not infer a hinge, mass, or material behavior from object names.

```json
{
  "units": "m",
  "objects": {
    "Door": {
      "articulation": {
        "joint": "revolute",
        "axis": [0, 0, 1],
        "pivot": [0, 0, 0],
        "limits": [0, 110]
      },
      "physics": {"mass": 12, "dynamic": true, "friction": 0.5}
    }
  }
}
```

You may instead pass this mapping directly: `reality.load("room.glb", metadata=metadata)`.
An explicit `metadata=` argument overrides the embedded document, which overrides the
sidecar. `units` labels mesh coordinates; it never silently rescales geometry.

Install the replaceable MuJoCo CPU physics backend with `pip install -e ".[physics]"`:

```python
world.set_physics("Box", mass=2.0, dynamic=True)
result = world.push("Box", force=(20, 0, 0), duration=0.2)
print(result.body("Box").final_transform)
```

Physical defaults are explicit: static, 1 kg, local-bounds box collider, friction 0.5,
restitution 0, and center-of-mass offset `(0, 0, 0)`. Semantic materials are not
inferred. The CPU backend maps orientation and center-of-mass data into MuJoCo. It
caches compiled topology locally and reports setup/step timing in `result.evidence`.
MuJoCo contact compliance is not a literal restitution mapping, and simulation joints
are still outside the current scope.

`world.branches(10_000)` shares one immutable snapshot and stores only `N x 3`
translation arrays for changed objects. CPU collision-batch evaluation is implemented.
Warp is optional. Reality contains custom Warp kernels for batched transforms, AABB
overlap, AABB distance, and centre-ray AABB visibility, with CPU reference
implementations and synchronized validation tools. CUDA is never claimed active without
a usable driver, successful launches, and CPU/GPU parity evidence. GPU AABB visibility is
not mesh-exact visibility.

## Distribution status

The package metadata uses the distributable name `reality` and keeps the import name
`reality`. Before publishing, run `python -m build`, install the generated wheel in a
fresh virtual environment, then reserve/upload the name. A PyPI name probe is inherently
time-sensitive and is recorded in `RELEASE_RESULTS.json` rather than asserted in prose.
