UNPKG

mylingo3d

Version:

Lingo3D is a React/Vue 3d game development framework that ships with a complete visual editor

68 lines (58 loc) 2.36 kB
import { createEffect } from "@lincode/reactivity" import { Box3 } from "three" import { emitBeforeCameraLoop } from "../../../../events/onBeforeCameraLoop" import { onBeforeRender } from "../../../../events/onBeforeRender" import { getBVHMap } from "../../../../states/useBVHMap" import getWorldDirection from "../../../utils/getWorldDirection" import { box3, line3, vector3, vector3_ } from "../../../utils/reusables" import { bvhCameraSet } from "./bvhCameraSet" createEffect(() => { const bvhArray = getBVHMap() if (!bvhArray.length) { const handle = onBeforeRender(emitBeforeCameraLoop) return () => { handle.cancel() } } const handle = onBeforeRender(() => { emitBeforeCameraLoop() for (const cam of bvhCameraSet) { const capsuleRadius = 0.5 cam.updateMatrixWorld() const direction = getWorldDirection(cam) const { start, end } = line3 end.copy(start.copy(cam.position)) box3.makeEmpty() box3.expandByPoint(start) box3.min.addScalar(-capsuleRadius) box3.max.addScalar(capsuleRadius) const triPoint = vector3 const capsulePoint = vector3_ let distance = 0 let depth = 0 for (const boundsTree of bvhArray) boundsTree.shapecast({ intersectsBounds: (box: Box3) => box.intersectsBox(box3), intersectsTriangle: (tri: any) => { distance = tri.closestPointToSegment( line3, triPoint, capsulePoint ) if (distance < capsuleRadius) { depth = capsuleRadius - distance start.addScaledVector(direction, depth) end.addScaledVector(direction, depth) } } }) const deltaVector = start.sub(cam.position) const offset = Math.max(0.0, deltaVector.length() - 1e-5) deltaVector.normalize().multiplyScalar(offset) cam.position.add(deltaVector) } }) return () => { handle.cancel() } }, [getBVHMap])