代码之家  ›  专栏  ›  技术社区  ›  john jacobs

如何移动三维模型位置THRE.js

  •  0
  • john jacobs  · 技术社区  · 3 年前

    我正在尝试用three.js创建一个行走的3D模型 3D model 以及 in place fbx walking animation 从Mixamo导入到我的项目中。模型和动画按预期工作;模型由于加载的动画而“行走”,但保持在相同的位置。我的问题是试图让模型的位置增加每一帧,给人一种模型向前走的错觉。

    这是我的代码:

    import './style.css'
    import * as THREE from 'three';
    import { FontLoader } from 'three/examples/jsm/loaders/FontLoader';
    import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry';
    import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
    import { Reflector } from 'three/examples/jsm/objects/Reflector.js';
    import { FirstPersonControls } from 'three/examples/jsm/controls/FirstPersonControls.js';
    import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
    import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader';
    
    
    let glow = 0.05;
    let clock = new THREE.Clock();
    
    
    /* CREATE CAMERA */
    
      const camera = new THREE.PerspectiveCamera( 100, window.innerWidth / window.innerHeight, 0.01, 4000);
      camera.position.setZ(1);
      camera.position.setX(200);
      camera.position.setY(10);
      // camera.lookAt(50, 0, -1200);
    
    /* END CAMERA */
    
    
    /* CREATE SCENE & FOG */
    
      const scene = new THREE.Scene();
      var setcolor = 0x3A4544;
      scene.background = new THREE.Color(setcolor);
      //scene.fog = new THREE.Fog(setcolor, 0, 4000);
    
    /* END SCENE & FOG */
    
    
    
    /* CREATE RENDERER */
    
      const renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
      renderer.setSize( window.innerWidth, window.innerHeight );
      renderer.setAnimationLoop( animation );
      renderer.setPixelRatio( window.devicePixelRatio );
      renderer.shadowMap.enabled = true;
      renderer.outputEncoding = THREE.sRGBEncoding;
      document.body.appendChild( renderer.domElement );
    
    /* END RENDERER */
    
    
    /* CREATE ORBIT CONTROLS */
    
      const controls = new OrbitControls( camera, renderer.domElement );
      // const controls = new FirstPersonControls( camera, renderer.domElement );
      // controls.movementSpeed = 50;
      // controls.lookSpeed = 0.05;
      // controls.lookVertical = true;
      // controls.constrainVertical = true
    
    /* END ORBIT CONTROLS */
    
    
    /* CREATE LIGHTS */
    
      const rectLight = new THREE.RectAreaLight( 0xf9d71c, glow, 150, 100 );
      scene.add( rectLight );
      rectLight.position.set( -8, 100, -290 );
      rectLight.lookAt( 0, 0, 0 );
    
      const ambientLight = new THREE.AmbientLight(0xaaaaaa, 0.15)
      ambientLight.position.set( 200, 100, 0 );
      ambientLight.lookAt( -300, -300, -300 );
      scene.add(ambientLight)
    
    /* END LIGHTS */
    
    
    /* CREATE CITY */
    
      // Floor
      let groundMirror1, geometry;
      geometry = new THREE.PlaneGeometry( 2500, 2500 );
      groundMirror1 = new Reflector( geometry, {
        clipBias: 0.003,
        color: new THREE.Color(0x212227),
        side: THREE.DoubleSide,
        mixBlur: 5    
      });
    
      groundMirror1.position.y = -50
      groundMirror1.rotateX( - Math.PI / 2);
    
      scene.add( groundMirror1 );
    
    
    
    
      // 3D Building Font
      let text = "JOHN JACOBS";
      let textMesh;
    
      const loader = new FontLoader();
      loader.load('node_modules/three/examples/fonts/droid/droid_serif_regular.typeface.json', function (font) {
        const textGeometry = new TextGeometry(text, {
          font: font,
          size: 40,
          height: 1,
          curveSegments: 12,
          bevelEnabled: true,
          bevelThickness: 2,
          bevelSize: 2,
          bevelOffset: 2,
          bevelSegments: 2
        });
    
        textMesh = new THREE.Mesh(textGeometry, [
          new THREE.MeshPhongMaterial({ emissive: 0xf9d71c, emissiveIntensity: glow }),
          new THREE.MeshPhongMaterial({ color: 0xffffff })
        ]);
    
        scene.add( textMesh );
    
        textMesh.position.y = 1685;
        textMesh.position.x = -2000;
        textMesh.position.z = 250;
        textMesh.rotation.y = ( Math.PI / 2 );
      });
    
    
      // 3D Models
      const gltfLoader1 = new GLTFLoader();
      gltfLoader1.load('models/building2/scene.gltf', (gltfScene1) => {
        gltfScene1.scene.scale.set( 20, 20, 20 );
        gltfScene1.scene.position.x = 20;
        gltfScene1.scene.position.z = 180;
        gltfScene1.scene.position.y = -50;
        scene.add(gltfScene1.scene);
      });
    
      const gltfLoader2 = new GLTFLoader();
      gltfLoader2.load('models/building3/scene.gltf', (gltfScene2) => {
        gltfScene2.scene.scale.set( 80, 80, 80 );
        gltfScene2.scene.position.x = -75;
        gltfScene2.scene.position.z = -400;
        gltfScene2.scene.position.y = -1410;
        gltfScene2.scene.rotation.y = ( - Math.PI / 2 )
        scene.add(gltfScene2.scene);
      });
    
      const gltfLoader3 = new GLTFLoader();
      gltfLoader3.load('models/building4/scene.gltf', (gltfScene3) => {
        gltfScene3.scene.scale.set( 70, 70, 70 );
        gltfScene3.scene.position.x = -500;
        gltfScene3.scene.position.z = 300;
        gltfScene3.scene.position.y = 75;
        scene.add(gltfScene3.scene);
      });
    
      const gltfLoader4 = new GLTFLoader();
      gltfLoader4.load('models/main_building/scene.gltf', (gltfScene4) => {
        gltfScene4.scene.scale.set( 10, 10, 10 );
        gltfScene4.scene.position.x = -2600;
        gltfScene4.scene.position.z = -450;
        gltfScene4.scene.position.y = 75;
        gltfScene4.scene.rotation.y = ( Math.PI / 2);
        scene.add(gltfScene4.scene);
      });
    
      const gltfLoader5 = new GLTFLoader();
      gltfLoader5.load('models/building5/scene.gltf', (gltfScene5) => {
        gltfScene5.scene.scale.set( 10, 10, 10 );
        gltfScene5.scene.position.x = -2600;
        gltfScene5.scene.position.z = -500;
        gltfScene5.scene.position.y = 275;
        scene.add(gltfScene5.scene);
      });
    
      // 3D model and walking animation
      let mixer;
      const zomLoader = new FBXLoader();
      zomLoader.load('models/characters/Ch44_nonPBR.fbx', (fbx) => {
        
        fbx.position.x = -500;
        fbx.position.z = 0;
        fbx.position.y = -50;
        fbx.rotation.y = ( Math.PI / 2 );
        fbx.scale.set( 1, 1, 1 );
    
        const anim = new FBXLoader();
        anim.load('models/characters/Walking.fbx', (anim) => {
          mixer = new THREE.AnimationMixer(fbx);
          const idle = mixer.clipAction(anim.animations[0]);
          idle.play();
        })
        scene.add(fbx)
      });
    
    /* END CITY */
    
    
    /* CREATE WINDOW RESIZE FUNCTION */
    
      window.addEventListener('resize', onWindowResize, false)
      function onWindowResize() {
          camera.aspect = window.innerWidth / window.innerHeight
          camera.updateProjectionMatrix()
          renderer.setSize(window.innerWidth, window.innerHeight)
          animation()
      }
    
    /* END WINDOW RESIZE FUNCTION */
    
    
    
    /* CREATE MAIN ANIMATION FUNCTION */
    
      animation();
      function animation() {
    
        requestAnimationFrame( animation );
    
        //I've tried these two options 
        //fbx.position.x += 0.5;
        //zomLoader(fbx).position.x += 0.5;
    
    
        glow = Math.random() - 0.01;
        textMesh.material[0].emissiveIntensity = glow;
        rectLight.intensity = glow;
    
    
        if(mixer){
          mixer.update(clock.getDelta());
        }
    
    
        //controls.update( clock.getDelta() );
        controls.update();
        renderer.render( scene, camera );
    
      }
    
    /* END MAIN ANIMATION FUNCTION */
    

    我对three.js还是个新手,我唯一移动过任何对象的时候都是网格,而不是导入的3D模型。我习惯于使用 mesh.position.x += 1 在主动画函数中,但当我尝试使用 fbx.position.x += 1 ,场景消失。我如何移动3D模型的位置,以产生模型沿x轴行走的错觉?

    编辑

    我想明白了。我添加了一个全局变量 let human; ,将其分配给 fbx 和使用 human.position.x += 1 在主动画功能中。干杯

    0 回复  |  直到 3 年前