HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RBD_State.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  */
7 
8 #ifndef __RBD_State_h__
9 #define __RBD_State_h__
10 
11 #include "RBD_API.h"
12 #include "RBD_Utils.h"
13 #include <SIM/SIM_Motion.h>
14 #include <UT/UT_Matrix.h>
15 #include <UT/UT_Matrix3.h>
16 #include <UT/UT_Vector3Array.h>
17 
18 class GU_SDF;
19 class SIM_Object;
20 class SIM_ObjectArray;
21 class SIM_Constraint;
22 class RBD_Object;
23 class SIM_Geometry;
24 class SIM_Force;
25 
26 // This class contains basic state information that applies to rigid body
27 // objects, such as position and velocity, and some physical attributes.
29 {
30 public:
31  // Named access functions for getting at our data.
32  GETSET_DATA_FUNCS_M3(RBD_NAME_ITENSOR, InertialTensor);
33  GET_DATA_FUNC_M3(RBD_NAME_ITENSORLOCALINV, InertialTensorLocalInv);
38  ComputeInertialTensor);
40  ComputeInertialTensorType);
44  InertialTensorStiffness);
45 
50 
51  /// Updates our values based on a given SDF or Geometry.
52  /// If SDF is null, will use the geometry and assume a thin plate model.
53  /// This will update the mass, COM, and ITensor provided
54  /// the relevant compute flags are true.
55  /// It will also recalculate your linear & angular velocity from
56  /// the underlying geometry if inherit is turned on.
57  /// updatelinearvel controls whether the linear velocity should be updated
58  /// when computing the COM.
59  /// It has no effect on calculations for inheriting vel
60  void updatePhysicalValues(RBD_Object *obj,
61  const GU_SDF *sdf,
62  const SIM_Geometry *geo,
63  bool updatelinearvel);
64 
65  // Methods to calculate new values based on old values and a time step.
66 
67  /// Integrates the position of this object forward by a timestep.
68  /// The current velocity is treated as constant.
69  void getNewPosition(const SIM_Object &object,
70  const SIM_Time &time,
71  const SIM_Time &timestep,
72  UT_Vector3 &newpos,
73  UT_Quaternion &neworient) const;
74 
75  /// Integrates velocity forward by one timestep.
76  /// This will iterate over all forces and soft constraints
77  /// to construct the required acceleration & apply it.
78  void getNewVelocity(RBD_Object *object,
79  const SIM_Time &time,
80  const SIM_Time &timestep,
81  UT_Vector3 &newvel,
82  UT_Vector3 &newangvel) const;
83 
84  /// Integrates velocity forward by one timestep.
85  /// This uses the specified center of mass for sampling the
86  /// force function rather than the objects pivot.
87  void getNewVelocity(RBD_Object *object,
88  const SIM_Time &time,
89  const SIM_Time &timestep,
90  const UT_Vector3 &com,
91  UT_Vector3 &newvel,
92  UT_Vector3 &newangvel) const;
93 
94  /// Takes an array of points in space with associated velocities.
95  /// Computes the angular velocity and velocity that best matches
96  /// the given values. Each point/velocity pair is treated as
97  /// equally important.
98  /// Note that center of mass is only needed to compute the linear
99  /// component.
100  static void projectRigidMotion(
101  UT_Vector3 &vel,
102  UT_Vector3 &angvel,
103  const UT_Vector3 &com,
104  const UT_Vector3Array &posarray,
105  const UT_Vector3Array &velarray);
106 
107  /// Applies an impulse to this object. This results in an instantaneous
108  /// change in velocity.
109  const UT_Vector3 getNewVelocity(fpreal impulse,
110  const UT_Vector3 &normal) const;
111  const UT_Vector3 getNewAngularVelocity(fpreal impulse,
112  const UT_Vector3 &pos,
113  const UT_Vector3 &normal) const;
114 
115  /// Iterate over all hard constraints and constrain
116  /// the pos and orient to those constraints. The new values
117  /// are output in pos & orient.
118  /// Note you likely want to constrain with time' = (time + timestep)
119  /// if you solved with time.
120  void constrainPosition(SIM_Object &object,
121  const SIM_Time &time,
122  const SIM_Time &timestep,
123  UT_Vector3 &pos,
124  UT_Quaternion &orient) const;
125 
126  /// Determines the new pos and orient that best satisfies the set
127  /// of constraints. hard_objpos and hard_goal pos are both in world
128  /// coordinates. The new pos and orient should be such that the
129  /// change will map hard_objpos onto hard_goalpos.
130  void constrainAccordingToPositions(
131  const UT_Vector3Array &hard_objpos,
132  const UT_Vector3Array &hard_goalpos,
133  const UT_Matrix3 &hard_filter,
134  UT_Vector3 &pos,
135  UT_Quaternion &orient) const;
136 
137  /// Iterate over all the hard constraints and constraint
138  /// the velocity according to those constraints.
139  /// The new values are output in pos & orient.
140  /// Note you likely want to constrain with time' = (time + timestep)
141  /// if you solved with time.
142  /// This only resolves nail constraints. Pin constraints are
143  /// handled at the RBD_Solver level as they can affect other
144  /// objects.
145  void constrainVelocity(SIM_Object &object,
146  const SIM_ObjectArray &solvingobjects,
147  const SIM_Time &time,
148  const SIM_Time &timestep,
149  UT_Vector3 &vel,
150  UT_Vector3 &angvel) const;
151 
152  /// This utility method solves for the impulse required to
153  /// create induce the given relative velocity at the given point.
154  /// This does *not* take the current velocity into consideration!
155  /// If the returned impulse is applied, the new velocity at the
156  /// point would change by relative velocity.
157  UT_Vector3 solveForImpulse(const UT_Vector3 &pos,
158  const UT_Vector3 &relvel) const;
159 
160  /// These act as setPosition, setOrientation
161  /// and setVelocity, setAngularVelocity.
162  /// The main difference is that they will properly propagate to
163  /// frozen sub objects.
164  void changePosition(RBD_Object *obj,
165  const UT_Vector3 &pos,
166  const UT_Quaternion &orient);
167  void changeVelocity(RBD_Object *obj,
168  const UT_Vector3 &vel,
169  const UT_Vector3 &angvel);
170 
171  /// This changes the pivot point of the object to the new value.
172  /// The new value is given in object cooridinates!
173  /// This will adjust both Position and Pivot so the object's position
174  /// doesn't change as a result.
175  /// This also changes the inertial tensor to account for the new
176  /// "center of mass".
177  /// Changing the inertial tensor in this fashion is NOT invertible!
178  /// updatelinearvel controls whether the linear velocity should be updated
179  /// taking into account the angular velocity
180  void changePivot(const UT_Vector3 &pivot,
181  bool updatetensor,
182  bool updatelinearvel = true);
183 
184  /// These alert the frozen object to impulses, causing it
185  /// to break off if they become large enough.
186  void accumulateGlueImpulse(fpreal impulse);
187 
188  /// This decays the frozen impulse according to the given
189  /// timestep.
190  void decayGlueImpulse(SIM_Time timestep);
191 
192 protected:
193  explicit RBD_State(const SIM_DataFactory *factory);
194  ~RBD_State() override;
195 
196  /// Override setOrientation because we need to update our local
197  /// inertial tensor when we do this.
198  void optionChangedSubclass(const char *name) override;
199 
200  /// Determines what sort of freedom of movement is available
201  /// if the given constraints hold.
202  /// The obj list is the world coordinates of points on the geometry
203  /// The goal list is the world coordinates of where those points
204  /// should be.
205  /// This sets the objpos to where an impulse should be given.
206  /// goalpos is where objpos should be. Axis is the only axis
207  /// of rotation allowed. neworient specifies the required change
208  /// of orientation (in world space) for the FULL case.
209  enum constrainType { CON_NONE, CON_SINGLEPOINT, CON_AXIS, CON_FULL };
210 
211  constrainType findConstraintType(const UT_Vector3Array &geo,
212  const UT_Vector3Array &anchor,
213  UT_Vector3 &objpos,
214  UT_Vector3 &goalpos,
215  UT_Vector3 &objaxis,
216  UT_Vector3 &goalaxis,
217  UT_Quaternion &orient) const;
218 
219 private:
220  void updateInertialTensor();
221  static const SIM_DopDescription *getStateDopDescription();
222 
223  /// Iterate over all force subdata & add the forces into sumforces
224  /// and sumtorques.
225  void calculateForceForces(const RBD_Object *obj,
226  const UT_Vector3 &com,
227  UT_Vector3 &sumforces,
228  UT_Vector3 &sumtorques,
229  UT_Matrix &sumDfDx,
230  UT_Matrix &sumDfDv) const;
231 
232  /// Iterate over all soft constraints and adds the forces
233  /// that are created by those constraints.
234  void calculateConstraintForces(SIM_Object &object,
235  const UT_Vector3 &com,
236  const SIM_Time &time,
237  const SIM_Time &timestep,
238  UT_Vector3 &sumforces,
239  UT_Vector3 &sumtorques,
240  UT_Matrix &sumDfDx,
241  UT_Matrix &sumDfDv) const;
242  /// Iterate over all impacts in our feedback data to create forces.
243  void calculateImpactForces(RBD_Object *object,
244  const UT_Vector3 &com,
245  const SIM_Time &time,
246  const SIM_Time &timestep,
247  const char *impactsdataname,
248  UT_Vector3 &sumforces,
249  UT_Vector3 &sumtorques) const;
250 
251  /// Methods to calculate physical properties either from the SDF
252  /// or from geometry. The latter will assume a ThinPlate model.
253  fpreal computeMassFromSDF(const GU_SDF *sdf);
254  fpreal computeMassFromGeometry(const SIM_Geometry *geo);
255 
256  void computeCenterOfMassFromSDF(UT_Vector3 &com,
257  const GU_SDF *sdf);
258  void computeCenterOfMassFromGeometry(UT_Vector3 &com,
259  const SIM_Geometry *geo);
260 
261  void computeInertialTensorFromSDF(UT_DMatrix3 &tensor,
262  const UT_Vector3 &com,
263  const GU_SDF *sdf);
264  void computeInertialTensorFromGeometry(UT_DMatrix3 &tensor,
265  const UT_Vector3 &com,
266  const SIM_Geometry *geo);
267  fpreal computePrimMass(const GU_Detail *gdp,
268  const GEO_Primitive *prim) const;
269  UT_Vector3 computePrimBaryCenter(const GU_Detail *gdp,
270  const GEO_Primitive *prim) const;
271 
272  // Samples a force, querying the force for its optimal sampling
273  // metric and then invoking the proper sampleFooForce.
274  void sampleForce(const RBD_Object *obj,
275  const UT_Vector3 &com,
276  const SIM_Force *forcedata,
277  UT_Vector3 &sumforce,
278  UT_Vector3 &sumtorque,
279  UT_Matrix &sumDfDx,
280  UT_Matrix &sumDfDv) const;
281 
282  // Samples a force over the volume of this object.
283  void sampleVolumeForce(const RBD_Object *obj,
284  const UT_Vector3 &com,
285  const SIM_Force *forcedata,
286  UT_Vector3 &sumforce,
287  UT_Vector3 &sumtorque,
288  UT_Matrix &sumDfDx,
289  UT_Matrix &sumDfDv) const;
290  // Samples the force over the area of this object
291  void sampleAreaForce(const RBD_Object *obj,
292  const UT_Vector3 &com,
293  const SIM_Force *forcedata,
294  UT_Vector3 &sumforce,
295  UT_Vector3 &sumtorque,
296  UT_Matrix &sumDfDx,
297  UT_Matrix &sumDfDv) const;
298  // Samples the force over the given point sample.
299  void samplePointForce(const RBD_Object *obj,
300  const UT_Vector3 &com,
301  const SIM_Force *forcedata,
302  UT_Vector3 &sumforce,
303  UT_Vector3 &sumtorque,
304  UT_Matrix &sumDfDx,
305  UT_Matrix &sumDfDv) const;
306 
309  SIM_Motion,
310  "RBD State",
311  getStateDopDescription());
312 };
313 
314 #endif
315 
#define RBD_NAME_COMPUTEINERTIALTENSOR
Definition: RBD_Utils.h:24
#define RBD_NAME_ITENSOR
Definition: RBD_Utils.h:18
#define DECLARE_STANDARD_GETCASTTOTYPE()
Definition: SIM_DataUtils.h:50
#define RBD_NAME_INHERITVELOCITY
Definition: RBD_Utils.h:29
#define GETSET_DATA_FUNCS_B(DataName, FuncName)
GT_API const UT_StringHolder time
#define GETSET_DATA_FUNCS_S(DataName, FuncName)
#define RBD_NAME_GLUEOBJECT
Definition: RBD_Utils.h:30
GA_API const UT_StringHolder com
#define RBD_API
Definition: RBD_API.h:10
void optionChangedSubclass(const char *name) override
#define GETSET_DATA_FUNCS_F(DataName, FuncName)
Definition: GU_SDF.h:302
#define RBD_NAME_GLUETHRESHOLD
Definition: RBD_Utils.h:31
#define GETSET_DATA_FUNCS_M3(DataName, FuncName)
#define RBD_NAME_COMPUTEMASS
Definition: RBD_Utils.h:21
#define DECLARE_DATAFACTORY(DataClass, SuperClass, Description, DopParms)
Definition: SIM_DataUtils.h:63
#define RBD_NAME_ITENSORLOCALINV
Definition: RBD_Utils.h:19
This is the default implementation for standard motion data.
Definition: SIM_Motion.h:18
#define RBD_NAME_GLUEIMPULSEHALFLIFE
Definition: RBD_Utils.h:33
Holds pointers to a number of SIM_Object objects.
#define RBD_NAME_GLUEIMPULSE
Definition: RBD_Utils.h:32
#define GETSET_DATA_FUNCS_I(DataName, FuncName)
GLuint const GLchar * name
Definition: glcorearb.h:786
GA_API const UT_StringHolder orient
#define RBD_NAME_COMPUTECOM
Definition: RBD_Utils.h:23
#define GET_DATA_FUNC_M3(DataName, FuncName)
#define RBD_NAME_DENSITY
Definition: RBD_Utils.h:22
fpreal64 fpreal
Definition: SYS_Types.h:277
#define RBD_NAME_MASS
Definition: RBD_Utils.h:20
#define GET_DATA_FUNC_F(DataName, FuncName)
GA_API const UT_StringHolder pivot
#define RBD_NAME_INERTIALTENSORSTIFFNESS
Definition: RBD_Utils.h:26
#define RBD_NAME_COMPUTEINERTIALTENSORTYPE
Definition: RBD_Utils.h:25