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
|
/**
* $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?
};
/**
* 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
);
void *getClientObject() { return m_client_object; }
void setClientObject(void *client_object) { m_client_object = client_object; }
void relax();
void backup() {
m_pos = m_prev_state.getPosition();
m_orn = m_prev_state.getOrientation();
m_xform = m_prev_xform;
}
private:
// 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
void *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
|