205 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			205 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /*
 | ||
|  | Bullet Continuous Collision Detection and Physics Library | ||
|  | Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.com
 | ||
|  | 
 | ||
|  | This software is provided 'as-is', without any express or implied warranty. | ||
|  | In no event will the authors be held liable for any damages arising from the use of this software. | ||
|  | Permission is granted to anyone to use this software for any purpose,  | ||
|  | including commercial applications, and to alter it and redistribute it freely,  | ||
|  | subject to the following restrictions: | ||
|  | 
 | ||
|  | 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. | ||
|  | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. | ||
|  | 3. This notice may not be removed or altered from any source distribution. | ||
|  | */ | ||
|  | 
 | ||
|  | 
 | ||
|  | #ifndef BT_KINEMATIC_CHARACTER_CONTROLLER_H
 | ||
|  | #define BT_KINEMATIC_CHARACTER_CONTROLLER_H
 | ||
|  | 
 | ||
|  | #include "LinearMath/btVector3.h"
 | ||
|  | 
 | ||
|  | #include "btCharacterControllerInterface.h"
 | ||
|  | 
 | ||
|  | #include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
 | ||
|  | 
 | ||
|  | 
 | ||
|  | class btCollisionShape; | ||
|  | class btConvexShape; | ||
|  | class btRigidBody; | ||
|  | class btCollisionWorld; | ||
|  | class btCollisionDispatcher; | ||
|  | class btPairCachingGhostObject; | ||
|  | 
 | ||
|  | ///btKinematicCharacterController is an object that supports a sliding motion in a world.
 | ||
|  | ///It uses a ghost object and convex sweep test to test for upcoming collisions. This is combined with discrete collision detection to recover from penetrations.
 | ||
|  | ///Interaction between btKinematicCharacterController and dynamic rigid bodies needs to be explicity implemented by the user.
 | ||
