flyyt / src /rigMetadata.ts
gpue's picture
Deploy practice-mode visualizer as Docker Space
d9bb6b1 verified
Raw History Blame Contribute Delete
2.38 kB
import raw from "./assets/rig-metadata.json";
export type LegName = "lf" | "lm" | "lh" | "rf" | "rm" | "rh";
export type WingSide = "l" | "r";
export interface JointInfo {
node: string;
axis: [number, number, number];
/** Biomechanical range in radians (wing-hinge joints only). */
range?: [number, number];
}
export const GROUND_OFFSET_MM: number = raw.groundOffsetMm;
export const EXTENT_MM: [number, number, number] = raw.extentMm as [number, number, number];
// Angle (atan2(x, z) convention) of the rig's own bind-pose forward
// direction. The mesh does not necessarily face +Z at rotation.y=0, so this
// must be subtracted when turning the model to face its direction of
// travel, or it visually appears to strafe instead of walking forward.
export const FACING_OFFSET_RAD: number = raw.facingOffsetRad;
export const LEGS: Record<LegName, string[]> = raw.legs;
// Each wing is one MuJoCo body (child of c_thorax) with 3 hinge DOFs: yaw =
// stroke angle (forward/back sweep), roll = deviation angle (up/down),
// pitch = rotation angle (blade twist) -- the real biomechanical wing-hinge
// axes from the flybody model, not a simplified single-axis flap.
export const WINGS: Record<WingSide, string[]> = raw.wings;
export const JOINTS: Record<string, JointInfo> = raw.joints as unknown as Record<string, JointInfo>;
const LEG_LEVEL_NODES: Record<"ThC" | "CTr" | "FTi" | "TiTa", (leg: LegName) => [string, string]> = {
ThC: (leg) => ["c_thorax", `${leg}_coxa`],
CTr: (leg) => [`${leg}_coxa`, `${leg}_trochanterfemur`],
FTi: (leg) => [`${leg}_trochanterfemur`, `${leg}_tibia`],
TiTa: (leg) => [`${leg}_tibia`, `${leg}_tarsus1`],
};
/**
* Builds a joint name from its anatomical level + axis rather than relying
* on array position in LEGS[leg] — different fly bodies define their DOFs in
* different orders (e.g. flybody is ThC yaw/roll/pitch, NeuroMechFly is
* yaw/pitch/roll), so positional destructuring would silently drive the
* wrong joint if the underlying rig changes.
*/
export function legJointName(
leg: LegName,
level: "ThC" | "CTr" | "FTi" | "TiTa",
axis: "yaw" | "roll" | "pitch",
): string {
const [parent, child] = LEG_LEVEL_NODES[level](leg);
return `${parent}-${child}-${axis}`;
}
export function wingJointName(side: WingSide, axis: "yaw" | "roll" | "pitch"): string {
return `c_thorax-${side}_wing-${axis}`;
}