1

我修改了 Three.js 库中的一个示例,并尝试在对象上添加点击事件。

经过多次尝试......我仍然无法听到点击。

此代码生成凸形。

有我的代码:

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

        var container, stats;

        var camera, scene, renderer;
        var  objects = [];

        init();
        animate();

        function init() {

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

            camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
            camera.position.y = 400;

            scene = new THREE.Scene();

            var light, object, object2, materials;

            scene.add( new THREE.AmbientLight( 0x404040 ) );

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

            var map = THREE.ImageUtils.loadTexture( 'textures/ash_uvgrid01.jpg' );
            map.wrapS = map.wrapT = THREE.RepeatWrapping;
            map.anisotropy = 16;

            materials = [
                new THREE.MeshLambertMaterial( { ambient: 0xbbbbbb, map: map } ),
                new THREE.MeshBasicMaterial( { color: 0x242424, wireframe: true, transparent: false, opacity: 0.1 } )
            ];


            // random convex

            points = [];
            for ( var i = 0; i < 15; i ++ ) {

                points.push( randomPointInSphere( 50 ) );

            }


            object = THREE.SceneUtils.createMultiMaterialObject( new THREE.ConvexGeometry( points ), materials );
            object.position.set( -250, 0, 200 );
            scene.add( object );


            objects.push( object );

            object.callback = function() { console.log('blabla');}
                

        


            renderer = new THREE.WebGLRenderer( { antialias: true } );
            renderer.setSize( window.innerWidth, window.innerHeight );

            container.appendChild( renderer.domElement );

            stats = new Stats();
            stats.domElement.style.position = 'absolute';
            stats.domElement.style.top = '0px';
            container.appendChild( stats.domElement );

            

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

        }

        function onWindowResize() {

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

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

        }


        function randomPointInSphere( radius ) {

            return new THREE.Vector3(
                ( Math.random() - 0.5 ) * 1 * radius,
                ( Math.random() - 0.5 ) * 1 * radius,
                ( Math.random() - 0.5 ) * 1 * radius
            );

        }

        function animate() {

            requestAnimationFrame( animate );

            render();
            stats.update();

        }

        function render() {

            var timer = Date.now() * 0.0001;

            camera.position.x = Math.cos( timer ) * 800;
            camera.position.z = Math.sin( timer ) * 800;

            camera.lookAt( scene.position );

            for ( var i = 0, l = scene.children.length; i < l; i ++ ) {

                var object = scene.children[ i ];

                object.rotation.x = timer * 5;
                object.rotation.y = timer * 2.5;

            }

            renderer.render( scene, camera );

        }

        function addMeteor()
        {
                    var map = THREE.ImageUtils.loadTexture( 'textures/ash_uvgrid01.jpg' );
            map.wrapS = map.wrapT = THREE.RepeatWrapping;
            map.anisotropy = 16;

                    var materials = [
                new THREE.MeshLambertMaterial( { ambient: 0xbbbbbb, map: map } ),
                new THREE.MeshBasicMaterial( { color: 0x242424, wireframe: true, transparent: false, opacity: 0.1 } )
            ];
            objects.push( materials );
                var object3;
                var points3 = [];
            for ( var i = 0; i < 10; i ++ ) {

                points3.push( randomPointInSphere( 50 ) );

            }

            object3 = THREE.SceneUtils.createMultiMaterialObject( new THREE.ConvexGeometry( points3 ), materials );
            object3.position.set( -50, Math.floor((Math.random()*window.innerWidth)), Math.floor((Math.random()* window.innerHeight)) );
            scene.add( object3 );
            objects.push( object3 );

        }
            projector = new THREE.Projector();
        // listeners
            document.addEventListener( 'mousedown', onDocumentMouseDown, false)

            // keyboard handler
            function onDocumentMouseDown( event ) {
                
                event.preventDefault();
                 console.log('blabla');
                
                var vector = new THREE.Vector3( 
                    ( event.clientX / window.innerWidth ) * 2 - 1, 
                    - ( event.clientY / window.innerHeight ) * 2 + 1, 
                    0.5 );
                
                projector.unprojectVector( vector, camera );
                
                var ray = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
                 console.log(objects);   
                var intersects = ray.intersectObjects( objects ); 
                  console.log(intersects);   

                if ( intersects.length > 0 ) {
                            
                    intersects[0].object.callback();

                    console.log('blabla');
                    
                }
                                
            }


        renderer.render( scene, camera );

我应该将 Mesh 推入 Objects 数组,但是是哪一个呢?

4

1 回答 1

3

THREE.SceneUtils.createMultiMaterialObject()创建具有两个子网格的对象。

因此,您需要在调用时将recursive标志设置为.trueRaycaster.intersectObjects()

var intersects = ray.intersectObjects( objects, true );

三.js r.62

于 2013-10-24T21:27:21.390 回答