接著上文繼續學習ode物理引擎的函數和數據結構O(∩_∩)O~
15.剛體對象的啟用和禁止
剛體對象可以被啟用或者禁止
禁止剛體對象則在仿真過程中剛體不參與仿真
如果啟用自禁止的話,那么剛體對象會在給定仿真步中idle(如何翻譯?)
如果啟用自動禁止的話,那么當剛體線速度和角速度同時小于給定閾值之時被禁止
1 void dBodyEnable (dBodyID);
2 void dBodyDisable (dBodyID);
3 int dBodyIsEnabled (dBodyID);
4 void dBodySetAutoDisableFlag (dBodyID, int do_auto_disable);
5 int dBodyGetAutoDisableFlag (dBodyID);
1
void dBodySetAutoDisableAngularThreshold (dBodyID, dReal angular_threshold);
2
dReal dBodyGetAutoDisableAngularThreshold (dBodyID);
3
void dBodySetAutoDisableLinearThreshold (dBodyID, dReal linear_threshold);
4
dReal dBodyGetAutoDisableLinearThreshold (dBodyID);
需要確保的是線速度和角速度要小于給定的閾值
16.幾個雜項函數
1 void dBodySetData (dBodyID, void *data);
2 void *dBodyGetData (dBodyID);
設置,和獲取剛體數據
1 int dBodyGetNumJoints (dBodyID b);
獲取關聯到物體上的關節個數
1 dJointID dBodyGetJoint (dBodyID, int index);
獲取給物體上定標號的關節句柄
1 void dBodySetGravityMode (dBodyID b, int mode);
2 int dBodyGetGravityMode (dBodyID b);
設置和獲取物體是否受重力影響(默認為是)
1 void dMakeRandomVector (dReal *A, int n, dReal range);
獲取n個范圍在+-rang中的隨機變量
17.矩陣操作
-- 在任何引擎中矩陣都是必不可少的
1 void dRSetIdentity (dMatrix3 R);
2 void dRFromAxisAndAngle (dMatrix3 R, dReal ax, dReal ay, dReal az,dReal angle);
3 void dRFromEulerAngles (dMatrix3 R, dReal phi, dReal theta, dReal psi);
4 void dRFrom2Axes (dMatrix3 R, dReal ax, dReal ay, dReal az,dReal bx, dReal by, dReal bz);
5 void dRFromZAxis (dMatrix3 R, dReal ax, dReal ay, dReal az);
6 void dQSetIdentity (dQuaternion q);
7 void dQFromAxisAndAngle (dQuaternion q, dReal ax, dReal ay, dReal az,dReal angle);
8 void dQMultiply0 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
9 void dQMultiply3 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
10 void dRfromQ (dMatrix3 R, const dQuaternion q);
11 void dQfromR (dQuaternion q, const dMatrix3 R);
12 void dDQfromW (dReal dq[4], const dVector3 w, const dQuaternion q);
這些函數為別是:
設置為單位矩陣,
從給定軸和角度或者矩陣
從歐拉角到矩陣
...
18.ode關節
1 dJointID dJointCreateBall (dWorldID, dJointGroupID);
2 dJointID dJointCreateHinge (dWorldID, dJointGroupID);
3 dJointID dJointCreateSlider (dWorldID, dJointGroupID);
4 dJointID dJointCreateContact (dWorldID, dJointGroupID,
5 const dContact *);
6 dJointID dJointCreateUniversal (dWorldID, dJointGroupID);
7 dJointID dJointCreateHinge2 (dWorldID, dJointGroupID);
8 dJointID dJointCreateFixed (dWorldID, dJointGroupID);
9 dJointID dJointCreateAMotor (dWorldID, dJointGroupID);
10 void dJointDestroy (dJointID);
可以看出ode中定義的關機類型有Ball,Hinge,Slider,...
對關節的銷毀動作為斷開所有連接的引擎物體,再銷毀關節
1 dJointGroupID dJointGroupCreate (int max_size);
2 void dJointGroupDestroy (dJointGroupID);
3 void dJointGroupEmpty (dJointGroupID);
4
第一個函數中的max_size目前必須是(0)這是為了和以前兼容
銷毀關節和清空關節點區別在于銷毀會銷毀關節組中所有的關節對象和銷毀關節組,而清空關節組則只是銷毀所有的關節對象
1 void dJointAttach (dJointID, dBodyID body1, dBodyID body2);
使用給定關節連接2個物理對象,如果關節先前是連接的則斷開之,如果body1或者body2有1個為0則說明把對象連接對靜態環境中去
1 void dJointSetData (dJointID, void *data);
2 void *dJointGetData (dJointID);
設置關節數據沒什么好說的
1 int dJointGetType (dJointID);
獲取給定關節的關節類型
可能的類型有
dJointTypeBall A ball-and-socket joint.
dJointTypeHinge A hinge joint.
dJointTypeSlider A slider joint.
dJointTypeContact A contact joint.
dJointTypeUniversal A universal joint.
dJointTypeHinge2 A hinge-2 joint.
dJointTypeFixed A fixed joint.
dJointTypeAMotor An angular motor joint.
1 dBodyID dJointGetBody (dJointID, int index);
獲取關節給定索引的連接物理對象(以0索引起始)
1 int dAreConnected (dBodyID, dBodyID);
檢測2個問題是不是別連接了
19.關節接觸;
ode用戶指南的原文是:
The contact joint prevents body 1 and body 2 from inter-penetrating at the contact point. It does this by
only allowing the bodies to have an "outgoing "velocity in the direction of the contact normal. Contact joints
typically have a lifetime of one time step. They are created and deleted in response to collision detection.
Contact joints can simulate friction at the contact by applying special forces in the two friction directions
that are perpendicular to the normal.When a contact joint is created, a dContact structure must be supplied. This has the following definition:
接觸關節預防碰撞對象的"刺穿"問題,當接觸關節產生的時候,其必要的數據元素必須被標記
1 struct dContact {
2 dSurfaceParameters surface;
3 dContactGeom geom;
4 dVector3 fdir1;
5 };
goem是碰撞函數設置的數據結構其中包含了:
碰撞點,碰撞法向矢量和碰撞的2個對象id
而fdir是第一摩擦力方向(其方向和摩擦力方向是相同的),同時也是垂直于接觸面法向矢量的.
當且僅當surface.mode = dContactFDir1時期需要被定義
而第二摩擦力方向則是由第一摩擦里方向和接觸面方向矢量計算的正交向量
其中的dSurfaceParameters surface是由用戶設置的數據結構
其數據結構為:
1 typedef struct dSurfaceParameters {
2 /* must always be defined */
3 int mode;
4 dReal mu;
5
6 /* only defined if the corresponding flag is set in mode */
7 dReal mu2;
8 dReal bounce;
9 dReal bounce_vel;
10 dReal soft_erp;
11 dReal soft_cfm;
12 dReal motion1,motion2;
13 dReal slip1,slip2;
14 } dSurfaceParameters;
其中的mode必須被標記
mu和mu2取值為(0 to dInfinity.)
如果沒有設置mu2,則使用mu為2個摩擦力方向
如果設置了mu2則使用mu為第一個摩擦力方向使用mu2為第二摩擦力方向
如果設置了fdir1則使用fdir作為第一摩擦力方向要不然則自動獲取其值
bounce表明其為彈性表面也就是說碰撞對象會相互彈起(取值0-1)0標明完全沒有彈性
soft_erp控制的是接觸表面的erp,這個值可以設置柔性表面
soft_cfm控制的是柔性表面的最大cfm
其他參數以后再介紹之
20.幾何體對象
幾何體是檢測系統中的基本單元
幾何體的銷毀和生成
1 void dGeomDestroy (dGeomID);
2 void dGeomSetData (dGeomID, void *);
3 void *dGeomGetData (dGeomID);
4 void dGeomSetBody (dGeomID, dBodyID);
5 dBodyID dGeomGetBody (dGeomID);
6 void dGeomSetPosition (dGeomID, dReal x, dReal y, dReal z);
7 void dGeomSetRotation (dGeomID, const dMatrix3 R);
8 void dGeomSetQuaternion (dGeomID, const dQuaternion);
9 const dReal * dGeomGetPosition (dGeomID);
10 const dReal * dGeomGetRotation (dGeomID);
11 void dGeomGetQuaternion (dGeomID, dQuaternion result);
12 void dGeomGetAABB (dGeomID, dReal aabb[6]);
13 int dGeomIsSpace (dGeomID);
14 dSpaceID dGeomGetSpace (dGeomID);
其中有幾何體的銷毀,設置幾何體數據,關聯幾何體到缸體
設置,獲取幾何體旋轉,
獲取幾何體aabb盒子以及檢測幾何體是否在空間中
1 int dGeomGetClass (dGeomID);
這是獲取幾何體類型的函數其取值為:
dSphereClass Sphere
dBoxClass Box
dCCylinderClass Capped cylinder
dCylinderClass Regular flat-ended cylinder
dPlaneClass Infinite plane (non-placeable)
dGeomTransformClass Geometry transform
dRayClass Ray
dTriMeshClass Triangle mesh
dSimpleSpaceClass Simple space
dHashSpaceClass Hash table based space
int dGeomGetClass (dGeomID);
下面的是幾何體的禁止和啟用
1 void dGeomEnable (dGeomID);
2 void dGeomDisable (dGeomID);
3 int dGeomIsEnabled (dGeomID);
如果幾何體被禁止那么他就不會才與碰撞(盡管它在物理空間中)
該篇就到這里吧,這里給出一個典型的接觸面設置:
1 surface.mode = dContactBounce | dContactSoftCFM;
2 surface.mu = dInfinity;
3 surface.mu2 = 0;
4 surface.bounce = 0.01;
5 surface.bounce_vel = 0.1;
6 surface.soft_cfm = 0.01;
可以看出他是使用了接觸面彈起
其第一摩擦力方向和第二摩擦力方向是相同的