IK.cpp 32 KB

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