By default, Spatial SDK objects don’t simulate real-world physics and lack physical properties like collision detection and gravity. For instance, objects cannot collide with other objects, free fall when placed above the ground, and other common physical behaviors. To mimic real-world physics, Spatial SDK provides you with a way to set up and configure the physics engine and enable physics for entities.
PhysicsFeature
Registering PhysicsFeature is the starting point for setting up physics. Add PhysicsFeature to the list of features defined in the registerFeatures hook of your main activity:
import com.meta.spatial.physics.PhysicsFeature
override fun registerFeatures(): List<SpatialFeature> {
return listOf(PhysicsFeature(spatial))
}
Behind the scenes, the Meta Spatial app runtime will initiate the work of setting up the physics engine, creating the physics objects, and more.
Physics component
Attach the Physics component to an entity to enable physics.
Spatial SDK currently supports only rigid body physics, and all units are in the metric system (meters, kilograms, Newtons).
shape: the geometric shape of the physics object you want to simulate. Supported shapes include box, sphere, and custom shapes. For simple custom shapes, you should pass the URI of the glTF file to the shape parameter.
linearVelocity: the linear velocity of the physics object.
angularVelocity: the angular velocity of the physics object.
dimensions: the dimensions of the physics object. This parameter specifies the length (dimensions.x), height (dimensions.y), and width (dimensions.z) for a box shaped object as well as the radius (dimensions.x) for a sphere object.
density: the mass density of the physics object. The mass of a physics object is the product of its density and its volume.
restitution: a measure of the collision elasticity with the physics object.
friction: the friction of the physics object. The friction object contains three floating numbers to represent different friction coefficients: slidingFriction, rollingFriction, and spinningFriction.
state: the simulation state of the physics object, with possible values being: dynamic, static and kinematic. dynamic means the physics object can be affected by forces and collisions. static means the physics object cannot be affected by forces but can collide. kinematic means the physics object cannot affected by forces but can move and cause collisions.
applyForce: the external force to apply to the physics object.
Custom shapes should be used sparingly. Simulating physics for a complicated glTF model degrades performance significantly. Use low-poly models instead of complex ones.
Physics simulation
After registering the PhysicsFeature and attaching the Physics components to the entities, the app automatically starts the physics simulation when the app runs.
Miscellaneous
PhysicsFeature is configurable. You can also add a PhysicsOutOfBoundsSystem to your application if you want to set boundaries for the physics objects.
PhysicsFeature configurations
When registering PhysicsFeature, you can specify whether to enable grabbable physics.
You can configure it like this:
class PhysicsFeature(val spatial: SpatialInterface, val useGrabbablePhysics: Boolean = true) :
SpatialFeature {
...
}
When grabbable physics is enabled, grabbed physics entities will have a physics state of kinematic, meaning they cannot be affected by external forces. If grabbable physics is disabled, grabbed physics entities will retain their physics state, be it static, dynamic or kinematic.
PhysicsOutOfBoundsSystem
By default, a Meta Spatial app does not set any boundaries in the physics environment. If you want to clean up or destroy entities that are out of the bounds, you can use the PhysicsOutOfBoundsSystem.
Here’s an example implementation of PhysicsOutOfBoundsSystem. This system automatically removes entities that are 100 meters below the origin point of the scene:
override fun onCreate(savedInstanceState: Bundle?) {
// Add a system to remove objects that fall out of bounds
systemManager.registerSystem(
PhysicsOutOfBoundsSystem(spatial).apply { setBounds(minY = -100.0f) })
}
You can define the bounds of the physics world using the setBounds method in the PhysicsOutOfBoundsSystem:
Meta Spatial apps use a left-handed 3D coordinate system. The positive x-axis points to the right. The positive y-axis points up. The positive z-axis points away from the screen.