source: trunk/test/Physics/Include/BulletCharacterController.h @ 1819

Last change on this file since 1819 was 1819, checked in by touky, 7 years ago

BulletCharacterController is now readable by a human being.
BtPhysTest now implements it with the BtKineCC logic -just modify that now-.

File size: 8.3 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2012 Sam Hocevar <sam@hocevar.net>
5//            (c) 2009-2012 Benjamin Huet <huet.benjamin@gmail.com>
6//   This program is free software; you can redistribute it and/or
7//   modify it under the terms of the Do What The Fuck You Want To
8//   Public License, Version 2, as published by Sam Hocevar. See
9//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
10//
11
12//
13// The BulletCharacterController class
14// ------------------
15// This class is a equivalent of btKinematicCharacterController, but more useful for Lol.
16//
17
18#if !defined __BULLETCHARACTERCONTROLLER_BULLETCHARACTERCONTROLLER_H__
19#define __BULLETCHARACTERCONTROLLER_BULLETCHARACTERCONTROLLER_H__
20
21#ifdef HAVE_PHYS_USE_BULLET
22#include "core.h"
23#include "EasyPhysics.h"
24//#include "BulletDynamics\Character\btCharacterControllerInterface.h"
25#endif
26
27#define USE_LOL_CTRLR_CHARAC
28
29namespace lol
30{
31
32        namespace phys
33        {
34
35#ifdef USE_LOL_CTRLR_CHARAC
36#ifdef HAVE_PHYS_USE_BULLET
37
38                ///BulletKinematicCharacterController is an object that supports a sliding motion in a world.
39                ///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.
40                ///Interaction between btKinematicCharacterController and dynamic rigid bodies needs to be explicity implemented by the user.
41                class BulletKinematicCharacterController : public btActionInterface
42                {
43                public:
44                        BulletKinematicCharacterController(btPairCachingGhostObject* NewGhostObject, btConvexShape* NewConvexShape, float NewStepHeight, int NewUpAxis=1)
45                        {
46                                m_convex_shape = NewConvexShape;       
47                                m_up_axis = NewUpAxis;
48                                m_ghost_object = NewGhostObject;
49                                m_step_height = NewStepHeight;
50
51                                m_added_margin = 0.02f;
52                                m_walk_direction = vec3(.0f, .0f, .0f);
53                                m_do_gobject_sweep_test = true;
54                                m_turn_angle = .0f;
55                                m_use_walk_direction = false; // Should remove walk direction, this doesn't work correctly.
56                                m_velocity_time_interval = .0f;
57                                m_vertical_velocity = .0f;
58                                m_vertical_offset = .0f;
59                                m_gravity = 9.8f * 3.f; // 3G acceleration.
60                                m_fall_speed = 55.f; // Terminal velocity of a sky diver in m/s.
61                                m_jump_speed = 10.f; // ?
62                                m_was_on_ground = false;
63                                m_was_jumping = false;
64                                SetMaxSlope(45.f);
65                        }
66                        ~BulletKinematicCharacterController() { }
67
68                protected:
69
70                        static vec3* GetUpAxisDirections()
71                        {
72                                static vec3 sUpAxisDirection[3] = { vec3(1.0f, 0.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f), vec3(0.0f, 0.0f, 1.0f) };
73       
74                                return sUpAxisDirection;
75                        }
76
77                        //--------------------------
78                        //CONVENIENCE FUNCTIONS
79                        //--
80
81                        //Returns the reflection Direction of a ray going 'Direction' hitting a surface with Normal 'Normal' from: http://www-cs-students.stanford.edu/~adityagp/final/node3.html
82                        vec3 GetReflectedDir(const vec3& Direction, const vec3& Normal)
83                        {
84                                return Direction - (2.f * dot(Direction, Normal) * Normal);
85                        }
86                        //Returns the portion of 'direction' that is parallel to 'normal'
87                        vec3 ProjectDirOnNorm(const vec3& Direction, const vec3& Normal)
88                        {
89                                return Normal * dot(Direction, Normal);
90                        }
91                        //Returns the portion of 'Direction' that is perpindicular to 'Normal'
92                        vec3 ProjectDirOnNormPerpindicular(const vec3& Direction, const vec3& Normal)
93                        {
94                                return Direction - ProjectDirOnNorm(Direction, Normal);
95                        }
96                        //Returns Ghost Object. -duh-
97                        btPairCachingGhostObject* GetGhostObject()
98                        {
99                                return m_ghost_object;
100                        }
101
102                        //"Real" war functions
103                        bool RecoverFromPenetration(btCollisionWorld* CollisionWorld);
104                        void UpdateTargetOnHit(const vec3& hit_normal, float TangentMag = .0f, float NormalMag = 1.f);
105                        void StepUp(btCollisionWorld* CollisionWorld);
106                        void StepForwardAndStrafe(btCollisionWorld* CollisionWorld, const vec3& MoveStep);
107                        void StepDown(btCollisionWorld* CollisionWorld, float DeltaTime);
108
109                public:
110                        ///btActionInterface interface : KEEP IN camelCase
111                        virtual void updateAction(btCollisionWorld* CollisionWorld, float deltaTime)
112                        {
113                                PreStep(CollisionWorld);
114                                PlayerStep(CollisionWorld, deltaTime);
115                        }
116
117                        //not in the interface, but called above
118                        void PreStep(btCollisionWorld* CollisionWorld);
119                        void PlayerStep(btCollisionWorld* CollisionWorld, float DeltaTime);
120
121                        ///btActionInterface interface : KEEP IN camelCase
122                        void debugDraw(btIDebugDraw* debugDrawer) { }
123                       
124                        void SetUpAxis(int NewAxis)
125                        {
126                                if (NewAxis < 0)
127                                        NewAxis = 0;
128                                if (NewAxis > 2)
129                                        NewAxis = 2;
130                                m_up_axis = NewAxis;
131                        }
132
133                        //!!!!!! SHOULD DITCH THAT !!!!!!
134                        //This should probably be called setPositionIncrementPerSimulatorStep.
135                        //This is neither a Direction nor a velocity, but the amount to
136                        //increment the position each simulation iteration, regardless
137                        //of DeltaTime.
138                        //This call will Reset any velocity set by SetVelocityForTimeInterval().
139                        virtual void SetWalkDirection(const vec3& walkDirection)
140                        {
141                                m_use_walk_direction = true;
142                                m_walk_direction = walkDirection;
143                                m_normalized_direction = normalize(m_walk_direction);
144                        }
145
146                        //Caller provides a velocity with which the character should MoveStep for
147                        //the given time period.  After the time period, velocity is Reset
148                        //to zero.
149                        //This call will Reset any walk Direction set by SetWalkDirection().
150                        //Negative time intervals will result in no motion.
151                        virtual void SetVelocityForTimeInterval(const vec3& velocity, float timeInterval)
152                        {
153                                m_use_walk_direction = false;
154                                m_walk_direction = velocity;
155                                m_normalized_direction = normalize(m_walk_direction);
156                                m_velocity_time_interval = timeInterval;
157                        }
158
159                        //Usefulness ?
160                        void Reset() { }
161                        void Warp(const vec3& NewOrigin)
162                        {
163                                btTransform NewTransform;
164                                NewTransform.setIdentity();
165                                NewTransform.setOrigin(LOL2BTU_VEC3(NewOrigin));
166                                m_ghost_object->setWorldTransform(NewTransform);
167                        }
168
169                        //External Setup
170                        //--
171
172                        void SetFallSpeed(float NewFallSpeed)                   { m_fall_speed = NewFallSpeed; }
173                        void SetJumpSpeed(float NewJumpSpeed)                   { m_jump_speed = NewJumpSpeed; }
174                        void SetMaxJumpHeight(float NewMaxJumpHeight)   { m_max_jump_height = NewMaxJumpHeight; }
175
176                        //Jump logic will go in EasyCC
177                        bool CanJump() const                                                    { return OnGround(); }
178                        void Jump();
179
180                        //NewGravity functions
181                        void SetGravity(float NewGravity)                               { m_gravity = NewGravity; }
182                        float GetGravity() const                                                { return m_gravity; }
183
184                        //The max slope determines the maximum angle that the controller can walk up.
185                        //The slope angle is measured in radians.
186                        void SetMaxSlope(float NewSlopeRadians)                 { m_max_slope_radians = NewSlopeRadians; m_max_slope_cosine = lol::cos(NewSlopeRadians); }
187                        float GetMaxSlope() const                                               { return m_max_slope_radians; }
188
189                        void SetUseGhostSweepTest(bool UseGObjectSweepTest) { m_do_gobject_sweep_test = UseGObjectSweepTest; }
190
191                        bool OnGround() const                                                   { return m_vertical_velocity == .0f && m_vertical_offset == .0f; }
192
193                private:
194
195                        btPairCachingGhostObject*       m_ghost_object;
196                        btConvexShape*                          m_convex_shape; //is also in m_ghost_object, but it needs to be convex, so we store it here to avoid upcast
197
198                        //keep track of the contact manifolds
199                        btManifoldArray                         m_manifold_array;
200
201                        float                                           m_half_height;
202                        float                                           m_velocity_time_interval;
203                        float                                           m_vertical_velocity;
204                        float                                           m_vertical_offset;
205                        float                                           m_fall_speed;
206                        float                                           m_jump_speed;
207                        float                                           m_max_jump_height;
208                        float                                           m_max_slope_radians; // Slope angle that is set (used for returning the exact value)
209                        float                                           m_max_slope_cosine;  // Cosine equivalent of m_max_slope_radians (calculated once when set, for optimization)
210                        float                                           m_gravity;
211                        float                                           m_turn_angle;
212                        float                                           m_step_height;
213                        float                                           m_added_margin;//@todo: remove this and fix the code
214
215                        ///this is the desired walk Direction, set by the user
216                        vec3                                            m_walk_direction;
217                        vec3                                            m_normalized_direction;
218
219                        //some internal variables
220                        vec3                                            m_current_position;
221                        float                                           m_current_step_offset;
222                        vec3                                            m_target_position;
223
224                        vec3                                            m_touching_normal;
225                        bool                                            m_touching_contact;
226
227                        bool                                            m_was_on_ground;
228                        bool                                            m_was_jumping;
229                        bool                                            m_do_gobject_sweep_test;
230                        bool                                            m_use_walk_direction;
231                        int                                                     m_up_axis;
232                };
233
234#endif // HAVE_PHYS_USE_BULLET
235#endif // USE_LOL_CTRLR_CHARAC
236
237        } /* namespace phys */
238
239} /* namespace lol */
240
241#endif /* __BULLETCHARACTERCONTROLLER_BULLETCHARACTERCONTROLLER_H__ */
242
Note: See TracBrowser for help on using the repository browser.