0

Im creating a scene using three.js and im adding 3 spheres to it. Then im trying to switching all spheres created from wireframe to non-wireframe material. I not using scene.traverse() because i have more objects on my scene and i only want to switch the spheres, but with this code i can only switch one sphere. How can i get to every sphere? Any help? Thanks!

var numSpheres = 3;

function createSphere (x, y, z){

    sphere = new THREE.Object3D();

    material = new THREE.MeshBasicMaterial({ color: 0XFFA500, wireframe: true});
    geometry = new THREE.SphereGeometry (2, 8, 8);
    mesh = new THREE.Mesh(geometry, material);

    sphere.add(mesh);
    sphere.position.set(x, y, z);

    scene.add(sphere);
}

createSpheres(numSpheres){

    for(i = 1; i <= numSpheres; i++){       
        var randomnumber1 = Math.floor(Math.random() * (29.5 - -29.5 + 1)) + -29.5;
        var randomnumber2 = Math.floor(Math.random() * (29.5 - -29.5 + 1)) + -29.5;

        createSphere(randomnumber1, 3, randomnumber2);
    }
}
function onKeyDown(e){

    case 65: 
    case 97:
        sphere.traverse(function (node){
                if(node instanceof THREE.mesh) {
                    node.material.wireframe = !node.material.wireframe;
                }
        });
  • You can push all created spheres into an array and then loop through it, changing property of materials of spheres in it. – prisoner849 Oct 25 '17 at 10:05
  • @prisoner849 isnt traverse function supposed to run all sphere childs? – Duarte Meneses Oct 25 '17 at 10:13
  • 1
    In the context of the given code, `sphere` has the reference to the last created instance of `THREE.Object3D()`, which has just one child of `THREE.Mesh()`, so, traversing it, you change the material of the last sphere. – prisoner849 Oct 25 '17 at 10:36

2 Answers2

0

As @prisoner849 suggested, put your objects you want to manipulate in an array or map (as @prisoner849 suggested). This way, you avoid the test instanceof THREE.Mesh and you only manipulate the objects you want to manipulate.

var numSpheres = 3;
var spheresMap = {}; // OR
var spheresArray = [];

function createSphere (x, y, z){

    var sphere = new THREE.Object3D();

    material = new THREE.MeshBasicMaterial({ color: 0XFFA500, wireframe: true});
    geometry = new THREE.SphereGeometry (2, 8, 8);
    mesh = new THREE.Mesh(geometry, material);

    sphere.add(mesh);
    sphere.position.set(x, y, z);

    scene.add(sphere);

    spheresMap[sphere.id] = sphere; // OR
    spheresArray.push(sphere);
}

createSpheres(numSpheres){

    for(i = 1; i <= numSpheres; i++){       
        var randomnumber1 = Math.floor(Math.random() * (29.5 - -29.5 + 1)) + -29.5;
        var randomnumber2 = Math.floor(Math.random() * (29.5 - -29.5 + 1)) + -29.5;

        createSphere(randomnumber1, 3, randomnumber2);
    }
}
function onKeyDown(e){

    case 65: 
    case 97:
        for (var key in spheresMap) {
            spheresMap[key].material.wireframe = !spheresMap[key].material.wireframe;
        }
        // OR
        for (var i=0; i<spheresArray.length; i++) {
            spheresArray[i].material.wireframe = !spheresArray[i].material.wireframe;
        }
}
Brakebein
  • 2,197
  • 1
  • 16
  • 21
0

If You can reach your spheres one by one in the future, most relative is array in object:

 function createSphere (x, y, z){

        var sphere= new THREE.Mesh(new THREE.SphereGeometry (2, 8, 8), new THREE.MeshBasicMaterial({ color: 0XFFA500, wireframe: true}));

        scene.add(sphere);
        sphere.position.set(x, y, z);    
        return sphere;

 }

 mySpheres = {};
 mySpheres.models = [];
 mySpheres.materials = [];

 for(i = 1; i <= 3; i++){       
        var randomnumber1 = Math.floor(Math.random() * (29.5 - -29.5 + 1)) + -29.5;
        var randomnumber2 = Math.floor(Math.random() * (29.5 - -29.5 + 1)) + -29.5;

        var obj = createSphere(randomnumber1, 3, randomnumber2); // 
        var id = obj.id; // or whartever (redone,barrack,donald,george)
        mySpheres.models[id] = obj;
        mySpheres.materials.push(obj.material);
 }


    //after that you can do 
    mySpheres.models['donald'].translateX(10); 
    //or 
    mySpheres.models['george'].material.opacity = 0.5;
    //or
    mySpheres.materials.forEach(function(m) {
         m.opacity = 0.5;
    });
Martin
  • 2,575
  • 6
  • 32
  • 53
  • `mySpheres.materials = [];` and then in the loop its value is just `mySpheres.materials = obj.material;`, which is `THREE.MeshBasicMaterial()`, and not an array. – prisoner849 Oct 26 '17 at 14:40