threejs comment tourner autour de son propre centre, au lieu de world center

enter image description here

deux objets dans la scène. l'axe de rotation du cube devrait être le centre du cube, c'est ce que j'attends.

mais l'axe de rotation du modèle de chaussure est l'axe y du monde.

mon code d'origine est.

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

j'ai trouvé une solution dans stackoverflow, comme ceci:

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

mais ça ne marche pas. Et puis, je change la chaussure.

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

le résultat est meilleur MAINTENANT, mais il n'est toujours pas parfait. Et comme il y a beaucoup de modèles de chaussures, Je ne peux pas déterminer la position de chaque modèle de chaussure.

27
demandé sur Kyle Patterson 2015-03-04 10:35:09

4 réponses

si votre maille ne tourne pas autour de son centre, c'est parce que les sommets de géométrie sont décalés de l'origine.

vous pouvez automatiser le repositionnement en utilisant une boîte de délimitation pour définir un centre raisonnable, puis décaler la position du maillage comme suit:

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

puis ajouter le maillage à un objet pivot:

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

dans votre boucle d'animation, tournez le pivot;

pivot.rotation.y += 0.01;

EDIT: UNE solution différente est de traduire la géométrie des sommets de sorte que la géométrie est centrée autour de, ou à proximité, de l'origine:

geometry.translate( distX, distY, distZ );

Ou, alternativement, vous pouvez simplement appeler:

geometry.center();

qui Centre les sommets de la géométrie pour vous basé sur la boîte limite de la géométrie.

trois.JSR.97

30
répondu WestLangley 2018-10-02 17:40:11

utilisez trois.Géométrie.prototype.centre comme suit:

myGeometry.center();

c'est comme utiliser ma géométrie.traduire (x,y,z) avec centrage automatique (x,y, z).

19
répondu Samuel Danielson 2016-05-24 11:38:24

la solution de pivot ne fonctionnait pas pour moi.

Avec OBJLoader.js (pour le chargement .obj objects), vous devez obtenir la boîte de liage de l'objet, obtenir son centre, multiplier scalar par -1, et utiliser ceci pour traduire la géométrie de la géométrie de chaque enfant. Ensuite, vous devez réinitialiser le boundingBox si vous voulez l'utiliser dans un but précis.

Voici une fonction qui charge un obj et "normalise" ses Vertex de géométrie, étant donné le répertoire et le nom de les fichiers OBJ et MTL (texture) (par exemple, si les fichiers OBJ et MTL sont dir1/myObject.obj et dir1 / myObject.mtl, puis vous appelez 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
répondu Manuel Dipre 2017-02-03 12:14:24

Heres comment j'ai eu des choses à travailler sur 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);
0
répondu Dustin Silk 2017-05-07 21:47:01