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);
我正在使用 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);