无法使用FirstPersonControls.js为相机设置lookAt位置

时间:2013-05-12 11:05:24

标签: three.js webgl

// Init a perspective camera
camera = new THREE.PerspectiveCamera(45, WIDTH / HEIGHT, 0.001, 10000);

// Init free camera controls for default
controls = new THREE.FirstPersonControls(camera);
controls.movementSpeed = 1;
controls.lookSpeed = 0.1;

// Add camera to scene
camera.position.set(3, 3, 3);
camera.lookAt(0, 0, 0);
scene.add(camera);

我正在使用FirstPersonControls.js为我的相机创建一个演示场景。一切都很好,但看起来在相机的位置,我无法设置它。 camera.lookAt(0, 0, 0);不起作用。我怎么处理这个?感谢您的阅读!

进一步说,这是我的demoscene的完整代码。                                   

<!-- Libraries -->
<script type="text/javascript" src="js/libs/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="js/libs/three.js"></script>
<script type="text/javascript" src="js/loaders/BinaryLoader.js"></script>
<!-- Camera control -->
<script type="text/javascript" src="js/controls/TrackballControls.js"></script>
<script type="text/javascript" src="js/controls/FirstPersonControls.js"></script>
<script type="text/javascript" src="js/controls/FlyControls.js"></script>
<script type="text/javascript" src="js/controls/PointerLockControls.js"></script>
<!-- Event handler -->
<script type="text/javascript" src="js/KeyboardState.js"></script>
<!-- JS for HTML interface -->
<script type="text/javascript" src="ajs/index.js"></script>

<!-- THREE -->
<script type="text/javascript">
// Set scene size
var WIDTH = window.innerWidth, HEIGHT = window.innerHeight;
// WebGL's object
var container = null, renderer = null, scene = null, camera = null;
// Camera object
var controls = null;
// Statistic object
var stats = null;
// Time
var clock = new THREE.Clock();
// Keyboard
var keyboard = new KeyboardState();
// Target geometry
var mesh = null;
// Objects array for handling something (haven't known yet) in PointerLock camera
var objects = [];
var ray = null;

// Initialize WebGL
function initWebGL() {
    setupRenderer();
    setupScene();
    setupCamera();
    setupLight();
}

// Initialize renderer
function setupRenderer() {
    // Create the canva element
    renderer = new THREE.WebGLRenderer();
    renderer.setClearColor({
        clearColor: 0x999999,
        clearAlpha: 1.0
    });
    renderer.setSize(WIDTH, HEIGHT);
    // Add the canvas into its container
    container = $('#canvas-container-1');
    container.append(renderer.domElement);
}

