首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从旋转网格中投射多条射线

从旋转网格中投射多条射线
EN

Stack Overflow用户
提问于 2022-11-28 16:41:37
回答 1查看 33关注 0票数 0

我试着从一个旋转的网格中拍摄多条射线。射线向多个方向射击(目标点位于一个圆圈上,除以射线数)。

为了调试目的,我为每个射线添加了ArrowHelpers。这样的想法是,箭头击中某物时应该变成红色,如果不是,则变成白色。它们还根据与相交物体的距离改变长度,当它们不相交时,它们的长度停留在射线的最大长度(远)。

到目前为止,我所得到的是,每条射线都在检查旋转网格的相同(我认为)正向方向。我认为我需要找到一个公式,根据物体当前的旋转来计算新的归一化向量。我试过很多不同的东西,比如object3D.localToGlobalVector3.applyQuaternion等等.然而,我的数学技能却让我失望了。

代码沙箱:https://codesandbox.io/s/raycast-issue-bch05b

雷射代码:

代码语言:javascript
运行
复制
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 };
};
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-30 17:16:59

好吧,回答我自己的问题,希望将来有人会用到这个.

我似乎对这个方法是正确的,我实际上在另一个堆叠溢出问题中找到了答案,解决方案就在这个问题中!

解决方案是使用一个复制旋转网格旋转的THREE.Matrix4类。然后,旋转矩阵应该应用到给定射线的方向上。

在夏天:

代码语言:javascript
运行
复制
// 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));

签出更新沙箱

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74603813

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档