Three.js - 如何检测什么形状被选中?阻力后阻力、形状、Three、js

2023-09-07 17:23:50 作者:吃饭睡觉拉粑粑

我与形状是一个画布...的形状拖动。 一切似乎很好地工作。但是现在我想弄清楚 我怎么能检测一下形状选择/拖?

这是我的code:(JavaScript)的

  VAR容器,统计;
            VAR摄像头,场景,投影机,渲染器;
            VAR对象= [],平面;

            VAR鼠标=新THREE.Vector2()
            偏移量=新THREE.Vector3(),
            相交,选中;

            变种basic_x_dist = 0;

            变种cameraX = 0,cameraY = 0,cameraZ = 100; //默认一样camera.position.z!

            在里面();
            动画();

            功能的init(){

                容器= document.createElement方法('格');
                document.body.appendChild(容器);

                摄像头=新THREE.PerspectiveCamera(70,window.innerWidth / window.innerHeight,1,500);
                camera.position.z = 300;

                现场=新THREE.Scene();

                scene.add(新THREE.AmbientLight(0x505050));

                VAR光=新THREE.SpotLight(0XFFFFFF,1.5);
                light.position.set(0,500,2000);
                light.castShadow = TRUE;
                scene.add(光);

                变种几何=新THREE.CubeGeometry(7,7,1,3,3,1);

                为(变种I = 0; I&小于5;我++){

                    VAR对象=新THREE.Mesh(几何,新THREE.MeshLambertMaterial({图:THREE.ImageUtils.loadTexture('red.png')}));

                    //object.material.ambient = object.material.color;

                      object.position.x = basic_x_dist;
                      basic_x_dist + = 10;
                    //object.position.x =的Math.random()* 100  -  50;
                    //object.position.y =的Math.random()* 60  -  30;
                    //object.position.z =的Math.random()* 80  -  40;

                    //object.rotation.x =(的Math.random()* 360)* Math.PI / 180;
                    //object.rotation.y =(的Math.random()* 360)* Math.PI / 180;
                    //object.rotation.z =(的Math.random()* 360)* Math.PI / 180;

                    //object.scale.x =的Math.random()* 2 + 1;
                    //object.scale.y =的Math.random()* 2 + 1;
                    //object.scale.z =的Math.random()* 2 + 1;

                    //object.castShadow = TRUE;
                    //object.receiveShadow = TRUE;

                    scene.add(对象);

                    objects.push(对象);

                }

                飞机=新THREE.Mesh(新THREE.PlaneGeometry(2000年,2000年,8,8),新THREE.MeshBasicMaterial({颜色:0x000000处,不透明度:0.25,透明:真,线框:真}));

                plane.lookAt(camera.position);
                plane.visible = FALSE;
                scene.add(平面);

                投影机=新THREE.Projector();

                渲染器=新THREE.CanvasRenderer();
                renderer.sortObjects = FALSE;
                renderer.setSize(window.innerWidth,window.innerHeight);


                //renderer.shadowMapEnabled = TRUE;
                //renderer.shadowMapSoft = TRUE;

                //renderer.shadowCameraNear = 3;
                //renderer.shadowCameraFar = camera.far;
                //renderer.shadowCameraFov = 50;

                //renderer.shadowMapBias = 0.0039;
                //renderer.shadowMapDarkness = 0.5;
                //renderer.shadowMapWidth = 1024;
                //renderer.shadowMapHeight = 1024;

                container.appendChild(renderer.domElement);

                VAR信息= document.createElement方法('格');
                info.style.position ='绝对';
                info.style.top ='10px的';
                info.style.width =100%;
                info.style.textAlign =中心;
                info.innerHTML ='< A HREF =htt​​p://github.com/mrdoob/three.js目标=_空白> three.js< / A> WebGL的 - 拖动立方体;
                container.appendChild(信息);

                统计数据=新的统计();
                stats.domElement.style.position ='绝对';
                stats.domElement.style.top =0px​​;
                container.appendChild(stats.domElement);

                renderer.domElement.addEventListener('鼠标移动',onDocumentMouseMove,假);
                renderer.domElement.addEventListener(鼠标按下,onDocumentMouseDown,假);
                renderer.domElement.addEventListener(鼠标松开,onDocumentMouseUp,假);
                document.onkey preSS = key_event;

            }

            功能onDocumentMouseMove(事件){

                。事件preventDefault();

                mouse.x =(event.clientX / window.innerWidth)* 2  -  1;
                mouse.y =  - (event.clientY / window.innerHeight)* 2 + 1;


                VAR向量=新THREE.Vector3(mouse.x,mouse.y,0.5);
                projector.unprojectVector(矢量,摄像头);

                VAR光=新THREE.Ray(camera.position,vector.subSelf(camera.position).normalize());


                如果(选择){

                    VAR相交= ray.intersectObject(平面);
                    SELECTED.position.copy(相交[0] .point.subSelf(偏移));
                    返回;

                }


                变种相交= ray.intersectObjects(对象);

                如果(intersects.length大于0){

                    如果(相交!=相交[0] .object){

                        如果(相交的)INTERSECTED.material.color.setHex(INTERSECTED.currentHex);

                        相交的相交= [0] .object;
                        INTERSECTED.currentHex = INTERSECTED.material.color.getHex();

                        plane.position.copy(INTERSECTED.position);

                    }

                    container.style.cursor ='指针';

                } 其他 {

                    如果(相交的)INTERSECTED.material.color.setHex(INTERSECTED.currentHex);

                    相交= NULL;

                    container.style.cursor ='自动';

                }

            }

            功能onDocumentMouseDown(事件){

                。事件preventDefault();

                VAR向量=新THREE.Vector3(mouse.x,mouse.y,0.5);
                projector.unprojectVector(矢量,摄像头);

                VAR光=新THREE.Ray(camera.position,vector.subSelf(camera.position).normalize());

                变种相交= ray.intersectObjects(对象);

                如果(intersects.length大于0){

                    SELECTED =相交[0] .object;

                    VAR相交= ray.intersectObject(平面);
                    offset.copy(相交[0] .point).subSelf(plane.position);

                    container.style.cursor =搬家;

                }

            }

            功能onDocumentMouseUp(事件){

                。事件preventDefault();

                如果(相交的){

                    plane.position.copy(INTERSECTED.position);

                    SELECTED = NULL;

                }

                container.style.cursor ='自动';

            }

            传播rotateLeft(){
                cameraX + = 5;
            }

            传播rotateRight(){
                cameraX  -  = 5;
            }

            传播rotateUp(){
                cameraY + = 5;
            }

            传播rotateDown(){
                cameraY  -  = 5;
            }

            传播zoomIn(){
                cameraZ + = 5;
            }

            传播zoomOut(){
                cameraZ  -  = 5;
            }

            功能showPositions(){
                为(变种I = 0; I&小于5;我++){
                    警报(对象[I] .position.x);
                    警报(对象[I] .position.y);
                    警报(对象[I] .position.z);
                }
            }

            功能key_event(事件){

                VAR UNI code = event.key code? event.key code:event.char code;
                //警报(UNI code); //找到字符code
                开关(UNI code){
                    案例97:rotateLeft();打破;
                    壳体100:rotateRight();打破;
                    壳体119:rotateUp();打破;
                    壳体120:rotateDown();打破;
                    壳体122:zoomIn();打破;
                    情况99:zoomOut();打破;
                    壳体115:showPositions();打破;
                }
                }


            功能动画(){

                requestAnimationFrame(动画);

                渲染();
                stats.update();

            }

            功能渲染(){

                camera.position.x = cameraX; //更新摄像机视图-X规模的事件之后
                camera.position.y = cameraY; //更新摄像机视图-Y规模的事件之后
                camera.position.z = cameraZ; //更新摄像机视图-Z大型赛事后,
                camera.lookAt(scene.position);
                renderer.render(场景,摄像头);

            }
 

