3

我正在尝试检测 Object3D 多维数据集组中的多维数据集单击。我已经查看并尝试合并在以下位置找到的示例和教程:

http://mrdoob.github.com/three.js/examples/webgl_interactive_cubes.html

http://mrdoob.github.com/three.js/examples/canvas_interactive_cubes.html

此外,我还查阅了本网站上的帖子:

Three.js - 如何检测选择了什么形状?拖后

如何在 THREE.js 中获取 CLICKED 元素

但由于某种原因,它仍然无法正常工作。谁能告诉我我做错了什么?这是我的代码,谢谢:

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Double Stamp It No Erasies</title>
<style>
html {
    background: url(Images/ComicBookExplosionBackground.jpg) no-repeat center center fixed;
    -webkit-background-size: cover;
    -moz-background-size: cover;
    -o-background-size: cover;
    background-size: cover;
}
body {
}
</style>
<script src="ThreeJs/build/three.min.js"></script>       
</head>

<body onLoad="onLoad();" style="">
<div id="container" style="width:100%; height:100%; position:absolute;"></div>
<script>
            var container, ButtonsCamera, ButtonsScene, ButtonsRenderer, ButtonsGeometry, ButtonsGroup;
            var mouseX = 0, mouseY = 0;
            var windowHalfX = window.innerWidth / 2;
            var windowHalfY = window.innerHeight / 2;   
            /****************************** CLICK START **********************************/
var mouse = { x: 0, y: 0 }, projector, INTERSECTED;
var objects = [];
    /****************************** CLICK END **********************************/


            document.addEventListener( 'mousemove', onDocumentMouseMove, false );
            //document.addEventListener( 'mousedown', onDocumentMouseDown, false );
            init();
            animate();      

            function init() {
                container = document.createElement( 'div' );
                document.body.appendChild( container );         
                ButtonsCamera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 10000 );
                ButtonsCamera.position.z = 500;
                ButtonsScene = new THREE.Scene();
                ButtonsScene.fog = new THREE.Fog( 0xffffff, 1, 10000 );
                /*************************** STACKOVERFLOW 1ST ANSWER START **********************************/ 
        var ButtonsGeometry = new THREE.CubeGeometry( 100, 100, 100 );
var ButtonsMaterial = new THREE.MeshFaceMaterial( [
    new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'Images/Twitter.jpg' ) } ),
    new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'Images/Twitter.jpg' ) } ),
    new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'Images/Twitter.jpg' ) } ),
    new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'Images/Twitter.jpg' ) } ),
    new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'Images/Twitter.jpg' ) } ),
    new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'Images/Twitter.jpg' ) } )] );        
                /*************************** STACKOVERFLOW 1ST ANSWER END **********************************/   
                ButtonsGroup = new THREE.Object3D();
                for ( var i = 0; i < 100; i ++ ) {
                    var ButtonsMesh;
                    if(i == 0)
                    {
                    ButtonsMesh = new THREE.Mesh( ButtonsGeometry, ButtonsMaterial );
                    }
                    else
                    {
                    ButtonsMesh = new THREE.Mesh( ButtonsGeometry, ButtonsMaterial );
                    }
                    ButtonsMesh.position.x = Math.random() * 2000 - 1000;
                    ButtonsMesh.position.y = Math.random() * 2000 - 1000;
                    ButtonsMesh.position.z = Math.random() * 2000 - 1000;
                    ButtonsMesh.rotation.x = Math.random() * 360 * ( Math.PI / 180 );
                    ButtonsMesh.rotation.y = Math.random() * 360 * ( Math.PI / 180 );
                    ButtonsMesh.matrixAutoUpdate = false;
                    ButtonsMesh.updateMatrix();
                    ButtonsGroup.add( ButtonsMesh );
                }
                ButtonsScene.add( ButtonsGroup );

            /****************************** CLICK START **********************************/
            objects.push( ButtonsMesh );
projector = new THREE.Projector();  
/****************************** CLICK END **********************************/



                ButtonsRenderer = new THREE.WebGLRenderer();
                ButtonsRenderer.setSize( window.innerWidth, window.innerHeight );
                ButtonsRenderer.sortObjects = false;
                container.appendChild( ButtonsRenderer.domElement );
            window.addEventListener( 'resize', onWindowResize, false );
            /****************************** CLICK START **********************************/
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
/****************************** CLICK END **********************************/


            }

            /****************************** CLICK START **********************************/
