Автоматическое центрирование и изменение размера GLTF-моделей в Three.js

После загрузки 3D-моделей с сайта sketchfab.com и импорта их в сцену Three.js они в большинстве случаев не центрированы и имеют очень большой размер.

Есть ли способ автоматически центрировать и масштабировать модели gltf с помощью скрипта или программного обеспечения (работающего в Linux) или иным образом делать это на лету в Three.js и иметь камеру для перемещения вокруг объекта с помощью OrbitControls.


person b26    schedule 11.09.2018    source источник


Ответы (4)


Ага. Этот код берет узел и находит его размер и центральную точку, а затем изменяет его масштаб так, чтобы максимальный размер был равен 1, а его центр находился на 0,0,0 и находился над землей по оси y.

    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);
person manthrax    schedule 11.09.2018
comment
yourScene - путь к объекту сцены или к реальному объекту? Не могли бы вы дать дополнительный контекст своему решению? - person Casivio; 26.03.2021
comment
yourScene будет любая сцена / объект, границы которых вы хотите получить .. в случае вашего примера загрузки GLTF вы можете сделать let mroot = gltf.scene. hth! - person manthrax; 26.03.2021

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 ));

Для перемещения по объекту используйте controls.target () https://threejs.org/docs/#examples/controls/OrbitControls.target

person corashina    schedule 11.09.2018
comment
Я не уверен, как это решит мою проблему. Объект по-прежнему смещен. И параметр масштабирования в вашем предложении не автоматический. - person b26; 07.10.2018

Другие предложенные решения мне не подошли. Однако я протестировал приведенный ниже простой подход на нескольких моделях для загрузки в мои сцены, и он отлично работает.

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);
      }
    );
person Marc    schedule 04.09.2020

Я изменил размер в РЕАКТЕ вот так!

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;
};

Просто позвоните <Earth />

person Daniel    schedule 18.06.2021