three.js加載obj模型 鍵盤控制模型局部動作

   先貼上我前無古人後無來者的宇宙無敵攪拌機


我想用鍵盤控制框框中各部分分別有各自的動作,我這模型雖然是簡單幾何體堆積的,但是這是在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)狼行天下 的資料分享。

這個方法還是笨笨的,畢竟模型複雜沒有尺寸或者動作較多時不能挨個找軸位置啊,感覺可解燃眉之急但並不是長久之計。若有好的思路望衆大神不吝賜教~~~



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章