simvx.core.physics.shapes¶
Role¶
A Shape is a plain collision-geometry resource (a value), not a scene
node. It is held by a :class:~simvx.core.physics.nodes.CollisionShape3D
node (via a Property) the way the old bodies held a radius/extents
field. A body never branches on shape kind: it calls shape.build(world) and
each subclass dispatches to the seam’s matching world.create_* factory. This
keeps body nodes open/closed over new shape kinds.
Stage 3a status¶
Additive and non-breaking. The concrete classes are dimension-suffixed
SphereShape3D / BoxShape3D (the abstract Shape base stays
un-suffixed, being dimensionless), distinct from the GJK CollisionShape
subclasses in collision.py. They live ONLY here. They are NOT exported via
physics/__init__.py or core/__init__.py: tests import them via this
module path. The facade flip + removal of the old shapes is Stage 4.
Shape resources for the new physics seam (Stage 3a).
Module Contents¶
Classes¶
Abstract collision-geometry resource. |
|
A sphere collision shape of a given radius. |
|
An axis-aligned box collision shape centred at the origin. |
|
A Y-axis capsule collision shape (a segment swept by a sphere). |
|
A Y-axis cylinder collision shape. |
|
A convex-hull collision shape defined by a point cloud (Tier-1). |
|
A static triangle-mesh collision shape (level geometry, Tier-1 static-only). |
Data¶
API¶
- simvx.core.physics.shapes.__all__¶
[‘Shape’, ‘SphereShape3D’, ‘BoxShape3D’, ‘CapsuleShape3D’, ‘CylinderShape3D’, ‘ConvexHullShape3D’, ‘…
- class simvx.core.physics.shapes.Shape[source]¶
Bases:
abc.ABCAbstract collision-geometry resource.
A
Shapeknows how to turn itself into an opaque seam shape handle via- Meth:
build. Bodies callshape.build(world)and never inspect the concrete kind, so adding a new shape requires no body changes.
- abstractmethod build(world: simvx.core.physics.world.PhysicsWorld) simvx.core.physics.world.ShapeHandle[source]¶
Create the backend shape for this resource and return its handle.
Each subclass dispatches to the matching
world.create_*factory.Args: world: The :class:
~simvx.core.physics.world.PhysicsWorldwhose shape factory builds the opaque handle.Returns: An opaque
ShapeHandlefor use withworld.create_body.
- abstract property bounding_radius: float[source]¶
Radius of the shape’s origin-centred bounding sphere, in local units.
A conservative, rotation-invariant size used for cheap broad-phase / CPU picking (a sphere test against the shape’s extent). Each subclass returns the radius of the smallest sphere centred on the shape’s local origin that contains it.
- __slots__¶
()
- class simvx.core.physics.shapes.SphereShape3D(radius: float = 0.5)[source]¶
Bases:
simvx.core.physics.shapes.ShapeA sphere collision shape of a given radius.
Args: radius: Sphere radius in world units (must be > 0).
Initialization
- __slots__¶
()
- class simvx.core.physics.shapes.BoxShape3D(half_extents: simvx.core.math.Vec3 | tuple[float, float, float] = (0.5, 0.5, 0.5))[source]¶
Bases:
simvx.core.physics.shapes.ShapeAn axis-aligned box collision shape centred at the origin.
Args: half_extents: Half-sizes along x/y/z. Coerced to
Vec3(float32); every component must be > 0.Initialization
- __slots__¶
()
- class simvx.core.physics.shapes.CapsuleShape3D(radius: float = 0.5, height: float = 2.0)[source]¶
Bases:
simvx.core.physics.shapes.ShapeA Y-axis capsule collision shape (a segment swept by a sphere).
heightis the TOTAL extent along Y, including the two hemispherical caps, so the central segment half-length ismax(0.0, height / 2 - radius)and the segment endpoints arecentre +- [0, half_len, 0]. Whenheight <= 2 * radiusthe segment collapses to a point and the capsule degenerates to a sphere of the given radius: that is a valid, documented case (matching Godot’s capsule and the segment-reduction maths in the builtin backend), NOT an error. Accordinglyheight >= 2 * radiusis NOT validated.Args: radius: Capsule radius in world units (must be > 0). height: Total extent along Y including both caps (must be > 0).
Initialization
- __slots__¶
()
- class simvx.core.physics.shapes.CylinderShape3D(radius: float = 0.5, height: float = 2.0)[source]¶
Bases:
simvx.core.physics.shapes.ShapeA Y-axis cylinder collision shape.
heightis the TOTAL extent along Y, with flat circular top/bottom caps at+-height / 2.Args: radius: Cylinder radius in world units (must be > 0). height: Total extent along Y (must be > 0).
Initialization
- __slots__¶
()
- class simvx.core.physics.shapes.ConvexHullShape3D(points: collections.abc.Sequence[simvx.core.math.Vec3 | tuple[float, float, float]])[source]¶
Bases:
simvx.core.physics.shapes.ShapeA convex-hull collision shape defined by a point cloud (Tier-1).
The hull is the convex hull of
points; the resource stores the raw cloud and the backend computes its own representation. At least 4 points are required (a 3D hull needs a tetrahedron). A coplanar / collinear cloud is accepted (it is finite and has >= 4 points) but yields a degenerate hull whose penetration depth is approximate: a full coplanarity test is deliberately NOT done at the resource layer (the backend tolerates degenerate clouds).Basic-tier honesty (see
builtin/world.py): the BuiltinPhysics backend does GJK for overlap (exact) and EPA-lite for penetration depth/normal (bounded iteration, documented approximation); hull rotation is ignored. The Jolt backend does a proper hull.Args: points: Iterable of >= 4 points (
Vec3or(x, y, z)tuples). Coerced to a single(N, 3)float32 array. Must be finite.Initialization
- classmethod from_mesh(vertices: collections.abc.Sequence[simvx.core.math.Vec3 | tuple[float, float, float]], indices: collections.abc.Sequence[int] | None = None) simvx.core.physics.shapes.ConvexHullShape3D[source]¶
Build a hull from a mesh’s VERTEX CLOUD (opt-in, per design S3).
The convex hull of a mesh equals the convex hull of its vertex cloud, so
indicesare ignored: this is a cheap, honest hull-from-mesh with no convex decomposition. Pass the mesh vertices and the topology is irrelevant to the result.Args: vertices: The mesh vertex cloud (
(N, 3)after coercion). indices: Ignored (the hull is independent of triangle topology).Returns: A
ConvexHullShape3Dover the vertex cloud.
- __slots__¶
()
- class simvx.core.physics.shapes.ConcaveMeshShape3D(vertices: collections.abc.Sequence[simvx.core.math.Vec3 | tuple[float, float, float]], indices: collections.abc.Sequence[int])[source]¶
Bases:
simvx.core.physics.shapes.ShapeA static triangle-mesh collision shape (level geometry, Tier-1 static-only).
Holds a triangle-list mesh as a vertex array plus a flat index array (three indices per triangle). This collider is STATIC-ONLY: placing it on a non-STATIC body is an error raised at body creation (every serious engine enforces this, including Jolt). It has no inertia / mass.
The
Shaperesource itself is a pure value with no static-mode awareness; the static-only contract is enforced at the world seam (create_body/set_body_mode), not here.Args: vertices: Vertex positions, coerced to a
(N, 3)float32 array; finite. indices: Flat triangle-list indices, coerced to a(3 * T,)int64 array.len(indices)must be a non-zero multiple of 3 and every index in[0, N).Initialization
- __slots__¶
()