yongnan
yongnan

Reputation: 415

How to control the data.gui.js that do not affect the object(Three.js r66)

I write a trackball to control the object rotation, everything goes fine. However, when I add the gui component to the program, and when I put the mouse to change the gui, the object is moving. Because my trackball project the screen coordinate to the virtual ball, when my mouse is on the gui component, it is still in the screen, and it makes the object move. How to avoid that? I try t find the reason about the trackball three.js has, and do not find the a result. Why his trackball do not affact the gui object?

<!DOCTYPE html>
<html lang="en">
<head>
    <title>three.js canvas - geometry - cube</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <style>
        body {
            font-family: Monospace;
            background-color: #f0f0f0;
            margin: 0px;
            overflow: hidden;
        }
    </style>
</head>
<body>

<script src="../build/three.min.js"></script>

<script src="js/libs/dat.gui.min.js"></script>
<script src="js/libs/stats.min.js"></script>
<script>

var container, stats;

var camera, scene, renderer;

var cube, plane;



var mouseDown = false;
var rotateStartP = new THREE.Vector3(0,0,1);
var rotateEndP = new THREE.Vector3(0,0,1);

var lastPosX;
var lastPosY;
var targetRotationY = 0;
var targetRotationX = 0;
var quater;
//var rotateQuaternion = new THREE.Quaternion();
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;

init();
animate();

function init() {

    container = document.createElement( 'div' );
    document.body.appendChild( container );

    var info = document.createElement( 'div' );
    info.style.position = 'absolute';
    info.style.top = '10px';
    info.style.width = '100%';
    info.style.textAlign = 'center';
    info.innerHTML = 'Drag to spin the cube';
    container.appendChild( info );

    camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
    camera.position.y = 150;
    camera.position.z = 500;

    scene = new THREE.Scene();

    // Cube

    var geometry = new THREE.CubeGeometry( 200, 200, 200 );

    for ( var i = 0; i < geometry.faces.length; i += 2 ) {

        var hex = Math.random() * 0xffffff;
        geometry.faces[ i ].color.setHex( hex );
        geometry.faces[ i + 1 ].color.setHex( hex );

    }

    var material = new THREE.MeshBasicMaterial( { vertexColors: THREE.FaceColors, overdraw: 0.5 } );

    cube = new THREE.Mesh( geometry, material );
    cube.position.y = 150;
    scene.add( cube );

    // Plane

    var geometry = new THREE.PlaneGeometry( 200, 200 );
    geometry.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) );

    var material = new THREE.MeshBasicMaterial( { color: 0xe0e0e0, overdraw: 0.5 } );

    plane = new THREE.Mesh( geometry, material );
    scene.add( plane );

    renderer = new THREE.CanvasRenderer();
    renderer.setClearColor( 0xf0f0f0 );
    renderer.setSize( window.innerWidth, window.innerHeight );

    container.appendChild( renderer.domElement );
    //GUI
    var controls = new function () {

        this.xx = false;
        this.yy = 512;



        this.onChange = function () {

        }

    };

    var gui = new dat.GUI();
    gui.add(controls, 'xx').onChange(controls.onChange);
    gui.add(controls, 'yy', 1, 10).step(1).onChange(controls.onChange);

    stats = new Stats();
    stats.domElement.style.position = 'absolute';
    stats.domElement.style.top = '0px';
    container.appendChild( stats.domElement );

    document.addEventListener( 'mousedown', onDocumentMouseDown, false );
    document.addEventListener( 'touchstart', onDocumentTouchStart, false );
    document.addEventListener( 'touchmove', onDocumentTouchMove, false );

    //

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

}

function onWindowResize() {

    windowHalfX = window.innerWidth / 2;
    windowHalfY = window.innerHeight / 2;

    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    renderer.setSize( window.innerWidth, window.innerHeight );

}

//

function onDocumentMouseDown( event ) {

    event.preventDefault();

    document.addEventListener( 'mousemove', onDocumentMouseMove, false );
    document.addEventListener( 'mouseup', onDocumentMouseUp, false );
    document.addEventListener( 'mouseout', onDocumentMouseOut, false );
    mouseDown = true;
    rotateStartP = projectOnTrackball(event.clientX, event.clientY);
}

function onDocumentMouseMove( event ) {

    if(!mouseDown)
    {
        return;
    }

    rotateEndP = projectOnTrackball(event.clientX, event.clientY);


}
function getMouseOnScreen( pageX, pageY) {

    return new THREE.Vector2.set(pageX / window.innerWidth ,pageY / window.innerHeight);

}

function projectOnTrackball(pageX, pageY) // The screen coordinate[(0,0)on the left-top] convert to the
    //trackball coordinate [(0,0) on the center of the page]
{
    var mouseOnBall = new THREE.Vector3();
    mouseOnBall.set(
                    ( pageX - window.innerWidth * 0.5 ) / (window.innerWidth * .5),
                    ( window.innerHeight * 0.5 - pageY ) / ( window.innerHeight * .5),
            0.0
    );

    var length = mouseOnBall.length();
    if (length > 1.0) {

        mouseOnBall.normalize();

    }
    else {
        mouseOnBall.z = Math.sqrt(1.0 - length * length);
    }
    return mouseOnBall;
}

