pyjallib 0.1.12__tar.gz → 0.1.13__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyjallib-0.1.12 → pyjallib-0.1.13}/.gitignore +11 -11
- {pyjallib-0.1.12 → pyjallib-0.1.13}/.python-version +1 -1
- {pyjallib-0.1.12 → pyjallib-0.1.13}/PKG-INFO +1 -1
- pyjallib-0.1.13/PRD/BIPPY_/353/260/224/354/235/264/355/214/250/353/223/234_/354/203/235/354/204/261_/353/266/204/354/204/235.md +440 -0
- pyjallib-0.1.13/PRD/PyJalLib_Mocap_Module_PRD.md +361 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/pyproject.toml +1 -1
- pyjallib-0.1.13/ref/BIPPY.ms +1555 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/__init__.py +1 -1
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/__init__.py +8 -4
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/anim.py +84 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/autoClavicle.py +1 -1
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/bip.py +89 -79
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/bone.py +84 -22
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/boneChain.py +19 -22
- pyjallib-0.1.13/src/pyjallib/max/fbxHandler.py +215 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/groinBone.py +3 -3
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/header.py +10 -13
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/hip.py +4 -4
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/kneeBone.py +44 -20
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/layer.py +12 -6
- pyjallib-0.1.13/src/pyjallib/max/mocap.py +376 -0
- pyjallib-0.1.13/src/pyjallib/max/rootMotion.py +639 -0
- pyjallib-0.1.13/src/pyjallib/max/toolManager.py +92 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/twistBone.py +5 -1
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/volumeBone.py +2 -1
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/perforce.py +34 -0
- pyjallib-0.1.13/tests/animNodeTest.py +24 -0
- pyjallib-0.1.13/tests/fbxExportTest.py +26 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/uv.lock +1 -1
- {pyjallib-0.1.12 → pyjallib-0.1.13}/README.md +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/docs/index.html +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/docs/pyjallib/max.html +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/docs/pyjallib/namePart.html +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/docs/pyjallib/nameToPath.html +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/docs/pyjallib/naming.html +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/docs/pyjallib/namingConfig.html +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/docs/pyjallib/p4module.html +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/docs/pyjallib/perforce.html +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/docs/pyjallib/reloadModules.html +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/docs/pyjallib.html +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/docs/search.js +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/generate_docs.ps1 +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/ConfigFiles/namingConfig.json +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/ConfigFiles/3DSMaxNamingConfig.json +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/ConfigFiles/Default_3DSMaxNamingConfig.json +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/align.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/constraint.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/helper.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/link.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/macro/jal_macro_align.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/macro/jal_macro_bone.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/macro/jal_macro_constraint.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/macro/jal_macro_helper.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/macro/jal_macro_link.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/macro/jal_macro_select.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/mirror.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/morph.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/name.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/select.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/skin.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/max/ui/Container.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/namePart.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/nameToPath.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/naming.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/namingConfig.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/py.typed +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/src/pyjallib/reloadModules.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/tests/autoclavicleTest.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/tests/globalVarTest.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/tests/moduleImportTest.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/tests/p4Test.py +0 -0
- {pyjallib-0.1.12 → pyjallib-0.1.13}/tests/volumePreserveBoneTest.py +0 -0
@@ -1,12 +1,12 @@
|
|
1
|
-
# Python-generated files
|
2
|
-
__pycache__/
|
3
|
-
*.py[oc]
|
4
|
-
build/
|
5
|
-
dist/
|
6
|
-
wheels/
|
7
|
-
*.egg-info
|
8
|
-
|
9
|
-
# Virtual environments
|
10
|
-
.venv/
|
11
|
-
|
1
|
+
# Python-generated files
|
2
|
+
__pycache__/
|
3
|
+
*.py[oc]
|
4
|
+
build/
|
5
|
+
dist/
|
6
|
+
wheels/
|
7
|
+
*.egg-info
|
8
|
+
|
9
|
+
# Virtual environments
|
10
|
+
.venv/
|
11
|
+
|
12
12
|
.vscode/
|
@@ -1 +1 @@
|
|
1
|
-
3.10.14
|
1
|
+
3.10.14
|
@@ -0,0 +1,440 @@
|
|
1
|
+
# BIPPY MaxScript 바이패드(Biped) 생성 분석 문서
|
2
|
+
|
3
|
+
## 개요
|
4
|
+
|
5
|
+
BIPPY는 3DS Max에서 FBX 파일의 본(bone) 데이터를 Biped 시스템으로 변환하는 MaxScript 도구입니다. 본 문서는 바이패드를 최초로 생성하는 핵심 메커니즘을 분석합니다.
|
6
|
+
|
7
|
+
## 주요 함수
|
8
|
+
|
9
|
+
### 1. assess_and_create_biped() 함수
|
10
|
+
**위치:** 576-703 라인
|
11
|
+
**목적:** FBX 본 구조를 분석하여 적절한 Biped를 생성
|
12
|
+
|
13
|
+
#### 1.1 바이패드 높이 계산
|
14
|
+
```maxscript
|
15
|
+
bip_height = (distance FBX_convert_str.FBX_array[140] FBX_convert_str.FBX_array[13])*1.8
|
16
|
+
```
|
17
|
+
- FBX_array[140]: 발목 본 위치
|
18
|
+
- FBX_array[13]: 목 본 위치
|
19
|
+
- 두 본 사이의 거리에 1.8을 곱하여 바이패드 전체 높이 결정
|
20
|
+
|
21
|
+
#### 1.2 본 구조 분석 및 카운팅
|
22
|
+
|
23
|
+
##### 척추(Spine) 본 카운팅
|
24
|
+
```maxscript
|
25
|
+
number_of_spines = 0
|
26
|
+
for c = 3 to 12 do (
|
27
|
+
if FBX_convert_str.FBX_array[c] != undefined do(
|
28
|
+
number_of_spines += 1
|
29
|
+
)
|
30
|
+
)
|
31
|
+
```
|
32
|
+
- 인덱스 3-12: 척추 본들
|
33
|
+
- 존재하는 척추 본의 개수를 계산
|
34
|
+
|
35
|
+
##### 다리(Leg) 본 카운팅
|
36
|
+
```maxscript
|
37
|
+
number_of_legs = 0
|
38
|
+
for c = 137 to 140 do (
|
39
|
+
if FBX_convert_str.FBX_array[c] != undefined do(
|
40
|
+
number_of_legs += 1
|
41
|
+
)
|
42
|
+
)
|
43
|
+
```
|
44
|
+
- 인덱스 137-140: 다리 본들
|
45
|
+
- 각 다리의 관절 개수 계산
|
46
|
+
|
47
|
+
##### 꼬리(Tail) 본 카운팅
|
48
|
+
```maxscript
|
49
|
+
number_of_tails = 0
|
50
|
+
for c = 165 to 189 do (
|
51
|
+
if FBX_convert_str.FBX_array[c] != undefined do(
|
52
|
+
number_of_tails += 1
|
53
|
+
)
|
54
|
+
)
|
55
|
+
```
|
56
|
+
|
57
|
+
##### 목(Neck) 본 카운팅
|
58
|
+
```maxscript
|
59
|
+
number_of_necks = 0
|
60
|
+
for c = 13 to 37 do (
|
61
|
+
if FBX_convert_str.FBX_array[c] != undefined do(
|
62
|
+
number_of_necks += 1
|
63
|
+
)
|
64
|
+
)
|
65
|
+
```
|
66
|
+
|
67
|
+
##### 포니테일(Ponytail) 본 카운팅
|
68
|
+
```maxscript
|
69
|
+
// 포니테일 1
|
70
|
+
number_of_ponytails1 = 0
|
71
|
+
for c = 39 to 63 do (
|
72
|
+
if FBX_convert_str.FBX_array[c] != undefined do(
|
73
|
+
number_of_ponytails1 += 1
|
74
|
+
)
|
75
|
+
)
|
76
|
+
|
77
|
+
// 포니테일 2
|
78
|
+
number_of_ponytails2 = 0
|
79
|
+
for c = 64 to 88 do (
|
80
|
+
if FBX_convert_str.FBX_array[c] != undefined do(
|
81
|
+
number_of_ponytails2 += 1
|
82
|
+
)
|
83
|
+
)
|
84
|
+
```
|
85
|
+
|
86
|
+
##### 손가락(Finger) 본 카운팅
|
87
|
+
```maxscript
|
88
|
+
number_of_fingers = 0
|
89
|
+
|
90
|
+
// 각 손가락별로 체크 (엄지, 검지, 중지, 약지, 새끼)
|
91
|
+
if FBX_convert_str.FBX_array[93] != undefined do(
|
92
|
+
number_of_fingers += 1
|
93
|
+
)
|
94
|
+
// ... (다른 손가락들도 동일한 방식)
|
95
|
+
```
|
96
|
+
|
97
|
+
##### 발가락(Toe) 본 카운팅
|
98
|
+
```maxscript
|
99
|
+
number_of_toes = 0
|
100
|
+
if FBX_convert_str.FBX_array[141] != undefined do(
|
101
|
+
number_of_toes += 1
|
102
|
+
)
|
103
|
+
// ... (다른 발가락들도 동일한 방식)
|
104
|
+
```
|
105
|
+
|
106
|
+
##### Props 본 체크
|
107
|
+
```maxscript
|
108
|
+
number_of_prop1 = false
|
109
|
+
if FBX_convert_str.FBX_array[200] != undefined do(
|
110
|
+
number_of_prop1 = true
|
111
|
+
)
|
112
|
+
// Prop2, Prop3도 동일한 방식
|
113
|
+
```
|
114
|
+
|
115
|
+
#### 1.3 바이패드 생성
|
116
|
+
```maxscript
|
117
|
+
FBX_convert_str.bipObj = biped.createNew bip_height 0 [0,0,0] \
|
118
|
+
spineLinks:number_of_spines \
|
119
|
+
legLinks:number_of_legs \
|
120
|
+
tailLinks:number_of_tails \
|
121
|
+
ponyTail1Links:number_of_ponytails1 \
|
122
|
+
neckLinks:number_of_necks \
|
123
|
+
ponyTail2Links:number_of_ponytails2 \
|
124
|
+
fingers:number_of_fingers \
|
125
|
+
fingerLinks:number_of_fingerlinks \
|
126
|
+
toes:number_of_toes \
|
127
|
+
toeLinks:number_of_toelinks \
|
128
|
+
prop1Exists:number_of_prop1 \
|
129
|
+
prop2Exists:number_of_prop2 \
|
130
|
+
prop3Exists:number_of_prop3
|
131
|
+
```
|
132
|
+
|
133
|
+
이 코드는 3DS Max의 `biped.createNew` 명령을 사용하여:
|
134
|
+
- 계산된 높이로 바이패드 생성
|
135
|
+
- 위치: [0,0,0]
|
136
|
+
- 분석된 본 구조에 맞춰 각 부위별 관절 수 설정
|
137
|
+
|
138
|
+
#### 1.4 본 매핑 배열 생성
|
139
|
+
```maxscript
|
140
|
+
local file = (getDir #userscripts + "\\Bippy/Bip.btf")
|
141
|
+
// BTF 파일에서 바이패드 본 이름들을 읽어옴
|
142
|
+
nam = FBX_convert_str.bipObj.name
|
143
|
+
FBX_convert_str.retarget_array[1] = FBX_convert_str.bipObj
|
144
|
+
|
145
|
+
for bI = 2 to FBX_convert_str.boneNum do(
|
146
|
+
name_Temp = "$'"+nam+" "+(readLine fileIO)+"'"
|
147
|
+
if FBX_convert_str.FBX_array[bI] != undefined do(
|
148
|
+
FBX_convert_str.retarget_array[bI] = temp = execute(name_Temp)
|
149
|
+
)
|
150
|
+
)
|
151
|
+
```
|
152
|
+
|
153
|
+
### 2. resize_biped() 함수
|
154
|
+
**위치:** 704-893 라인
|
155
|
+
**목적:** 생성된 바이패드를 FBX 본 크기에 맞춰 조정
|
156
|
+
|
157
|
+
#### 2.1 Figure Mode 활성화
|
158
|
+
```maxscript
|
159
|
+
FBX_convert_str.biped_ctrl = FBX_convert_str.bipObj.transform.controller
|
160
|
+
FBX_convert_str.biped_ctrl.figureMode = true
|
161
|
+
```
|
162
|
+
|
163
|
+
#### 2.2 각 부위별 크기 조정
|
164
|
+
|
165
|
+
##### 루트(Root) 및 펠비스(Pelvis) 조정
|
166
|
+
```maxscript
|
167
|
+
-- 루트 본의 위치와 회전 설정
|
168
|
+
biped.setTransform FBX_convert_str.retarget_array[1] #pos (FBX_convert_str.FBX_array[1].transform.pos) True
|
169
|
+
biped.setTransform FBX_convert_str.retarget_array[1] #rotation (FBX_convert_str.FBX_array[1].transform.rotation) True
|
170
|
+
|
171
|
+
-- 펠비스 크기 조정 (FBX_array[2]는 펠비스, FBX_array[137]은 왼쪽 다리)
|
172
|
+
local temp = (distance FBX_convert_str.FBX_array[2] FBX_convert_str.FBX_array[137])*2
|
173
|
+
biped.setTransform FBX_convert_str.retarget_array[2] #scale ([temp,temp,temp]) True
|
174
|
+
```
|
175
|
+
|
176
|
+
##### 척추(Spine) 본 조정
|
177
|
+
```maxscript
|
178
|
+
-- 척추 본들 (인덱스 3-12, 최대 10개)
|
179
|
+
for i = 1 to 10 do(
|
180
|
+
if FBX_convert_str.FBX_array[i+2] != undefined do(
|
181
|
+
if FBX_convert_str.FBX_array[i+3] != undefined then (
|
182
|
+
-- 다음 척추 본이 있으면 그 사이의 거리 측정
|
183
|
+
local temp = distance FBX_convert_str.FBX_array[i+2] FBX_convert_str.FBX_array[i+3]
|
184
|
+
biped.setTransform FBX_convert_str.retarget_array[i+2] #scale ([temp,temp,temp]) True
|
185
|
+
)else(
|
186
|
+
-- 마지막 척추 본이면 목까지의 거리 측정 (FBX_array[13]은 첫 번째 목 본)
|
187
|
+
local temp = distance FBX_convert_str.FBX_array[i+2] FBX_convert_str.FBX_array[13]
|
188
|
+
biped.setTransform FBX_convert_str.retarget_array[i+2] #scale ([temp,temp,temp]) True
|
189
|
+
)
|
190
|
+
)
|
191
|
+
)
|
192
|
+
```
|
193
|
+
|
194
|
+
##### 목(Neck) 본 조정
|
195
|
+
```maxscript
|
196
|
+
-- 목 본들 (인덱스 13-37, 최대 25개)
|
197
|
+
for i = 1 to 25 do(
|
198
|
+
if FBX_convert_str.FBX_array[i+12] != undefined do(
|
199
|
+
if FBX_convert_str.FBX_array[i+13] != undefined then (
|
200
|
+
-- 다음 목 본이 있으면 그 사이의 거리 측정
|
201
|
+
local temp = distance FBX_convert_str.FBX_array[i+12] FBX_convert_str.FBX_array[i+13]
|
202
|
+
biped.setTransform FBX_convert_str.retarget_array[i+12] #scale ([temp,temp,temp]) True
|
203
|
+
)else(
|
204
|
+
-- 마지막 목 본이면 머리까지의 거리 측정 (FBX_array[38]은 머리)
|
205
|
+
local temp = distance FBX_convert_str.FBX_array[i+12] FBX_convert_str.FBX_array[38]
|
206
|
+
biped.setTransform FBX_convert_str.retarget_array[i+12] #scale ([temp,temp,temp]) True
|
207
|
+
)
|
208
|
+
)
|
209
|
+
)
|
210
|
+
```
|
211
|
+
|
212
|
+
##### 포니테일 1 본 조정
|
213
|
+
```maxscript
|
214
|
+
-- 첫 번째 포니테일 (인덱스 39-63)
|
215
|
+
for i = 1 to 25 do(
|
216
|
+
if FBX_convert_str.FBX_array[i+38] != undefined do(
|
217
|
+
if (FBX_convert_str.FBX_array[i+39] != undefined) and (FBX_convert_str.FBX_array[i+39].parent == FBX_convert_str.FBX_array[i+38]) then (
|
218
|
+
-- 다음 포니테일 본이 있고 부모-자식 관계가 맞으면
|
219
|
+
local temp = distance FBX_convert_str.FBX_array[i+38] FBX_convert_str.FBX_array[i+39]
|
220
|
+
biped.setTransform FBX_convert_str.retarget_array[i+38] #scale ([temp,temp,temp]) True
|
221
|
+
)else(
|
222
|
+
-- 그렇지 않으면 이전 본과의 거리 사용
|
223
|
+
local temp = distance FBX_convert_str.FBX_array[i+37] FBX_convert_str.FBX_array[i+38]
|
224
|
+
biped.setTransform FBX_convert_str.retarget_array[i+38] #scale ([temp,temp,temp]) True
|
225
|
+
)
|
226
|
+
)
|
227
|
+
)
|
228
|
+
```
|
229
|
+
|
230
|
+
##### 포니테일 2 본 조정
|
231
|
+
```maxscript
|
232
|
+
-- 두 번째 포니테일 (인덱스 64-88)
|
233
|
+
for i = 1 to 25 do(
|
234
|
+
if FBX_convert_str.FBX_array[i+63] != undefined do(
|
235
|
+
if (FBX_convert_str.FBX_array[i+64] != undefined) and (FBX_convert_str.FBX_array[i+64].parent == FBX_convert_str.FBX_array[i+63]) then (
|
236
|
+
local temp = distance FBX_convert_str.FBX_array[i+63] FBX_convert_str.FBX_array[i+64]
|
237
|
+
biped.setTransform FBX_convert_str.retarget_array[i+63] #scale ([temp,temp,temp]) True
|
238
|
+
)else(
|
239
|
+
local temp = distance FBX_convert_str.FBX_array[i+62] FBX_convert_str.FBX_array[i+63]
|
240
|
+
biped.setTransform FBX_convert_str.retarget_array[i+63] #scale ([temp,temp,temp]) True
|
241
|
+
)
|
242
|
+
)
|
243
|
+
)
|
244
|
+
```
|
245
|
+
|
246
|
+
##### 왼쪽 팔(Left Arm) 조정
|
247
|
+
```maxscript
|
248
|
+
-- 왼쪽 팔 (인덱스 89-92: 쇄골, 어깨, 팔꿈치, 손목)
|
249
|
+
for i = 1 to 3 do(
|
250
|
+
local temp = distance FBX_convert_str.FBX_array[i+88] FBX_convert_str.FBX_array[i+89]
|
251
|
+
biped.setTransform FBX_convert_str.retarget_array[i+88] #scale ([temp,temp,temp]) True
|
252
|
+
)
|
253
|
+
|
254
|
+
-- 왼쪽 손목에서 첫 번째 손가락까지 (있는 경우)
|
255
|
+
if FBX_convert_str.FBX_array[93] != undefined do(
|
256
|
+
local temp = distance FBX_convert_str.FBX_array[92] FBX_convert_str.FBX_array[93]
|
257
|
+
biped.setTransform FBX_convert_str.retarget_array[92] #scale ([temp,temp,temp]) True
|
258
|
+
)
|
259
|
+
```
|
260
|
+
|
261
|
+
##### 오른쪽 팔(Right Arm) 조정
|
262
|
+
```maxscript
|
263
|
+
-- 오른쪽 팔 (인덱스 113-116: 쇄골, 어깨, 팔꿈치, 손목)
|
264
|
+
for i = 1 to 3 do(
|
265
|
+
local temp = distance FBX_convert_str.FBX_array[i+112] FBX_convert_str.FBX_array[i+113]
|
266
|
+
biped.setTransform FBX_convert_str.retarget_array[i+112] #scale ([temp,temp,temp]) True
|
267
|
+
)
|
268
|
+
|
269
|
+
-- 오른쪽 손목에서 첫 번째 손가락까지 (있는 경우)
|
270
|
+
if FBX_convert_str.FBX_array[117] != undefined do(
|
271
|
+
local temp = distance FBX_convert_str.FBX_array[116] FBX_convert_str.FBX_array[117]
|
272
|
+
biped.setTransform FBX_convert_str.retarget_array[116] #scale ([temp,temp,temp]) True
|
273
|
+
)
|
274
|
+
```
|
275
|
+
|
276
|
+
##### 왼쪽 다리(Left Leg) 조정
|
277
|
+
```maxscript
|
278
|
+
-- 왼쪽 다리 (인덱스 137-140: 허벅지, 무릎, 발목)
|
279
|
+
for i = 1 to 3 do(
|
280
|
+
if FBX_convert_str.FBX_array[i+136] != undefined do(
|
281
|
+
if FBX_convert_str.FBX_array[i+137] != undefined then (
|
282
|
+
-- 다음 다리 본이 있으면 그 사이의 거리
|
283
|
+
local temp = distance FBX_convert_str.FBX_array[i+136] FBX_convert_str.FBX_array[i+137]
|
284
|
+
biped.setTransform FBX_convert_str.retarget_array[i+136] #scale ([temp,temp,temp]) True
|
285
|
+
)else(
|
286
|
+
-- 다음 본이 없으면 그 다음 본까지의 거리
|
287
|
+
local temp = distance FBX_convert_str.FBX_array[i+136] FBX_convert_str.FBX_array[i+138]
|
288
|
+
biped.setTransform FBX_convert_str.retarget_array[i+136] #scale ([temp,temp,temp]) True
|
289
|
+
)
|
290
|
+
)
|
291
|
+
)
|
292
|
+
```
|
293
|
+
|
294
|
+
##### 오른쪽 다리(Right Leg) 조정
|
295
|
+
```maxscript
|
296
|
+
-- 오른쪽 다리 (인덱스 156-159: 허벅지, 무릎, 발목)
|
297
|
+
for i = 1 to 3 do(
|
298
|
+
if FBX_convert_str.FBX_array[i+155] != undefined do(
|
299
|
+
if FBX_convert_str.FBX_array[i+156] != undefined then (
|
300
|
+
local temp = distance FBX_convert_str.FBX_array[i+155] FBX_convert_str.FBX_array[i+156]
|
301
|
+
biped.setTransform FBX_convert_str.retarget_array[i+155] #scale ([temp,temp,temp]) True
|
302
|
+
)else(
|
303
|
+
local temp = distance FBX_convert_str.FBX_array[i+155] FBX_convert_str.FBX_array[i+157]
|
304
|
+
biped.setTransform FBX_convert_str.retarget_array[i+155] #scale ([temp,temp,temp]) True
|
305
|
+
)
|
306
|
+
)
|
307
|
+
)
|
308
|
+
```
|
309
|
+
|
310
|
+
##### 발 크기 계산 (주석 처리된 코드)
|
311
|
+
```maxscript
|
312
|
+
-- 왼쪽 발 크기 계산 예제 (현재는 주석 처리됨)
|
313
|
+
local a = FBX_convert_str.FBX_array[141].pos -- 왼쪽 발가락 위치
|
314
|
+
local b = FBX_convert_str.FBX_array[140].pos -- 왼쪽 발목 위치
|
315
|
+
local d = [b.x,b.y,a.z] -- 발목의 X,Y와 발가락의 Z
|
316
|
+
local c = [a.x,a.y,b.z] -- 발가락의 X,Y와 발목의 Z
|
317
|
+
local lenght = distance c b -- 발의 길이
|
318
|
+
local height = distance b d -- 발의 높이
|
319
|
+
-- 실제 적용 코드는 주석 처리됨
|
320
|
+
|
321
|
+
-- 오른쪽 발도 동일한 방식으로 계산
|
322
|
+
```
|
323
|
+
|
324
|
+
##### 최종 위치 조정
|
325
|
+
```maxscript
|
326
|
+
-- 첫 번째 척추 본의 위치를 FBX에 맞춰 재조정
|
327
|
+
biped.setTransform FBX_convert_str.retarget_array[3] #pos (FBX_convert_str.FBX_array[3].transform.pos) True
|
328
|
+
|
329
|
+
-- 모든 바이패드 본의 위치와 회전을 FBX 본에 맞춰 최종 조정
|
330
|
+
for b = 1 to local_number_of_items do (
|
331
|
+
biped.setTransform local_retarget_array[b] #pos (local_fbx_array[b].transform.pos) True
|
332
|
+
biped.setTransform local_retarget_array[b] #rotation (local_fbx_array[b].transform.rotation) True
|
333
|
+
-- 위치와 회전을 두 번 설정하여 확실하게 적용
|
334
|
+
biped.setTransform local_retarget_array[b] #pos (local_fbx_array[b].transform.pos) True
|
335
|
+
biped.setTransform local_retarget_array[b] #rotation (local_fbx_array[b].transform.rotation) True
|
336
|
+
)
|
337
|
+
```
|
338
|
+
|
339
|
+
##### Clavicle과 팔 본들의 위치 조정
|
340
|
+
BIPPY에서는 Clavicle(쇄골)과 팔 본들에 대한 별도의 위치 조정 루틴은 없습니다. 대신 **모든 본들의 위치와 회전이 일괄적으로 조정**됩니다:
|
341
|
+
|
342
|
+
```maxscript
|
343
|
+
-- 모든 바이패드 본의 위치와 회전을 FBX 본에 맞춰 최종 조정
|
344
|
+
for b = 1 to local_number_of_items do (
|
345
|
+
-- 위치 설정
|
346
|
+
biped.setTransform local_retarget_array[b] #pos (local_fbx_array[b].transform.pos) True
|
347
|
+
-- 회전 설정
|
348
|
+
biped.setTransform local_retarget_array[b] #rotation (local_fbx_array[b].transform.rotation) True
|
349
|
+
-- 안정성을 위해 두 번 설정
|
350
|
+
biped.setTransform local_retarget_array[b] #pos (local_fbx_array[b].transform.pos) True
|
351
|
+
biped.setTransform local_retarget_array[b] #rotation (local_fbx_array[b].transform.rotation) True
|
352
|
+
)
|
353
|
+
```
|
354
|
+
|
355
|
+
**Clavicle과 팔 본 인덱스 매핑:**
|
356
|
+
- **왼쪽 Clavicle**: FBX_array[89] → retarget_array[89]
|
357
|
+
- **왼쪽 Upper Arm**: FBX_array[90] → retarget_array[90]
|
358
|
+
- **왼쪽 Forearm**: FBX_array[91] → retarget_array[91]
|
359
|
+
- **왼쪽 Hand**: FBX_array[92] → retarget_array[92]
|
360
|
+
- **오른쪽 Clavicle**: FBX_array[113] → retarget_array[113]
|
361
|
+
- **오른쪽 Upper Arm**: FBX_array[114] → retarget_array[114]
|
362
|
+
- **오른쪽 Forearm**: FBX_array[115] → retarget_array[115]
|
363
|
+
- **오른쪽 Hand**: FBX_array[116] → retarget_array[116]
|
364
|
+
|
365
|
+
이 과정에서 Clavicle과 팔 본들도 다른 모든 본들과 동일하게:
|
366
|
+
1. **크기 조정 단계**: `distance` 함수로 본 간 거리를 측정하여 스케일 설정
|
367
|
+
2. **위치 조정 단계**: FBX 본의 `transform.pos`를 바이패드 본에 직접 복사
|
368
|
+
3. **회전 조정 단계**: FBX 본의 `transform.rotation`을 바이패드 본에 직접 복사
|
369
|
+
|
370
|
+
##### Figure Mode 해제
|
371
|
+
```maxscript
|
372
|
+
-- 크기 조정이 완료되면 Figure Mode 해제
|
373
|
+
FBX_convert_str.biped_ctrl.figureMode = false
|
374
|
+
```
|
375
|
+
|
376
|
+
**주요 특징:**
|
377
|
+
- **거리 기반 스케일링**: 각 본 간의 3D 거리를 측정하여 바이패드 본의 스케일 설정
|
378
|
+
- **조건부 처리**: 본이 존재하지 않는 경우를 대비한 예외 처리
|
379
|
+
- **부모-자식 관계 확인**: 포니테일과 같은 체인 구조에서 올바른 연결 확인
|
380
|
+
- **일괄 변환**: 모든 본(Clavicle, 팔, 다리, 척추 등)이 동일한 로직으로 처리
|
381
|
+
- **이중 설정**: 위치와 회전을 두 번 설정하여 안정적인 적용 보장
|
382
|
+
|
383
|
+
### 3. Map_biped_to_FBX() 함수
|
384
|
+
**위치:** 894 라인 이후
|
385
|
+
**목적:** 전체 바이패드 생성 프로세스 관리
|
386
|
+
|
387
|
+
#### 3.1 생성 모드 결정
|
388
|
+
```maxscript
|
389
|
+
if(FBX_convert_str.using_Own_FIG == false) then (
|
390
|
+
assess_and_create_biped()
|
391
|
+
resize_biped()
|
392
|
+
)
|
393
|
+
else (
|
394
|
+
assess_and_create_biped()
|
395
|
+
// FIG 파일 로드 로직
|
396
|
+
biped.LoadFigFile FBX_convert_str.biped_ctrl FBX_convert_str.Fig_File
|
397
|
+
)
|
398
|
+
```
|
399
|
+
|
400
|
+
두 가지 모드:
|
401
|
+
1. **자동 생성 모드**: FBX 구조 분석하여 자동으로 바이패드 생성
|
402
|
+
2. **FIG 파일 모드**: 미리 저장된 FIG 파일을 사용하여 바이패드 구조 적용
|
403
|
+
|
404
|
+
## FBX 본 인덱스 매핑
|
405
|
+
|
406
|
+
| 인덱스 범위 | 본 유형 | 설명 |
|
407
|
+
|-------------|---------|------|
|
408
|
+
| 1 | Root | 루트 본 |
|
409
|
+
| 3-12 | Spine | 척추 본들 |
|
410
|
+
| 13-37 | Neck | 목 본들 |
|
411
|
+
| 39-63 | Ponytail1 | 첫 번째 포니테일 |
|
412
|
+
| 64-88 | Ponytail2 | 두 번째 포니테일 |
|
413
|
+
| 89-92 | Left Arm | 왼쪽 팔 |
|
414
|
+
| 93-109 | Left Fingers | 왼쪽 손가락들 |
|
415
|
+
| 113-116 | Right Arm | 오른쪽 팔 |
|
416
|
+
| 117-133 | Right Fingers | 오른쪽 손가락들 |
|
417
|
+
| 137-140 | Left Leg | 왼쪽 다리 |
|
418
|
+
| 141-153 | Left Toes | 왼쪽 발가락들 |
|
419
|
+
| 156-159 | Right Leg | 오른쪽 다리 |
|
420
|
+
| 160-172 | Right Toes | 오른쪽 발가락들 |
|
421
|
+
| 165-189 | Tail | 꼬리 |
|
422
|
+
| 200-202 | Props | 프롭 오브젝트들 |
|
423
|
+
|
424
|
+
## 생성 프로세스 요약
|
425
|
+
|
426
|
+
1. **FBX 본 구조 분석**: 각 부위별 본의 존재 여부와 개수 파악
|
427
|
+
2. **바이패드 높이 계산**: 발목-목 거리 기반으로 전체 높이 결정
|
428
|
+
3. **바이패드 생성**: `biped.createNew`로 분석된 구조에 맞는 바이패드 생성
|
429
|
+
4. **본 매핑**: BTF 파일에서 바이패드 본 이름들을 읽어와 매핑 배열 구성
|
430
|
+
5. **크기 조정**: Figure Mode에서 각 본의 길이를 FBX 본에 맞춰 조정
|
431
|
+
6. **애니메이션 적용**: 프레임별로 FBX 본의 transform을 바이패드에 복사
|
432
|
+
|
433
|
+
## 주요 특징
|
434
|
+
|
435
|
+
- **동적 구조 분석**: FBX 파일의 본 구조를 자동으로 분석하여 적절한 바이패드 생성
|
436
|
+
- **유연한 매핑**: 다양한 캐릭터 구조(꼬리, 포니테일, 다양한 손가락 수 등)에 대응
|
437
|
+
- **정확한 크기 조정**: 실제 FBX 본 간의 거리를 측정하여 바이패드 크기 조정
|
438
|
+
- **배치 처리 지원**: 여러 FBX 파일을 일괄 처리할 수 있는 구조
|
439
|
+
|
440
|
+
이 시스템은 모션 캡처 데이터를 3DS Max의 Biped 시스템으로 효율적으로 변환하기 위한 포괄적인 솔루션을 제공합니다.
|