先贴上我前无古人后无来者的宇宙无敌搅拌机
我想用键盘控制框框中各部分分别有各自的动作,我这模型虽然是简单几何体堆积的,但是这是在blender里制作了模型,导出obj格式的模型再导进页面的,主要是测试功能,所以模型没好好做,有点辣眼睛。在blender里制作模型的时候我把需要单独动作的部分不进行合并,这样导进页面后好控制。
我用OBJLoader和MTLLoader将模型导入页面
用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)狼行天下 的资料分享。
这个方法还是笨笨的,毕竟模型复杂没有尺寸或者动作较多时不能挨个找轴位置啊,感觉可解燃眉之急但并不是长久之计。若有好的思路望众大神不吝赐教~~~