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