Release Healer Man 0.1.9
This commit is contained in:
1 parent
c245a199b6
commit
d060296ade
74 files changed
+5901
-334
No files matched your search
@@ -0,0 +1,63 @@
|
||||
import { SkinnedMesh, Vector3, type Object3D } from "three";
|
||||
import type { AvatarAttachmentPoint } from "./characterManifest";
|
||||
|
||||
export interface AvatarAttachmentTransform {
|
||||
readonly target: Object3D;
|
||||
readonly position: Vector3;
|
||||
readonly scale: Vector3;
|
||||
}
|
||||
|
||||
export interface AvatarAttachmentOptions {
|
||||
/** The manifest point is the authored origin of its referenced attachment joint. */
|
||||
readonly useTargetOrigin?: boolean;
|
||||
}
|
||||
|
||||
const safeScaleRatio = (rootScale: number, targetScale: number): number => (
|
||||
Number.isFinite(rootScale)
|
||||
&& Number.isFinite(targetScale)
|
||||
&& Math.abs(targetScale) > 1e-6
|
||||
? rootScale / targetScale
|
||||
: 1
|
||||
);
|
||||
|
||||
function attachmentScale(root: Object3D, target: Object3D): Vector3 {
|
||||
const rootScale = root.getWorldScale(new Vector3());
|
||||
const targetScale = target.getWorldScale(new Vector3());
|
||||
return new Vector3(
|
||||
safeScaleRatio(rootScale.x, targetScale.x),
|
||||
safeScaleRatio(rootScale.y, targetScale.y),
|
||||
safeScaleRatio(rootScale.z, targetScale.z),
|
||||
);
|
||||
}
|
||||
|
||||
export function findAvatarSkinBone(root: Object3D, boneIndex: number): Object3D | null {
|
||||
let bone: Object3D | null = null;
|
||||
root.traverse((node) => {
|
||||
if (bone) return;
|
||||
const skinnedMesh = node as SkinnedMesh;
|
||||
if (!skinnedMesh.isSkinnedMesh) return;
|
||||
bone = skinnedMesh.skeleton.bones[boneIndex] ?? null;
|
||||
});
|
||||
return bone;
|
||||
}
|
||||
|
||||
/** Converts a manifest point from avatar-local space into its target bone. */
|
||||
export function resolveAvatarAttachmentPoint(
|
||||
root: Object3D,
|
||||
point: AvatarAttachmentPoint | undefined,
|
||||
fallbackTarget: Object3D | null,
|
||||
options: AvatarAttachmentOptions = {},
|
||||
): AvatarAttachmentTransform | null {
|
||||
const skinBone = point ? findAvatarSkinBone(root, point.bone) : null;
|
||||
const target = skinBone ?? fallbackTarget;
|
||||
if (!target) return null;
|
||||
root.updateWorldMatrix(true, true);
|
||||
const scale = attachmentScale(root, target);
|
||||
if (!point || (skinBone && options.useTargetOrigin)) {
|
||||
return { target, position: new Vector3(), scale };
|
||||
}
|
||||
|
||||
const position = root.localToWorld(new Vector3(...point.position));
|
||||
target.worldToLocal(position);
|
||||
return { target, position, scale };
|
||||
}
|
||||
Reference in new issue
Block a user