threejs how to rotate around object's own center,instead of world center

匿名 (未验证) 提交于 2019-12-03 02:56:01

问题:

two objects in the scene. the cube rotate axis should be the cube's center,that's my expect.

but the shoe model's rotate axis is the world's y axis.

my original code is.

cube.rotation.y += 0.01; shoe.rotation.y += 0.01; 

I found a solution in stackoverflow,like this:

cube.rotation.y += 0.01; var pivot = new THREE.Object3D(); pivot.add(shoe); pivot.rotation.y += 0.01; 

but it doesn't works. and then,I change the shoe's position.

cube.rotation.y += 0.01; var pivot = new THREE.Object3D(); shoe.position.set(-5,0,0); pivot.add(shoe); pivot.rotation.y += 0.01; 

the result is better now, but it still not perfect. and since there are a lot of shoe's model, I can't determine different position for every shoe model.

回答1:

If your mesh is not rotating around its center, it is because the geometry vertices are offset from the origin.

You can automate repositioning by using a bounding box to define a reasonable center, and then offset the mesh's position like so:

var box = new THREE.Box3().setFromObject( mesh ); box.center( mesh.position ); // this re-sets the mesh position mesh.position.multiplyScalar( - 1 ); 

Then add the mesh to a pivot object:

var pivot = new THREE.Group(); scene.add( pivot ); pivot.add( mesh ); 

In your animation loop, rotate the pivot;

pivot.rotation.y += 0.01; 

EDIT: A different solution is to translate the geometry vertices so the geometry is centered around, or near, the origin:

geometry.translate( distX, distY, distZ ); 

three.js r.78



回答2:

Use THREE.Geometry.prototype.center as follows:

myGeometry.center(); 

This is like using myGeometery.translate(x,y,z) with automatic centering (x,y,z).



回答3:

The pivot solution was not working for me.

With OBJLoader.js (for loading .obj objects), you need to get the boundingBox of the object, get its center, multiply scalar by -1, and use this to translate the geometry of EVERY child's geometry. Then, you need to reUpdate the boundingBox if you want to use it for a purpose.

Here is a function that loads an obj and "normalize" its geometry vertexes, given the directory and name of the OBJ and MTL (texture) files (for example, if the OBJ and MTL files are dir1/myObject.obj and dir1/myObject.mtl, then you call loadObj('dir1','myObject')).

 function loadObj(dir, objName) {         var onProgress = function(xhr) {             if (xhr.lengthComputable) {                 var percentComplete = xhr.loaded / xhr.total * 100;                 console.log(Math.round(percentComplete, 2) + '% downloaded');             }         };          var onError = function(xhr) {};          // Manager         var manager = new THREE.LoadingManager();         manager.onProgress = function(item, loaded, total) {             console.log( 'Started loading file: ' + item + '.\nLoaded ' + loaded + ' of ' + total + ' files.' );         };          var mtlLoader = new THREE.MTLLoader();         mtlLoader.setPath(dir);         mtlLoader.load(objName + '.mtl', function(materials) {             materials.preload();              // Model             var loader = new THREE.OBJLoader(manager);             loader.setMaterials(materials);             loader.setPath(dir);             loader.load(objName + '.obj', function (object) {              var objBbox = new THREE.Box3().setFromObject(object);              // Geometry vertices centering to world axis             var bboxCenter = objBbox.getCenter().clone();             bboxCenter.multiplyScalar(-1);              object.traverse(function (child) {                 if (child instanceof THREE.Mesh) {                     child.geometry.translate(bboxCenter.x, bboxCenter.y, bboxCenter.z);                 }             });              objBbox.setFromObject(object); // Update the bounding box              scene.add(object);             }, onProgress, onError);         });     } 


回答4:

Heres how i got things to work on r86

// Store original position let box = new THREE.Box3().setFromObject(this.mesh); let offset = box.getCenter();  // Center geometry faces this.geometry.center();  // Add to pivot group this.group = new THREE.Object3D(); this.group.add(this.mesh);  // Offset pivot group by original position this.group.position.set(offset.x, offset.y, offset.z); 


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