IK.cpp 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #include "../idlib/precompiled.h"
  21. #pragma hdrstop
  22. #include "Game_local.h"
  23. /*
  24. ===============================================================================
  25. idIK
  26. ===============================================================================
  27. */
  28. /*
  29. ================
  30. idIK::idIK
  31. ================
  32. */
  33. idIK::idIK( void ) {
  34. ik_activate = false;
  35. initialized = false;
  36. self = NULL;
  37. animator = NULL;
  38. modifiedAnim = 0;
  39. modelOffset.Zero();
  40. }
  41. /*
  42. ================
  43. idIK::~idIK
  44. ================
  45. */
  46. idIK::~idIK( void ) {
  47. }
  48. /*
  49. ================
  50. idIK::Save
  51. ================
  52. */
  53. void idIK::Save( idSaveGame *savefile ) const {
  54. savefile->WriteBool( initialized );
  55. savefile->WriteBool( ik_activate );
  56. savefile->WriteObject( self );
  57. savefile->WriteString( animator != NULL && animator->GetAnim( modifiedAnim ) ? animator->GetAnim( modifiedAnim )->Name() : "" );
  58. savefile->WriteVec3( modelOffset );
  59. }
  60. /*
  61. ================
  62. idIK::Restore
  63. ================
  64. */
  65. void idIK::Restore( idRestoreGame *savefile ) {
  66. idStr anim;
  67. savefile->ReadBool( initialized );
  68. savefile->ReadBool( ik_activate );
  69. savefile->ReadObject( reinterpret_cast<idClass *&>( self ) );
  70. savefile->ReadString( anim );
  71. savefile->ReadVec3( modelOffset );
  72. if ( self ) {
  73. animator = self->GetAnimator();
  74. if ( animator == NULL || animator->ModelDef() == NULL ) {
  75. gameLocal.Warning( "idIK::Restore: IK for entity '%s' at (%s) has no model set.",
  76. self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0) );
  77. }
  78. modifiedAnim = animator->GetAnim( anim );
  79. if ( modifiedAnim == 0 ) {
  80. gameLocal.Warning( "idIK::Restore: IK for entity '%s' at (%s) has no modified animation.",
  81. self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0) );
  82. }
  83. } else {
  84. animator = NULL;
  85. modifiedAnim = 0;
  86. }
  87. }
  88. /*
  89. ================
  90. idIK::IsInitialized
  91. ================
  92. */
  93. bool idIK::IsInitialized( void ) const {
  94. return initialized && ik_enable.GetBool();
  95. }
  96. /*
  97. ================
  98. idIK::Init
  99. ================
  100. */
  101. bool idIK::Init( idEntity *self, const char *anim, const idVec3 &modelOffset ) {
  102. idRenderModel *model;
  103. if ( self == NULL ) {
  104. return false;
  105. }
  106. this->self = self;
  107. animator = self->GetAnimator();
  108. if ( animator == NULL || animator->ModelDef() == NULL ) {
  109. gameLocal.Warning( "idIK::Init: IK for entity '%s' at (%s) has no model set.",
  110. self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0) );
  111. return false;
  112. }
  113. if ( animator->ModelDef()->ModelHandle() == NULL ) {
  114. gameLocal.Warning( "idIK::Init: IK for entity '%s' at (%s) uses default model.",
  115. self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0) );
  116. return false;
  117. }
  118. model = animator->ModelHandle();
  119. if ( model == NULL ) {
  120. gameLocal.Warning( "idIK::Init: IK for entity '%s' at (%s) has no model set.",
  121. self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0) );
  122. return false;
  123. }
  124. modifiedAnim = animator->GetAnim( anim );
  125. if ( modifiedAnim == 0 ) {
  126. gameLocal.Warning( "idIK::Init: IK for entity '%s' at (%s) has no modified animation.",
  127. self->name.c_str(), self->GetPhysics()->GetOrigin().ToString(0) );
  128. return false;
  129. }
  130. this->modelOffset = modelOffset;
  131. return true;
  132. }
  133. /*
  134. ================
  135. idIK::Evaluate
  136. ================
  137. */
  138. void idIK::Evaluate( void ) {
  139. }
  140. /*
  141. ================
  142. idIK::ClearJointMods
  143. ================
  144. */
  145. void idIK::ClearJointMods( void ) {
  146. ik_activate = false;
  147. }
  148. /*
  149. ================
  150. idIK::SolveTwoBones
  151. ================
  152. */
  153. bool idIK::SolveTwoBones( const idVec3 &startPos, const idVec3 &endPos, const idVec3 &dir, float len0, float len1, idVec3 &jointPos ) {
  154. float length, lengthSqr, lengthInv, x, y;
  155. idVec3 vec0, vec1;
  156. vec0 = endPos - startPos;
  157. lengthSqr = vec0.LengthSqr();
  158. lengthInv = idMath::InvSqrt( lengthSqr );
  159. length = lengthInv * lengthSqr;
  160. // if the start and end position are too far out or too close to each other
  161. if ( length > len0 + len1 || length < idMath::Fabs( len0 - len1 ) ) {
  162. jointPos = startPos + 0.5f * vec0;
  163. return false;
  164. }
  165. vec0 *= lengthInv;
  166. vec1 = dir - vec0 * dir * vec0;
  167. vec1.Normalize();
  168. x = ( length * length + len0 * len0 - len1 * len1 ) * ( 0.5f * lengthInv );
  169. y = idMath::Sqrt( len0 * len0 - x * x );
  170. jointPos = startPos + x * vec0 + y * vec1;
  171. return true;
  172. }
  173. /*
  174. ================
  175. idIK::GetBoneAxis
  176. ================
  177. */
  178. float idIK::GetBoneAxis( const idVec3 &startPos, const idVec3 &endPos, const idVec3 &dir, idMat3 &axis ) {
  179. float length;
  180. axis[0] = endPos - startPos;
  181. length = axis[0].Normalize();
  182. axis[1] = dir - axis[0] * dir * axis[0];
  183. axis[1].Normalize();
  184. axis[2].Cross( axis[1], axis[0] );
  185. return length;
  186. }
  187. /*
  188. ===============================================================================
  189. idIK_Walk
  190. ===============================================================================
  191. */
  192. /*
  193. ================
  194. idIK_Walk::idIK_Walk
  195. ================
  196. */
  197. idIK_Walk::idIK_Walk() {
  198. int i;
  199. initialized = false;
  200. footModel = NULL;
  201. numLegs = 0;
  202. enabledLegs = 0;
  203. for ( i = 0; i < MAX_LEGS; i++ ) {
  204. footJoints[i] = INVALID_JOINT;
  205. ankleJoints[i] = INVALID_JOINT;
  206. kneeJoints[i] = INVALID_JOINT;
  207. hipJoints[i] = INVALID_JOINT;
  208. dirJoints[i] = INVALID_JOINT;
  209. hipForward[i].Zero();
  210. kneeForward[i].Zero();
  211. upperLegLength[i] = 0.0f;
  212. lowerLegLength[i] = 0.0f;
  213. upperLegToHipJoint[i].Identity();
  214. lowerLegToKneeJoint[i].Identity();
  215. oldAnkleHeights[i] = 0.0f;
  216. }
  217. waistJoint = INVALID_JOINT;
  218. smoothing = 0.75f;
  219. waistSmoothing = 0.5f;
  220. footShift = 0.0f;
  221. waistShift = 0.0f;
  222. minWaistFloorDist = 0.0f;
  223. minWaistAnkleDist = 0.0f;
  224. footUpTrace = 32.0f;
  225. footDownTrace = 32.0f;
  226. tiltWaist = false;
  227. usePivot = false;
  228. pivotFoot = -1;
  229. pivotYaw = 0.0f;
  230. pivotPos.Zero();
  231. oldHeightsValid = false;
  232. oldWaistHeight = 0.0f;
  233. waistOffset.Zero();
  234. }
  235. /*
  236. ================
  237. idIK_Walk::~idIK_Walk
  238. ================
  239. */
  240. idIK_Walk::~idIK_Walk() {
  241. if ( footModel ) {
  242. delete footModel;
  243. }
  244. }
  245. /*
  246. ================
  247. idIK_Walk::Save
  248. ================
  249. */
  250. void idIK_Walk::Save( idSaveGame *savefile ) const {
  251. int i;
  252. idIK::Save( savefile );
  253. savefile->WriteClipModel( footModel );
  254. savefile->WriteInt( numLegs );
  255. savefile->WriteInt( enabledLegs );
  256. for ( i = 0; i < MAX_LEGS; i++ )
  257. savefile->WriteInt( footJoints[i] );
  258. for ( i = 0; i < MAX_LEGS; i++ )
  259. savefile->WriteInt( ankleJoints[i] );
  260. for ( i = 0; i < MAX_LEGS; i++ )
  261. savefile->WriteInt( kneeJoints[i] );
  262. for ( i = 0; i < MAX_LEGS; i++ )
  263. savefile->WriteInt( hipJoints[i] );
  264. for ( i = 0; i < MAX_LEGS; i++ )
  265. savefile->WriteInt( dirJoints[i] );
  266. savefile->WriteInt( waistJoint );
  267. for ( i = 0; i < MAX_LEGS; i++ )
  268. savefile->WriteVec3( hipForward[i] );
  269. for ( i = 0; i < MAX_LEGS; i++ )
  270. savefile->WriteVec3( kneeForward[i] );
  271. for ( i = 0; i < MAX_LEGS; i++ )
  272. savefile->WriteFloat( upperLegLength[i] );
  273. for ( i = 0; i < MAX_LEGS; i++ )
  274. savefile->WriteFloat( lowerLegLength[i] );
  275. for ( i = 0; i < MAX_LEGS; i++ )
  276. savefile->WriteMat3( upperLegToHipJoint[i] );
  277. for ( i = 0; i < MAX_LEGS; i++ )
  278. savefile->WriteMat3( lowerLegToKneeJoint[i] );
  279. savefile->WriteFloat( smoothing );
  280. savefile->WriteFloat( waistSmoothing );
  281. savefile->WriteFloat( footShift );
  282. savefile->WriteFloat( waistShift );
  283. savefile->WriteFloat( minWaistFloorDist );
  284. savefile->WriteFloat( minWaistAnkleDist );
  285. savefile->WriteFloat( footUpTrace );
  286. savefile->WriteFloat( footDownTrace );
  287. savefile->WriteBool( tiltWaist );
  288. savefile->WriteBool( usePivot );
  289. savefile->WriteInt( pivotFoot );
  290. savefile->WriteFloat( pivotYaw );
  291. savefile->WriteVec3( pivotPos );
  292. savefile->WriteBool( oldHeightsValid );
  293. savefile->WriteFloat( oldWaistHeight );
  294. for ( i = 0; i < MAX_LEGS; i++ ) {
  295. savefile->WriteFloat( oldAnkleHeights[i] );
  296. }
  297. savefile->WriteVec3( waistOffset );
  298. }
  299. /*
  300. ================
  301. idIK_Walk::Restore
  302. ================
  303. */
  304. void idIK_Walk::Restore( idRestoreGame *savefile ) {
  305. int i;
  306. idIK::Restore( savefile );
  307. savefile->ReadClipModel( footModel );
  308. savefile->ReadInt( numLegs );
  309. savefile->ReadInt( enabledLegs );
  310. for ( i = 0; i < MAX_LEGS; i++ )
  311. savefile->ReadInt( (int&)footJoints[i] );
  312. for ( i = 0; i < MAX_LEGS; i++ )
  313. savefile->ReadInt( (int&)ankleJoints[i] );
  314. for ( i = 0; i < MAX_LEGS; i++ )
  315. savefile->ReadInt( (int&)kneeJoints[i] );
  316. for ( i = 0; i < MAX_LEGS; i++ )
  317. savefile->ReadInt( (int&)hipJoints[i] );
  318. for ( i = 0; i < MAX_LEGS; i++ )
  319. savefile->ReadInt( (int&)dirJoints[i] );
  320. savefile->ReadInt( (int&)waistJoint );
  321. for ( i = 0; i < MAX_LEGS; i++ )
  322. savefile->ReadVec3( hipForward[i] );
  323. for ( i = 0; i < MAX_LEGS; i++ )
  324. savefile->ReadVec3( kneeForward[i] );
  325. for ( i = 0; i < MAX_LEGS; i++ )
  326. savefile->ReadFloat( upperLegLength[i] );
  327. for ( i = 0; i < MAX_LEGS; i++ )
  328. savefile->ReadFloat( lowerLegLength[i] );
  329. for ( i = 0; i < MAX_LEGS; i++ )
  330. savefile->ReadMat3( upperLegToHipJoint[i] );
  331. for ( i = 0; i < MAX_LEGS; i++ )
  332. savefile->ReadMat3( lowerLegToKneeJoint[i] );
  333. savefile->ReadFloat( smoothing );
  334. savefile->ReadFloat( waistSmoothing );
  335. savefile->ReadFloat( footShift );
  336. savefile->ReadFloat( waistShift );
  337. savefile->ReadFloat( minWaistFloorDist );
  338. savefile->ReadFloat( minWaistAnkleDist );
  339. savefile->ReadFloat( footUpTrace );
  340. savefile->ReadFloat( footDownTrace );
  341. savefile->ReadBool( tiltWaist );
  342. savefile->ReadBool( usePivot );
  343. savefile->ReadInt( pivotFoot );
  344. savefile->ReadFloat( pivotYaw );
  345. savefile->ReadVec3( pivotPos );
  346. savefile->ReadBool( oldHeightsValid );
  347. savefile->ReadFloat( oldWaistHeight );
  348. for ( i = 0; i < MAX_LEGS; i++ ) {
  349. savefile->ReadFloat( oldAnkleHeights[i] );
  350. }
  351. savefile->ReadVec3( waistOffset );
  352. }
  353. /*
  354. ================
  355. idIK_Walk::Init
  356. ================
  357. */
  358. bool idIK_Walk::Init( idEntity *self, const char *anim, const idVec3 &modelOffset ) {
  359. int i;
  360. float footSize;
  361. idVec3 verts[4];
  362. idTraceModel trm;
  363. const char *jointName;
  364. idVec3 dir, ankleOrigin, kneeOrigin, hipOrigin, dirOrigin;
  365. idMat3 axis, ankleAxis, kneeAxis, hipAxis;
  366. static idVec3 footWinding[4] = {
  367. idVec3( 1.0f, 1.0f, 0.0f ),
  368. idVec3( -1.0f, 1.0f, 0.0f ),
  369. idVec3( -1.0f, -1.0f, 0.0f ),
  370. idVec3( 1.0f, -1.0f, 0.0f )
  371. };
  372. if ( !self ) {
  373. return false;
  374. }
  375. numLegs = Min( self->spawnArgs.GetInt( "ik_numLegs", "0" ), MAX_LEGS );
  376. if ( numLegs == 0 ) {
  377. return true;
  378. }
  379. if ( !idIK::Init( self, anim, modelOffset ) ) {
  380. return false;
  381. }
  382. int numJoints = animator->NumJoints();
  383. idJointMat *joints = ( idJointMat * )_alloca16( numJoints * sizeof( joints[0] ) );
  384. // create the animation frame used to setup the IK
  385. gameEdit->ANIM_CreateAnimFrame( animator->ModelHandle(), animator->GetAnim( modifiedAnim )->MD5Anim( 0 ), numJoints, joints, 1, animator->ModelDef()->GetVisualOffset() + modelOffset, animator->RemoveOrigin() );
  386. enabledLegs = 0;
  387. // get all the joints
  388. for ( i = 0; i < numLegs; i++ ) {
  389. jointName = self->spawnArgs.GetString( va( "ik_foot%d", i+1 ) );
  390. footJoints[i] = animator->GetJointHandle( jointName );
  391. if ( footJoints[i] == INVALID_JOINT ) {
  392. gameLocal.Error( "idIK_Walk::Init: invalid foot joint '%s'", jointName );
  393. }
  394. jointName = self->spawnArgs.GetString( va( "ik_ankle%d", i+1 ) );
  395. ankleJoints[i] = animator->GetJointHandle( jointName );
  396. if ( ankleJoints[i] == INVALID_JOINT ) {
  397. gameLocal.Error( "idIK_Walk::Init: invalid ankle joint '%s'", jointName );
  398. }
  399. jointName = self->spawnArgs.GetString( va( "ik_knee%d", i+1 ) );
  400. kneeJoints[i] = animator->GetJointHandle( jointName );
  401. if ( kneeJoints[i] == INVALID_JOINT ) {
  402. gameLocal.Error( "idIK_Walk::Init: invalid knee joint '%s'\n", jointName );
  403. }
  404. jointName = self->spawnArgs.GetString( va( "ik_hip%d", i+1 ) );
  405. hipJoints[i] = animator->GetJointHandle( jointName );
  406. if ( hipJoints[i] == INVALID_JOINT ) {
  407. gameLocal.Error( "idIK_Walk::Init: invalid hip joint '%s'\n", jointName );
  408. }
  409. jointName = self->spawnArgs.GetString( va( "ik_dir%d", i+1 ) );
  410. dirJoints[i] = animator->GetJointHandle( jointName );
  411. enabledLegs |= 1 << i;
  412. }
  413. jointName = self->spawnArgs.GetString( "ik_waist" );
  414. waistJoint = animator->GetJointHandle( jointName );
  415. if ( waistJoint == INVALID_JOINT ) {
  416. gameLocal.Error( "idIK_Walk::Init: invalid waist joint '%s'\n", jointName );
  417. }
  418. // get the leg bone lengths and rotation matrices
  419. for ( i = 0; i < numLegs; i++ ) {
  420. oldAnkleHeights[i] = 0.0f;
  421. ankleAxis = joints[ ankleJoints[ i ] ].ToMat3();
  422. ankleOrigin = joints[ ankleJoints[ i ] ].ToVec3();
  423. kneeAxis = joints[ kneeJoints[ i ] ].ToMat3();
  424. kneeOrigin = joints[ kneeJoints[ i ] ].ToVec3();
  425. hipAxis = joints[ hipJoints[ i ] ].ToMat3();
  426. hipOrigin = joints[ hipJoints[ i ] ].ToVec3();
  427. // get the IK direction
  428. if ( dirJoints[i] != INVALID_JOINT ) {
  429. dirOrigin = joints[ dirJoints[ i ] ].ToVec3();
  430. dir = dirOrigin - kneeOrigin;
  431. } else {
  432. dir.Set( 1.0f, 0.0f, 0.0f );
  433. }
  434. hipForward[i] = dir * hipAxis.Transpose();
  435. kneeForward[i] = dir * kneeAxis.Transpose();
  436. // conversion from upper leg bone axis to hip joint axis
  437. upperLegLength[i] = GetBoneAxis( hipOrigin, kneeOrigin, dir, axis );
  438. upperLegToHipJoint[i] = hipAxis * axis.Transpose();
  439. // conversion from lower leg bone axis to knee joint axis
  440. lowerLegLength[i] = GetBoneAxis( kneeOrigin, ankleOrigin, dir, axis );
  441. lowerLegToKneeJoint[i] = kneeAxis * axis.Transpose();
  442. }
  443. smoothing = self->spawnArgs.GetFloat( "ik_smoothing", "0.75" );
  444. waistSmoothing = self->spawnArgs.GetFloat( "ik_waistSmoothing", "0.75" );
  445. footShift = self->spawnArgs.GetFloat( "ik_footShift", "0" );
  446. waistShift = self->spawnArgs.GetFloat( "ik_waistShift", "0" );
  447. minWaistFloorDist = self->spawnArgs.GetFloat( "ik_minWaistFloorDist", "0" );
  448. minWaistAnkleDist = self->spawnArgs.GetFloat( "ik_minWaistAnkleDist", "0" );
  449. footUpTrace = self->spawnArgs.GetFloat( "ik_footUpTrace", "32" );
  450. footDownTrace = self->spawnArgs.GetFloat( "ik_footDownTrace", "32" );
  451. tiltWaist = self->spawnArgs.GetBool( "ik_tiltWaist", "0" );
  452. usePivot = self->spawnArgs.GetBool( "ik_usePivot", "0" );
  453. // setup a clip model for the feet
  454. footSize = self->spawnArgs.GetFloat( "ik_footSize", "4" ) * 0.5f;
  455. if ( footSize > 0.0f ) {
  456. for ( i = 0; i < 4; i++ ) {
  457. verts[i] = footWinding[i] * footSize;
  458. }
  459. trm.SetupPolygon( verts, 4 );
  460. footModel = new idClipModel( trm );
  461. }
  462. initialized = true;
  463. return true;
  464. }
  465. /*
  466. ================
  467. idIK_Walk::Evaluate
  468. ================
  469. */
  470. void idIK_Walk::Evaluate( void ) {
  471. int i, newPivotFoot;
  472. float modelHeight, jointHeight, lowestHeight, floorHeights[MAX_LEGS];
  473. float shift, smallestShift, newHeight, step, newPivotYaw, height, largestAnkleHeight;
  474. idVec3 modelOrigin, normal, hipDir, kneeDir, start, end, jointOrigins[MAX_LEGS];
  475. idVec3 footOrigin, ankleOrigin, kneeOrigin, hipOrigin, waistOrigin;
  476. idMat3 modelAxis, waistAxis, axis;
  477. idMat3 hipAxis[MAX_LEGS], kneeAxis[MAX_LEGS], ankleAxis[MAX_LEGS];
  478. trace_t results;
  479. if ( !self || !gameLocal.isNewFrame ) {
  480. return;
  481. }
  482. // if no IK enabled on any legs
  483. if ( !enabledLegs ) {
  484. return;
  485. }
  486. normal = - self->GetPhysics()->GetGravityNormal();
  487. modelOrigin = self->GetPhysics()->GetOrigin();
  488. modelAxis = self->GetRenderEntity()->axis;
  489. modelHeight = modelOrigin * normal;
  490. modelOrigin += modelOffset * modelAxis;
  491. // create frame without joint mods
  492. animator->CreateFrame( gameLocal.time, false );
  493. // get the joint positions for the feet
  494. lowestHeight = idMath::INFINITY;
  495. for ( i = 0; i < numLegs; i++ ) {
  496. animator->GetJointTransform( footJoints[i], gameLocal.time, footOrigin, axis );
  497. jointOrigins[i] = modelOrigin + footOrigin * modelAxis;
  498. jointHeight = jointOrigins[i] * normal;
  499. if ( jointHeight < lowestHeight ) {
  500. lowestHeight = jointHeight;
  501. newPivotFoot = i;
  502. }
  503. }
  504. if ( usePivot ) {
  505. newPivotYaw = modelAxis[0].ToYaw();
  506. // change pivot foot
  507. if ( newPivotFoot != pivotFoot || idMath::Fabs( idMath::AngleNormalize180( newPivotYaw - pivotYaw ) ) > 30.0f ) {
  508. pivotFoot = newPivotFoot;
  509. pivotYaw = newPivotYaw;
  510. animator->GetJointTransform( footJoints[pivotFoot], gameLocal.time, footOrigin, axis );
  511. pivotPos = modelOrigin + footOrigin * modelAxis;
  512. }
  513. // keep pivot foot in place
  514. jointOrigins[pivotFoot] = pivotPos;
  515. }
  516. // get the floor heights for the feet
  517. for ( i = 0; i < numLegs; i++ ) {
  518. if ( !( enabledLegs & ( 1 << i ) ) ) {
  519. continue;
  520. }
  521. start = jointOrigins[i] + normal * footUpTrace;
  522. end = jointOrigins[i] - normal * footDownTrace;
  523. gameLocal.clip.Translation( results, start, end, footModel, mat3_identity, CONTENTS_SOLID|CONTENTS_IKCLIP, self );
  524. floorHeights[i] = results.endpos * normal;
  525. if ( ik_debug.GetBool() && footModel ) {
  526. idFixedWinding w;
  527. for ( int j = 0; j < footModel->GetTraceModel()->numVerts; j++ ) {
  528. w += footModel->GetTraceModel()->verts[j];
  529. }
  530. gameRenderWorld->DebugWinding( colorRed, w, results.endpos, results.endAxis );
  531. }
  532. }
  533. const idPhysics *phys = self->GetPhysics();
  534. // test whether or not the character standing on the ground
  535. bool onGround = phys->HasGroundContacts();
  536. // test whether or not the character is standing on a plat
  537. bool onPlat = false;
  538. for ( i = 0; i < phys->GetNumContacts(); i++ ) {
  539. idEntity *ent = gameLocal.entities[ phys->GetContact( i ).entityNum ];
  540. if ( ent != NULL && ent->IsType( idPlat::Type ) ) {
  541. onPlat = true;
  542. break;
  543. }
  544. }
  545. // adjust heights of the ankles
  546. smallestShift = idMath::INFINITY;
  547. largestAnkleHeight = -idMath::INFINITY;
  548. for ( i = 0; i < numLegs; i++ ) {
  549. if ( onGround && ( enabledLegs & ( 1 << i ) ) ) {
  550. shift = floorHeights[i] - modelHeight + footShift;
  551. } else {
  552. shift = 0.0f;
  553. }
  554. if ( shift < smallestShift ) {
  555. smallestShift = shift;
  556. }
  557. animator->GetJointTransform( ankleJoints[i], gameLocal.time, ankleOrigin, ankleAxis[i] );
  558. jointOrigins[i] = modelOrigin + ankleOrigin * modelAxis;
  559. height = jointOrigins[i] * normal;
  560. if ( oldHeightsValid && !onPlat ) {
  561. step = height + shift - oldAnkleHeights[i];
  562. shift -= smoothing * step;
  563. }
  564. newHeight = height + shift;
  565. if ( newHeight > largestAnkleHeight ) {
  566. largestAnkleHeight = newHeight;
  567. }
  568. oldAnkleHeights[i] = newHeight;
  569. jointOrigins[i] += shift * normal;
  570. }
  571. animator->GetJointTransform( waistJoint, gameLocal.time, waistOrigin, waistAxis );
  572. waistOrigin = modelOrigin + waistOrigin * modelAxis;
  573. // adjust position of the waist
  574. waistOffset = ( smallestShift + waistShift ) * normal;
  575. // if the waist should be at least a certain distance above the floor
  576. if ( minWaistFloorDist > 0.0f && waistOffset * normal < 0.0f ) {
  577. start = waistOrigin;
  578. end = waistOrigin + waistOffset - normal * minWaistFloorDist;
  579. gameLocal.clip.Translation( results, start, end, footModel, modelAxis, CONTENTS_SOLID|CONTENTS_IKCLIP, self );
  580. height = ( waistOrigin + waistOffset - results.endpos ) * normal;
  581. if ( height < minWaistFloorDist ) {
  582. waistOffset += ( minWaistFloorDist - height ) * normal;
  583. }
  584. }
  585. // if the waist should be at least a certain distance above the ankles
  586. if ( minWaistAnkleDist > 0.0f ) {
  587. height = ( waistOrigin + waistOffset ) * normal;
  588. if ( height - largestAnkleHeight < minWaistAnkleDist ) {
  589. waistOffset += ( minWaistAnkleDist - ( height - largestAnkleHeight ) ) * normal;
  590. }
  591. }
  592. if ( oldHeightsValid ) {
  593. // smoothly adjust height of waist
  594. newHeight = ( waistOrigin + waistOffset ) * normal;
  595. step = newHeight - oldWaistHeight;
  596. waistOffset -= waistSmoothing * step * normal;
  597. }
  598. // save height of waist for smoothing
  599. oldWaistHeight = ( waistOrigin + waistOffset ) * normal;
  600. if ( !oldHeightsValid ) {
  601. oldHeightsValid = true;
  602. return;
  603. }
  604. // solve IK
  605. for ( i = 0; i < numLegs; i++ ) {
  606. // get the position of the hip in world space
  607. animator->GetJointTransform( hipJoints[i], gameLocal.time, hipOrigin, axis );
  608. hipOrigin = modelOrigin + waistOffset + hipOrigin * modelAxis;
  609. hipDir = hipForward[i] * axis * modelAxis;
  610. // get the IK bend direction
  611. animator->GetJointTransform( kneeJoints[i], gameLocal.time, kneeOrigin, axis );
  612. kneeDir = kneeForward[i] * axis * modelAxis;
  613. // solve IK and calculate knee position
  614. SolveTwoBones( hipOrigin, jointOrigins[i], kneeDir, upperLegLength[i], lowerLegLength[i], kneeOrigin );
  615. if ( ik_debug.GetBool() ) {
  616. gameRenderWorld->DebugLine( colorCyan, hipOrigin, kneeOrigin );
  617. gameRenderWorld->DebugLine( colorRed, kneeOrigin, jointOrigins[i] );
  618. gameRenderWorld->DebugLine( colorYellow, kneeOrigin, kneeOrigin + hipDir );
  619. gameRenderWorld->DebugLine( colorGreen, kneeOrigin, kneeOrigin + kneeDir );
  620. }
  621. // get the axis for the hip joint
  622. GetBoneAxis( hipOrigin, kneeOrigin, hipDir, axis );
  623. hipAxis[i] = upperLegToHipJoint[i] * ( axis * modelAxis.Transpose() );
  624. // get the axis for the knee joint
  625. GetBoneAxis( kneeOrigin, jointOrigins[i], kneeDir, axis );
  626. kneeAxis[i] = lowerLegToKneeJoint[i] * ( axis * modelAxis.Transpose() );
  627. }
  628. // set the joint mods
  629. animator->SetJointAxis( waistJoint, JOINTMOD_WORLD_OVERRIDE, waistAxis );
  630. animator->SetJointPos( waistJoint, JOINTMOD_WORLD_OVERRIDE, ( waistOrigin + waistOffset - modelOrigin ) * modelAxis.Transpose() );
  631. for ( i = 0; i < numLegs; i++ ) {
  632. animator->SetJointAxis( hipJoints[i], JOINTMOD_WORLD_OVERRIDE, hipAxis[i] );
  633. animator->SetJointAxis( kneeJoints[i], JOINTMOD_WORLD_OVERRIDE, kneeAxis[i] );
  634. animator->SetJointAxis( ankleJoints[i], JOINTMOD_WORLD_OVERRIDE, ankleAxis[i] );
  635. }
  636. ik_activate = true;
  637. }
  638. /*
  639. ================
  640. idIK_Walk::ClearJointMods
  641. ================
  642. */
  643. void idIK_Walk::ClearJointMods( void ) {
  644. int i;
  645. if ( !self || !ik_activate ) {
  646. return;
  647. }
  648. animator->SetJointAxis( waistJoint, JOINTMOD_NONE, mat3_identity );
  649. animator->SetJointPos( waistJoint, JOINTMOD_NONE, vec3_origin );
  650. for ( i = 0; i < numLegs; i++ ) {
  651. animator->SetJointAxis( hipJoints[i], JOINTMOD_NONE, mat3_identity );
  652. animator->SetJointAxis( kneeJoints[i], JOINTMOD_NONE, mat3_identity );
  653. animator->SetJointAxis( ankleJoints[i], JOINTMOD_NONE, mat3_identity );
  654. }
  655. ik_activate = false;
  656. }
  657. /*
  658. ================
  659. idIK_Walk::EnableAll
  660. ================
  661. */
  662. void idIK_Walk::EnableAll( void ) {
  663. enabledLegs = ( 1 << numLegs ) - 1;
  664. oldHeightsValid = false;
  665. }
  666. /*
  667. ================
  668. idIK_Walk::DisableAll
  669. ================
  670. */
  671. void idIK_Walk::DisableAll( void ) {
  672. enabledLegs = 0;
  673. oldHeightsValid = false;
  674. }
  675. /*
  676. ================
  677. idIK_Walk::EnableLeg
  678. ================
  679. */
  680. void idIK_Walk::EnableLeg( int num ) {
  681. enabledLegs |= 1 << num;
  682. }
  683. /*
  684. ================
  685. idIK_Walk::DisableLeg
  686. ================
  687. */
  688. void idIK_Walk::DisableLeg( int num ) {
  689. enabledLegs &= ~( 1 << num );
  690. }
  691. /*
  692. ===============================================================================
  693. idIK_Reach
  694. ===============================================================================
  695. */
  696. /*
  697. ================
  698. idIK_Reach::idIK_Reach
  699. ================
  700. */
  701. idIK_Reach::idIK_Reach() {
  702. int i;
  703. initialized = false;
  704. numArms = 0;
  705. enabledArms = 0;
  706. for ( i = 0; i < MAX_ARMS; i++ ) {
  707. handJoints[i] = INVALID_JOINT;
  708. elbowJoints[i] = INVALID_JOINT;
  709. shoulderJoints[i] = INVALID_JOINT;
  710. dirJoints[i] = INVALID_JOINT;
  711. shoulderForward[i].Zero();
  712. elbowForward[i].Zero();
  713. upperArmLength[i] = 0.0f;
  714. lowerArmLength[i] = 0.0f;
  715. upperArmToShoulderJoint[i].Identity();
  716. lowerArmToElbowJoint[i].Identity();
  717. }
  718. }
  719. /*
  720. ================
  721. idIK_Reach::~idIK_Reach
  722. ================
  723. */
  724. idIK_Reach::~idIK_Reach() {
  725. }
  726. /*
  727. ================
  728. idIK_Reach::Save
  729. ================
  730. */
  731. void idIK_Reach::Save( idSaveGame *savefile ) const {
  732. int i;
  733. idIK::Save( savefile );
  734. savefile->WriteInt( numArms );
  735. savefile->WriteInt( enabledArms );
  736. for ( i = 0; i < MAX_ARMS; i++ )
  737. savefile->WriteInt( handJoints[i] );
  738. for ( i = 0; i < MAX_ARMS; i++ )
  739. savefile->WriteInt( elbowJoints[i] );
  740. for ( i = 0; i < MAX_ARMS; i++ )
  741. savefile->WriteInt( shoulderJoints[i] );
  742. for ( i = 0; i < MAX_ARMS; i++ )
  743. savefile->WriteInt( dirJoints[i] );
  744. for ( i = 0; i < MAX_ARMS; i++ )
  745. savefile->WriteVec3( shoulderForward[i] );
  746. for ( i = 0; i < MAX_ARMS; i++ )
  747. savefile->WriteVec3( elbowForward[i] );
  748. for ( i = 0; i < MAX_ARMS; i++ )
  749. savefile->WriteFloat( upperArmLength[i] );
  750. for ( i = 0; i < MAX_ARMS; i++ )
  751. savefile->WriteFloat( lowerArmLength[i] );
  752. for ( i = 0; i < MAX_ARMS; i++ )
  753. savefile->WriteMat3( upperArmToShoulderJoint[i] );
  754. for ( i = 0; i < MAX_ARMS; i++ )
  755. savefile->WriteMat3( lowerArmToElbowJoint[i] );
  756. }
  757. /*
  758. ================
  759. idIK_Reach::Restore
  760. ================
  761. */
  762. void idIK_Reach::Restore( idRestoreGame *savefile ) {
  763. int i;
  764. idIK::Restore( savefile );
  765. savefile->ReadInt( numArms );
  766. savefile->ReadInt( enabledArms );
  767. for ( i = 0; i < MAX_ARMS; i++ )
  768. savefile->ReadInt( (int&)handJoints[i] );
  769. for ( i = 0; i < MAX_ARMS; i++ )
  770. savefile->ReadInt( (int&)elbowJoints[i] );
  771. for ( i = 0; i < MAX_ARMS; i++ )
  772. savefile->ReadInt( (int&)shoulderJoints[i] );
  773. for ( i = 0; i < MAX_ARMS; i++ )
  774. savefile->ReadInt( (int&)dirJoints[i] );
  775. for ( i = 0; i < MAX_ARMS; i++ )
  776. savefile->ReadVec3( shoulderForward[i] );
  777. for ( i = 0; i < MAX_ARMS; i++ )
  778. savefile->ReadVec3( elbowForward[i] );
  779. for ( i = 0; i < MAX_ARMS; i++ )
  780. savefile->ReadFloat( upperArmLength[i] );
  781. for ( i = 0; i < MAX_ARMS; i++ )
  782. savefile->ReadFloat( lowerArmLength[i] );
  783. for ( i = 0; i < MAX_ARMS; i++ )
  784. savefile->ReadMat3( upperArmToShoulderJoint[i] );
  785. for ( i = 0; i < MAX_ARMS; i++ )
  786. savefile->ReadMat3( lowerArmToElbowJoint[i] );
  787. }
  788. /*
  789. ================
  790. idIK_Reach::Init
  791. ================
  792. */
  793. bool idIK_Reach::Init( idEntity *self, const char *anim, const idVec3 &modelOffset ) {
  794. int i;
  795. const char *jointName;
  796. idTraceModel trm;
  797. idVec3 dir, handOrigin, elbowOrigin, shoulderOrigin, dirOrigin;
  798. idMat3 axis, handAxis, elbowAxis, shoulderAxis;
  799. if ( !self ) {
  800. return false;
  801. }
  802. numArms = Min( self->spawnArgs.GetInt( "ik_numArms", "0" ), MAX_ARMS );
  803. if ( numArms == 0 ) {
  804. return true;
  805. }
  806. if ( !idIK::Init( self, anim, modelOffset ) ) {
  807. return false;
  808. }
  809. int numJoints = animator->NumJoints();
  810. idJointMat *joints = ( idJointMat * )_alloca16( numJoints * sizeof( joints[0] ) );
  811. // create the animation frame used to setup the IK
  812. gameEdit->ANIM_CreateAnimFrame( animator->ModelHandle(), animator->GetAnim( modifiedAnim )->MD5Anim( 0 ), numJoints, joints, 1, animator->ModelDef()->GetVisualOffset() + modelOffset, animator->RemoveOrigin() );
  813. enabledArms = 0;
  814. // get all the joints
  815. for ( i = 0; i < numArms; i++ ) {
  816. jointName = self->spawnArgs.GetString( va( "ik_hand%d", i+1 ) );
  817. handJoints[i] = animator->GetJointHandle( jointName );
  818. if ( handJoints[i] == INVALID_JOINT ) {
  819. gameLocal.Error( "idIK_Reach::Init: invalid hand joint '%s'", jointName );
  820. }
  821. jointName = self->spawnArgs.GetString( va( "ik_elbow%d", i+1 ) );
  822. elbowJoints[i] = animator->GetJointHandle( jointName );
  823. if ( elbowJoints[i] == INVALID_JOINT ) {
  824. gameLocal.Error( "idIK_Reach::Init: invalid elbow joint '%s'\n", jointName );
  825. }
  826. jointName = self->spawnArgs.GetString( va( "ik_shoulder%d", i+1 ) );
  827. shoulderJoints[i] = animator->GetJointHandle( jointName );
  828. if ( shoulderJoints[i] == INVALID_JOINT ) {
  829. gameLocal.Error( "idIK_Reach::Init: invalid shoulder joint '%s'\n", jointName );
  830. }
  831. jointName = self->spawnArgs.GetString( va( "ik_elbowDir%d", i+1 ) );
  832. dirJoints[i] = animator->GetJointHandle( jointName );
  833. enabledArms |= 1 << i;
  834. }
  835. // get the arm bone lengths and rotation matrices
  836. for ( i = 0; i < numArms; i++ ) {
  837. handAxis = joints[ handJoints[ i ] ].ToMat3();
  838. handOrigin = joints[ handJoints[ i ] ].ToVec3();
  839. elbowAxis = joints[ elbowJoints[ i ] ].ToMat3();
  840. elbowOrigin = joints[ elbowJoints[ i ] ].ToVec3();
  841. shoulderAxis = joints[ shoulderJoints[ i ] ].ToMat3();
  842. shoulderOrigin = joints[ shoulderJoints[ i ] ].ToVec3();
  843. // get the IK direction
  844. if ( dirJoints[i] != INVALID_JOINT ) {
  845. dirOrigin = joints[ dirJoints[ i ] ].ToVec3();
  846. dir = dirOrigin - elbowOrigin;
  847. } else {
  848. dir.Set( -1.0f, 0.0f, 0.0f );
  849. }
  850. shoulderForward[i] = dir * shoulderAxis.Transpose();
  851. elbowForward[i] = dir * elbowAxis.Transpose();
  852. // conversion from upper arm bone axis to should joint axis
  853. upperArmLength[i] = GetBoneAxis( shoulderOrigin, elbowOrigin, dir, axis );
  854. upperArmToShoulderJoint[i] = shoulderAxis * axis.Transpose();
  855. // conversion from lower arm bone axis to elbow joint axis
  856. lowerArmLength[i] = GetBoneAxis( elbowOrigin, handOrigin, dir, axis );
  857. lowerArmToElbowJoint[i] = elbowAxis * axis.Transpose();
  858. }
  859. initialized = true;
  860. return true;
  861. }
  862. /*
  863. ================
  864. idIK_Reach::Evaluate
  865. ================
  866. */
  867. void idIK_Reach::Evaluate( void ) {
  868. int i;
  869. idVec3 modelOrigin, shoulderOrigin, elbowOrigin, handOrigin, shoulderDir, elbowDir;
  870. idMat3 modelAxis, axis;
  871. idMat3 shoulderAxis[MAX_ARMS], elbowAxis[MAX_ARMS];
  872. trace_t trace;
  873. modelOrigin = self->GetRenderEntity()->origin;
  874. modelAxis = self->GetRenderEntity()->axis;
  875. // solve IK
  876. for ( i = 0; i < numArms; i++ ) {
  877. // get the position of the shoulder in world space
  878. animator->GetJointTransform( shoulderJoints[i], gameLocal.time, shoulderOrigin, axis );
  879. shoulderOrigin = modelOrigin + shoulderOrigin * modelAxis;
  880. shoulderDir = shoulderForward[i] * axis * modelAxis;
  881. // get the position of the hand in world space
  882. animator->GetJointTransform( handJoints[i], gameLocal.time, handOrigin, axis );
  883. handOrigin = modelOrigin + handOrigin * modelAxis;
  884. // get first collision going from shoulder to hand
  885. gameLocal.clip.TracePoint( trace, shoulderOrigin, handOrigin, CONTENTS_SOLID, self );
  886. handOrigin = trace.endpos;
  887. // get the IK bend direction
  888. animator->GetJointTransform( elbowJoints[i], gameLocal.time, elbowOrigin, axis );
  889. elbowDir = elbowForward[i] * axis * modelAxis;
  890. // solve IK and calculate elbow position
  891. SolveTwoBones( shoulderOrigin, handOrigin, elbowDir, upperArmLength[i], lowerArmLength[i], elbowOrigin );
  892. if ( ik_debug.GetBool() ) {
  893. gameRenderWorld->DebugLine( colorCyan, shoulderOrigin, elbowOrigin );
  894. gameRenderWorld->DebugLine( colorRed, elbowOrigin, handOrigin );
  895. gameRenderWorld->DebugLine( colorYellow, elbowOrigin, elbowOrigin + elbowDir );
  896. gameRenderWorld->DebugLine( colorGreen, elbowOrigin, elbowOrigin + shoulderDir );
  897. }
  898. // get the axis for the shoulder joint
  899. GetBoneAxis( shoulderOrigin, elbowOrigin, shoulderDir, axis );
  900. shoulderAxis[i] = upperArmToShoulderJoint[i] * ( axis * modelAxis.Transpose() );
  901. // get the axis for the elbow joint
  902. GetBoneAxis( elbowOrigin, handOrigin, elbowDir, axis );
  903. elbowAxis[i] = lowerArmToElbowJoint[i] * ( axis * modelAxis.Transpose() );
  904. }
  905. for ( i = 0; i < numArms; i++ ) {
  906. animator->SetJointAxis( shoulderJoints[i], JOINTMOD_WORLD_OVERRIDE, shoulderAxis[i] );
  907. animator->SetJointAxis( elbowJoints[i], JOINTMOD_WORLD_OVERRIDE, elbowAxis[i] );
  908. }
  909. ik_activate = true;
  910. }
  911. /*
  912. ================
  913. idIK_Reach::ClearJointMods
  914. ================
  915. */
  916. void idIK_Reach::ClearJointMods( void ) {
  917. int i;
  918. if ( !self || !ik_activate ) {
  919. return;
  920. }
  921. for ( i = 0; i < numArms; i++ ) {
  922. animator->SetJointAxis( shoulderJoints[i], JOINTMOD_NONE, mat3_identity );
  923. animator->SetJointAxis( elbowJoints[i], JOINTMOD_NONE, mat3_identity );
  924. animator->SetJointAxis( handJoints[i], JOINTMOD_NONE, mat3_identity );
  925. }
  926. ik_activate = false;
  927. }