Raycaster 是什么有什么用作
- Raycaster 光线投影是用来做三维事件判断的API
- Raycaster 主要通过 与 Vector2 与本身的属性 intersectObjects 来判断是否点击了某个3D环境中有物体
使用示例
<template>
<div id="parkingLot" ref="parkingLot"></div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
const parkingLot = ref();
onMounted(() => {
const DOMEl = parkingLot.value;
const width = DOMEl.clientWidth;
const height = DOMEl.clientHeight;
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
DOMEl.appendChild(renderer.domElement);
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, width / height, 1, 2000);
camera.position.set(0, 5, 50);
camera.lookAt(0, 0, 0);
const controls = new OrbitControls(camera, renderer.domElement);
const cubes = [];
const geometry = new THREE.BoxGeometry();
for (let i = 0; i < 5; i++) {
const material = new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff });
const cube = new THREE.Mesh(geometry, material);
cube.position.x = Math.random() * 4 - 2;
cube.position.y = Math.random() * 4 - 2;
cube.position.z = Math.random() * 4 - 2;
cubes.push(cube);
scene.add(cube);
}
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
const onMouseClick = (event) => {
const rect = DOMEl.getBoundingClientRect();
mouse.x = ((event.clientX - rect.left) / width) * 2 - 1;
mouse.y = -((event.clientY - rect.top) / height) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(scene.children);
if (intersects.length > 0) {
const intersectedObject = intersects[0].object;
console.log('Hit object:', intersectedObject);
intersectedObject.material.color.set(0xff0000);
} else {
console.log('No objects hit.');
}
};
window.addEventListener('click', onMouseClick);
function animate() {
requestAnimationFrame(animate);
cubes.forEach(cube => {
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
});
renderer.render(scene, camera);
}
animate();
onUnmounted(() => {
window.removeEventListener('click', onMouseClick);
controls.dispose();
renderer.dispose();
});
});
</script>
<style lang="scss" scoped>
#parkingLot {
width: 940px;
height: 940px;
border: 1px solid #ccc;
margin: 30px auto;
}
</style>