11

After downloading 3D models from sketchfab.com and importing them into a Three.js scene, they are most of the times not centered and their size is very big.

Is there a way to automatically center and scale gltf models using a script or a software (working on Linux) or otherwise to do it on-the-fly in Three.js and having the camera to move around the object using OrbitControls.

4 Answers 4

12

Yep. This code takes a node and finds its size and centerpoint, then rescales it so the max extent is 1 and its centered at 0,0,0, and above the ground on the y axis.

    var mroot = yourScene;
    var bbox = new THREE.Box3().setFromObject(mroot);
    var cent = bbox.getCenter(new THREE.Vector3());
    var size = bbox.getSize(new THREE.Vector3());

    //Rescale the object to normalized space
    var maxAxis = Math.max(size.x, size.y, size.z);
    mroot.scale.multiplyScalar(1.0 / maxAxis);
    bbox.setFromObject(mroot);
    bbox.getCenter(cent);
    bbox.getSize(size);
    //Reposition to 0,halfY,0
    mroot.position.copy(cent).multiplyScalar(-1);
    mroot.position.y-= (size.y * 0.5);
Sign up to request clarification or add additional context in comments.

2 Comments

is yourScene a path to a scene object or an actual object? Can you provide some more context to your solution?
yourScene would be whatever scene/object you want to get the bounds of.. in the case of your GLTF loading example you could do let mroot = gltf.scene. hth!
8
var loader = new THREE.GLTFLoader();
loader.load( 'models/yourmodel.gltf', 
function ( gltf ) {
    gltf.scene.traverse( function ( child ) {
        if ( child.isMesh ) {
            child.geometry.center(); // center here
        }
    });
    gltf.scene.scale.set(10,10,10) // scale here
    scene.add( gltf.scene );
}, (xhr) => xhr, ( err ) => console.error( e ));

To move around the object use controls.target() https://threejs.org/docs/#examples/controls/OrbitControls.target

1 Comment

I'm not sure how this fixes my problem. The object is still offset. And scaling parameter in your proposition is not automatic.
3

I resized in REACT like this!

import React, { useState, useRef, useEffect } from "react";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
const Earth = () => {
const [model, setModel] = useState();
useEffect(() => {
    new GLTFLoader().load("scene.gltf", (model) => {
      model.scene.scale.set(0.03, 0.03, 0.03);
      setModel(model);
    });
  });
  return model ? <primitive object={model.scene} /> : null;
};

Just call <Earth />

Comments

2

Other proposed solutions did not work well for me. However, I tested the simple approach below on several models to be loaded into my scenes and it works nicely.

const loader = new GLTFLoader();
loader.load("assets/model_path/scene.gltf",
      (gltf) => {
        gltf.scene.scale.multiplyScalar(1 / 100); // adjust scalar factor to match your scene scale
        gltf.scene.position.x = 20; // once rescaled, position the model where needed
        gltf.scene.position.z = -20;

        scene.add(gltf.scene);
        render();
      },
      (err) => {
        console.error(err);
      }
    );

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.