12 #ifndef hifi_CharacterController_h
13 #define hifi_CharacterController_h
18 #include <btBulletDynamicsCommon.h>
19 #include <BulletDynamics/Character/btCharacterControllerInterface.h>
21 #include <GLMHelpers.h>
22 #include <NumericalConstants.h>
24 #include "AvatarConstants.h"
25 #include "BulletUtil.h"
26 #include "CharacterGhostObject.h"
27 #include "PhysicsEngine.h"
28 #include "PhysicsHelpers.h"
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;
39 const float DEFAULT_MIN_FLOOR_NORMAL_DOT_UP = cosf(PI / 3.0f);
41 const uint32_t NUM_SUBSTEPS_FOR_STUCK_TRANSITION = 6;
42 const uint32_t NUM_SUBSTEPS_FOR_SAFE_LANDING_RETRY = NUM_SUBSTEPS_PER_SECOND / 2;
45 class btCollisionWorld;
46 class btDynamicsWorld;
50 const btScalar MAX_CHARACTER_MOTOR_TIMESCALE = 60.0f;
51 const btScalar MIN_CHARACTER_MOTOR_TIMESCALE = 0.05f;
53 class CharacterController :
public btCharacterControllerInterface {
56 enum class FollowType : uint8_t {
64 typedef std::array<float, static_cast<size_t>(FollowType::Count)> FollowTimePerType;
67 static constexpr
float FOLLOW_TIME_IMMEDIATE_SNAP = FLT_MAX;
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; }
77 void setGravity(
float gravity);
79 void recomputeFlying();
81 virtual void updateShapeIfNecessary() = 0;
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; }
94 virtual void jump(
const btVector3& dir = btVector3(0.0f, 0.0f, 0.0f))
override;
95 virtual bool onGround()
const override;
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; }
106 void setLinearAcceleration(
const glm::vec3& acceleration) { _linearAcceleration = glmToBullet(acceleration); }
108 void preSimulation();
109 void postSimulation();
111 void setPositionAndOrientation(
const glm::vec3& position,
const glm::quat& orientation);
112 void getPositionAndOrientation(glm::vec3& position, glm::quat& rotation)
const;
114 void setParentVelocity(
const glm::vec3& parentVelocity);
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;
122 glm::vec3 getLinearVelocity()
const;
123 glm::vec3 getVelocityChange()
const;
125 float getCapsuleRadius()
const {
return _radius; }
126 float getCapsuleHalfHeight()
const {
return _halfHeight; }
127 glm::vec3 getCapsuleLocalOffset()
const {
return _shapeLocalOffset; }
137 State getState()
const {
return _state; }
140 void setLocalBoundingBox(
const glm::vec3& minCorner,
const glm::vec3& scale);
142 void setPhysicsEngine(
const PhysicsEnginePointer& engine);
143 bool isEnabledAndReady()
const {
return (
bool)_physicsEngine; }
144 bool isStuck()
const {
return _isStuck; }
145 float getCollisionBrakeAttenuationFactor()
const;
147 void setCollisionless(
bool collisionless);
149 virtual int32_t computeCollisionMask()
const = 0;
150 virtual void handleChangedCollisionMask() = 0;
152 bool getRigidBodyLocation(glm::vec3& avatarRigidBodyPosition, glm::quat& avatarRigidBodyRotation);
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);
159 void setPendingFlagsUpdateCollisionMask(){ _pendingFlags |= PENDING_FLAG_UPDATE_COLLISION_MASK; }
160 void setSeated(
bool isSeated) { _isSeated = isSeated; }
161 bool getSeated()
const {
return _isSeated; }
163 void resetStuckCounter() { _numStuckSubsteps = 0; }
166 #ifdef DEBUG_STATE_CHANGE
167 void setState(State state,
const char* reason);
169 void setState(State state);
172 virtual void updateMassProperties() = 0;
173 void updateCurrentGravity();
174 void updateUpAxis(
const glm::quat& rotation);
175 bool checkForSupport(btCollisionWorld* collisionWorld);
178 struct CharacterMotor {
179 CharacterMotor(
const glm::vec3& vel,
const glm::quat& rot,
float horizTimescale,
float vertTimescale = -1.0f);
181 btVector3 velocity { btVector3(0.0f, 0.0f, 0.0f) };
182 btQuaternion rotation;
183 btScalar hTimescale { MAX_CHARACTER_MOTOR_TIMESCALE };
184 btScalar vTimescale { MAX_CHARACTER_MOTOR_TIMESCALE };
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;
198 btQuaternion _rotation;
200 glm::vec3 _shapeLocalOffset;
204 quint64 _rayHitStartTime;
205 quint64 _takeoffToInAirStartTime;
206 quint64 _jumpButtonDownStartTime;
207 quint32 _jumpButtonDownCount;
208 quint32 _takeoffJumpButtonID;
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 };
218 btScalar _halfHeight { 0.0f };
219 btScalar _radius { 0.0f };
221 btScalar _floorDistance;
222 bool _steppingUp {
false };
223 bool _stepUpEnabled {
true };
226 btScalar _currentGravity { 0.0f };
227 btScalar _gravity { DEFAULT_AVATAR_GRAVITY };
229 btScalar _followTime;
230 btVector3 _followLinearDisplacement;
231 btQuaternion _followAngularDisplacement;
232 btVector3 _linearAcceleration;
233 btVector3 _netCollisionImpulse;
237 bool _isStuck {
false };
238 bool _isSeated {
false };
239 float _collisionBrake { 0.0f };
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 };
248 bool _inWorld {
false };
249 bool _zoneFlyingAllowed {
true };
250 bool _comfortFlyingAllowed {
true };
251 bool _hoverWhenUnsupported{
true };
252 bool _collisionlessAllowed {
true };
253 bool _collisionless {
false };
255 btScalar _scaleFactor { 1.0f };