Initial Dansori character workspace
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
# Rig.md — 스켈레톤 정의 (`rig.json`, 풀캔버스 모드)
|
||||
|
||||
경량 리그 뼈대. 뷰어(`../07_Viewer/index.html`)와 WPF 앱이 동일하게 읽는다.
|
||||
|
||||
## 모델: 풀캔버스 (full-canvas)
|
||||
- 각 파츠 PNG = **520×900 풀캔버스**, 파츠가 **마스터 제자리**에 있음.
|
||||
- 렌더러는 파츠를 **원점(0,0)에 그리고, 관절 피벗을 중심으로 회전**한다.
|
||||
- **휴지 자세(모든 rot/tx/ty=0)** 에서는 모든 월드행렬 = 단위행렬 → 16장 스택 = 마스터 복원.
|
||||
- 그래서 **위치 앵커 튜닝이 필요 없다**(위치는 이미 파츠에 baked).
|
||||
|
||||
## 본 계층
|
||||
```
|
||||
pelvis (root)
|
||||
├─ chest
|
||||
│ ├─ neck ─ head
|
||||
│ ├─ upperarm_r ─ forearm_r ─ hand_r (캐릭터 오른팔 = 화면 왼쪽)
|
||||
│ └─ upperarm_l ─ forearm_l ─ hand_l
|
||||
├─ thigh_r ─ shin_r ─ foot_r
|
||||
└─ thigh_l ─ shin_l ─ foot_l
|
||||
```
|
||||
|
||||
## 필드 (bones[])
|
||||
| 필드 | 의미 |
|
||||
|---|---|
|
||||
| `name` | 본 이름(= 애니메이션 트랙 키) |
|
||||
| `parent` | 부모(root=null). 배열은 부모 먼저 |
|
||||
| `pivot` `[x,y]` | **회전 중심 = 관절 좌표**(520×900 캔버스 픽셀). **파츠 오버랩 centroid로 자동 산출** |
|
||||
| `z` | 그리기 순서(작을수록 뒤) |
|
||||
| `image` | 파츠 PNG(`imageBase`+이 값), 520×900 풀캔버스 |
|
||||
|
||||
## FK (렌더 수식)
|
||||
```
|
||||
world[bone] = world[parent] · Mlocal
|
||||
Mlocal = T(tx,ty) · T(pivot) · R(rot) · T(-pivot) // rot/tx/ty = 애니메이션 delta
|
||||
draw: setTransform(world); drawImage(part, 0, 0) // 원점에 그림
|
||||
```
|
||||
|
||||
## 피벗 산출(자동)
|
||||
`pivot(bone) = centroid( opaque(bone) ∩ opaque(parent) )` — 인접 파츠의 오버랩 영역 무게중심 = 관절. (스크립트로 1회 산출해 여기 박음. 파츠 교체 시 재산출.)
|
||||
|
||||
## 검증됨
|
||||
- 16파츠 스택 = 마스터(missed 0 / extra 0.03%).
|
||||
- 자동 피벗으로 `dance_idle` 재생 시 관절이 자연스럽게 회전(헤드리스 렌더 t=0/0.5/1.0/1.5 확인).
|
||||
|
||||
## 튜닝 (필요 시)
|
||||
- 관절 회전축이 어긋나면 해당 `pivot` 미세조정. 겹침 순서는 `z`.
|
||||
- 큰 각도에서 이음새가 보이면 애니 진폭↓ 또는 후속 mesh-warp(`../02_Architecture/Limits_and_Mitigations.md`).
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 142 KiB |
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"pelvis": [
|
||||
259.6,
|
||||
363.4
|
||||
],
|
||||
"chest": [
|
||||
259.6,
|
||||
363.4
|
||||
],
|
||||
"neck": [
|
||||
262.0,
|
||||
229.3
|
||||
],
|
||||
"head": [
|
||||
259.8,
|
||||
209.3
|
||||
],
|
||||
"upperarm_r": [
|
||||
174.2,
|
||||
287.2
|
||||
],
|
||||
"forearm_r": [
|
||||
137.3,
|
||||
358.0
|
||||
],
|
||||
"hand_r": [
|
||||
134.2,
|
||||
400.8
|
||||
],
|
||||
"upperarm_l": [
|
||||
346.0,
|
||||
286.5
|
||||
],
|
||||
"forearm_l": [
|
||||
382.9,
|
||||
357.6
|
||||
],
|
||||
"hand_l": [
|
||||
389.6,
|
||||
400.6
|
||||
],
|
||||
"thigh_r": [
|
||||
226.3,
|
||||
455.0
|
||||
],
|
||||
"shin_r": [
|
||||
233.3,
|
||||
609.1
|
||||
],
|
||||
"foot_r": [
|
||||
236.5,
|
||||
729.4
|
||||
],
|
||||
"thigh_l": [
|
||||
294.1,
|
||||
455.0
|
||||
],
|
||||
"shin_l": [
|
||||
286.9,
|
||||
609.1
|
||||
],
|
||||
"foot_l": [
|
||||
283.9,
|
||||
729.5
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "LeeSori",
|
||||
"canvas": { "width": 520, "height": 900 },
|
||||
"imageBase": "../03_Assets/Parts/Images/",
|
||||
"mode": "fullcanvas",
|
||||
"note": "Full-canvas parts: each PNG is 520x900 with the part already at its master position. Renderer draws each image at the ORIGIN (0,0) and rotates it about its pivot (the joint). pivot = auto-derived centroid of the opaque overlap between the part and its parent. At rest (all rot/tx/ty = 0) every world matrix is identity, so stacking reproduces the master.",
|
||||
"bones": [
|
||||
{ "name": "pelvis", "parent": null, "pivot": [259.6, 363.4], "z": 6, "image": "sori_part_pelvis.png" },
|
||||
{ "name": "chest", "parent": "pelvis", "pivot": [259.6, 363.4], "z": 8, "image": "sori_part_chest.png" },
|
||||
{ "name": "neck", "parent": "chest", "pivot": [262.0, 229.3], "z": 9, "image": "sori_part_neck.png" },
|
||||
{ "name": "head", "parent": "neck", "pivot": [259.8, 209.3], "z": 10, "image": "sori_part_head.png" },
|
||||
|
||||
{ "name": "upperarm_r", "parent": "chest", "pivot": [174.2, 287.2], "z": 5, "image": "sori_part_upperarm_r.png" },
|
||||
{ "name": "forearm_r", "parent": "upperarm_r", "pivot": [137.3, 358.0], "z": 5, "image": "sori_part_forearm_r.png" },
|
||||
{ "name": "hand_r", "parent": "forearm_r", "pivot": [134.2, 400.8], "z": 5, "image": "sori_part_hand_r.png" },
|
||||
|
||||
{ "name": "upperarm_l", "parent": "chest", "pivot": [346.0, 286.5], "z": 12, "image": "sori_part_upperarm_l.png" },
|
||||
{ "name": "forearm_l", "parent": "upperarm_l", "pivot": [382.9, 357.6], "z": 12, "image": "sori_part_forearm_l.png" },
|
||||
{ "name": "hand_l", "parent": "forearm_l", "pivot": [389.6, 400.6], "z": 13, "image": "sori_part_hand_l.png" },
|
||||
|
||||
{ "name": "thigh_r", "parent": "pelvis", "pivot": [226.3, 455.0], "z": 4, "image": "sori_part_thigh_r.png" },
|
||||
{ "name": "shin_r", "parent": "thigh_r", "pivot": [233.3, 609.1], "z": 3, "image": "sori_part_shin_r.png" },
|
||||
{ "name": "foot_r", "parent": "shin_r", "pivot": [236.5, 729.4], "z": 2, "image": "sori_part_foot_r.png" },
|
||||
|
||||
{ "name": "thigh_l", "parent": "pelvis", "pivot": [294.1, 455.0], "z": 4, "image": "sori_part_thigh_l.png" },
|
||||
{ "name": "shin_l", "parent": "thigh_l", "pivot": [286.9, 609.1], "z": 3, "image": "sori_part_shin_l.png" },
|
||||
{ "name": "foot_l", "parent": "shin_l", "pivot": [283.9, 729.5], "z": 2, "image": "sori_part_foot_l.png" }
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user