Anathapindika
Anathapindika

Reputation: 141

Aframe, 3dio scene: orientation changes

I used to upload a 3dio scene into a-frame via the bakedModelUrl

<a-entity io3d-data3d="key:/3f995099-d624-4c8e-ab6b-1fd5e3799173/170515-0913-4p3ktf/1e588a3b-90ac-4a32-b5b8-ff2fda7f87c4.gz.data3d.buffer"></a-entity>

which is described here: https://3d.io/docs/api/1/aframe-components.html

but while using this method (via sceneId):

const scene = document.querySelector('a-scene')
io3d.scene.getAframeElements(sceneId)
.then(elements => {
// this will give us two elements
// The first is the actual scene according to the scene structure hierarchy
// The second is the camera with potential waypoints that where defined in the scene structure
// you can leverage the waypoints using our A-Frame tour component
elements.forEach((el) => {
  // add elements to the scene
  scene.appendChild(el)
})
scene.appendChild(element)
})

which is described here: https://3d.io/docs/api/1/scene.html, I don't seem to get the same orientation of the models.

have a look:

https://codepen.io/Anathapindika/pen/mqzGPB?editors=1011 (bakedModelUrl Method - camera position = "10 10 0")

https://codepen.io/Anathapindika/pen/RjBxqO (sceneId Methode - camera position = "0 10 0")

Upvotes: 3

Views: 285

Answers (2)

Frederic
Frederic

Reputation: 326

io3d.scene.getAframeElements(sceneId)

imports the entire scene hierarchy and creates corresponding A-Frame nodes.

The baked model is bound to the level node which is a child of the plan node. the plan node is the highest hierarchy. https://3d.io/docs/api/1/scene-structure-reference.html#level

An assumption is that in your case the plan node has rotation or position changes.

To import a scene without applying the root rotation and position you have two options:

Adapt the sceneStructure before importing:

io3d.scene.getStructure(sceneId)
  .then(sceneStructure => {
     // root node is the 'plan' node. reset it's position and rotation
     sceneStructure.x = sceneStructure.z = sceneStructure.ry = 0
     // convert sceneStructure to A-Frame Elements
     var elements = io3d.scene.getAframeElementsFromSceneStructure(sceneStructure)
     // add elements to the scene
     elements.forEach((el) => {
       // add elements to the scene
       scene.appendChild(el)
     })
  })

Or adapt the root DOM element directly after importing

io3d.scene.getAframeElements(sceneId)
  .then(elements => {
    elements[0].setAttribute('position', '0 0 0')
    elements[0].setAttribute('rotation', '0 0 0')
    // add elements to the scene
    elements.forEach((el) => {
      // add elements to the scene
      scene.appendChild(el)
    })
 })

Upvotes: 1

geekonaut
geekonaut

Reputation: 5954

I agree that this seems surprising and we need to either rethink this behaviour or explain it better.

There is a subtle difference between using the io3d-data3d component directly vs. using io3d.scene-methods to import the entire scene structure into A-Frame.

Basically the data3d is part of the scene structure, but the scene structure contains more than just the data3d. It's noteworthy that the data3d is usually not the top-level object.

Now, what does that mean?

That means, that the scene structure supports things such as multiple levels (aka floors or storeys), each having their own data3d model inside them. Each of the data3d models can then be rotated individually and the top-level scene object can be rotated as well.

When using the data3d model directly, you won't get these rotations while you do get them when using the scene structure methods.

However, in your particular case I checked the JSON to find all rotation is 0 anyway but then I noticed something: The two models actually look different. Is it possible that the data3d URL is outdated (each time you redo realistic lighting, the data3d URL will change.

If I use the new data3d URL, the orientation is the same in both codepens.

Upvotes: 1

Related Questions