function rotateMatrix(rotateStart, rotateEnd)
{
    var axis = new THREE.Vector3(),
            quaternion = new THREE.Quaternion();

    var angle = Math.acos( rotateStart.dot( rotateEnd ) / rotateStart.length() / rotateEnd.length() );

    if ( angle )
    {
        axis.crossVectors( rotateStart, rotateEnd ).normalize();
        angle *= 0.01;            //Here we could define rotate speed
        quaternion.setFromAxisAngle( axis, angle );
    }
    return  quaternion;
}

function onDocumentMouseUp( event ) {

    document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
    document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
    document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
    mouseDown = false;
    rotateStartP = rotateEndP;

}

function onDocumentMouseOut( event ) {

    document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
    document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
    document.removeEventListener( 'mouseout', onDocumentMouseOut, false );

}

function onDocumentTouchStart( event ) {

    if ( event.touches.length === 1 ) {

        event.preventDefault();
        /*
         mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX;
         targetRotationOnMouseDownX = targetRotationX;
         mouseYOnMouseDown = event.touches[ 0 ].pageY - windowHalfY;
         targetRotationOnMouseDownY = targetRotationY;  */
    }

}

function onDocumentTouchMove( event ) {

    if ( event.touches.length === 1 ) {

        event.preventDefault();
        /*
         mouseX = event.touches[ 0 ].pageX - windowHalfX;
         targetRotationX = targetRotationOnMouseDownX + ( mouseX - mouseXOnMouseDown ) * 0.05;
         mouseY = event.touches[ 0 ].pageY - windowHalfY;
         targetRotationY = targetRotationOnMouseDownY + ( mouseY - mouseYOnMouseDown ) * 0.05; */
    }

}

//
function animate() {

    requestAnimationFrame( animate );
    render();
    stats.update();

}

function render() {
    //if(rotateStartP != rotateEndP) {
    //rotateQuaternion = rotateMatrix(rotateStartP, rotateEndP);
    //quater=cube.quaternion;
    //quater.multiplyQuaternions(rotateQuaternion, quater);
    //quater.multiply(rotateQuaternion);
    //quater.normalize();
    var rotateQuaternion = rotateMatrix(rotateStartP, rotateEndP);
    quater=cube.quaternion;
    quater.multiplyQuaternions(rotateQuaternion,quater);
    quater.normalize();
    cube.setRotationFromQuaternion(quater);
    // }


    renderer.render( scene, camera );

}

</script>

</body>
</html>

Change my code to ObjectTrackball.js

The code is as follows:

TrackballControls = function ( object, domElement ) {

    var _this = this;

    _this.quater = object.quaternion;
    _this.object = object;
    _this.domElement = ( domElement !== undefined ) ? domElement : document;

    _this.zoomValue = 0;
    _this.mouseDown = true;

    _this.rotateStartP = new THREE.Vector3();
    _this.rotateEndP = new THREE.Vector3();

    // events
    var changeEvent = { type: 'change' };

    // methods

    this.handleEvent = function ( event ) {

        if ( typeof this[ event.type ] == 'function' ) {

            this[ event.type ]( event );

        }

    };

    this.update = function () {

        var rotateQuaternion = rotateMatrix(_this.rotateStartP, _this.rotateEndP);
        _this.quater = _this.object.quaternion;
        _this.quater.multiplyQuaternions(rotateQuaternion,_this.quater);
        _this.quater.normalize();
        _this.object.setRotationFromQuaternion(_this.quater);
        _this.object.position.z += _this.zoomValue;
        _this.zoomValue = 0;

    };



    function mousedown( event ) {

        event.preventDefault();
        _this.mouseDown = true;
        _this.rotateStartP = projectOnTrackball(event.clientX, event.clientY);

        document.addEventListener( 'mousemove', mousemove, false );
        document.addEventListener( 'mouseup', mouseup, false );



    }
    function getMouseOnScreen( pageX, pageY) {

        return new THREE.Vector2.set(pageX / window.innerWidth ,pageY / window.innerHeight);

    }

    function projectOnTrackball(pageX, pageY) // The screen coordinate[(0,0)on the left-top] convert to the
        //trackball coordinate [(0,0) on the center of the page]
    {
        var mouseOnBall = new THREE.Vector3();
        mouseOnBall.set(
                ( pageX - window.innerWidth * 0.5 ) / (window.innerWidth * .5),
                ( window.innerHeight * 0.5 - pageY ) / ( window.innerHeight * .5),
            0.0
        );

        var length = mouseOnBall.length();
        if (length > 1.0) {

            mouseOnBall.normalize();

        }
        else {
            mouseOnBall.z = Math.sqrt(1.0 - length * length);
        }
        return mouseOnBall;
    }

    function rotateMatrix(rotateStart, rotateEnd)
    {
        var axis = new THREE.Vector3(),
            quaternion = new THREE.Quaternion();

        var angle = Math.acos( rotateStart.dot( rotateEnd ) / rotateStart.length() / rotateEnd.length() );

        if ( angle )
        {
            axis.crossVectors( rotateStart, rotateEnd ).normalize();
            angle *= 0.01;            //Here we could define rotate speed
            quaternion.setFromAxisAngle( axis, angle );
        }
        return  quaternion;
    }

    function mousemove( event ) {

        if(!_this.mouseDown)
        {
            return;
        }

        _this.rotateEndP = projectOnTrackball(event.clientX, event.clientY);

    }

    function mouseup( event ) {

        _this.mouseDown = false;
        _this.rotateStartP = _this.rotateEndP;
        document.removeEventListener( 'mousemove', mousemove );
        document.removeEventListener( 'mouseup', mouseup );

    }

    function mousewheel( event ) {

        event.preventDefault();
        event.stopPropagation();

        var delta = 0;

        if ( event.wheelDelta ) { // WebKit / Opera / Explorer 9

            delta = event.wheelDelta / 40;

        } else if ( event.detail ) { // Firefox

            delta = - event.detail / 3;

        }

        _this.zoomValue += delta;

    }

    this.domElement.addEventListener( 'mousedown', mousedown, false );

    this.domElement.addEventListener( 'mousewheel', mousewheel, false );
    this.domElement.addEventListener( 'DOMMouseScroll', mousewheel, false ); // firefox

};

