0

オンライン 3D エディターから .json をエクスポートし、それを読み込んで、この例のように 20 のバージョンをインスタンス化しようとしています。私のコードには欠陥があり、実際には 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)


});

最後のコンソール ログは次のように返されます。 ここに画像の説明を入力

4

3 に答える 3

1

clone() のアイデアを提供してくれた @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)

});
于 2016-10-24T18:56:22.617 に答える
1

現時点では、serverObject複数回操作して追加する単一のオブジェクト ( ) がありますが、ループの各反復では同じオブジェクトが変更され、以前のパラメーターがオーバーライドされます。

clone()...メソッドを使用して、メッシュのクローンを作成する必要があります。その後、そのオブジェクト (コピー)の設定を変更できるようになり、各メッシュは独立したままになります。

または、ループ内でメソッドを実行してobjectLoader.load、JSON ファイルからオブジェクトを複数回作成することもできますが、これはおそらくリソースの無駄です。

于 2016-10-24T18:36:14.820 に答える
0

これは私にはポインターの問題のように見えます。

JavaScript では、変数をポインターのようなものと考えることができます。そのため、変数に型を割り当てる必要がなく、関数を変数にして、通常のコンピューター サイエンスで機能させることができます。

この場合、配列内の各スロットに同じポインタを割り当てています。

これは問題の超単純バージョンです。obj2.foo は変更されませんでしたが、obj.foo を変更したため、var が単に同じオブジェクトを指しているため、obj2.foo が変更されました。

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

obj.foo = 2;

console.log(obj2.foo);

私がすることは、新しいオブジェクトを作成し、「serverObject」の場合はマスターオブジェクトの情報を入力することです

allBrains.push(serverObject)
于 2016-10-24T18:44:49.297 に答える