function onDocumentMouseDown( event ) {
//alert('clicky');
                event.preventDefault();

                var vector = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
                projector.unprojectVector( vector, ButtonsCamera );

                var raycaster = new THREE.Raycaster( ButtonsCamera.position, vector.subSelf( ButtonsCamera.position ).normalize() );

                var intersects = raycaster.intersectObjects( objects);

                if ( intersects.length > 0 ) {
                    intersects[ 0 ].object.material.color.setHex( Math.random() * 0xffffff );

                    var particle = new THREE.Particle( particleMaterial );
                    particle.position = intersects[ 0 ].point;
                    particle.scale.x = particle.scale.y = 8;
                    ButtonsScene.add( particle );

                }

                /*
                // Parse all the faces
                for ( var i in intersects ) {

                    intersects[ i ].face.material[ 0 ].color.setHex( Math.random() * 0xffffff | 0x80000000 );

                }
                */
            }
/****************************** CLICK END **********************************/




            function onWindowResize() {
                windowHalfX = window.innerWidth / 2;
                windowHalfY = window.innerHeight / 2;
                ButtonsCamera.aspect = window.innerWidth / window.innerHeight;
                ButtonsCamera.updateProjectionMatrix();
                ButtonsRenderer.setSize( window.innerWidth, window.innerHeight );
            }




            function onDocumentMouseMove(event) {
                mouseX = ( event.clientX - windowHalfX ) * 10;
                mouseY = ( event.clientY - windowHalfY ) * 10;
            }

            function animate() {                
                requestAnimationFrame( animate );
                render();
                ButtonsStats.update();
            }


            /****************************** CLICK START **********************************/
var radius = 100;
            var theta = 0;
            /****************************** CLICK END **********************************/


            function render() {




                var ButtonsTime = Date.now() * 0.001;
                var rx = Math.sin( ButtonsTime * 0.7 ) * 0.5,
                    ry = Math.sin( ButtonsTime * 0.3 ) * 0.5,
                    rz = Math.sin( ButtonsTime * 0.2 ) * 0.5;
                ButtonsCamera.position.x += ( mouseX - ButtonsCamera.position.x ) * .05;
                ButtonsCamera.position.y += ( - mouseY - ButtonsCamera.position.y ) * .05;
                ButtonsCamera.lookAt( ButtonsScene.position );
                ButtonsGroup.rotation.x = rx;
                ButtonsGroup.rotation.y = ry;
                ButtonsGroup.rotation.z = rz;
                ButtonsRenderer.render( ButtonsScene, ButtonsCamera );
            }
        </script>

</body>
</html>
4

1 回答 1

4

嘿,我希望我还不算太晚,但无论如何,您的问题的解决方案是错误的陈述和不推荐使用的方法。

您的对象数组中只有一个对象,这就是为什么当您单击随机框时,光线投射器不太可能检测到交叉点。将数组 push 调用移动到 for 循环中,以便将每个对象添加到数组中,而不是添加最后一个创建的对象。

for (var i = 0; i < 100; i++) {
    var ButtonsMesh;
    if (i == 0) 
    {
        ButtonsMesh = new THREE.Mesh(ButtonsGeometry, ButtonsMaterial);
    } 
    else 
    {
        ButtonsMesh = new THREE.Mesh(ButtonsGeometry, ButtonsMaterial);
    }
    ButtonsMesh.position.x = Math.random() * 2000 - 1000;
    ButtonsMesh.position.y = Math.random() * 2000 - 1000;
    ButtonsMesh.position.z = Math.random() * 2000 - 1000;
    ButtonsMesh.rotation.x = Math.random() * 360 * (Math.PI / 180);
    ButtonsMesh.rotation.y = Math.random() * 360 * (Math.PI / 180);
    ButtonsMesh.matrixAutoUpdate = false;
    ButtonsMesh.updateMatrix();
    ButtonsGroup.add(ButtonsMesh);
    objects.push(ButtonsMesh);
}

第二个问题是较新版本的 THREE 不使用 subSelf(),而是用 sub() 代替。因此,对 Raycaster 定义进行更改。

var raycaster = new THREE.Raycaster(ButtonsCamera.position, 
                vector.sub(ButtonsCamera.position).normalize());

那应该可以解决您的问题,但是您的代码中有更多错误,但它们都是微不足道的。

我希望这会有所帮助,这是一个工作版本:http: //jsbin.com/uhihoq/1/edit

和平!

于 2013-06-26T21:14:40.547 回答