当前位置:网站首页>Threejs clicks the scene object to obtain object information, and threejs uses raycaster to pick up object information

Threejs clicks the scene object to obtain object information, and threejs uses raycaster to pick up object information

2022-07-05 04:00:00 Zuo Ben

1, Introduce

This example uses r95 edition Three.js library . Here is how to use the mouse to select objects in the scene .

The renderings are as follows :

 2, Main description

We use THREE.Projector and THREE.Raycaster To detect whether an object is clicked with the mouse . When we click the mouse on the screen , The following will happen :

(1) First , Based on the click position on the screen, a THREE.Vecor3 vector .

(2) next , Use vector.unproject Method to convert the click position on the screen into Three.js Coordinates in the scene . let me put it another way , It is to convert screen coordinates into coordinates in 3D scene .

(3) then , establish THREE.Raycaster. Use THREE.Raycaster You can emit light into the scene . In this example , From the position of the camera (camera.position) Emit light to the click position of the mouse in the scene .

(4) Last , We use raycaster.intersectObjects Method to determine which of the specified objects are illuminated by the light .

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

function onDocumentMouseDown(event) {
	//  Click on the screen to create a vector 
	var vector = new THREE.Vector3((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window
		.innerHeight) * 2 + 1, 0.5);
	vector = vector.unproject(camera); //  Convert the coordinates of the screen into coordinates in the 3D scene 
	var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
	var intersects = raycaster.intersectObjects(mesh, true);
	if (intersects.length > 0) {
		intersects[0].object.material.color.set("#ff0000");
	}
}

3, Source code