// Initialize camera
function setupCamera() {
    // Init a perspective camera
    camera = new THREE.PerspectiveCamera(45, WIDTH / HEIGHT, 0.001, 10000);
    // Init free camera controls for default
    controls = new THREE.FirstPersonControls(camera);
    controls.movementSpeed = 1;
    controls.lookSpeed = 0.1;
    // Add camera to scene
    camera.position.set(3, 3, 3);
    camera.lookAt(new THREE.Vector3(0.0, 0.0, 0.0));
    scene.add(camera);

    // Init camera controls (get the checked radio input value)
    var chosenCamera = $('input[name=camera]:checked').val();

    // What will happen if $('input[name=camera]') value is changed
    $('input[name=camera]').change(function () {
        // Reload chosenCamera value
        chosenCamera = $('input[name=camera]:checked').val();

        // Camera controls
        if (chosenCamera == 0) { // Free
            controls = new THREE.FirstPersonControls(camera);
            controls.movementSpeed = 1;
            controls.lookSpeed = 0.1;
            // Add camera to scene
            scene.add(camera);

        } else if (chosenCamera == 1) { // Track ball
            controls = new THREE.TrackballControls(camera);
            // Add camera to scene
            scene.add(camera);

        } else if (chosenCamera == 2) { // First person
            // Add controls
            controls = new THREE.PointerLockControls(camera);

            ray = new THREE.Raycaster();
            ray.ray.direction.set(0, -1, 0);

            // Add camera to scene
            scene.add(controls.getObject());

            // Feature detection
            var havePointerLock = 'pointerLockElement' in document ||
                    'mozPointerLockElement' in document ||
                    'webkitPointerLockElement' in document;

            if (havePointerLock) {
                // Object(s)
                var element = document.body;

                // Action for event listener below
                var pointerlockchange = function (e) { // Action for changes pointerlock
                    if (document.pointerLockElement === element ||
                            document.mozPointerLockElement === element ||
                            document.webkitPointerLockElement === element) {
                        controls.enable = true;
                    } else {
                        controls.enable = false;
                    }
                }

                var pointerlockerror = function (e) { // Action for pointerlock error
                    $('#instructions').html('Error!');
                }

                // Hook pointer lock state change events
                document.addEventListener('pointerlockchange', pointerlockchange, false);
                document.addEventListener('mozpointerlockchange', pointerlockchange, false);
                document.addEventListener('webkitpointerlockchange', pointerlockchange, false);

                document.addEventListener('pointerlockerror', pointerlockerror, false);
                document.addEventListener('mozpointerlockerror', pointerlockerror, false);
                document.addEventListener('webkitpointerlockerror', pointerlockerror, false);

                // Ask the browser to lock the pointer
                element.requestPointerLock = element.requestPointerLock ||
                        element.mozRequestPointerLock ||
                        element.webkitRequestPointerLock;

                if (/Firefox/i.test(navigator.userAgent)) {
                    var fullscreenchange = function (e) {
                        if (document.webkitFullscreenElement === element ||
                                document.mozFullscreenElement === element ||
                                document.mozFullScreenElement === element) { // Older API upper case 'S'.
                            document.removeEventListener('fullscreenchange', fullscreenchange);
                            document.removeEventListener('mozfullscreenchange', fullscreenchange);
                            element.requestPointerLock();
                        }
                    }

                    document.addEventListener('fullscreenchange', fullscreenchange, false);
                    document.addEventListener('mozfullscreenchange', fullscreenchange, false);

                    element.requestFullscreen = requestFullscreen = element.requestFullscreen ||
                            element.mozRequestFullscreen ||
                            element.mozRequestFullScreen || // Older API upper case 'S'.
                            element.webkitRequestFullscreen;

                    element.requestFullscreen();
                } else {
                    element.requestPointerLock();
                }
            } else {
                $('#instructions').html('Your browser doesn\'t seem to support Pointer Lock API');
            }
        }
    });
}

// Add lights to the scene
function setupLight() {
    var ambientLight = new THREE.AmbientLight(0x404040); // soft white light
    scene.add(ambientLight);

    var directionalLight = new THREE.DirectionalLight(0xffffff);
    directionalLight.position.set(1, 0, 0).normalize();
    scene.add(directionalLight);

    var pointLight = new THREE.PointLight(0xffffff);
    pointLight.position.set(250, 250, 250);
    scene.add(pointLight);
}

// Initialize scene
function setupScene() {
    scene = new THREE.Scene();
    render();
}

// Rendering
function render() {
    /* ********** ********** ********** ********** ********** ********** ********** ********** ********** **********
     Floor texture
     */
    var floorTexture = new THREE.ImageUtils.loadTexture('models/textures/grey-concrete-texture-01.jpg');
    floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping;
    floorTexture.repeat.set(100, 100);

    // Floor material
    var floorMaterial = new THREE.MeshBasicMaterial({
        map: floorTexture,
        side: THREE.DoubleSide
    });

    // Floor geometry
    var floorGeometry = new THREE.PlaneGeometry(200, 200);

    // Floor
    var floor = new THREE.Mesh(floorGeometry, floorMaterial);
    floor.rotation.x = Math.PI / 2;
    floor.position.y = 0;
    objects.push(floor);
    scene.add(floor);


    /* ********** ********** ********** ********** ********** ********** ********** ********** ********** **********
     Add sky box
     */
    var r = "models/textures/skybox/sky6/";
    var urls = [
        r + "px.png",
        r + "nx.png",
        r + "py.png",
        r + "ny.png",
        r + "pz.png",
        r + "nz.png"
    ];

    var textureCube = THREE.ImageUtils.loadTextureCube(urls);
    textureCube.format = THREE.RGBFormat;

    var shader = THREE.ShaderLib["cube"];
    shader.uniforms["tCube"].value = textureCube;

    var material = new THREE.ShaderMaterial({
        fragmentShader: shader.fragmentShader,
        vertexShader: shader.vertexShader,
        uniforms: shader.uniforms,
        depthWrite: false,
        side: THREE.BackSide
    });

    var skybox = new THREE.Mesh(new THREE.CubeGeometry(7000, 7000, 7000, 1, 1, 1), material);
    scene.add(skybox);


    /* ********** ********** ********** ********** ********** ********** ********** ********** ********** **********
     Load A1 building
     */
    var building = null;
    var jsonLoader = new THREE.BinaryLoader();
    jsonLoader.load('models/a1/A1.js', function (geometry, materials) {
        // Init material
        var faceMaterial = new THREE.MeshFaceMaterial(materials);
        for (var s = 0; s < materials.length; s++)
            materials[s].side = THREE.DoubleSide;

        // Init mesh
        building = new THREE.Mesh(geometry, faceMaterial);
        building.scale.set(0.0001, 0.0001, 0.0001);

        // Add mesh to the scene
        scene.add(building);
    });


    /* ********** ********** ********** ********** ********** ********** ********** ********** ********** **********
     Axis
     */
    scene.add(new THREE.AxisHelper(10));

    (function loop() {
        update(loop);
    })()
}

