threejs如何围绕对象自身的中心旋转,而不是世界中心
threejs how to rotate around object's own center,instead of world center
场景中有两个对象。
立方体旋转轴应该是立方体的中心,这是我的期望。
但是鞋模型的旋转轴是世界的y轴。
我的原码是。
cube.rotation.y += 0.01;
shoe.rotation.y += 0.01;
我在Whosebug上找到了一个解决方案,像这样:
cube.rotation.y += 0.01;
var pivot = new THREE.Object3D();
pivot.add(shoe);
pivot.rotation.y += 0.01;
但是没有用。
然后,我改变鞋子的位置。
cube.rotation.y += 0.01;
var pivot = new THREE.Object3D();
shoe.position.set(-5,0,0);
pivot.add(shoe);
pivot.rotation.y += 0.01;
现在效果好多了,但还不够完美。而且由于鞋款很多,我无法确定每个鞋款的位置。
如果您的网格没有围绕其中心旋转,那是因为几何顶点偏离了原点。
您可以通过使用边界框定义合理的中心来自动重新定位,然后像这样偏移网格的位置:
var box = new THREE.Box3().setFromObject( mesh );
box.center( mesh.position ); // this re-sets the mesh position
mesh.position.multiplyScalar( - 1 );
然后将网格添加到枢轴对象:
var pivot = new THREE.Group();
scene.add( pivot );
pivot.add( mesh );
在你的动画循环中,旋转枢轴;
pivot.rotation.y += 0.01;
编辑:A different solution 是平移几何顶点,使几何以原点为中心或靠近原点:
geometry.translate( distX, distY, distZ );
或者,您也可以直接调用:
geometry.center();
根据几何体的边界框将几何体的顶点居中。
three.js r.97
使用THREE.Geometry.prototype.center如下:
myGeometry.center();
这就像使用 myGeometery.translate(x,y,z) 自动居中 (x,y,z)。
枢轴解决方案对我不起作用。
用OBJLoader.js(用于加载.obj objects),你需要得到object的boundingBox,得到它的中心,标量乘以-1,然后使用这是为了翻译每个 child 的几何图形。然后,如果您想将其用于某个目的,则需要重新更新 boundingBox。
这是一个加载对象并“规范化”其几何顶点的函数,给定 OBJ 和 MTL(纹理)文件的目录和名称(例如,如果 OBJ 和 MTL 文件是 [=19= .obj 和 dir1/myObject.mtl,然后调用 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
);
});
}
这是我如何在 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);
如果有多个mesh(最常见),设置父节点在场景图中的位置,达到模型居中的目的。如果场景图是这样 gltfObject -> childObject ->.. -> array of meshes
const bbox = new THREE.Box3().setFromObject( gltfObject );
const offset = new THREE.Vector3();
bbox.getCenter(offset).negate();
childObject.position.set(offset.x, offset.y, offset.z);
场景中有两个对象。 立方体旋转轴应该是立方体的中心,这是我的期望。
但是鞋模型的旋转轴是世界的y轴。
我的原码是。
cube.rotation.y += 0.01;
shoe.rotation.y += 0.01;
我在Whosebug上找到了一个解决方案,像这样:
cube.rotation.y += 0.01;
var pivot = new THREE.Object3D();
pivot.add(shoe);
pivot.rotation.y += 0.01;
但是没有用。 然后,我改变鞋子的位置。
cube.rotation.y += 0.01;
var pivot = new THREE.Object3D();
shoe.position.set(-5,0,0);
pivot.add(shoe);
pivot.rotation.y += 0.01;
现在效果好多了,但还不够完美。而且由于鞋款很多,我无法确定每个鞋款的位置。
如果您的网格没有围绕其中心旋转,那是因为几何顶点偏离了原点。
您可以通过使用边界框定义合理的中心来自动重新定位,然后像这样偏移网格的位置:
var box = new THREE.Box3().setFromObject( mesh );
box.center( mesh.position ); // this re-sets the mesh position
mesh.position.multiplyScalar( - 1 );
然后将网格添加到枢轴对象:
var pivot = new THREE.Group();
scene.add( pivot );
pivot.add( mesh );
在你的动画循环中,旋转枢轴;
pivot.rotation.y += 0.01;
编辑:A different solution 是平移几何顶点,使几何以原点为中心或靠近原点:
geometry.translate( distX, distY, distZ );
或者,您也可以直接调用:
geometry.center();
根据几何体的边界框将几何体的顶点居中。
three.js r.97
使用THREE.Geometry.prototype.center如下:
myGeometry.center();
这就像使用 myGeometery.translate(x,y,z) 自动居中 (x,y,z)。
枢轴解决方案对我不起作用。
用OBJLoader.js(用于加载.obj objects),你需要得到object的boundingBox,得到它的中心,标量乘以-1,然后使用这是为了翻译每个 child 的几何图形。然后,如果您想将其用于某个目的,则需要重新更新 boundingBox。
这是一个加载对象并“规范化”其几何顶点的函数,给定 OBJ 和 MTL(纹理)文件的目录和名称(例如,如果 OBJ 和 MTL 文件是 [=19= .obj 和 dir1/myObject.mtl,然后调用 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
);
});
}
这是我如何在 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);
如果有多个mesh(最常见),设置父节点在场景图中的位置,达到模型居中的目的。如果场景图是这样 gltfObject -> childObject ->.. -> array of meshes
const bbox = new THREE.Box3().setFromObject( gltfObject );
const offset = new THREE.Vector3();
bbox.getCenter(offset).negate();
childObject.position.set(offset.x, offset.y, offset.z);