UNPKG

lingo3d

Version:

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

83 lines 3.57 kB
import { createEffect } from "@lincode/reactivity"; import "../eventLoop"; import { getWorldPlayComputed } from "../../states/useWorldPlayComputed"; import { setPxVec, setPxVec_ } from "./pxMath"; import fpsAlpha from "../../display/utils/fpsAlpha"; import { onPhysXLoop } from "../../events/onPhysXLoop"; import { physxPtr } from "../../pointers/physxPtr"; import { getPhysXLoaded } from "../../states/usePhysXLoaded"; import { controllerVYUpdateMap, controllerVXUpdateMap, controllerVZUpdateMap, groundedControllerManagers, managerActorMap, managerControllerMap } from "../../collections/pxCollections"; import { dtPtr } from "../../pointers/dtPtr"; import { gravityPtr } from "../../pointers/gravityPtr"; import { physxLoopPtr } from "../../pointers/physxLoopPtr"; const hitMap = new WeakMap(); const vyMap = new WeakMap(); const lockHitSet = new WeakSet(); const lockHit = (manager, lock) => { if (lockHitSet.has(manager)) return true; if (lock) { lockHitSet.add(manager); setTimeout(() => lockHitSet.delete(manager), 500); return true; } return false; }; createEffect(() => { const { pxScene, pxControllerFilters, pxRaycast } = physxPtr[0]; if (!pxScene || !getWorldPlayComputed()) return; physxLoopPtr[0] = true; const handle = onPhysXLoop(() => { groundedControllerManagers.clear(); for (const [manager, controller] of managerControllerMap) { const { x: px, y: py, z: pz } = manager.position; let dy = 0; const vyUpdate = controllerVYUpdateMap.get(manager); controllerVYUpdateMap.delete(manager); const dx = controllerVXUpdateMap.get(manager) ?? 0; const dz = controllerVZUpdateMap.get(manager) ?? 0; if (manager.gravity !== false) { const hit = lockHit(manager, vyUpdate !== undefined) ? false : !!pxRaycast(setPxVec(px, py, pz), setPxVec_(0, -1, 0), manager.$capsuleHeight, manager.$actor.ptr); hitMap.set(manager, hit); if (hit) { dy = -manager.$capsuleHeight; vyMap.set(manager, 0); groundedControllerManagers.add(manager); controllerVXUpdateMap.delete(manager); controllerVZUpdateMap.delete(manager); } else { const vy = (vyUpdate ?? vyMap.get(manager) ?? 0) + gravityPtr[0] * dtPtr[0]; vyMap.set(manager, vy); dy = vy * dtPtr[0]; } } else hitMap.set(manager, false); controller.move(setPxVec(dx, dy, dz), 0.001, dtPtr[0], pxControllerFilters); } pxScene.simulate(dtPtr[0]); pxScene.fetchResults(true); for (const [manager, actor] of managerActorMap) { const { p, q } = actor.getGlobalPose(); manager.position.copy(p); manager.quaternion.copy(q); } for (const manager of managerControllerMap.keys()) { const { position } = manager.outerObject3d; const { p } = manager.$actor.getGlobalPose(); position.lerp(p, fpsAlpha(hitMap.get(manager) ? 0.3 : 1)); position.x = p.x; position.z = p.z; } }); return () => { handle.cancel(); physxLoopPtr[0] = false; }; }, [getPhysXLoaded, getWorldPlayComputed]); //# sourceMappingURL=physxLoop.js.map