Welcome to mirror list, hosted at ThFree Co, Russian Federation.

SM_Object.h « include « Fuzzics « Sumo « Physics « gameengine « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: b37e1a5466b0d4848ed7572c933d614176272331 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
/**
 * $Id$
 *
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version. The Blender
 * Foundation also sells licenses for use in proprietary software under
 * the Blender License.  See http://www.blender.org/BL/ for information
 * about this.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 * All rights reserved.
 *
 * The Original Code is: all of this file.
 *
 * Contributor(s): none yet.
 *
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
 */
#ifndef SM_OBJECT_H
#define SM_OBJECT_H

#include <vector>

#include <SOLID/SOLID.h>

#include "SM_Callback.h"
#include "SM_MotionState.h"
#include <stdio.h>

class SM_FhObject;

/** Properties of dynamic objects */
struct SM_ShapeProps {
	MT_Scalar  m_mass;                  ///< Total mass
	MT_Scalar  m_radius;                ///< Bound sphere size
	MT_Vector3 m_inertia;               ///< Inertia, should be a tensor some time 
	MT_Scalar  m_lin_drag;              ///< Linear drag (air, water) 0 = concrete, 1 = vacuum 
	MT_Scalar  m_ang_drag;              ///< Angular drag
	MT_Scalar  m_friction_scaling[3];   ///< Scaling for anisotropic friction. Component in range [0, 1]   
	bool       m_do_anisotropic;        ///< Should I do anisotropic friction? 
	bool       m_do_fh;                 ///< Should the object have a linear Fh spring?
	bool       m_do_rot_fh;             ///< Should the object have an angular Fh spring?
};


/** Properties of collidable objects (non-ghost objects) */
struct SM_MaterialProps {
	MT_Scalar m_restitution;           ///< restitution of energy after a collision 0 = inelastic, 1 = elastic
	MT_Scalar m_friction;              ///< Coulomb friction (= ratio between the normal en maximum friction force)
	MT_Scalar m_fh_spring;             ///< Spring constant (both linear and angular)
	MT_Scalar m_fh_damping;            ///< Damping factor (linear and angular) in range [0, 1]
	MT_Scalar m_fh_distance;           ///< The range above the surface where Fh is active.    
	bool      m_fh_normal;             ///< Should the object slide off slopes?
};

class SM_ClientObject
{
public:
	SM_ClientObject() {}
	virtual ~SM_ClientObject() {}
	
	virtual bool hasCollisionCallback() = 0;
};

/**
 * SM_Object is an internal part of the Sumo physics engine.
 *
 * It encapsulates an object in the physics scene, and is responsible
 * for calculating the collision response of objects.
 */
class SM_Object : public SM_MotionState {
public:
	SM_Object() ;
	SM_Object(
		DT_ShapeHandle shape, 
		const SM_MaterialProps *materialProps,
		const SM_ShapeProps *shapeProps,
		SM_Object *dynamicParent
	);
	virtual ~SM_Object();

	bool isDynamic() const;  

	/* nzc experimental. There seem to be two places where kinematics
	 * are evaluated: proceedKinematic (called from SM_Scene) and
	 * proceed() in this object. I'll just try and bunge these out for
	 * now.  */

	void suspend(void);
	void resume(void);

	void suspendDynamics();
	
	void restoreDynamics();
	
	bool isGhost() const;

	void suspendMaterial();
	
	void restoreMaterial();
	
	SM_FhObject *getFhObject() const;
	
	void registerCallback(SM_Callback& callback);

	void calcXform();
	void notifyClient();
	void updateInvInertiaTensor();

    
	// Save the current state information for use in the 
	// velocity computation in the next frame.  

	void proceedKinematic(MT_Scalar timeStep);

	void saveReactionForce(MT_Scalar timeStep) ;
	
	void clearForce() ;

	void clearMomentum() ;
	
	void setMargin(MT_Scalar margin) ;
	
	MT_Scalar getMargin() const ;
	
	const SM_MaterialProps *getMaterialProps() const ;
	
