使用3.Raycaster-我总是得到ID 8?

问题描述 投票:2回答:1

我想创建一个仪表板,在其上显示一定数量的“ THREE.Meshes”。当我用鼠标单击其中之一时,我想调用一个识别我所单击内容的函数。

我的问题:我总是从“ callFromTitleWithId”函数获得ID:8。用鼠标单击选择哪一个都没关系。

也许有人可以帮忙,我找不到错误:(

这里是完整的示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>TEST</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

        <style>
            body { margin: 0;
            background: black; }
            canvas { width: 100%; height: 100% }
        </style>
    </head>

    <body>
        <!-- Bibs -->
        <script src="../extlib/webthree/build/three.js"></script>
        <script>
            document.addEventListener('mousedown', onDocumentMouseDown, false);

            var arrayTiles = [];

            //[SCREEN]
            var SCREEN_WIDTH = window.innerWidth - 5;
            var SCREEN_HEIGHT = window.innerHeight - 5;

            screenOrientationValue=0;

            //RayCaster für Objekte
            var raycaster2 = new THREE.Raycaster(new THREE.Vector3(0,0,35),new THREE.Vector3(0,0,1));
            var mouse2 = new THREE.Vector2();

            var renderer = new THREE.WebGLRenderer();
            renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
            document.body.appendChild( renderer.domElement );

            var sceneWorld = new THREE.Scene();
            sceneWorld.add( new THREE.AxesHelper(50) );
            createTiles(sceneWorld);

            var camera= new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
            camera.position.set(0,0,35);

            var light2 = new THREE.AmbientLight( 0x20202A, 20, 100 );
            light2.position.set( 30, -10, 30 );
            sceneWorld.add( light2 );


            var animate = function () {

                requestAnimationFrame( animate );
                renderer.render( sceneWorld, camera);
                sceneUpdate();
            };

            animate();

            function sceneUpdate()
            {
                //Update            
            }

            function callFromTitleWithId(titleId)
            {
                console.log("ID:"+titleId);
            }

            function onDocumentMouseDown(event)
            {
                event.preventDefault();



                    mouse2.x = (event.clientX / renderer.domElement.clientWidth) * 2 - 1;
                    mouse2.y =  - (event.clientY / renderer.domElement.clientHeight) * 2 + 1;

                    raycaster2.setFromCamera(mouse2, camera);

                    var intersects2 = raycaster2.intersectObjects(arrayTiles,true);

                    if (intersects2.length > 0) {
                          console.log('Maus: X:'+mouse2.x+' Y:'+mouse2.y);
                          console.log("intersects:" + intersects2[0].object);
                          console.log("distance:" + intersects2[0].distance);
                          console.log("face:" + intersects2[0].face);
                          console.log("faceIndex:" + intersects2[0].faceIndex);
                          console.log("faceIndex y:" + intersects2[0].point.y);
                          console.log("faceIndex x:" + intersects2[0].point.x);

                          intersects2[0].object.callback();                       
                    }
            }

            function createTiles(sceneWorld)
            {
                var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
                var materialSide = new THREE.MeshBasicMaterial( {color: 0xffff00} );
                var materialsTiles = [materialSide, // Left side
                materialSide, // Right side
                materialSide, // Top side   ---> THIS IS THE FRONT
                materialSide, // Bottom side --> THIS IS THE BACK
                material, // Front side
                materialSide  // Back side
                ];

                var maxTileSizeWidth=11;
                var maxTileSizeHeight=8;

                var distanceBetween=2;
                var distanceBorderLeft=-1;

                var countInColumns=2;
                var countInRow = 4;

                var startCoordinatesX = ((((countInColumns * maxTileSizeWidth)+(countInColumns-6.5)*distanceBetween)/2))*-1;
                var startCoordinatesY = 20;

                var actualCoordinatesX = startCoordinatesX;
                var actualCoordinatesY = startCoordinatesY;

                //id for test
                var idNumberForTest=0;

                let r;
                for(r=1; r<=countInRow; r++ )
                {
                    let i;
                    for(i=1; i<=countInColumns; i++ )
                    {
                        var geometry = new THREE.BoxGeometry(maxTileSizeWidth, maxTileSizeHeight, 1 );
                        var tileX = new THREE.Mesh( geometry, materialsTiles );
                        tileX.position.set(actualCoordinatesX,actualCoordinatesY,0);

                        //Change actualCoordinates X
                        actualCoordinatesX = actualCoordinatesX + maxTileSizeWidth + distanceBetween;

                        idNumberForTest=idNumberForTest + 1;
                        tileX.callback = function(){callFromTitleWithId(idNumberForTest+'')};
                        arrayTiles.push(tileX);

                        sceneWorld.add( tileX );
                    }

                    actualCoordinatesY = actualCoordinatesY - (maxTileSizeHeight+1);
                    actualCoordinatesX = startCoordinatesX;
                }
            }
        </script>
    </body>
</html>

`

three.js callback mouse object-detection raycasting
1个回答
2
投票

问题是idNumberForTest对于所有对象都是相等的。回调函数始终引用相同的变量。除了使用回调函数,您还可以像这样存储单击的网格的ID:

tileX.userData.id = idNumberForTest;

以这种方式,将正确的ID分配给各个对象。请查看以下实时示例,以了解这种方法的实际效果。

document.addEventListener('mousedown', onDocumentMouseDown, false);

var arrayTiles = [];

//[SCREEN]
var SCREEN_WIDTH = window.innerWidth - 5;
var SCREEN_HEIGHT = window.innerHeight - 5;

screenOrientationValue=0;

//RayCaster für Objekte
var raycaster2 = new THREE.Raycaster(new THREE.Vector3(0,0,35),new THREE.Vector3(0,0,1));
var mouse2 = new THREE.Vector2();

var renderer = new THREE.WebGLRenderer();
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
document.body.appendChild( renderer.domElement );

var sceneWorld = new THREE.Scene();
sceneWorld.add( new THREE.AxesHelper(50) );
createTiles(sceneWorld);

var camera= new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.set(0,0,35);

var light2 = new THREE.AmbientLight( 0x20202A, 20, 100 );
light2.position.set( 30, -10, 30 );
sceneWorld.add( light2 );


var animate = function () {

	requestAnimationFrame( animate );
	renderer.render( sceneWorld, camera);
	sceneUpdate();
};

animate();

function sceneUpdate()
{
	//Update            
}

function callFromTitleWithId(titleId)
{
	console.log("ID:"+titleId);
}

function onDocumentMouseDown(event)
{
	event.preventDefault();

	mouse2.x = (event.clientX / renderer.domElement.clientWidth) * 2 - 1;
	mouse2.y =  - (event.clientY / renderer.domElement.clientHeight) * 2 + 1;

	raycaster2.setFromCamera(mouse2, camera);
	
	console.log( arrayTiles );

	var intersects2 = raycaster2.intersectObjects(arrayTiles,true);

	if (intersects2.length > 0) {
		console.log('Maus: X:'+mouse2.x+' Y:'+mouse2.y);
		console.log("intersects:" + intersects2[0].object);
		console.log("distance:" + intersects2[0].distance);
		console.log("face:" + intersects2[0].face);
		console.log("faceIndex:" + intersects2[0].faceIndex);
		console.log("faceIndex y:" + intersects2[0].point.y);
		console.log("faceIndex x:" + intersects2[0].point.x);

		console.log("ID:", intersects2[0].object.userData.id);                
	}
}

function createTiles(sceneWorld)
{
	var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
	var materialSide = new THREE.MeshBasicMaterial( {color: 0xffff00} );
	var materialsTiles = [materialSide, // Left side
												materialSide, // Right side
												materialSide, // Top side   ---> THIS IS THE FRONT
												materialSide, // Bottom side --> THIS IS THE BACK
												material, // Front side
												materialSide  // Back side
											 ];

	var maxTileSizeWidth=11;
	var maxTileSizeHeight=8;

	var distanceBetween=2;
	var distanceBorderLeft=-1;

	var countInColumns=2;
	var countInRow = 4;

	var startCoordinatesX = ((((countInColumns * maxTileSizeWidth)+(countInColumns-6.5)*distanceBetween)/2))*-1;
	var startCoordinatesY = 20;

	var actualCoordinatesX = startCoordinatesX;
	var actualCoordinatesY = startCoordinatesY;

	//id for test
	var idNumberForTest=0;

	let r;
	for(r=1; r<=countInRow; r++ )
	{
		let i;
		for(i=1; i<=countInColumns; i++ )
		{
			var geometry = new THREE.BoxGeometry(maxTileSizeWidth, maxTileSizeHeight, 1 );
			var tileX = new THREE.Mesh( geometry, materialsTiles );
			tileX.position.set(actualCoordinatesX,actualCoordinatesY,0);

			//Change actualCoordinates X
			actualCoordinatesX = actualCoordinatesX + maxTileSizeWidth + distanceBetween;

			idNumberForTest=idNumberForTest + 1;
			arrayTiles.push(tileX);
			tileX.userData.id = idNumberForTest;

			sceneWorld.add( tileX );
		}

		actualCoordinatesY = actualCoordinatesY - (maxTileSizeHeight+1);
		actualCoordinatesX = startCoordinatesX;
	}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
© www.soinside.com 2019 - 2024. All rights reserved.