UNPKG

sandai-react

Version:

React components and utilities for the Sandai 3D AI Characters.

130 lines 4.43 kB
import { VRM } from "@pixiv/three-vrm"; import { Vector3, Camera } from "three"; export declare class FocusDirectionManager { private _vrm; private _camera; private _isQuadruped; private _invertHeadDirection; private _previousDistanceToTarget?; constructor(vrm: VRM, camera: Camera); /** * Determines if the model is a quadruped (e.g. a horse, bear, etc.) * based on the angular difference between the hips' up vector and * the heads' direction vector (aka. lookAt vector) * * Since humanoid characters (bipeds) are the default, it will tend to * favor determining that the model is a humanoid by default. * * Humanoid models can generally have a difference between the expected 0° (straight up) * angle of the up vector of the hips of up to ~0.786 (Pi / 4), but typically have around 0.2, * as the hip bone is commonly placed "behind" the spine bone (on the z-axis). * * --- * * So instead of looking like this: * ```txt * ◯ ⮕ - head direction * ▿─┼─▿ * \│ \ * ┌┴┐ ⬆ - hips to spine * │ │ * __________________ * 0° (0 rad) * ``` * * --- * * They tend to look like this: * * ```txt * ◯ ⮕ - head direction * ▿─┼─▿ * \/ \ * ┌┴┐ ⬈ - hips to spine * │ │ * __________________ * ~15° (0.261 rad) * ``` * * To be safe, the default threshold value is set to 1 rad (PI / 3). * If you work with quadrupeds, you'll probably be fine, but you can lower this threshold * if the camera world position or lookAt position is messed up * * @param vrm - The VRM model * @param angleOffsetThreshold - The threshold for determining quadrupedality, which is * the delta between the expected 0° offset and the actual offset * @returns */ private _getIsQuadruped; /** * Determines the angle offset of the hips to the spine against the head direction. * * The expected armature is that of a humanoid, which will have a head direction * (aka. lookAt direction) perpendicular to the hips -> spine vector. * The angle is expected to be 90°, which will be subtracted from the calculated * vectors, optimally leaving the angle offset at 0° or at least close to 0° (0 rad) * for humanoid armatures. * * For Quadrupeds, this angle offset will be closer to 90° (~0.785 rad) * * ------------------ * * To illustrate: * * ```txt * ◯ ⮕ - head direction * ▿─┼─▿ * \│ \ * ┌┴┐ ⬆ - hips to spine * │ │ * __________________ * returns 0° (0 rad) | Math.abs(90° - 90°) * ``` * ------------------ * ```txt * * ◯ ⮕ - head direction * ┌─┬──┬┴┐ ⮕ - hips to spine * │ │ │ │ * __________________ * returns 90° (~0.785 rad) | Math.abs(0° - 90°) * ``` * * ------------------ * * If there is no position data in the normalized rest pose for the head, spine and hips, * the current world positions of the head, spine and hips will be used. * If those are undefined as well, the returned value will be 0. * * To get the head direction, it needs to be available through * `vrm.humanoid.getNormalizedBoneNode('head')` * If it is undefined, 0° will be returned. * * * @param vrm - The VRM instance * @returns Angle offset as described above in radians */ private _getRootToHeadAngleOffset; getInverseHeadDirection(opt: { trackCharacterLookAt: boolean; }): { headDirection?: undefined; headWorldPosition?: undefined; } | { headDirection: Vector3; headWorldPosition: Vector3; }; getTargetPosition(opt: { trackCharacterLookAt: boolean; cameraOffset: Vector3; orthographic?: boolean; static?: boolean; }): { targetPosition: Vector3; distanceToTarget: number; signedDistanceToTarget: number; headWorldPosition: Vector3; headDirection: Vector3; } | undefined; } //# sourceMappingURL=FocusDirectionManager.d.ts.map