Inaccuarate BoundingBox reading for mesh?

async function LoadModel1() {
  let positionXYZ = localStorage.getItem('xyz') || "0, 0, 0";
  let position = new THREE.Vector3(0, 0, 0);
  if (positionXYZ) {
    const xyzArray = positionXYZ.split(',').map(parseFloat);
    if (xyzArray.length === 3) {
      const [x, y, z] = xyzArray;
      //camera.position.set(x, y, z);
      //position.set(x, y, z);
    } else {console.error('Stored xyz coordinates in localStorage are not in the expected format.');}
    } else {console.error('No xyz coordinates found in localStorage.');}
  const mesh = await LoadPMX(Pmx);
  mesh.position.copy(position);
  scene.add(mesh);
  //Get PMX Height
  const urlParams = new URLSearchParams(window.location.search);
  const pmx1 = urlParams.get('pmx') || "AoiZaizen/AoiZaizen.pmx";
  const boundingBox = new THREE.Box3().setFromObject(mesh);
  //const height = boundingBox.max.y - boundingBox.min.y;
  const height = ((boundingBox.max.y - boundingBox.min.y) / 12.97132464115047).toFixed(2); // Convert and round height directly
  const pmxHeight = `${pmx1.trim()}:${height} cm`;
  localStorage.setItem('pmxheight', pmxHeight);
  const vmdClip = await LoadVMDAnimation(mesh, false); // Pass false for mesh
  const helper = new THREE.MMDAnimationHelper({ afterglow: 1.0 });
  const mmd = { mesh: mesh, animation: vmdClip };
  helper.add(mmd.mesh, {
    animation: mmd.animation,
    physics: true
  });
  return { mesh: mesh, helper: helper };}
async function LoadModel2() {
  try {if (!Pmx2) {
    throw new Error('Pmx2 is not defined.');}
    let positionXYZ = localStorage.getItem('xyz') || "0, 0, 0";
    let position = new THREE.Vector3(0, 0, 0);
    if (positionXYZ) {
      const xyzArray = positionXYZ.split(',').map(parseFloat);
      if (xyzArray.length === 3) {
        const [x, y, z] = xyzArray;
        position.set(x, y, z);
      } else {throw new Error('Stored xyz coordinates in localStorage are not in the expected format.');}
      } else {throw new Error('No xyz coordinates found in localStorage.');}
    const mesh2 = await LoadPMX(Pmx2);
    //mesh2.position.copy(position);
    //mesh2.position.x += 15;
    //!new URLSearchParams(window.location.search).has('vmd2') && (mesh2.position.x += 15);
    mesh2.position.x = parseInt(new URLSearchParams(window.location.search).get('distance')) || (new URLSearchParams(window.location.search).has('vmd2') ? 0 : 15);
    scene.add(mesh2);
    // Get PMX2 Height
    const boundingBox2 = new THREE.Box3().setFromObject(mesh2);
    //const height2 = boundingBox2.max.y - boundingBox2.min.y;
    const height2 = ((boundingBox2.max.y - boundingBox2.min.y) / 12.97132464115047).toFixed(2); // Convert and round height directly
    const pmx2 = new URLSearchParams(window.location.search).get('pmx2') || "AoiZaizen/AoiZaizen.pmx";
    const pmxHeight2 = `${pmx2.trim()}:${height2} cm`;
    let pmxHeight = localStorage.getItem('pmxheight') || "";
    pmxHeight += pmxHeight ? `;${pmxHeight2}` : pmxHeight2;
    localStorage.setItem('pmxheight', pmxHeight);
    const vmdClip = await LoadVMDAnimation(mesh2, true); // Pass true for mesh2
    const helper = new THREE.MMDAnimationHelper({ afterglow: 1.0 });
    helper.add(mesh2, {
      animation: vmdClip,
      physics: true
    });
    document.getElementById('error') && (document.getElementById('error').innerHTML = ""); //empty error div after loading has finished
    return { mesh: mesh2, helper };
  } catch (error) {
    console.error('Error loading model 2:', error);
    return null;}}

Is how I currently infer height (nevermind the division factor, I pulled that out of thin air)

Eitherhow:
Some Models -despite being OBVIOUSLY smaller, report as like 2 meters ?- Any ideas on how to get a more accurate reading ?

The models in this case are:
Model left:
Model right:

Computing bounding boxes of skinnedMeshes is problematic… because the first frame of animation can immediately change the dimensions of the mesh, and often, artists use the bind pose to bring the mesh into its initial size…

So .setFromObject will give you the bounds of the untransformed mesh before any bind pose/animations have been applied.

There is a way to get the current bounding box of an object once it’s animations are running i think by passing “true” as second parameter to setFromObject

related reading:

1 Like