Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

refresh dat.gui with new values

I would like to refresh the dat.gui menu with new values. I have loaded a model and display in folder the name of the objects inside a gui folder.
How can I display the new object name when I reload a other model ?
Or it's possible to reset/clear the gui. enter image description here

like image 663
user2244365 Avatar asked Apr 23 '13 09:04

user2244365


4 Answers

Basically, you have to set the controllers to "listen" for input when you add them, for example,

gui = new dat.GUI();
var guiX = gui.add( parameters, 'x' ).min(0).max(200).listen();

For documentation, see:

http://workshop.chromeexperiments.com/examples/gui/#9--Updating-the-Display-Automatically

For an example of this in Three.js, see:

http://stemkoski.github.io/Three.js/GUI-Controller.html

like image 93
Stemkoski Avatar answered Oct 19 '22 09:10

Stemkoski


Echt Einfach's solution didn't work for me, and Stemkoski's one is a bit wide. I finally made it with the updateDisplay function:

for (var i in gui.__controllers) {
    gui.__controllers[i].updateDisplay();
}

http://workshop.chromeexperiments.com/examples/gui/#10--Updating-the-Display-Manually

Note that if you have the values in some folder folder1 the call is like this:

for (var i = 0; i < this.gui.__folders.folder1.__controllers.length; i++) {
    this.gui.__folders.folder1.controllers[i].updateDisplay();
}

If you do not want to hard-code folder1, or simply want to update all folders, you can proceed as follows:

for (var i = 0; i < Object.keys(gui.__folders).length; i++) {
    var key = Object.keys(gui.__folders)[i];
    for (var j = 0; j < gui.__folders[key].__controllers.length; j++ )
    {
        gui.__folders[key].__controllers[j].updateDisplay();
    }
}
like image 31
jmmut Avatar answered Oct 19 '22 09:10

jmmut


Wrote a function to update dat.gui dropdowns with a new set of values:

function updateDatDropdown(target, list){   
    innerHTMLStr = "";
    if(list.constructor.name == 'Array'){
        for(var i=0; i<list.length; i++){
            var str = "<option value='" + list[i] + "'>" + list[i] + "</option>";
            innerHTMLStr += str;        
        }
    }

    if(list.constructor.name == 'Object'){
        for(var key in list){
            var str = "<option value='" + list[key] + "'>" + key + "</option>";
            innerHTMLStr += str;
        }
    }
    if (innerHTMLStr != "") target.domElement.children[0].innerHTML = innerHTMLStr;
}

Usage:

myDropdown = gui.add(MyObject, 'myVariable', ['one','two','three']);
updateDatDropdown(myDropdown , ['A','B','C']);

// Also accepts named values

updateDatDropdown(myDropdown , {'A':1,'B':2,'C':3});
like image 4
Andru Phoenix Avatar answered Oct 19 '22 10:10

Andru Phoenix


Lee Stemkoski's and Echt Einfach's solutions use the .listen() method on a selected controller in the GUI.

jmmut's solution ,using .updateDisplay(), loops through ALL of the controllers in the GUI

It strikes me that both these solution types are EXPENSIVE if you only want to manually update the value of a single controller at a particular time.

You can avoid this by using the method .updateDisplay() for a SINGLE controller.

One way to do this is if you know beforehand the index[i] of the single controller. But this is rather fiddly to implement.

A better way is to reference the particular controller by name

// AT INITIALISATION TIME
gui1 = new dat.GUI();
Gparameters = { x: 0, y: 0, z: 0}
var gui1_X = gui1.add( Gparameters, 'x' ).min(0).max(200); // note no need to use the method .listen()

// AT RUN TIME
Gparameters.x++;
gui1_X.updateDisplay()  

Note: I have not included the extra code required to make this work with controllers inside folders. You can get this from the other answers.

like image 3
steveOw Avatar answered Oct 19 '22 10:10

steveOw