AFrame: position offset units when adding new Object3D to the current one

喜欢而已 提交于 2021-02-08 08:44:37

问题


I'm trying to add an Object3D to my gltf model and place it above the model. I'm doing it the following way:

this.el.addEventListener('model-loaded', () => {

            this.bar = new MyCustomObject3D();

            const size = new THREE.Vector3();
            let box = new THREE.Box3().setFromObject(this.el.object3D);
            box.getSize(size)
            let height = size.y + 1;

            this.bar.position.set(0, height, 0);
            this.el.setObject3D("bar", this.bar);
            // same result: 
            // this.el.object3D.add(this.bar); 
        })

The height is 2 and if I placed an element with this position into root (i.e. scene) it would be placed correctly right above the model. But when I add it to the Object3D it's being placed somewhere below the model on height ~0.5. Only by multiplying the height by 25 I could achieve the right position. So how to calculate the exact offset needed to place the new Object3D above the model without multiplying it to a random number?

UPDATE:

Adding reproducible example. Note the width and height I had to pass to GLTF model.


回答1:


One way of placing objects above a model, would be grabbing its bounding box, and placing an object above it.

In general, it it simple - just like you did it:

let box = new THREE.Box3().setFromObject(this.el.object3D);
box.getSize(size)
let height = size.y + 1;
this.bar.position.set(0, height, 0);

But in this case - the bounding box is off. Way off. The minimum is way too low, and the maximum is somewhere in the middle. Why is that? (tldr: check it out here)

The cuprit is: skinning. The model is transformed by its bones - which is a form of vertex displacement that happens on the GPU (vertex shader), and has nothing to do with the geometry (source).

Here is some visual aid - the model with its armature: And without the armature applied:

Now we see why the box is off - its corresponding to the bottom picture! So we need to re-create what the bones are doing to the geometry:

1. The hard route

  1. You need to take a THREE.Box3.
  2. Iterate through each geometry point of the model
  3. Apply the bone transform to each point (it is done here - but not available in a-frame 1.0.4)
  4. Expand the THREE.Box3

2. The easy route
While looking into this, I've made a utility function THREE.Box3Utils.fromSkinnedMesh(mesh, box3); - box3 will be the bounding box of the model at the time when the function is called. The function is a part of this repo. Its used on this example.



来源:https://stackoverflow.com/questions/64747675/aframe-position-offset-units-when-adding-new-object3d-to-the-current-one

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!