Added resolveCombinedVelocities()
[blender.git] / source / gameengine / Physics / Sumo / Fuzzics / include / SM_Object.h
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32 #ifndef SM_OBJECT_H
33 #define SM_OBJECT_H
34
35 #include <vector>
36
37 #include <SOLID/SOLID.h>
38
39 #include "SM_Callback.h"
40 #include "SM_MotionState.h"
41 #include <stdio.h>
42
43 class SM_FhObject;
44
45
46 // Properties of dynamic objects
47 struct SM_ShapeProps {
48         MT_Scalar  m_mass;                  // Total mass
49         MT_Scalar  m_radius;                // Bound sphere size
50         MT_Scalar  m_inertia;               // Inertia, should be a tensor some time 
51         MT_Scalar  m_lin_drag;              // Linear drag (air, water) 0 = concrete, 1 = vacuum 
52         MT_Scalar  m_ang_drag;              // Angular drag
53         MT_Scalar  m_friction_scaling[3];   // Scaling for anisotropic friction. Component in range [0, 1]   
54         bool       m_do_anisotropic;        // Should I do anisotropic friction? 
55         bool       m_do_fh;                 // Should the object have a linear Fh spring?
56         bool       m_do_rot_fh;             // Should the object have an angular Fh spring?
57 };
58
59
60 // Properties of collidable objects (non-ghost objects)
61 struct SM_MaterialProps {
62         MT_Scalar m_restitution;           // restitution of energie after a collision 0 = inelastic, 1 = elastic
63         MT_Scalar m_friction;              // Coulomb friction (= ratio between the normal en maximum friction force)
64         MT_Scalar m_fh_spring;             // Spring constant (both linear and angular)
65         MT_Scalar m_fh_damping;            // Damping factor (linear and angular) in range [0, 1]
66         MT_Scalar m_fh_distance;           // The range above the surface where Fh is active.    
67         bool      m_fh_normal;             // Should the object slide off slopes?
68 };
69
70
71
72 class SM_Object : public SM_MotionState {
73 public:
74     SM_Object() ;
75     SM_Object(
76                 DT_ShapeHandle shape, 
77                 const SM_MaterialProps *materialProps,
78                 const SM_ShapeProps *shapeProps,
79                 SM_Object *dynamicParent
80         );
81     virtual ~SM_Object();
82
83         bool isDynamic() const;  
84
85         /* nzc experimental. There seem to be two places where kinematics
86          * are evaluated: proceedKinematic (called from SM_Scene) and
87          * proceed() in this object. I'll just try and bunge these out for
88          * now.  */
89
90         void suspend(void);
91         void resume(void);
92
93         void suspendDynamics();
94         
95         void restoreDynamics();
96         
97         bool isGhost() const;
98
99         void suspendMaterial();
100         
101         void restoreMaterial();
102         
103         SM_FhObject *getFhObject() const;
104         
105         void registerCallback(SM_Callback& callback);
106
107         void calcXform();
108         void notifyClient();
109     
110         // Save the current state information for use in the 
111         // velocity computation in the next frame.  
112
113         void proceedKinematic(MT_Scalar timeStep);
114
115         void saveReactionForce(MT_Scalar timeStep) ;
116         
117         void clearForce() ;
118
119     void clearMomentum() ;
120
121     void setMargin(MT_Scalar margin) ;
122
123     MT_Scalar getMargin() const ;
124     
125     const SM_MaterialProps *getMaterialProps() const ;
126
127         const SM_ShapeProps *getShapeProps() const ;
128
129     void setPosition(const MT_Point3& pos);
130     void setOrientation(const MT_Quaternion& orn);
131     void setScaling(const MT_Vector3& scaling);
132
133
134         /**
135          * set an external velocity. This velocity complements
136          * the physics velocity. So setting it does not override the
137          * physics velocity. It is your responsibility to clear 
138          * this external velocity. This velocity is not subject to 
139          * friction or damping.
140          */
141
142
143     void setExternalLinearVelocity(const MT_Vector3& lin_vel) ;
144         void addExternalLinearVelocity(const MT_Vector3& lin_vel) ;
145
146         /** Override the physics velocity */
147
148     void addLinearVelocity(const MT_Vector3& lin_vel);
149         void setLinearVelocity(const MT_Vector3& lin_vel);
150
151         /**
152          * Set an external angular velocity. This velocity complemetns
153          * the physics angular velocity so does not override it. It is
154          * your responsibility to clear this velocity. This velocity
155          * is not subject to friction or damping.
156          */
157
158     void setExternalAngularVelocity(const MT_Vector3& ang_vel) ;
159     void addExternalAngularVelocity(const MT_Vector3& ang_vel);
160
161         /** Override the physics angular velocity */
162
163         void addAngularVelocity(const MT_Vector3& ang_vel);
164         void setAngularVelocity(const MT_Vector3& ang_vel);
165
166         /** Clear the external velocities */
167
168         void clearCombinedVelocities();
169
170         /** 
171          * Tell the physics system to combine the external velocity
172          * with the physics velocity. 
173          */
174
175         void resolveCombinedVelocities(
176                 const MT_Vector3 & lin_vel,
177                 const MT_Vector3 & ang_vel
178         ) ;
179
180
181
182         MT_Scalar getInvMass() const;
183
184         MT_Scalar getInvInertia() const ;
185
186     void applyForceField(const MT_Vector3& accel) ;
187
188     void applyCenterForce(const MT_Vector3& force) ;
189
190     void applyTorque(const MT_Vector3& torque) ;
191
192     void applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse) ;
193
194     void applyCenterImpulse(const MT_Vector3& impulse);
195
196     void applyAngularImpulse(const MT_Vector3& impulse);
197
198     MT_Point3 getWorldCoord(const MT_Point3& local) const;
199     MT_Point3 getLocalCoord(const MT_Point3& world) const;
200     
201         MT_Vector3 getVelocity(const MT_Point3& local) const;
202
203
204         const MT_Vector3& getReactionForce() const ;
205
206         void getMatrix(double *m) const ;
207
208         const double *getMatrix() const ;
209
210         // Still need this???
211         const MT_Transform&  getScaledTransform()  const; 
212
213         DT_ObjectHandle getObjectHandle() const ;
214         DT_ShapeHandle getShapeHandle() const ;
215
216         SM_Object *getDynamicParent() ;
217
218         void integrateForces(MT_Scalar timeStep);
219         void integrateMomentum(MT_Scalar timeSteo);
220
221         void setRigidBody(bool is_rigid_body) ;
222
223         bool isRigidBody() const ;
224
225         // This is the callback for handling collisions of dynamic objects
226         static 
227                 DT_Bool 
228         boing(
229                 void *client_data,  
230                 void *object1,
231                 void *object2,
232                 const DT_CollData *coll_data
233         );
234
235         static 
236                 DT_Bool 
237         fix(
238                 void *client_data,  
239                 void *object1,
240                 void *object2,
241                 const DT_CollData *coll_data
242         );
243         
244         
245         void *getClientObject() { return m_client_object; }
246         void setClientObject(void *client_object) { m_client_object = client_object; }
247         
248         void relax();
249         
250         void backup() {
251                 m_pos = m_prev_state.getPosition();
252                 m_orn = m_prev_state.getOrientation();
253                 m_xform = m_prev_xform;
254         }
255 private:
256
257         // return the actual linear_velocity of this object this 
258         // is the addition of m_combined_lin_vel and m_lin_vel.
259
260         const 
261                 MT_Vector3
262         actualLinVelocity(
263         ) const ;
264
265         const 
266                 MT_Vector3
267         actualAngVelocity(
268         ) const ;
269         
270         void dynamicCollision(const MT_Point3 &local2, 
271                 const MT_Vector3 &normal, 
272                 MT_Scalar dist, 
273                 const MT_Vector3 &rel_vel,
274                 MT_Scalar restitution,
275                 MT_Scalar friction_factor,
276                 MT_Scalar invMass
277         );
278
279         typedef std::vector<SM_Callback *> T_CallbackList;
280
281
282         T_CallbackList          m_callbackList;    // Each object can have multiple callbacks from the client (=game engine)
283         SM_Object              *m_dynamicParent;   // Collisions between parent and children are ignored
284
285     // as the collision callback now has only information
286         // on an SM_Object, there must be a way that the SM_Object client
287         // can identify it's clientdata after a collision
288         void                   *m_client_object;
289
290         DT_ShapeHandle          m_shape;                 // Shape for collision detection
291
292         // Material and shape properties are not owned by this class.
293
294         const SM_MaterialProps *m_materialProps;         
295         const SM_MaterialProps *m_materialPropsBackup;   // Backup in case the object temporarily becomes a ghost.
296         const SM_ShapeProps    *m_shapeProps;           
297         const SM_ShapeProps    *m_shapePropsBackup;      // Backup in case the object's dynamics is temporarily suspended
298         DT_ObjectHandle         m_object;                // A handle to the corresponding object in SOLID.
299         MT_Scalar               m_margin;                // Offset for the object's shape (also for collision detection)
300         MT_Vector3              m_scaling;               // Non-uniform scaling of the object's shape
301
302         double                  m_ogl_matrix[16];        // An OpenGL-type 4x4 matrix      
303         MT_Transform            m_xform;                 // The object's local coordinate system
304         MT_Transform            m_prev_xform;            // The object's local coordinate system in the previous frame
305         SM_MotionState          m_prev_state;            // The object's motion state in the previous frame
306         MT_Scalar               m_timeStep;              // The duration of the last frame 
307
308         MT_Vector3              m_reaction_impulse;      // The accumulated impulse resulting from collisions
309         MT_Vector3              m_reaction_force;        // The reaction force derived from the reaction impulse   
310
311         unsigned int            m_kinematic      : 1;    // Have I been displaced (translated, rotated, scaled) in this frame? 
312         unsigned int            m_prev_kinematic : 1;    // Have I been displaced (translated, rotated, scaled) in the previous frame? 
313         unsigned int            m_is_rigid_body  : 1;    // Should friction give me a change in angular momentum?
314
315         MT_Vector3              m_lin_mom;               // Linear momentum (linear velocity times mass)
316         MT_Vector3              m_ang_mom;               // Angular momentum (angualr velocity times inertia)
317         MT_Vector3              m_force;                 // Force on center of mass (afffects linear momentum)
318         MT_Vector3              m_torque;                // Torque around center of mass (affects angualr momentum)
319         
320         MT_Vector3              m_error;                 // Error in position:- amount object must be moved to prevent intersection with scene
321
322         // Here are the values of externally set linear and angular
323         // velocity. These are updated from the outside
324         // (actuators and python) each frame and combined with the
325         // physics values. At the end of each frame (at the end of a
326         // call to proceed) they are set to zero. This allows the
327         // outside world to contribute to the velocity of an object
328         // but still have it react to physics. 
329
330         MT_Vector3                              m_combined_lin_vel;
331         MT_Vector3                              m_combined_ang_vel;
332
333         // The force and torque are the accumulated forces and torques applied by the client (game logic, python).
334
335         SM_FhObject            *m_fh_object;             // The ray object used for Fh
336         bool                    m_suspended;             // Is this object frozen?
337 };
338
339 #endif
340