|  | ATTRIBUTE_ALIGNED16(class) btKinematicCharacterController : public btCharacterControllerInterface | ||
|  | { | ||
|  | protected: | ||
|  | 
 | ||
|  | 	btScalar m_halfHeight; | ||
|  | 	 | ||
|  | 	btPairCachingGhostObject* m_ghostObject; | ||
|  | 	btConvexShape*	m_convexShape;//is also in m_ghostObject, but it needs to be convex, so we store it here to avoid upcast
 | ||
|  | 	 | ||
|  | 	btScalar m_maxPenetrationDepth; | ||
|  | 	btScalar m_verticalVelocity; | ||
|  | 	btScalar m_verticalOffset; | ||
|  | 	btScalar m_fallSpeed; | ||
|  | 	btScalar m_jumpSpeed; | ||
|  | 	btScalar m_SetjumpSpeed; | ||
|  | 	btScalar m_maxJumpHeight; | ||
|  | 	btScalar m_maxSlopeRadians; // Slope angle that is set (used for returning the exact value)
 | ||
|  | 	btScalar m_maxSlopeCosine;  // Cosine equivalent of m_maxSlopeRadians (calculated once when set, for optimization)
 | ||
|  | 	btScalar m_gravity; | ||
|  | 
 | ||
|  | 	btScalar m_turnAngle; | ||
|  | 	 | ||
|  | 	btScalar m_stepHeight; | ||
|  | 
 | ||
|  | 	btScalar	m_addedMargin;//@todo: remove this and fix the code
 | ||
|  | 
 | ||
|  | 	///this is the desired walk direction, set by the user
 | ||
|  | 	btVector3	m_walkDirection; | ||
|  | 	btVector3	m_normalizedDirection; | ||
|  | 	btVector3	m_AngVel; | ||
|  | 
 | ||
|  | 	btVector3	m_jumpPosition; | ||
|  | 
 | ||
|  | 	//some internal variables
 | ||
|  | 	btVector3 m_currentPosition; | ||
|  | 	btScalar  m_currentStepOffset; | ||
|  | 	btVector3 m_targetPosition; | ||
|  | 
 | ||
|  | 	btQuaternion m_currentOrientation; | ||
|  | 	btQuaternion m_targetOrientation; | ||
|  | 
 | ||
|  | 	///keep track of the contact manifolds
 | ||
|  | 	btManifoldArray	m_manifoldArray; | ||
|  | 
 | ||
|  | 	bool m_touchingContact; | ||
|  | 	btVector3 m_touchingNormal; | ||
|  | 
 | ||
|  | 	btScalar m_linearDamping; | ||
|  | 	btScalar m_angularDamping; | ||
|  | 
 | ||
|  | 	bool  m_wasOnGround; | ||
|  | 	bool  m_wasJumping; | ||
|  | 	bool	m_useGhostObjectSweepTest; | ||
|  | 	bool	m_useWalkDirection; | ||
|  | 	btScalar	m_velocityTimeInterval; | ||
|  | 	btVector3 m_up; | ||
|  | 	btVector3 m_jumpAxis; | ||
|  | 
 | ||
|  | 	static btVector3* getUpAxisDirections(); | ||
|  | 	bool  m_interpolateUp; | ||
|  | 	bool  full_drop; | ||
|  | 	bool  bounce_fix; | ||
|  | 
 | ||
|  | 	btVector3 computeReflectionDirection (const btVector3& direction, const btVector3& normal); | ||
|  | 	btVector3 parallelComponent (const btVector3& direction, const btVector3& normal); | ||
|  | 	btVector3 perpindicularComponent (const btVector3& direction, const btVector3& normal); | ||
|  | 
 | ||
|  | 	bool recoverFromPenetration ( btCollisionWorld* collisionWorld); | ||
|  | 	void stepUp (btCollisionWorld* collisionWorld); | ||
|  | 	void updateTargetPositionBasedOnCollision (const btVector3& hit_normal, btScalar tangentMag = btScalar(0.0), btScalar normalMag = btScalar(1.0)); | ||
|  | 	void stepForwardAndStrafe (btCollisionWorld* collisionWorld, const btVector3& walkMove); | ||
|  | 	void stepDown (btCollisionWorld* collisionWorld, btScalar dt); | ||
|  | 
 | ||
|  | 	virtual bool needsCollision(const btCollisionObject* body0, const btCollisionObject* body1); | ||
|  | 
 | ||
|  | 	void setUpVector(const btVector3& up); | ||
|  | 
 | ||
|  | 	btQuaternion getRotation(btVector3& v0, btVector3& v1) const; | ||
|  | 
 | ||
|  | public: | ||
|  | 
 | ||
|  | 	BT_DECLARE_ALIGNED_ALLOCATOR(); | ||
|  | 
 | ||
|  | 	btKinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight, const btVector3& up = btVector3(1.0,0.0,0.0)); | ||
|  | 	~btKinematicCharacterController (); | ||
|  | 	 | ||
|  | 
 | ||
|  | 	///btActionInterface interface
 | ||
|  | 	virtual void updateAction( btCollisionWorld* collisionWorld,btScalar deltaTime) | ||
|  | 	{ | ||
|  | 		preStep ( collisionWorld); | ||
|  | 		playerStep (collisionWorld, deltaTime); | ||
|  | 	} | ||
|  | 	 | ||
|  | 	///btActionInterface interface
 | ||
|  | 	void	debugDraw(btIDebugDraw* debugDrawer); | ||
|  | 
 | ||
|  | 	void setUp(const btVector3& up); | ||
|  | 
 | ||
|  | 	const btVector3& getUp() { return m_up; } | ||
|  | 
 | ||
|  | 	/// This should probably be called setPositionIncrementPerSimulatorStep.
 | ||
|  | 	/// This is neither a direction nor a velocity, but the amount to
 | ||
