Dynamic objects
Dynamic Objects are Meta Spatial SDK entities that Cognitive3D tracks for position, rotation, scale, and participant gaze over time. Register the entities participants interact with, such as imported models, tools, and panels, to see which content holds attention and how participants arrange it in space.
When you register a Dynamic Object, Cognitive3D automatically tracks:
- Position, rotation, and scale over time, from the entity's
TransformandScalecomponents. - Visibility, from the entity's
Visiblecomponent. - Participant gaze that hits the object.
Register entities as Dynamic Objects when:
- Participants can interact with them: models they can grab, move, or manipulate.
- They represent meaningful content: imported files, placed annotations, spawned tools.
- They appear or disappear during the session: to track the object's lifecycle.
The SDK tracks controllers and hands automatically. You don't need to register them.
Basic usage
Register a Dynamic Object after you create its entity:
import android.net.Uri
import com.meta.spatial.core.Entity
import com.meta.spatial.core.Pose
import com.meta.spatial.core.Vector3
import com.meta.spatial.toolkit.Box
import com.meta.spatial.toolkit.Mesh
import com.meta.spatial.toolkit.Transform
val homeModel = Entity.create(
listOf(
Mesh(Uri.parse("apk:///models/nice_home_3d.glb")),
Transform(Pose(Vector3(0f, 1f, -2f))),
Box(Vector3(-0.5f, 0f, -0.5f), Vector3(0.5f, 1.2f, 0.5f)) // Bounds for gaze hits
)
)
Cognitive3DManager.registerDynamicObject(
name = "model_nice_home_3d", // Name
meshName = "nice_home_3d", // Mesh name for grouping similar objects
trackable = homeModel // The Meta Spatial SDK Entity
)
Cognitive3DManager.registerDynamicObject(
"model_nice_home_3d", // Name
"nice_home_3d", // Mesh name for grouping similar objects
homeModel, // The Meta Spatial SDK Entity
null // Optional custom ID
);
name: The name of the object. Use the same name as the exported and uploaded 3D model.meshName: A category name for this type of object. All instances of the same model share a mesh name, which enables aggregate analysis, such as comparing attention on architectural models and product models. Use the same mesh name as the exported and uploaded 3D model.trackable: The Meta Spatial SDKEntity(com.meta.spatial.core.Entity) to track.id: Optional. A custom Dynamic Object ID. Leave itnullto let the SDK generate one. Java callers must pass this argument explicitly.
Gaze hit detection
The SDK detects gaze hits against the entity's Box component, which defines its local bounding box. The SDK reads the box once, when you register the entity. Add a Box component that matches your model's bounds before you call registerDynamicObject, as the basic usage example shows. To add one to an existing entity, call setComponent:
entity.setComponent(
Box(Vector3(-0.5f, 0f, -0.5f), Vector3(0.5f, 1.2f, 0.5f))
)
entity.setComponent(
new Box(new Vector3(-0.5f, 0f, -0.5f), new Vector3(0.5f, 1.2f, 0.5f))
);
Note
If the entity has no Box component when you register it, the SDK adds a default box 1 m wide, 1 m tall, and 0.1 m deep, centered on the entity. This default suits flat panels. Add your own Box for 3D models.
Unregister a Dynamic Object
Unregister an object before you destroy its entity, so the SDK stops tracking it:
Cognitive3DManager.unregisterDynamicObject(homeModel)
homeModel.destroy()
Cognitive3DManager.unregisterDynamicObject(homeModel);
homeModel.destroy();
Examples
Use Dynamic Objects when you need to track where 3D content is positioned and how participants interact with it spatially.
Registering imported 3D models
Track user-loaded models to see which files get the most attention and how participants position them in space:
fun onModelLoaded(model: LoadedModel, entity: Entity) {
// Register for spatial tracking
Cognitive3DManager.registerDynamicObject(
name = "model_${model.name}",
meshName = model.originalFileName.substringBeforeLast("."), // Group by original file
trackable = entity
)
// Send event with additional metadata (not tracked by dynamic object system)
Cognitive3DManager.sendCustomEvent("Model registered", mapOf(
"model_id" to model.id,
"model_name" to model.displayName,
"file_type" to model.fileExtension,
"polygon_count" to model.polygonCount,
"imported_by" to model.importedByUserId
))
}
public void onModelLoaded(LoadedModel model, Entity entity) {
// Register for spatial tracking
String fileName = model.getOriginalFileName();
String meshName = fileName.substring(0, fileName.lastIndexOf("."));
Cognitive3DManager.registerDynamicObject(
"model_" + model.getName(),
meshName,
entity,
null
);
// Send event with additional metadata
Map<String, Object> properties = new HashMap<>();
properties.put("model_id", model.getId());
properties.put("model_name", model.getDisplayName());
properties.put("file_type", model.getFileExtension());
properties.put("polygon_count", model.getPolygonCount());
properties.put("imported_by", model.getImportedByUserId());
Cognitive3DManager.sendCustomEvent("Model registered", properties);
}
Registering panels
Track spatial panels to see which ones participants look at. Panels are flat, so the default Box the SDK adds works without changes:
fun onPanelCreated(panelName: String, panelEntity: Entity) {
Cognitive3DManager.registerDynamicObject(
name = "panel_$panelName",
meshName = "panel",
trackable = panelEntity
)
}
public void onPanelCreated(String panelName, Entity panelEntity) {
Cognitive3DManager.registerDynamicObject(
"panel_" + panelName,
"panel",
panelEntity,
null
);
}
Best practices
What to register
- User-loaded content, such as models, images, and documents.
- Interactive tools, such as pointers, markers, and measurement tools.
- Persistent spatial content, such as annotations, pins, and labels.
What to skip
- Static environment geometry.
- Transient visual effects, such as particles and highlights.
- UI elements that aren't spatially meaningful.
See also
If you have a question or any feedback about our documentation please use the Intercom button (purple circle) in the lower right corner of any web page or join our Discord.