	const SM_ShapeProps *getShapeProps() const ;
	
	void setPosition(const MT_Point3& pos);
	void setOrientation(const MT_Quaternion& orn);
	void setScaling(const MT_Vector3& scaling);
	
	/**
	 * set an external velocity. This velocity complements
	 * the physics velocity. So setting it does not override the
	 * physics velocity. It is your responsibility to clear 
	 * this external velocity. This velocity is not subject to 
	 * friction or damping.
	 */
	void setExternalLinearVelocity(const MT_Vector3& lin_vel) ;
	void addExternalLinearVelocity(const MT_Vector3& lin_vel) ;

	/** Override the physics velocity */
	void addLinearVelocity(const MT_Vector3& lin_vel);
	void setLinearVelocity(const MT_Vector3& lin_vel);

	/**
	 * Set an external angular velocity. This velocity complemetns
	 * the physics angular velocity so does not override it. It is
	 * your responsibility to clear this velocity. This velocity
	 * is not subject to friction or damping.
	 */
	void setExternalAngularVelocity(const MT_Vector3& ang_vel) ;
	void addExternalAngularVelocity(const MT_Vector3& ang_vel);

	/** Override the physics angular velocity */
	void addAngularVelocity(const MT_Vector3& ang_vel);
	void setAngularVelocity(const MT_Vector3& ang_vel);

	/** Clear the external velocities */
	void clearCombinedVelocities();

	/** 
	 * Tell the physics system to combine the external velocity
	 * with the physics velocity. 
	 */
	void resolveCombinedVelocities(
		const MT_Vector3 & lin_vel,
		const MT_Vector3 & ang_vel
	) ;



	MT_Scalar getInvMass() const;

	const MT_Vector3& getInvInertia() const ;
	
	const MT_Matrix3x3& getInvInertiaTensor() const;

	void applyForceField(const MT_Vector3& accel) ;
	
	void applyCenterForce(const MT_Vector3& force) ;
	
	void applyTorque(const MT_Vector3& torque) ;
	
	/**
	 * Apply an impulse to the object.  The impulse will be split into
	 * angular and linear components.
	 * @param attach point to apply the impulse to (in world coordinates)
	 */
	void applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse) ;
	
	/**
	 * Applies an impulse through the centre of this object. (ie the angular
	 * velocity will not change.
	 */
	void applyCenterImpulse(const MT_Vector3& impulse);
	/**
	 * Applies an angular impulse.
	 */
	void applyAngularImpulse(const MT_Vector3& impulse);
	
	MT_Point3 getWorldCoord(const MT_Point3& local) const;
	MT_Point3 getLocalCoord(const MT_Point3& world) const;
    
	MT_Vector3 getVelocity(const MT_Point3& local) const;


	const MT_Vector3& getReactionForce() const ;

	void getMatrix(double *m) const ;

	const double *getMatrix() const ;

	// Still need this???
	const MT_Transform&  getScaledTransform()  const; 

	DT_ObjectHandle getObjectHandle() const ;
	DT_ShapeHandle getShapeHandle() const ;

	SM_Object *getDynamicParent() ;

	void integrateForces(MT_Scalar timeStep);
	void integrateMomentum(MT_Scalar timeSteo);

	void setRigidBody(bool is_rigid_body) ;

	bool isRigidBody() const ;

	// This is the callback for handling collisions of dynamic objects
	static 
		DT_Bool 
	boing(
		void *client_data,  
		void *object1,
		void *object2,
		const DT_CollData *coll_data
	);

	static 
		DT_Bool 
	fix(
		void *client_data,  
		void *object1,
		void *object2,
		const DT_CollData *coll_data
	);
	
	
	SM_ClientObject *getClientObject() { return m_client_object; }
	void setClientObject(SM_ClientObject *client_object) { m_client_object = client_object; }
	
	void relax();
	
