three.js加载obj模型键盘控制模型局部动作

xiaoxiao2021-02-28  126

   先贴上我前无古人后无来者的宇宙无敌搅拌机

我想用键盘控制框框中各部分分别有各自的动作,我这模型虽然是简单几何体堆积的,但是这是在blender里制作了模型,导出obj格式的模型再导进页面的,主要是测试功能,所以模型没好好做,有点辣眼睛。在blender里制作模型的时候我把需要单独动作的部分不进行合并,这样导进页面后好控制。

我用OBJLoader和MTLLoader将模型导入页面

<script src="build/three.js"></script> <script src="build/OBJLoader.js"></script> <script src="build/MTLLoader.js"></script>

用Object3D的移动旋转方法控制局部动作。cord的位置是按照从大块动作到小块动作的方向找的,cord4的位置是相对于cord3位置的偏移量。加cubMesh是为了标识coed的位置,cubeMesh位置不重新设置,只改变cord的位置,这样将cubMesh调到旋转中心点后(即cord的原点),无论cord中包含什么,不管设置的是朝哪个方向转动,转动的中心都是此cubMesh。上图中是调好cord位置后把cubeMesh注释掉的结果。

var container; var camera, scene, renderer,cord; var robot=null,joint1=null,joint2=null; var mouseX = 0, mouseY = 0; var m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12; var windowHalfX = window.innerWidth / 2; var windowHalfY = window.innerHeight / 2; var cord0=new THREE.Object3D; var cord1=new THREE.Object3D; var cord2=new THREE.Object3D; var cord3=new THREE.Object3D; var cord4=new THREE.Object3D; var cord5=new THREE.Object3D; init(); function init() { container = document.createElement( 'div' ); document.body.appendChild( container ); camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 10000 ); camera.position.set(200, 100, 150); scene = new THREE.Scene(); //辅助轴 // var axisHelper = new THREE.AxisHelper( 500); // scene.add( axisHelper ); //辅助网格 // var size = 100; // var step = 10; // // var gridHelper = new THREE.GridHelper( size, step ); // scene.add( gridHelper ); // var gridHelper1 = new THREE.GridHelper( size, step ); // gridHelper1.rotation.z=Math.PI*0.5; // scene.add( gridHelper1 ); var ambient = new THREE.AmbientLight( 0x101030,5 ); scene.add( ambient ); var directionalLight = new THREE.DirectionalLight( 0xffeedd ,1); directionalLight.position.set( 0, 10, 10 ); scene.add( directionalLight ); // texture var manager = new THREE.LoadingManager(); manager.onProgress = function ( item, loaded, total ) { }; var onProgress = function ( xhr ) { if ( xhr.lengthComputable ) { var percentComplete = xhr.loaded / xhr.total * 100; } }; var onError = function ( xhr ) { }; var mtlLoader = new THREE.MTLLoader(); mtlLoader.setPath('obj/'); mtlLoader.load('jiaobanji.mtl', function(materials) { materials.preload(); var objLoader = new THREE.OBJLoader(); objLoader.setMaterials(materials); objLoader.setPath('obj/'); objLoader.load('jiaobanji.obj', function(object) { m0=object.children[5]; m1=object.children[4]; m2=object.children[3]; m3=object.children[2]; m4=object.children[1]; m5=object.children[0]; //找cord位置的辅助方块 // var cubeMesh, cubeMesh1,cubeMesh2,cubeMesh3,cubeMesh4; // cubeMesh = new THREE.Mesh(new THREE.BoxGeometry(5,5,5),new THREE.MeshLambertMaterial({color:0xff0000})); // cubeMesh1 = new THREE.Mesh(new THREE.BoxGeometry(5,5,5),new THREE.MeshLambertMaterial({color:0x000000})); // cubeMesh2 = new THREE.Mesh(new THREE.BoxGeometry(5,5,5),new THREE.MeshLambertMaterial({color:0x000080})); // cord5.add(m5,cubeMesh); cord5.add(m5); cord5.position.set(0,-25,0); m5.position.x-=(cord5.position.x); m5.position.y-=(cord5.position.y); m5.position.z-=(cord5.position.z); // cord4.add(m4,cord5,cubeMesh1); cord4.add(m4,cord5); cord4.position.set(0,-5,0); m5.position.x-=(cord4.position.x); m5.position.y-=(cord4.position.y); m5.position.z-=(cord4.position.z); m4.position.x-=(cord4.position.x); m4.position.y-=(cord4.position.y); m4.position.z-=(cord4.position.z); // cord3.add(m3,cord4,cubeMesh2); cord3.add(m3,cord4); cord3.position.set(0,0,-60); m5.position.x-=(cord3.position.x); m5.position.y-=(cord3.position.y); m5.position.z-=(cord3.position.z); m4.position.x-=(cord3.position.x); m4.position.y-=(cord3.position.y); m4.position.z-=(cord3.position.z); m3.position.x-=(cord3.position.x); m3.position.y-=(cord3.position.y); m3.position.z-=(cord3.position.z); cord2.add(m2,cord3); cord2.position.set(0,96,0); m5.position.x-=(cord2.position.x); m5.position.y-=(cord2.position.y); m5.position.z-=(cord2.position.z); m4.position.x-=(cord2.position.x); m4.position.y-=(cord2.position.y); m4.position.z-=(cord2.position.z); m3.position.x-=(cord2.position.x); m3.position.y-=(cord2.position.y); m3.position.z-=(cord2.position.z); m2.position.x-=(cord2.position.x); m2.position.y-=(cord2.position.y); m2.position.z-=(cord2.position.z); cord1.add(m1,cord2); cord0.add(m0,cord1); scene.add(cord0); render(); return object; }, onProgress, onError); }); renderer = new THREE.WebGLRenderer(); renderer.setClearColor( 0xffffff ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); container.appendChild( renderer.domElement ); window.addEventListener( 'resize', onWindowResize, false ); document.addEventListener( 'keydown', onKeyDown, false ); } function onKeyDown(event){ if(event.keyCode==90){ cord1.rotation.y+=0.1; } if(event.keyCode==65){ cord1.rotation.y-=0.1; } if(event.keyCode==88){ if(cord2.rotation.x>3.14){} else{ cord2.rotation.x+=0.1; } } if(event.keyCode==83){ if(cord2.rotation.x<-0.4){} else{ cord2.rotation.x-=0.1; } } if(event.keyCode==67){ cord3.rotation.x+=0.1; } if(event.keyCode==68){ cord3.rotation.x+=0.1; } if(event.keyCode==86 ){ if(cord4.position.y>6){} else{ cord4.position.y+=0.5; } } if(event.keyCode==70 ){ if(cord4.position.y<-6){} else{ cord4.position.y-=0.5; } } if(event.keyCode==66){ cord5.rotation.y+=0.1; } if(event.keyCode==71){ cord5.rotation.y-=0.1; } render(); } function onWindowResize() { windowHalfX = window.innerWidth / 2; windowHalfY = window.innerHeight / 2; camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight ); } function render() { camera.lookAt(new THREE.Vector3( 0, 50, 0 )); renderer.render( scene, camera ); } 看效果:http://ulyanov.esy.es/3D/jiaobanji.html

感谢WebGL学习交流群(Three.js)狼行天下 的资料分享。

这个方法还是笨笨的,毕竟模型复杂没有尺寸或者动作较多时不能挨个找轴位置啊,感觉可解燃眉之急但并不是长久之计。若有好的思路望众大神不吝赐教~~~

转载请注明原文地址: https://www.6miu.com/read-17546.html

最新回复(0)