javascriptthree.jsdat.gui

How to use dat.gui to control the rotation speed of a model in three.js?


I wanna control rotation speed of my model,so I try to use dat.gui to accomplish it.And I write flollows in my render script:

function render() {
                    group.rotation.y -= controls.rotation;
                    renderer.render(scene, camera);
                } 

controls is parameter of dat.gui.

var controls = {
                    rotation :-0.004,
                };
                var gui = new dat.GUI();
                gui.add(controls, 'rotation', -0.001, 0.001);

But when I run my demo,my model disappeared!I can see my scene only. I wanna know where errors occur,so I modify it:

function render() {
                    alert(controls.rotation);
                    group.rotation.y -= controls.rotation;
                    renderer.render(scene, camera);
                } 

I found first alert was -0.004,but the others (the second,the third,etc...)were undefined.So I guess my demo only render the first frame,because model was not loading competely,so I cannot see it.

I wanna to know why it happened,and how to fix it?

Ps:all codes follows:

<head>
    <meta charset="UTF-8">
    <title>ytest</title>
    <script type="text/javascript" src="JSandCSS/three.js"></script>
    <script type="text/javascript" src="JSandCSS/OrbitControls.js"></script>
    <script type="text/javascript" src="JSandCSS/OBJLoader.js"></script>
    <script type="text/javascript" src="JSandCSS/Raycaster.js"></script>
    <script type="text/javascript" src="dat.gui-master/build/dat.gui.js"></script>
    <script type="text/javascript" src="JSandCSS/stats.min.js"></script>
    <style>
    body {
        /* set margin to 0 and overflow to hidden, to go fullscreen */
        margin: 0;
        overflow: hidden;
    }
</style>
</head>

<body>
    <div id="Stats-output">
    </div>
    <div id="WebGL-output">
    </div>
    <div id="form">
    </div>
    <div id="ui">
    </div>
    <script type="text/javascript">
        function init() {

            var stats = initStats();
            var scene = new THREE.Scene();
            var group = new THREE.Group;
            scene.add(group);
            var controls = new function() {
                this.rotation = 0.004;
            };
            var gui = new dat.GUI();
            gui.add(controls, 'rotation', 0, 0.008);

            var textureLoader = new THREE.TextureLoader();
            var mat = new THREE.MeshLambertMaterial({
                map: textureLoader.load("model/earth/texture.jpg"),
                specularMap: textureLoader.load("model/earth/specular.jpg"),
                lightMap: textureLoader.load("model/earth/light.jpg")
            }); 

            var loader = new THREE.OBJLoader();
            loader.load('model/earth/earth.obj',
                function chuanzhi(obj) {
                    obj.traverse(function(child) {
                        if(child instanceof THREE.Mesh) {
                            child.material = mat;
                        }
                    });
                    Mesh = obj;
                    obj.scale.set(2, 2, 2);
                    group.add(obj);
                    objects.push(Mesh);
                });

            var light = new THREE.PointLight(0xffffff);
            light.position.set(300, 400, 200);
            light.intensity.set = 0.1;
            scene.add(light);
            scene.add(new THREE.AmbientLight(0x333333));


            var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
            camera.position.set(200, 200, 200);
            camera.lookAt(scene.position);

            var renderer = new THREE.WebGLRenderer({
                antialias: true
            });
            renderer.setSize(window.innerWidth, window.innerHeight);
            document.body.appendChild(renderer.domElement);

            renderer.render(scene, camera);
            renderer.setClearColor(0x808080, 0.5); 


            document.getElementById("WebGL-output").appendChild(renderer.domElement);

            var controls = new THREE.OrbitControls(camera);
            controls.addEventListener('change', render); 

            render(); 

            window.addEventListener('resize', handleWindowResize, false); 

            function render() {
                stats.update();
                group.rotation.y-=controls.rotation;
                requestAnimationFrame(render);
                renderer.render(scene, camera);

            } 
            function handleWindowResize() {
                HEIGHT = window.innerHeight;
                WIDTH = window.innerWidth;
                renderer.setSize(WIDTH, HEIGHT);
                camera.aspect = WIDTH / HEIGHT;
                camera.updateProjectionMatrix();
            }

            function initStats() {

                var stats = new Stats();

                stats.setMode(0); // 0: fps, 1: ms

                // Align top-left
                stats.domElement.style.position = 'absolute';
                stats.domElement.style.left = '0px';
                stats.domElement.style.top = '0px';

                document.getElementById("Stats-output").appendChild(stats.domElement);

                return stats;
            }
        }
        window.onload = init;
    </script>

</body>


Solution

  • Have you tried to use in the render cycle

    group.rotateY(controls.rotation);
    

    for setting the geometry rotation? (I'm asumming you're rotating the geometry).

    Another aproach could be the following:

    var rotationAngle = 0.001;
    ...
    var gui = new dat.GUI();
    gui.add(controls, 'rotation', -5, 5).onChange(function(value){
    rotationAngle = value * Math.PI / 180;
    });
    ...
    function render() {
                        group.rotateY(rotationAngle);
                        renderer.render(scene, camera);
                    }