Skip to main content
Participant
February 10, 2025

Relationship between SceneObject and Entity

  • February 10, 2025
  • 3 replies
  • 908 views

I am able to create SceneObjects and view them:

val sceneObject = SceneObject(scene, mesh, "foo-object")
sceneObject.setPosition(x,y,z)
sceneObject.setVisible(true)

But I want to add this object to the ECS scene graph. I thought maybe the "entity" parameter specified the parent:

val sceneObject = SceneObject(scene, mesh, "foo-object", parentEntity)

but it does NOT seem to inherit the parentEntity transform.

I have also tried using the Entity.create() method to include the sceneObject:

Entity.create(listOf(SceneObject(scene, mesh, "foo-object"), ...)))

but this won't even compile (I assume because SceneObject is not a "component"?).

I really don't see how to include SceneObject's into a scene graph? How does this work? What it the "entity" parameter for the SceneObject constructor?


    This topic has been closed for replies.

    3 replies

    Meta Employee
    February 13, 2025

    Hi,

    The entity argument when creating a SceneObject is actually meant to represent the entity the SceneObject is tied to, not its parent entity. We recommend setting the SceneObject’s transform via ECS by using the Transform component instead of using the sceneObject.setPosition API directly. We also have a TransformParent component that can be used to make a hierarchy in the scene. Here’s an example of how you could create a SceneObject and use ECS to position it:

    val mesh = SceneMesh(...)
    val parentEntity = Entity.create(Transform(Pose(Vector3(1f, 2f, 3f))))
    
    // TransformParent makes sceneObjectEntity (and its associated SceneObject) positioned at
    // an offset from parentEntity’s transform
    val sceneObjectEntity = Entity.create(Transform(Pose(Vector3(1f, 2f, 3f))), TransformParent(parentEntity)) 
    
    // so in this case our created sceneObject would be placed at point (2, 4, 6)
    val sceneObject = SceneObject(scene, mesh, "foo-object", sceneObjectEntity)
    
    Meta Employee
    February 21, 2025

    On top of this, make sure to add the SceneObject to the SceneObjectSystem:

    systemManager
    .findSystem<SceneObjectSystem>()
    .addSceneObject(
    fooEntity,
    CompletableFuture<SceneObject>().apply { complete(fooObject) })

    This ensures the object will be hooked up to the ECS and things like Visible and Scale will work as expected.

    Participant
    February 24, 2025

    Thank you. This works using Transform(Pose(...)) components in that the transforms are properly applied to the children in a hierarchical manner. But Scale components do not seem to propagate to their child entities. 

    For example, given I have a parentEntity that contains a Scale and Transform component, say I attach some child entities as listed below. Note that a sceneObject is created and placed inside each child entity:

    for (mesh in meshes) {
                val entity = Entity.create(
                    listOf(
                        TransformParent(parentEntity),
                        Scale(Vector3(1f)),    // no scale
                        Transform(Pose(t = Vector3(0f, 0f, 0f), q = Quaternion(w = 1f, x = 0f, y = 0f, z = 0f))) // identity
                    )
                )
                val sceneObject = SceneObject(scene, mesh, "mesh", entity = entity)
                
                sceneObjectSystem.addSceneObject(
                    entity,
                    CompletableFuture<SceneObject>.apply {
                        complete(sceneObject)
                    }
                )
    }

    Later I set the transform and scale components in the parentEntity as follows:

    parentEntity.setComponent(Transform(updatedPose))
    parentEntity.setComponent(Scale(2f, 3f, 1f))

    The Transform component works properly (i.e. is properly inherited by its children), but the added Scale component has no effect. Is there something special I need to set up for the scale to be propagated to its children?