Подтвердить что ты не робот

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;

результат теперь лучше, но он все еще не идеален. и, поскольку существует много моделей обуви, я не могу определить разные позиции для каждой модели обуви.

4b9b3361

Ответ 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);