ThreeJs 缩放对象相对于另一个对象

ThreeJs scale object relative to another object

我正在使用 threejs 渲染一些模型 (gltf/glb)。个个大小不一,有大有小。现在我想将它们全部缩放到相同的大小。

如果我使用 mesh.scale() 将相对于对象自身的大小缩放对象。有没有办法不用手动计算每个模型的比例就可以做到这一点?

更新:

这是我的代码

function loadModels(points) {
  // loader
  const loader = new GLTFLoader();

  const dl = new DRACOLoader();
  dl.setDecoderPath("/scripts/decoder/");
  loader.setDRACOLoader(dl);

  let lengthRatios;
  const meshes = [];

  for (let i = 0; i < store.length; i++) {
    loader.load(
      store[i].model,
      (gltf) => {
        const mesh = gltf.scene;
        const meshBounds = new THREE.Box3().setFromObject(mesh);

        // Calculate side lengths of model1
        const lengthMeshBounds = {
          x: Math.abs(meshBounds.max.x - meshBounds.min.x),
          y: Math.abs(meshBounds.max.y - meshBounds.min.y),
          z: Math.abs(meshBounds.max.z - meshBounds.min.z),
        };

        if (lengthRatios) {
          lengthRatios = [
            lengthRatios[0] / lengthMeshBounds.x,
            lengthRatios[1] / lengthMeshBounds.y,
            lengthRatios[2] / lengthMeshBounds.z,
          ];
        } else {
          lengthRatios = [
            lengthMeshBounds.x,
            lengthMeshBounds.y,
            lengthMeshBounds.z,
          ];
        }

        meshes.push(mesh);
        if (meshes.length == store.length) {
          addModels();
        }
      },
      (xhr) => {
        console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
      },
      (error) => {
        console.log("An error happened");
      }
    );
  }

  function addModels() {
    // Select smallest ratio in order to contain the models within the scene
    const minRation = Math.min(...lengthRatios);

    for (let i = 0; i < meshes.length; i++) {
      // Use smallest ratio to scale the model
      meshes[i].scale.set(minRation, minRation, minRation);

      // position the model/mesh
      meshes[i].position.set(...points[i]);

      // add it to the scene
      scene.add(meshes[i]);
    }
  }
}

您应该在每个模型周围创建一个边界框。

//Creating the actual bounding boxes
mesh1Bounds = new THREE.Box3().setFromObject( model1 );
mesh2Bounds = new THREE.Box3().setFromObject( model2 );

// Calculate side lengths of model1
let lengthMesh1Bounds = {
  x: Math.abs(mesh1Bounds.max.x - mesh1Bounds.min.x),
  y: Math.abs(mesh1Bounds.max.y - mesh1Bounds.min.y),
  z: Math.abs(mesh1Bounds.max.z - mesh1Bounds.min.z),
};

// Calculate side lengths of model2
let lengthMesh2Bounds = {
  x: Math.abs(mesh2Bounds.max.x - mesh2Bounds.min.x),
  y: Math.abs(mesh2Bounds.max.y - mesh2Bounds.min.y),
  z: Math.abs(mesh2Bounds.max.z - mesh2Bounds.min.z),
};

// Calculate length ratios
let lengthRatios = [
  (lengthMesh1Bounds.x / lengthMesh2Bounds.x),
  (lengthMesh1Bounds.y / lengthMesh2Bounds.y),
  (lengthMesh1Bounds.z / lengthMesh2Bounds.z),
];

// Select smallest ratio in order to contain the models within the scene
let minRatio = Math.min(...lengthRatios);

// Use smallest ratio to scale the model
model.scale.set(minRatio, minRatio, minRatio);