Threejs使用鼠标移动事件旋转多个对象

时间:2015-06-19 14:44:54

标签: javascript three.js

我想要旋转多个对象,但只能旋转一个对象。 这是我的代码:

1.creatgeo fun

function createScene( geometry, scale, material ) {

geometry.computeTangents();

creatgeo = new THREE.Mesh( geometry, material );

creatgeo.scale.x = creatgeo.scale.y = creatgeo.scale.z = scale;

scene.add( creatgeo );

}

2.在函数init()中使用json loader

var jgdframe = new THREE.JSONLoader();
jgdframe.load( "obj/jgd/GALD-JGD-frame.json", function( geometry ) { createScene( geometry, 1, framemat ) } );
var jgdlogo = new THREE.JSONLoader();
jgdlogo.load( "obj/jgd/GALD-JGD-logo.json", function( geometry ) { createScene( geometry, 1, logomat ) } );
var jgdlight = new THREE.JSONLoader();
jgdlight.load( "obj/jgd/GALD-JGD-light.json", function( geometry ) { createScene( geometry, 1, lightmat ) } );

函数init()中的3.add事件

document.addEventListener( 'mousemove', onDocumentMouseMove, false );

4.在函数render()

中渲染
function render() {

var ry = mouseX * 0.0003, rx = mouseY * 0.0003;

if( creatgeo ) {

    creatgeo.rotation.y = ry;
    creatgeo.rotation.x = rx;

};


camera.lookAt( scene.position );

renderer.render( scene, camera );

}

我加载了三个物体,但只有一个物体可以旋转。 如何解决它。谢谢大家!

1 个答案:

答案 0 :(得分:0)

查看代码示例,我可以指出一些更正:

  • 名为creatgeo的变量未预先初始化。如果每次调用函数createScene()时都被覆盖,这会使它在全局范围内泄漏。这就是为什么只有最后加载的对象是动画的。

  • 您应该在为其分配任何值之前声明任何变量:var creatgeo;。这使得变量仅在函数的本地范围内可用。虽然这不足以解决您的问题。你需要声明一个数组或一个对象,你将缓存jsonLoader加载的所有模型。

这样的事情应该有效:

var objects = []; // I suggest renaming "creatgeo" to "objects"

function updateScene( id, geometry, scale, material ) {
    geometry.computeTangents();
    objects[id]= new THREE.Mesh( geometry, material );
    objects[id].scale.x = objects[id].scale.y = objects[id].scale.z = scale;
    scene.add( objects[id] );
}
  • 另请注意,每次加载对象时都不需要创建加载器,这样效率低,加载时会降低浏览器的速度,同时还会分配更多内存。

  • 注意您可以在json对象中使用导出工具定义的自定义材质。如果您的模型已定义材料,请使用装载器材料。如果不按原样保留。

示例:

var jsonLoader = new THREE.JSONLoader();

jsonLoader.load( 
    "obj/jgd/GALD-JGD-frame.json", 
    function( geometry, material ) { 
        createScene( 0, geometry, 1, framemat ) 
    });

jsonLoader.load( 
    "obj/jgd/GALD-JGD-logo.json", 
    function( geometry, material ) { 
        createScene( 1, geometry, 1, logomat ) 
    });

jsonLoader.load( 
    "obj/jgd/GALD-JGD-light.json", 
    function( geometry, material ) { 
        createScene( 2, geometry, 1, lightmat ) 
    });
  • 您可以通过使用循环增加id并从数组中检索路径字符串来进一步实现此目的。
  • 观察IIFE(立即调用函数表达式)。在这种结构中,这绝对是必要的。 IIFE创建了一个闭包,其id保存在当前迭代中。否则,所有加载器将收到增加的id的最后一个值,弄乱代码。

示例:

var jsonLoader = new THREE.JSONLoader(),
    paths = [
        "obj/jgd/GALD-JGD-frame.json", 
        "obj/jgd/GALD-JGD-logo.json", 
        "obj/jgd/GALD-JGD-light.json"
    ],
    objNum = paths.length; // Cache obects.length


for ( var id = 0; id < paths.length; id++ ) {
    (function(){ // IIFE start

        // Basic loader
        jsonLoader.load( paths[id], 
            function( geometry, material ) { 
                createScene( id, geometry, 1, material ) 
            }
        );

    })(); // IIFE end
}
  • 最后,您需要为每个对象设置动画。

这是渲染循环:

for ( var id = 0; id < objNum; id++ ) {
    if( objects[id] ) {
        objects[id].position.set(x, y, z);
        objects[id].rotation.set(rx, ry, rz);
    }
}