Forum Discussion

🚨 This forum is archived and read-only. To submit a forum post, please visit our new Developer Forum. 🚨
waynecochran's avatar
10 months ago

Relationship between SceneObject and Entity

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?


3 Replies

Replies have been turned off for this discussion
  • 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)
    
  • dav-s's avatar
    dav-s
    Meta Employee

    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.

    • 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?