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