threejs cómo girar alrededor del propio centro del objeto, en lugar del centro mundial

enter image description here

dos objetos en la escena. el eje de rotación del cubo debe ser el centro del cubo, esa es mi expectativa.

pero el eje de rotación del modelo de zapato es el eje y del mundo.

mi código original es.

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

Encontré una solución en stackoverflow, como esta:

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

Pero no funciona. Y luego, cambio la posición del zapato.

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

El resultado es mejor ahora, pero todavía no es perfecto. Y dado que hay muchos modelos de zapatos, no puedo determinar una posición diferente para cada modelo de zapatos.

Respuestas:5 Respuestas 5
Tiempo:hace 7 años, 6 meses
Última modificación:hace 11 meses

Solución

Si su malla no está girando alrededor de su centro, es porque los vértices de la geometría están desviados del origen.

Puede automatizar el reposicionamiento mediante un cuadro delimitador para definir un centro razonable y, a continuación, desplazar la posición de la malla de la siguiente manera:

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

A continuación, agregue la malla a un objeto pivote:

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

En el bucle de animación, gire el pivote;

pivot.rotation.y += 0.01;

EDITAR: Una solución diferente es traducir los vértices de geometría para que la geometría se centre alrededor o cerca del origen:

geometry.translate( distX, distY, distZ );

O, alternativamente, puede llamar a:

geometry.center();

que centra los vértices de la geometría en función del cuadro delimitador de la geometría.

tres.js r.97

Otras respuestas

La solución pivote no funcionaba para mí.

Con OBJLoader.js (para cargar objetos .obj), debe obtener el boundingBox del objeto, obtener su centro, multiplicar el escalar por -1 y usar esto para traducir la geometría de la geometría de CADA niño. Luego, debe volver a actualizar el boundingBox si desea usarlo para un propósito.

Aquí hay una función que carga un obj y «normaliza» sus vértices de geometría, dado el directorio y el nombre de los archivos OBJ y MTL (textura) (por ejemplo, si los archivos OBJ y MTL son dir1/myObject.obj y dir1/myObject.mtl, entonces se llama a 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
    );
  });
}

Deja un comentario