Search code examples
javascriptthree.jsdat.gui

updating dat.gui based on selected object


current working code

I'm trying to figure out how to update/change/refresh dat.gui to reflect my current selection. My goal is to generate some random cubes and then select a single cube for manipulation like: rotate, scale, change position, etc.

The first step is being able to select a cube and being able to control something, anything from dat.gui. In the example below, I simply want to display the name of the selected object. I feel like If I solve that, I can add methods to control rotation, position, etc.

I am trying to achieve something like this, but this code is old and hard to understand.

controller = new THREE.Object3D();
controller.objects = [];
controller.scene = scene;
controller.gui = gui;
controller.color = 0xFFFFFF;
controller.number_of_objects = controller.objects.length;
controller.selected_cube = 'test123';


controller.createNew = function() {
    var cube = new THREE.Mesh(
            new THREE.BoxGeometry(5, 5, 5),
            new THREE.MeshBasicMaterial({
                color: Math.random() * 0xffffff,
            opacity: 0.5})
    );

    cube.position.x = Math.random() * (world_size * 2) - world_size;
    cube.position.z = Math.random() * (world_size * 2) - world_size;
    cube.name = 'cube_' + controller.objects.length;

    controller.scene.add(cube);
    controller.objects.push(cube);
    controller.number_of_objects = controller.objects.length;
    controller.selected_cube = cube.name;

};

gui.add(controller, 'number_of_objects').listen();
gui.add(controller, 'selected_cube').listen();
gui.add(controller, 'createNew');

Solution

  • I've forked your example and added code so that the selected cube gets shown in the dat.GUI control:

    http://jsfiddle.net/Fresh/5vbkub4v/

    The code to achieve this is here:

        if (intersects.length > 0) {
            var selectedObject = intersects[0].object;
            selectedObject.material.color.setHex(Math.random() * 0xffffff);
    
            // listen() has already been applied to the dat.GUI selected_cube controller
            // so updating the value of selected_cube will cause the dat.GUI view
            // to be automatically updated.
            controller.selected_cube = selectedObject.name;
    
            var particle = new THREE.Sprite(particleMaterial);
            particle.position.copy(intersects[0].point);
            particle.scale.x = particle.scale.y = 2;
            scene.add(particle);
        }
    

    This works because as:

    gui.add(controller, 'selected_cube').listen();
    

    has already been defined, changing the value of dat.GUI selected_cube variable would automatically be reflected in the control panel.