world-simulator / frontend /src /scene /useCompletePreviousTickPosition.ts
DeltaZN
feat: Implement deterministic runtime configuration & small visual fixes
86758a1
Raw
History Blame Contribute Delete
1.22 kB
import { useLayoutEffect, useRef } from "react";
import type { RefObject } from "react";
import type { Group } from "three";
type ActorPosition = readonly [number, number, number];
type CompletePreviousTickPositionOptions = {
groupRef: RefObject<Group | null>;
tick: number;
target: ActorPosition;
};
const SETTLED_DISTANCE = 0.025;
export function useCompletePreviousTickPosition({
groupRef,
tick,
target,
}: CompletePreviousTickPositionOptions) {
const previousTickRef = useRef(tick);
const previousTargetRef = useRef<ActorPosition>(target);
useLayoutEffect(() => {
const group = groupRef.current;
const previousTarget = previousTargetRef.current;
if (group && tick !== previousTickRef.current && !isAtPosition(group, previousTarget)) {
group.position.set(previousTarget[0], previousTarget[1], previousTarget[2]);
}
previousTickRef.current = tick;
previousTargetRef.current = target;
}, [groupRef, target, tick]);
}
function isAtPosition(group: Group, target: ActorPosition): boolean {
return (
Math.abs(group.position.y - target[1]) <= SETTLED_DISTANCE &&
Math.hypot(group.position.x - target[0], group.position.z - target[2]) <= SETTLED_DISTANCE
);
}