Threejs, как вращать вокруг объекта собственный центр, а не центр мира
![enter image description here]()
два объекта в сцене.
ось вращения куба должна быть центром куба, который я ожидаю.
но ось вращения модели обуви является мировой осью y.
мой исходный код.
cube.rotation.y += 0.01;
shoe.rotation.y += 0.01;
Я нашел решение в stackoverflow, например:
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;
результат теперь лучше, но он все еще не идеален. и, поскольку существует много моделей обуви, я не могу определить разные позиции для каждой модели обуви.
Ответы
Ответ 1
Если ваша сетка не вращается вокруг ее центра, это потому, что вершины геометрии смещены от начала координат.
Вы можете автоматизировать репозиционирование с помощью ограничивающего прямоугольника, чтобы определить разумный центр, а затем смещать позицию сетки следующим образом:
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;
EDIT: Другое решение - это перевести вершины геометрии, чтобы геометрия была центрирована вокруг или около начала:
geometry.translate( distX, distY, distZ );
three.js r.78
Ответ 2
Используйте THREE.Geometry.prototype.center следующим образом:
myGeometry.center();
Это похоже на использование myGeometery.translate(x, y, z) с автоматическим центрированием (x, y, z).
Ответ 3
Сводное решение для меня не работало.
С OBJLoader.js(для загрузки объектов .obj) вам нужно получить boundingBox объекта, получить его центр, умножить скаляр на -1 и использовать его для перевода геометрии любой детской геометрии. Затем вам нужно повторно обновить ограничивающий бокс, если вы хотите использовать его для определенной цели.
Вот функция, которая загружает obj и "нормализует" свои вершины геометрии, учитывая каталог и имя файлов OBJ и MTL (текстуры) (например, если OBJ и MTL файлы - dir1/myObject.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);
});
}
Ответ 4
Вот как я начал работать на 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);