Skeleton.cpp 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. /******************************************************************************/
  5. #define CC4_SKEL CC4('S','K','E','L')
  6. // prioritize type so if we want to share animation between multiple skeletons, and one skeleton has bones: "Hips" BONE_SPINE 0:0, "Spine" BONE_SPINE 0:1, and another has "Spine" BONE_SPINE 0:0, "Spine1" BONE_SPINE 0:1, then we will match by type/index first
  7. #define FIND_BONE_PRIORITY_NAME 1
  8. #define FIND_BONE_PRIORITY_TYPE 2
  9. #define BONE_FRAC 0.3f
  10. /******************************************************************************/
  11. Cache<Skeleton> Skeletons("Skeleton");
  12. /******************************************************************************/
  13. static Str SkelName(C Skeleton *skel)
  14. {
  15. if(CChar *name=Skeletons.name(skel))return S+" \""+name+'"';
  16. return S;
  17. }
  18. static Bool Singular(BONE_TYPE type) // bones which usually occur single
  19. {
  20. switch(type)
  21. {
  22. case BONE_UNKNOWN:
  23. case BONE_SPINE :
  24. case BONE_NECK :
  25. case BONE_HEAD :
  26. case BONE_JAW :
  27. case BONE_TONGUE :
  28. case BONE_NOSE :
  29. case BONE_TAIL :
  30. case BONE_CAPE : return true;
  31. default : return false;
  32. }
  33. }
  34. static CChar8* BoneName_t[]=
  35. {
  36. "Unknown",
  37. "Spine",
  38. "Shoulder",
  39. "UpperArm",
  40. "Forearm",
  41. "Hand",
  42. "Finger",
  43. "UpperLeg",
  44. "LowerLeg",
  45. "Foot",
  46. "Toe",
  47. "Neck",
  48. "Head",
  49. "Jaw",
  50. "Tongue",
  51. "Nose",
  52. "Eye",
  53. "Eyelid",
  54. "Eyebrow",
  55. "Ear",
  56. "Breast",
  57. "Butt",
  58. "Tail",
  59. "Wing",
  60. "Cape",
  61. "Hair",
  62. }; ASSERT(Elms(BoneName_t)==BONE_NUM);
  63. CChar8* BoneName(BONE_TYPE type) {return InRange(type, BoneName_t) ? BoneName_t[type] : null;}
  64. /******************************************************************************/
  65. // SKELETON SLOT
  66. /******************************************************************************/
  67. SkelSlot::SkeletonSlot()
  68. {
  69. dir .set (0, 0, 1);
  70. perp.set (0, 1, 0);
  71. pos .zero( );
  72. name[0]=0;
  73. setParent(0xFF);
  74. }
  75. void SkelSlot::save(TextNode &node, C Skeleton *owner)C
  76. {
  77. node.set(name);
  78. super::save(node.nodes);
  79. if(owner)
  80. {
  81. if(InRange(bone , owner->bones))node.nodes.New().set("Bone" , owner->bones[bone ].name);
  82. if(InRange(bone1, owner->bones))node.nodes.New().set("Bone1", owner->bones[bone1].name);
  83. }
  84. }
  85. /******************************************************************************/
  86. // BONE ID
  87. /******************************************************************************/
  88. BoneID& BoneID::set(CChar8 *name, BONE_TYPE type, Int type_index, Int type_sub)
  89. {
  90. Set(T.name, name); T.type=type; T.type_index=type_index; T.type_sub=type_sub; return T;
  91. }
  92. Bool BoneID::operator==(C BoneID &id)C
  93. {
  94. return Equal(name, id.name)
  95. && type ==id.type
  96. && type_index==id.type_index
  97. && type_sub ==id.type_sub;
  98. }
  99. /******************************************************************************/
  100. // SKELETON BONE
  101. /******************************************************************************/
  102. SkelBone::SkeletonBone()
  103. {
  104. dir .set (0, 0, 1);
  105. perp.set (0, 1, 0);
  106. pos .zero( );
  107. parent=0xFF;
  108. children_offset=children_num=0;
  109. flag =0;
  110. length=0.3f;
  111. width =0.2f;
  112. offset.zero();
  113. shape .set(width*length, length, Vec(0, 0, 0.5f));
  114. }
  115. void SkelBone::draw(C Color &color)C
  116. {
  117. Vec drf=pos+dir*length*BONE_FRAC,
  118. to =pos+dir*length;
  119. Vec p = perp; p*=width*length*SQRT2_2;
  120. Vec pp=Cross(dir , p);
  121. Vec p1=drf+p+pp,
  122. p2=drf+p-pp,
  123. p3=drf-p-pp,
  124. p4=drf-p+pp;
  125. VI.color(color);
  126. VI.line(to, p1); VI.line(pos, p1);
  127. VI.line(to, p2); VI.line(pos, p2);
  128. VI.line(to, p3); VI.line(pos, p3);
  129. VI.line(to, p4); VI.line(pos, p4);
  130. VI.line(p1, p2);
  131. VI.line(p2, p3);
  132. VI.line(p3, p4);
  133. VI.line(p4, p1);
  134. VI.line(pos, pos+p);
  135. VI.end();
  136. }
  137. void SkelBone::save(TextNode &node, C Skeleton *owner)C
  138. {
  139. node.set(name);
  140. super::save(node.nodes);
  141. node.nodes.New().set("Length", length);
  142. node.nodes.New().set("Width" , width );
  143. node.nodes.New().set("Flag" , flag );
  144. if(owner && InRange(parent, owner->bones))node.nodes.New().set("Parent", owner->bones[parent].name);
  145. }
  146. /******************************************************************************/
  147. SkelBone& SkelBone::operator+=(C Vec &v)
  148. {
  149. pos +=v;
  150. shape+=v;
  151. return T;
  152. }
  153. SkelBone& SkelBone::operator-=(C Vec &v)
  154. {
  155. pos -=v;
  156. shape-=v;
  157. return T;
  158. }
  159. SkelBone& SkelBone::operator*=(C Vec &v)
  160. {
  161. pos *=v;
  162. dir *=v;
  163. perp *=v;
  164. length*=dir.normalize();
  165. offset*=v;
  166. shape *=v;
  167. fixPerp();
  168. return T;
  169. }
  170. SkelBone& SkelBone::operator*=(C Matrix3 &matrix)
  171. {
  172. pos *=matrix;
  173. dir *=matrix;
  174. perp *=matrix;
  175. length*=dir.normalize();
  176. offset*=matrix;
  177. shape *=matrix;
  178. fixPerp();
  179. return T;
  180. }
  181. SkelBone& SkelBone::operator/=(C Matrix3 &matrix)
  182. {
  183. pos /=matrix;
  184. dir /=matrix;
  185. perp /=matrix;
  186. length*=dir.normalize(); // 'length' should indeed be multiplied here because 'dir' already got transformed in correct way
  187. offset/=matrix;
  188. shape /=matrix;
  189. fixPerp();
  190. return T;
  191. }
  192. SkelBone& SkelBone::operator*=(C Matrix &matrix)
  193. {
  194. pos *=matrix;
  195. dir *=matrix.orn();
  196. perp *=matrix.orn();
  197. length*=dir .normalize();
  198. offset*=matrix.orn(); // !! position should not be applied here !!
  199. shape *=matrix;
  200. fixPerp();
  201. return T;
  202. }
  203. SkelBone& SkelBone::operator/=(C Matrix &matrix)
  204. {
  205. pos /=matrix;
  206. dir /=matrix.orn();
  207. perp /=matrix.orn();
  208. length*=dir .normalize(); // 'length' should indeed be multiplied here because 'dir' already got transformed in correct way
  209. offset/=matrix.orn(); // !! position should not be applied here !!
  210. shape /=matrix;
  211. fixPerp();
  212. return T;
  213. }
  214. /******************************************************************************/
  215. SkelBone& SkelBone::mirrorX () {super::mirrorX (); CHS (offset.x); return T;}
  216. SkelBone& SkelBone::mirrorY () {super::mirrorY (); CHS (offset.y); return T;}
  217. SkelBone& SkelBone::mirrorZ () {super::mirrorZ (); CHS (offset.z); return T;}
  218. SkelBone& SkelBone::rightToLeft() {super::rightToLeft(); offset.rightToLeft(); return T;}
  219. /******************************************************************************/
  220. SkelBone& SkelBone::setFromTo(C Vec &from, C Vec &to)
  221. {
  222. Vec f=from; // operate on copy in case 'from' is set to 'pos' or 'dir'
  223. dir =to-f; // set 'dir' first because it uses 2 variables
  224. pos = f; // set 'pos' next and from the backup variable in case 'from' was set to 'dir' which is now different
  225. length=dir.normalize();
  226. fixPerp();
  227. return T;
  228. }
  229. /******************************************************************************/
  230. // SKELETON
  231. /******************************************************************************/
  232. Skeleton::Skeleton() : _skel_anims("Animation", 8)
  233. {
  234. _skel_anims.setLoadUser(this);
  235. }
  236. Skeleton::Skeleton(C Skeleton &src) : Skeleton() {T=src;}
  237. Skeleton& Skeleton::del()
  238. {
  239. _skel_anims.del();
  240. bones .del();
  241. slots .del();
  242. return T;
  243. }
  244. Skeleton& Skeleton::operator=(C Skeleton &src)
  245. {
  246. if(this!=&src)
  247. {
  248. _skel_anims.del();
  249. bones=src.bones;
  250. slots=src.slots;
  251. }
  252. return T;
  253. }
  254. /******************************************************************************/
  255. Skeleton& Skeleton::move(C Vec &move)
  256. {
  257. REPAO(bones)+=move;
  258. REPAO(slots)+=move;
  259. return T;
  260. }
  261. Skeleton& Skeleton::scale(C Vec &scale)
  262. {
  263. REPAO(bones)*=scale;
  264. REPAO(slots)*=scale;
  265. return T;
  266. }
  267. Skeleton& Skeleton::scaleMove(C Vec &scale, C Vec &move)
  268. {
  269. REPA(bones)(bones[i]*=scale)+=move;
  270. REPA(slots)(slots[i]*=scale)+=move;
  271. return T;
  272. }
  273. Skeleton& Skeleton::transform(C Matrix3 &matrix)
  274. {
  275. REPAO(bones)*=matrix;
  276. REPAO(slots)*=matrix;
  277. return T;
  278. }
  279. Skeleton& Skeleton::transform(C Matrix &matrix)
  280. {
  281. REPAO(bones)*=matrix;
  282. REPAO(slots)*=matrix;
  283. return T;
  284. }
  285. Skeleton& Skeleton::animate(C AnimatedSkeleton &skel)
  286. {
  287. REPAO(bones)*=skel.bones[i].matrix();
  288. REPAO(slots) =skel.slots[i];
  289. return T;
  290. }
  291. Skeleton& Skeleton::mirrorX()
  292. {
  293. REPAO(bones).mirrorX();
  294. REPAO(slots).mirrorX();
  295. return T;
  296. }
  297. Skeleton& Skeleton::mirrorY()
  298. {
  299. REPAO(bones).mirrorY();
  300. REPAO(slots).mirrorY();
  301. return T;
  302. }
  303. Skeleton& Skeleton::mirrorZ()
  304. {
  305. REPAO(bones).mirrorZ();
  306. REPAO(slots).mirrorZ();
  307. return T;
  308. }
  309. Skeleton& Skeleton::rightToLeft()
  310. {
  311. REPAO(bones).rightToLeft();
  312. REPAO(slots).rightToLeft();
  313. return T;
  314. }
  315. /******************************************************************************/
  316. SkelBone* Skeleton::findBone (BONE_TYPE type, Int type_index, Int type_sub) {return bones.addr(findBoneI(type, type_index, type_sub));}
  317. Byte Skeleton::findBoneB(BONE_TYPE type, Int type_index, Int type_sub)C {Int i=findBoneI(type, type_index, type_sub); return InRange(i, 256) ? i : 255;}
  318. Int Skeleton::findBoneI(BONE_TYPE type, Int type_index, Int type_sub)C
  319. {
  320. if(type)REPA(bones)
  321. {
  322. C SkelBone &bone=bones[i];
  323. if(bone.type==type && bone.type_index==type_index && bone.type_sub==type_sub)return i;
  324. }
  325. return -1;
  326. }
  327. SkelBone* Skeleton::findBone (CChar8 *name, BONE_TYPE type, Int type_index, Int type_sub) {return bones.addr(findBoneI(name, type, type_index, type_sub));}
  328. Int Skeleton::findBoneI(CChar8 *name, BONE_TYPE type, Int type_index, Int type_sub)C
  329. {
  330. Int bone_index=-1, best_match=0;
  331. REPA(bones)
  332. {
  333. C SkelBone &bone=bones[i];
  334. Int match=0;
  335. if(Equal(bone.name, name))match+=FIND_BONE_PRIORITY_NAME;
  336. if(type && bone.type==type && bone.type_index==type_index && bone.type_sub==type_sub)match+=FIND_BONE_PRIORITY_TYPE; // check this only if 'type' is specified
  337. if(match>best_match)
  338. {
  339. bone_index=i;
  340. best_match=match;
  341. if(match==FIND_BONE_PRIORITY_NAME+FIND_BONE_PRIORITY_TYPE)break; // if found highest possible match then stop
  342. }
  343. }
  344. return bone_index;
  345. }
  346. Int Animation::findBoneI(CChar8 *name, BONE_TYPE type, Int type_index, Int type_sub)C
  347. {
  348. Int bone_index=-1, best_match=0;
  349. REPA(bones)
  350. {
  351. C AnimBone &bone=bones[i];
  352. Int match=0;
  353. if(Equal(bone.name, name))match+=FIND_BONE_PRIORITY_NAME;
  354. if(type && bone.type==type && bone.type_index==type_index && bone.type_sub==type_sub)match+=FIND_BONE_PRIORITY_TYPE; // check this only if 'type' is specified
  355. if(match>best_match)
  356. {
  357. bone_index=i;
  358. best_match=match;
  359. if(match==FIND_BONE_PRIORITY_NAME+FIND_BONE_PRIORITY_TYPE)break; // if found highest possible match then stop
  360. }
  361. }
  362. return bone_index;
  363. }
  364. Int BoneMap::find(CChar8 *name, BONE_TYPE type, Int type_index, Int type_sub)C
  365. {
  366. Int bone_index=-1, best_match=0;
  367. REP(_bones)
  368. {
  369. C Bone &bone=_bone[i];
  370. Int match=0;
  371. if(Equal(T.name(i), name))match+=FIND_BONE_PRIORITY_NAME;
  372. if(type && bone.type==type && bone.type_index==type_index && bone.type_sub==type_sub)match+=FIND_BONE_PRIORITY_TYPE; // check this only if 'type' is specified
  373. if(match>best_match)
  374. {
  375. bone_index=i;
  376. best_match=match;
  377. if(match==FIND_BONE_PRIORITY_NAME+FIND_BONE_PRIORITY_TYPE)break; // if found highest possible match then stop
  378. }
  379. }
  380. return bone_index;
  381. }
  382. Int Skeleton::findBoneI(CChar8 *name )C {if(Is(name))REPA(bones)if(Equal(bones[i].name, name))return i; return -1;}
  383. Int Skeleton::findSlotI(CChar8 *name )C {if(Is(name))REPA(slots)if(Equal(slots[i].name, name))return i; return -1;}
  384. Byte Skeleton::findSlotB(CChar8 *name )C {Int i=findSlotI(name ); return InRange(i, 256) ? i : 255;}
  385. Int Skeleton:: getBoneI(BONE_TYPE type, Int type_index, Int type_sub)C {Int i=findBoneI(type, type_index, type_sub); if(i<0)Exit(S+"Bone "+BoneName(type)+':'+type_index+':'+type_sub+" not found in skeleton"+SkelName(this)+'.'); return i;}
  386. Int Skeleton:: getBoneI(CChar8 *name )C {Int i=findBoneI(name ); if(i<0)Exit(S+"Bone \""+ name +"\" not found in skeleton"+SkelName(this)+'.'); return i;}
  387. Int Skeleton:: getSlotI(CChar8 *name )C {Int i=findSlotI(name ); if(i<0)Exit(S+"Slot \""+ name +"\" not found in skeleton"+SkelName(this)+'.'); return i;}
  388. SkelBone* Skeleton::findBone (CChar8 *name ) {return bones.addr(findBoneI(name));}
  389. SkelSlot* Skeleton::findSlot (CChar8 *name ) {return slots.addr(findSlotI(name));}
  390. SkelBone& Skeleton:: getBone (BONE_TYPE type, Int type_index, Int type_sub) {return bones [ getBoneI(type, type_index, type_sub)];}
  391. SkelBone& Skeleton:: getBone (CChar8 *name ) {return bones [ getBoneI(name)];}
  392. SkelSlot& Skeleton:: getSlot (CChar8 *name ) {return slots [ getSlotI(name)];}
  393. /******************************************************************************/
  394. Bool Skeleton::contains(Int parent, Int child)C
  395. {
  396. if(parent<0)parent=0xFF;
  397. if(child <0)child =0xFF;
  398. if(parent==child)return true; // if contains self ('parent' contains 'child' where both are the same)
  399. for(; InRange(child, bones); )
  400. {
  401. Int child_parent=bones[child].parent; // get 'child' parent
  402. if( child_parent==parent)return true;
  403. if( child_parent>=child )break; // proceed only if the parent has a smaller index (this solves the issue of never ending loops with incorrect data)
  404. child=child_parent;
  405. }
  406. return false;
  407. }
  408. UInt Skeleton::memUsage()C
  409. {
  410. return bones.memUsage()
  411. +slots.memUsage();
  412. }
  413. Int Skeleton::boneRoot(Int bone)C
  414. {
  415. if(InRange(bone, bones))
  416. {
  417. again:
  418. Int parent=boneParent(bone); if(parent>=0){bone=parent; goto again;}
  419. return bone;
  420. }
  421. return -1;
  422. }
  423. Int Skeleton::boneParent(Int bone)C
  424. {
  425. if(InRange(bone, bones))
  426. {
  427. Int parent=bones[bone].parent;
  428. if(InRange(parent, bones) && parent<bone)return parent; // parent index must always be smaller than of the bone
  429. }
  430. return -1;
  431. }
  432. Int Skeleton::boneParents(Int bone)C
  433. {
  434. Int parents=0;
  435. for(;; parents++)
  436. {
  437. bone=boneParent(bone);
  438. if(bone<0)break;
  439. }
  440. return parents;
  441. }
  442. Int Skeleton::boneLevel(Int bone)C {return boneParents(bone)+InRange(bone, bones);}
  443. Int Skeleton::findParent(Int bone, BONE_TYPE type)C
  444. {
  445. for(;;)
  446. {
  447. bone=boneParent(bone); if(bone<0)break;
  448. if(bones[bone].type==type)return bone;
  449. }
  450. return -1;
  451. }
  452. Int Skeleton::findRagdollParent(Int bone_index)C
  453. {
  454. for(; InRange(bone_index, bones); )
  455. {
  456. C SkelBone &bone=bones[bone_index];
  457. if(bone.flag&BONE_RAGDOLL)return bone_index;
  458. if(bone.parent>=bone_index)break; // proceed only if the parent has a smaller index (this solves the issue of never ending loops with incorrect data)
  459. bone_index=bone.parent;
  460. }
  461. return -1;
  462. }
  463. struct BoneParents
  464. {
  465. Byte bone, parents;
  466. };
  467. Int Skeleton::bonesSharedParent(MemPtr<Byte, 256> bones)C
  468. {
  469. MemtN<BoneParents, 256> bone_parents;
  470. bone_parents.setNum(bones.elms());
  471. Int min_parents=-1;
  472. REPA(bones)
  473. {
  474. BoneParents &bp=bone_parents[i];
  475. bp.bone =bones[i];
  476. bp.parents=boneParents(bp.bone);
  477. if(min_parents<0)min_parents=bp.parents;else MIN(min_parents, bp.parents);
  478. }
  479. if(min_parents>0) // there's at least one parent
  480. {
  481. // make all bones to be at the same depth
  482. REPA(bone_parents)
  483. {
  484. BoneParents &bp=bone_parents[i];
  485. REP(bp.parents-min_parents+1)bp.bone=T.bones[bp.bone].parent; // +1 to set all bones to their parents
  486. }
  487. // keep checking each parent for all bones if it's the same (starting from leaf to root)
  488. for(;;)
  489. {
  490. Int parent=bone_parents.last().bone;
  491. REP(bone_parents.elms()-1)if(bone_parents[i].bone!=parent)goto different;
  492. return parent; // all parents are the same
  493. different:
  494. if(!--min_parents)break;
  495. REPA(bone_parents)bone_parents[i].bone=T.bones[bone_parents[i].bone].parent;
  496. }
  497. }
  498. return 0xFF;
  499. }
  500. Int Skeleton::hierarchyDistance(Int bone_a, Int bone_b)C
  501. {
  502. Int a_level=boneLevel(bone_a),
  503. b_level=boneLevel(bone_b);
  504. if(!a_level)return b_level;
  505. if(!b_level)return a_level;
  506. // put bones to the same depth
  507. Int min_level=Min(a_level, b_level);
  508. Int dist=a_level-min_level; REP(dist)bone_a=bones[bone_a].parent;
  509. Int d =b_level-min_level; REP(d )bone_b=bones[bone_b].parent; dist+=d;
  510. // find a shared bone
  511. for(;;)
  512. {
  513. if(bone_a==bone_b)break;
  514. dist+=2; // add 2 because each bone moves once
  515. if(!--min_level)break;
  516. bone_a=bones[bone_a].parent;
  517. bone_b=bones[bone_b].parent;
  518. }
  519. return dist;
  520. }
  521. /******************************************************************************/
  522. void Skeleton::getSkin(C Vec &pos, VecB4 &blend, VecB4 &matrix)C
  523. {
  524. Int find[2]={-1, -1};
  525. Flt dist[2]={ 0, 0};
  526. REPA(bones)
  527. {
  528. C SkelBone &bone=bones[i];
  529. if(DistPointPlane(pos, bone.pos, bone.dir)>=-0.5f*BONE_FRAC *bone.length &&
  530. DistPointStr (pos, bone.pos, bone.dir)<= 2.5f*bone.width*bone.length)
  531. {
  532. Flt d=DistPointEdge(pos, bone.pos, bone.to());
  533. if(find[0]<0 || d<dist[0])
  534. {
  535. find[1]=find[0];
  536. dist[1]=dist[0];
  537. find[0]=i;
  538. dist[0]=d;
  539. }else
  540. if(find[1]<0 || d<dist[1])
  541. {
  542. find[1]=i;
  543. dist[1]=d;
  544. }
  545. }
  546. }
  547. if(find[0]<0)
  548. {
  549. matrix=0;
  550. blend .set(255, 0, 0, 0);
  551. }else
  552. if(find[1]<0)
  553. {
  554. C SkelBone &bone=bones[find[0]];
  555. matrix.c[0]=( 1+find[0] );
  556. matrix.c[1]=((bone.parent==0xFF) ? 0 : 1+bone.parent);
  557. matrix.c[2]=0;
  558. matrix.c[3]=0;
  559. Byte b=RoundU(Sat(DistPointPlane(pos, bone.pos, bone.dir)/(BONE_FRAC*bone.length)+0.5f)*255);
  560. blend.set(b, 255-b, 0, 0);
  561. }else
  562. if(bones[find[0]].parent==find[1] || bones[find[1]].parent==find[0])
  563. {
  564. Int parent, child; MinMax(find[0], find[1], parent, child);
  565. C SkelBone &bone=bones[child];
  566. matrix.c[0]=1+child;
  567. matrix.c[1]=1+parent;
  568. matrix.c[2]=0;
  569. matrix.c[3]=0;
  570. Byte b=RoundU(Sat(DistPointPlane(pos, bone.pos, bone.dir)/(BONE_FRAC*bone.length)+0.5f)*255);
  571. blend.set(b, 255-b, 0, 0);
  572. }else
  573. /*if(smooth)
  574. {
  575. matrix.c[0]=1+find[0];
  576. matrix.c[1]=1+find[1];
  577. matrix.c[2]=0;
  578. matrix.c[3]=0;
  579. Byte b=RoundU(Sat(dist[0]/(dist[0]+dist[1]))*255);
  580. blend.set(b, 255-b, 0, 0);
  581. }else*/
  582. {
  583. C SkelBone &bone=bones[find[0]];
  584. matrix.c[0]=( 1+find[0] );
  585. matrix.c[1]=((bone.parent==0xFF) ? 0 : 1+bone.parent);
  586. matrix.c[2]=0;
  587. matrix.c[3]=0;
  588. Byte b=RoundU(Sat(DistPointPlane(pos, bone.pos, bone.dir)/(BONE_FRAC*bone.length)+0.5f)*255);
  589. blend.set(b, 255-b, 0, 0);
  590. }
  591. }
  592. /******************************************************************************/
  593. void Skeleton::boneRemap(C MemPtr<Byte, 256> &old_to_new) // !! this does not modify 'children_offset' and 'children_num' !!
  594. {
  595. #if 1 // clear out of range
  596. REPA(bones){Byte &b =bones[i].parent; b =(InRange(b , old_to_new) ? old_to_new[b ] : 0xFF);}
  597. REPA(slots){Byte &b =slots[i].bone ; b =(InRange(b , old_to_new) ? old_to_new[b ] : 0xFF);
  598. Byte &b1=slots[i].bone1 ; b1=(InRange(b1, old_to_new) ? old_to_new[b1] : 0xFF);}
  599. #else // keep out of range
  600. if(old_to_new.elms())
  601. {
  602. REPA(bones){Byte &b =bones[i].parent; if(InRange(b , old_to_new))b =old_to_new[b ];}
  603. REPA(slots){Byte &b =slots[i].bone ; if(InRange(b , old_to_new))b =old_to_new[b ];
  604. Byte &b1=slots[i].bone1 ; if(InRange(b1, old_to_new))b1=old_to_new[b1];}
  605. }
  606. #endif
  607. }
  608. Bool Skeleton::removeBone(Int i, MemPtr<Byte, 256> old_to_new)
  609. {
  610. if(InRange(i, bones))
  611. {
  612. SkelBone &bone=bones[i];
  613. #if 0 // this is not done, instead 'setBoneTypes' is called to handle 'type_index' as well
  614. // adjust 'type_sub', performing this is optional
  615. if(bone.type)for(Int j=i+1; j<bones.elms(); j++)
  616. {
  617. SkelBone &test=bones[j];
  618. if(test.type==bone.type && test.type_index==bone.type_index && test.type_sub>bone.type_sub)test.type_sub--;
  619. }
  620. #endif
  621. Memt<Byte, 256> otn_rem; otn_rem.setNum(bones.elms());
  622. FREPD(j, i) otn_rem[j]=j ; // all before 'i' are not changed
  623. otn_rem[i]=bone.parent; // 'i' is changed to parent of removed bone (parent index is always smaller than that bone)
  624. for(Int j=i+1; j<bones.elms(); j++)otn_rem[j]=j-1 ; // all after 'i' are set to index-1
  625. bones.remove(i, true);
  626. boneRemap(otn_rem);
  627. // since we're assigning children of 'bone' to its parent, we need to sort the bones
  628. Memt<Byte, 256> otn_sort; sortBones(otn_sort);
  629. setBoneTypes(); // call this because 'type_index' and 'type_sub' could have changed
  630. if(old_to_new)
  631. {
  632. old_to_new.setNum(otn_rem.elms());
  633. REPA(old_to_new)
  634. {
  635. Byte otn=otn_rem[i];
  636. old_to_new[i]=(InRange(otn, otn_sort) ? otn_sort[otn] : 0xFF);
  637. }
  638. }
  639. return true;
  640. }
  641. old_to_new.clear();
  642. return false;
  643. }
  644. Skeleton& Skeleton::add(C Skeleton &src, MemPtr<Byte, 256> old_to_new) // !! assumes that skeletons have different bone names !!
  645. {
  646. if(&src==this)return T;
  647. Int offset=bones.elms();
  648. FREPA(src.bones) // copy in the same order
  649. {
  650. C SkelBone &s=src.bones[i];
  651. SkelBone &d= bones.New();
  652. d=s; if(d.parent!=0xFF)d.parent+=offset;
  653. }
  654. FREPA(src.slots) // copy in the same order
  655. {
  656. C SkelSlot &s=src.slots[i];
  657. SkelSlot &d= slots.New();
  658. d=s;
  659. if(d.bone !=0xFF)d.bone +=offset;
  660. if(d.bone1!=0xFF)d.bone1+=offset;
  661. }
  662. return sortBones(old_to_new).setBoneTypes();
  663. }
  664. Skeleton& Skeleton::addSlots(C Skeleton &src)
  665. {
  666. if(&src==this)return T;
  667. FREPA(src.slots) // copy in the same order
  668. {
  669. C SkelSlot &s=src.slots[i];
  670. SkelSlot &d= slots.New();
  671. d=s;
  672. d.bone=0xFF;
  673. if(C SkelBone *bone=src.bones.addr(s.bone)) // get bone in 'src' skeleton that 's' slot is attached to
  674. {
  675. Int i=findBoneI(bone->name, bone->type, bone->type_index, bone->type_sub); // find that bone in this skeleton
  676. if(i>=0)d.bone=i;
  677. }
  678. d.bone1=0xFF;
  679. if(C SkelBone *bone=src.bones.addr(s.bone1)) // get bone in 'src' skeleton that 's' slot is attached to
  680. {
  681. Int i=findBoneI(bone->name, bone->type, bone->type_index, bone->type_sub); // find that bone in this skeleton
  682. if(i>=0)d.bone1=i;
  683. }
  684. }
  685. return T;
  686. }
  687. /******************************************************************************/
  688. static void AddChildren(Skeleton &skeleton, MemtN<Int, 256> &order, Byte parent)
  689. {
  690. Int start=order.elms(), // number of bones added at this point
  691. elms =Min(skeleton.bones.elms(), 0xFF); // don't process bone with index 0xFF because this is assumed to be <null> and would trigger adding bones from the start (never ending loop)
  692. SkelBone *parent_bone=skeleton.bones.addr(parent); // get parent bone (if any) for further processing
  693. if( parent_bone)parent_bone->children_offset=order.elms(); // set parent children offset
  694. FREP(elms) // process forward, to try preserving existing order, this is very important as some codes may need this
  695. if(skeleton.bones[i].parent==parent) // if bone is a child of current parent
  696. {
  697. if(parent_bone)parent_bone->children_num++; // increase children number
  698. order.add(i); // add i-th bone to the order of added bones
  699. }
  700. Int end=order.elms(); // number of bones added at this point !! keep it as a variable because calls to 'AddChildren' below will change the order.elms !!
  701. for(Int i=start; i<end; i++) // process forward, to try preserving existing order
  702. AddChildren(skeleton, order, order[i]); // add children of bones that were added in above step
  703. }
  704. Skeleton& Skeleton::sortBones(MemPtr<Byte, 256> old_to_new)
  705. {
  706. REPA(bones){SkelBone &bone=bones[i]; bone.children_offset=bone.children_num=0;} // reset data first
  707. MemtN<Int , 256> order; AddChildren(T, order, 0xFF);
  708. Memt <Byte, 256> otn ; otn .setNum(bones.elms()); REPAO(otn)=0xFF;
  709. Mems <SkelBone > temp ; temp.setNum(order.elms());
  710. REPA(order)
  711. {
  712. Int old =order[i];
  713. otn [old]=i;
  714. temp[i ]=bones[old];
  715. }
  716. Swap(temp, bones);
  717. boneRemap(otn);
  718. if(old_to_new)old_to_new=otn;
  719. return T;
  720. }
  721. Skeleton& Skeleton::setBoneLengths()
  722. {
  723. const Flt min_bone_length=0.005f;
  724. // maximize lengths of bones which have children
  725. FREPA(bones) // process in order because we're first clearing the bone lengths
  726. {
  727. SkelBone &bone=bones[i]; bone.length=0;
  728. if(InRange(bone.parent, bones))
  729. {
  730. SkelBone &parent=bones[bone.parent];
  731. MAX(parent.length, DistPointPlane(bone.pos, parent.pos, parent.dir));
  732. }
  733. }
  734. // calculate average bone length
  735. Flt avg_length=0;
  736. Int avg_length_num=0;
  737. REPA(bones)if(Flt length=bones[i].length)
  738. {
  739. avg_length+=length;
  740. avg_length_num++;
  741. }
  742. if(avg_length_num)avg_length/=avg_length_num;else
  743. if(bones.elms() )
  744. {
  745. Box box=bones[0].pos; REPA(bones)box.include(bones[i].pos);
  746. avg_length=box.size().length()*0.08f;
  747. }
  748. MAX(avg_length, min_bone_length);
  749. // set lengths for bones which weren't set yet
  750. Flt min_length=Max(min_bone_length, avg_length*0.05f);
  751. FREPA(bones) // process in order because we're checking parents, so we want to process them first
  752. {
  753. SkelBone &bone=bones[i];
  754. if(bone.length<=min_length)bone.length=(InRange(bone.parent, bones) ? bones[bone.parent].length : avg_length);
  755. }
  756. return T;
  757. }
  758. /******************************************************************************/
  759. struct BoneOrder
  760. {
  761. Int bone_i, parent;
  762. Flt order;
  763. void set(Int bone_i, Int parent, Flt order) {T.bone_i=bone_i; T.parent=parent; T.order=order;}
  764. static Int Compare(C BoneOrder &a, C BoneOrder &b) {if(Int c=::Compare(a.parent, b.parent))return c; return ::Compare(a.order, b.order);}
  765. };
  766. static inline Bool Lower(Char8 c) {return c>='a' && c<='z';}
  767. static inline Bool Upper(Char8 c) {return c>='A' && c<='Z';}
  768. static Bool BoneName(C SkelBone &bone, CChar8 *name) // this works as 'Contains' with extra checking for previous/next characters
  769. {
  770. if(Int length=Length(name))
  771. for(CChar8 *start=bone.name; start=TextPos(start, name); )
  772. {
  773. if(start!=bone.name) // check previous character (if there's any)
  774. {
  775. if(Lower(*start)) // if found text starts from a lowercase character
  776. {
  777. Char8 p=start[-1]; // get previous character
  778. if(Lower(p) || Upper(p))goto next; // if it's a character
  779. }
  780. Bool lower=false; REP(length)if(Lower(start[i])){lower=true; break;} // check if there's at least one lowercase character
  781. if( lower) // check only if at least one lowercase, don't check if all uppercase
  782. REP(length)
  783. if(Upper(start[i]) // if this is an uppercase character
  784. && Lower(name [i])) // but the requested character is lowercase (uppercase not allowed) then fail, this is for things like "HipSHJnt" to be detected as "Hip" instead of "Hips"
  785. goto next;
  786. }
  787. if(Lower(start[length]))goto next; // if next character is lowercase then fail
  788. return true;
  789. next:
  790. start++;
  791. }
  792. return false;
  793. }
  794. #define UNASSIGNED (-128)
  795. static Int BoneTypeIndex(C Skeleton &skel, C SkelBone &bone) // this function needs to be used to check all parents recursively, because we're processing elements out of order (for example we're processing Head bones in Hydra model, and we're asking for type indexes of their parents (necks) however some leaf-necks may still have UNASSIGNED because only root-necks are set)
  796. {
  797. if(bone.type_index!=UNASSIGNED)return bone.type_index; // if already known, then set
  798. for(Int cur=skel.bones.index(&bone); ; ) // iterate all parents until a parent of same type with known index is found
  799. {
  800. cur=skel.boneParent(cur); if(cur<0)break;
  801. C SkelBone &parent=skel.bones[cur]; if(parent.type==bone.type && parent.type_index!=UNASSIGNED)return parent.type_index;
  802. }
  803. return 0;
  804. }
  805. static Int BoneTypeIndexSub(C Skeleton &skel, C SkelBone &bone)
  806. {
  807. Byte index=Abs(BoneTypeIndex(skel, bone)); // use Abs because of negative numbers
  808. return (index<<8)|(255-bone.type_sub); // prioritize index and reverse order for sub-index (to make shoulders have lowest type index when they belong to most furthest bones, for example monsters with 4 shoulders/arms will have top shoulders/arms with 0 and -1 indexes, while lower shoulders/arms will have 1 and -2 indexes)
  809. }
  810. Skeleton& Skeleton::setBoneTypes()
  811. {
  812. REPA(bones)
  813. {
  814. SkelBone &bone=bones[i];
  815. BONE_TYPE type=BONE_UNKNOWN;
  816. // leave not unique names (such as "arm", "leg", "eye" and "head") at the end
  817. if(BoneName(bone, "Spine") || BoneName(bone, "Pelvis") || BoneName(bone, "Hips") || BoneName(bone, "Chest") || BoneName(bone, "Torso") || BoneName(bone, "Body") || BoneName(bone, "Ribs") || BoneName(bone, "RibCage") || BoneName(bone, "Rib Cage") || BoneName(bone, "Rib_Cage"))type=BONE_SPINE;else
  818. if(BoneName(bone, "Shoulder") || BoneName(bone, "Shoulders") || BoneName(bone, "Clavicle") || BoneName(bone, "CollarBone"))type=BONE_SHOULDER;else // "Shoulders" used by "Orcs"
  819. if(BoneName(bone, "ForeArm") || BoneName(bone, "LowerArm") || BoneName(bone, "Elbow"))type=BONE_LOWER_ARM;else // "Elbow" used by "Fire Ice Elemental"
  820. if(BoneName(bone, "Hand") || BoneName(bone, "Wrist") || BoneName(bone, "Palm") && !BoneName(bone, "LegPalm"))type=BONE_HAND;else
  821. if(BoneName(bone, "Finger") || BoneName(bone, "Fingers") || BoneName(bone, "Fing"))type=BONE_FINGER;else // "Fingers" used by "Troll", "Fing" used by "Hit Man"
  822. if(BoneName(bone, "Calf") || BoneName(bone, "Crus") || BoneName(bone, "Shin") || BoneName(bone, "LowerLeg") || BoneName(bone, "HorseLink") || BoneName(bone, "Knee"))type=BONE_LOWER_LEG;else
  823. if(BoneName(bone, "Toe") || BoneName(bone, "Toes") || Equal(bone.name, "FootL0") || Equal(bone.name, "FootR0"))type=BONE_TOE;else // "Toes" used by "Cyclop", "FootL0/FootR0" is from the EE recommended naming system
  824. if(BoneName(bone, "Foot") || BoneName(bone, "Feet") || BoneName(bone, "Ankle") || BoneName(bone, "LegPalm"))type=BONE_FOOT;else // "LegPalm" used by "Wolf"
  825. if(BoneName(bone, "Neck"))type=BONE_NECK;else
  826. if(BoneName(bone, "Jaw"))type=BONE_JAW;else
  827. if(BoneName(bone, "Tongue"))type=BONE_TONGUE;else
  828. if(BoneName(bone, "Nose") || BoneName(bone, "Snout"))type=BONE_NOSE;else
  829. //if(BoneName(bone, "Mouth") || BoneName(bone, "Lips") || BoneName(bone, "Lip"))type=BONE_MOUTH;else
  830. if(BoneName(bone, "EyeLid") || BoneName(bone, "EyeLids"))type=BONE_EYELID;else
  831. if(BoneName(bone, "EyeBrow") || BoneName(bone, "EyeBrows") || BoneName(bone, "Brows"))type=BONE_EYEBROW;else // "brows" used by BitGem animals
  832. if(BoneName(bone, "Ear"))type=BONE_EAR;else
  833. if(BoneName(bone, "Hair"))type=BONE_HAIR;else
  834. if(BoneName(bone, "Breast") || BoneName(bone, "Boob"))type=BONE_BREAST;else
  835. if(BoneName(bone, "Butt") || BoneName(bone, "Buttock"))type=BONE_BUTT;else
  836. if(BoneName(bone, "Tail") && !BoneName(bone, "PonyTail") && !BoneName(bone, "Pony Tail") && !BoneName(bone, "Pony_Tail"))type=BONE_TAIL;else
  837. if(BoneName(bone, "Wing") || BoneName(bone, "Wings"))type=BONE_WING;else // "Wings" used by "Bat"
  838. if(BoneName(bone, "Cape") || BoneName(bone, "Cloak"))type=BONE_CAPE;else
  839. // not unique names
  840. if(BoneName(bone, "Eye"))type=BONE_EYE;else
  841. if(BoneName(bone, "Head"))type=BONE_HEAD;else // this can be "HeadJaw"
  842. if(BoneName(bone, "Arm") || BoneName(bone, "UpArm") || BoneName(bone, "UpperArm"))type=BONE_UPPER_ARM;else // this can be both BONE_UPPER_ARM and BONE_LOWER_ARM
  843. if(BoneName(bone, "Thigh") || BoneName(bone, "Leg") || BoneName(bone, "UpLeg") || BoneName(bone, "UpperLeg") || BoneName(bone, "Hip"))type=BONE_UPPER_LEG;else // this can be both BONE_UPPER_LEG and BONE_LOWER_LEG
  844. {}
  845. bone.type=type;
  846. }
  847. // set fingers/toes
  848. REPA(bones)
  849. {
  850. SkelBone &bone=bones[i];
  851. if(bone.type==BONE_UNKNOWN // process unknown bones
  852. || bone.type==BONE_HAND || bone.type==BONE_UPPER_ARM // or hands/arms, in case they're named like "ArmHandThumb" which falls into BONE_HAND category above
  853. || bone.type==BONE_FOOT || bone.type==BONE_UPPER_LEG) // or feet /legs, in case they're named like "FootMiddle" which falls into BONE_FOOT category above
  854. for(Int parent_i=i; ; )
  855. {
  856. parent_i=boneParent(parent_i); if(parent_i<0)break;
  857. SkelBone &parent=bones[parent_i]; if(parent.type) // find first parent with a known type
  858. {
  859. BONE_TYPE type=BONE_UNKNOWN;
  860. if(parent.type==BONE_HAND || parent.type==BONE_UPPER_ARM || parent.type==BONE_FINGER)type=BONE_FINGER;else
  861. if(parent.type==BONE_FOOT || parent.type==BONE_UPPER_LEG || parent.type==BONE_TOE )type=BONE_TOE ;
  862. if(type)
  863. {
  864. if(BoneName(bone, "Thumb" )
  865. || BoneName(bone, "Index" )
  866. || BoneName(bone, "Middle")
  867. || BoneName(bone, "Ring" )
  868. || BoneName(bone, "Pinky" ) || BoneName(bone, "Pinkie" ) || BoneName(bone, "Little") // "Little" used by "Fire Ice Elemental", "Pinkie" used by "Barbarian (Poker)"
  869. || BoneName(bone, "Digit" ))bone.type=type; // used by "Barbarian" and "Wolf"
  870. }
  871. break;
  872. }
  873. }
  874. }
  875. // convert BONE_UPPER_ARM/BONE_UPPER_LEG to BONE_LOWER_ARM/BONE_LOWER_LEG
  876. REPA(bones)
  877. {
  878. SkelBone &bone=bones[i];
  879. if(bone.type==BONE_UPPER_ARM)
  880. {
  881. if(SkelBone *parent=bones.addr(bone.parent))if(parent->type==BONE_UPPER_ARM) // parent is also UPPER_ARM
  882. REP(bone.children_num)if(SkelBone *child=bones.addr(bone.children_offset+i))if(child->type==BONE_HAND) // any child is a HAND
  883. {
  884. bone.type=BONE_LOWER_ARM;
  885. break;
  886. }
  887. }else
  888. if(bone.type==BONE_UPPER_LEG)
  889. {
  890. if(SkelBone *parent=bones.addr(bone.parent))if(parent->type==BONE_UPPER_LEG) // parent is also UPPER_LEG
  891. REP(bone.children_num)if(SkelBone *child=bones.addr(bone.children_offset+i))if(child->type==BONE_FOOT) // any child is a FOOT
  892. {
  893. bone.type=BONE_LOWER_LEG;
  894. break;
  895. }
  896. }
  897. }
  898. // the following algorithm is not perfect because it will assign the same 'type_index, type_sub' combination for sibling bones with 'type_sub>0', for example if there's "Spine0" bone and it has 2 children: "SpineA" and "SpineB", then Spine0 will be 0(index) : 0(sub) and SpineA/B will both have 0(index) : 1(sub)
  899. // set sub-indexes (needed for assigning 'type_index')
  900. FREPA(bones) // go from the start to assign parents first
  901. {
  902. SkelBone &bone=bones[i];
  903. Int sub=0; if(bone.type)for(Int cur=i; ; )
  904. {
  905. cur=boneParent(cur); if(cur<0)break;
  906. SkelBone &parent=bones[cur]; if(parent.type==bone.type)
  907. {
  908. sub=parent.type_sub+1; break;
  909. }
  910. }
  911. bone.type_sub =sub;
  912. bone.type_index=(bone.type ? UNASSIGNED : 0); // set all BONE_UNKNOWN to 0
  913. }
  914. // assign 'type_index'
  915. MemtN<BoneOrder, 256> groups[2]; // 0=negative, 1=positive
  916. FREPA(bones) // go from the start to assign parents first
  917. {
  918. SkelBone &bone=bones[i]; if(bone.type_index==UNASSIGNED) // if not yet assigned
  919. {
  920. if(bone.type_sub)bone.type_index=BoneTypeIndex(T, bone);else // if this is a sub bone then grab from parent
  921. {
  922. Bool singular=Singular(bone.type);
  923. REPA(bones) // get all bones that have the same type and zero sub level
  924. {
  925. C SkelBone &test=bones[i]; if(test.type==bone.type && !test.type_sub)
  926. {
  927. Bool positive=true; // use positive indexes by default
  928. Flt order;
  929. SkelBone *parent=bones.addr(test.parent);
  930. Vec pos=((test.type==BONE_SHOULDER) ? test.to() : test.pos); // for shoulders use target location because they can be located close to the center (or in case of some models even on the other side)
  931. if(parent)
  932. {
  933. pos.divNormalized(Matrix(*parent));
  934. switch(parent->type)
  935. {
  936. case BONE_SPINE:
  937. case BONE_NECK :
  938. case BONE_HEAD :
  939. pos.swapYZ(); CHS(pos.x); // swap YZ because spine is expected to have perp(Y) pointed forward, and dir(Z) pointed up, change X sign because cross(X) points left
  940. break;
  941. }
  942. }
  943. if(!singular) // if not singular then detect side
  944. {
  945. if(parent && !Singular(parent->type))positive=(BoneTypeIndex(T, *parent)>=0); // if have a non-singular parent, then get from parent
  946. else positive=(pos.x>=0);
  947. order=Abs(pos.x)-pos.y-pos.z; // start with left top front
  948. }else
  949. {
  950. order=pos.x-pos.y-pos.z; // start with left top front
  951. }
  952. if(test.type==BONE_FINGER)
  953. {
  954. pos.normalize();
  955. order=pos.x; // start with left
  956. if(!positive)CHS(order); // change order for left hands
  957. }
  958. groups[positive].New().set(i, parent ? BoneTypeIndexSub(T, *parent) : 0, order);
  959. }
  960. }
  961. REPAD(sides, groups)
  962. {
  963. MemtN<BoneOrder, 256> &group=groups[sides];
  964. group.sort(BoneOrder::Compare);
  965. REPA(group)bones[group[i].bone_i].type_index=(sides ? i : -1-i);
  966. group.clear();
  967. }
  968. }
  969. }
  970. }
  971. return T;
  972. }
  973. static Bool ChildOK(C SkelBone &parent, C SkelBone &child)
  974. {
  975. Flt parent_width=parent.width*parent.length,
  976. x=DistPointStr (child.pos, parent.pos, parent.dir)/parent_width ,
  977. y=DistPointPlane(child.pos, parent.pos, parent.dir)/parent.length;
  978. return y > x*x + 0.5; // +0.5 because we want to test points at least half way from parent start to end
  979. }
  980. static void NextChild(C Skeleton &skel, Int i, Vec &to)
  981. {
  982. if(InRange(i, skel.bones))
  983. {
  984. C SkelBone &bone=skel.bones[i];
  985. Int children_ok=0, child_i=-1; REP(bone.children_num) // iterate all children
  986. {
  987. Int ci=bone.children_offset+i;
  988. if(ChildOK(bone, skel.bones[ci])){children_ok++; child_i=ci;} // remember last ok child index
  989. }
  990. if(children_ok==1)
  991. {
  992. C SkelBone &child=skel.bones[child_i];
  993. if(child.flag&BONE_RAGDOLL)
  994. {
  995. to=child.pos;
  996. }else
  997. {
  998. to=child.to();
  999. NextChild(skel, child_i, to);
  1000. }
  1001. }
  1002. }
  1003. }
  1004. Skeleton& Skeleton::setBoneShapes()
  1005. {
  1006. REPA(bones)
  1007. {
  1008. SkelBone &sbon=bones[i];
  1009. Vec from=sbon.pos, to=sbon.to();
  1010. Flt r =sbon.width*sbon.length;
  1011. if(sbon.flag&BONE_RAGDOLL)NextChild(T, i, to);
  1012. Vec dir =!(to-from);
  1013. if(sbon.parent!=0xFF)from-=dir*r;
  1014. sbon.shape.set(r, Max(Dist(from, to), 2.0f*r), Avg(from, to)+sbon.offset, dir);
  1015. }
  1016. return T;
  1017. }
  1018. Bool Skeleton::setBoneParent(Int child, Int parent, MemPtr<Byte, 256> old_to_new)
  1019. {
  1020. if(InRange(child, bones) && child!=parent) // can't be a child of itself
  1021. {
  1022. if(!InRange(parent, bones))parent=0xFF; // set <null> if parent is invalid
  1023. Byte &bone_parent =bones[child].parent;
  1024. if( bone_parent!=parent) // if different
  1025. {
  1026. bone_parent=parent; // set new parent
  1027. sortBones(old_to_new).setBoneTypes(); // sort because we need to rebuild 'children_offset' and 'children_num', and in case child has an index smaller than parent
  1028. return true;
  1029. }
  1030. }
  1031. old_to_new.clear();
  1032. return false;
  1033. }
  1034. /******************************************************************************/
  1035. void Skeleton::draw(C Color &bone_color, C Color &slot_color, Flt slot_size)C
  1036. {
  1037. if(bone_color.a)REPAO(bones).draw(bone_color);
  1038. if(slot_color.a)REPAO(slots).draw(slot_color, slot_size);
  1039. }
  1040. /******************************************************************************/
  1041. // IO
  1042. /******************************************************************************/
  1043. Bool Skeleton::save(File &f)C
  1044. {
  1045. f.putMulti(UInt(CC4_SKEL), Byte(7)); // version
  1046. bones.saveRaw(f); // if in the future bones are saved manually, then use 'File.putStr' for their names
  1047. slots.saveRaw(f); // if in the future slots are saved manually, then use 'File.putStr' for their names
  1048. return f.ok();
  1049. }
  1050. Bool Skeleton::load(File &f)
  1051. {
  1052. _skel_anims.del();
  1053. Flt b_frac;
  1054. if(f.getUInt()==CC4_SKEL)switch(f.decUIntV()) // version
  1055. {
  1056. case 7:
  1057. {
  1058. bones.loadRaw(f);
  1059. slots.loadRaw(f);
  1060. if(f.ok())return true;
  1061. }break;
  1062. case 6:
  1063. {
  1064. bones.setNum(f.decUIntV()); FREPA(bones){SkelBone &b=bones[i]; f>>SCAST(OrientP, b)>>SCAST(BoneID, b)>>b.parent>>b.children_offset>>b.children_num>>b.flag; f.skip(1); f>>b.length>>b.width>>b_frac>>b.offset>>b.shape;}
  1065. slots.setNum(f.decUIntV()); FREPA(slots){SkelSlot &s=slots[i]; f>>SCAST(OrientP, s)>>s.name>>s.bone; s.bone1=s.bone; f.skip(3);}
  1066. if(f.ok())return true;
  1067. }break;
  1068. case 5:
  1069. {
  1070. bones.setNum(f.decUIntV());
  1071. slots.setNum(f.decUIntV());
  1072. FREPA(bones){SkelBone &b=bones[i]; f>>SCAST(OrientP, b)>>b.name>>b.parent>>b.children_offset>>b.children_num>>b.flag>>b.type>>b.type_index>>b.type_sub; f.skip(1); f>>b.length>>b.width>>b_frac>>b.offset>>b.shape;}
  1073. FREPA(slots){SkelSlot &s=slots[i]; f>>SCAST(OrientP, s)>>s.name>>s.bone; s.bone1=s.bone; f.skip(3);}
  1074. if(f.ok())return true;
  1075. }break;
  1076. case 4:
  1077. {
  1078. bones.clear().setNum(f.decUIntV());
  1079. slots. setNum(f.decUIntV());
  1080. FREPA(bones){SkelBone &b=bones[i]; f>>SCAST(OrientP, b)>>b.name>>b.parent>>b.children_offset>>b.children_num>>b.flag>>b.length>>b.width>>b_frac>>b.offset>>b.shape;}
  1081. FREPA(slots){SkelSlot &s=slots[i]; f>>SCAST(OrientP, s)>>s.name>>s.bone; s.bone1=s.bone; f.skip(3);}
  1082. if(f.ok())
  1083. {
  1084. setBoneTypes();
  1085. return true;
  1086. }
  1087. }break;
  1088. case 3:
  1089. {
  1090. bones.clear().setNum(f.decUIntV());
  1091. slots. setNum(f.decUIntV());
  1092. FREPA(bones){SkelBone &b=bones[i]; f>>SCAST(OrientP, b)>>b.name>>b.parent>>b.flag; f.skip(2); f>>b.length>>b.width>>b_frac>>b.offset>>b.shape;}
  1093. FREPA(slots){SkelSlot &s=slots[i]; f>>SCAST(OrientP, s)>>s.name>>s.bone; s.bone1=s.bone; f.skip(3);}
  1094. if(f.ok())
  1095. {
  1096. sortBones().setBoneTypes(); // sort to calculate 'children..', do this before 'setBoneTypes' because it needs that date
  1097. return true;
  1098. }
  1099. }break;
  1100. case 2:
  1101. {
  1102. bones.clear().setNum(f.getUShort());
  1103. slots. setNum(f.getUShort());
  1104. FREPA(bones){SkelBone &b=bones[i]; f>>SCAST(OrientP, b)>>b.name>>b.parent>>b.flag; f.skip(2); f>>b.length>>b.width>>b_frac;}
  1105. FREPA(slots){SkelSlot &s=slots[i]; f>>SCAST(OrientP, s)>>s.name>>s.bone; s.bone1=s.bone; f.skip(3);}
  1106. if(f.ok())
  1107. {
  1108. sortBones().setBoneTypes().setBoneShapes(); // sort to calculate 'children..', do this before 'setBoneTypes,setBoneShapes' because they need that data
  1109. return true;
  1110. }
  1111. }break;
  1112. case 1:
  1113. {
  1114. bones.clear().setNum(f.getUShort());
  1115. slots.clear().setNum(f.getUShort());
  1116. f.skip(2); // old body bones
  1117. FREPA(bones){SkelBone &b=bones[i]; f>>SCAST(OrientP, b); f.get(b.name, 16); f>>b.parent>>b.flag; f.skip(2); f>>b.length>>b.width>>b_frac;}
  1118. FREPA(slots){SkelSlot &s=slots[i]; f>>SCAST(OrientP, s); f.get(s.name, 16); f>>s.bone; s.bone1=s.bone; f.skip(3); }
  1119. if(f.ok())
  1120. {
  1121. sortBones().setBoneTypes().setBoneShapes(); // sort to calculate 'children..', do this before 'setBoneTypes,setBoneShapes' because they need that data
  1122. return true;
  1123. }
  1124. }break;
  1125. case 0:
  1126. {
  1127. f.skip(1); // old version byte
  1128. bones.clear().setNum(f.getUShort());
  1129. slots.clear().setNum(f.getUShort());
  1130. FREPA(bones){SkelBone &b=bones[i]; f>>SCAST(OrientP, b); f.get(b.name, 16); f>>b.parent>>b.flag; f.skip(2); f>>b.length>>b.width>>b_frac;}
  1131. FREPA(slots){SkelSlot &s=slots[i]; f>>SCAST(OrientP, s); f.get(s.name, 16); f>>s.bone; s.bone1=s.bone; f.skip(3); }
  1132. if(f.ok())
  1133. {
  1134. sortBones().setBoneTypes().setBoneShapes(); // sort to calculate 'children..', do this before 'setBoneTypes,setBoneShapes' because they need that data
  1135. return true;
  1136. }
  1137. }break;
  1138. }
  1139. del(); return false;
  1140. }
  1141. /******************************************************************************/
  1142. Bool Skeleton::save(C Str &name)C
  1143. {
  1144. File f; if(f.writeTry(name)){if(save(f) && f.flush())return true; f.del(); FDelFile(name);}
  1145. return false;
  1146. }
  1147. Bool Skeleton::load(C Str &name)
  1148. {
  1149. File f; if(f.readTry(name))return load(f);
  1150. del(); return false;
  1151. }
  1152. void Skeleton::operator=(C UID &id ) {T=_EncodeFileName(id);}
  1153. void Skeleton::operator=(C Str &name)
  1154. {
  1155. if(!load(name))Exit(MLT(S+"Can't load Skeleton \"" +name+"\"",
  1156. PL,S+u"Nie można wczytać Szkieletu \""+name+"\""));
  1157. }
  1158. /******************************************************************************/
  1159. void Skeleton::save(MemPtr<TextNode> nodes)C
  1160. {
  1161. if(bones.elms())
  1162. {
  1163. TextNode &node=nodes.New(); node.name="Bones";
  1164. FREPAO(bones).save(node.nodes.New(), this);
  1165. }
  1166. if(slots.elms())
  1167. {
  1168. TextNode &node=nodes.New(); node.name="Slots";
  1169. FREPAO(slots).save(node.nodes.New(), this);
  1170. }
  1171. }
  1172. /******************************************************************************/
  1173. // BONE MAP
  1174. /******************************************************************************/
  1175. BoneMap::BoneMap(C BoneMap &src) : BoneMap() {T=src;}
  1176. void BoneMap::del()
  1177. {
  1178. Free(_bone); _bones=0;
  1179. }
  1180. Int BoneMap::alloc(Int bones, Int name_size)
  1181. {
  1182. del();
  1183. Int size=SIZE(Bone)*bones + name_size;
  1184. _bones=bones;
  1185. _bone =(Bone*)Alloc(size);
  1186. return size;
  1187. }
  1188. void BoneMap::operator=(C BoneMap &src)
  1189. {
  1190. if(this!=&src)
  1191. {
  1192. Int size=alloc(src._bones, src.nameSize());
  1193. CopyFast(_bone, src._bone, size);
  1194. }
  1195. }
  1196. void BoneMap::create(C Skeleton &skeleton)
  1197. {
  1198. Int name_size=0; REPA(skeleton.bones)name_size+=Length(skeleton.bones[i].name)+1; // calculate memory needed for names
  1199. alloc(skeleton.bones.elms(), name_size);
  1200. name_size=0;
  1201. Char8 *bone_name=nameStart();
  1202. FREP(_bones)
  1203. {
  1204. C SkelBone &sbon=skeleton.bones[i];
  1205. Bone &bone= _bone [i];
  1206. bone.type =sbon.type;
  1207. bone.type_index =sbon.type_index;
  1208. bone.type_sub =sbon.type_sub;
  1209. bone.parent =sbon.parent;
  1210. bone.name_offset=name_size;
  1211. Int length_1=Length(sbon.name)+1;
  1212. Set(bone_name, sbon.name, length_1);
  1213. bone_name+=length_1;
  1214. name_size+=length_1;
  1215. }
  1216. }
  1217. Int BoneMap::nameSize ( )C {return _bones ? _bone[_bones-1].name_offset + Length(name(_bones-1)) + 1 : 0;}
  1218. Char8* BoneMap::nameStart( )C {return (Char8*)(_bone+_bones);}
  1219. CChar8* BoneMap::name (Int i)C {return InRange(i, _bones) ? nameStart()+_bone[i].name_offset : null;}
  1220. Int BoneMap::find(CChar8 *name)C {REP(_bones)if(Equal(T.name(i), name))return i; return -1;}
  1221. Bool BoneMap::same(C Skeleton &skeleton)C
  1222. {
  1223. if (_bones!=skeleton.bones.elms())return false; // if bone number doesn't match
  1224. REP(_bones)
  1225. {
  1226. C SkelBone &skel_bone=skeleton.bones[i];
  1227. C Bone &bone= _bone [i];
  1228. if(bone.type !=skel_bone.type
  1229. || bone.type_index!=skel_bone.type_index
  1230. || bone.type_sub !=skel_bone.type_sub
  1231. || bone.parent !=skel_bone.parent
  1232. || !Equal(name(i), skel_bone.name)
  1233. )return false; // if any i-th bone name is different from i-th skeleton bone
  1234. }
  1235. return true;
  1236. }
  1237. /*Bool rename(C Str8 &src, C Str8 &dest); // rename 'src' bone to 'dest', returns true if any change was made
  1238. Bool BoneMap::rename(C Str8 &src, C Str8 &dest)
  1239. {
  1240. this ignores adjusting type type_index type_sub
  1241. REPD(b, _bones)if(Equal(name(b), src))
  1242. {
  1243. BoneMap temp; temp.alloc(_bones, nameSize() + (dest.length()-src.length()));
  1244. Char8 *bone_name =temp.nameStart();
  1245. Int name_offset=0;
  1246. FREP(temp._bones)
  1247. {
  1248. CChar8 *name=((i==b) ? dest() : T.name(i));
  1249. Int length_1=Length(name)+1;
  1250. Set(bone_name, name, length_1);
  1251. temp._bone[i].parent =T._bone[i].parent;
  1252. temp._bone[i].name_offset=name_offset;
  1253. bone_name +=length_1;
  1254. name_offset+=length_1;
  1255. }
  1256. Swap(temp, T);
  1257. return true;
  1258. }
  1259. return false;
  1260. }*/
  1261. void BoneMap::remap(C MemPtr<Byte, 256> &old_to_new)
  1262. {
  1263. if(_bones) // process only if this already has some bones, this is important so we don't set a new map from empty data
  1264. {
  1265. MemtN<Int, 256> new_to_old; // create a 'new_to_old' remap
  1266. // Warning: Multiple OLD elements can point to the same NEW element, in that case pick the OLD with the smallest index (the parent), for that we need to process from end to start, so parents are processed last and overwrite results
  1267. REPAD(old, old_to_new) // order is important! process from end to start as noted above
  1268. {
  1269. Int _new=old_to_new[old];
  1270. if( _new!=0xFF)new_to_old(_new)=old+1; // for the moment use +1 values because 0 are created when using () operator, which below will be converted to -1
  1271. }
  1272. REPAO(new_to_old)--; // now correct the "+1" indexes, invalid indexes will now be set to "-1"
  1273. Int name_size=0; REPA(new_to_old){Int old=new_to_old[i]; name_size+=Length(name(old))+1;} // calculate memory needed for names
  1274. BoneMap temp; temp.alloc(new_to_old.elms(), name_size);
  1275. Char8 *bone_name=temp.nameStart();
  1276. Int name_offset=0;
  1277. FREP(temp._bones)
  1278. {
  1279. Bone &bone=temp._bone[i];
  1280. Int old=new_to_old[i];
  1281. if(InRange(old, _bones))
  1282. {
  1283. C Bone &old_bone=_bone[old]; Byte old_parent=old_bone.parent;
  1284. bone.type =old_bone.type ;
  1285. bone.type_index=old_bone.type_index;
  1286. bone.type_sub =old_bone.type_sub ;
  1287. bone.parent =(InRange(old_parent, old_to_new) ? old_to_new[old_parent] : 0xFF);
  1288. }else
  1289. {
  1290. bone.type =BONE_UNKNOWN;
  1291. bone.type_index=0;
  1292. bone.type_sub =0;
  1293. bone.parent =0xFF;
  1294. }
  1295. CChar8 *name=T.name(old);
  1296. Int length_1=Length(name)+1;
  1297. Set(bone_name, name, length_1);
  1298. bone.name_offset=name_offset;
  1299. bone_name +=length_1;
  1300. name_offset+=length_1;
  1301. }
  1302. Swap(temp, T);
  1303. }
  1304. }
  1305. void BoneMap::setRemap(C Skeleton &skeleton, MemPtr<Byte, 256> old_to_new, Bool by_name)C
  1306. {
  1307. old_to_new.clear();
  1308. FREP(_bones) // process in order
  1309. {
  1310. C Bone &bone=_bone[i];
  1311. Int skel_bone=(by_name ? skeleton.findBoneI(name(i)) : skeleton.findBoneI(name(i), bone.type, bone.type_index, bone.type_sub)); // find i-th bone in skeleton
  1312. if( skel_bone<0) // not found
  1313. {
  1314. Byte parent_index=_bone[i].parent;
  1315. skel_bone=(InRange(parent_index, old_to_new) ? old_to_new[parent_index] : 0xFF); // set "new bone" as the same as "old parents new bone"
  1316. }
  1317. old_to_new.add(skel_bone);
  1318. }
  1319. }
  1320. Bool BoneMap::save(File &f)C
  1321. {
  1322. f.cmpUIntV(_bones); if(_bones)
  1323. {
  1324. Int name_size=nameSize(); f.cmpUIntV(name_size);
  1325. f.put(_bone, SIZE(Bone)*_bones + name_size);
  1326. }
  1327. return f.ok();
  1328. }
  1329. Bool BoneMap::load(File &f)
  1330. {
  1331. if(Int bones=f.decUIntV())
  1332. {
  1333. Int name_size=f.decUIntV(),
  1334. total_size=alloc(bones, name_size);
  1335. f.getFast(_bone, total_size);
  1336. }else del();
  1337. if(f.ok())return true;
  1338. del(); return false;
  1339. }
  1340. Bool BoneMap::saveOld1(File &f)C
  1341. {
  1342. f.cmpUIntV(_bones); if(_bones)
  1343. {
  1344. Int name_size=nameSize(); f.cmpUIntV(name_size);
  1345. FREP(_bones){Bone &bone=_bone[i]; f<<bone.parent; f.cmpUIntV(bone.name_offset);}
  1346. f.put(nameStart(), name_size);
  1347. }
  1348. return f.ok();
  1349. }
  1350. Bool BoneMap::loadOld1(File &f)
  1351. {
  1352. if(Int bones=f.decUIntV())
  1353. {
  1354. Int name_size=f.decUIntV();
  1355. alloc(bones, name_size);
  1356. FREP( bones){Bone &bone=_bone[i]; bone.type=BONE_UNKNOWN; bone.type_index=bone.type_sub=0; f>>bone.parent; bone.name_offset=f.decUIntV();}
  1357. f.getFast(nameStart(), name_size);
  1358. }else del();
  1359. if(f.ok())return true;
  1360. del(); return false;
  1361. }
  1362. Bool BoneMap::saveOld(File &f)C
  1363. {
  1364. f<<_bones; if(_bones)
  1365. {
  1366. Int name_size=nameSize(); f<<name_size;
  1367. FREP(_bones){Bone &bone=_bone[i]; f<<bone.parent; f.putInt(bone.name_offset);}
  1368. f.put(nameStart(), name_size);
  1369. }
  1370. return f.ok();
  1371. }
  1372. Bool BoneMap::loadOld(File &f)
  1373. {
  1374. if(Int bones=f.getInt())
  1375. {
  1376. Int name_size=f.getInt();
  1377. alloc(bones, name_size);
  1378. FREP( bones){Bone &bone=_bone[i]; bone.type=BONE_UNKNOWN; bone.type_index=bone.type_sub=0; f>>bone.parent; bone.name_offset=f.getInt();}
  1379. f.getFast(nameStart(), name_size);
  1380. }else del();
  1381. if(f.ok())return true;
  1382. del(); return false;
  1383. }
  1384. /******************************************************************************/
  1385. }
  1386. /******************************************************************************/