TrackballControls.prototype = Object.create( THREE.EventDispatcher.prototype );

Code of The Object control application (Three.js r66)

<!DOCTYPE html>
<html lang="en">
<head>
    <title>three.js canvas - geometry - cube</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <style>
        body {
            font-family: Monospace;
            background-color: #f0f0f0;
            margin: 0px;
            overflow: hidden;
        }
    </style>
</head>
<body>

<script src="../build/three.min.js"></script>

<script src="js/libs/dat.gui.min.js"></script>
<script src="js/libs/stats.min.js"></script>
<script src="js/controls/ObjectTrackballControl.js"></script>
<script>

var container, stats;

var camera, scene, renderer;

var cube, plane;
var control;


var mouseDown = false;
var rotateStartP = new THREE.Vector3(0,0,1);
var rotateEndP = new THREE.Vector3(0,0,1);

var lastPosX;
var lastPosY;
var targetRotationY = 0;
var targetRotationX = 0;
var quater;
//var rotateQuaternion = new THREE.Quaternion();
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;

init();
animate();

function init() {

    container = document.createElement( 'div' );
    document.body.appendChild( container );

    var info = document.createElement( 'div' );
    info.style.position = 'absolute';
    info.style.top = '10px';
    info.style.width = '100%';
    info.style.textAlign = 'center';
    info.innerHTML = 'Drag to spin the cube';
    container.appendChild( info );

    camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
    camera.position.y = 150;
    camera.position.z = 500;

    scene = new THREE.Scene();

    // Cube

    var geometry = new THREE.CubeGeometry( 200, 200, 200 );

    for ( var i = 0; i < geometry.faces.length; i += 2 ) {

        var hex = Math.random() * 0xffffff;
        geometry.faces[ i ].color.setHex( hex );
        geometry.faces[ i + 1 ].color.setHex( hex );

    }

    var material = new THREE.MeshBasicMaterial( { vertexColors: THREE.FaceColors, overdraw: 0.5 } );

    cube = new THREE.Mesh( geometry, material );
    cube.position.y = 150;
    scene.add( cube );

    control = new TrackballControls(cube);
    // Plane

    var geometry = new THREE.PlaneGeometry( 200, 200 );
    geometry.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) );

    var material = new THREE.MeshBasicMaterial( { color: 0xe0e0e0, overdraw: 0.5 } );

    plane = new THREE.Mesh( geometry, material );
    scene.add( plane );

    renderer = new THREE.CanvasRenderer();
    renderer.setClearColor( 0xf0f0f0 );
    renderer.setSize( window.innerWidth, window.innerHeight );

    container.appendChild( renderer.domElement );
    //GUI
    var controls = new function () {

        this.xx = false;
        this.yy = 512;



        this.onChange = function () {

        }

    };

    var gui = new dat.GUI();
    gui.add(controls, 'xx').onChange(controls.onChange);
    gui.add(controls, 'yy', 1, 10).step(1).onChange(controls.onChange);

    stats = new Stats();
    stats.domElement.style.position = 'absolute';
    stats.domElement.style.top = '0px';
    container.appendChild( stats.domElement );

    //

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

}

function onWindowResize() {

    windowHalfX = window.innerWidth / 2;
    windowHalfY = window.innerHeight / 2;

    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    renderer.setSize( window.innerWidth, window.innerHeight );

}


//
function animate() {

    requestAnimationFrame( animate );
    render();
    stats.update();

}

function render() {

    control.update();
    renderer.render( scene, camera );

}

</script>

</body>
</html>

Upvotes: 0

Views: 1043

Answers (0)

Related Questions