00001 #ifndef IPSA_SOWORLDPHYSICS_H
00002 #define IPSA_SOWORLDPHYSICS_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00027 #include "IPSA.h"
00028 #include "SoCollisionShape.h"
00029
00030 #include <Inventor/nodes/SoSeparator.h>
00031 #include <Inventor/actions/SoCallbackAction.h>
00032 #include <Inventor/sensors/SoTimerSensor.h>
00033 #include <Inventor/sensors/SoFieldSensor.h>
00034 #include <Inventor/fields/SoSFFloat.h>
00035 #include <Inventor/fields/SoSFInt32.h>
00036 #include <Inventor/fields/SoSFVec3f.h>
00037 #include <Inventor/fields/SoSFBool.h>
00038 #include <Inventor/fields/SoSFTrigger.h>
00039 #include <ode/ode.h>
00040
00041 #include <vector>
00042
00043 class IPSA_IMPORT_EXPORT SoWorldPhysics : public SoSeparator
00044 {
00045
00046 SO_NODE_HEADER(SoWorldPhysics);
00047
00048 public:
00049 SoWorldPhysics(const SbString& nodeName = "", int numChildren = 5);
00050
00051 virtual ~SoWorldPhysics();
00052
00053 static void initClasses();
00054 static void initClass();
00055 static void Init();
00056 static void DeInit();
00057
00058 virtual SbBool setUpConnections(SbBool onOff, SbBool doItAlways = FALSE);
00059 virtual SbBool readInstance(SoInput* in, unsigned short flags);
00060
00061 static SoCallbackAction::Response InitialiseWorldCB(void* userdata, SoCallbackAction*, const SoNode* node);
00062 static SoCallbackAction::Response ScheduleWorldCB(void* userdata, SoCallbackAction*, const SoNode* node);
00063 static SoCallbackAction::Response UnscheduleWorldCB(void* userdata, SoCallbackAction*, const SoNode* node);
00064 static SoCallbackAction::Response UpdateSingleWorldCB(void*, SoCallbackAction* action, const SoNode* node);
00065 static SoCallbackAction::Response ResetWorldCB(void* userdata, SoCallbackAction* action, const SoNode* node);
00066
00067 static void NearCallback (void* data, dGeomID o1, dGeomID o2);
00068 static void StepOde(void* data, SoSensor*);
00069 static void ApplyActionToWorldPhysicNodesInGraph(SoCallbackAction::SoCallbackActionCB &cb, SoNode* root, void* userdata=NULL);
00070
00071 void initialiseWorld();
00072 void resetWorld();
00073 void setStepsize(float stepSizeInSeconds);
00074 float getStepsize();
00075 void schedule();
00076 void unschedule();
00077 bool isScheduled() {return (this->sens.isScheduled() == TRUE);}
00078
00079 static bool IsNaN (double value);
00080
00081 dWorldID ownworld;
00082 dSpaceID ownspace;
00083
00084 SoSFVec3f gravity;
00085 SoSFFloat ERP;
00086 SoSFFloat CFM;
00087 SoSFFloat SoftERP;
00088 SoSFFloat SoftCFM;
00089
00090 enum eContactApprox
00091 {
00092 BOXFRICTION = dContactApprox0,
00093 PYRAMIDFRICTION = dContactApprox1_1
00094 };
00095
00096 SoSFEnum ContactApprox;
00097 dJointGroupID contactgroup;
00098
00099
00100 enum eStepping
00101 {
00102 WORLDSTEP,
00103 QUICKSTEP,
00104 STEPFAST1
00105 };
00106 SoSFEnum stepping;
00107 SoSFInt32 sf1maxiterations;
00108
00109 const int MAX_BODY_CONTACTS;
00110 const float DEFAULT_ODE_STEPSIZE;
00111
00112 protected:
00113 SoSFTrigger updateOdeParamtersTrigger;
00114 SoFieldSensor updateOdeParamtersSensor;
00115 SbBool connectionsSetUp;
00116
00117 private:
00118 static void updateOdeParamtersCB(void* data, SoSensor*);
00119
00120 SoSFFloat stepsize;
00121 SoTimerSensor sens;
00122 std::vector<dJointFeedback> iContactFeedback;
00123
00124 static bool bOdeColliderInitialised;
00125 static bool bClassesInitialised;
00126
00127 static double frictioncoeff[SoCollisionShape::NO_OF_SURFACEMATERIALS][SoCollisionShape::NO_OF_SURFACEMATERIALS];
00128 };
00129
00130 #endif