我试着从一个旋转的网格中拍摄多条射线。射线向多个方向射击(目标点位于一个圆圈上,除以射线数)。
为了调试目的,我为每个射线添加了ArrowHelpers。这样的想法是,箭头击中某物时应该变成红色,如果不是,则变成白色。它们还根据与相交物体的距离改变长度,当它们不相交时,它们的长度停留在射线的最大长度(远)。
到目前为止,我所得到的是,每条射线都在检查旋转网格的相同(我认为)正向方向。我认为我需要找到一个公式,根据物体当前的旋转来计算新的归一化向量。我试过很多不同的东西,比如object3D.localToGlobal,Vector3.applyQuaternion等等.然而,我的数学技能却让我失望了。
代码沙箱:https://codesandbox.io/s/raycast-issue-bch05b
雷射代码:
import { RefObject } from "react";
import * as THREE from "three";
import React from "react";
import { useFrame, useThree } from "@react-three/fiber";
export type RayCastResult = {
hit: boolean;
angle: number;
direction: THREE.Vector3;
distance: number;
};
export const useRaycasts = ({
count = 4,
near = 1,
far = 10,
obj
}: {
count?: number;
near?: number;
far?: number;
obj: RefObject<THREE.Mesh>;
}): { rays: RayCastResult[] } => {
const rays = React.useMemo(() => {
const rays: RayCastResult[] = [];
let angle = 0;
const step = (2 * Math.PI) / count;
for (let i = 0; i < count; i++) {
rays.push({
hit: false,
angle: angle,
direction: new THREE.Vector3(
Math.cos(angle),
0,
Math.sin(angle)
).normalize(),
distance: 10
});
angle += step;
}
return rays;
}, [count]);
const pos = React.useMemo(() => new THREE.Vector3(), []);
const dir = React.useMemo(() => new THREE.Vector3(), []);
const { scene, raycaster } = useThree();
useFrame(() => {
if (!obj.current) return;
obj.current.getWorldDirection(dir);
obj.current.getWorldPosition(pos);
rays.forEach((direction, i) => {
if (!obj.current) return;
raycaster.set(
pos,
dir
.applyAxisAngle(rays[0].direction, obj.current?.rotation.y)
.normalize()
//dir.applyAxisAngle(rays[i].direction, rays[i].angle),
//dir.applyAxisAngle(rays[i].direction, Math.PI / 2)
//dir.applyQuaternion(obj.current.quaternion).add(rays[i].direction)
);
raycaster.near = near;
raycaster.far = far;
const intersects = raycaster.intersectObjects(scene.children);
// ONLY check first object
if (intersects.length) {
rays[i].hit = true;
rays[i].distance = intersects[0].distance;
} else {
rays[i].hit = false;
rays[i].distance = raycaster.far;
}
});
});
return { rays };
};发布于 2022-11-30 17:16:59
好吧,回答我自己的问题,希望将来有人会用到这个.
我似乎对这个方法是正确的,我实际上在另一个堆叠溢出问题中找到了答案,解决方案就在这个问题中!
解决方案是使用一个复制旋转网格旋转的THREE.Matrix4类。然后,旋转矩阵应该应用到给定射线的方向上。
在夏天:
// construct a Matrix4 class (do it once to save resources)
const matrix = useMemo(() => new THREE.Matrix4(), []);
// Later inside the loop:
// get the object's current position
obj.current.getWorldPosition(pos);
// copy the objects rotation matrix to our matrix
matrix.extractRotation(obj.current.matrix);
// apply the rotation to the ray direction
raycaster.set(pos, dir.copy(rays[i].direction).applyMatrix4(matrix));签出更新沙箱
https://stackoverflow.com/questions/74603813
复制相似问题