<!DOCTYPE html>
<html>
	<head>
		<title>Threejs Click the scene object to get the object information ,Threejs Use Raycaster Pick object information </title>
		<script type="text/javascript" src="libs/three.js"></script>
		<script type="text/javascript" src="libs/OrbitControls.js"></script>
		<style>
			body {
				margin: 0;
				overflow: hidden;
			}
		</style>
	</head>
	<body>
		<div id="dom"></div>
		<script type="text/javascript">
			var camera;
			var renderer;
			var length = 36;
			var ws = 2;
			var graph = [];
			var mesh = [];

			function init() {
				//  Create a scene , It will contain all our elements , Like an object , Cameras and lights .
				var scene = new THREE.Scene();

				var urls = [
					'assets/textures/cubemap/flowers/posx.jpg',
					'assets/textures/cubemap/flowers/negx.jpg',
					'assets/textures/cubemap/flowers/posy.jpg',
					'assets/textures/cubemap/flowers/negy.jpg',
					'assets/textures/cubemap/flowers/posz.jpg',
					'assets/textures/cubemap/flowers/negz.jpg'
				];

				var cubeLoader = new THREE.CubeTextureLoader();
				scene.background = cubeLoader.load(urls);

				//  Create a camera , It defines where we are looking 
				camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 0.1, 1000);
				//  Aim the camera at the center of the scene 
				camera.position.x = 60;
				camera.position.y = 35;
				camera.position.z = 60;
				camera.lookAt(scene.position);
				var orbit = new THREE.OrbitControls(camera);

				//  Create a renderer and set the size ,WebGLRenderer The computer graphics card will be used to render the scene 
				// initialize basic renderer
				renderer = new THREE.WebGLRenderer();
				renderer.setSize(window.innerWidth, window.innerHeight);

				//  Add planes to the scene 
				var plane = createPlaneGeometryBasicMaterial();
				scene.add(plane);

				//  Display the coordinate axis on the screen 
				var axes = new THREE.AxesHelper(100);
				scene.add(axes);
				scene.add(new THREE.AmbientLight(0x666666));
				scene.add(new THREE.AmbientLight("#ffffff", 1));
				document.getElementById("dom").appendChild(renderer.domElement);

				initGround();
				initGrid();

				//  Start animation 
				renderScene();

				//  Create a ground 
				function createPlaneGeometryBasicMaterial() {
					var textureLoader = new THREE.TextureLoader();
					var cubeMaterial = new THREE.MeshStandardMaterial({
						map: textureLoader.load("assets/textures/stone/cd.jpg"),
					});
					cubeMaterial.map.wrapS = THREE.RepeatWrapping;
					cubeMaterial.map.wrapT = THREE.RepeatWrapping;
					cubeMaterial.map.repeat.set(18, 18)
					//  Create the ground plane and set the size 
					var planeGeometry = new THREE.PlaneGeometry(500, 500);
					var plane = new THREE.Mesh(planeGeometry, cubeMaterial);

					//  Set the plane position and rotate 
					plane.rotation.x = -0.5 * Math.PI;
					plane.position.x = 0;
					plane.position.z = 0;
					return plane;
				}

				//  Initialize the line 
				function initLine(pArr) {
					var points = [];
					var geometry = new THREE.Geometry();
					for (var i = 0; i < pArr.length; i++) {
						var randomX = pArr[i].x;
						var randomY = pArr[i].y;
						var randomZ = pArr[i].z;
						var vector = new THREE.Vector3(randomX, randomY, randomZ);
						geometry.vertices.push(vector);
						points.push(vector);
					}
					var material = new THREE.LineBasicMaterial({
						color: 0x0000FF
					});
					var line = new THREE.Line(geometry, material);
					scene.add(line);
					return points;
				}

				//  Draw road network 
				function initGround() {
					var geometry = new THREE.Geometry();
					geometry.vertices.push(new THREE.Vector3(0, 0, 0));
					geometry.vertices.push(new THREE.Vector3(length, 0, 0));

					for (var i = 0; i <= length / ws; i++) {
						var material = new THREE.LineBasicMaterial({
							color: 0x808080
						});
						var line = new THREE.Line(geometry, material);
						line.position.z = i * ws;
						scene.add(line);

						var line = new THREE.Line(geometry, material);
						line.position.x = i * ws;
						line.position.z = length;
						line.rotation.y = 90 * Math.PI / 180;
						scene.add(line);
					}
				}

				//  Initialize obstacles 
				function initGrid() {
					for (var i = 0; i < length / ws; i++) {
						var nodeRow = [];
						for (var j = 0; j < length / ws; j++) {
							var salt = Math.random() * 7;
							if (salt > 2) {
								nodeRow.push(1);
							} else {
								nodeRow.push(0);
							}
							if (salt <= 2) {
								var cube = new THREE.Mesh(new THREE.CubeGeometry(1, 1, 1), new THREE.MeshBasicMaterial({
									color: 0xC0C0C0
								}));
								let x = ws * j + ws / 2;
								let z = ws * i + ws / 2;
								cube.position.set(x, 1.2, z);
								scene.add(cube);
								mesh.push(cube);
							}
						}
						graph.push(nodeRow);
					}
				}
				
				document.addEventListener('click', onDocumentMouseDown, false);
				
				function onDocumentMouseDown(event) {
					//  Click on the screen to create a vector 
					var vector = new THREE.Vector3((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window
						.innerHeight) * 2 + 1, 0.5);
					vector = vector.unproject(camera); //  Convert the coordinates of the screen into coordinates in the 3D scene 
					var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
					var intersects = raycaster.intersectObjects(mesh, true);
					if (intersects.length > 0) {
						intersects[0].object.material.color.set("#ff0000");
					}
				}

				//  Animation rendering 
				var step = 5;

				function renderScene() {
					orbit.update();

					//  Use requestAnimationFrame Function to render 
					requestAnimationFrame(renderScene);
					renderer.render(scene, camera);
				}

				//  Rendered scenes 
				renderer.render(scene, camera);
			}
			window.onload = init;

			function onResize() {
				camera.aspect = window.innerWidth / window.innerHeight;
				camera.updateProjectionMatrix();
				renderer.setSize(window.innerWidth, window.innerHeight);
			}
			//  Listen for resizing events 
			window.addEventListener('resize', onResize, false);
		</script>
	</body>
</html>

If you need a complete code, please leave a message or contact me on wechat :1171053128 

原网站

版权声明
本文为[Zuo Ben]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202140717141121.html