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
  );
}