2015-03-04 10 views
25

enter image description herethreejs come ruotare intorno al proprio centro dell'oggetto, invece di centro mondiale

due oggetti nella scena. l'asse di rotazione del cubo dovrebbe essere il centro del cubo, è quello che mi aspetto.

ma l'asse di rotazione del modello di scarpa è l'asse y del mondo.

il mio codice originale è.

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

ho trovato una soluzione a StackOverflow, in questo modo:

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

ma non fa opere. e poi, cambio la posizione della scarpa.

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

il risultato è migliore ora, ma non è ancora perfetto. e dal momento che ci sono molti modelli di scarpe, non riesco a determinare la posizione diversa per ogni modello di scarpa.

risposta

24

Se la mesh non ruota attorno al suo centro, è perché i vertici della geometria sono sfalsati rispetto all'origine.

È possibile automatizzare riposizionamento utilizzando un rettangolo per definire un centro ragionevole, e quindi compensare la posizione della maglia in questo modo:

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

Poi aggiungere il mesh un oggetto pivot:

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

Nel loop dell'animazione, ruota il perno;

pivot.rotation.y += 0.01; 

EDIT: A different solution è di tradurre i vertici della geometria così la geometria è centrata intorno, o quasi, l'origine:

geometry.translate(distX, distY, distZ); 

Three.js r.78

13

Usa THREE.Geometry.prototype.center come segue:

myGeometry.center(); 

È come utilizzare myGeometery.translate (x, y, z) con il centraggio automatico (x, y, z).

+0

semplicemente aggiungendo questa linea risolto il mio problema –

1

La soluzione pivot non funzionava per me.

Con OBJLoader.js (per il caricamento di oggetti .obj), è necessario ottenere il boundingBox dell'oggetto, ottenerne il centro, moltiplicare lo scalare di -1 e utilizzarlo per tradurre la geometria della geometria di OGNI bambino. Quindi, è necessario aggiornare il boundingBox se si desidera utilizzarlo per uno scopo.

Ecco una funzione che carica un oggetto e "normalizza" i suoi vertici di geometria, data la directory e il nome dei file OBJ e MTL (trama) (ad esempio, se i file OBJ e MTL sono dir1/myObject.obj e dir1/myObject.mtl, quindi si chiama 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); 
     }); 
    } 
0

Ecco come ho ottenuto cose su cui lavorare 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); 
Problemi correlati