解决方案

我发现pretty的简单的解决方案...但我想这是它始终工作:-)所有你需要做的检测是2路事情:首先再添变数:VAR的thisObject;之后,你必须去的onmousedown事件()函数。右后SELECTED =相交[0] .object;你必须写这件事情:

 的(VAR I = 0; I< objects.length;我++)
    {
       如果(SELECTED.position.x ==对象[I] .position.x)
              的thisObject =我;
    }
 
Threejs 开发 3D 地图实践总结

...现在的thisObject保持当前形状的(所选择/拖)的对象数组索引...是啊这么简单: - )

I made a canvas with shapes in it...the shapes are draggable. Everything seems to work fine...But now I'm trying to figure out how can I detect what shape was selected/dragged?

this is my code: (Javascript)

var container, stats;
            var camera, scene, projector, renderer;
            var objects = [], plane;

            var mouse = new THREE.Vector2(),
            offset = new THREE.Vector3(),
            INTERSECTED, SELECTED;

            var basic_x_dist = 0;

            var cameraX = 0,cameraY = 0,cameraZ = 100; // default-same as camera.position.z!            

            init();
            animate();

            function init() {

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

                camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 500 );
                camera.position.z = 300;

                scene = new THREE.Scene();

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

                var light = new THREE.SpotLight( 0xffffff, 1.5 );
                light.position.set( 0, 500, 2000 );
                light.castShadow = true;
                scene.add( light );             

                var geometry = new THREE.CubeGeometry( 7, 7, 1, 3, 3, 1);

                for ( var i = 0; i < 5; i ++ ) {

                    var object = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( {  map:                                       THREE.ImageUtils.loadTexture( 'red.png' ) } ) );

                    //object.material.ambient = object.material.color;

                      object.position.x = basic_x_dist;
                      basic_x_dist += 10;
                    //object.position.x = Math.random() * 100 - 50;
                    //object.position.y = Math.random() * 60 - 30;
                    //object.position.z = Math.random() * 80 - 40;

                    //object.rotation.x = ( Math.random() * 360 ) * Math.PI / 180;
                    //object.rotation.y = ( Math.random() * 360 ) * Math.PI / 180;
                    //object.rotation.z = ( Math.random() * 360 ) * Math.PI / 180;

                    //object.scale.x = Math.random() * 2 + 1;
                    //object.scale.y = Math.random() * 2 + 1;
                    //object.scale.z = Math.random() * 2 + 1;

                    //object.castShadow = true;
                    //object.receiveShadow = true;

                    scene.add( object );

                    objects.push( object );

                }

                plane = new THREE.Mesh( new THREE.PlaneGeometry( 2000, 2000, 8, 8 ), new                    THREE.MeshBasicMaterial( { color: 0x000000, opacity: 0.25, transparent: true, wireframe:                    true } ) );

                plane.lookAt( camera.position );
                plane.visible = false;
                scene.add( plane );

                projector = new THREE.Projector();

                renderer = new THREE.CanvasRenderer();
                renderer.sortObjects = false;
                renderer.setSize( window.innerWidth, window.innerHeight );


                //renderer.shadowMapEnabled = true;
                //renderer.shadowMapSoft = true;

                //renderer.shadowCameraNear = 3;
                //renderer.shadowCameraFar = camera.far;
                //renderer.shadowCameraFov = 50;

                //renderer.shadowMapBias = 0.0039;
                //renderer.shadowMapDarkness = 0.5;
                //renderer.shadowMapWidth = 1024;
                //renderer.shadowMapHeight = 1024;

                container.appendChild( renderer.domElement );

                var info = document.createElement( 'div' );
                info.style.position = 'absolute';
                info.style.top = '10px';
                info.style.width = '100%';
                info.style.textAlign = 'center';
                info.innerHTML = '<a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> webgl - draggable cubes';
                container.appendChild( info );

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

                renderer.domElement.addEventListener( 'mousemove', onDocumentMouseMove, false );
                renderer.domElement.addEventListener( 'mousedown', onDocumentMouseDown, false );
                renderer.domElement.addEventListener( 'mouseup', onDocumentMouseUp, false );
                document.onkeypress=key_event;

            }

            function onDocumentMouseMove( event ) {

                event.preventDefault();

                mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
                mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;


                var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
                projector.unprojectVector( vector, camera );

                var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );


                if ( SELECTED ) {

                    var intersects = ray.intersectObject( plane );
                    SELECTED.position.copy( intersects[ 0 ].point.subSelf( offset ) );
                    return;

                }


                var intersects = ray.intersectObjects( objects );

                if ( intersects.length > 0 ) {

                    if ( INTERSECTED != intersects[ 0 ].object ) {

                        if ( INTERSECTED ) INTERSECTED.material.color.setHex( INTERSECTED.currentHex );

                        INTERSECTED = intersects[ 0 ].object;
                        INTERSECTED.currentHex = INTERSECTED.material.color.getHex();

                        plane.position.copy( INTERSECTED.position );

                    }

                    container.style.cursor = 'pointer';

                } else {

                    if ( INTERSECTED ) INTERSECTED.material.color.setHex( INTERSECTED.currentHex );

                    INTERSECTED = null;

                    container.style.cursor = 'auto';

                }

            }

            function onDocumentMouseDown( event ) {

                event.preventDefault();

                var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
                projector.unprojectVector( vector, camera );

                var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );

                var intersects = ray.intersectObjects( objects );

                if ( intersects.length > 0 ) {

                    SELECTED = intersects[ 0 ].object;

                    var intersects = ray.intersectObject( plane );
                    offset.copy( intersects[ 0 ].point ).subSelf( plane.position );

                    container.style.cursor = 'move';

                }

            }

            function onDocumentMouseUp( event ) {

                event.preventDefault();

                if ( INTERSECTED ) {

                    plane.position.copy( INTERSECTED.position );

                    SELECTED = null;

                }

                container.style.cursor = 'auto';

            }

            function rotateLeft(){
                cameraX += 5;           
            }

            function rotateRight(){
                cameraX -= 5;           
            }

            function rotateUp(){
                cameraY += 5;           
            }

            function rotateDown(){
                cameraY -= 5;           
            }

            function zoomIn(){
                cameraZ += 5;           
            }

            function zoomOut(){
                cameraZ -= 5;           
            }

            function showPositions(){
                for(var i=0; i<5; i++){
                    alert(objects[i].position.x);
                    alert(objects[i].position.y);
                    alert(objects[i].position.z);
                }
            }

            function key_event( event ) {

                var unicode=event.keyCode? event.keyCode : event.charCode;
                //alert(unicode); // find the char code
                switch(unicode){
                    case 97:  rotateLeft(); break;
                    case 100: rotateRight(); break;
                    case 119: rotateUp(); break;
                    case 120: rotateDown(); break;
                    case 122: zoomIn(); break;
                    case 99:  zoomOut(); break;
                    case 115: showPositions(); break;
                }
                }


            function animate() {

                requestAnimationFrame( animate );

                render();
                stats.update();

            }

            function render() {

                camera.position.x = cameraX; // updating the camera view-x scale after events
                camera.position.y = cameraY; // updating the camera view-y scale after events
                camera.position.z = cameraZ; // updating the camera view-z scale after events
                camera.lookAt( scene.position );
                renderer.render( scene, camera );

            }

解决方案

I found pretty simple solution...but I guess that's the way it always works :-) All you have to do for the detection is 2 things: First of all add another variable: var thisObject; After that you have to go to the onMouseDown() function. Right after the SELECTED = intersects[0].object; you have to write this thing:

 for(var i=0; i<objects.length; i++)
    { 
       if(SELECTED.position.x == objects[i].position.x)
              thisObject = i; 
    }

...Now thisObject holds the index of the current shape (that was selected/dragged) in objects array...yeah that simple :-)