lingo3d
Version:
Lingo3D is a React/Vue 3d game development framework that ships with a complete visual editor
83 lines • 3.57 kB
JavaScript
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