2

I'm hoping someone can clarify what is happening behind the scenes here.

I have an object that I am loading via the following method:

var loader = new THREE.FBXLoader();
                loader.load( '../assets/models/Windia_C4D_Export.fbx', function ( object ) {
                //loader.load( '../assets/models/quiggles_AR.fbx', function ( object ) {
                    console.log(object);
                    object.traverse( function ( child ) {
                        console.log(child);
                        if ( child.isMesh ) {

                            const oldMat = child.material;
                            //CONVERT MATERIAL TO STANDARD MATERIAL.
                            child.material = new THREE.MeshStandardMaterial({
                                color: oldMat.color,
                                map: oldMat.map,
                            });

                            child.castShadow = true;
                            child.receiveShadow = true;
                            child.material.combine = THREE.MixOperation;
                            child.material.envMap = envMap;
                            child.material.shininess=10;
                            child.material.refractionRatio=.5;
                            child.material.reflectivity=0.1;
                            //child.material.normalMap = texture;
                            //child.material.normalMapType = 0;
                            child.material.metalness=1;
                            //child.material.color.setHex( 0xffffff );

                            var sphereAxis = new THREE.AxesHelper(200);
                            child.add(sphereAxis);

                        }

                    } );
                    console.log(object);
                    object.scale.set(1,1,1);
                    scene.add( object );

                } ); 

After iterating over all the children that are loaded and applying the same THREE.AxesHelper to each child that is a mesh object, every axeshelper is at the same position 0,0,0 instead of being aligned with the child they are associated with.

This is the result of logging the loaded object:

Group {uuid: "FBBF7E4B-7754-4138-BF1D-729398C2FB57", name: "VSM890D050Z05S22SN12_obj", type: "Group", parent: Group, children: Array(12), …}
ID: 140463347645952
animations: undefined
castShadow: false
children: (12) [Mesh, Mesh, Mesh, Mesh, Mesh, Mesh, Mesh, Mesh, Mesh, Mesh, Mesh, Mesh]
frustumCulled: true
layers: Layers {mask: 1}
matrix: Matrix4 {elements: Array(16)}
matrixAutoUpdate: true
matrixWorld: Matrix4 {elements: Array(16)}
matrixWorldNeedsUpdate: false
name: "VSM890D050Z05S22SN12_obj"
parent: Scene {uuid: "2D5254A0-ECA2-48D7-93D3-E0DD23E31277", name: "", type: "Scene", parent: null, children: Array(4), …}
position: Vector3 {x: 0, y: 0, z: 0}
quaternion: Quaternion {_x: 0, _y: 0, _z: 0, _w: 1, onChangeCallback: ƒ}
receiveShadow: false
renderOrder: 0
rotation: Euler {_x: -0, _y: 0, _z: -0, _order: "XYZ", onChangeCallback: ƒ}
scale: Vector3 {x: 1, y: 1, z: 1}
type: "Group"
up: Vector3 {x: 0, y: 1, z: 0}
userData: {transformData: {…}}
uuid: "FBBF7E4B-7754-4138-BF1D-729398C2FB57"
visible: true
eulerOrder: (...)
id: 17
modelViewMatrix: Matrix4 {elements: Array(16)}
normalMatrix: Matrix3 {elements: Array(9)}
useQuaternion: (...)
__proto__: Object3D

The following are expanded views of the first 2 child meshes in the group above. You can see the position of the axes helper are identical even though the items are in a different position within the loaded model.