// Update
function update(act) {
    // Variables for calculation of animation
    var delta = clock.getDelta(); // milliseconds

    // If the chosen camera is PointerLock
    if ($('input[name=camera]:checked').val() == 2) {
        controls.isOnObject(false);
        ray.ray.origin.copy(controls.getObject().position);
        ray.ray.origin.y -= 10;
        var intersections = ray.intersectObjects(objects);
        if (intersections.length > 0) {
            var distance = intersections[0].distance;
            if (distance > 0 && distance < 10) {
                controls.isOnObject(true);
            }
        }
    }

    // Update camera control
    (controls == null) ? {} : controls.update(delta);

    // Update renderer
    renderer.render(scene, camera);

    // Loop
    requestAnimationFrame(act);
}
</script>

<!-- Assistant functions -->
<script type="text/javascript">
    // Resize canvas
    function windowResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);
    }

    // Animation loop
    window.requestAnimFrame = (function () {
        return  window.requestAnimationFrame ||
                window.webkitRequestAnimationFrame ||
                window.mozRequestAnimationFrame ||
                window.oRequestAnimationFrame ||
                window.msRequestAnimationFrame ||
                function (callback) {
                    window.setTimeout(callback, 1000 / 60);
                };
    })();
</script>

<!-- jQuery -->
<script type="text/javascript">
    $(document).ready(function () {
        // Init drawing
        initWebGL();

        // Window resize event
        $(window).resize(function () {
            windowResize();
        });
    });
</script>
</head>

<body>
<div id="canvas-container-1"></div>

<!-- panel -->
<div id="panel" class="dock">
    <p class="pull"><b>Camera</b></p>

    <form id="pan" name="pan" method="post">
        <input id="free-camera" name="camera" type="radio" value="0" checked=""/>
        <label for="free-camera">Free</label>
        <br/>
        <input id="trackball-camera" name="camera" type="radio" value="1"/>
        <label for="trackball-camera">Track Ball</label>
        <br/>
        <input id="pointer-lock-camera" name="camera" type="radio" value="2"/>
        <label for="pointer-lock-camera">Pointer Lock</label>
    </form>
</div>

<!-- instructions -->
<div id="instructions" class="dock">
    <p class="pull"><b>Thông tin</b></p>

    <article>
        Đề tài nghiên cứu khoa học của nhóm sinh viên lớp ĐH Hệ Thống Thông Tin K5, trường Đại Học Công Nghiệp Hà Nội.
    </article>
</div>
</body>
</html>

3 个答案:

答案 0 :(得分:2)

camera.lookAt (new THREE.Vector3 (0.0, 0.0, 0.0));

答案 1 :(得分:0)

您可以使用

预先将其旋转到初始位置
controls.lon = degrees;
controls.lat = someOtherDegrees;

答案 2 :(得分:0)

我遇到同样的问题,FirstPersonControls只希望在X轴的后面看,并且:

camera.lookAt (new THREE.Vector3 (0.0, 0.0, 0.0));

对我也不起作用。

但我成功了:

direction = camera.getWorldDirection().clone();
angle = direction.angleTo (new THREE.Vector3(1,0,0))  // Forward and X axis 
controls.lon = - angle * 180 / Math.PI;

它适合我。