Physics_Parametric.cpp 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182
  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. CLASS_DECLARATION( idPhysics_Base, idPhysics_Parametric )
  24. END_CLASS
  25. /*
  26. ================
  27. idPhysics_Parametric::Activate
  28. ================
  29. */
  30. void idPhysics_Parametric::Activate( void ) {
  31. current.atRest = -1;
  32. self->BecomeActive( TH_PHYSICS );
  33. }
  34. /*
  35. ================
  36. idPhysics_Parametric::TestIfAtRest
  37. ================
  38. */
  39. bool idPhysics_Parametric::TestIfAtRest( void ) const {
  40. if ( ( current.linearExtrapolation.GetExtrapolationType() & ~EXTRAPOLATION_NOSTOP ) == EXTRAPOLATION_NONE &&
  41. ( current.angularExtrapolation.GetExtrapolationType() & ~EXTRAPOLATION_NOSTOP ) == EXTRAPOLATION_NONE &&
  42. current.linearInterpolation.GetDuration() == 0 &&
  43. current.angularInterpolation.GetDuration() == 0 &&
  44. current.spline == NULL ) {
  45. return true;
  46. }
  47. if ( !current.linearExtrapolation.IsDone( current.time ) ) {
  48. return false;
  49. }
  50. if ( !current.angularExtrapolation.IsDone( current.time ) ) {
  51. return false;
  52. }
  53. if ( !current.linearInterpolation.IsDone( current.time ) ) {
  54. return false;
  55. }
  56. if ( !current.angularInterpolation.IsDone( current.time ) ) {
  57. return false;
  58. }
  59. if ( current.spline != NULL && !current.spline->IsDone( current.time ) ) {
  60. return false;
  61. }
  62. return true;
  63. }
  64. /*
  65. ================
  66. idPhysics_Parametric::Rest
  67. ================
  68. */
  69. void idPhysics_Parametric::Rest( void ) {
  70. current.atRest = gameLocal.time;
  71. self->BecomeInactive( TH_PHYSICS );
  72. }
  73. /*
  74. ================
  75. idPhysics_Parametric::idPhysics_Parametric
  76. ================
  77. */
  78. idPhysics_Parametric::idPhysics_Parametric( void ) {
  79. current.time = gameLocal.time;
  80. current.atRest = -1;
  81. current.useSplineAngles = false;
  82. current.origin.Zero();
  83. current.angles.Zero();
  84. current.axis.Identity();
  85. current.localOrigin.Zero();
  86. current.localAngles.Zero();
  87. current.linearExtrapolation.Init( 0, 0, vec3_zero, vec3_zero, vec3_zero, EXTRAPOLATION_NONE );
  88. current.angularExtrapolation.Init( 0, 0, ang_zero, ang_zero, ang_zero, EXTRAPOLATION_NONE );
  89. current.linearInterpolation.Init( 0, 0, 0, 0, vec3_zero, vec3_zero );
  90. current.angularInterpolation.Init( 0, 0, 0, 0, ang_zero, ang_zero );
  91. current.spline = NULL;
  92. current.splineInterpolate.Init( 0, 1, 1, 2, 0, 0 );
  93. saved = current;
  94. isPusher = false;
  95. pushFlags = 0;
  96. clipModel = NULL;
  97. isBlocked = false;
  98. memset( &pushResults, 0, sizeof( pushResults ) );
  99. hasMaster = false;
  100. isOrientated = false;
  101. }
  102. /*
  103. ================
  104. idPhysics_Parametric::~idPhysics_Parametric
  105. ================
  106. */
  107. idPhysics_Parametric::~idPhysics_Parametric( void ) {
  108. if ( clipModel != NULL ) {
  109. delete clipModel;
  110. clipModel = NULL;
  111. }
  112. if ( current.spline != NULL ) {
  113. delete current.spline;
  114. current.spline = NULL;
  115. }
  116. }
  117. /*
  118. ================
  119. idPhysics_Parametric_SavePState
  120. ================
  121. */
  122. void idPhysics_Parametric_SavePState( idSaveGame *savefile, const parametricPState_t &state ) {
  123. savefile->WriteInt( state.time );
  124. savefile->WriteInt( state.atRest );
  125. savefile->WriteBool( state.useSplineAngles );
  126. savefile->WriteVec3( state.origin );
  127. savefile->WriteAngles( state.angles );
  128. savefile->WriteMat3( state.axis );
  129. savefile->WriteVec3( state.localOrigin );
  130. savefile->WriteAngles( state.localAngles );
  131. savefile->WriteInt( (int)state.linearExtrapolation.GetExtrapolationType() );
  132. savefile->WriteFloat( state.linearExtrapolation.GetStartTime() );
  133. savefile->WriteFloat( state.linearExtrapolation.GetDuration() );
  134. savefile->WriteVec3( state.linearExtrapolation.GetStartValue() );
  135. savefile->WriteVec3( state.linearExtrapolation.GetBaseSpeed() );
  136. savefile->WriteVec3( state.linearExtrapolation.GetSpeed() );
  137. savefile->WriteInt( (int)state.angularExtrapolation.GetExtrapolationType() );
  138. savefile->WriteFloat( state.angularExtrapolation.GetStartTime() );
  139. savefile->WriteFloat( state.angularExtrapolation.GetDuration() );
  140. savefile->WriteAngles( state.angularExtrapolation.GetStartValue() );
  141. savefile->WriteAngles( state.angularExtrapolation.GetBaseSpeed() );
  142. savefile->WriteAngles( state.angularExtrapolation.GetSpeed() );
  143. savefile->WriteFloat( state.linearInterpolation.GetStartTime() );
  144. savefile->WriteFloat( state.linearInterpolation.GetAcceleration() );
  145. savefile->WriteFloat( state.linearInterpolation.GetDeceleration() );
  146. savefile->WriteFloat( state.linearInterpolation.GetDuration() );
  147. savefile->WriteVec3( state.linearInterpolation.GetStartValue() );
  148. savefile->WriteVec3( state.linearInterpolation.GetEndValue() );
  149. savefile->WriteFloat( state.angularInterpolation.GetStartTime() );
  150. savefile->WriteFloat( state.angularInterpolation.GetAcceleration() );
  151. savefile->WriteFloat( state.angularInterpolation.GetDeceleration() );
  152. savefile->WriteFloat( state.angularInterpolation.GetDuration() );
  153. savefile->WriteAngles( state.angularInterpolation.GetStartValue() );
  154. savefile->WriteAngles( state.angularInterpolation.GetEndValue() );
  155. // spline is handled by owner
  156. savefile->WriteFloat( state.splineInterpolate.GetStartTime() );
  157. savefile->WriteFloat( state.splineInterpolate.GetAcceleration() );
  158. savefile->WriteFloat( state.splineInterpolate.GetDuration() );
  159. savefile->WriteFloat( state.splineInterpolate.GetDeceleration() );
  160. savefile->WriteFloat( state.splineInterpolate.GetStartValue() );
  161. savefile->WriteFloat( state.splineInterpolate.GetEndValue() );
  162. }
  163. /*
  164. ================
  165. idPhysics_Parametric_RestorePState
  166. ================
  167. */
  168. void idPhysics_Parametric_RestorePState( idRestoreGame *savefile, parametricPState_t &state ) {
  169. extrapolation_t etype;
  170. float startTime, duration, accelTime, decelTime, startValue, endValue;
  171. idVec3 linearStartValue, linearBaseSpeed, linearSpeed, startPos, endPos;
  172. idAngles angularStartValue, angularBaseSpeed, angularSpeed, startAng, endAng;
  173. savefile->ReadInt( state.time );
  174. savefile->ReadInt( state.atRest );
  175. savefile->ReadBool( state.useSplineAngles );
  176. savefile->ReadVec3( state.origin );
  177. savefile->ReadAngles( state.angles );
  178. savefile->ReadMat3( state.axis );
  179. savefile->ReadVec3( state.localOrigin );
  180. savefile->ReadAngles( state.localAngles );
  181. savefile->ReadInt( (int &)etype );
  182. savefile->ReadFloat( startTime );
  183. savefile->ReadFloat( duration );
  184. savefile->ReadVec3( linearStartValue );
  185. savefile->ReadVec3( linearBaseSpeed );
  186. savefile->ReadVec3( linearSpeed );
  187. state.linearExtrapolation.Init( startTime, duration, linearStartValue, linearBaseSpeed, linearSpeed, etype );
  188. savefile->ReadInt( (int &)etype );
  189. savefile->ReadFloat( startTime );
  190. savefile->ReadFloat( duration );
  191. savefile->ReadAngles( angularStartValue );
  192. savefile->ReadAngles( angularBaseSpeed );
  193. savefile->ReadAngles( angularSpeed );
  194. state.angularExtrapolation.Init( startTime, duration, angularStartValue, angularBaseSpeed, angularSpeed, etype );
  195. savefile->ReadFloat( startTime );
  196. savefile->ReadFloat( accelTime );
  197. savefile->ReadFloat( decelTime );
  198. savefile->ReadFloat( duration );
  199. savefile->ReadVec3( startPos );
  200. savefile->ReadVec3( endPos );
  201. state.linearInterpolation.Init( startTime, accelTime, decelTime, duration, startPos, endPos );
  202. savefile->ReadFloat( startTime );
  203. savefile->ReadFloat( accelTime );
  204. savefile->ReadFloat( decelTime );
  205. savefile->ReadFloat( duration );
  206. savefile->ReadAngles( startAng );
  207. savefile->ReadAngles( endAng );
  208. state.angularInterpolation.Init( startTime, accelTime, decelTime, duration, startAng, endAng );
  209. // spline is handled by owner
  210. savefile->ReadFloat( startTime );
  211. savefile->ReadFloat( accelTime );
  212. savefile->ReadFloat( duration );
  213. savefile->ReadFloat( decelTime );
  214. savefile->ReadFloat( startValue );
  215. savefile->ReadFloat( endValue );
  216. state.splineInterpolate.Init( startTime, accelTime, decelTime, duration, startValue, endValue );
  217. }
  218. /*
  219. ================
  220. idPhysics_Parametric::Save
  221. ================
  222. */
  223. void idPhysics_Parametric::Save( idSaveGame *savefile ) const {
  224. idPhysics_Parametric_SavePState( savefile, current );
  225. idPhysics_Parametric_SavePState( savefile, saved );
  226. savefile->WriteBool( isPusher );
  227. savefile->WriteClipModel( clipModel );
  228. savefile->WriteInt( pushFlags );
  229. savefile->WriteTrace( pushResults );
  230. savefile->WriteBool( isBlocked );
  231. savefile->WriteBool( hasMaster );
  232. savefile->WriteBool( isOrientated );
  233. }
  234. /*
  235. ================
  236. idPhysics_Parametric::Restore
  237. ================
  238. */
  239. void idPhysics_Parametric::Restore( idRestoreGame *savefile ) {
  240. idPhysics_Parametric_RestorePState( savefile, current );
  241. idPhysics_Parametric_RestorePState( savefile, saved );
  242. savefile->ReadBool( isPusher );
  243. savefile->ReadClipModel( clipModel );
  244. savefile->ReadInt( pushFlags );
  245. savefile->ReadTrace( pushResults );
  246. savefile->ReadBool( isBlocked );
  247. savefile->ReadBool( hasMaster );
  248. savefile->ReadBool( isOrientated );
  249. }
  250. /*
  251. ================
  252. idPhysics_Parametric::SetPusher
  253. ================
  254. */
  255. void idPhysics_Parametric::SetPusher( int flags ) {
  256. assert( clipModel );
  257. isPusher = true;
  258. pushFlags = flags;
  259. }
  260. /*
  261. ================
  262. idPhysics_Parametric::IsPusher
  263. ================
  264. */
  265. bool idPhysics_Parametric::IsPusher( void ) const {
  266. return isPusher;
  267. }
  268. /*
  269. ================
  270. idPhysics_Parametric::SetLinearExtrapolation
  271. ================
  272. */
  273. void idPhysics_Parametric::SetLinearExtrapolation( extrapolation_t type, int time, int duration, const idVec3 &base, const idVec3 &speed, const idVec3 &baseSpeed ) {
  274. current.time = gameLocal.time;
  275. current.linearExtrapolation.Init( time, duration, base, baseSpeed, speed, type );
  276. current.localOrigin = base;
  277. Activate();
  278. }
  279. /*
  280. ================
  281. idPhysics_Parametric::SetAngularExtrapolation
  282. ================
  283. */
  284. void idPhysics_Parametric::SetAngularExtrapolation( extrapolation_t type, int time, int duration, const idAngles &base, const idAngles &speed, const idAngles &baseSpeed ) {
  285. current.time = gameLocal.time;
  286. current.angularExtrapolation.Init( time, duration, base, baseSpeed, speed, type );
  287. current.localAngles = base;
  288. Activate();
  289. }
  290. /*
  291. ================
  292. idPhysics_Parametric::GetLinearExtrapolationType
  293. ================
  294. */
  295. extrapolation_t idPhysics_Parametric::GetLinearExtrapolationType( void ) const {
  296. return current.linearExtrapolation.GetExtrapolationType();
  297. }
  298. /*
  299. ================
  300. idPhysics_Parametric::GetAngularExtrapolationType
  301. ================
  302. */
  303. extrapolation_t idPhysics_Parametric::GetAngularExtrapolationType( void ) const {
  304. return current.angularExtrapolation.GetExtrapolationType();
  305. }
  306. /*
  307. ================
  308. idPhysics_Parametric::SetLinearInterpolation
  309. ================
  310. */
  311. void idPhysics_Parametric::SetLinearInterpolation( int time, int accelTime, int decelTime, int duration, const idVec3 &startPos, const idVec3 &endPos ) {
  312. current.time = gameLocal.time;
  313. current.linearInterpolation.Init( time, accelTime, decelTime, duration, startPos, endPos );
  314. current.localOrigin = startPos;
  315. Activate();
  316. }
  317. /*
  318. ================
  319. idPhysics_Parametric::SetAngularInterpolation
  320. ================
  321. */
  322. void idPhysics_Parametric::SetAngularInterpolation( int time, int accelTime, int decelTime, int duration, const idAngles &startAng, const idAngles &endAng ) {
  323. current.time = gameLocal.time;
  324. current.angularInterpolation.Init( time, accelTime, decelTime, duration, startAng, endAng );
  325. current.localAngles = startAng;
  326. Activate();
  327. }
  328. /*
  329. ================
  330. idPhysics_Parametric::SetSpline
  331. ================
  332. */
  333. void idPhysics_Parametric::SetSpline( idCurve_Spline<idVec3> *spline, int accelTime, int decelTime, bool useSplineAngles ) {
  334. if ( current.spline != NULL ) {
  335. delete current.spline;
  336. current.spline = NULL;
  337. }
  338. current.spline = spline;
  339. if ( current.spline != NULL ) {
  340. float startTime = current.spline->GetTime( 0 );
  341. float endTime = current.spline->GetTime( current.spline->GetNumValues() - 1 );
  342. float length = current.spline->GetLengthForTime( endTime );
  343. current.splineInterpolate.Init( startTime, accelTime, decelTime, endTime - startTime, 0.0f, length );
  344. }
  345. current.useSplineAngles = useSplineAngles;
  346. Activate();
  347. }
  348. /*
  349. ================
  350. idPhysics_Parametric::GetSpline
  351. ================
  352. */
  353. idCurve_Spline<idVec3> *idPhysics_Parametric::GetSpline( void ) const {
  354. return current.spline;
  355. }
  356. /*
  357. ================
  358. idPhysics_Parametric::GetSplineAcceleration
  359. ================
  360. */
  361. int idPhysics_Parametric::GetSplineAcceleration( void ) const {
  362. return current.splineInterpolate.GetAcceleration();
  363. }
  364. /*
  365. ================
  366. idPhysics_Parametric::GetSplineDeceleration
  367. ================
  368. */
  369. int idPhysics_Parametric::GetSplineDeceleration( void ) const {
  370. return current.splineInterpolate.GetDeceleration();
  371. }
  372. /*
  373. ================
  374. idPhysics_Parametric::UsingSplineAngles
  375. ================
  376. */
  377. bool idPhysics_Parametric::UsingSplineAngles( void ) const {
  378. return current.useSplineAngles;
  379. }
  380. /*
  381. ================
  382. idPhysics_Parametric::GetLocalOrigin
  383. ================
  384. */
  385. void idPhysics_Parametric::GetLocalOrigin( idVec3 &curOrigin ) const {
  386. curOrigin = current.localOrigin;
  387. }
  388. /*
  389. ================
  390. idPhysics_Parametric::GetLocalAngles
  391. ================
  392. */
  393. void idPhysics_Parametric::GetLocalAngles( idAngles &curAngles ) const {
  394. curAngles = current.localAngles;
  395. }
  396. /*
  397. ================
  398. idPhysics_Parametric::SetClipModel
  399. ================
  400. */
  401. void idPhysics_Parametric::SetClipModel( idClipModel *model, float density, int id, bool freeOld ) {
  402. assert( self );
  403. assert( model );
  404. if ( clipModel && clipModel != model && freeOld ) {
  405. delete clipModel;
  406. }
  407. clipModel = model;
  408. clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
  409. }
  410. /*
  411. ================
  412. idPhysics_Parametric::GetClipModel
  413. ================
  414. */
  415. idClipModel *idPhysics_Parametric::GetClipModel( int id ) const {
  416. return clipModel;
  417. }
  418. /*
  419. ================
  420. idPhysics_Parametric::GetNumClipModels
  421. ================
  422. */
  423. int idPhysics_Parametric::GetNumClipModels( void ) const {
  424. return ( clipModel != NULL );
  425. }
  426. /*
  427. ================
  428. idPhysics_Parametric::SetMass
  429. ================
  430. */
  431. void idPhysics_Parametric::SetMass( float mass, int id ) {
  432. }
  433. /*
  434. ================
  435. idPhysics_Parametric::GetMass
  436. ================
  437. */
  438. float idPhysics_Parametric::GetMass( int id ) const {
  439. return 0.0f;
  440. }
  441. /*
  442. ================
  443. idPhysics_Parametric::SetClipMask
  444. ================
  445. */
  446. void idPhysics_Parametric::SetContents( int contents, int id ) {
  447. if ( clipModel ) {
  448. clipModel->SetContents( contents );
  449. }
  450. }
  451. /*
  452. ================
  453. idPhysics_Parametric::SetClipMask
  454. ================
  455. */
  456. int idPhysics_Parametric::GetContents( int id ) const {
  457. if ( clipModel ) {
  458. return clipModel->GetContents();
  459. }
  460. return 0;
  461. }
  462. /*
  463. ================
  464. idPhysics_Parametric::GetBounds
  465. ================
  466. */
  467. const idBounds &idPhysics_Parametric::GetBounds( int id ) const {
  468. if ( clipModel ) {
  469. return clipModel->GetBounds();
  470. }
  471. return idPhysics_Base::GetBounds();
  472. }
  473. /*
  474. ================
  475. idPhysics_Parametric::GetAbsBounds
  476. ================
  477. */
  478. const idBounds &idPhysics_Parametric::GetAbsBounds( int id ) const {
  479. if ( clipModel ) {
  480. return clipModel->GetAbsBounds();
  481. }
  482. return idPhysics_Base::GetAbsBounds();
  483. }
  484. /*
  485. ================
  486. idPhysics_Parametric::Evaluate
  487. ================
  488. */
  489. bool idPhysics_Parametric::Evaluate( int timeStepMSec, int endTimeMSec ) {
  490. idVec3 oldLocalOrigin, oldOrigin, masterOrigin;
  491. idAngles oldLocalAngles, oldAngles;
  492. idMat3 oldAxis, masterAxis;
  493. isBlocked = false;
  494. oldLocalOrigin = current.localOrigin;
  495. oldOrigin = current.origin;
  496. oldLocalAngles = current.localAngles;
  497. oldAngles = current.angles;
  498. oldAxis = current.axis;
  499. current.localOrigin.Zero();
  500. current.localAngles.Zero();
  501. if ( current.spline != NULL ) {
  502. float length = current.splineInterpolate.GetCurrentValue( endTimeMSec );
  503. float t = current.spline->GetTimeForLength( length, 0.01f );
  504. current.localOrigin = current.spline->GetCurrentValue( t );
  505. if ( current.useSplineAngles ) {
  506. current.localAngles = current.spline->GetCurrentFirstDerivative( t ).ToAngles();
  507. }
  508. } else if ( current.linearInterpolation.GetDuration() != 0 ) {
  509. current.localOrigin += current.linearInterpolation.GetCurrentValue( endTimeMSec );
  510. } else {
  511. current.localOrigin += current.linearExtrapolation.GetCurrentValue( endTimeMSec );
  512. }
  513. if ( current.angularInterpolation.GetDuration() != 0 ) {
  514. current.localAngles += current.angularInterpolation.GetCurrentValue( endTimeMSec );
  515. } else {
  516. current.localAngles += current.angularExtrapolation.GetCurrentValue( endTimeMSec );
  517. }
  518. current.localAngles.Normalize360();
  519. current.origin = current.localOrigin;
  520. current.angles = current.localAngles;
  521. current.axis = current.localAngles.ToMat3();
  522. if ( hasMaster ) {
  523. self->GetMasterPosition( masterOrigin, masterAxis );
  524. if ( masterAxis.IsRotated() ) {
  525. current.origin = current.origin * masterAxis + masterOrigin;
  526. if ( isOrientated ) {
  527. current.axis *= masterAxis;
  528. current.angles = current.axis.ToAngles();
  529. }
  530. }
  531. else {
  532. current.origin += masterOrigin;
  533. }
  534. }
  535. if ( isPusher ) {
  536. gameLocal.push.ClipPush( pushResults, self, pushFlags, oldOrigin, oldAxis, current.origin, current.axis );
  537. if ( pushResults.fraction < 1.0f ) {
  538. clipModel->Link( gameLocal.clip, self, 0, oldOrigin, oldAxis );
  539. current.localOrigin = oldLocalOrigin;
  540. current.origin = oldOrigin;
  541. current.localAngles = oldLocalAngles;
  542. current.angles = oldAngles;
  543. current.axis = oldAxis;
  544. isBlocked = true;
  545. return false;
  546. }
  547. current.angles = current.axis.ToAngles();
  548. }
  549. if ( clipModel ) {
  550. clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
  551. }
  552. current.time = endTimeMSec;
  553. if ( TestIfAtRest() ) {
  554. Rest();
  555. }
  556. return ( current.origin != oldOrigin || current.axis != oldAxis );
  557. }
  558. /*
  559. ================
  560. idPhysics_Parametric::UpdateTime
  561. ================
  562. */
  563. void idPhysics_Parametric::UpdateTime( int endTimeMSec ) {
  564. int timeLeap = endTimeMSec - current.time;
  565. current.time = endTimeMSec;
  566. // move the trajectory start times to sync the trajectory with the current endTime
  567. current.linearExtrapolation.SetStartTime( current.linearExtrapolation.GetStartTime() + timeLeap );
  568. current.angularExtrapolation.SetStartTime( current.angularExtrapolation.GetStartTime() + timeLeap );
  569. current.linearInterpolation.SetStartTime( current.linearInterpolation.GetStartTime() + timeLeap );
  570. current.angularInterpolation.SetStartTime( current.angularInterpolation.GetStartTime() + timeLeap );
  571. if ( current.spline != NULL ) {
  572. current.spline->ShiftTime( timeLeap );
  573. current.splineInterpolate.SetStartTime( current.splineInterpolate.GetStartTime() + timeLeap );
  574. }
  575. }
  576. /*
  577. ================
  578. idPhysics_Parametric::GetTime
  579. ================
  580. */
  581. int idPhysics_Parametric::GetTime( void ) const {
  582. return current.time;
  583. }
  584. /*
  585. ================
  586. idPhysics_Parametric::IsAtRest
  587. ================
  588. */
  589. bool idPhysics_Parametric::IsAtRest( void ) const {
  590. return current.atRest >= 0;
  591. }
  592. /*
  593. ================
  594. idPhysics_Parametric::GetRestStartTime
  595. ================
  596. */
  597. int idPhysics_Parametric::GetRestStartTime( void ) const {
  598. return current.atRest;
  599. }
  600. /*
  601. ================
  602. idPhysics_Parametric::IsPushable
  603. ================
  604. */
  605. bool idPhysics_Parametric::IsPushable( void ) const {
  606. return false;
  607. }
  608. /*
  609. ================
  610. idPhysics_Parametric::SaveState
  611. ================
  612. */
  613. void idPhysics_Parametric::SaveState( void ) {
  614. saved = current;
  615. }
  616. /*
  617. ================
  618. idPhysics_Parametric::RestoreState
  619. ================
  620. */
  621. void idPhysics_Parametric::RestoreState( void ) {
  622. current = saved;
  623. if ( clipModel ) {
  624. clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
  625. }
  626. }
  627. /*
  628. ================
  629. idPhysics_Parametric::SetOrigin
  630. ================
  631. */
  632. void idPhysics_Parametric::SetOrigin( const idVec3 &newOrigin, int id ) {
  633. idVec3 masterOrigin;
  634. idMat3 masterAxis;
  635. current.linearExtrapolation.SetStartValue( newOrigin );
  636. current.linearInterpolation.SetStartValue( newOrigin );
  637. current.localOrigin = current.linearExtrapolation.GetCurrentValue( current.time );
  638. if ( hasMaster ) {
  639. self->GetMasterPosition( masterOrigin, masterAxis );
  640. current.origin = masterOrigin + current.localOrigin * masterAxis;
  641. }
  642. else {
  643. current.origin = current.localOrigin;
  644. }
  645. if ( clipModel ) {
  646. clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
  647. }
  648. Activate();
  649. }
  650. /*
  651. ================
  652. idPhysics_Parametric::SetAxis
  653. ================
  654. */
  655. void idPhysics_Parametric::SetAxis( const idMat3 &newAxis, int id ) {
  656. idVec3 masterOrigin;
  657. idMat3 masterAxis;
  658. current.localAngles = newAxis.ToAngles();
  659. current.angularExtrapolation.SetStartValue( current.localAngles );
  660. current.angularInterpolation.SetStartValue( current.localAngles );
  661. current.localAngles = current.angularExtrapolation.GetCurrentValue( current.time );
  662. if ( hasMaster && isOrientated ) {
  663. self->GetMasterPosition( masterOrigin, masterAxis );
  664. current.axis = current.localAngles.ToMat3() * masterAxis;
  665. current.angles = current.axis.ToAngles();
  666. }
  667. else {
  668. current.axis = current.localAngles.ToMat3();
  669. current.angles = current.localAngles;
  670. }
  671. if ( clipModel ) {
  672. clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
  673. }
  674. Activate();
  675. }
  676. /*
  677. ================
  678. idPhysics_Parametric::Move
  679. ================
  680. */
  681. void idPhysics_Parametric::Translate( const idVec3 &translation, int id ) {
  682. }
  683. /*
  684. ================
  685. idPhysics_Parametric::Rotate
  686. ================
  687. */
  688. void idPhysics_Parametric::Rotate( const idRotation &rotation, int id ) {
  689. }
  690. /*
  691. ================
  692. idPhysics_Parametric::GetOrigin
  693. ================
  694. */
  695. const idVec3 &idPhysics_Parametric::GetOrigin( int id ) const {
  696. return current.origin;
  697. }
  698. /*
  699. ================
  700. idPhysics_Parametric::GetAxis
  701. ================
  702. */
  703. const idMat3 &idPhysics_Parametric::GetAxis( int id ) const {
  704. return current.axis;
  705. }
  706. /*
  707. ================
  708. idPhysics_Parametric::GetAngles
  709. ================
  710. */
  711. void idPhysics_Parametric::GetAngles( idAngles &curAngles ) const {
  712. curAngles = current.angles;
  713. }
  714. /*
  715. ================
  716. idPhysics_Parametric::SetLinearVelocity
  717. ================
  718. */
  719. void idPhysics_Parametric::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) {
  720. SetLinearExtrapolation( extrapolation_t(EXTRAPOLATION_LINEAR|EXTRAPOLATION_NOSTOP), gameLocal.time, 0, current.origin, newLinearVelocity, vec3_origin );
  721. current.linearInterpolation.Init( 0, 0, 0, 0, vec3_zero, vec3_zero );
  722. Activate();
  723. }
  724. /*
  725. ================
  726. idPhysics_Parametric::SetAngularVelocity
  727. ================
  728. */
  729. void idPhysics_Parametric::SetAngularVelocity( const idVec3 &newAngularVelocity, int id ) {
  730. idRotation rotation;
  731. idVec3 vec;
  732. float angle;
  733. vec = newAngularVelocity;
  734. angle = vec.Normalize();
  735. rotation.Set( vec3_origin, vec, (float) RAD2DEG( angle ) );
  736. SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_LINEAR|EXTRAPOLATION_NOSTOP), gameLocal.time, 0, current.angles, rotation.ToAngles(), ang_zero );
  737. current.angularInterpolation.Init( 0, 0, 0, 0, ang_zero, ang_zero );
  738. Activate();
  739. }
  740. /*
  741. ================
  742. idPhysics_Parametric::GetLinearVelocity
  743. ================
  744. */
  745. const idVec3 &idPhysics_Parametric::GetLinearVelocity( int id ) const {
  746. static idVec3 curLinearVelocity;
  747. curLinearVelocity = current.linearExtrapolation.GetCurrentSpeed( gameLocal.time );
  748. return curLinearVelocity;
  749. }
  750. /*
  751. ================
  752. idPhysics_Parametric::GetAngularVelocity
  753. ================
  754. */
  755. const idVec3 &idPhysics_Parametric::GetAngularVelocity( int id ) const {
  756. static idVec3 curAngularVelocity;
  757. idAngles angles;
  758. angles = current.angularExtrapolation.GetCurrentSpeed( gameLocal.time );
  759. curAngularVelocity = angles.ToAngularVelocity();
  760. return curAngularVelocity;
  761. }
  762. /*
  763. ================
  764. idPhysics_Parametric::DisableClip
  765. ================
  766. */
  767. void idPhysics_Parametric::DisableClip( void ) {
  768. if ( clipModel ) {
  769. clipModel->Disable();
  770. }
  771. }
  772. /*
  773. ================
  774. idPhysics_Parametric::EnableClip
  775. ================
  776. */
  777. void idPhysics_Parametric::EnableClip( void ) {
  778. if ( clipModel ) {
  779. clipModel->Enable();
  780. }
  781. }
  782. /*
  783. ================
  784. idPhysics_Parametric::UnlinkClip
  785. ================
  786. */
  787. void idPhysics_Parametric::UnlinkClip( void ) {
  788. if ( clipModel ) {
  789. clipModel->Unlink();
  790. }
  791. }
  792. /*
  793. ================
  794. idPhysics_Parametric::LinkClip
  795. ================
  796. */
  797. void idPhysics_Parametric::LinkClip( void ) {
  798. if ( clipModel ) {
  799. clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
  800. }
  801. }
  802. /*
  803. ================
  804. idPhysics_Parametric::GetBlockingInfo
  805. ================
  806. */
  807. const trace_t *idPhysics_Parametric::GetBlockingInfo( void ) const {
  808. return ( isBlocked ? &pushResults : NULL );
  809. }
  810. /*
  811. ================
  812. idPhysics_Parametric::GetBlockingEntity
  813. ================
  814. */
  815. idEntity *idPhysics_Parametric::GetBlockingEntity( void ) const {
  816. if ( isBlocked ) {
  817. return gameLocal.entities[ pushResults.c.entityNum ];
  818. }
  819. return NULL;
  820. }
  821. /*
  822. ================
  823. idPhysics_Parametric::SetMaster
  824. ================
  825. */
  826. void idPhysics_Parametric::SetMaster( idEntity *master, const bool orientated ) {
  827. idVec3 masterOrigin;
  828. idMat3 masterAxis;
  829. if ( master ) {
  830. if ( !hasMaster ) {
  831. // transform from world space to master space
  832. self->GetMasterPosition( masterOrigin, masterAxis );
  833. current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose();
  834. if ( orientated ) {
  835. current.localAngles = ( current.axis * masterAxis.Transpose() ).ToAngles();
  836. }
  837. else {
  838. current.localAngles = current.axis.ToAngles();
  839. }
  840. current.linearExtrapolation.SetStartValue( current.localOrigin );
  841. current.angularExtrapolation.SetStartValue( current.localAngles );
  842. hasMaster = true;
  843. isOrientated = orientated;
  844. }
  845. }
  846. else {
  847. if ( hasMaster ) {
  848. // transform from master space to world space
  849. current.localOrigin = current.origin;
  850. current.localAngles = current.angles;
  851. SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, current.origin, vec3_origin, vec3_origin );
  852. SetAngularExtrapolation( EXTRAPOLATION_NONE, 0, 0, current.angles, ang_zero, ang_zero );
  853. hasMaster = false;
  854. }
  855. }
  856. }
  857. /*
  858. ================
  859. idPhysics_Parametric::GetLinearEndTime
  860. ================
  861. */
  862. int idPhysics_Parametric::GetLinearEndTime( void ) const {
  863. if ( current.spline != NULL ) {
  864. if ( current.spline->GetBoundaryType() != idCurve_Spline<idVec3>::BT_CLOSED ) {
  865. return current.spline->GetTime( current.spline->GetNumValues() - 1 );
  866. } else {
  867. return 0;
  868. }
  869. } else if ( current.linearInterpolation.GetDuration() != 0 ) {
  870. return current.linearInterpolation.GetEndTime();
  871. } else {
  872. return current.linearExtrapolation.GetEndTime();
  873. }
  874. }
  875. /*
  876. ================
  877. idPhysics_Parametric::GetAngularEndTime
  878. ================
  879. */
  880. int idPhysics_Parametric::GetAngularEndTime( void ) const {
  881. if ( current.angularInterpolation.GetDuration() != 0 ) {
  882. return current.angularInterpolation.GetEndTime();
  883. } else {
  884. return current.angularExtrapolation.GetEndTime();
  885. }
  886. }
  887. /*
  888. ================
  889. idPhysics_Parametric::WriteToSnapshot
  890. ================
  891. */
  892. void idPhysics_Parametric::WriteToSnapshot( idBitMsgDelta &msg ) const {
  893. msg.WriteLong( current.time );
  894. msg.WriteLong( current.atRest );
  895. msg.WriteFloat( current.origin[0] );
  896. msg.WriteFloat( current.origin[1] );
  897. msg.WriteFloat( current.origin[2] );
  898. msg.WriteFloat( current.angles[0] );
  899. msg.WriteFloat( current.angles[1] );
  900. msg.WriteFloat( current.angles[2] );
  901. msg.WriteDeltaFloat( current.origin[0], current.localOrigin[0] );
  902. msg.WriteDeltaFloat( current.origin[1], current.localOrigin[1] );
  903. msg.WriteDeltaFloat( current.origin[2], current.localOrigin[2] );
  904. msg.WriteDeltaFloat( current.angles[0], current.localAngles[0] );
  905. msg.WriteDeltaFloat( current.angles[1], current.localAngles[1] );
  906. msg.WriteDeltaFloat( current.angles[2], current.localAngles[2] );
  907. msg.WriteBits( current.linearExtrapolation.GetExtrapolationType(), 8 );
  908. msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetStartTime() );
  909. msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetDuration() );
  910. msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetStartValue()[0] );
  911. msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetStartValue()[1] );
  912. msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetStartValue()[2] );
  913. msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetSpeed()[0] );
  914. msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetSpeed()[1] );
  915. msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetSpeed()[2] );
  916. msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetBaseSpeed()[0] );
  917. msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetBaseSpeed()[1] );
  918. msg.WriteDeltaFloat( 0.0f, current.linearExtrapolation.GetBaseSpeed()[2] );
  919. msg.WriteBits( current.angularExtrapolation.GetExtrapolationType(), 8 );
  920. msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetStartTime() );
  921. msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetDuration() );
  922. msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetStartValue()[0] );
  923. msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetStartValue()[1] );
  924. msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetStartValue()[2] );
  925. msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetSpeed()[0] );
  926. msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetSpeed()[1] );
  927. msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetSpeed()[2] );
  928. msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetBaseSpeed()[0] );
  929. msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetBaseSpeed()[1] );
  930. msg.WriteDeltaFloat( 0.0f, current.angularExtrapolation.GetBaseSpeed()[2] );
  931. msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetStartTime() );
  932. msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetAcceleration() );
  933. msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetDeceleration() );
  934. msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetDuration() );
  935. msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetStartValue()[0] );
  936. msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetStartValue()[1] );
  937. msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetStartValue()[2] );
  938. msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetEndValue()[0] );
  939. msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetEndValue()[1] );
  940. msg.WriteDeltaFloat( 0.0f, current.linearInterpolation.GetEndValue()[2] );
  941. msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetStartTime() );
  942. msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetAcceleration() );
  943. msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetDeceleration() );
  944. msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetDuration() );
  945. msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetStartValue()[0] );
  946. msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetStartValue()[1] );
  947. msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetStartValue()[2] );
  948. msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetEndValue()[0] );
  949. msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetEndValue()[1] );
  950. msg.WriteDeltaFloat( 0.0f, current.angularInterpolation.GetEndValue()[2] );
  951. }
  952. /*
  953. ================
  954. idPhysics_Parametric::ReadFromSnapshot
  955. ================
  956. */
  957. void idPhysics_Parametric::ReadFromSnapshot( const idBitMsgDelta &msg ) {
  958. extrapolation_t linearType, angularType;
  959. float startTime, duration, accelTime, decelTime;
  960. idVec3 linearStartValue, linearSpeed, linearBaseSpeed, startPos, endPos;
  961. idAngles angularStartValue, angularSpeed, angularBaseSpeed, startAng, endAng;
  962. current.time = msg.ReadLong();
  963. current.atRest = msg.ReadLong();
  964. current.origin[0] = msg.ReadFloat();
  965. current.origin[1] = msg.ReadFloat();
  966. current.origin[2] = msg.ReadFloat();
  967. current.angles[0] = msg.ReadFloat();
  968. current.angles[1] = msg.ReadFloat();
  969. current.angles[2] = msg.ReadFloat();
  970. current.localOrigin[0] = msg.ReadDeltaFloat( current.origin[0] );
  971. current.localOrigin[1] = msg.ReadDeltaFloat( current.origin[1] );
  972. current.localOrigin[2] = msg.ReadDeltaFloat( current.origin[2] );
  973. current.localAngles[0] = msg.ReadDeltaFloat( current.angles[0] );
  974. current.localAngles[1] = msg.ReadDeltaFloat( current.angles[1] );
  975. current.localAngles[2] = msg.ReadDeltaFloat( current.angles[2] );
  976. linearType = (extrapolation_t) msg.ReadBits( 8 );
  977. startTime = msg.ReadDeltaFloat( 0.0f );
  978. duration = msg.ReadDeltaFloat( 0.0f );
  979. linearStartValue[0] = msg.ReadDeltaFloat( 0.0f );
  980. linearStartValue[1] = msg.ReadDeltaFloat( 0.0f );
  981. linearStartValue[2] = msg.ReadDeltaFloat( 0.0f );
  982. linearSpeed[0] = msg.ReadDeltaFloat( 0.0f );
  983. linearSpeed[1] = msg.ReadDeltaFloat( 0.0f );
  984. linearSpeed[2] = msg.ReadDeltaFloat( 0.0f );
  985. linearBaseSpeed[0] = msg.ReadDeltaFloat( 0.0f );
  986. linearBaseSpeed[1] = msg.ReadDeltaFloat( 0.0f );
  987. linearBaseSpeed[2] = msg.ReadDeltaFloat( 0.0f );
  988. current.linearExtrapolation.Init( startTime, duration, linearStartValue, linearBaseSpeed, linearSpeed, linearType );
  989. angularType = (extrapolation_t) msg.ReadBits( 8 );
  990. startTime = msg.ReadDeltaFloat( 0.0f );
  991. duration = msg.ReadDeltaFloat( 0.0f );
  992. angularStartValue[0] = msg.ReadDeltaFloat( 0.0f );
  993. angularStartValue[1] = msg.ReadDeltaFloat( 0.0f );
  994. angularStartValue[2] = msg.ReadDeltaFloat( 0.0f );
  995. angularSpeed[0] = msg.ReadDeltaFloat( 0.0f );
  996. angularSpeed[1] = msg.ReadDeltaFloat( 0.0f );
  997. angularSpeed[2] = msg.ReadDeltaFloat( 0.0f );
  998. angularBaseSpeed[0] = msg.ReadDeltaFloat( 0.0f );
  999. angularBaseSpeed[1] = msg.ReadDeltaFloat( 0.0f );
  1000. angularBaseSpeed[2] = msg.ReadDeltaFloat( 0.0f );
  1001. current.angularExtrapolation.Init( startTime, duration, angularStartValue, angularBaseSpeed, angularSpeed, angularType );
  1002. startTime = msg.ReadDeltaFloat( 0.0f );
  1003. accelTime = msg.ReadDeltaFloat( 0.0f );
  1004. decelTime = msg.ReadDeltaFloat( 0.0f );
  1005. duration = msg.ReadDeltaFloat( 0.0f );
  1006. startPos[0] = msg.ReadDeltaFloat( 0.0f );
  1007. startPos[1] = msg.ReadDeltaFloat( 0.0f );
  1008. startPos[2] = msg.ReadDeltaFloat( 0.0f );
  1009. endPos[0] = msg.ReadDeltaFloat( 0.0f );
  1010. endPos[1] = msg.ReadDeltaFloat( 0.0f );
  1011. endPos[2] = msg.ReadDeltaFloat( 0.0f );
  1012. current.linearInterpolation.Init( startTime, accelTime, decelTime, duration, startPos, endPos );
  1013. startTime = msg.ReadDeltaFloat( 0.0f );
  1014. accelTime = msg.ReadDeltaFloat( 0.0f );
  1015. decelTime = msg.ReadDeltaFloat( 0.0f );
  1016. duration = msg.ReadDeltaFloat( 0.0f );
  1017. startAng[0] = msg.ReadDeltaFloat( 0.0f );
  1018. startAng[1] = msg.ReadDeltaFloat( 0.0f );
  1019. startAng[2] = msg.ReadDeltaFloat( 0.0f );
  1020. endAng[0] = msg.ReadDeltaFloat( 0.0f );
  1021. endAng[1] = msg.ReadDeltaFloat( 0.0f );
  1022. endAng[2] = msg.ReadDeltaFloat( 0.0f );
  1023. current.angularInterpolation.Init( startTime, accelTime, decelTime, duration, startAng, endAng );
  1024. current.axis = current.angles.ToMat3();
  1025. if ( clipModel ) {
  1026. clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
  1027. }
  1028. }