2015-03-04 8 views
25

enter image description herethreejs wie um objekteigenen Zentrum zu drehen, statt Weltzentrum

zwei Objekte in der Szene. Die Würfelachse sollte das Zentrum des Würfels sein, das ist meine Erwartung.

aber die Drehachse des Schuhmodells ist die y-Achse der Welt.

mein ursprünglicher Code ist.

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

fand ich eine Lösung in Stackoverflow, wie folgt aus:

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

aber es funktioniert nicht funktioniert. und dann ändere ich die Position des Schuhs.

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

das Ergebnis ist jetzt besser, aber es immer noch nicht perfekt. und da es viele Schuhmodelle gibt, kann ich nicht für jedes Schuhmodell eine andere Position bestimmen.

Antwort

24

Wenn sich Ihr Gitter nicht um sein Zentrum dreht, liegt dies daran, dass die geometrischen Scheitelpunkte vom Ursprung versetzt sind.

Sie können Neupositionierung automatisieren, indem Sie einen Begrenzungsrahmen mit einem vernünftigen Zentrum zu definieren und dann die Position des Mesh-Offset wie folgt:

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

Dann um das Netz zu einem Dreh Objekt hinzufügen:

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

In der Animationsschleife den Drehpunkt drehen;

pivot.rotation.y += 0.01; 

EDIT: A different solution ist die Geometrie Eckpunkte zu übersetzen, so dass die Geometrie um zentriert ist, oder in der Nähe der Herkunft:

geometry.translate(distX, distY, distZ); 

three.js r.78

13

Verwenden THREE.Geometry.prototype.center wie folgt:

myGeometry.center(); 

Dies ist wie mit myGeometery.translate (x, y, z) mit automatischer Zentrierung (x, y, z).

+0

Hinzufügen nur diese Zeile mein Problem gelöst –

1

Die Pivot-Lösung funktionierte nicht für mich.

Mit OBJLoader.js (für das Laden von OBJ-Objekten) müssen Sie die BoundingBox des Objekts abrufen, dessen Mittelpunkt erhalten, den Skalarwert mit -1 multiplizieren und damit die Geometrie der Geometrie jedes einzelnen Kindes übersetzen. Dann müssen Sie die BoundingBox erneut aktualisieren, wenn Sie sie für einen bestimmten Zweck verwenden möchten.

Hier ist eine Funktion, die ein Obj lädt und ihre Geometrie-Vertexe "normalisiert", wobei das Verzeichnis und der Name der OBJ- und MTL-Dateien angegeben werden (zB wenn OBJ- und MTL-Dateien dir1/myObject.obj sind) und dir1/myObject.mtl, dann rufen Sie 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

Heres, wie ich die Dinge bekam auf R86 arbeiten

// 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);