source: trunk/test/Physics/EasyPhysics.h @ 1722

Last change on this file since 1722 was 1722, checked in by touky, 9 years ago

LocalInertia error FIX.
Character integration better but still not working.

File size: 10.1 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 EasyPhysic class
14// ------------------
15//
16
17#if !defined __EASYPHYSICS_EASYPHYSICS_H__
18#define __EASYPHYSICS_EASYPHYSICS_H__
19
20#ifdef HAVE_PHYS_USE_BULLET
21#include "core.h"
22#include <bullet/btBulletDynamicsCommon.h>
23#include <bullet/btBulletCollisionCommon.h>
24#include <bullet/BulletCollision/CollisionDispatch/btGhostObject.h>
25#include <BulletDynamics/Character/btKinematicCharacterController.h>
26#endif
27
28namespace lol
29{
30
31namespace phys
32{
33
34class EasyPhysic
35{
36
37        friend class EasyConstraint;
38
39#ifdef HAVE_PHYS_USE_BULLET
40
41public:
42        EasyPhysic();
43        ~EasyPhysic();
44
45        virtual void SetShapeToBox(lol::vec3& box_size);
46        virtual void SetShapeToSphere(float radius);
47        virtual void SetShapeToCone(float radius, float height);
48        virtual void SetShapeToCylinder(lol::vec3& cyl_size);
49        virtual void SetShapeToCapsule(float radius, float height);
50
51        virtual bool CanChangeCollisionChannel() { return (m_rigid_body == NULL); }
52        virtual void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation=lol::quat(lol::mat4(1.0f)));
53        virtual void SetMass(float mass);
54        virtual void InitBodyToRigid(bool ZeroMassIsKinematic=false);
55        virtual void InitBodyToGhost();
56        virtual void AddToSimulation(class Simulation* current_simulation);
57        virtual void RemoveFromSimulation(class Simulation* current_simulation);
58        virtual mat4 GetTransform();
59
60protected:
61        virtual void SetLocalInertia(float mass);
62        virtual void SetShapeTo(btCollisionShape* collision_shape);
63
64        virtual btGhostObject* GetGhostObject();
65
66        btCollisionObject*                                                      m_collision_object;
67
68        btGhostObject*                                                          m_ghost_object;
69
70        btRigidBody*                                                            m_rigid_body;
71        btVector3                                                                       m_local_inertia;
72
73        btCollisionShape*                                                       m_collision_shape;
74        btConvexShape*                                                          m_convex_shape;
75        btMotionState*                                                          m_motion_state;
76
77#else  // NO PHYSIC IMPLEMENTATION
78
79public:
80        EasyPhysic() { }
81
82        virtual void SetShapeToBox(lol::vec3& BoxSize) { }
83        virtual void SetShapeToSphere(float radius) { }
84        virtual void SetShapeToCone(float radius, float height) { }
85        virtual void SetShapeToCylinder(lol::vec3& cyl_size) { }
86        virtual void SetShapeToCapsule(float radius, float height) { }
87
88        virtual bool CanChangeCollisionChannel() { return true; }
89        virtual void SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation=lol::quat(lol::mat4(1.0f))) { }
90        virtual void SetMass(float mass) { }
91        virtual void InitBodyToRigid() { }
92        virtual void InitBodyToGhost() { }
93        virtual void AddToSimulation(class Simulation* current_simulation) { }
94        virtual void RemoveFromSimulation(class Simulation* current_simulation) { }
95        virtual mat4 GetTransform() { return mat4(1.0f); }
96
97        virtual void InitBodyToGhost() { }
98
99#endif // PHYSIC IMPLEMENTATION
100
101public:
102        //Sets the collision Group & Mask.
103        //Mask can change at runtime, not group !
104        virtual bool SetCollisionChannel(int NewGroup, int NewMask)
105        {
106                if (CanChangeCollisionChannel())
107                {
108                        m_collision_group = (1<<NewGroup);
109                        m_collision_mask = NewMask;
110                        return true;
111                }
112                return false;
113        }
114        int GetCollisionGroup() { return m_collision_group; }
115        int GetCollisionMask()  { return m_collision_mask; }
116
117protected:
118        lol::mat4                                                                       m_local_to_world;
119        float                                                                           m_mass;
120        int                                                                                     m_collision_group;
121        int                                                                                     m_collision_mask;
122};
123
124class EasyCharacterController : public EasyPhysic
125{
126
127#ifdef HAVE_PHYS_USE_BULLET
128
129public:
130        EasyCharacterController() :
131                EasyPhysic(),
132                m_character(NULL)
133        {
134                m_up_axis = 1;
135        }
136        ~EasyCharacterController()
137        {
138                delete m_character;
139        }
140
141        virtual void InitBodyToRigid(bool ZeroMassIsKinematic=false);
142        virtual void InitBodyToGhost();
143        virtual void AddToSimulation(class Simulation* current_simulation);
144        virtual void RemoveFromSimulation(class Simulation* current_simulation);
145
146protected:
147
148        virtual btGhostObject* GetGhostObject();
149
150        btPairCachingGhostObject*               m_pair_caching_object;
151        btKinematicCharacterController* m_character;
152
153        float                                                   m_step_height;
154        int                                                             m_up_axis;
155
156#else  // NO PHYSIC IMPLEMENTATION
157
158#endif // PHYSIC IMPLEMENTATION
159
160};
161
162class EasyConstraint
163{
164#ifdef HAVE_PHYS_USE_BULLET
165
166public:
167        EasyConstraint() :
168                m_typed_constraint(NULL),
169                m_p2p_constraint(NULL),
170                m_hinge_constraint(NULL),
171                m_slider_constraint(NULL),
172                m_cone_twist_constraint(NULL),
173                m_6dof_constraint(NULL),
174                m_a_physobj(NULL),
175                m_b_physobj(NULL),
176                m_a_transform(lol::mat4(1.f)),
177                m_b_transform(lol::mat4(1.f)),
178                m_using_ref_a(false),
179                m_disable_a2b_collision(false)
180
181        {
182        }
183        ~EasyConstraint()
184        {
185                delete m_typed_constraint;
186                m_p2p_constraint = NULL;
187                m_hinge_constraint = NULL;
188                m_slider_constraint = NULL;
189                m_cone_twist_constraint = NULL;
190                m_6dof_constraint = NULL;
191        }
192
193        void AddToSimulation(class Simulation* current_simulation);
194        void RemoveFromSimulation(class Simulation* current_simulation);
195
196private:
197
198        //check if Init can be done
199        bool CanProceedWithInit()
200        {
201                if (!m_a_physobj || !m_b_physobj)
202                        return false;
203
204                if (!m_a_physobj->m_rigid_body || !m_b_physobj->m_rigid_body)
205                        return false;
206
207                return true;
208        }
209
210        //-------------------------------------------------------------------------
211        //Init constraint functions
212        //--
213        void CustomInitConstraintToPoint2Point()
214        {
215                m_p2p_constraint = new btPoint2PointConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body,
216                                                                                                                LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT));
217                m_typed_constraint = m_p2p_constraint;
218        }
219
220        void CustomInitConstraintToHinge()
221        {
222                m_hinge_constraint = new btHingeConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body,
223                                                                                                                btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT)),
224                                                                                                                btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT)),
225                                                                                                                m_using_ref_a);
226                m_typed_constraint = m_hinge_constraint;
227        }
228
229        void CustomInitConstraintToSlider()
230        {
231                m_slider_constraint = new btSliderConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body,
232                                                                                                                btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT)),
233                                                                                                                btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT)),
234                                                                                                                m_using_ref_a);
235                m_typed_constraint = m_slider_constraint;
236        }
237
238        void CustomInitConstraintToConeTwist()
239        {
240                m_cone_twist_constraint = new btConeTwistConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body,
241                                                                                                                btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT)),
242                                                                                                                btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT)));
243                m_typed_constraint = m_cone_twist_constraint;
244        }
245
246        void CustomInitConstraintTo6Dof()
247        {
248                m_6dof_constraint = new btGeneric6DofConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body,
249                                                                                                                btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT)),
250                                                                                                                btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT)),
251                                                                                                                m_using_ref_a);
252                m_typed_constraint = m_6dof_constraint;
253        }
254
255        btTypedConstraint*                      m_typed_constraint;
256        btPoint2PointConstraint*        m_p2p_constraint;
257        btHingeConstraint*                      m_hinge_constraint;
258        btSliderConstraint*                     m_slider_constraint;
259        btConeTwistConstraint*          m_cone_twist_constraint;
260        btGeneric6DofConstraint*        m_6dof_constraint;
261
262#else  // NO PHYSIC IMPLEMENTATION
263
264public:
265        EasyConstraint() :
266                m_a_physobj(NULL),
267                m_b_physobj(NULL),
268                m_a_transform(lol::mat4(1.f)),
269                m_b_transform(lol::mat4(1.f)),
270                m_using_ref_a(false),
271                m_disable_a2b_collision(false)
272        {
273        }
274
275private:
276
277        void AddToSimulation(class Simulation* current_simulation) { }
278        void RemoveFromSimulation(class Simulation* current_simulation) { }
279
280        //check if Init can be done
281        bool CanProceedWithInit() { return false; }
282        void CustomInitConstraintToPoint2Point() { }
283        void CustomInitConstraintToHinge() { }
284        void CustomInitConstraintToSlider() { }
285        void CustomInitConstraintToConeTwist() { }
286        void CustomInitConstraintTo6Dof() { }
287
288#endif // PHYSIC IMPLEMENTATION
289
290public:
291        void InitConstraintToPoint2Point()      { if (CanProceedWithInit()) CustomInitConstraintToPoint2Point(); }
292        void InitConstraintToHinge()            { if (CanProceedWithInit()) CustomInitConstraintToHinge(); }
293        void InitConstraintToSlider()           { if (CanProceedWithInit()) CustomInitConstraintToSlider(); }
294        void InitConstraintToConeTwist()        { if (CanProceedWithInit()) CustomInitConstraintToConeTwist(); }
295        void InitConstraintTo6Dof()                     { if (CanProceedWithInit()) CustomInitConstraintTo6Dof(); }
296
297        //Set given physic object to the proper slot.
298        void SetPhysObjA(EasyPhysic* NewPhysObj, lol::mat4 NewTransform) { SetPhysObj(false, NewPhysObj, NewTransform); }
299        void SetPhysObjB(EasyPhysic* NewPhysObj, lol::mat4 NewTransform) { SetPhysObj(true, NewPhysObj, NewTransform); }
300        void SetPhysObj(bool SetToB, EasyPhysic* NewPhysObj, lol::mat4 NewTransform)
301        {
302                if (SetToB)
303                {
304                        m_b_physobj = NewPhysObj;
305                        m_b_transform = NewTransform;
306                }
307                else
308                {
309                        m_a_physobj = NewPhysObj;
310                        m_a_transform = NewTransform;
311                }
312        }
313
314        //Set whether or not the physic engine should use the A object as the reference (most constraint transform are local).
315        void SetRefAsA(bool NewUseRefA)
316        {
317                m_using_ref_a = NewUseRefA;
318        }
319
320        //Set whether or not to disable the collision between the bodies
321        void DisableCollisionBetweenObjs(bool DisableCollision)
322        {
323                m_disable_a2b_collision = DisableCollision;
324        }
325
326private:
327        EasyPhysic*                                     m_a_physobj;
328        EasyPhysic*                                     m_b_physobj;
329        lol::mat4                                       m_a_transform;
330        lol::mat4                                       m_b_transform;
331        bool                                            m_using_ref_a;
332        bool                                            m_disable_a2b_collision;
333
334};
335
336} /* namespace phys */
337
338} /* namespace lol */
339
340#endif /* __EASYPHYSICS_EASYPHYSICS_H__ */
341
Note: See TracBrowser for help on using the repository browser.