Reputation: 171
we are trying to generate bounding Spheres for child objects. Sadly we do not know how to get the proper positions for them. Even if the child objects are clearly NOT placed in the center, the position vector is still 0,0,0
We are using the UTF8Loader for importing objects and do not have access to the "standard" vertices array.
Furthermore it looks like bounding radius is calculated by distance from center of the parent.
Any ideas?
Live demo:
Login with this demo account: http://threever.org/login user: Demo passw: demoacc
and go to: threever.org/editor
A picture of the problem: picture
And the code snippet when traversing the object:
object.traverse( function( node ) {
if( node.geometry ) {
if(node.geometry.boundingSphere){
[...]
var sphere = new THREE.Mesh( spheregeometry, material);
sphere.position.copy(node.position);
[...]
_this.scene.add(sphere);
}
}
});
EDIT:
We tried the described workflow (thanks @WestLangley) for updating the matrix position but still had no luck. Since it looks like that the bounding spheres are not generated correctly either (in general to large) we decided to try out another approach: We were generating bounding geometry for the sole purpose of having "selection meshes" for ray casting (which can be somewhat difficult if the mesh is THREE.BufferGeometry
[not?]). So we looked in the THREE.UTF8Loader
file and tried to reconstruct the way geometry is created when useBuffers
is false
. Then we set the dynamic
flag for THREE.BufferGeometry
to true
which gives access to the attribute Arrays. When the mesh is generated we use our createSelectionDummy
function to generate a simplified THREE.Geometry
version of the mesh (no uvs, merged Vertices, normal vector(0,0,0)) using the attribute Arrays. What do you think of this technique? Does this have a performance gain vs useBuffers:false
?
this.createSelectionDummy = function( indices, positions ) {
var geom = new THREE.Geometry();
for( var i = 0; i < indices.length; i += 3 ) {
geom.vertices.push( new THREE.Vector3( positions[ i*3 ], positions[ i*3+1 ], positions[ i*3+2 ] ) );
geom.vertices.push( new THREE.Vector3( positions[ i*3+3 ], positions[ i*3+4 ], positions[ i*3+5 ] ) );
geom.vertices.push( new THREE.Vector3( positions[ i*3+6 ], positions[ i*3+7 ], positions[ i*3+8 ] ) );
geom.faces.push( new THREE.Face3( indices[ i ], indices[ i + 1 ], indices[ i + 2 ], new THREE.Vector3(0,0,0) , null, 0 ) );
}
//reduce mesh size by 3
geom.mergeVertices();
geom.computeCentroids();
geom.computeFaceNormals();
return (new THREE.Mesh( geom, new THREE.MeshBasicMaterial({wireframe:true}) ));
};
Upvotes: 1
Views: 4985
Reputation: 104783
You can get an object's world position like so:
var position = object.matrixWorld.getPosition();
It is important to make sure the object's world matrix is updated first. This normally happens in each render call. But if for some reason it is not, you can call the following first:
object.updateMatrixWorld( true );
You can compute the bounding sphere radius object.geometry.boundingSphere.radius
this way:
object.geometry.computeBoundingSphere();
Upvotes: 2