File size: 1,224 Bytes
86758a1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | 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
);
}
|