【问题标题】:Three.js - SELECTED SpotLight & dat.guiThree.js - 选定的 SpotLight 和 dat.gui
【发布时间】:2015-10-29 16:05:08
【问题描述】:

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

But, when selected, I want to be able to edit the SpotLight settings.问题是我正在与几何体(已选择)而不是直接与 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;});

[编辑] 这是我的 SELECTED 变量:

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

怎么可能?

【问题讨论】:

  • 你的 SELECTED 变量从哪里获得它的值?
  • 见上文编辑 :)
  • 你不需要objects变量!你可以使用scene.children

标签: javascript three.js light


【解决方案1】:

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

一种选择是将helper 添加为object 的子代。然后,当您选择辅助对象时,您可以使用其父对象来操作值。

第二个选项是给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
    }
} );

【讨论】:

  • 你是对的!有用! :P 如果您同时管理 SpotLight、PointLight 和 DirectionalLight,以便能够编辑 SELECTED 对象,您会怎么做?
  • 您可以控制SELECTED 的含义和含义。
  • 什么意思? :s
  • 关于您的问题,我认为您希望变量 SELECTED 在一个实例中为 SpotLight 或在另一个实例中为 PointLight。所以你会根据变量的含义来编码。
  • 我只需要能够随时选择聚光灯或点光源,然后就可以使用 dat.gui 编辑其设置
【解决方案2】:
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);
        }
    } );
});

成功了。

【讨论】:

    【解决方案3】:

    我做到了

    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,它只适用于第一个。

    【讨论】:

    • 那么,对于一些不起作用的事情,你如何奖励自己正确的答案呢?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多