首页 > 解决方案 > 更新加载模型的旋转

问题描述

上周一直在使用three.js 库,我遇到了将转换应用于加载的模型(gltf)的问题。每当我尝试更新旋转时,我都会收到“未捕获的类型错误:无法读取未定义的属性‘位置’。” 我很困惑;好像我只能访问 onLoad 中的 .position/.rotation 属性?

let container;
let camera;
let controls;
let renderer;
let scene;
let mesh;

const mixers = [];
const clock = new THREE.Clock();

function init() {

  container = document.querySelector('#scene-container');

  scene = new THREE.Scene();
  scene.background = new THREE.Color(0x8FBCD4);

  createCamera();
  createLights();
  loadModels();
  createRenderer();
  createControls();

  renderer.setAnimationLoop(() => {

    update();
    render();
  });
}

function createCamera() {

  const fov = 35;
  const aspect = container.clientWidth / container.clientHeight;
  const near = 0.1; //near clipping plane
  const far = 100; //far clipping plane

  camera = new THREE.PerspectiveCamera(fov, aspect, near, far);

  camera.position.set(-1.5, 1.5, 6.5);
}

function createLights() {

  const ambientLight = new THREE.HemisphereLight(
    0xddeeff, //bright sky color
    0x202020, //dim ground color
    3 //intensity
  );

  //this is a specular light
  const mainLight = new THREE.DirectionalLight(0xffffff, 10);
  mainLight.position.set(10, 10, 10);

  scene.add(ambientLight, mainLight);
}

function createRenderer() {
  renderer = new THREE.WebGLRenderer({
    antialias: true
  });
  renderer.setSize(container.clientWidth, container.clientHeight);

  renderer.setPixelRatio(window.devicePixelRatio);

  renderer.gammaFactor = 2.2;
  renderer.gammaFactor = true;

  renderer.physicallyCorrectLights = true; //allows us to use lux, candela and lumens to set lighting

  container.appendChild(renderer.domElement);
}

function loadModels() {

  const loader = new THREE.GLTFLoader();

  const onLoad = ( gltf, position ) => {
    const model = gltf.scene.children[ 0 ]; //get reference to the model
    model.position.copy( position ); //passes the position parameter into the models position value

    const animation = gltf.animations[ 0 ];

    const mixer = new THREE.AnimationMixer( model ); //instances a animation controller
    mixers.push( mixer );

    const action = mixer.clipAction( animation );
    action.play();

    mesh = model;

    scene.add( model );

  };

  const onProgress = () => {};

  const onError = (errorMessage) => { console.log(errorMessage); };


  //loads a position the model and the position
  const suzannePosition = new THREE.Vector3(0, 0, 2.5);
  loader.load('models/test/suzanne.glb', gltf => onLoad(gltf, suzannePosition), onProgress, onError);
}

function update() {
  const delta = clock.getDelta();

  for (const mixer of mixers) {
    mixer.update(delta);
  }

  /* ---THIS DOESN'T WORK---
    mesh.rotation.x += .01;
    console.log(mesh.rotation);
  */
}

function createControls() {

  controls = new THREE.OrbitControls(camera, container);
}

function render() {
  renderer.render(scene, camera);
}

function onWindowResize() {

  camera.aspect = container.clientWidth / container.clientHeight;

  //update camera's frustum
  camera.updateProjectionMatrix();

  renderer.setSize(container.clientWidth, container.clientHeight);
}


window.addEventListener('resize', onWindowResize);
init();

标签: javascriptthree.js

解决方案


mesh = model;

此分配发生在 的onLoad()回调中GLTFLoader.load()。重要的是要了解此回调是在加载模型时异步执行的。

同时,meshundefined。因此,将您的代码更改为以下内容以消除运行时错误:

if ( mesh ) mesh.rotation.x += .01;

推荐阅读