以上为当前 scene 渲染模型
针对红点想选中/通过鼠标来移动到制定位置
但是在编写过程中,这边使用raycaster来进行模型选中,但并不好使,恳请有经验的大佬得以指点一二
// 创建一个小球体作为点[多个点]
let raycasterObjects = [];
let point = new THREE.Vector3(-20.79461170700156, -31.34449501478036, 10.72384259079748);
const geometry = new THREE.SphereGeometry(1, 16, 16);
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const sphere = new THREE.Mesh(geometry, material);
sphere.name = "sphere";
// 设置小球的位置为交点的位置
sphere.position.copy(point);
scene.add(sphere)
raycasterObjects.push(sphere);
//以下是创建鼠标按键事件
let pointer = new THREE.Vector2();
let raycaster = new THREE.Raycaster();
onPointerDown(event) {
const _this = this;
pointer.x = (event.clientX / window.innerWidth) * 2 - 1
pointer.y = -(event.clientY / window.innerHeight) * 2 + 1
// 使用Raycaster检测是否点击到了可拖拽的点
raycaster.setFromCamera(pointer, camera);
const intersects = raycaster.intersectObjects(raycasterObjects, false);
console.log(`output->intersects`, intersects)
if (intersects.length > 0) {
let selectedObject = intersects[0].object; // 选择的对象
console.log(`output->selectedObject`, selectedObject)
}
}
具体实现思路
1.通过鼠标按下得到当前选中模型
2.通过鼠标抬起事件,获取当前鼠标的相对坐标[x,y,z] 来进行坐标给当前模型
3.移动模型
备注:也可以承接出去,最好自带报价,感谢感谢
因为是片段代码,所以我只能说问题的原因,需要把click点击事件和mousemove分开写,处理逻辑写在click事件中。
示例代码:
<script setup>
import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import { onMounted, ref } from 'vue'
/**
* scene
*/
const scene = new THREE.Scene()
/**
* camera
*/
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
100
)
camera.position.z = 3
/**
* object
*/
const object1 = new THREE.Mesh(
new THREE.SphereGeometry(0.5, 16, 16),
new THREE.MeshBasicMaterial({ color: '#ff0000' })
)
object1.position.x = - 2
const object2 = new THREE.Mesh(
new THREE.SphereGeometry(0.5, 16, 16),
new THREE.MeshBasicMaterial({ color: '#ff0000' })
)
const object3 = new THREE.Mesh(
new THREE.SphereGeometry(0.5, 16, 16),
new THREE.MeshBasicMaterial({ color: '#ff0000' })
)
object3.position.x = 2
scene.add(object1, object2, object3)
/**
* renderer
*/
const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
})
/**
* axesHelper
*/
const axesHelper = new THREE.AxesHelper(5)
scene.add(axesHelper)
/**
* control
*/
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true
/**
* raycaster
*/
const raycaster = new THREE.Raycaster()
/**
* mouse
*/
const mouse = new THREE.Vector2(1, 1)
window.addEventListener('mousemove', (event) => {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1
mouse.y = - (event.clientY / window.innerHeight) * 2 + 1
})
/**
* render
*/
const clock = new THREE.Clock()
let currentIntersect = null
const tick = () => {
const elapsedTime = clock.getElapsedTime()
const objectsToTest = [object1, object2, object3]
const intersects = raycaster.intersectObjects(objectsToTest)
raycaster.setFromCamera(mouse, camera) // 根据camera的位置设置方向
if (intersects.length > 0) {
// console.log('enter');
currentIntersect = intersects[0]
} else {
// console.log('leave');
currentIntersect = null
}
for (const object of objectsToTest) {
object.material.color.set(0xff0000)
}
for (const intersect of intersects) {
intersect.object.material.color.set('#0000ff')
}
// update
controls.update()
requestAnimationFrame(tick)
renderer.render(scene, camera)
}
document.addEventListener('click', () => {
if (currentIntersect) {
switch (currentIntersect.object) {
case object1:
console.log('click obj1');
break
case object2:
console.log('click obj2');
break
case object3:
console.log('click obj3');
break
}
}
})
onMounted(() => {
tick()
})
</script>