ThreeJS - 来自.json 3D文件的多个网格

时间:2016-10-24 17:14:13

标签: javascript for-loop three.js objloader

我从在线3D编辑器导出了一个.json,我正在尝试加载它并实例化它的20个版本,比如this example。我的代码有缺陷bc所有20个版本实际上就像是同一个对象。不确定为什么它们没有作为给定的x,z坐标中的单独对象添加到场景中。

var serverObject;
var allBrains = []
var xCenter;
var zCenter;
var spacing = .2;
var newServ;

var objectLoader = new THREE.ObjectLoader();
objectLoader.load("asset_src/model.json", function(obj) {

    //give it a global name, so I can access it later?
    serverObject = obj

    //see what's inside of it
    obj.traverse(function(child) {
            if (child instanceof THREE.Mesh) {
                console.log(child)
            }
        })

        //was trying to add transparency this way, but ended up
        //going through the online editor to apply it
        // var cubeMaterial1 = new THREE.MeshBasicMaterial({
        //     color: 0xb7b7b7,
        //     refractionRatio: 0.98
        // });


    //Do i need to instantiate my mesh like this, if so, how do I make sure that it gets the materials from the json? The json has 6 children each with a different material
    // serverObject = new THREE.Mesh( obj, cubeMaterial1 );


    //make 20 versions of the file
    for (var i = 0; i < 20; i++) {
        xCenter = Math.cos(toRadians(i * spacing))
        zCenter = Math.sin(toRadians(i * spacing))
        serverObject.scale.set(.09, .09, .09)

        //this amount of offset is correct for the scale of my world
        //i was going to use my xCenter, zCenter but tried to simplify it till it works
        serverObject.position.set((i * .1), controls.userHeight - 1, i * .1);
        allBrains.push(serverObject)
         //I've attempted a number of ways of adding the obj to the scene, this was just one
        scene.add(allBrains[i]);

    }

     // see that there are 20 meshes
    console.log(allBrains)


});

我上次控制台日志的返回如下所示: enter image description here

3 个答案:

答案 0 :(得分:1)

目前,您有一个对象(serverObject),您可以操作并添加多次,但循环的每次迭代只会修改同一个对象,覆盖以前的参数。

您需要使用... clone()方法克隆网格。然后,您就可以修改 对象(副本)的设置,并且每个网格将保持独立。

或者,您可以在循环内运行objectLoader.load方法从JSON文件多次创建对象,但这可能是浪费资源。

答案 1 :(得分:1)

感谢@jcaor克隆()的想法,这是工作代码:

var objectLoader = new THREE.ObjectLoader();
objectLoader.load("asset_src/model.json", function(obj) {

    //give it a global name, so I can access it later
    serverObject = obj

    //see what's inside of it
    obj.traverse(function(child) {
            if (child instanceof THREE.Mesh) {
                console.log(child)
            }
        })


    for (var i = 0; i < 20; i++) {
        var tempNew = serverObject.clone()
        xCenter = Math.cos(toRadians(i * spacing))
        zCenter = Math.sin(toRadians(i * spacing))
        tempNew.scale.set(.05, .05, .05)
        tempNew.position.set(xCenter, controls.userHeight - 1, zCenter);
        allBrains.push(tempNew)
        scene.add(allBrains[i]);

    }

    console.log(allBrains)

});

答案 2 :(得分:0)

这对我来说就像一个指针问题。

在JavaScript中,您可以考虑像指针这样的变量,这就是为什么您不必为变量分配类型以及函数如何成为变量并且仍然可以在普通计算机科学中工作的原因。

在这种情况下,您将为数组中的每个插槽分配相同的指针。

这是问题的超级简单版本。 obj2.foo从未改变,但是因为我们改变了obj.foo obj2.foo因为var只是指向同一个对象而改变了。

var obj = {
  foo : 1
}
var obj2 = obj;

obj.foo = 2;

console.log(obj2.foo);

我要做的是创建一个新对象,并在主题为“serverObject”的情况下使用主对象的信息弹出它

allBrains.push(serverObject)