Group {uuid: "FBBF7E4B-7754-4138-BF1D-729398C2FB57", name: "VSM890D050Z05S22SN12_obj", type: "Group", parent: Group, children: Array(12), …}
ID: 140463347645952
animations: undefined
castShadow: false
children: Array(12)
0: Mesh
ID: 140463347532800
castShadow: true
children: Array(1)
0: AxesHelper
castShadow: false
children: []
frustumCulled: true
geometry: BufferGeometry {uuid: "D2B77D74-2F72-4EC5-BBA3-B76A70E6C5D0", name: "", type: "BufferGeometry", index: null, attributes: {…}, …}
layers: Layers {mask: 1}
material: LineBasicMaterial {uuid: "253322F5-E482-4713-AF9B-D28DE8A06C35", name: "", type: "LineBasicMaterial", fog: true, lights: false, …}
matrix: Matrix4 {elements: Array(16)}
matrixAutoUpdate: true
matrixWorld: Matrix4 {elements: Array(16)}
matrixWorldNeedsUpdate: false
name: ""
parent: Mesh {uuid: "6A310982-D8A0-43B8-98F0-75C2B88BF8AE", name: "VSM890D050Z05S22SN12_11", type: "Mesh", parent: Group, children: Array(1), …}
position: Vector3 {x: 0, y: 0, z: 0}
quaternion: Quaternion {_x: 0, _y: 0, _z: 0, _w: 1, onChangeCallback: ƒ}
receiveShadow: false
renderOrder: 0
rotation: Euler {_x: 0, _y: 0, _z: 0, _order: "XYZ", onChangeCallback: ƒ}
scale: Vector3 {x: 1, y: 1, z: 1}
type: "LineSegments"
up: Vector3 {x: 0, y: 1, z: 0}
userData: {}
uuid: "3C46906A-BDBF-42D7-9608-52B7D9228271"
visible: true
eulerOrder: (...)
id: 30
modelViewMatrix: Matrix4 {elements: Array(16)}
normalMatrix: Matrix3 {elements: Array(9)}
useQuaternion: (...)
__proto__: LineSegments
length: 1
__proto__: Array(0)
drawMode: 0
frustumCulled: true
geometry: BufferGeometry {uuid: "ED7C9B64-2824-4364-AA97-3F92B00AC904", name: "", type: "BufferGeometry", index: null, attributes: {…}, …}
layers: Layers {mask: 1}
material: MeshStandardMaterial {uuid: "7BD69404-BFFF-4C54-A025-28F93AC84082", name: "", type: "MeshStandardMaterial", fog: true, lights: true, …}
matrix: Matrix4 {elements: Array(16)}
matrixAutoUpdate: true
matrixWorld: Matrix4 {elements: Array(16)}
matrixWorldNeedsUpdate: false
name: "VSM890D050Z05S22SN12_11"
parent: Group {uuid: "FBBF7E4B-7754-4138-BF1D-729398C2FB57", name: "VSM890D050Z05S22SN12_obj", type: "Group", parent: Scene, children: Array(12), …}
position: Vector3 {x: 0, y: 0, z: 0}
quaternion: Quaternion {_x: 0, _y: 0, _z: 0, _w: 1, onChangeCallback: ƒ}
receiveShadow: true
renderOrder: 0
rotation: Euler {_x: -0, _y: 0, _z: -0, _order: "XYZ", onChangeCallback: ƒ}
scale: Vector3 {x: 1, y: 1, z: 1}
type: "Mesh"
up: Vector3 {x: 0, y: 1, z: 0}
userData: {transformData: {…}}
uuid: "6A310982-D8A0-43B8-98F0-75C2B88BF8AE"
visible: true
eulerOrder: (...)
id: 18
modelViewMatrix: Matrix4 {elements: Array(16)}
normalMatrix: Matrix3 {elements: Array(9)}
useQuaternion: (...)
__proto__: Object3D
1: Mesh
ID: 140463525802496
castShadow: true
children: Array(1)
0: AxesHelper
castShadow: false
children: []
frustumCulled: true
geometry: BufferGeometry {uuid: "8D681768-AD23-49F4-BB4C-56ADB6A23695", name: "", type: "BufferGeometry", index: null, attributes: {…}, …}
layers: Layers {mask: 1}
material: LineBasicMaterial {uuid: "4DFCAAC0-F5A4-48B0-B417-FBEE4746E814", name: "", type: "LineBasicMaterial", fog: true, lights: false, …}
matrix: Matrix4 {elements: Array(16)}
matrixAutoUpdate: true
matrixWorld: Matrix4 {elements: Array(16)}
matrixWorldNeedsUpdate: false
name: ""
parent: Mesh {uuid: "D43C3C58-F4DE-4825-AA43-0BE94A5F536B", name: "VSM890D050Z05S22SN12_10", type: "Mesh", parent: Group, children: Array(1), …}
position: Vector3 {x: 0, y: 0, z: 0}
quaternion: Quaternion {_x: 0, _y: 0, _z: 0, _w: 1, onChangeCallback: ƒ}
receiveShadow: false
renderOrder: 0
rotation: Euler {_x: 0, _y: 0, _z: 0, _order: "XYZ", onChangeCallback: ƒ}
scale: Vector3 {x: 1, y: 1, z: 1}
type: "LineSegments"
up: Vector3 {x: 0, y: 1, z: 0}
userData: {}
uuid: "90F56573-8EEC-4A93-A372-DEC40C5CBC38"
visible: true
eulerOrder: (...)
id: 31
modelViewMatrix: Matrix4 {elements: Array(16)}
normalMatrix: Matrix3 {elements: Array(9)}
useQuaternion: (...)
__proto__: LineSegments
length: 1
__proto__: Array(0)
drawMode: 0
frustumCulled: true
geometry: BufferGeometry {uuid: "FCD47BEB-751B-4D17-9936-DE7C30A00D53", name: "", type: "BufferGeometry", index: null, attributes: {…}, …}
layers: Layers {mask: 1}
material: MeshStandardMaterial {uuid: "64AB972B-4390-4E54-985B-433D24C09D4F", name: "", type: "MeshStandardMaterial", fog: true, lights: true, …}
matrix: Matrix4 {elements: Array(16)}
matrixAutoUpdate: true
matrixWorld: Matrix4 {elements: Array(16)}
matrixWorldNeedsUpdate: false
name: "VSM890D050Z05S22SN12_10"
parent: Group {uuid: "FBBF7E4B-7754-4138-BF1D-729398C2FB57", name: "VSM890D050Z05S22SN12_obj", type: "Group", parent: Scene, children: Array(12), …}
position: Vector3 {x: 0, y: 0, z: 0}
quaternion: Quaternion {_x: 0, _y: 0, _z: 0, _w: 1, onChangeCallback: ƒ}
receiveShadow: true
renderOrder: 0
rotation: Euler {_x: -0, _y: 0, _z: -0, _order: "XYZ", onChangeCallback: ƒ}
scale: Vector3 {x: 1, y: 1, z: 1}
type: "Mesh"
up: Vector3 {x: 0, y: 1, z: 0}
userData: {transformData: {…}}
uuid: "D43C3C58-F4DE-4825-AA43-0BE94A5F536B"
visible: true
eulerOrder: (...)
id: 19
modelViewMatrix: Matrix4 {elements: Array(16)}
normalMatrix: Matrix3 {elements: Array(9)}
useQuaternion: (...)
__proto__: Object3D

