1 | /**************************************************************************/ |
2 | /* skeleton_profile.cpp */ |
3 | /**************************************************************************/ |
4 | /* This file is part of: */ |
5 | /* GODOT ENGINE */ |
6 | /* https://godotengine.org */ |
7 | /**************************************************************************/ |
8 | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ |
9 | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ |
10 | /* */ |
11 | /* Permission is hereby granted, free of charge, to any person obtaining */ |
12 | /* a copy of this software and associated documentation files (the */ |
13 | /* "Software"), to deal in the Software without restriction, including */ |
14 | /* without limitation the rights to use, copy, modify, merge, publish, */ |
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */ |
16 | /* permit persons to whom the Software is furnished to do so, subject to */ |
17 | /* the following conditions: */ |
18 | /* */ |
19 | /* The above copyright notice and this permission notice shall be */ |
20 | /* included in all copies or substantial portions of the Software. */ |
21 | /* */ |
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ |
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ |
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ |
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ |
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ |
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ |
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
29 | /**************************************************************************/ |
30 | |
31 | #include "skeleton_profile.h" |
32 | |
33 | bool SkeletonProfile::_set(const StringName &p_path, const Variant &p_value) { |
34 | ERR_FAIL_COND_V(is_read_only, false); |
35 | String path = p_path; |
36 | |
37 | if (path.begins_with("groups/" )) { |
38 | int which = path.get_slicec('/', 1).to_int(); |
39 | String what = path.get_slicec('/', 2); |
40 | ERR_FAIL_INDEX_V(which, groups.size(), false); |
41 | |
42 | if (what == "group_name" ) { |
43 | set_group_name(which, p_value); |
44 | } else if (what == "texture" ) { |
45 | set_texture(which, p_value); |
46 | } else { |
47 | return false; |
48 | } |
49 | } |
50 | |
51 | if (path.begins_with("bones/" )) { |
52 | int which = path.get_slicec('/', 1).to_int(); |
53 | String what = path.get_slicec('/', 2); |
54 | ERR_FAIL_INDEX_V(which, bones.size(), false); |
55 | |
56 | if (what == "bone_name" ) { |
57 | set_bone_name(which, p_value); |
58 | } else if (what == "bone_parent" ) { |
59 | set_bone_parent(which, p_value); |
60 | } else if (what == "tail_direction" ) { |
61 | set_tail_direction(which, static_cast<TailDirection>((int)p_value)); |
62 | } else if (what == "bone_tail" ) { |
63 | set_bone_tail(which, p_value); |
64 | } else if (what == "reference_pose" ) { |
65 | set_reference_pose(which, p_value); |
66 | } else if (what == "handle_offset" ) { |
67 | set_handle_offset(which, p_value); |
68 | } else if (what == "group" ) { |
69 | set_group(which, p_value); |
70 | } else if (what == "require" ) { |
71 | set_require(which, p_value); |
72 | } else { |
73 | return false; |
74 | } |
75 | } |
76 | return true; |
77 | } |
78 | |
79 | bool SkeletonProfile::_get(const StringName &p_path, Variant &r_ret) const { |
80 | String path = p_path; |
81 | |
82 | if (path.begins_with("groups/" )) { |
83 | int which = path.get_slicec('/', 1).to_int(); |
84 | String what = path.get_slicec('/', 2); |
85 | ERR_FAIL_INDEX_V(which, groups.size(), false); |
86 | |
87 | if (what == "group_name" ) { |
88 | r_ret = get_group_name(which); |
89 | } else if (what == "texture" ) { |
90 | r_ret = get_texture(which); |
91 | } else { |
92 | return false; |
93 | } |
94 | } |
95 | |
96 | if (path.begins_with("bones/" )) { |
97 | int which = path.get_slicec('/', 1).to_int(); |
98 | String what = path.get_slicec('/', 2); |
99 | ERR_FAIL_INDEX_V(which, bones.size(), false); |
100 | |
101 | if (what == "bone_name" ) { |
102 | r_ret = get_bone_name(which); |
103 | } else if (what == "bone_parent" ) { |
104 | r_ret = get_bone_parent(which); |
105 | } else if (what == "tail_direction" ) { |
106 | r_ret = get_tail_direction(which); |
107 | } else if (what == "bone_tail" ) { |
108 | r_ret = get_bone_tail(which); |
109 | } else if (what == "reference_pose" ) { |
110 | r_ret = get_reference_pose(which); |
111 | } else if (what == "handle_offset" ) { |
112 | r_ret = get_handle_offset(which); |
113 | } else if (what == "group" ) { |
114 | r_ret = get_group(which); |
115 | } else if (what == "require" ) { |
116 | r_ret = is_require(which); |
117 | } else { |
118 | return false; |
119 | } |
120 | } |
121 | return true; |
122 | } |
123 | |
124 | void SkeletonProfile::_validate_property(PropertyInfo &p_property) const { |
125 | if (is_read_only) { |
126 | if (p_property.name == ("group_size" ) || p_property.name == ("bone_size" ) || p_property.name == ("root_bone" ) || p_property.name == ("scale_base_bone" )) { |
127 | p_property.usage = PROPERTY_USAGE_NO_EDITOR; |
128 | return; |
129 | } |
130 | } |
131 | |
132 | if (p_property.name == ("root_bone" ) || p_property.name == ("scale_base_bone" )) { |
133 | String hint = "" ; |
134 | for (int i = 0; i < bones.size(); i++) { |
135 | hint += i == 0 ? String(bones[i].bone_name) : "," + String(bones[i].bone_name); |
136 | } |
137 | p_property.hint_string = hint; |
138 | } |
139 | |
140 | PackedStringArray split = p_property.name.split("/" ); |
141 | if (split.size() == 3 && split[0] == "bones" ) { |
142 | if (split[2] == "bone_tail" && get_tail_direction(split[1].to_int()) != TAIL_DIRECTION_SPECIFIC_CHILD) { |
143 | p_property.usage = PROPERTY_USAGE_NONE; |
144 | } |
145 | } |
146 | } |
147 | |
148 | void SkeletonProfile::_get_property_list(List<PropertyInfo> *p_list) const { |
149 | if (is_read_only) { |
150 | return; |
151 | } |
152 | String group_names = "" ; |
153 | for (int i = 0; i < groups.size(); i++) { |
154 | String path = "groups/" + itos(i) + "/" ; |
155 | p_list->push_back(PropertyInfo(Variant::STRING_NAME, path + "group_name" )); |
156 | p_list->push_back(PropertyInfo(Variant::OBJECT, path + "texture" , PROPERTY_HINT_RESOURCE_TYPE, "Texture2D" )); |
157 | if (i > 0) { |
158 | group_names = group_names + "," ; |
159 | } |
160 | group_names = group_names + groups[i].group_name; |
161 | } |
162 | for (int i = 0; i < bones.size(); i++) { |
163 | String path = "bones/" + itos(i) + "/" ; |
164 | p_list->push_back(PropertyInfo(Variant::STRING_NAME, path + "bone_name" )); |
165 | p_list->push_back(PropertyInfo(Variant::STRING_NAME, path + "bone_parent" )); |
166 | p_list->push_back(PropertyInfo(Variant::INT, path + "tail_direction" , PROPERTY_HINT_ENUM, "AverageChildren,SpecificChild,End" )); |
167 | p_list->push_back(PropertyInfo(Variant::STRING_NAME, path + "bone_tail" )); |
168 | p_list->push_back(PropertyInfo(Variant::TRANSFORM3D, path + "reference_pose" )); |
169 | p_list->push_back(PropertyInfo(Variant::VECTOR2, path + "handle_offset" )); |
170 | p_list->push_back(PropertyInfo(Variant::STRING_NAME, path + "group" , PROPERTY_HINT_ENUM, group_names)); |
171 | p_list->push_back(PropertyInfo(Variant::BOOL, path + "require" )); |
172 | } |
173 | |
174 | for (PropertyInfo &E : *p_list) { |
175 | _validate_property(E); |
176 | } |
177 | } |
178 | |
179 | StringName SkeletonProfile::get_root_bone() { |
180 | return root_bone; |
181 | } |
182 | |
183 | void SkeletonProfile::set_root_bone(StringName p_bone_name) { |
184 | if (is_read_only) { |
185 | return; |
186 | } |
187 | root_bone = p_bone_name; |
188 | } |
189 | |
190 | StringName SkeletonProfile::get_scale_base_bone() { |
191 | return scale_base_bone; |
192 | } |
193 | |
194 | void SkeletonProfile::set_scale_base_bone(StringName p_bone_name) { |
195 | if (is_read_only) { |
196 | return; |
197 | } |
198 | scale_base_bone = p_bone_name; |
199 | } |
200 | |
201 | int SkeletonProfile::get_group_size() { |
202 | return groups.size(); |
203 | } |
204 | |
205 | void SkeletonProfile::set_group_size(int p_size) { |
206 | if (is_read_only) { |
207 | return; |
208 | } |
209 | ERR_FAIL_COND(p_size < 0); |
210 | groups.resize(p_size); |
211 | emit_signal("profile_updated" ); |
212 | notify_property_list_changed(); |
213 | } |
214 | |
215 | StringName SkeletonProfile::get_group_name(int p_group_idx) const { |
216 | ERR_FAIL_INDEX_V(p_group_idx, groups.size(), StringName()); |
217 | return groups[p_group_idx].group_name; |
218 | } |
219 | |
220 | void SkeletonProfile::set_group_name(int p_group_idx, const StringName p_group_name) { |
221 | if (is_read_only) { |
222 | return; |
223 | } |
224 | ERR_FAIL_INDEX(p_group_idx, groups.size()); |
225 | groups.write[p_group_idx].group_name = p_group_name; |
226 | emit_signal("profile_updated" ); |
227 | } |
228 | |
229 | Ref<Texture2D> SkeletonProfile::get_texture(int p_group_idx) const { |
230 | ERR_FAIL_INDEX_V(p_group_idx, groups.size(), Ref<Texture2D>()); |
231 | return groups[p_group_idx].texture; |
232 | } |
233 | |
234 | void SkeletonProfile::set_texture(int p_group_idx, const Ref<Texture2D> &p_texture) { |
235 | if (is_read_only) { |
236 | return; |
237 | } |
238 | ERR_FAIL_INDEX(p_group_idx, groups.size()); |
239 | groups.write[p_group_idx].texture = p_texture; |
240 | emit_signal("profile_updated" ); |
241 | } |
242 | |
243 | int SkeletonProfile::get_bone_size() { |
244 | return bones.size(); |
245 | } |
246 | |
247 | void SkeletonProfile::set_bone_size(int p_size) { |
248 | if (is_read_only) { |
249 | return; |
250 | } |
251 | ERR_FAIL_COND(p_size < 0); |
252 | bones.resize(p_size); |
253 | emit_signal("profile_updated" ); |
254 | notify_property_list_changed(); |
255 | } |
256 | |
257 | int SkeletonProfile::find_bone(StringName p_bone_name) const { |
258 | if (p_bone_name == StringName()) { |
259 | return -1; |
260 | } |
261 | for (int i = 0; i < bones.size(); i++) { |
262 | if (bones[i].bone_name == p_bone_name) { |
263 | return i; |
264 | } |
265 | } |
266 | return -1; |
267 | } |
268 | |
269 | StringName SkeletonProfile::get_bone_name(int p_bone_idx) const { |
270 | ERR_FAIL_INDEX_V(p_bone_idx, bones.size(), StringName()); |
271 | return bones[p_bone_idx].bone_name; |
272 | } |
273 | |
274 | void SkeletonProfile::set_bone_name(int p_bone_idx, const StringName p_bone_name) { |
275 | if (is_read_only) { |
276 | return; |
277 | } |
278 | ERR_FAIL_INDEX(p_bone_idx, bones.size()); |
279 | bones.write[p_bone_idx].bone_name = p_bone_name; |
280 | emit_signal("profile_updated" ); |
281 | } |
282 | |
283 | StringName SkeletonProfile::get_bone_parent(int p_bone_idx) const { |
284 | ERR_FAIL_INDEX_V(p_bone_idx, bones.size(), StringName()); |
285 | return bones[p_bone_idx].bone_parent; |
286 | } |
287 | |
288 | void SkeletonProfile::set_bone_parent(int p_bone_idx, const StringName p_bone_parent) { |
289 | if (is_read_only) { |
290 | return; |
291 | } |
292 | ERR_FAIL_INDEX(p_bone_idx, bones.size()); |
293 | bones.write[p_bone_idx].bone_parent = p_bone_parent; |
294 | emit_signal("profile_updated" ); |
295 | } |
296 | |
297 | SkeletonProfile::TailDirection SkeletonProfile::get_tail_direction(int p_bone_idx) const { |
298 | ERR_FAIL_INDEX_V(p_bone_idx, bones.size(), TAIL_DIRECTION_AVERAGE_CHILDREN); |
299 | return bones[p_bone_idx].tail_direction; |
300 | } |
301 | |
302 | void SkeletonProfile::set_tail_direction(int p_bone_idx, const TailDirection p_tail_direction) { |
303 | if (is_read_only) { |
304 | return; |
305 | } |
306 | ERR_FAIL_INDEX(p_bone_idx, bones.size()); |
307 | bones.write[p_bone_idx].tail_direction = p_tail_direction; |
308 | emit_signal("profile_updated" ); |
309 | notify_property_list_changed(); |
310 | } |
311 | |
312 | StringName SkeletonProfile::get_bone_tail(int p_bone_idx) const { |
313 | ERR_FAIL_INDEX_V(p_bone_idx, bones.size(), StringName()); |
314 | return bones[p_bone_idx].bone_tail; |
315 | } |
316 | |
317 | void SkeletonProfile::set_bone_tail(int p_bone_idx, const StringName p_bone_tail) { |
318 | if (is_read_only) { |
319 | return; |
320 | } |
321 | ERR_FAIL_INDEX(p_bone_idx, bones.size()); |
322 | bones.write[p_bone_idx].bone_tail = p_bone_tail; |
323 | emit_signal("profile_updated" ); |
324 | } |
325 | |
326 | Transform3D SkeletonProfile::get_reference_pose(int p_bone_idx) const { |
327 | ERR_FAIL_INDEX_V(p_bone_idx, bones.size(), Transform3D()); |
328 | return bones[p_bone_idx].reference_pose; |
329 | } |
330 | |
331 | void SkeletonProfile::set_reference_pose(int p_bone_idx, const Transform3D p_reference_pose) { |
332 | if (is_read_only) { |
333 | return; |
334 | } |
335 | ERR_FAIL_INDEX(p_bone_idx, bones.size()); |
336 | bones.write[p_bone_idx].reference_pose = p_reference_pose; |
337 | emit_signal("profile_updated" ); |
338 | } |
339 | |
340 | Vector2 SkeletonProfile::get_handle_offset(int p_bone_idx) const { |
341 | ERR_FAIL_INDEX_V(p_bone_idx, bones.size(), Vector2()); |
342 | return bones[p_bone_idx].handle_offset; |
343 | } |
344 | |
345 | void SkeletonProfile::set_handle_offset(int p_bone_idx, const Vector2 p_handle_offset) { |
346 | if (is_read_only) { |
347 | return; |
348 | } |
349 | ERR_FAIL_INDEX(p_bone_idx, bones.size()); |
350 | bones.write[p_bone_idx].handle_offset = p_handle_offset; |
351 | emit_signal("profile_updated" ); |
352 | } |
353 | |
354 | StringName SkeletonProfile::get_group(int p_bone_idx) const { |
355 | ERR_FAIL_INDEX_V(p_bone_idx, bones.size(), StringName()); |
356 | return bones[p_bone_idx].group; |
357 | } |
358 | |
359 | void SkeletonProfile::set_group(int p_bone_idx, const StringName p_group) { |
360 | if (is_read_only) { |
361 | return; |
362 | } |
363 | ERR_FAIL_INDEX(p_bone_idx, bones.size()); |
364 | bones.write[p_bone_idx].group = p_group; |
365 | emit_signal("profile_updated" ); |
366 | } |
367 | |
368 | bool SkeletonProfile::is_require(int p_bone_idx) const { |
369 | ERR_FAIL_INDEX_V(p_bone_idx, bones.size(), false); |
370 | return bones[p_bone_idx].require; |
371 | } |
372 | |
373 | void SkeletonProfile::set_require(int p_bone_idx, const bool p_require) { |
374 | if (is_read_only) { |
375 | return; |
376 | } |
377 | ERR_FAIL_INDEX(p_bone_idx, bones.size()); |
378 | bones.write[p_bone_idx].require = p_require; |
379 | emit_signal("profile_updated" ); |
380 | } |
381 | |
382 | bool SkeletonProfile::has_bone(StringName p_bone_name) { |
383 | bool is_found = false; |
384 | for (int i = 0; i < bones.size(); i++) { |
385 | if (bones[i].bone_name == p_bone_name) { |
386 | is_found = true; |
387 | break; |
388 | } |
389 | } |
390 | return is_found; |
391 | } |
392 | |
393 | void SkeletonProfile::_bind_methods() { |
394 | ClassDB::bind_method(D_METHOD("set_root_bone" , "bone_name" ), &SkeletonProfile::set_root_bone); |
395 | ClassDB::bind_method(D_METHOD("get_root_bone" ), &SkeletonProfile::get_root_bone); |
396 | |
397 | ClassDB::bind_method(D_METHOD("set_scale_base_bone" , "bone_name" ), &SkeletonProfile::set_scale_base_bone); |
398 | ClassDB::bind_method(D_METHOD("get_scale_base_bone" ), &SkeletonProfile::get_scale_base_bone); |
399 | |
400 | ClassDB::bind_method(D_METHOD("set_group_size" , "size" ), &SkeletonProfile::set_group_size); |
401 | ClassDB::bind_method(D_METHOD("get_group_size" ), &SkeletonProfile::get_group_size); |
402 | |
403 | ClassDB::bind_method(D_METHOD("get_group_name" , "group_idx" ), &SkeletonProfile::get_group_name); |
404 | ClassDB::bind_method(D_METHOD("set_group_name" , "group_idx" , "group_name" ), &SkeletonProfile::set_group_name); |
405 | |
406 | ClassDB::bind_method(D_METHOD("get_texture" , "group_idx" ), &SkeletonProfile::get_texture); |
407 | ClassDB::bind_method(D_METHOD("set_texture" , "group_idx" , "texture" ), &SkeletonProfile::set_texture); |
408 | |
409 | ClassDB::bind_method(D_METHOD("set_bone_size" , "size" ), &SkeletonProfile::set_bone_size); |
410 | ClassDB::bind_method(D_METHOD("get_bone_size" ), &SkeletonProfile::get_bone_size); |
411 | |
412 | ClassDB::bind_method(D_METHOD("find_bone" , "bone_name" ), &SkeletonProfile::find_bone); |
413 | |
414 | ClassDB::bind_method(D_METHOD("get_bone_name" , "bone_idx" ), &SkeletonProfile::get_bone_name); |
415 | ClassDB::bind_method(D_METHOD("set_bone_name" , "bone_idx" , "bone_name" ), &SkeletonProfile::set_bone_name); |
416 | |
417 | ClassDB::bind_method(D_METHOD("get_bone_parent" , "bone_idx" ), &SkeletonProfile::get_bone_parent); |
418 | ClassDB::bind_method(D_METHOD("set_bone_parent" , "bone_idx" , "bone_parent" ), &SkeletonProfile::set_bone_parent); |
419 | |
420 | ClassDB::bind_method(D_METHOD("get_tail_direction" , "bone_idx" ), &SkeletonProfile::get_tail_direction); |
421 | ClassDB::bind_method(D_METHOD("set_tail_direction" , "bone_idx" , "tail_direction" ), &SkeletonProfile::set_tail_direction); |
422 | |
423 | ClassDB::bind_method(D_METHOD("get_bone_tail" , "bone_idx" ), &SkeletonProfile::get_bone_tail); |
424 | ClassDB::bind_method(D_METHOD("set_bone_tail" , "bone_idx" , "bone_tail" ), &SkeletonProfile::set_bone_tail); |
425 | |
426 | ClassDB::bind_method(D_METHOD("get_reference_pose" , "bone_idx" ), &SkeletonProfile::get_reference_pose); |
427 | ClassDB::bind_method(D_METHOD("set_reference_pose" , "bone_idx" , "bone_name" ), &SkeletonProfile::set_reference_pose); |
428 | |
429 | ClassDB::bind_method(D_METHOD("get_handle_offset" , "bone_idx" ), &SkeletonProfile::get_handle_offset); |
430 | ClassDB::bind_method(D_METHOD("set_handle_offset" , "bone_idx" , "handle_offset" ), &SkeletonProfile::set_handle_offset); |
431 | |
432 | ClassDB::bind_method(D_METHOD("get_group" , "bone_idx" ), &SkeletonProfile::get_group); |
433 | ClassDB::bind_method(D_METHOD("set_group" , "bone_idx" , "group" ), &SkeletonProfile::set_group); |
434 | |
435 | ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "root_bone" , PROPERTY_HINT_ENUM_SUGGESTION, "" ), "set_root_bone" , "get_root_bone" ); |
436 | ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "scale_base_bone" , PROPERTY_HINT_ENUM_SUGGESTION, "" ), "set_scale_base_bone" , "get_scale_base_bone" ); |
437 | |
438 | ADD_PROPERTY(PropertyInfo(Variant::INT, "group_size" , PROPERTY_HINT_RANGE, "0,100,1" , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_ARRAY, "Groups,groups/" ), "set_group_size" , "get_group_size" ); |
439 | ADD_PROPERTY(PropertyInfo(Variant::INT, "bone_size" , PROPERTY_HINT_RANGE, "0,100,1" , PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_ARRAY, "Bones,bones/" ), "set_bone_size" , "get_bone_size" ); |
440 | |
441 | ADD_SIGNAL(MethodInfo("profile_updated" )); |
442 | |
443 | BIND_ENUM_CONSTANT(TAIL_DIRECTION_AVERAGE_CHILDREN); |
444 | BIND_ENUM_CONSTANT(TAIL_DIRECTION_SPECIFIC_CHILD); |
445 | BIND_ENUM_CONSTANT(TAIL_DIRECTION_END); |
446 | } |
447 | |
448 | SkeletonProfile::SkeletonProfile() { |
449 | } |
450 | |
451 | SkeletonProfile::~SkeletonProfile() { |
452 | } |
453 | |
454 | SkeletonProfileHumanoid::SkeletonProfileHumanoid() { |
455 | is_read_only = true; |
456 | |
457 | root_bone = "Root" ; |
458 | scale_base_bone = "Hips" ; |
459 | |
460 | groups.resize(4); |
461 | |
462 | groups.write[0].group_name = "Body" ; |
463 | groups.write[1].group_name = "Face" ; |
464 | groups.write[2].group_name = "LeftHand" ; |
465 | groups.write[3].group_name = "RightHand" ; |
466 | |
467 | bones.resize(56); |
468 | |
469 | bones.write[0].bone_name = "Root" ; |
470 | bones.write[0].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0); |
471 | bones.write[0].handle_offset = Vector2(0.5, 0.91); |
472 | bones.write[0].group = "Body" ; |
473 | |
474 | bones.write[1].bone_name = "Hips" ; |
475 | bones.write[1].bone_parent = "Root" ; |
476 | bones.write[1].tail_direction = TAIL_DIRECTION_SPECIFIC_CHILD; |
477 | bones.write[1].bone_tail = "Spine" ; |
478 | bones.write[1].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.75, 0); |
479 | bones.write[1].handle_offset = Vector2(0.5, 0.5); |
480 | bones.write[1].group = "Body" ; |
481 | bones.write[1].require = true; |
482 | |
483 | bones.write[2].bone_name = "Spine" ; |
484 | bones.write[2].bone_parent = "Hips" ; |
485 | bones.write[2].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0); |
486 | bones.write[2].handle_offset = Vector2(0.5, 0.43); |
487 | bones.write[2].group = "Body" ; |
488 | bones.write[2].require = true; |
489 | |
490 | bones.write[3].bone_name = "Chest" ; |
491 | bones.write[3].bone_parent = "Spine" ; |
492 | bones.write[3].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0); |
493 | bones.write[3].handle_offset = Vector2(0.5, 0.36); |
494 | bones.write[3].group = "Body" ; |
495 | |
496 | bones.write[4].bone_name = "UpperChest" ; |
497 | bones.write[4].bone_parent = "Chest" ; |
498 | bones.write[4].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0); |
499 | bones.write[4].handle_offset = Vector2(0.5, 0.29); |
500 | bones.write[4].group = "Body" ; |
501 | |
502 | bones.write[5].bone_name = "Neck" ; |
503 | bones.write[5].bone_parent = "UpperChest" ; |
504 | bones.write[5].tail_direction = TAIL_DIRECTION_SPECIFIC_CHILD; |
505 | bones.write[5].bone_tail = "Head" ; |
506 | bones.write[5].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0); |
507 | bones.write[5].handle_offset = Vector2(0.5, 0.23); |
508 | bones.write[5].group = "Body" ; |
509 | bones.write[5].require = false; |
510 | |
511 | bones.write[6].bone_name = "Head" ; |
512 | bones.write[6].bone_parent = "Neck" ; |
513 | bones.write[6].tail_direction = TAIL_DIRECTION_END; |
514 | bones.write[6].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0); |
515 | bones.write[6].handle_offset = Vector2(0.5, 0.18); |
516 | bones.write[6].group = "Body" ; |
517 | bones.write[6].require = true; |
518 | |
519 | bones.write[7].bone_name = "LeftEye" ; |
520 | bones.write[7].bone_parent = "Head" ; |
521 | bones.write[7].reference_pose = Transform3D(1, 0, 0, 0, 0, -1, 0, 1, 0, 0.05, 0.15, 0); |
522 | bones.write[7].handle_offset = Vector2(0.6, 0.46); |
523 | bones.write[7].group = "Face" ; |
524 | |
525 | bones.write[8].bone_name = "RightEye" ; |
526 | bones.write[8].bone_parent = "Head" ; |
527 | bones.write[8].reference_pose = Transform3D(1, 0, 0, 0, 0, -1, 0, 1, 0, -0.05, 0.15, 0); |
528 | bones.write[8].handle_offset = Vector2(0.37, 0.46); |
529 | bones.write[8].group = "Face" ; |
530 | |
531 | bones.write[9].bone_name = "Jaw" ; |
532 | bones.write[9].bone_parent = "Head" ; |
533 | bones.write[9].reference_pose = Transform3D(-1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0.05, 0.05); |
534 | bones.write[9].handle_offset = Vector2(0.46, 0.75); |
535 | bones.write[9].group = "Face" ; |
536 | |
537 | bones.write[10].bone_name = "LeftShoulder" ; |
538 | bones.write[10].bone_parent = "UpperChest" ; |
539 | bones.write[10].reference_pose = Transform3D(0, 1, 0, 0, 0, 1, 1, 0, 0, 0.05, 0.1, 0); |
540 | bones.write[10].handle_offset = Vector2(0.55, 0.235); |
541 | bones.write[10].group = "Body" ; |
542 | bones.write[10].require = true; |
543 | |
544 | bones.write[11].bone_name = "LeftUpperArm" ; |
545 | bones.write[11].bone_parent = "LeftShoulder" ; |
546 | bones.write[11].reference_pose = Transform3D(-1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0.05, 0); |
547 | bones.write[11].handle_offset = Vector2(0.6, 0.24); |
548 | bones.write[11].group = "Body" ; |
549 | bones.write[11].require = true; |
550 | |
551 | bones.write[12].bone_name = "LeftLowerArm" ; |
552 | bones.write[12].bone_parent = "LeftUpperArm" ; |
553 | bones.write[12].reference_pose = Transform3D(0, 0, -1, 0, 1, 0, 1, 0, 0, 0, 0.25, 0); |
554 | bones.write[12].handle_offset = Vector2(0.7, 0.24); |
555 | bones.write[12].group = "Body" ; |
556 | bones.write[12].require = true; |
557 | |
558 | bones.write[13].bone_name = "LeftHand" ; |
559 | bones.write[13].bone_parent = "LeftLowerArm" ; |
560 | bones.write[13].tail_direction = TAIL_DIRECTION_SPECIFIC_CHILD; |
561 | bones.write[13].bone_tail = "LeftMiddleProximal" ; |
562 | bones.write[13].reference_pose = Transform3D(0, 0, 1, 0, 1, 0, -1, 0, 0, 0, 0.25, 0); |
563 | bones.write[13].handle_offset = Vector2(0.82, 0.235); |
564 | bones.write[13].group = "Body" ; |
565 | bones.write[13].require = true; |
566 | |
567 | bones.write[14].bone_name = "LeftThumbMetacarpal" ; |
568 | bones.write[14].bone_parent = "LeftHand" ; |
569 | bones.write[14].reference_pose = Transform3D(0, -0.577, 0.816, 0, 0.816, 0.577, -1, 0, 0, -0.025, 0.025, 0); |
570 | bones.write[14].handle_offset = Vector2(0.4, 0.8); |
571 | bones.write[14].group = "LeftHand" ; |
572 | |
573 | bones.write[15].bone_name = "LeftThumbProximal" ; |
574 | bones.write[15].bone_parent = "LeftThumbMetacarpal" ; |
575 | bones.write[15].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.043, 0); |
576 | bones.write[15].handle_offset = Vector2(0.3, 0.69); |
577 | bones.write[15].group = "LeftHand" ; |
578 | |
579 | bones.write[16].bone_name = "LeftThumbDistal" ; |
580 | bones.write[16].bone_parent = "LeftThumbProximal" ; |
581 | bones.write[16].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.043, 0); |
582 | bones.write[16].handle_offset = Vector2(0.23, 0.555); |
583 | bones.write[16].group = "LeftHand" ; |
584 | |
585 | bones.write[17].bone_name = "LeftIndexProximal" ; |
586 | bones.write[17].bone_parent = "LeftHand" ; |
587 | bones.write[17].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.025, 0.075, 0); |
588 | bones.write[17].handle_offset = Vector2(0.413, 0.52); |
589 | bones.write[17].group = "LeftHand" ; |
590 | |
591 | bones.write[18].bone_name = "LeftIndexIntermediate" ; |
592 | bones.write[18].bone_parent = "LeftIndexProximal" ; |
593 | bones.write[18].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.05, 0); |
594 | bones.write[18].handle_offset = Vector2(0.403, 0.36); |
595 | bones.write[18].group = "LeftHand" ; |
596 | |
597 | bones.write[19].bone_name = "LeftIndexDistal" ; |
598 | bones.write[19].bone_parent = "LeftIndexIntermediate" ; |
599 | bones.write[19].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.025, 0); |
600 | bones.write[19].handle_offset = Vector2(0.403, 0.255); |
601 | bones.write[19].group = "LeftHand" ; |
602 | |
603 | bones.write[20].bone_name = "LeftMiddleProximal" ; |
604 | bones.write[20].bone_parent = "LeftHand" ; |
605 | bones.write[20].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.075, 0); |
606 | bones.write[20].handle_offset = Vector2(0.5, 0.51); |
607 | bones.write[20].group = "LeftHand" ; |
608 | |
609 | bones.write[21].bone_name = "LeftMiddleIntermediate" ; |
610 | bones.write[21].bone_parent = "LeftMiddleProximal" ; |
611 | bones.write[21].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.075, 0); |
612 | bones.write[21].handle_offset = Vector2(0.5, 0.345); |
613 | bones.write[21].group = "LeftHand" ; |
614 | |
615 | bones.write[22].bone_name = "LeftMiddleDistal" ; |
616 | bones.write[22].bone_parent = "LeftMiddleIntermediate" ; |
617 | bones.write[22].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.025, 0); |
618 | bones.write[22].handle_offset = Vector2(0.5, 0.22); |
619 | bones.write[22].group = "LeftHand" ; |
620 | |
621 | bones.write[23].bone_name = "LeftRingProximal" ; |
622 | bones.write[23].bone_parent = "LeftHand" ; |
623 | bones.write[23].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.025, 0.075, 0); |
624 | bones.write[23].handle_offset = Vector2(0.586, 0.52); |
625 | bones.write[23].group = "LeftHand" ; |
626 | |
627 | bones.write[24].bone_name = "LeftRingIntermediate" ; |
628 | bones.write[24].bone_parent = "LeftRingProximal" ; |
629 | bones.write[24].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.05, 0); |
630 | bones.write[24].handle_offset = Vector2(0.59, 0.36); |
631 | bones.write[24].group = "LeftHand" ; |
632 | |
633 | bones.write[25].bone_name = "LeftRingDistal" ; |
634 | bones.write[25].bone_parent = "LeftRingIntermediate" ; |
635 | bones.write[25].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.025, 0); |
636 | bones.write[25].handle_offset = Vector2(0.591, 0.25); |
637 | bones.write[25].group = "LeftHand" ; |
638 | |
639 | bones.write[26].bone_name = "LeftLittleProximal" ; |
640 | bones.write[26].bone_parent = "LeftHand" ; |
641 | bones.write[26].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.05, 0.05, 0); |
642 | bones.write[26].handle_offset = Vector2(0.663, 0.543); |
643 | bones.write[26].group = "LeftHand" ; |
644 | |
645 | bones.write[27].bone_name = "LeftLittleIntermediate" ; |
646 | bones.write[27].bone_parent = "LeftLittleProximal" ; |
647 | bones.write[27].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.05, 0); |
648 | bones.write[27].handle_offset = Vector2(0.672, 0.415); |
649 | bones.write[27].group = "LeftHand" ; |
650 | |
651 | bones.write[28].bone_name = "LeftLittleDistal" ; |
652 | bones.write[28].bone_parent = "LeftLittleIntermediate" ; |
653 | bones.write[28].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.025, 0); |
654 | bones.write[28].handle_offset = Vector2(0.672, 0.32); |
655 | bones.write[28].group = "LeftHand" ; |
656 | |
657 | bones.write[29].bone_name = "RightShoulder" ; |
658 | bones.write[29].bone_parent = "UpperChest" ; |
659 | bones.write[29].reference_pose = Transform3D(0, -1, 0, 0, 0, 1, -1, 0, 0, -0.05, 0.1, 0); |
660 | bones.write[29].handle_offset = Vector2(0.45, 0.235); |
661 | bones.write[29].group = "Body" ; |
662 | bones.write[29].require = true; |
663 | |
664 | bones.write[30].bone_name = "RightUpperArm" ; |
665 | bones.write[30].bone_parent = "RightShoulder" ; |
666 | bones.write[30].reference_pose = Transform3D(-1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0.05, 0); |
667 | bones.write[30].handle_offset = Vector2(0.4, 0.24); |
668 | bones.write[30].group = "Body" ; |
669 | bones.write[30].require = true; |
670 | |
671 | bones.write[31].bone_name = "RightLowerArm" ; |
672 | bones.write[31].bone_parent = "RightUpperArm" ; |
673 | bones.write[31].reference_pose = Transform3D(0, 0, 1, 0, 1, 0, -1, 0, 0, 0, 0.25, 0); |
674 | bones.write[31].handle_offset = Vector2(0.3, 0.24); |
675 | bones.write[31].group = "Body" ; |
676 | bones.write[31].require = true; |
677 | |
678 | bones.write[32].bone_name = "RightHand" ; |
679 | bones.write[32].bone_parent = "RightLowerArm" ; |
680 | bones.write[32].tail_direction = TAIL_DIRECTION_SPECIFIC_CHILD; |
681 | bones.write[32].bone_tail = "RightMiddleProximal" ; |
682 | bones.write[32].reference_pose = Transform3D(0, 0, -1, 0, 1, 0, 1, 0, 0, 0, 0.25, 0); |
683 | bones.write[32].handle_offset = Vector2(0.18, 0.235); |
684 | bones.write[32].group = "Body" ; |
685 | bones.write[32].require = true; |
686 | |
687 | bones.write[33].bone_name = "RightThumbMetacarpal" ; |
688 | bones.write[33].bone_parent = "RightHand" ; |
689 | bones.write[33].reference_pose = Transform3D(0, 0.577, -0.816, 0, 0.816, 0.577, 1, 0, 0, 0.025, 0.025, 0); |
690 | bones.write[33].handle_offset = Vector2(0.6, 0.8); |
691 | bones.write[33].group = "RightHand" ; |
692 | |
693 | bones.write[34].bone_name = "RightThumbProximal" ; |
694 | bones.write[34].bone_parent = "RightThumbMetacarpal" ; |
695 | bones.write[34].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.043, 0); |
696 | bones.write[34].handle_offset = Vector2(0.7, 0.69); |
697 | bones.write[34].group = "RightHand" ; |
698 | |
699 | bones.write[35].bone_name = "RightThumbDistal" ; |
700 | bones.write[35].bone_parent = "RightThumbProximal" ; |
701 | bones.write[35].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.043, 0); |
702 | bones.write[35].handle_offset = Vector2(0.77, 0.555); |
703 | bones.write[35].group = "RightHand" ; |
704 | |
705 | bones.write[36].bone_name = "RightIndexProximal" ; |
706 | bones.write[36].bone_parent = "RightHand" ; |
707 | bones.write[36].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.025, 0.075, 0); |
708 | bones.write[36].handle_offset = Vector2(0.587, 0.52); |
709 | bones.write[36].group = "RightHand" ; |
710 | |
711 | bones.write[37].bone_name = "RightIndexIntermediate" ; |
712 | bones.write[37].bone_parent = "RightIndexProximal" ; |
713 | bones.write[37].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.05, 0); |
714 | bones.write[37].handle_offset = Vector2(0.597, 0.36); |
715 | bones.write[37].group = "RightHand" ; |
716 | |
717 | bones.write[38].bone_name = "RightIndexDistal" ; |
718 | bones.write[38].bone_parent = "RightIndexIntermediate" ; |
719 | bones.write[38].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.025, 0); |
720 | bones.write[38].handle_offset = Vector2(0.597, 0.255); |
721 | bones.write[38].group = "RightHand" ; |
722 | |
723 | bones.write[39].bone_name = "RightMiddleProximal" ; |
724 | bones.write[39].bone_parent = "RightHand" ; |
725 | bones.write[39].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.075, 0); |
726 | bones.write[39].handle_offset = Vector2(0.5, 0.51); |
727 | bones.write[39].group = "RightHand" ; |
728 | |
729 | bones.write[40].bone_name = "RightMiddleIntermediate" ; |
730 | bones.write[40].bone_parent = "RightMiddleProximal" ; |
731 | bones.write[40].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.075, 0); |
732 | bones.write[40].handle_offset = Vector2(0.5, 0.345); |
733 | bones.write[40].group = "RightHand" ; |
734 | |
735 | bones.write[41].bone_name = "RightMiddleDistal" ; |
736 | bones.write[41].bone_parent = "RightMiddleIntermediate" ; |
737 | bones.write[41].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.025, 0); |
738 | bones.write[41].handle_offset = Vector2(0.5, 0.22); |
739 | bones.write[41].group = "RightHand" ; |
740 | |
741 | bones.write[42].bone_name = "RightRingProximal" ; |
742 | bones.write[42].bone_parent = "RightHand" ; |
743 | bones.write[42].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.025, 0.075, 0); |
744 | bones.write[42].handle_offset = Vector2(0.414, 0.52); |
745 | bones.write[42].group = "RightHand" ; |
746 | |
747 | bones.write[43].bone_name = "RightRingIntermediate" ; |
748 | bones.write[43].bone_parent = "RightRingProximal" ; |
749 | bones.write[43].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.05, 0); |
750 | bones.write[43].handle_offset = Vector2(0.41, 0.36); |
751 | bones.write[43].group = "RightHand" ; |
752 | |
753 | bones.write[44].bone_name = "RightRingDistal" ; |
754 | bones.write[44].bone_parent = "RightRingIntermediate" ; |
755 | bones.write[44].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.025, 0); |
756 | bones.write[44].handle_offset = Vector2(0.409, 0.25); |
757 | bones.write[44].group = "RightHand" ; |
758 | |
759 | bones.write[45].bone_name = "RightLittleProximal" ; |
760 | bones.write[45].bone_parent = "RightHand" ; |
761 | bones.write[45].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.05, 0.05, 0); |
762 | bones.write[45].handle_offset = Vector2(0.337, 0.543); |
763 | bones.write[45].group = "RightHand" ; |
764 | |
765 | bones.write[46].bone_name = "RightLittleIntermediate" ; |
766 | bones.write[46].bone_parent = "RightLittleProximal" ; |
767 | bones.write[46].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.05, 0); |
768 | bones.write[46].handle_offset = Vector2(0.328, 0.415); |
769 | bones.write[46].group = "RightHand" ; |
770 | |
771 | bones.write[47].bone_name = "RightLittleDistal" ; |
772 | bones.write[47].bone_parent = "RightLittleIntermediate" ; |
773 | bones.write[47].reference_pose = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.025, 0); |
774 | bones.write[47].handle_offset = Vector2(0.328, 0.32); |
775 | bones.write[47].group = "RightHand" ; |
776 | |
777 | bones.write[48].bone_name = "LeftUpperLeg" ; |
778 | bones.write[48].bone_parent = "Hips" ; |
779 | bones.write[48].reference_pose = Transform3D(-1, 0, 0, 0, -1, 0, 0, 0, 1, 0.1, 0, 0); |
780 | bones.write[48].handle_offset = Vector2(0.549, 0.49); |
781 | bones.write[48].group = "Body" ; |
782 | bones.write[48].require = true; |
783 | |
784 | bones.write[49].bone_name = "LeftLowerLeg" ; |
785 | bones.write[49].bone_parent = "LeftUpperLeg" ; |
786 | bones.write[49].reference_pose = Transform3D(-1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0.375, 0); |
787 | bones.write[49].handle_offset = Vector2(0.548, 0.683); |
788 | bones.write[49].group = "Body" ; |
789 | bones.write[49].require = true; |
790 | |
791 | bones.write[50].bone_name = "LeftFoot" ; |
792 | bones.write[50].bone_parent = "LeftLowerLeg" ; |
793 | bones.write[50].reference_pose = Transform3D(-1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0.375, 0); |
794 | bones.write[50].handle_offset = Vector2(0.545, 0.9); |
795 | bones.write[50].group = "Body" ; |
796 | bones.write[50].require = true; |
797 | |
798 | bones.write[51].bone_name = "LeftToes" ; |
799 | bones.write[51].bone_parent = "LeftFoot" ; |
800 | bones.write[51].reference_pose = Transform3D(-1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0.15, 0); |
801 | bones.write[51].handle_offset = Vector2(0.545, 0.95); |
802 | bones.write[51].group = "Body" ; |
803 | |
804 | bones.write[52].bone_name = "RightUpperLeg" ; |
805 | bones.write[52].bone_parent = "Hips" ; |
806 | bones.write[52].reference_pose = Transform3D(-1, 0, 0, 0, -1, 0, 0, 0, 1, -0.1, 0, 0); |
807 | bones.write[52].handle_offset = Vector2(0.451, 0.49); |
808 | bones.write[52].group = "Body" ; |
809 | bones.write[52].require = true; |
810 | |
811 | bones.write[53].bone_name = "RightLowerLeg" ; |
812 | bones.write[53].bone_parent = "RightUpperLeg" ; |
813 | bones.write[53].reference_pose = Transform3D(-1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0.375, 0); |
814 | bones.write[53].handle_offset = Vector2(0.452, 0.683); |
815 | bones.write[53].group = "Body" ; |
816 | bones.write[53].require = true; |
817 | |
818 | bones.write[54].bone_name = "RightFoot" ; |
819 | bones.write[54].bone_parent = "RightLowerLeg" ; |
820 | bones.write[54].reference_pose = Transform3D(-1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0.375, 0); |
821 | bones.write[54].handle_offset = Vector2(0.455, 0.9); |
822 | bones.write[54].group = "Body" ; |
823 | bones.write[54].require = true; |
824 | |
825 | bones.write[55].bone_name = "RightToes" ; |
826 | bones.write[55].bone_parent = "RightFoot" ; |
827 | bones.write[55].reference_pose = Transform3D(-1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0.15, 0); |
828 | bones.write[55].handle_offset = Vector2(0.455, 0.95); |
829 | bones.write[55].group = "Body" ; |
830 | } |
831 | |
832 | SkeletonProfileHumanoid::~SkeletonProfileHumanoid() { |
833 | } |
834 | |
835 | ////////////////////////////////////// |
836 | |