如何使用threejs中的按钮更改Collada的颜色?

时间:2019-01-16 14:59:42

标签: three.js collada

我想创建一个具有交互式骨骼的骨架模型,这样,如果您单击按钮之一,骨架的某些部分会改变颜色。

我试图在同一位置添加两个相同的模型,但是它们的颜色不同,但是这导致我的collada模型不在y轴上旋转。

<body>
    <script src="js/three.js"></script>                 
    <script src="js/loaders/ColladaLoader.js"></script> 
    <script src="js/Detector.js"></script>              

    <script>

        if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

        var container;
        var camera, scene, renderer, objects;           
        var dae;            
        var dae2;                   
        var loader = new THREE.ColladaLoader();

        loader.options.convertUpAxis = true;
        var url='obj/szkieletCube.dae';  

        loader.load( url, function ( collada ) {
            dae = collada.scene;
            dae.traverse( function ( child ) {
                if ( child instanceof THREE.SkinnedMesh ) {
                    var animation = new THREE.Animation( child, child.geometry.animation );
                    animation.play();
                }
            } );

            dae.scale.x = dae.scale.y = dae.scale.z = 100; 
            dae.rotation.y+=Math.PI/2;
            dae.position.y-=2048;
            dae.position.x-=0;
            dae.position.z+=0;
            dae.updateMatrix();

            dae.traverse( function ( child ) {  
                child.castShadow = true;
                child.receiveShadow = false;
            } );            

            init();
            animate();
        } );            

        function init() 
        {

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

            camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 40000 );
            camera.position.set( Math.pow(2,13), 1024, 0);

            scene = new THREE.Scene();

            scene.add( dae );

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

            renderer = new THREE.WebGLRenderer();
            renderer.setSize( window.innerWidth, window.innerHeight); 
            renderer.shadowMapEnabled=true;
            renderer.shadowMapType=THREE.PCFSoftShadowMap;

            container.appendChild( renderer.domElement );

            window.addEventListener( 'resize', onWindowResize, false );

        }


        function onWindowResize() {                 

            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();

            renderer.setSize( window.innerWidth, window.innerHeight);
        }

        function animate() {                
            requestAnimationFrame( animate );
            render();
        }
        var kat = 0;
        function render() {
            camera.position.y = 1024;
            kat -= -0.001;
            dae.rotation.y = Math.cos( kat ) * 10;
            camera.lookAt( scene.position );        
            renderer.render( scene, camera );
        }

    </script>
</body>

1 个答案:

答案 0 :(得分:0)

看,您在这里使用SkinnedMesh,它是Mesh的派生类 Mesh本身具有Mesh.material属性。

因此,更改颜色所需要做的就是收集子项,以便您可以在按钮单击处理程序中单独访问它们。

您在这里对代码进行了调整:

    var daeChildren = {}; // map dae child name => child node
    var loader = new THREE.ColladaLoader();

    loader.options.convertUpAxis = true;
    var url='obj/szkieletCube.dae';  

    loader.load( url, function ( collada ) {
        dae = collada.scene;

        ...

        dae.traverse( function ( child ) {  
            child.castShadow = true;
            child.receiveShadow = false;

            // 1. Collect DAE children here
            daeChildren[child.name] = child;
        } );            

        ...

    } );

然后单击按钮,您可以更改材料的颜色:

function handleButtonClick() {
    // 2. drop texture if you need the mesh to be just colored
    daeChildren[child.name].material.map = null;

    // 3. set mesh color red
    daeChildren[child.name].material.color = new THREE.Color( 0xff0000 );

    // 4. tell threejs that material must be updated
    daeChildren[child.name].material.needsUpdate = true;
}