source: trunk/test/Physics/Src/EasyPhysics.cpp @ 1751

Last change on this file since 1751 was 1751, checked in by touky, 8 years ago

Added a skeleton for Input Tracking & base idea for Touch/untouch mechanics.

File size: 8.2 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2012 Sam Hocevar <sam@hocevar.net>
5//            (c) 2009-2012 Cédric Lecacheur <jordx@free.fr>
6//            (c) 2009-2012 Benjamin Huet <huet.benjamin@gmail.com>
7//   This program is free software; you can redistribute it and/or
8//   modify it under the terms of the Do What The Fuck You Want To
9//   Public License, Version 2, as published by Sam Hocevar. See
10//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
11//
12
13#if defined HAVE_CONFIG_H
14#   include "config.h"
15#endif
16
17#include "../Include/LolBtPhysicsIntegration.h"
18#include "../Include/LolPhysics.h"
19
20namespace lol
21{
22
23namespace phys
24{
25
26#ifdef HAVE_PHYS_USE_BULLET
27
28//-------------------------------------------------------------------------
29//EASY_PHYSIC
30//--
31
32EasyPhysic::EasyPhysic() :
33        m_collision_object(NULL),
34        m_rigid_body(NULL),
35        m_ghost_object(NULL),
36        m_collision_shape(NULL),
37        m_motion_state(NULL),
38        m_mass(.0f),
39        m_local_inertia(btVector3(.0f, .0f, .0f)),
40        m_collision_group(1),
41        m_collision_mask(1)
42{
43}
44
45EasyPhysic::~EasyPhysic()
46{
47        m_rigid_body = NULL;
48        delete m_collision_object;
49        delete m_collision_shape;
50        delete m_motion_state;
51}
52
53//-------------------------------------------------------------------------
54//Set Shape functions
55//--
56
57void EasyPhysic::SetShapeTo(btCollisionShape* collision_shape)
58{
59        bool bReinitToRigidBody = false;
60        if (m_rigid_body)
61        {
62                bReinitToRigidBody = true;
63                delete m_rigid_body;
64        }
65        if (m_collision_shape)
66                delete m_collision_shape;
67
68        m_collision_shape = collision_shape;
69
70        if (bReinitToRigidBody)
71                InitBodyToRigid();
72}
73
74//Box Shape support
75void EasyPhysic::SetShapeToBox(lol::vec3& box_size)
76{
77        vec3 new_box_size = box_size * LOL2BT_UNIT * LOL2BT_SIZE;
78        m_convex_shape = new btBoxShape(LOL2BT_VEC3(new_box_size));
79        SetShapeTo(m_convex_shape);
80}
81
82void EasyPhysic::SetShapeToSphere(float radius)
83{
84        m_convex_shape = new btSphereShape(radius * LOL2BT_UNIT * LOL2BT_SIZE);
85        SetShapeTo(m_convex_shape);
86}
87
88void EasyPhysic::SetShapeToCone(float radius, float height)
89{
90        m_convex_shape = new btConeShape(       radius * LOL2BT_UNIT,
91                                                                                height * LOL2BT_UNIT);
92        SetShapeTo(m_convex_shape);
93}
94
95void EasyPhysic::SetShapeToCylinder(lol::vec3& cyl_size)
96{
97        vec3 new_cyl_size = cyl_size * LOL2BT_UNIT;
98        new_cyl_size.y *= LOL2BT_SIZE;
99        m_convex_shape = new btCylinderShape(LOL2BT_VEC3(new_cyl_size));
100        SetShapeTo(m_convex_shape);
101}
102
103void EasyPhysic::SetShapeToCapsule(float radius, float height)
104{
105        m_convex_shape = new btCapsuleShape(radius * LOL2BT_UNIT * LOL2BT_SIZE,
106                                                                                height * LOL2BT_UNIT * LOL2BT_SIZE);
107        SetShapeTo(m_convex_shape);
108}
109
110//-------------------------------------------------------------------------
111//Base Location/Rotation setup
112//--
113void EasyPhysic::SetTransform(const lol::vec3& base_location, const lol::quat& base_rotation)
114{
115        m_local_to_world = lol::mat4::translate(base_location) * mat4(base_rotation);
116
117        if (m_ghost_object)
118                m_ghost_object->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(base_location * LOL2BT_UNIT)));
119        else
120        {
121                if (m_motion_state)
122                        m_motion_state->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(base_location * LOL2BT_UNIT)));
123                else
124                        m_motion_state = new btDefaultMotionState(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(base_location * LOL2BT_UNIT)));
125        }
126}
127
128//-------------------------------------------------------------------------
129//Mass related functions
130//--
131//Set Shape functions
132void EasyPhysic::SetMass(float mass)
133{
134        m_mass = mass;
135
136        if (m_rigid_body)
137        {
138                SetLocalInertia(m_mass);
139                m_rigid_body->setMassProps(mass, m_local_inertia);
140        }
141}
142
143//-------------------------------------------------------------------------
144//Final conversion pass functons : Body related
145//--
146
147//Init to rigid body
148void EasyPhysic::InitBodyToRigid(bool SetToKinematic)
149{
150        if (m_collision_object)
151                delete m_collision_object;
152
153        if (!m_motion_state)
154                SetTransform(vec3(.0f));
155
156        btRigidBody::btRigidBodyConstructionInfo NewInfos(m_mass, m_motion_state, m_collision_shape, m_local_inertia);
157        m_rigid_body = new btRigidBody(NewInfos);
158        m_collision_object = m_rigid_body;
159        m_collision_object->setUserPointer(this);
160
161        if (m_mass == .0f)
162        {
163                if (SetToKinematic)
164                {
165                        m_rigid_body->setActivationState(DISABLE_DEACTIVATION);
166                        m_rigid_body->setCollisionFlags(m_rigid_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
167                }
168        }
169        else
170                SetMass(m_mass);
171}
172
173//Return correct Ghost Object
174btGhostObject* EasyPhysic::GetGhostObject()
175{
176        return new btGhostObject();
177}
178
179//Init to Ghost object, for Overlap/Sweep Test/Touching logic
180void EasyPhysic::InitBodyToGhost()
181{
182        if (m_collision_object)
183                delete m_collision_object;
184
185        m_ghost_object = GetGhostObject();
186        m_ghost_object->setCollisionShape(m_collision_shape);
187        m_collision_object = m_ghost_object;
188        m_collision_object->setUserPointer(this);
189
190        SetTransform(m_local_to_world.v3.xyz, lol::quat(m_local_to_world));
191
192        m_ghost_object->setCollisionFlags(m_ghost_object->getCollisionFlags());
193}
194
195//-------------
196//Touch logic
197//-------------
198  //    btManifoldArray   manifoldArray;
199  //    btBroadphasePairArray& pairArray = ghostObject->getOverlappingPairCache()->getOverlappingPairArray();
200  //    int numPairs = pairArray.size();
201
202  //    for (int i=0;i<numPairs;i++)
203  //    {
204  //       manifoldArray.clear();
205
206  //       const btBroadphasePair& pair = pairArray[i];
207  //       
208  //       //unless we manually perform collision detection on this pair, the contacts are in the dynamics world paircache:
209  //       btBroadphasePair* collisionPair = dynamicsWorld->getPairCache()->findPair(pair.m_pProxy0,pair.m_pProxy1);
210  //       if (!collisionPair)
211  //          continue;
212
213  //       if (collisionPair->m_algorithm)
214  //          collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
215
216  //       for (int j=0;j<manifoldArray.size();j++)
217  //       {
218  //          btPersistentManifold* manifold = manifoldArray[j];
219  //          btScalar directionSign = manifold->getBody0() == m_ghostObject ? btScalar(-1.0) : btScalar(1.0);
220  //          for (int p=0;p<manifold->getNumContacts();p++)
221  //          {
222  //            const btManifoldPoint&pt = manifold->getContactPoint(p);
223  //              if (pt.getDistance()<0.f)
224                //{
225                //      const btVector3& ptA = pt.getPositionWorldOnA();
226                //      const btVector3& ptB = pt.getPositionWorldOnB();
227                //      const btVector3& normalOnB = pt.m_normalWorldOnB;
228                //      /// work here
229                //}
230  //          }
231  //       }
232  //    }
233
234
235//Add Physic object to the simulation
236void EasyPhysic::AddToSimulation(class Simulation* current_simulation)
237{
238        btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
239        if (dynamics_world)
240        {
241                if (m_ghost_object)
242                {
243                        dynamics_world->addCollisionObject(m_ghost_object, m_collision_group, m_collision_mask);
244                        current_simulation->AddToGhost(this);
245                }
246                else if (m_rigid_body)
247                {
248                        dynamics_world->addRigidBody(m_rigid_body, m_collision_group, m_collision_mask);
249                        if (m_mass != .0f)
250                                current_simulation->AddToDynamic(this);
251                        else
252                                current_simulation->AddToStatic(this);
253                }
254                else
255                        dynamics_world->addCollisionObject(m_collision_object, m_collision_group, m_collision_mask);
256        }
257}
258
259//Remove Physic object to the simulation
260void EasyPhysic::RemoveFromSimulation(class Simulation* current_simulation)
261{
262        btDiscreteDynamicsWorld* dynamics_world = current_simulation->GetWorld();
263        if (dynamics_world)
264        {
265                if (m_rigid_body)
266                        dynamics_world->removeRigidBody(m_rigid_body);
267                else if (m_collision_object)
268                        dynamics_world->removeCollisionObject(m_collision_object);
269        }
270}
271
272//-------------------------------------------------------------------------
273//Getter functons
274//--
275
276mat4 EasyPhysic::GetTransform()
277{
278        m_local_to_world = lol::mat4(1.0f);
279        if (m_rigid_body && m_motion_state)
280        {
281                btTransform CurTransform;
282                m_motion_state->getWorldTransform(CurTransform);
283                CurTransform.getOpenGLMatrix(&m_local_to_world[0][0]);
284        }
285        else if (m_collision_object)
286                m_collision_object->getWorldTransform().getOpenGLMatrix(&m_local_to_world[0][0]);
287        return m_local_to_world;
288}
289
290//Set Local Inertia
291void EasyPhysic::SetLocalInertia(float mass)
292{
293        if (mass != .0f)
294                m_collision_shape->calculateLocalInertia(mass, m_local_inertia);
295        else
296                m_local_inertia = btVector3(.0f, .0f, .0f);
297}
298
299#endif // HAVE_PHYS_USE_BULLET
300
301} /* namespace phys */
302
303} /* namespace lol */
Note: See TracBrowser for help on using the repository browser.