Three.js - 选定的 SpotLight 和 dat.gui

Three.js - SELECTED SpotLight & dat.gui

我正在向我的场景添加一个 SpotLight 和一个 OctahedronGeometry(作为助手)以使其对用户可见。 用户必须能够通过点击 transformControls 来移动 SpotLight 到 select。并且有效!

但是,当 selected 时,我希望能够编辑 SpotLight 设置。问题是我正在与几何体(selected)交互,而不是直接与 SpotLight 交互。

这是我的函数:

var aSpotLight = document.getElementById("addSpotLight");
aSpotLight.addEventListener("click", addSpotLight, false);

    function addSpotLight(){
        var object = new THREE.SpotLight( 0xffffff, 1, 0, Math.PI * 0.1, 10 );
        object.name = 'SpotLight';
        var helper = new THREE.Mesh(new THREE.OctahedronGeometry(10, 0), new THREE.MeshBasicMaterial( { color: 0x00ee00, wireframe: true, transparent: true } ));
        helper.position.set( 0, 30, 0 );
        object.position.set( 0, 30, 0 );

        scene.add(helper);
        helper.add( object );

        objects.push(object);

        renderer.render( scene, camera );
        material.needsUpdate = true;
    }

这是我的 dat.gui 设置:

selectedObjectAppearance = {
        lightColor : 0xffffff,
        lightDistance : 10,
        lightIntensity : 1,
        lightlightShadowDarkness : 1
    };

    guiObject.addColor(selectedObjectAppearance, 'lightColor').name('Light Color').onChange(function (e) {SELECTED.children.color = new THREE.Color(e);});
        guiObject.add( selectedObjectAppearance, 'lightDistance' ).min(1).max(15).step(0.5).name('Light distance').onChange(function (e) {SELECTED.distance = e;});
        guiObject.add( selectedObjectAppearance, 'lightIntensity' ).min(0).max(1).step(0.05).name('Light intensity').onChange(function (e) {SELECTED.intensity = e;});
        guiObject.add( selectedObjectAppearance, 'lightlightShadowDarkness' ).min(0).max(1).step(0.05).name('Light shadow darkness').onChange(function (e) {SELECTED.shadowDarkness = e;});

[编辑] 这是我选择的变量:

function onDocumentMouseDown(event){
    event.preventDefault();
    if($(event.target).is('canvas')){
        mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
        mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
        raycaster.setFromCamera(mouse, camera);
        var intersects = raycaster.intersectObjects(objects);
        if(intersects.length > 0){
            SELECTED = intersects[ 0 ].object;

            control.attach(SELECTED);
            scene.add(control);
            $(guiObject.domElement).attr("hidden", false);
            // SELECTED.material.color.setHex( Math.random() * 0xffffff );
        } else{
            control.detach(SELECTED);
            scene.remove(control);
            control.update();
            $(guiObject.domElement).attr("hidden", true);
        }
    } else{
        $(guiObject.domElement).attr("hidden", false);
    }
}

怎么做到的?

我看到两个选项,你选择哪一个取决于你想做什么。

一种选择是将 helper 添加为 object 的子项。然后,当您 select 助手时,您可以使用它的父级来操作值。

第二个选项是在 helper 中添加一个名称(即 helper.name = SpotLightHelper),然后执行:

scene.traverse( function( child ) {
    if (child.name === 'SpotLightHelper') {
        // do what you want here
    }
    else if (child.name === 'PointLightHelper') {
        // do what you want here
    }
} );

我做到了

guiObject.addColor(selectedObjectAppearance, 'lightColor').name('Light Color').onChange(function (e) {
    scene.traverse( function( child ) {

        if (SELECTED.name === 'SpotLightHelper') {
            var object = scene.getObjectByName("SpotLight");
            object.color = new THREE.Color(e);
        }
        else if (SELECTED.name === 'PointLightHelper') {
            var object = scene.getObjectByName("PointLight");
            object.color = new THREE.Color(e);
        }
        else if (SELECTED.name === 'DirectionalLightHelper') {
            var object = scene.getObjectByName("DirectionalLight");
            object.color = new THREE.Color(e);
        }
    } );
});

唯一的问题是,如果我有 2 个 SpotLights/PointLight/DirectionalLights,它只适用于第一个。

guiObject.addColor(selectedObjectAppearance, 'lightColor').name('Light Color').onChange(function (e) {
    scene.traverse( function( child ) {
        var object = helper.children[0];

        if ((SELECTED === helper) && (child instanceof THREE.SpotLight)) {
            object.color = new THREE.Color(e);
        }
        else if ((SELECTED === helper) && (child instanceof THREE.PointLight)) {
            object.color = new THREE.Color(e);
        }
        else if ((SELECTED === helper) && (child instanceof THREE.DirectionalLight)) {
            object.color = new THREE.Color(e);
        }
    } );
});

成功了。