Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug in scale or getDimensions #4167

Open
2 tasks done
simplerick opened this issue Mar 16, 2023 · 4 comments
Open
2 tasks done

Bug in scale or getDimensions #4167

simplerick opened this issue Mar 16, 2023 · 4 comments

Comments

@simplerick
Copy link

Description

Unexpected behaviour when trying to scale a model using Puppeteer (but I believe it will be reproduced in any browser).
After scaling at 1.5 times a model size becomes incredibly large according to getDimensions and getBoundingBoxCenter (see the output below). However, it looks like the problem is in the output of incorrect values for sizes, because the model is rendered as if it had been enlarged correctly.

image

Code snippet that I used to generate this output

  let evalError = await page.evaluate(async () => {
      const scale = async (modelViewerTransform) => {
        console.log(`dims: ${modelViewerTransform.getDimensions()}`);
        console.log(`bbcenter: ${modelViewerTransform.getBoundingBoxCenter()}`);
        modelViewerTransform.scale = "1.5 1.5 1.5";
        modelViewerTransform.updateFraming();
        await modelViewerTransform.updateComplete;
        console.log(`dims: ${modelViewerTransform.getDimensions()}`);
        console.log(`bbcenter: ${modelViewerTransform.getBoundingBoxCenter()}`);
      };
      const modelViewer = document.getElementById('snapshot-viewer');
      await scale(modelViewer);
  })

Model (for additional info: I transformed it with gltf-transform since it has SpecGloss PBR format):
robot.glb.zip

html template:

  const defaultAttributes = {
    id: 'snapshot-viewer',
    style: `background-color: ${backgroundColor};`,
    'interaction-prompt': 'none',
    src: inputPath,
    'animation-crossfade-duration': 0,
    'interpolation-decay': 1,
  };

  validateCustomAttributes(defaultAttributes, modelViewerArgs);

  const defaultAttributesString = toHTMLAttributeString(defaultAttributes);
  const modelViewerArgsString = toHTMLAttributeString(modelViewerArgs);

  let htmlTemplate = `
    <!DOCTYPE html>
    <html>
      <head>
        <meta name="viewport" content="width=device-width, initial-scale=${devicePixelRatio}">
        <script type="module"
          src="${modelViewerUrl}">
        </script>
        <style>
          body {
            margin: 0;
          }
          model-viewer {
            --progress-bar-color: transparent;
            width: ${width}px;
            height: ${height}px;
          }
        </style>
      </head>
      <body>
        <model-viewer
          ${defaultAttributesString}
          ${modelViewerArgsString}
        />
      </body>
    </html>
  `;

Version

  • model-viewer: v3.0.1 (min.js)

Browser Affected

  • Puppeteer, version: 13.7.0

OS

  • Linux
@elalish
Copy link
Collaborator

elalish commented Mar 16, 2023

This seems to be working fine on the dev tools command line. I wonder if you forgot to wait for the load event?

@simplerick
Copy link
Author

Thank you for attention, checked loaded and modelIsVisible props:

        console.log(`loaded: ${modelViewerTransform.loaded}`);
        console.log(`modelIsVisible: ${modelViewerTransform.modelIsVisible}`);
        console.log(`dims: ${modelViewerTransform.getDimensions()}`);
        console.log(`bbcenter: ${modelViewerTransform.getBoundingBoxCenter()}`);
        modelViewerTransform.scale = "1.5 1.5 1.5";
        modelViewerTransform.updateFraming();
        await modelViewerTransform.updateComplete;
        console.log(`loaded: ${modelViewerTransform.loaded}`);
        console.log(`modelIsVisible: ${modelViewerTransform.modelIsVisible}`);
        console.log(`dims: ${modelViewerTransform.getDimensions()}`);
        console.log(`bbcenter: ${modelViewerTransform.getBoundingBoxCenter()}`);

image

Web viever

I also tried to view the model at https://modelviewer.dev/editor/. Everything is fine (model is visible) if I assign camera-target manually. Here is the snippet:

<model-viewer src="robot.glb" ar ar-modes="webxr scene-viewer quick-look" camera-controls poster="poster.webp" shadow-intensity="1" scale="1.5 1.5 1.5" camera-target="0m 0.3m 0m"> </model-viewer>

But if I change camera-target to "auto auto auto" it shows nothing, presumably because it gets wrong bbox center.

@elalish
Copy link
Collaborator

elalish commented Mar 29, 2023

Okay, so I can repro this now - it's specific to this model, or at least has something to do with its skinned mesh portion and large transforms. The first time bounds are calculated, the bindMatrixInverse down in three.js is identity, because they haven't even been applied yet. That seems wrong, yet that's what gets the correct result. The next time (when you change scale) the bind matrices have been calculated and they're tiny (based on the matrixWorld due to being in attached mode), making the inverses huge, and causing the huge and incorrect bounding box computation. This looks like a three.js bug, though likely one I helped write.

@simplerick
Copy link
Author

I see, great investigation. For now, as a workaround, I avoid changing the scale of the model and change the distance in the camera-orbit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants