Physics Engine¶
SimVX provides rigid body dynamics, impulse-based collision response, and constraint joints on top of the collision detection system described in Collision & Physics. The physics engine runs in the physics_process tick and integrates with the node lifecycle automatically.
PhysicsServer¶
PhysicsServer is a singleton that manages all physics bodies, steps the simulation, and emits overlap signals. Bodies register themselves on enter_tree and unregister on exit_tree.
from simvx.core.physics.engine import PhysicsServer, Vec3
server = PhysicsServer.get()
server.set_gravity(Vec3(0, -9.8, 0))
Each step(dt) performs: force integration, broadphase/narrowphase detection, iterative impulse solving, position integration, Baumgarte correction, and overlap signal dispatch.
PhysicsMaterial¶
Surface properties that control bounce and friction:
from simvx.core.physics.engine import PhysicsMaterial
rubber = PhysicsMaterial(friction=0.9, restitution=0.8, density=1.2)
ice = PhysicsMaterial(friction=0.05, restitution=0.1, density=0.9)
Field |
Default |
Description |
|---|---|---|
|
|
Coefficient of friction [0..1] |
|
|
Bounciness [0..1] – 1 is perfectly elastic |
|
|
Mass per unit volume |
Body Types¶
RigidBody2D / RigidBody3D¶
Fully simulated – affected by gravity, forces, and collisions:
from simvx.core.physics.engine import RigidBody3D, PhysicsMaterial
from simvx.core import SphereShape, Property
class Ball(RigidBody3D):
mass = Property(2.0)
physics_material = PhysicsMaterial(restitution=0.8)
def ready(self):
self.set_collision_shape(SphereShape(radius=0.5))
StaticBody2D / StaticBody3D¶
Immovable – infinite effective mass, never displaced by forces:
from simvx.core.physics.engine import StaticBody3D
from simvx.core import BoxShape, Vec3
ground = StaticBody3D(position=Vec3(0, -1, 0))
ground.set_collision_shape(BoxShape(half_extents=(50, 1, 50)))
KinematicBody2D / KinematicBody3D¶
Moved by code – not affected by forces, but pushes dynamic bodies:
from simvx.core.physics.engine import KinematicBody3D
from simvx.core import Vec3
import math
class MovingPlatform(KinematicBody3D):
def physics_process(self, dt):
t = self.get_process_time()
self.linear_velocity = Vec3(0, math.sin(t) * 2, 0)
Forces and Impulses¶
All body types with the _PhysicsBodyMixin support:
apply_force(force, position=None)– Continuous force integrated over the next step. Passpositionfor off-center torque.apply_impulse(impulse, position=None)– Instantaneous velocity change. Passpositionfor angular impulse.apply_torque(torque)– Continuous torque (Vec3 for 3D, scalar for 2D).
# Launch a ball upward
ball.apply_impulse(Vec3(0, 20, 0))
# Spin it
ball.apply_torque(Vec3(0, 5, 0))
Signals¶
body_entered(other)– Emitted when a new overlap begins.body_exited(other)– Emitted when a previously overlapping body separates.
Joints¶
Joints constrain the relative motion of two bodies.
PinJoint2D / PinJoint3D¶
Maintains a fixed distance between two bodies (distance auto-computed from initial positions if not specified):
from simvx.core.physics.engine import PinJoint3D
joint = PinJoint3D(body_a=ball_a, body_b=ball_b, stiffness=0.9, damping=0.1)
HingeJoint3D¶
Constrains rotation to a single axis, plus a pin-style distance constraint:
from simvx.core.physics.engine import HingeJoint3D
from simvx.core import Vec3
hinge = HingeJoint3D(
body_a=door, body_b=frame,
axis=Vec3(0, 1, 0), # Rotate around Y
angular_limit_min=-90.0,
angular_limit_max=90.0,
)
Bouncing Ball Example¶
from simvx.core import Node3D, Vec3, SphereShape, BoxShape, Property
from simvx.core.physics.engine import RigidBody3D, StaticBody3D, PhysicsMaterial
class BouncingBall(RigidBody3D):
mass = Property(1.0)
physics_material = PhysicsMaterial(restitution=0.9)
def ready(self):
self.set_collision_shape(SphereShape(radius=0.5))
self.position = Vec3(0, 10, 0)
class Floor(StaticBody3D):
def ready(self):
self.set_collision_shape(BoxShape(half_extents=(20, 0.5, 20)))
self.position = Vec3(0, -0.5, 0)
class Scene(Node3D):
def ready(self):
self.add_child(BouncingBall())
self.add_child(Floor())
API Reference¶
See simvx.core.physics.engine for the complete physics engine API.