Three.js - 当我将指针放在THREE.Line上时,我的程序就会死掉

时间:2015-02-10 15:20:18

标签: javascript three.js

我有一个Three.js程序,每当我将指针放在一个立方体上时,它就会给我它的位置。这很好(这就是我需要的),但是当我将指针放在线上时,我的程序停止了。谁能告诉我为什么以及如何解决这个问题?无论我的指针在哪里,我都需要我的程序继续运行。 当我将指针放在白线上时,我得到以下错误:
未捕获的TypeError:无法读取未定义的属性'getHex'

代码:

var container, stats;
var scene, camera, renderer, raycaster;
var cube;
var clock = new THREE.Clock();
var mouse = new THREE.Vector2(), INTERSECTED;
var radius = 100, theta = 0;
var composer;

initScene();

//Let's add a cube
var geometry = new THREE.BoxGeometry( 20, 20, 20 );
cube = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({
    color : Math.random() * 0xffffff
}));
cube.position.set(0,20,50)
scene.add( cube );

//Let's add another cube
var geometry2 = new THREE.BoxGeometry( 20, 20, 20 );
var cube2 = new THREE.Mesh(geometry2, new THREE.MeshLambertMaterial({
    color : Math.random() * 0xffffff
}));
cube2.position.set(200,20,50)
scene.add( cube2 );

//Let's add a line
var material = new THREE.LineBasicMaterial({
    color: 0xffffff
});
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(0, 20, 50));
geometry.vertices.push(new THREE.Vector3(200, 20, 50));
var line = new THREE.Line(geometry, material);
scene.add(line);

animate();

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

    var fov = 70;
    var aspect = window.innerWidth / window.innerHeight;
    var near = 1;
    var far = 10000;
    var zpos = 300;
    // Initialize camera
    GlobalCamera(fov, aspect, near, far, zpos);

    scene = new THREE.Scene();

    // Set camera controls
    cameraControls2();

    // renderer controls
    rendererControls2();


}

function GlobalCamera(fov, aspect, near, far, zpos) {

    camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
    camera.position.z = zpos;

}

function cameraControls2() {

    controls = new THREE.FlyControls(camera);
    controls.movementSpeed = 2500;
    controls.domElement = container;
    controls.rollSpeed = Math.PI / 6;
    controls.autoForward = false;
    controls.dragToLook = false

}

function rendererControls2() {
    renderer = new THREE.WebGLRenderer({
        antialias : true,
        alpha : true
    });
    renderer.setClearColor(0xf0f0f0);
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.sortObjects = false;
    container.appendChild(renderer.domElement);

    renderer.gammaInput = true;
    renderer.gammaOutput = true;

}

function findIntersection() {

    raycaster.setFromCamera(mouse, camera);

    var intersects = raycaster.intersectObjects(scene.children);

    if (intersects.length > 0) {


        if (INTERSECTED != intersects[0].object) {

            if (INTERSECTED)
                INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);

            INTERSECTED = intersects[0].object;
            INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();
            INTERSECTED.material.emissive.setHex(0xff0000);
            console.log(INTERSECTED.position);
        }

    } else {

        if (INTERSECTED)
            INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);                  

        INTERSECTED = null;

    }

}

function onDocumentMouseMove(event) {
    event.preventDefault();
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}

function preAnimate(){
    raycaster = new THREE.Raycaster();
    // events
    document.addEventListener('mousemove', onDocumentMouseMove, false);
}

function animate() {
    preAnimate();
    requestAnimationFrame(animate);
    render();
}

function render() {
    var delta = clock.getDelta();
    findIntersection();
    controls.update(delta);
    renderer.render(scene, camera);
}

1 个答案:

答案 0 :(得分:1)

这是我与Three.js的第一次冒险,但我想我已经找到了你的问题。会发生什么是THREE.LineBasicMaterial没有像THREE.MeshLambertMaterial那样的自发属性。要在THREE.LineBasicMaterial对象上操作的属性是color属性。

这是一个有效的jsFiddle,我已经在emissive属性可用的地方添加了一些检查: https://jsfiddle.net/thedole/4wkFu/162/区别在于在findIntersection方法中添加了提到的检查:

function findIntersection() {

    raycaster.setFromCamera(mouse, camera);

    var intersects = raycaster.intersectObjects(scene.children),
    material;

    if (intersects.length > 0) {


        if (INTERSECTED != intersects[0].object) {

            if (INTERSECTED){
                material = INTERSECTED.material;
                if(material.emissive){
                    material.emissive.setHex(INTERSECTED.currentHex);
                }
                else{
                    material.color.setHex(INTERSECTED.currentHex);
                }
            }   
            INTERSECTED = intersects[0].object;
            material = INTERSECTED.material;
            if(material.emissive){
                INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();
                material.emissive.setHex(0xff0000);
            }
            else{
                INTERSECTED.currentHex = material.color.getHex();
                material.color.setHex(0xff0000);
            }

            console.log(INTERSECTED.position);
        }

    } else {

        if (INTERSECTED){
            material = INTERSECTED.material;

            if(material.emissive){
                material.emissive.setHex(INTERSECTED.currentHex);
            }
            else
            {
                material.color.setHex(INTERSECTED.currentHex);
            }
        }

        INTERSECTED = null;

    }

}