Physics_Parametric.cpp 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087
  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. #pragma hdrstop
  21. #include "../../idlib/precompiled.h"
  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() {
  31. current.atRest = -1;
  32. self->BecomeActive( TH_PHYSICS );
  33. }
  34. /*
  35. ================
  36. idPhysics_Parametric::TestIfAtRest
  37. ================
  38. */
  39. bool idPhysics_Parametric::TestIfAtRest() 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() {
  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() {
  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() {
  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() 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() const {
  296. return current.linearExtrapolation.GetExtrapolationType();
  297. }
  298. /*
  299. ================
  300. idPhysics_Parametric::GetAngularExtrapolationType
  301. ================
  302. */
  303. extrapolation_t idPhysics_Parametric::GetAngularExtrapolationType() 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() const {
  354. return current.spline;
  355. }
  356. /*
  357. ================
  358. idPhysics_Parametric::GetSplineAcceleration
  359. ================
  360. */
  361. int idPhysics_Parametric::GetSplineAcceleration() const {
  362. return current.splineInterpolate.GetAcceleration();
  363. }
  364. /*
  365. ================
  366. idPhysics_Parametric::GetSplineDeceleration
  367. ================
  368. */
  369. int idPhysics_Parametric::GetSplineDeceleration() const {
  370. return current.splineInterpolate.GetDeceleration();
  371. }
  372. /*
  373. ================
  374. idPhysics_Parametric::UsingSplineAngles
  375. ================
  376. */
  377. bool idPhysics_Parametric::UsingSplineAngles() 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() 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. if ( clipModel ) {
  539. clipModel->Link( gameLocal.clip, self, 0, oldOrigin, oldAxis );
  540. }
  541. current.localOrigin = oldLocalOrigin;
  542. current.origin = oldOrigin;
  543. current.localAngles = oldLocalAngles;
  544. current.angles = oldAngles;
  545. current.axis = oldAxis;
  546. isBlocked = true;
  547. return false;
  548. }
  549. current.angles = current.axis.ToAngles();
  550. }
  551. if ( clipModel ) {
  552. clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
  553. }
  554. current.time = endTimeMSec;
  555. if ( TestIfAtRest() ) {
  556. Rest();
  557. }
  558. return ( current.origin != oldOrigin || current.axis != oldAxis );
  559. }
  560. /*
  561. ================
  562. Sets the currentInterpolated state based on previous, next, and the fraction.
  563. ================
  564. */
  565. bool idPhysics_Parametric::Interpolate( const float fraction ) {
  566. if( self->GetNumSnapshotsReceived() <= 1 ) {
  567. return false;
  568. }
  569. idVec3 oldOrigin = current.origin;
  570. idMat3 oldAxis = current.axis;
  571. const bool hasChanged = InterpolatePhysicsState( current, previous, next, fraction );
  572. gameLocal.push.ClipPush( pushResults, self, pushFlags, oldOrigin, oldAxis, current.origin, current.axis );
  573. if ( clipModel ) {
  574. clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
  575. }
  576. return hasChanged;
  577. }
  578. /*
  579. ================
  580. idPhysics_Parametric::UpdateTime
  581. ================
  582. */
  583. void idPhysics_Parametric::UpdateTime( int endTimeMSec ) {
  584. int timeLeap = endTimeMSec - current.time;
  585. current.time = endTimeMSec;
  586. // move the trajectory start times to sync the trajectory with the current endTime
  587. current.linearExtrapolation.SetStartTime( current.linearExtrapolation.GetStartTime() + timeLeap );
  588. current.angularExtrapolation.SetStartTime( current.angularExtrapolation.GetStartTime() + timeLeap );
  589. current.linearInterpolation.SetStartTime( current.linearInterpolation.GetStartTime() + timeLeap );
  590. current.angularInterpolation.SetStartTime( current.angularInterpolation.GetStartTime() + timeLeap );
  591. if ( current.spline != NULL ) {
  592. current.spline->ShiftTime( timeLeap );
  593. current.splineInterpolate.SetStartTime( current.splineInterpolate.GetStartTime() + timeLeap );
  594. }
  595. }
  596. /*
  597. ================
  598. idPhysics_Parametric::GetTime
  599. ================
  600. */
  601. int idPhysics_Parametric::GetTime() const {
  602. return current.time;
  603. }
  604. /*
  605. ================
  606. idPhysics_Parametric::IsAtRest
  607. ================
  608. */
  609. bool idPhysics_Parametric::IsAtRest() const {
  610. return current.atRest >= 0;
  611. }
  612. /*
  613. ================
  614. idPhysics_Parametric::GetRestStartTime
  615. ================
  616. */
  617. int idPhysics_Parametric::GetRestStartTime() const {
  618. return current.atRest;
  619. }
  620. /*
  621. ================
  622. idPhysics_Parametric::IsPushable
  623. ================
  624. */
  625. bool idPhysics_Parametric::IsPushable() const {
  626. return false;
  627. }
  628. /*
  629. ================
  630. idPhysics_Parametric::SaveState
  631. ================
  632. */
  633. void idPhysics_Parametric::SaveState() {
  634. saved = current;
  635. }
  636. /*
  637. ================
  638. idPhysics_Parametric::RestoreState
  639. ================
  640. */
  641. void idPhysics_Parametric::RestoreState() {
  642. current = saved;
  643. if ( clipModel ) {
  644. clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
  645. }
  646. }
  647. /*
  648. ================
  649. idPhysics_Parametric::SetOrigin
  650. ================
  651. */
  652. void idPhysics_Parametric::SetOrigin( const idVec3 &newOrigin, int id ) {
  653. idVec3 masterOrigin;
  654. idMat3 masterAxis;
  655. current.linearExtrapolation.SetStartValue( newOrigin );
  656. current.linearInterpolation.SetStartValue( newOrigin );
  657. current.localOrigin = current.linearExtrapolation.GetCurrentValue( current.time );
  658. if ( hasMaster ) {
  659. self->GetMasterPosition( masterOrigin, masterAxis );
  660. current.origin = masterOrigin + current.localOrigin * masterAxis;
  661. }
  662. else {
  663. current.origin = current.localOrigin;
  664. }
  665. if ( clipModel ) {
  666. clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
  667. }
  668. Activate();
  669. }
  670. /*
  671. ================
  672. idPhysics_Parametric::SetAxis
  673. ================
  674. */
  675. void idPhysics_Parametric::SetAxis( const idMat3 &newAxis, int id ) {
  676. idVec3 masterOrigin;
  677. idMat3 masterAxis;
  678. current.localAngles = newAxis.ToAngles();
  679. current.angularExtrapolation.SetStartValue( current.localAngles );
  680. current.angularInterpolation.SetStartValue( current.localAngles );
  681. current.localAngles = current.angularExtrapolation.GetCurrentValue( current.time );
  682. if ( hasMaster && isOrientated ) {
  683. self->GetMasterPosition( masterOrigin, masterAxis );
  684. current.axis = current.localAngles.ToMat3() * masterAxis;
  685. current.angles = current.axis.ToAngles();
  686. }
  687. else {
  688. current.axis = current.localAngles.ToMat3();
  689. current.angles = current.localAngles;
  690. }
  691. if ( clipModel ) {
  692. clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
  693. }
  694. Activate();
  695. }
  696. /*
  697. ================
  698. idPhysics_Parametric::Move
  699. ================
  700. */
  701. void idPhysics_Parametric::Translate( const idVec3 &translation, int id ) {
  702. }
  703. /*
  704. ================
  705. idPhysics_Parametric::Rotate
  706. ================
  707. */
  708. void idPhysics_Parametric::Rotate( const idRotation &rotation, int id ) {
  709. }
  710. /*
  711. ================
  712. idPhysics_Parametric::GetOrigin
  713. ================
  714. */
  715. const idVec3 &idPhysics_Parametric::GetOrigin( int id ) const {
  716. return current.origin;
  717. }
  718. /*
  719. ================
  720. idPhysics_Parametric::GetAxis
  721. ================
  722. */
  723. const idMat3 &idPhysics_Parametric::GetAxis( int id ) const {
  724. return current.axis;
  725. }
  726. /*
  727. ================
  728. idPhysics_Parametric::GetAngles
  729. ================
  730. */
  731. void idPhysics_Parametric::GetAngles( idAngles &curAngles ) const {
  732. curAngles = current.angles;
  733. }
  734. /*
  735. ================
  736. idPhysics_Parametric::SetLinearVelocity
  737. ================
  738. */
  739. void idPhysics_Parametric::SetLinearVelocity( const idVec3 &newLinearVelocity, int id ) {
  740. SetLinearExtrapolation( extrapolation_t(EXTRAPOLATION_LINEAR|EXTRAPOLATION_NOSTOP), gameLocal.time, 0, current.origin, newLinearVelocity, vec3_origin );
  741. current.linearInterpolation.Init( 0, 0, 0, 0, vec3_zero, vec3_zero );
  742. Activate();
  743. }
  744. /*
  745. ================
  746. idPhysics_Parametric::SetAngularVelocity
  747. ================
  748. */
  749. void idPhysics_Parametric::SetAngularVelocity( const idVec3 &newAngularVelocity, int id ) {
  750. idRotation rotation;
  751. idVec3 vec;
  752. float angle;
  753. vec = newAngularVelocity;
  754. angle = vec.Normalize();
  755. rotation.Set( vec3_origin, vec, (float) RAD2DEG( angle ) );
  756. SetAngularExtrapolation( extrapolation_t(EXTRAPOLATION_LINEAR|EXTRAPOLATION_NOSTOP), gameLocal.time, 0, current.angles, rotation.ToAngles(), ang_zero );
  757. current.angularInterpolation.Init( 0, 0, 0, 0, ang_zero, ang_zero );
  758. Activate();
  759. }
  760. /*
  761. ================
  762. idPhysics_Parametric::GetLinearVelocity
  763. ================
  764. */
  765. const idVec3 &idPhysics_Parametric::GetLinearVelocity( int id ) const {
  766. static idVec3 curLinearVelocity;
  767. curLinearVelocity = current.linearExtrapolation.GetCurrentSpeed( gameLocal.time );
  768. return curLinearVelocity;
  769. }
  770. /*
  771. ================
  772. idPhysics_Parametric::GetAngularVelocity
  773. ================
  774. */
  775. const idVec3 &idPhysics_Parametric::GetAngularVelocity( int id ) const {
  776. static idVec3 curAngularVelocity;
  777. idAngles angles;
  778. angles = current.angularExtrapolation.GetCurrentSpeed( gameLocal.time );
  779. curAngularVelocity = angles.ToAngularVelocity();
  780. return curAngularVelocity;
  781. }
  782. /*
  783. ================
  784. idPhysics_Parametric::DisableClip
  785. ================
  786. */
  787. void idPhysics_Parametric::DisableClip() {
  788. if ( clipModel ) {
  789. clipModel->Disable();
  790. }
  791. }
  792. /*
  793. ================
  794. idPhysics_Parametric::EnableClip
  795. ================
  796. */
  797. void idPhysics_Parametric::EnableClip() {
  798. if ( clipModel ) {
  799. clipModel->Enable();
  800. }
  801. }
  802. /*
  803. ================
  804. idPhysics_Parametric::UnlinkClip
  805. ================
  806. */
  807. void idPhysics_Parametric::UnlinkClip() {
  808. if ( clipModel ) {
  809. clipModel->Unlink();
  810. }
  811. }
  812. /*
  813. ================
  814. idPhysics_Parametric::LinkClip
  815. ================
  816. */
  817. void idPhysics_Parametric::LinkClip() {
  818. if ( clipModel ) {
  819. clipModel->Link( gameLocal.clip, self, 0, current.origin, current.axis );
  820. }
  821. }
  822. /*
  823. ================
  824. idPhysics_Parametric::GetBlockingInfo
  825. ================
  826. */
  827. const trace_t *idPhysics_Parametric::GetBlockingInfo() const {
  828. return ( isBlocked ? &pushResults : NULL );
  829. }
  830. /*
  831. ================
  832. idPhysics_Parametric::GetBlockingEntity
  833. ================
  834. */
  835. idEntity *idPhysics_Parametric::GetBlockingEntity() const {
  836. if ( isBlocked ) {
  837. return gameLocal.entities[ pushResults.c.entityNum ];
  838. }
  839. return NULL;
  840. }
  841. /*
  842. ================
  843. idPhysics_Parametric::SetMaster
  844. ================
  845. */
  846. void idPhysics_Parametric::SetMaster( idEntity *master, const bool orientated ) {
  847. idVec3 masterOrigin;
  848. idMat3 masterAxis;
  849. if ( master ) {
  850. if ( !hasMaster ) {
  851. // transform from world space to master space
  852. self->GetMasterPosition( masterOrigin, masterAxis );
  853. current.localOrigin = ( current.origin - masterOrigin ) * masterAxis.Transpose();
  854. if ( orientated ) {
  855. current.localAngles = ( current.axis * masterAxis.Transpose() ).ToAngles();
  856. }
  857. else {
  858. current.localAngles = current.axis.ToAngles();
  859. }
  860. current.linearExtrapolation.SetStartValue( current.localOrigin );
  861. current.angularExtrapolation.SetStartValue( current.localAngles );
  862. hasMaster = true;
  863. isOrientated = orientated;
  864. }
  865. }
  866. else {
  867. if ( hasMaster ) {
  868. // transform from master space to world space
  869. current.localOrigin = current.origin;
  870. current.localAngles = current.angles;
  871. SetLinearExtrapolation( EXTRAPOLATION_NONE, 0, 0, current.origin, vec3_origin, vec3_origin );
  872. SetAngularExtrapolation( EXTRAPOLATION_NONE, 0, 0, current.angles, ang_zero, ang_zero );
  873. hasMaster = false;
  874. }
  875. }
  876. }
  877. /*
  878. ================
  879. idPhysics_Parametric::GetLinearEndTime
  880. ================
  881. */
  882. int idPhysics_Parametric::GetLinearEndTime() const {
  883. if ( current.spline != NULL ) {
  884. if ( current.spline->GetBoundaryType() != idCurve_Spline<idVec3>::BT_CLOSED ) {
  885. return current.spline->GetTime( current.spline->GetNumValues() - 1 );
  886. } else {
  887. return 0;
  888. }
  889. } else if ( current.linearInterpolation.GetDuration() != 0 ) {
  890. return current.linearInterpolation.GetEndTime();
  891. } else {
  892. return current.linearExtrapolation.GetEndTime();
  893. }
  894. }
  895. /*
  896. ================
  897. idPhysics_Parametric::GetAngularEndTime
  898. ================
  899. */
  900. int idPhysics_Parametric::GetAngularEndTime() const {
  901. if ( current.angularInterpolation.GetDuration() != 0 ) {
  902. return current.angularInterpolation.GetEndTime();
  903. } else {
  904. return current.angularExtrapolation.GetEndTime();
  905. }
  906. }
  907. /*
  908. ================
  909. idPhysics_Parametric::WriteToSnapshot
  910. ================
  911. */
  912. void idPhysics_Parametric::WriteToSnapshot( idBitMsg &msg ) const {
  913. const idQuat currentQuat = current.axis.ToQuat();
  914. WriteFloatArray( msg, current.origin );
  915. WriteFloatArray( msg, currentQuat );
  916. }
  917. /*
  918. ================
  919. idPhysics_Parametric::ReadFromSnapshot
  920. ================
  921. */
  922. void idPhysics_Parametric::ReadFromSnapshot( const idBitMsg &msg ) {
  923. previous = next;
  924. next.origin = ReadFloatArray< idVec3 >( msg );
  925. next.axis = ReadFloatArray< idQuat >( msg );
  926. if( self->GetNumSnapshotsReceived() <= 1 ) {
  927. current.origin = next.origin;
  928. previous.origin = next.origin;
  929. current.axis = next.axis.ToMat3();
  930. previous.axis = next.axis;
  931. }
  932. }