65 lines
1.9 KiB
TypeScript
65 lines
1.9 KiB
TypeScript
import type {
|
|
HandTrackingHand,
|
|
HandTrackingLandmark,
|
|
} from "@/types/handTracking/handTracking";
|
|
|
|
function lerp(previous: number, next: number, factor: number): number {
|
|
return previous * (1 - factor) + next * factor;
|
|
}
|
|
|
|
function smoothLandmark(
|
|
previous: HandTrackingLandmark,
|
|
next: HandTrackingLandmark,
|
|
factor: number,
|
|
): HandTrackingLandmark {
|
|
return {
|
|
x: lerp(previous.x, next.x, factor),
|
|
y: lerp(previous.y, next.y, factor),
|
|
z: lerp(previous.z, next.z, factor),
|
|
};
|
|
}
|
|
|
|
function smoothHand(
|
|
previous: HandTrackingHand,
|
|
next: HandTrackingHand,
|
|
factor: number,
|
|
): HandTrackingHand {
|
|
return {
|
|
...next,
|
|
x: lerp(previous.x, next.x, factor),
|
|
y: lerp(previous.y, next.y, factor),
|
|
z: lerp(previous.z, next.z, factor),
|
|
landmarks: next.landmarks.map((landmark, index) => {
|
|
const previousLandmark = previous.landmarks[index];
|
|
if (!previousLandmark) return landmark;
|
|
return smoothLandmark(previousLandmark, landmark, factor);
|
|
}),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Apply an exponential moving average to the landmark positions of each
|
|
* detected hand. MediaPipe lands per-frame positions with noticeable
|
|
* jitter (especially at ~10fps), and feeding those raw values into the
|
|
* scene makes both the glove rig and any grabbed object tremble.
|
|
*
|
|
* `factor` is the weight given to the latest sample (0 = previous frame
|
|
* only, 1 = no smoothing). Hands are matched between frames by
|
|
* handedness so left/right don't bleed into each other.
|
|
*/
|
|
export function smoothHands(
|
|
previousHands: HandTrackingHand[],
|
|
nextHands: HandTrackingHand[],
|
|
factor: number,
|
|
): HandTrackingHand[] {
|
|
if (factor >= 1) return nextHands;
|
|
|
|
return nextHands.map((next) => {
|
|
const previous = previousHands.find(
|
|
(candidate) => candidate.handedness === next.handedness,
|
|
);
|
|
if (!previous) return next;
|
|
return smoothHand(previous, next, factor);
|
|
});
|
|
}
|