00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef __RBD_Solver__
00016 #define __RBD_Solver__
00017
00018 #include "RBD_API.h"
00019
00020 #include <SIM/SIM_Collider.h>
00021 #include <SIM/SIM_Isect.h>
00022 #include <SIM/SIM_OptionsUser.h>
00023 #include <SIM/SIM_Solver.h>
00024 #include <GU/GU_SDF.h>
00025
00026 #include "RBD_Object.h"
00027 #include "RBD_Utils.h"
00028
00029 class SIM_Object;
00030 class SIM_Random;
00031 class SIM_SDF;
00032 class RBD_State;
00033 class RBD_ContactGraph;
00034 class RBD_ObjectTree;
00035
00036
00037 #define RBD_NAME_COLLISIONITERATIONS "collisioniterations"
00038 #define RBD_NAME_CONTACTITERATIONS "contactiterations"
00039 #define RBD_NAME_SUBCONTACTITERATIONS "subcontactiterations"
00040 #define RBD_NAME_SHOCKPROPAGATION "shockpropagation"
00041 #define RBD_NAME_USEEDGES "useedges"
00042 #define RBD_NAME_FLAGPENETRATION "flagpenetration"
00043 #define RBD_NAME_MINIMUMSUBSTEPS "minimumsubsteps"
00044 #define RBD_NAME_MAXIMUMSUBSTEPS "maximumsubsteps"
00045 #define RBD_NAME_CFLCOND "cflcond"
00046 #define RBD_NAME_RESOLVEPENETRATION "resolvepenetration"
00047 #define RBD_NAME_GLUEIGNORESRESTING "glueignoresrestingobjects"
00048
00049
00050
00051 class RBD_API RBD_Solver : public SIM_Solver,
00052 public SIM_OptionsUser
00053 {
00054 public:
00055 GETSET_DATA_FUNCS_I(RBD_NAME_COLLISIONITERATIONS, CollisionIterations)
00056 GETSET_DATA_FUNCS_I(RBD_NAME_CONTACTITERATIONS, ContactIterations)
00057 GETSET_DATA_FUNCS_I(RBD_NAME_SUBCONTACTITERATIONS, SubContactIterations)
00058 GETSET_DATA_FUNCS_I(RBD_NAME_SHOCKPROPAGATION, ShockPropagation)
00059 GETSET_DATA_FUNCS_I(RBD_NAME_RESOLVEPENETRATION, ResolvePenetrations)
00060 GETSET_DATA_FUNCS_B(RBD_NAME_FLAGPENETRATION, FlagPenetration);
00061 GETSET_DATA_FUNCS_B(RBD_NAME_GLUEIGNORESRESTING, GlueIgnoresRestingObjects);
00062 GETSET_DATA_FUNCS_B(RBD_NAME_USEPOINTVELOCITY, UsePointVelocity);
00063 GETSET_DATA_FUNCS_B(RBD_NAME_USESDFVELOCITY, UseSDFVelocity);
00064 GETSET_DATA_FUNCS_I(RBD_NAME_CULLMODE, CullMode);
00065
00066 GETSET_DATA_FUNCS_B(RBD_NAME_ADDIMPACTS, AddImpacts);
00067 GETSET_DATA_FUNCS_I(RBD_NAME_CONTACTGROUPMETHOD, ContactGroupMethod);
00068 GETSET_DATA_FUNCS_F(RBD_NAME_CONTACTGROUPTOL, ContactGroupTol);
00069
00070 GET_DATA_FUNC_I(RBD_NAME_MINIMUMSUBSTEPS, MinimumSubSteps);
00071 GET_DATA_FUNC_I(RBD_NAME_MAXIMUMSUBSTEPS, MaximumSubSteps);
00072 GET_DATA_FUNC_F(RBD_NAME_CFLCOND, CFLCond);
00073
00074
00075 bool doObjectsCollide(RBD_Object *obja,
00076 RBD_Object *objb,
00077 const SIM_Time &time,
00078 const SIM_Time ×tep) const;
00079
00080
00081
00082 RBD_ObjectTree *createObjectTree() const;
00083
00084
00085
00086
00087
00088 RBD_Object *convertToRBDObject(const SIM_Object *obj) const;
00089
00090
00091
00092 enum rbdContactGroupMethod
00093 {
00094 CONTACTGROUP_NONE = 0,
00095 CONTACTGROUP_CLOSESTPOINT,
00096 CONTACTGROUP_AVERAGE
00097 };
00098
00099 protected:
00100 explicit RBD_Solver(const SIM_DataFactory *factory);
00101 virtual ~RBD_Solver();
00102
00103 virtual SIM_Result solveObjectsSubclass(SIM_Engine &engine,
00104 SIM_ObjectArray &objects,
00105 SIM_ObjectArray &newobjects,
00106 SIM_ObjectArray &feedbacktoobjects,
00107 const SIM_Time ×tep);
00108 virtual void getImpulseMassMatrixSubclass(
00109 const SIM_Object &object,
00110 const UT_Vector3 &impulseworldpos,
00111 UT_DMatrix3 &immatrix) const;
00112 virtual void getPointImpulseMassMatrixSubclass(
00113 const SIM_Object &object,
00114 int ptnum, UT_DMatrix3 &immatrix) const;
00115 virtual fpreal getPropertyAtPositionSubclass(const SIM_Object &object,
00116 const UT_Vector3 &worldspacepos,
00117 const SIM_Property &property) const;
00118 virtual fpreal getPropertyAtPointSubclass(const SIM_Object &object,
00119 int ptnum, const SIM_Property &property) const;
00120 virtual void getDefaultColliderLabelSubclass(
00121 const SIM_Object &object,
00122 UT_String &label) const;
00123 virtual void getDefaultColliderSubclass(
00124 const SIM_Object &object,
00125 const UT_String &colliderlabel,
00126 UT_String &collidertype,
00127 bool &colliderreverseobjectroles) const;
00128
00129 private:
00130 static const SIM_DopDescription *getSolverRBDDopDescription();
00131
00132
00133 fpreal getPropertyFromState(const SIM_Object &object,
00134 const SIM_Property &property) const;
00135
00136
00137 void solveStackObjects(SIM_ObjectArray &objects,
00138 SIM_ObjectArray &newobjects,
00139 const SIM_Time &time,
00140 const SIM_Time ×tep);
00141
00142
00143
00144
00145
00146 SIM_Random *createRandomData();
00147
00148
00149
00150 bool resolveContactForces(const RBD_ContactGraph &graph,
00151 const RBD_ObjectArray &objects,
00152 const SIM_Time &time,
00153 const SIM_Time ×tep,
00154 bool applyshock) const;
00155
00156
00157
00158
00159
00160
00161
00162
00163 bool resolvePenetrations(const RBD_ContactGraph &graph,
00164 const UT_PtrArray<RBD_Object *> &objects,
00165 const SIM_Time &time,
00166 const SIM_Time ×tep) const;
00167
00168
00169
00170
00171 bool fixPenetrations(RBD_Object *obj, RBD_Object *rest,
00172 const SIM_Collider *collider,
00173 fpreal restitution,
00174 const SIM_Time time,
00175 const SIM_Time timestep) const;
00176
00177
00178
00179 bool resolveElasticCollisions(RBD_ObjectArray &objects,
00180 const SIM_Time &time,
00181 const SIM_Time ×tep) const;
00182
00183
00184
00185 void resolvePinConstraintVelocities(RBD_Object *obj) const;
00186
00187
00188
00189
00190
00191
00192 void shockPropagatePinConstraints(const RBD_ObjectArray &objects) const;
00193
00194
00195
00196
00197
00198
00199 bool elasticCollide(RBD_Object *obj_a, RBD_Object *obj_b,
00200 bool infinitemass,
00201 fpreal restitution,
00202 bool onlyfirst,
00203 bool usebounce,
00204 const SIM_Time time,
00205 const SIM_Time timestep,
00206 const SIM_Collider *collider,
00207 SIM_Collider::SIM_ImpactApplyType affectortype) const;
00208
00209
00210
00211 SIM_Isect *groupContacts(SIM_IsectPriorityQueue &queue,
00212 RBD_Object *obj_a,
00213 RBD_Object *obj_b,
00214 bool infinitemass) const;
00215
00216
00217
00218
00219 bool collidePoint(RBD_Object *obj_a, RBD_Object *obj_b,
00220 bool infinitemass,
00221 const SIM_Isect *isect,
00222 fpreal restitution,
00223 bool usebounce,
00224 const SIM_Time curtime,
00225 bool usesdfvel,
00226 bool usepointvel,
00227 int child_id_a = -1,
00228 int child_id_b = -1) const;
00229
00230
00231
00232
00233
00234
00235
00236 bool findClosestChild(RBD_Object *obj,
00237 const UT_Vector3 &pos,
00238 RBD_Object *&closest, fpreal &mindist,
00239 bool onlytoplevel = false,
00240 int child_id = -1) const;
00241
00242
00243
00244
00245
00246
00247
00248
00249 void applyCollisionImpulse(RBD_Object *obj_a,
00250 RBD_Object *obj_b,
00251 int obj_b_id,
00252 fpreal scale,
00253 const UT_Vector3 &pos,
00254 const UT_Vector3 &impulse,
00255 const SIM_Time curtime,
00256 int child_id_a,
00257 int child_id_b,
00258 bool infiniteforceVSinfinitemass,
00259 bool restingcollision) const;
00260
00261
00262
00263
00264 void addImpactData(RBD_Object *obj_a,
00265 RBD_Object *obj_b,
00266 int obj_b_id,
00267 const UT_Vector3 &pos,
00268 const UT_Vector3 &nml,
00269 fpreal strength,
00270 const SIM_Time curtime,
00271 bool restingcollision) const;
00272
00273
00274 bool collideObjects (RBD_Object *obj_a, RBD_Object *obj_b,
00275 const SIM_Time startTime,
00276 const SIM_Time endTime,
00277 SIM_Collider::SIM_ImpactApplyType affectortype) const;
00278
00279 SIM_Time getCurSolveTime() const
00280 { return myCurSolveTime; }
00281 void setCurSolveTime(SIM_Time time)
00282 { myCurSolveTime = time; }
00283 SIM_Time getCurSolveStep() const
00284 { return myCurSolveStep; }
00285 void setCurSolveStep(SIM_Time step)
00286 { myCurSolveStep = step; }
00287
00288 bool doAddImpacts() const
00289 { return myAddImpacts; }
00290 bool doGlueIgnoresResting() const
00291 { return myGlueIgnoresResting; }
00292
00293 DECLARE_STANDARD_GETCASTTOTYPE();
00294 DECLARE_DATAFACTORY(RBD_Solver,
00295 SIM_Solver,
00296 "RBD Solver",
00297 getSolverRBDDopDescription());
00298
00299 private:
00300
00301
00302
00303
00304 mutable bool myBreakOccurred;
00305
00306
00307
00308
00309
00310 mutable bool myAddImpacts;
00311 mutable bool myGlueIgnoresResting;
00312
00313
00314 SIM_Time myCurSolveTime;
00315 SIM_Time myCurSolveStep;
00316
00317 SIM_Engine *myEngine;
00318 };
00319
00320 #endif
00321