【问题标题】:Three Js Object3D Button Group Detect Single Object Click While Mouse Movement Causes Object3D Button Group Zoomi三个 Js Object3D 按钮组检测单个对象单击而鼠标移动导致 Object3D 按钮组 Zoomi
【发布时间】:2013-06-27 05:14:40
【问题描述】:

我正在尝试检测 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 - how to detect what shape was selected? after drag

how to Get CLICKED element in THREE.js

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

<!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>

【问题讨论】:

  • 你能设置一个jsfiddle吗?
  • 您好 mrdoob,感谢您提供的所有帮助,并且对我的问题的超快速响应非常棒。我已经按照你的要求设置了一个 jsfiddle,这里是分享链接:jsfiddle.net/sweetj77/7BymE/1
  • 您需要学习如何设置 jsfiddle 以便它运行(使用当前版本的库)。示例:jsfiddle.net/rgE2j/4
  • 您好,我已经按照您发送的示例设置了 jsfiddle。我在 jsfiddle 文档中搜索了如何上传附件,但没有找到。我需要检测点击的立方体有一个映射到所有侧面的图像。请指教。谢谢,乔纳森 如果您想在生产中查看它,这是我的网站:doublestampitnoerasies.com

标签: three.js


【解决方案1】:

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

您的对象数组中只有一个对象,这就是为什么当您单击一个对象时 raycaster 不太可能检测到交叉点的随机框。 将数组 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

和平!

【讨论】:

  • 嗨,这个答案是信息性的,但是我在尝试更改示例时遇到了一些问题。我尝试将 CubeGeometry 更改为 SphereGeometry,它所有的渲染和所有的东西,除了命中测试有点偏离。大约两个月以来,我一直在寻找关于三个 js 的最新资源和教程,但没有找到任何使用最新的。任何想法,将不胜感激。谢谢
  • 是的,点击率有点不准确,我一直在努力寻找解决方案。我所知道的是,问题与浏览器鼠标位置如何转换为三个坐标、窗口尺寸和相机位置有关。 Raycaster 对象具有您可以使用的精度属性。我正在编写一些三个教程,使用最新版本,完成后我会发给你一个链接。
猜你喜欢
  • 2012-03-15
  • 1970-01-01
  • 2012-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
相关资源
最近更新 更多