private:
	// Tweak parameters
	static MT_Scalar ImpulseThreshold;

	// return the actual linear_velocity of this object this 
	// is the addition of m_combined_lin_vel and m_lin_vel.

	const 
		MT_Vector3
	actualLinVelocity(
	) const ;

	const 
		MT_Vector3
	actualAngVelocity(
	) const ;
	
	void dynamicCollision(const MT_Point3 &local2, 
		const MT_Vector3 &normal, 
		MT_Scalar dist, 
		const MT_Vector3 &rel_vel,
		MT_Scalar restitution,
		MT_Scalar friction_factor,
		MT_Scalar invMass
	);

	typedef std::vector<SM_Callback *> T_CallbackList;


	T_CallbackList          m_callbackList;    // Each object can have multiple callbacks from the client (=game engine)
	SM_Object              *m_dynamicParent;   // Collisions between parent and children are ignored

    // as the collision callback now has only information
	// on an SM_Object, there must be a way that the SM_Object client
	// can identify it's clientdata after a collision
	SM_ClientObject        *m_client_object;

	DT_ShapeHandle          m_shape;                 // Shape for collision detection

	// Material and shape properties are not owned by this class.

	const SM_MaterialProps *m_materialProps;         
	const SM_MaterialProps *m_materialPropsBackup;   // Backup in case the object temporarily becomes a ghost.
	const SM_ShapeProps    *m_shapeProps;           
	const SM_ShapeProps    *m_shapePropsBackup;      // Backup in case the object's dynamics is temporarily suspended
	DT_ObjectHandle         m_object;                // A handle to the corresponding object in SOLID.
	MT_Scalar               m_margin;                // Offset for the object's shape (also for collision detection)
	MT_Vector3              m_scaling;               // Non-uniform scaling of the object's shape

	double                  m_ogl_matrix[16];        // An OpenGL-type 4x4 matrix      
	MT_Transform            m_xform;                 // The object's local coordinate system
	MT_Transform            m_prev_xform;            // The object's local coordinate system in the previous frame
	SM_MotionState          m_prev_state;            // The object's motion state in the previous frame
	MT_Scalar               m_timeStep;              // The duration of the last frame 

	MT_Vector3              m_reaction_impulse;      // The accumulated impulse resulting from collisions
	MT_Vector3              m_reaction_force;        // The reaction force derived from the reaction impulse   

	unsigned int            m_kinematic      : 1;    // Have I been displaced (translated, rotated, scaled) in this frame? 
	unsigned int            m_prev_kinematic : 1;    // Have I been displaced (translated, rotated, scaled) in the previous frame? 
	unsigned int            m_is_rigid_body  : 1;    // Should friction give me a change in angular momentum?

	MT_Vector3              m_lin_mom;               // Linear momentum (linear velocity times mass)
	MT_Vector3              m_ang_mom;               // Angular momentum (angualr velocity times inertia)
	MT_Vector3              m_force;                 // Force on center of mass (afffects linear momentum)
	MT_Vector3              m_torque;                // Torque around center of mass (affects angualr momentum)
	
	MT_Vector3              m_error;                 // Error in position:- amount object must be moved to prevent intersection with scene

	// Here are the values of externally set linear and angular
	// velocity. These are updated from the outside
	// (actuators and python) each frame and combined with the
	// physics values. At the end of each frame (at the end of a
	// call to proceed) they are set to zero. This allows the
	// outside world to contribute to the velocity of an object
	// but still have it react to physics. 

	MT_Vector3				m_combined_lin_vel;
	MT_Vector3				m_combined_ang_vel;

	// The force and torque are the accumulated forces and torques applied by the client (game logic, python).

	SM_FhObject            *m_fh_object;             // The ray object used for Fh
	bool                    m_suspended;             // Is this object frozen?
	
	// Mass properties
	MT_Scalar               m_inv_mass;              // 1/mass
	MT_Vector3              m_inv_inertia;           // [1/inertia_x, 1/inertia_y, 1/inertia_z]
	MT_Matrix3x3            m_inv_inertia_tensor;    // Inverse Inertia Tensor
};

#endif