See Also: PhysicsWorld
Urho3D implements rigid body physics simulation using the Bullet library.
The physics simulation has its own fixed update rate, which by default is 60Hz. When the rendering framerate is higher than the physics update rate, physics motion is interpolated so that it always appears smooth. The update rate can be changed with PhysicsWorld.Fps property. The physics update rate also determines the frequency of fixed timestep scene logic updates. Hard limit for physics steps per frame or adaptive timestep can be configured with PhysicsWorld.MaxSubSteps property. These can help to prevent a "spiral of death" due to the CPU being unable to handle the physics load. However, note that using either can lead to time slowing down (when steps are limited) or inconsistent physics behavior (when using adaptive step.)
The other physics components are:
- RigidBody: a physics object instance. Its parameters include mass, linear/angular velocities, friction and restitution.
- CollisionShape: defines physics collision geometry. The supported shapes are box, sphere, cylinder, capsule, cone, triangle mesh, convex hull and heightfield terrain (requires the Terrain component in the same node.)
- Constraint: connects two RigidBodies together, or one RigidBody to a static point in the world. Point, hinge, slider and cone twist constraints are supported.
Movement and Collision
Both a RigidBody and at least one CollisionShape component must exist in a scene node for it to behave physically (a collision shape by itself does nothing.) Several collision shapes may exist in the same node to create compound shapes. An offset position and rotation relative to the node's transform can be specified for each. Triangle mesh and convex hull geometries require specifying a Model resource and the LOD level to use.
CollisionShape provides two APIs for defining the collision geometry. Either setting individual properties such as the shape type or size, or specifying both the shape type and all its properties at once using CollisionShape.SetBox, CollisionShape.SetCapsule or CollisionShape.SetTriangleMesh for example.
RigidBodies can be either static or moving. A body is static if its mass is 0, and moving if the mass is greater than 0. Note that the triangle mesh collision shape is not supported for moving objects; it will not collide properly due to limitations in the Bullet library. In this case the convex hull shape can be used instead.
The collision behaviour of a rigid body is controlled by several variables.
First, the collision layer and mask define which other objects to collide with: see RigidBody.SetCollisionLayerAndMask. By default a rigid body is on layer 1; the layer will be ANDed with the other body's collision mask to see if the collision should be reported. A rigid body can also be set to trigger mode to only report collisions without actually applying collision forces. This can be used to implement trigger areas. Finally, the friction, rolling friction and restitution coefficients (between 0 - 1) control how kinetic energy is transferred in the collisions. Note that rolling friction is by default zero, and if you want for example a sphere rolling on the floor to eventually stop, you need to set a non-zero rolling friction on both the sphere and floor rigid bodies.
By default rigid bodies can move and rotate about all 3 coordinate axes when forces are applied. To limit the movement, use RigidBody.SetLinearFactor and RigidBody.SetAngularFactor and set the axes you wish to use to 1 and those you do not wish to use to 0. For example moving humanoid characters are often represented by a capsule shape: to ensure they stay upright and only rotate when you explicitly set the rotation in code, set the angular factor to 0, 0, 0.
To prevent tunneling of a fast moving rigid body through obstacles, continuous collision detection can be used. It approximates the object as a swept sphere, but has a performance cost, so it should be used only when necessary. Set the CcdRadius and CcdMotionThreshold with non-zero values to enable. To prevent false collisions, the body's actual collision shape should completely contain the radius. The motion threshold is the required motion per simulation step for CCD to kick in: for example a box with size 1 should have motion threshold 1 as well.
All physics calculations are performed in world space. Nodes containing a RigidBody component should preferably be parented to the Scene (root node) to ensure independent motion. For ragdolls this is not absolute, as retaining proper bone hierarchy is more important, but be aware that the ragdoll bones may drift far from the animated model's root scene node.
When several collision shapes are present in the same node, edits to them can cause redundant mass/inertia update computation in the RigidBody. To optimize performance in these cases, the edits can be enclosed between calls to RigidBody.DisableMassUpdate and RigidBody.EnableMassUpdate.
Constraint position (and rotation if relevant) need to be defined in relation to both connected bodies, see Constraint.SetPosition and Constraint.SetOtherPosition. If the constraint connects a body to the static world, then the "other body position" and "other body rotation" mean the static end's transform in world space. There is also a helper function Constraint.SetWorldPosition to assign the constraint to a world-space position; this sets both relative positions.
Specifying the constraint's motion axis instead of rotation is provided as an alternative as it can be more intuitive, see Constraint.SetAxis. However, by explicitly specifying a rotation you can be sure the constraint is oriented precisely as you want.
Hinge, slider and cone twist constraints support defining limits for the motion. To be generic, these are encoded slightly unintuitively into Vector2’s. For a hinge constraint, the low and high limit X coordinates define the minimum and maximum angle in degrees. For example -45 to 45. For a slider constraint, the X coordinates define the maximum linear motion in world space units, and the Y coordinates define maximum angular motion in degrees. The cone twist constraint uses only the high limit to define the maximum angles (minimum angle is always -maximum) in the following manner: The X coordinate is the limit of the twist (main) axis, while Y is the limit of the swinging motion about the other axes.
The physics world sends 8 types of events during its update step:
- PhysicsWorld.PhysicsPreStep: before the simulation is stepped.
- PhysicsWorld.PhysicsCollisionStart: for each new collision during the simulation step. The participating scene nodes will also send Node.NodeCollisionStart event.
- PhysicsWorld.PhysicsCollision for each ongoing collision during the simulation step. The participating scene nodes will also send Node.NodeCollision events.
- PhysicsWorld.PhysicsCollisionEnd for each collision which has ceased. The participating scene nodes will also send Node.NodeCollisionEnd event.
- PhysicsWorld.PhysicsPostStep after the simulation has been stepped.
Note that if the rendering framerate is high, the physics might not be stepped at all on each frame: in that case those events will not be sent.
Reading collision events
A new or ongoing physics collision event will report the collided scene nodes and rigid bodies, whether either of the bodies is a trigger, and the list of contact points.
These are returned in a CollisionData array, from the “Contacts” property of the EventArguments for the various physics events.
Assembly: Urho (in Urho.dll)
Assembly Versions: 126.96.36.199
The members of Urho.Physics.PhysicsWorld are listed below.
See Also: Component
|ApplyingTransforms||Boolean. Return whether node dirtying should be disregarded.|
|Fps||Int32. Return simulation steps per second. Or Set simulation substeps per second.|
|[read-only]||Gravity||Vector3. Return gravity.|
|InternalEdge||Boolean. Return whether Bullet's internal edge utility for trimesh collisions is enabled. Or Set whether to use Bullet's internal edge utility for trimesh collisions. Disabled by default.|
|Interpolation||Boolean. Return whether interpolation between simulation steps is enabled. Or Set whether to interpolate between simulation steps.|
|MaxNetworkAngularVelocity||Single. Return maximum angular velocity for network replication. Or Set maximum angular velocity for network replication.|
|MaxSubSteps||Int32. Return maximum number of physics substeps per frame. Or Set maximum number of physics substeps per frame. 0 (default) is unlimited. Positive values cap the amount. Use a negative value to enable an adaptive timestep. This may cause inconsistent physics behavior.|
|NumIterations||Int32. Return number of constraint solver iterations. Or Set number of constraint solver iterations.|
|[read-only]||Simulating||Boolean. Return whether is currently inside the Bullet substep loop.|
|SplitImpulse||Boolean. Return whether split impulse collision mode is enabled. Or Set split impulse collision mode. This is more accurate, but slower. Disabled by default.|
|Type||StringHash. Urho's type system type.|
|TypeName||String. Urho's low-level type name.|
|TypeNameStatic||String. Urho's low-level type name, accessible as a static method.|
|TypeStatic||StringHash. Urho's low-level type, accessible as a static method.|
|UpdateEnabled||Boolean. Return whether physics world will automatically simulate during scene update. Or Enable or disable automatic physics simulation during scene update. Enabled by default.|
Add a collision shape to keep track of. Called by CollisionShape.
Add a constraint to keep track of. Called by Constraint.
Add a rigid body to keep track of. Called by RigidBody.
Clean up the geometry cache.
|ConvexCast(ref PhysicsRaycastResult, CollisionShape, Vector3, Quaternion, Vector3, Quaternion, UInt32)|
Perform a physics world swept convex test using a user-supplied collision shape and return the first hit.
Add debug geometry to the debug renderer.
Visualize the component as debug geometry.
Return debug draw flags.
|RaycastSingle(ref PhysicsRaycastResult, Ray, Single, UInt32)|
Perform a physics world raycast and return the closest hit.
|RaycastSingleSegmented(ref PhysicsRaycastResult, Ray, Single, Single, UInt32)|
Perform a physics world segmented raycast and return the closest hit. Useful for big scenes with many bodies.
Register object factory.
Invalidate cached collision geometry for a model.
Remove a collision shape. Called by CollisionShape.
Remove a constraint. Called by Constraint.
Remove a rigid body. Called by RigidBody.
Set debug geometry depth test mode. Called both by PhysicsWorld itself and physics components.
Set debug draw flags.
Set debug renderer to use. Called both by PhysicsWorld itself and physics components.
|SphereCast(ref PhysicsRaycastResult, Ray, Single, Single, UInt32)|
Perform a physics world swept sphere test and return the closest hit.
Subscribes to the PhysicsCollision event raised by the PhysicsWorld.
Subscribes to the PhysicsCollisionEnd event raised by the PhysicsWorld.
Subscribes to the PhysicsCollisionStart event raised by the PhysicsWorld.
Subscribes to the PhysicsPostStep event raised by the PhysicsWorld.
Subscribes to the PhysicsPreStep event raised by the PhysicsWorld.
Step the simulation forward.
Refresh collisions only without updating dynamics.
|PhysicsCollision||Event raised for each ongoing collision during the simulation step|
|PhysicsCollisionEnd||Event raised for each collision which has ceased.|
|PhysicsCollisionStart||Event raised or each new collision during the simulation step.|
|PhysicsPostStep||Event raised when the physics world has stepped.|
|PhysicsPreStep||Event raised when the physics world is about to be stepped.|