sandai-react
Version:
React components and utilities for the Sandai 3D AI Characters.
130 lines • 4.43 kB
TypeScript
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