This result leads me to believe the following:

AxesHelper relies upon the position of the object it is applied to. For whatever reason, the FBX object that is being loaded does not rely on independent positions of each child mesh object that is loaded. So when the FBX is loaded, all the children occupy the same 0,0,0 position (even though they are in different positions within the group). When the AxesHelper is applied to the child mesh, it occupies the same 0,0,0 position.

My question, is there a way for three.js to recognize or re-compute the position of all child meshes relative to the coordinate space within the group?

Is there another way to correct this? Is it a limitation of the FBX loader?

I'm using THREE.WebGLRenderer 97.

gman
  • 100,619
  • 31
  • 269
  • 393
user2355051
  • 605
  • 1
  • 8
  • 26
  • Do you have a codepen example of this? It looks like all of the positional data within your object is set to 0,0,0. If the models are all positioned correctly when you exported them, they should be added to the scene like that. – danlong Nov 05 '18 at 17:10
  • @danlong I do not, but you are correct. The objects are coming in as part of a group. The group has all the objects positioned correctly, and the position of the group is 0,0,0. Is there a way I can get the real position of all the object in the group as they relate to the world space? I found this and it returns 0,0,0 for all objects. https://stackoverflow.com/a/14216289/2355051 So I suppose the real question is how can I get the real coordinates for each object? – user2355051 Nov 05 '18 at 17:40
  • After the scene has rendered and the world matrices are updated, `target = new THREE.Vector3(); target.setFromMatrixPosition( object.matrixWorld );` – WestLangley Nov 05 '18 at 21:18

1 Answers1

2

It looks like your objects' origins are positioned at 0, 0, 0 but the geometry is elsewhere. You should use the .computeBoundingBox() method to find where your geometry is, then you can use its .boundingBox property to access those coordinates.

// First, you must compute the geometry's bounds
child.geometry.computeBoundingBox();

// Get boundingBox prperty
var bounds = child.geometry.boundingBox;

// Get center of boundingBox
var center = bounds.getCenter();

// Position axisHelper at center of geometry
var sphereAxis = new THREE.AxesHelper(200);
sphereAxis.position.copy(center);
child.add(sphereAxis);

You can access several different properties of the boundingBox. There's more details in the documentation

M -
  • 26,908
  • 11
  • 49
  • 81