openusd-explorer / src /motion.ts
ZIP Space Deployer
Deploy ZIP — 2026-10-26 20:15 UTC
0dfa89f
Raw History Blame Contribute Delete
1.64 kB
import {bodyMatrices,jointValue} from './vendor/kinematics.js';
export type MotionJoint={id:string;label?:string|null;name?:string|null;type?:string;home:number;far:number;range?:number[];body0?:string;body1?:string;partial?:boolean};
export function motionTitle(joint:MotionJoint,index:number){
const label=(joint.label||joint.name||'').replace(/_/g,' ').replace(/([a-z])([A-Z])/g,'$1 $2').trim();
if(/^hinged part\s*\d*$/i.test(label))return `Rotation ${index+1}`;
if(/^sliding part\s*\d*$/i.test(label))return `Slide ${index+1}`;
if(label&&!/^j\d+$|^joint\s*\d*$/i.test(label))return label[0].toUpperCase()+label.slice(1);
return `${joint.type==='prismatic'?'Slide':'Rotation'} ${index+1}`;
}
export function motionValue(joint:MotionJoint,progress:number){
const value=jointValue(joint,progress);
return joint.type==='prismatic'?`${Math.round(value*1000)/10} cm`:`${Math.round(value)}°`;
}
export function selectedPose(values:Record<string,number>,id:string,progress:number){
return {...values,[id]:Math.min(1,Math.max(0,Number.isFinite(progress)?progress:0))};
}
/** Compare resolved kinematics, so mimic joints and descendants are highlighted too. */
export function affectedBodies(articulation:any,id:string,values:Record<string,number>={}){
const start=bodyMatrices(articulation,selectedPose(values,id,0)) as Record<string,number[]>;
const samples=[.37,1].map(progress=>bodyMatrices(articulation,selectedPose(values,id,progress)) as Record<string,number[]>);
return new Set(Object.keys(start).filter(body=>samples.some(sample=>sample[body].some((v:number,i:number)=>Math.abs(v-start[body][i])>1e-7))));
}