|  | 	///	increment the position each simulation iteration, regardless
 | ||
|  | 	///	of dt.
 | ||
|  | 	/// This call will reset any velocity set by setVelocityForTimeInterval().
 | ||
|  | 	virtual void	setWalkDirection(const btVector3& walkDirection); | ||
|  | 
 | ||
|  | 	/// Caller provides a velocity with which the character should move for
 | ||
|  | 	///	the given time period.  After the time period, velocity is reset
 | ||
|  | 	///	to zero.
 | ||
|  | 	/// This call will reset any walk direction set by setWalkDirection().
 | ||
|  | 	/// Negative time intervals will result in no motion.
 | ||
|  | 	virtual void setVelocityForTimeInterval(const btVector3& velocity, | ||
|  | 				btScalar timeInterval); | ||
|  | 
 | ||
|  | 	virtual void setAngularVelocity(const btVector3& velocity); | ||
|  | 	virtual const btVector3& getAngularVelocity() const; | ||
|  | 
 | ||
|  | 	virtual void setLinearVelocity(const btVector3& velocity); | ||
|  | 	virtual btVector3 getLinearVelocity() const; | ||
|  | 
 | ||
|  | 	void setLinearDamping(btScalar d) { m_linearDamping = btClamped(d, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); } | ||
|  | 	btScalar getLinearDamping() const { return  m_linearDamping; } | ||
|  | 	void setAngularDamping(btScalar d) { m_angularDamping = btClamped(d, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); } | ||
|  | 	btScalar getAngularDamping() const { return  m_angularDamping; } | ||
|  | 
 | ||
|  | 	void reset ( btCollisionWorld* collisionWorld ); | ||
|  | 	void warp (const btVector3& origin); | ||
|  | 
 | ||
|  | 	void preStep (  btCollisionWorld* collisionWorld); | ||
|  | 	void playerStep ( btCollisionWorld* collisionWorld, btScalar dt); | ||
|  | 
 | ||
|  | 	void setStepHeight(btScalar h); | ||
|  | 	btScalar getStepHeight() const { return m_stepHeight; } | ||
|  | 	void setFallSpeed (btScalar fallSpeed); | ||
|  | 	btScalar getFallSpeed() const { return m_fallSpeed; } | ||
|  | 	void setJumpSpeed (btScalar jumpSpeed); | ||
|  | 	btScalar getJumpSpeed() const { return m_jumpSpeed; } | ||
|  | 	void setMaxJumpHeight (btScalar maxJumpHeight); | ||
|  | 	bool canJump () const; | ||
|  | 
 | ||
|  | 	void jump(const btVector3& v = btVector3()); | ||
|  | 
 | ||
|  | 	void applyImpulse(const btVector3& v) { jump(v); } | ||
|  | 
 | ||
|  | 	void setGravity(const btVector3& gravity); | ||
|  | 	btVector3 getGravity() const; | ||
|  | 
 | ||
|  | 	/// The max slope determines the maximum angle that the controller can walk up.
 | ||
|  | 	/// The slope angle is measured in radians.
 | ||
|  | 	void setMaxSlope(btScalar slopeRadians); | ||
|  | 	btScalar getMaxSlope() const; | ||
|  | 
 | ||
|  | 	void setMaxPenetrationDepth(btScalar d); | ||
|  | 	btScalar getMaxPenetrationDepth() const; | ||
|  | 
 | ||
|  | 	btPairCachingGhostObject* getGhostObject(); | ||
|  | 	void	setUseGhostSweepTest(bool useGhostObjectSweepTest) | ||
|  | 	{ | ||
|  | 		m_useGhostObjectSweepTest = useGhostObjectSweepTest; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	bool onGround () const; | ||
|  | 	void setUpInterpolate (bool value); | ||
|  | }; | ||
|  | 
 | ||
|  | #endif // BT_KINEMATIC_CHARACTER_CONTROLLER_H
 |