如何控制不影响对象的data.gui.js(Three.js r66)

时间:2014-05-05 16:46:01

标签: events user-interface three.js controls trackball

我写了一个轨迹球来控制物体旋转,一切都很顺利。但是,当我将gui组件添加到程序中时,当我用鼠标更改gui时,对象正在移动。因为我的轨迹球将屏幕坐标投影到虚拟球,当我的鼠标位于gui组件上时,它仍然在屏幕上,并且它使对象移动。怎么避免呢?我试着找到关于轨迹球three.js的原因,并没有找到结果。为什么他的轨迹球不会影响gui对象?

<!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>

将我的代码更改为ObjectTrackball.js

代码如下:

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 );

对象控制应用程序的代码(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>

0 个答案:

没有答案