Overte C++ Documentation
CharacterController.h
1 //
2 // CharacterControllerInterface.h
3 // libraries/physics/src
4 //
5 // Created by Andrew Meadows 2015.10.21
6 // Copyright 2015 High Fidelity, Inc.
7 //
8 // Distributed under the Apache License, Version 2.0.
9 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
10 //
11 
12 #ifndef hifi_CharacterController_h
13 #define hifi_CharacterController_h
14 
15 #include <assert.h>
16 #include <stdint.h>
17 #include <atomic>
18 #include <btBulletDynamicsCommon.h>
19 #include <BulletDynamics/Character/btCharacterControllerInterface.h>
20 
21 #include <GLMHelpers.h>
22 #include <NumericalConstants.h>
23 
24 #include "AvatarConstants.h"
25 #include "BulletUtil.h"
26 #include "CharacterGhostObject.h"
27 #include "PhysicsEngine.h"
28 #include "PhysicsHelpers.h"
29 
30 const uint32_t PENDING_FLAG_ADD_TO_SIMULATION = 1U << 0;
31 const uint32_t PENDING_FLAG_REMOVE_FROM_SIMULATION = 1U << 1;
32 const uint32_t PENDING_FLAG_UPDATE_SHAPE = 1U << 2;
33 const uint32_t PENDING_FLAG_JUMP = 1U << 3;
34 const uint32_t PENDING_FLAG_UPDATE_COLLISION_MASK = 1U << 4;
35 const uint32_t PENDING_FLAG_RECOMPUTE_FLYING = 1U << 5;
36 const uint32_t PENDING_FLAG_ADD_DETAILED_TO_SIMULATION = 1U << 6;
37 const uint32_t PENDING_FLAG_REMOVE_DETAILED_FROM_SIMULATION = 1U << 7;
38 
39 const float DEFAULT_MIN_FLOOR_NORMAL_DOT_UP = cosf(PI / 3.0f);
40 
41 const uint32_t NUM_SUBSTEPS_FOR_STUCK_TRANSITION = 6; // physics substeps
42 const uint32_t NUM_SUBSTEPS_FOR_SAFE_LANDING_RETRY = NUM_SUBSTEPS_PER_SECOND / 2; // retry every half second
43 
44 class btRigidBody;
45 class btCollisionWorld;
46 class btDynamicsWorld;
47 
48 //#define DEBUG_STATE_CHANGE
49 
50 const btScalar MAX_CHARACTER_MOTOR_TIMESCALE = 60.0f; // one minute
51 const btScalar MIN_CHARACTER_MOTOR_TIMESCALE = 0.05f;
52 
53 class CharacterController : public btCharacterControllerInterface {
54 
55 public:
56  enum class FollowType : uint8_t {
57  Rotation,
58  Horizontal,
59  Vertical,
60  Count
61  };
62 
63  // Remaining follow time for each FollowType
64  typedef std::array<float, static_cast<size_t>(FollowType::Count)> FollowTimePerType;
65 
66  // Follow time value meaning that we should snap immediately to the target.
67  static constexpr float FOLLOW_TIME_IMMEDIATE_SNAP = FLT_MAX;
68 
69  CharacterController(const FollowTimePerType& followTimeRemainingPerType);
70  virtual ~CharacterController();
71  bool needsRemoval() const;
72  bool needsAddition() const;
73  virtual void addToWorld();
74  void removeFromWorld();
75  btCollisionObject* getCollisionObject() { return _rigidBody; }
76 
77  void setGravity(float gravity);
78  float getGravity();
79  void recomputeFlying();
80 
81  virtual void updateShapeIfNecessary() = 0;
82 
83  // overrides from btCharacterControllerInterface
84  virtual void setWalkDirection(const btVector3 &walkDirection) override { assert(false); }
85  virtual void setVelocityForTimeInterval(const btVector3 &velocity, btScalar timeInterval) override { assert(false); }
86  virtual void reset(btCollisionWorld* collisionWorld) override {}
87  virtual void warp(const btVector3& origin) override {}
88  virtual void debugDraw(btIDebugDraw* debugDrawer) override {}
89  virtual void setUpInterpolate(bool value) override {}
90  virtual void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTime) override;
91  virtual void preStep(btCollisionWorld *collisionWorld) override;
92  virtual void playerStep(btCollisionWorld *collisionWorld, btScalar dt) override;
93  virtual bool canJump() const override { assert(false); return false; } // never call this
94  virtual void jump(const btVector3& dir = btVector3(0.0f, 0.0f, 0.0f)) override;
95  virtual bool onGround() const override;
96 
97  void clearMotors();
98  void addMotor(const glm::vec3& velocity, const glm::quat& rotation, float horizTimescale, float vertTimescale = -1.0f);
99  void applyMotor(int index, btScalar dt, btVector3& worldVelocity, std::vector<btVector3>& velocities, std::vector<btScalar>& weights);
100  void setStepUpEnabled(bool enabled) { _stepUpEnabled = enabled; }
101  void computeNewVelocity(btScalar dt, btVector3& velocity);
102  void computeNewVelocity(btScalar dt, glm::vec3& velocity);
103  void setScaleFactor(btScalar scaleFactor) { _scaleFactor = scaleFactor; }
104 
105  // HACK for legacy 'thrust' feature
106  void setLinearAcceleration(const glm::vec3& acceleration) { _linearAcceleration = glmToBullet(acceleration); }
107 
108  void preSimulation();
109  void postSimulation();
110 
111  void setPositionAndOrientation(const glm::vec3& position, const glm::quat& orientation);
112  void getPositionAndOrientation(glm::vec3& position, glm::quat& rotation) const;
113 
114  void setParentVelocity(const glm::vec3& parentVelocity);
115 
116  void setFollowParameters(const glm::mat4& desiredWorldMatrix);
117  float getFollowTime() const { return _followTime; }
118  glm::vec3 getFollowLinearDisplacement() const;
119  glm::quat getFollowAngularDisplacement() const;
120  glm::vec3 getFollowVelocity() const;
121 
122  glm::vec3 getLinearVelocity() const;
123  glm::vec3 getVelocityChange() const;
124 
125  float getCapsuleRadius() const { return _radius; }
126  float getCapsuleHalfHeight() const { return _halfHeight; }
127  glm::vec3 getCapsuleLocalOffset() const { return _shapeLocalOffset; }
128 
129  enum class State {
130  Ground = 0,
131  Takeoff,
132  InAir,
133  Hover,
134  Seated
135  };
136 
137  State getState() const { return _state; }
138  void updateState();
139 
140  void setLocalBoundingBox(const glm::vec3& minCorner, const glm::vec3& scale);
141 
142  void setPhysicsEngine(const PhysicsEnginePointer& engine);
143  bool isEnabledAndReady() const { return (bool)_physicsEngine; }
144  bool isStuck() const { return _isStuck; }
145  float getCollisionBrakeAttenuationFactor() const;
146 
147  void setCollisionless(bool collisionless);
148 
149  virtual int32_t computeCollisionMask() const = 0;
150  virtual void handleChangedCollisionMask() = 0;
151 
152  bool getRigidBodyLocation(glm::vec3& avatarRigidBodyPosition, glm::quat& avatarRigidBodyRotation);
153 
154  void setZoneFlyingAllowed(bool value) { _zoneFlyingAllowed = value; }
155  void setComfortFlyingAllowed(bool value) { _comfortFlyingAllowed = value; }
156  void setHoverWhenUnsupported(bool value) { _hoverWhenUnsupported = value; }
157  void setCollisionlessAllowed(bool value);
158 
159  void setPendingFlagsUpdateCollisionMask(){ _pendingFlags |= PENDING_FLAG_UPDATE_COLLISION_MASK; }
160  void setSeated(bool isSeated) { _isSeated = isSeated; }
161  bool getSeated() const { return _isSeated; }
162 
163  void resetStuckCounter() { _numStuckSubsteps = 0; }
164 
165 protected:
166 #ifdef DEBUG_STATE_CHANGE
167  void setState(State state, const char* reason);
168 #else
169  void setState(State state);
170 #endif
171 
172  virtual void updateMassProperties() = 0;
173  void updateCurrentGravity();
174  void updateUpAxis(const glm::quat& rotation);
175  bool checkForSupport(btCollisionWorld* collisionWorld);
176 
177 protected:
178  struct CharacterMotor {
179  CharacterMotor(const glm::vec3& vel, const glm::quat& rot, float horizTimescale, float vertTimescale = -1.0f);
180 
181  btVector3 velocity { btVector3(0.0f, 0.0f, 0.0f) }; // local-frame
182  btQuaternion rotation; // local-to-world
183  btScalar hTimescale { MAX_CHARACTER_MOTOR_TIMESCALE }; // horizontal
184  btScalar vTimescale { MAX_CHARACTER_MOTOR_TIMESCALE }; // vertical
185  };
186 
187  std::vector<CharacterMotor> _motors;
188  CharacterGhostObject _ghost;
189  btVector3 _currentUp;
190  btVector3 _targetVelocity;
191  btVector3 _parentVelocity;
192  btVector3 _preSimulationVelocity;
193  btVector3 _velocityChange;
194  btTransform _followDesiredBodyTransform;
195  const FollowTimePerType& _followTimeRemainingPerType;
196  btTransform _characterBodyTransform;
197  btVector3 _position;
198  btQuaternion _rotation;
199 
200  glm::vec3 _shapeLocalOffset;
201 
202  glm::vec3 _boxScale; // used to compute capsule shape
203 
204  quint64 _rayHitStartTime;
205  quint64 _takeoffToInAirStartTime;
206  quint64 _jumpButtonDownStartTime;
207  quint32 _jumpButtonDownCount;
208  quint32 _takeoffJumpButtonID;
209 
210  // data for walking up steps
211  btVector3 _stepPoint { 0.0f, 0.0f, 0.0f };
212  btVector3 _stepNormal { 0.0f, 0.0f, 0.0f };
213  btScalar _stepHeight { 0.0f };
214  btScalar _minStepHeight { 0.0f };
215  btScalar _maxStepHeight { 0.0f };
216  btScalar _minFloorNormalDotUp { DEFAULT_MIN_FLOOR_NORMAL_DOT_UP };
217 
218  btScalar _halfHeight { 0.0f };
219  btScalar _radius { 0.0f };
220 
221  btScalar _floorDistance;
222  bool _steppingUp { false };
223  bool _stepUpEnabled { true };
224  bool _hasSupport;
225 
226  btScalar _currentGravity { 0.0f };
227  btScalar _gravity { DEFAULT_AVATAR_GRAVITY };
228 
229  btScalar _followTime;
230  btVector3 _followLinearDisplacement;
231  btQuaternion _followAngularDisplacement;
232  btVector3 _linearAcceleration;
233  btVector3 _netCollisionImpulse;
234 
235  State _state;
236  bool _isPushingUp;
237  bool _isStuck { false };
238  bool _isSeated { false };
239  float _collisionBrake { 0.0f };
240 
241  PhysicsEnginePointer _physicsEngine { nullptr };
242  btRigidBody* _rigidBody { nullptr };
243  uint32_t _pendingFlags { 0 };
244  uint32_t _previousFlags { 0 };
245  uint32_t _stuckTransitionCount { 0 };
246  uint32_t _numStuckSubsteps { 0 };
247 
248  bool _inWorld { false };
249  bool _zoneFlyingAllowed { true };
250  bool _comfortFlyingAllowed { true };
251  bool _hoverWhenUnsupported{ true };
252  bool _collisionlessAllowed { true };
253  bool _collisionless { false };
254 
255  btScalar _scaleFactor { 1.0f };
256 };
257 
258 #endif // hifi_CharacterController_h