humanoid-v1.js 3.31 KB
// humanoid-v1.js — 全角色共享的固定骨架定义(RigDefinition)。
// 移植自旧原型 client/js/stage/rig/humanoid-v1.js(算法已验证,本处仅搬运成纯数据)。
//
// 坐标系:Pixi 习惯,+y 向下,角度单位「度」(顺时针为正),在 rig 局部画布坐标里描述。
// root 位于双脚之间、贴地面(y=0),身体向上为负 y。
//
// 这是一份「与具体角色无关」的常量:所有角色复用同一棵骨骼树和同一批 slot。
// 角色差异只体现在 CharacterSkin(每个 slot 贴哪张图 + 对齐元数据),属于 @drama/assets,不在本包。
//
// 约定:
//  - bone.pos 是相对父骨骼的局部坐标(setup pose)
//  - bone.rotation 是 setup pose 的局部旋转(度)
//  - slot.bone 指明该部件挂在哪根骨骼上(随骨骼变换)
//  - slot.zOrder 是全局渲染层级(低=靠后),用于解决 2.5D 遮挡(左臂在身前/右臂在身后)
//
// bones 顺序保证「父先于子」:root 在最前,每根子骨都排在其父之后,core 可一次遍历求世界变换。

/** @type {import('../types.js').RigDefinition} */
export const HUMANOID_V1 = {
  id: 'humanoid_v1',
  // rig 设计基准画布:AI 出部件图时按这个坐标系/尺度出图。
  canvas: { width: 400, height: 620 },

  bones: [
    { name: 'root', parent: null, pos: { x: 0, y: 0 }, rotation: 0 },
    { name: 'hip', parent: 'root', pos: { x: 0, y: -250 }, rotation: 0 },
    { name: 'torso', parent: 'hip', pos: { x: 0, y: 0 }, rotation: 0 },
    { name: 'neck', parent: 'torso', pos: { x: 0, y: -150 }, rotation: 0 },
    { name: 'head', parent: 'neck', pos: { x: 0, y: -22 }, rotation: 0 },

    // 左 = 角色自身左 = 屏幕右侧(facing 默认朝向观众)。这里 _l/_r 直接用屏幕语义命名以免混淆:
    // upper_arm_l 渲染在屏幕左,upper_arm_r 渲染在屏幕右。
    { name: 'upper_arm_l', parent: 'torso', pos: { x: 48, y: -138 }, rotation: 6 },
    { name: 'lower_arm_l', parent: 'upper_arm_l', pos: { x: 0, y: 78 }, rotation: 0 },
    { name: 'upper_arm_r', parent: 'torso', pos: { x: -48, y: -138 }, rotation: -6 },
    { name: 'lower_arm_r', parent: 'upper_arm_r', pos: { x: 0, y: 78 }, rotation: 0 },

    { name: 'thigh_l', parent: 'hip', pos: { x: 24, y: 0 }, rotation: 0 },
    { name: 'shin_l', parent: 'thigh_l', pos: { x: 0, y: 118 }, rotation: 0 },
    { name: 'thigh_r', parent: 'hip', pos: { x: -24, y: 0 }, rotation: 0 },
    { name: 'shin_r', parent: 'thigh_r', pos: { x: 0, y: 118 }, rotation: 0 },
  ],

  // 渲染层级(低 z 靠后)。右臂/右腿在身后,左臂/左腿在身前。
  slots: [
    { name: 'upper_arm_r', bone: 'upper_arm_r', zOrder: 1 },
    { name: 'lower_arm_r', bone: 'lower_arm_r', zOrder: 2 },
    { name: 'thigh_r', bone: 'thigh_r', zOrder: 3 },
    { name: 'shin_r', bone: 'shin_r', zOrder: 4 },
    { name: 'thigh_l', bone: 'thigh_l', zOrder: 5 },
    { name: 'shin_l', bone: 'shin_l', zOrder: 6 },
    { name: 'torso', bone: 'torso', zOrder: 10 },
    { name: 'neck', bone: 'neck', zOrder: 11 },
    { name: 'head', bone: 'head', zOrder: 20 },
    { name: 'face', bone: 'head', zOrder: 25 }, // 表情挂在 head 上,随头动,贴图独立换
    { name: 'upper_arm_l', bone: 'upper_arm_l', zOrder: 30 },
    { name: 'lower_arm_l', bone: 'lower_arm_l', zOrder: 31 },
  ],
}