player.h

Engine/source/T3D/player.h

More...

Classes:

Public Typedefs

PlayerPose 

Public Functions

Detailed Description

Public Typedefs

typedef Player::Pose PlayerPose 

Public Functions

DefineEnumType(PlayerPose )

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
 25// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
 26// Copyright (C) 2015 Faust Logic, Inc.
 27//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
 28
 29#ifndef _PLAYER_H_
 30#define _PLAYER_H_
 31
 32#ifndef _SHAPEBASE_H_
 33#include "T3D/shapeBase.h"
 34#endif
 35#ifndef _BOXCONVEX_H_
 36#include "collision/boxConvex.h"
 37#endif
 38
 39#include "T3D/gameBase/gameProcess.h"
 40
 41class Material;
 42class ParticleEmitter;
 43class ParticleEmitterData;
 44class DecalData;
 45class SplashData;
 46class PhysicsPlayer;
 47class Player;
 48
 49#ifdef TORQUE_OPENVR
 50class OpenVRTrackedObject;
 51#endif
 52
 53//----------------------------------------------------------------------------
 54
 55struct PlayerData: public ShapeBaseData {
 56   typedef ShapeBaseData Parent;
 57   enum Constants {
 58      RecoverDelayBits = 7,
 59      JumpDelayBits = 7,
 60      NumSpineNodes = 6,
 61      ImpactBits = 3,
 62      NUM_SPLASH_EMITTERS = 3,
 63      BUBBLE_EMITTER = 2,
 64   };
 65   bool renderFirstPerson;    ///< Render the player shape in first person
 66
 67   /// Render shadows while in first person when 
 68   /// renderFirstPerson is disabled.
 69   bool firstPersonShadows; 
 70
 71   StringTableEntry  imageAnimPrefix;                             ///< Passed along to mounted images to modify
 72                                                                  ///  animation sequences played in third person. [optional]
 73   bool              allowImageStateAnimation;                    ///< When true a new thread is added to the player to allow for
 74                                                                  ///  mounted images to request a sequence be played on the player
 75                                                                  ///  through the image's state machine.  It is only optional so
 76                                                                  ///  that we don't create a TSThread on the player if we don't
 77                                                                  ///  need to.
 78
 79   StringTableEntry  shapeNameFP[ShapeBase::MaxMountedImages];    ///< Used to render with mounted images in first person [optional]
 80   StringTableEntry  imageAnimPrefixFP;                           ///< Passed along to mounted images to modify
 81                                                                  ///  animation sequences played in first person. [optional]
 82   Resource<TSShape> mShapeFP[ShapeBase::MaxMountedImages];       ///< First person mounted image shape resources [optional]
 83   U32               mCRCFP[ShapeBase::MaxMountedImages];         ///< Computed CRC values for the first person mounted image shapes
 84                                                                  ///  Depends on the ShapeBaseData computeCRC field.
 85   bool              mValidShapeFP[ShapeBase::MaxMountedImages];  ///< Indicates that there is a valid first person mounted image shape
 86
 87   F32 pickupRadius;          ///< Radius around player for items (on server)
 88   F32 maxTimeScale;          ///< Max timeScale for action animations
 89
 90   F32 minLookAngle;          ///< Lowest angle (radians) the player can look
 91   F32 maxLookAngle;          ///< Highest angle (radians) the player can look
 92   F32 maxFreelookAngle;      ///< Max left/right angle the player can look
 93
 94   /// @name Physics constants
 95   /// @{
 96
 97   F32 maxStepHeight;         ///< Maximum height the player can step up
 98   F32 runSurfaceAngle;       ///< Maximum angle from vertical in degrees the player can run up
 99
100   F32 horizMaxSpeed;         ///< Max speed attainable in the horizontal
101   F32 horizResistSpeed;      ///< Speed at which resistance will take place
102   F32 horizResistFactor;     ///< Factor of resistance once horizResistSpeed has been reached
103
104   F32 upMaxSpeed;            ///< Max vertical speed attainable
105   F32 upResistSpeed;         ///< Speed at which resistance will take place
106   F32 upResistFactor;        ///< Factor of resistance once upResistSpeed has been reached
107
108   F32 fallingSpeedThreshold; ///< Downward speed at which we consider the player falling
109
110   S32 recoverDelay;          ///< # tick
111   F32 recoverRunForceScale;  ///< RunForce multiplier in recover state
112   F32 landSequenceTime;      ///< If greater than 0 then the legacy fall recovery system will be bypassed
113                              ///  in favour of just playing the player's land sequence.  The time to
114                              ///  recover from a fall then becomes this parameter's time and the land
115                              ///  sequence's playback will be scaled to match.
116   bool transitionToLand;     ///< When going from a fall to a land, should we transition between the two?
117
118   // Running/Walking
119   F32 runForce;              ///< Force used to accelerate player
120   F32 runEnergyDrain;        ///< Energy drain/tick
121   F32 minRunEnergy;          ///< Minimum energy required to run
122   F32 maxForwardSpeed;       ///< Maximum forward speed when running
123   F32 maxBackwardSpeed;      ///< Maximum backward speed when running
124   F32 maxSideSpeed;          ///< Maximum side speed when running
125
126   // Jumping
127   F32 jumpForce;             ///< Force exerted per jump
128   F32 jumpEnergyDrain;       ///< Energy drained per jump
129   F32 minJumpEnergy;         ///< Minimum energy required to jump
130   F32 minJumpSpeed;          ///< Minimum speed needed to jump
131   F32 maxJumpSpeed;          ///< Maximum speed before the player can no longer jump
132   F32 jumpSurfaceAngle;      ///< Angle from vertical in degrees where the player can jump
133   S32 jumpDelay;             ///< Delay time in ticks between jumps
134
135   // Sprinting
136   F32 sprintForce;                 ///< Force used to accelerate player
137   F32 sprintEnergyDrain;           ///< Energy drain/tick
138   F32 minSprintEnergy;             ///< Minimum energy required to sprint
139   F32 maxSprintForwardSpeed;       ///< Maximum forward speed when sprinting
140   F32 maxSprintBackwardSpeed;      ///< Maximum backward speed when sprinting
141   F32 maxSprintSideSpeed;          ///< Maximum side speed when sprinting
142   F32 sprintStrafeScale;           ///< Amount to scale strafing motion vector while sprinting
143   F32 sprintYawScale;              ///< Amount to scale yaw motion while sprinting
144   F32 sprintPitchScale;            ///< Amount to scale pitch motion while sprinting
145   bool sprintCanJump;              ///< Can the player jump while sprinting
146
147   // Swimming
148   F32 swimForce;                   ///< Force used to accelerate player while swimming
149   F32 maxUnderwaterForwardSpeed;   ///< Maximum underwater forward speed when running
150   F32 maxUnderwaterBackwardSpeed;  ///< Maximum underwater backward speed when running
151   F32 maxUnderwaterSideSpeed;      ///< Maximum underwater side speed when running
152
153   // Crouching
154   F32 crouchForce;                 ///< Force used to accelerate player while crouching
155   F32 maxCrouchForwardSpeed;       ///< Maximum forward speed when crouching
156   F32 maxCrouchBackwardSpeed;      ///< Maximum backward speed when crouching
157   F32 maxCrouchSideSpeed;          ///< Maximum side speed when crouching
158
159   // Prone
160   F32 proneForce;                  ///< Force used to accelerate player while prone
161   F32 maxProneForwardSpeed;        ///< Maximum forward speed when prone
162   F32 maxProneBackwardSpeed;       ///< Maximum backward speed when prone
163   F32 maxProneSideSpeed;           ///< Maximum side speed when prone
164
165   // Jetting
166   F32 jetJumpForce;
167   F32 jetJumpEnergyDrain;    ///< Energy per jump
168   F32 jetMinJumpEnergy;
169   F32 jetMinJumpSpeed;
170   F32 jetMaxJumpSpeed;
171   F32 jetJumpSurfaceAngle;   ///< Angle vertical degrees
172   /// @}
173
174   /// @name Hitboxes
175   /// @{
176
177   F32 boxHeadPercentage;
178   F32 boxTorsoPercentage;
179
180   F32 boxHeadLeftPercentage;
181   F32 boxHeadRightPercentage;
182   F32 boxHeadBackPercentage;
183   F32 boxHeadFrontPercentage;
184   /// @}
185
186   F32 minImpactSpeed;        ///< Minimum impact speed required to apply fall damage
187   F32 minLateralImpactSpeed; ///< Minimum impact speed required to apply non-falling damage.
188
189   F32 decalOffset;
190
191   F32 groundImpactMinSpeed;      ///< Minimum impact speed required to apply fall damage with the ground
192   VectorF groundImpactShakeFreq; ///< Frequency in each direction for the camera to shake
193   VectorF groundImpactShakeAmp;  ///< How much to shake
194   F32 groundImpactShakeDuration; ///< How long to shake
195   F32 groundImpactShakeFalloff;  ///< How fast the shake disapates
196
197   /// Zounds!
198   enum Sounds {
199      FootSoft,
200      FootHard,
201      FootMetal,
202      FootSnow,
203      MaxSoundOffsets,
204      FootShallowSplash,
205      FootWading,
206      FootUnderWater,
207      FootBubbles,
208      MoveBubbles,
209      WaterBreath,
210      ImpactStart,
211      ImpactSoft = ImpactStart,
212      ImpactHard,
213      ImpactMetal,
214      ImpactSnow,
215      ImpactWaterEasy,
216      ImpactWaterMedium,
217      ImpactWaterHard,
218      ExitWater,
219      MaxSounds
220   };
221   SFXTrack* sound[MaxSounds];
222
223   Point3F boxSize;           ///< Width, depth, height
224   Point3F crouchBoxSize;
225   Point3F proneBoxSize;
226   Point3F swimBoxSize;
227
228   /// Animation and other data initialized in onAdd
229   struct ActionAnimationDef {
230      const char* name;       ///< Sequence name
231      struct Vector {
232         F32 x,y,z;
233      } dir;                  ///< Default direction
234   };
235   struct ActionAnimation {
236      const char* name;       ///< Sequence name
237      S32      sequence;      ///< Sequence index
238      VectorF  dir;           ///< Dir of animation ground transform
239      F32      speed;         ///< Speed in m/s
240      bool     velocityScale; ///< Scale animation by velocity
241      bool     death;         ///< Are we dying?
242   };
243   enum {
244      // *** WARNING ***
245      // These enum values are used to index the ActionAnimationList
246      // array instantiated in player.cc
247      // The first several are selected in the move state based on velocity
248      RootAnim,
249      RunForwardAnim,
250      BackBackwardAnim,
251      SideLeftAnim,
252      SideRightAnim,
253
254      SprintRootAnim,
255      SprintForwardAnim,
256      SprintBackwardAnim,
257      SprintLeftAnim,
258      SprintRightAnim,
259
260      CrouchRootAnim,
261      CrouchForwardAnim,
262      CrouchBackwardAnim,
263      CrouchLeftAnim,
264      CrouchRightAnim,
265
266      ProneRootAnim,
267      ProneForwardAnim,
268      ProneBackwardAnim,
269
270      SwimRootAnim,
271      SwimForwardAnim,
272      SwimBackwardAnim,
273      SwimLeftAnim,
274      SwimRightAnim,
275
276      // These are set explicitly based on player actions
277      FallAnim,
278      JumpAnim,
279      StandJumpAnim,
280      LandAnim,
281      JetAnim,
282
283      // 
284      NumTableActionAnims = JetAnim + 1,
285
286      NumExtraActionAnims = 512 - NumTableActionAnims,
287      NumActionAnims = NumTableActionAnims + NumExtraActionAnims,
288      ActionAnimBits = 9,
289      NullAnimation = (1 << ActionAnimBits) - 1
290   };
291
292   static ActionAnimationDef ActionAnimationList[NumTableActionAnims];
293   ActionAnimation actionList[NumActionAnims];
294   U32 actionCount;
295   U32 lookAction;
296   S32 spineNode[NumSpineNodes];
297   S32 pickupDelta;           ///< Base off of pcikupRadius
298   F32 runSurfaceCos;         ///< Angle from vertical in cos(runSurfaceAngle)
299   F32 jumpSurfaceCos;        ///< Angle from vertical in cos(jumpSurfaceAngle)
300
301   enum Impacts {
302      ImpactNone,
303      ImpactNormal,
304   };
305
306   enum Recoil {
307      LightRecoil,
308      MediumRecoil,
309      HeavyRecoil,
310      NumRecoilSequences
311   };
312   S32 recoilSequence[NumRecoilSequences];
313
314   /// @name Particles
315   /// All of the data relating to environmental effects
316   /// @{
317
318   ParticleEmitterData * footPuffEmitter;
319   S32 footPuffID;
320   S32 footPuffNumParts;
321   F32 footPuffRadius;
322
323   DecalData* decalData;
324   S32 decalID;
325
326   ParticleEmitterData * dustEmitter;
327   S32 dustID;
328
329   SplashData* splash;
330   S32 splashId;
331   F32 splashVelocity;
332   F32 splashAngle;
333   F32 splashFreqMod;
334   F32 splashVelEpsilon;
335   F32 bubbleEmitTime;
336
337   F32 medSplashSoundVel;
338   F32 hardSplashSoundVel;
339   F32 exitSplashSoundVel;
340   F32 footSplashHeight;
341
342   // Air control
343   F32 airControl;
344
345   // Jump off surfaces at their normal rather than straight up
346   bool jumpTowardsNormal;
347
348   // For use if/when mPhysicsPlayer is created
349   StringTableEntry physicsPlayerType;
350
351   ParticleEmitterData* splashEmitterList[NUM_SPLASH_EMITTERS];
352   S32 splashEmitterIDList[NUM_SPLASH_EMITTERS];
353   /// @}
354
355   //
356   DECLARE_CONOBJECT(PlayerData);
357   PlayerData();
358   bool preload(bool server, String &errorStr);
359   void getGroundInfo(TSShapeInstance*,TSThread*,ActionAnimation*);
360   bool isTableSequence(S32 seq);
361   bool isJumpAction(U32 action);
362
363   static void initPersistFields();
364   virtual void packData(BitStream* stream);
365   virtual void unpackData(BitStream* stream);
366
367   /// @name Callbacks
368   /// @{
369   DECLARE_CALLBACK( void, onPoseChange, ( Player* obj, const char* oldPose, const char* newPose ) );
370   DECLARE_CALLBACK( void, onStartSwim, ( Player* obj ) );
371   DECLARE_CALLBACK( void, onStopSwim, ( Player* obj ) );
372   DECLARE_CALLBACK( void, onStartSprintMotion, ( Player* obj ) );
373   DECLARE_CALLBACK( void, onStopSprintMotion, ( Player* obj ) );
374   DECLARE_CALLBACK( void, doDismount, ( Player* obj ) );
375   DECLARE_CALLBACK( void, onEnterLiquid, ( Player* obj, F32 coverage, const char* type ) );
376   DECLARE_CALLBACK( void, onLeaveLiquid, ( Player* obj, const char* type ) );
377   DECLARE_CALLBACK( void, animationDone, ( Player* obj ) );
378   DECLARE_CALLBACK( void, onEnterMissionArea, ( Player* obj ) );
379   DECLARE_CALLBACK( void, onLeaveMissionArea, ( Player* obj ) );
380   /// @}
381};
382
383
384//----------------------------------------------------------------------------
385
386class Player: public ShapeBase
387{
388   typedef ShapeBase Parent;
389
390public:
391   enum Pose {
392      StandPose = 0,
393      SprintPose,
394      CrouchPose,
395      PronePose,
396      SwimPose,
397      NumPoseBits = 3
398   };
399
400   /// The ExtendedMove position/rotation index used for head movements
401   static S32 smExtendedMoveHeadPosRotIndex;
402
403protected:
404
405   /// Bit masks for different types of events
406   enum MaskBits {
407      ActionMask   = Parent::NextFreeMask << 0,
408      MoveMask     = Parent::NextFreeMask << 1,
409      ImpactMask   = Parent::NextFreeMask << 2,
410      TriggerMask      = Parent::NextFreeMask << 3,
411      NextFreeMask     = Parent::NextFreeMask << 4
412   };
413
414   SimObjectPtr<ParticleEmitter> mSplashEmitter[PlayerData::NUM_SPLASH_EMITTERS];
415   F32 mBubbleEmitterTime;
416
417   /// Client interpolation/warp data
418   struct StateDelta {
419      Move move;                    ///< Last move from server
420      F32 dt;                       ///< Last interpolation time
421      /// @name Interpolation data
422     /// @{
423
424      Point3F pos;
425      Point3F rot;
426      Point3F head;
427      VectorF posVec;
428      VectorF rotVec;
429      VectorF headVec;
430     /// @}
431
432     /// @name Warp data
433     /// @{
434
435      S32 warpTicks;
436      Point3F warpOffset;
437      Point3F rotOffset;
438     /// @}
439   };
440   StateDelta mDelta;                ///< Used for interpolation on the client.  @see StateDelta
441   S32 mPredictionCount;            ///< Number of ticks to predict
442
443   // Current pos, vel etc.
444   Point3F mHead;                   ///< Head rotation, uses only x & z
445   Point3F mRot;                    ///< Body rotation, uses only z
446   VectorF mVelocity;               ///< Velocity
447   Point3F mAnchorPoint;            ///< Pos compression anchor
448   S32 mImpactSound;
449
450   bool mUseHeadZCalc;              ///< Including mHead.z in transform calculations
451
452   F32 mLastAbsoluteYaw;            ///< Stores that last absolute yaw value as passed in by ExtendedMove
453   F32 mLastAbsolutePitch;          ///< Stores that last absolute pitch value as passed in by ExtendedMove
454   F32 mLastAbsoluteRoll;           ///< Stores that last absolute roll value as passed in by ExtendedMove
455
456   S32 mMountPending;               ///< mMountPending suppresses tickDelay countdown so players will sit until
457                                    ///< their mount, or another animation, comes through (or 13 seconds elapses).
458
459   /// Main player state
460   enum ActionState {
461      NullState,
462      MoveState,
463      RecoverState,
464      NumStateBits = 3
465   };
466   ActionState mState;              ///< What is the player doing? @see ActionState
467   bool mFalling;                   ///< Falling in mid-air?
468   S32 mJumpDelay;                  ///< Delay till next jump   
469   
470   Pose  mPose;
471   bool  mAllowJumping;
472   bool  mAllowJetJumping;
473   bool  mAllowSprinting;
474   bool  mAllowCrouching;
475   bool  mAllowProne;
476   bool  mAllowSwimming;
477   
478   S32 mContactTimer;               ///< Ticks since last contact
479
480   Point3F mJumpSurfaceNormal;      ///< Normal of the surface the player last jumped on
481   U32 mJumpSurfaceLastContact;     ///< How long it's been since the player landed (ticks)
482   F32  mWeaponBackFraction;        ///< Amount to slide the weapon back (if it's up against something)
483
484   SFXSource* mMoveBubbleSound;   ///< Sound for moving bubbles
485   SFXSource* mWaterBreathSound;  ///< Sound for underwater breath
486
487   SimObjectPtr<ShapeBase> mControlObject; ///< Controlling object
488
489   /// @name Animation threads & data
490   /// @{
491
492   struct ActionAnimation {
493      S32 action;
494      TSThread* thread;
495      S32 delayTicks;               // before picking another.
496      bool forward;
497      bool firstPerson;
498      bool waitForEnd;
499      bool holdAtEnd;
500      bool animateOnServer;
501      bool atEnd;
502   } mActionAnimation;
503
504   struct ArmAnimation {
505      U32 action;
506      TSThread* thread;
507   } mArmAnimation;
508   TSThread* mArmThread;
509
510   TSThread* mHeadVThread;
511   TSThread* mHeadHThread;
512   TSThread* mRecoilThread;
513   TSThread* mImageStateThread;
514   /// @}
515
516   bool mInMissionArea;       ///< Are we in the mission area?
517   //
518   S32 mRecoverTicks;         ///< same as recoverTicks in the player datablock
519   U32 mReversePending;
520   F32 mRecoverDelay;         ///< When bypassing the legacy recover system and only using the land sequence,
521                              ///  this is how long the player will be in the land sequence.
522
523   bool mInWater;            ///< Is true if WaterCoverage is greater than zero
524   bool mSwimming;            ///< Is true if WaterCoverage is above the swimming threshold
525   //
526   PlayerData* mDataBlock;    ///< MMmmmmm...datablock...
527
528   Point3F mLastPos;          ///< Holds the last position for physics updates
529   Point3F mLastWaterPos;     ///< Same as mLastPos, but for water
530
531#ifdef TORQUE_OPENVR
532   SimObjectPtr<OpenVRTrackedObject> mControllers[2];
533#endif
534
535   struct ContactInfo 
536   {
537      bool contacted, jump, run;
538      SceneObject *contactObject;
539      VectorF  contactNormal;
540
541      void clear()
542      {
543         contacted=<a href="/coding/class/structplayer_1_1contactinfo/#structplayer_1_1contactinfo_1ab93456a3bd9f64080afed2c164e0fd4a">jump</a>=<a href="/coding/class/structplayer_1_1contactinfo/#structplayer_1_1contactinfo_1a9f358023586e2989549d20c72ee0bd64">run</a>=false; 
544         contactObject = NULL; 
545         contactNormal.set(1,1,1);
546      }
547
548      ContactInfo() { clear(); }
549
550   } mContactInfo;
551
552   struct Death {
553      F32      lastPos;
554      Point3F  posAdd;
555      VectorF  rotate;
556      VectorF  curNormal;
557      F32      curSink;
558      void     clear()           {dMemset(this, 0, sizeof(*this)); initFall();}
559      VectorF  getPosAdd()       {VectorF ret(posAdd); posAdd.set(0,0,0); return ret;}
560      bool     haveVelocity()    {return posAdd.x != 0 || posAdd.y != 0;}
561      void     initFall()        {curNormal.set(0,0,1); curSink = 0;}
562      Death()                    {clear();}
563      MatrixF* fallToGround(F32 adjust, const Point3F& pos, F32 zrot, F32 boxRad);
564   } mDeath;
565
566   PhysicsPlayer *mPhysicsRep;
567
568   // First person mounted image shapes
569   TSShapeInstance*  mShapeFPInstance[ShapeBase::MaxMountedImages];
570   TSThread *mShapeFPAmbientThread[ShapeBase::MaxMountedImages];
571   TSThread *mShapeFPVisThread[ShapeBase::MaxMountedImages];
572   TSThread *mShapeFPAnimThread[ShapeBase::MaxMountedImages];
573   TSThread *mShapeFPFlashThread[ShapeBase::MaxMountedImages];
574   TSThread *mShapeFPSpinThread[ShapeBase::MaxMountedImages];
575
576   
577  public:
578  
579   // New collision
580   OrthoBoxConvex mConvex;
581   Box3F          mWorkingQueryBox;
582
583   /// Standing / Crouched / Prone or Swimming   
584   Pose getPose() const { return mPose; }
585   virtual const char* getPoseName() const;
586   
587   /// Setting this from script directly might not actually work,
588   /// This is really just a helper for the player class so that its bounding box
589   /// will get resized appropriately when the pose changes
590   void setPose( Pose pose );
591
592   PhysicsPlayer* getPhysicsRep() const { return mPhysicsRep; }
593
594#ifdef TORQUE_OPENVR
595   void setControllers(Vector<OpenVRTrackedObject*> controllerList);
596#endif
597
598  protected:
599   virtual void reSkin();
600
601   void setState(ActionState state, U32 ticks=0);
602   void updateState();
603
604
605   // Jetting
606   bool mJetting;
607
608   ///Update the movement
609   virtual void updateMove(const Move *move);
610
611   ///Interpolate movement
612   Point3F _move( const F32 travelTime, Collision *outCol );
613   F32 _doCollisionImpact( const Collision *collision, bool fallingCollision);
614   void _handleCollision( const Collision &collision );
615   virtual bool updatePos(const F32 travelTime = TickSec);
616
617   // PATHSHAPE
618   void updateAttachment();
619   // PATHSHAPE END
620   ///Update head animation
621   void updateLookAnimation(F32 dT = 0.f);
622
623   ///Update other animations
624   void updateAnimation(F32 dt);
625   void updateAnimationTree(bool firstPerson);
626   bool step(Point3F *pos,F32 *maxStep,F32 time);
627
628   ///See if the player is still in the mission area
629   void checkMissionArea();
630
631   virtual U32 getArmAction() const { return mArmAnimation.action; }
632   virtual bool setArmThread(U32 action);
633   virtual void setActionThread(U32 action,bool forward,bool hold = false,bool wait = false,bool fsp = false, bool forceSet = false);
634   virtual void updateActionThread();
635   virtual void pickBestMoveAction(U32 startAnim, U32 endAnim, U32 * action, bool * forward) const;
636   virtual void pickActionAnimation();
637
638   /// @name Mounted objects
639   /// @{
640   virtual void onUnmount( SceneObject *obj, S32 node );
641   virtual void unmount();
642   /// @}
643
644   void setPosition(const Point3F& pos,const Point3F& viewRot);
645   void setRenderPosition(const Point3F& pos,const Point3F& viewRot,F32 dt=-1);
646   void _findContact( SceneObject **contactObject, VectorF *contactNormal, Vector<SceneObject*> *outOverlapObjects );
647   void findContact( bool *run, bool *jump, VectorF *contactNormal );
648
649   void buildImagePrefixPaths(String* prefixPaths);
650   S32 findPrefixSequence(String* prefixPaths, const String& baseSeq);
651   S32 convertActionToImagePrefix(U32 action);
652
653   virtual void onImage(U32 imageSlot, bool unmount);
654   virtual void onImageRecoil(U32 imageSlot,ShapeBaseImageData::StateData::RecoilState);
655   virtual void onImageStateAnimation(U32 imageSlot, const char* seqName, bool direction, bool scaleToState, F32 stateTimeOutValue);
656   virtual const char* getImageAnimPrefix(U32 imageSlot, S32 imageShapeIndex);
657   virtual void onImageAnimThreadChange(U32 imageSlot, S32 imageShapeIndex, ShapeBaseImageData::StateData* lastState, const char* anim, F32 pos, F32 timeScale, bool reset=false);
658   virtual void onImageAnimThreadUpdate(U32 imageSlot, S32 imageShapeIndex, F32 dt);
659
660   virtual void updateDamageLevel();
661   virtual void updateDamageState();
662   /// Set which client is controlling this player
663   void setControllingClient(GameConnection* client);
664
665   void calcClassRenderData();
666   
667   /// Play sound for foot contact.
668   ///
669   /// @param triggeredLeft If true, left foot hit; right otherwise.
670   /// @param contactMaterial Material onto which the player stepped; may be NULL.
671   /// @param contactObject Object onto which the player stepped; may be NULL.
672   void playFootstepSound( bool triggeredLeft, Material* contactMaterial, SceneObject* contactObject );
673   
674   /// Play an impact sound.
675   void playImpactSound();
676
677   /// Are we in the process of dying?
678   bool inDeathAnim();
679   F32  deathDelta(Point3F &delta);
680   void updateDeathOffsets();
681   bool inSittingAnim();
682
683   /// @name Water
684   /// @{
685
686   void updateSplash();                             ///< Update the splash effect
687   void updateFroth( F32 dt );                      ///< Update any froth
688   void updateWaterSounds( F32 dt );                ///< Update water sounds
689   void createSplash( Point3F &pos, F32 speed );    ///< Creates a splash
690   bool collidingWithWater( Point3F &waterHeight ); ///< Are we colliding with water?
691   /// @}
692
693   void disableHeadZCalc() { mUseHeadZCalc = false; }
694   void enableHeadZCalc() { mUseHeadZCalc = true; }
695
696public:
697   DECLARE_CONOBJECT(Player);
698
699   Player();
700   ~Player();
701   static void consoleInit();
702
703   /// @name Transforms
704   /// @{
705
706   void setTransform(const MatrixF &mat);
707   void getEyeTransform(MatrixF* mat);
708   void getEyeBaseTransform(MatrixF* mat, bool includeBank);
709   void getRenderEyeTransform(MatrixF* mat);
710   void getRenderEyeBaseTransform(MatrixF* mat, bool includeBank);
711   void getCameraParameters(F32 *min, F32 *max, Point3F *offset, MatrixF *rot);
712   void getMuzzleTransform(U32 imageSlot,MatrixF* mat);
713   void getRenderMuzzleTransform(U32 imageSlot,MatrixF* mat);   
714
715   virtual void getMuzzleVector(U32 imageSlot,VectorF* vec);
716   /// @}
717
718   F32 getSpeed() const;
719   Point3F getVelocity() const;
720   void setVelocity(const VectorF& vel);
721   /// Apply an impulse at the given point, with magnitude/direction of vec
722   void applyImpulse(const Point3F& pos,const VectorF& vec);
723   /// Get the rotation of the player
724   const Point3F& getRotation() { return mRot; }
725   /// Get the rotation of the head of the player
726   const Point3F& getHeadRotation() { return mHead; }
727   void getDamageLocation(const Point3F& in_rPos, const char *&out_rpVert, const char *&out_rpQuad);
728
729   void allowAllPoses();
730   void allowJumping(bool state) { mAllowJumping = state; }
731   void allowJetJumping(bool state) { mAllowJetJumping = state; }
732   void allowSprinting(bool state) { mAllowSprinting = state; }
733   void allowCrouching(bool state) { mAllowCrouching = state; }
734   void allowProne(bool state) { mAllowProne = state; }
735   void allowSwimming(bool state) { mAllowSwimming = state; }
736
737   bool canJump();                                         ///< Can the player jump?
738   bool canJetJump();                                      ///< Can the player jet?
739   bool canSwim();                                         ///< Can the player swim?
740   bool canCrouch();
741   bool canStand();
742   bool canProne();
743   bool canSprint();
744   bool haveContact() const { return !mContactTimer; }         ///< Is it in contact with something
745   void getMuzzlePointAI( U32 imageSlot, Point3F *point );
746   F32 getMaxForwardVelocity() const { return (mDataBlock != NULL ? mDataBlock->maxForwardSpeed : 0); }
747
748   virtual bool    isDisplacable() const;
749   virtual Point3F getMomentum() const;
750   virtual void    setMomentum(const Point3F &momentum);
751   virtual bool    displaceObject(const Point3F& displaceVector);
752   virtual bool    getAIMove(Move*);
753
754   bool checkDismountPosition(const MatrixF& oldPos, const MatrixF& newPos);  ///< Is it safe to dismount here?
755
756   //
757   bool onAdd();
758   void onRemove();
759   bool onNewDataBlock( GameBaseData *dptr, bool reload );
760   void onScaleChanged();
761   Box3F mScaledBox;
762
763   // Animation
764   const char* getStateName();
765   bool setActionThread(const char* sequence,bool hold,bool wait,bool fsp = false);
766   const String& getArmThread() const;
767   bool setArmThread(const char* sequence);
768
769   // Object control
770   void setControlObject(ShapeBase *obj);
771   ShapeBase* getControlObject();
772   
773   //
774   void updateWorkingCollisionSet();
775   virtual void processTick(const Move *move);
776   void interpolateTick(F32 delta);
777   void advanceTime(F32 dt);
778   bool castRay(const Point3F &start, const Point3F &end, RayInfo* info);
779   bool buildPolyList(PolyListContext context, AbstractPolyList* polyList, const Box3F &box, const SphereF &sphere);
780   void buildConvex(const Box3F& box, Convex* convex);
781   bool isControlObject();
782
783   void onCameraScopeQuery(NetConnection *cr, CameraScopeQuery *);
784   void writePacketData(GameConnection *conn, BitStream *stream);
785   void readPacketData (GameConnection *conn, BitStream *stream);
786   U32  packUpdate  (NetConnection *conn, U32 mask, BitStream *stream);
787   void unpackUpdate(NetConnection *conn,           BitStream *stream);
788
789   virtual void prepRenderImage( SceneRenderState* state );
790   virtual void renderConvex( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat );   
791   virtual void renderMountedImage( U32 imageSlot, TSRenderState &rstate, SceneRenderState *state );
792private:
793   static void  afx_consoleInit();
794   void         afx_init();
795   U32          afx_packUpdate(NetConnection*, U32 mask, BitStream*, U32 retMask);
796   void         afx_unpackUpdate(NetConnection*, BitStream*);
797private:
798   static bool  sCorpsesHiddenFromRayCast;
799   
800public:
801   virtual void restoreAnimation(U32 tag);
802   virtual U32 getAnimationID(const char* name);
803   virtual U32 playAnimationByID(U32 anim_id, F32 pos, F32 rate, F32 trans, bool hold, bool wait, bool is_death_anim);
804   virtual F32 getAnimationDurationByID(U32 anim_id);
805   virtual bool isBlendAnimation(const char* name);
806   virtual const char* getLastClipName(U32 clip_tag);
807   virtual void unlockAnimation(U32 tag, bool force=false);
808   virtual U32 lockAnimation();
809   virtual bool isAnimationLocked() const { return ((anim_clip_flags & BLOCK_USER_CONTROL) != 0); }
810   
811protected:
812   bool         overrideLookAnimation;
813   F32          armLookOverridePos;
814   F32          headVLookOverridePos;
815   F32          headHLookOverridePos;
816public:
817   void         setLookAnimationOverride(bool flag);
818   void         copyHeadRotation(const Player* p) { mHead = p->mHead; }
819public:
820   bool ignore_updates;
821   void resetContactTimer() { mContactTimer = 0; }
822private:
823   U8     move_trigger_states;
824   U32    fx_s_triggers;
825   U32    mark_fx_c_triggers;
826   U32    fx_c_triggers;
827   F32    z_velocity;
828   bool   mark_idle;
829   F32    idle_timer;
830   bool   mark_s_landing;
831   void   process_client_triggers(bool triggeredLeft, bool triggeredRight);
832public:
833   enum {
834     // server events
835     PLAYER_MOVE_TRIGGER_0        = BIT(0),
836     PLAYER_MOVE_TRIGGER_1        = BIT(1),
837     PLAYER_MOVE_TRIGGER_2        = BIT(2),
838     PLAYER_MOVE_TRIGGER_3        = BIT(3),
839     PLAYER_MOVE_TRIGGER_4        = BIT(4),
840     PLAYER_MOVE_TRIGGER_5        = BIT(5),
841     PLAYER_LANDING_S_TRIGGER     = BIT(6),
842
843     PLAYER_FIRE_S_TRIGGER        = PLAYER_MOVE_TRIGGER_0,
844     PLAYER_FIRE_ALT_S_TRIGGER    = PLAYER_MOVE_TRIGGER_1,
845     PLAYER_JUMP_S_TRIGGER        = BIT(7),
846
847     // client events
848     PLAYER_LF_FOOT_C_TRIGGER       = BIT(16),
849     PLAYER_RT_FOOT_C_TRIGGER       = BIT(17),
850     PLAYER_LANDING_C_TRIGGER       = BIT(18),
851     PLAYER_IDLE_C_TRIGGER          = BIT(19),
852   };
853   U32  getClientEventTriggers() const { return fx_c_triggers; }
854   U32  getServerEventTriggers() const { return fx_s_triggers; }
855private:
856   F32      speed_bias;
857   F32      speed_bias_goal;
858   bool     override_movement;
859   Point3F  movement_data;
860   U8       movement_op;
861   U32      last_movement_tag;
862   static U32   unique_movement_tag_counter;
863public:
864   void     setMovementSpeedBias(F32 bias);
865   U32      setMovementOverride(F32 bias, const Point3F* mov=0, U32 op=1);
866   void     restoreMovement(U32 tag);
867private:
868   S32      footfallDecalOverride;
869   S32      footfallSoundOverride;
870   S32      footfallDustOverride;
871   bool     noFootfallFX;
872public:
873   void     overrideFootfallFX(bool decals=true, bool sounds=true, bool dust=true);
874   void     restoreFootfallFX(bool decals=true, bool sounds=true, bool dust=true);
875};
876
877typedef Player::Pose PlayerPose;
878
879DefineEnumType( PlayerPose );
880
881#endif
882