本例子源于ode自帶的例子:demo_chain2
演示的是一個由小盒子構成的鏈子在受正弦力左右下的物理現象(當然還有重力因素).
其代碼如下:
1 //! 2010.03.03
2 /////////////////////////////////////////////////////
3 /// 蓋莫游戲引擎的物理引擎測試2
4 /////////////////////////////////////////////////////
5 #include <GEngine/Gaimo.hpp>
6
7 //! 定義立方體個數
8 #define NUM 9
9
10 #define SIDE 2.0f
11 #define MASS 1.0f
12
13 core::PhysicsEngine<dWorldID,dSpaceID,dJointGroupID,dGeomID> engine;
14 core::PhysicsBody<dBodyID,dGeomID,1> object[NUM];
15 dJointID joint[NUM-1];
16
17 //! 盒子表面紋理
18 int cubeid;
19
20 //! 檢測碰撞回調函數
21 static void nearCallback(void *data, dGeomID o1, dGeomID o2)
22 {
23 //! 獲取幾何體對于德物理對象
24 dBodyID b1 = dGeomGetBody(o1);
25 dBodyID b2 = dGeomGetBody(o2);
26 //! 如果物體是相連的則返回之
27 if(b1 && b2 && dAreConnected(b1,b2))
28 return;
29
30 dContact contact;
31 contact.surface.mode = 0;
32 contact.surface.mu = dInfinity;
33 //! 如果物體之間發生了碰撞則關聯之
34 if(dCollide (o1,o2,1,&contact.geom,sizeof(dContactGeom)))
35 {
36 dJointID c = dJointCreateContact(engine.GetWorld(),engine.GetContactGroup(),&contact);
37 dJointAttach (c,b1,b2);
38 }
39 }
40
41 void ShowGrid();
42 void SimLoop();
43
44 int main(int argc, char **argv)
45 {
46 //! 初始化引擎設備并得到設備指針
47 core::Device* device = core::InitDevice("蓋莫引擎物理場景測試2");
48 //! 得到引擎場景指針
49 core::RefPtr<core::SceneManager> scenemanager = device->GetSceneManager();
50 //! 得到引擎資源指針
51 core::ResourceManager* resourcemanager = device->GetResourceManager();
52
53 //! 獲取盒子圖形和紋理
54 core::RefPtr<core::Image> cubeimage = resourcemanager->GetImage("cube","..\\image//tile.tga");
55 core::RefPtr<core::Texture> cubetexture = resourcemanager->GetTexture("cube",cubeimage);
56 cubetexture->Bind();
57 cubeid = cubetexture->GetTextureId();
58
59 //! 獲取全局攝像機
60 core::RefPtr<core::Camera> camera = scenemanager->GetGlobalCamera(Vector3f(30,11,30),
61 Vector3f(0,0,0),
62 Vector3f(0,1,0));
63 camera->SetViewport(0,0,640,480);
64 camera->SetPerspective(50.0f,640.0f/480.0f,0.1f,1000.0f);
65 glClearDepth(1.0f);
66 glDepthFunc(GL_LEQUAL);
67 glEnable(GL_DEPTH_TEST);
68 glEnable(GL_CULL_FACE);
69 glShadeModel(GL_SMOOTH);
70 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
71
72 //! 設置空間重力加速度
73 engine.SetGravity(0,-0.8,0);
74 //! 設置空間平面
75 engine.SetPlane(0,1,0,0);
76 //! 加載碰撞檢測回調函數
77 engine.SetCollideCallBack(&nearCallback);
78
79 for(int i=0; i<NUM; i++)
80 {
81 dMass m;
82 object[i].body = dBodyCreate(engine.GetWorld());
83 dReal k = i*SIDE;
84 dBodySetPosition(object[i].body,k,k+0.8,k);
85 dMassSetBox(&m,1,SIDE,SIDE,SIDE);
86 dMassAdjust(&m,MASS);
87 dBodySetMass(object[i].body,&m);
88 dBodySetData(object[i].body,(void*)i);
89 object[i].geom[0] = dCreateBox(engine.GetSpace(),SIDE,SIDE,SIDE);
90 dGeomSetBody(object[i].geom[0],object[i].body);
91 }
92 for(int i=0; i< NUM-1; i++)
93 {
94 //! 必須確保生成關節的空間指針為空
95 joint[i] = dJointCreateBall(engine.GetWorld(),NULL);
96 dJointAttach(joint[i],object[i].body,object[i+1].body);
97 dReal k = (i+0.5)*SIDE;
98 dJointSetBallAnchor(joint[i],k,k+0.8,k);
99 }
100
101 BEGIN_LOOP(device)
102 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
103 glLoadIdentity();
104 camera->SetPerspective(45.0f,640.0f/480.0f,0.1f,1000.0f);
105 camera->Render();
106 //! 繪制網格
107 ShowGrid();
108 SimLoop();
109 END_LOOP(device)
110
111 device->Close();
112 device->Drop();
113
114 return 0;
115 }
116
117 void SimLoop()
118 {
119 static double angle = 0;
120 angle += 0.05;
121 dBodyAddForce(object[NUM-1].body,0,3*(sin(angle)+1.0),0);
122
123 engine.Simulation();
124
125 for (int i=0; i<NUM; i++)
126 {
127 dReal sides[3];
128 const dReal *pos;
129 const dReal *mat;
130 dGeomBoxGetLengths(object[i].geom[0], sides);
131 float dsides[] = {sides[0],sides[1],sides[2]};
132 pos = dGeomGetPosition(object[i].geom[0]);
133 float dpos[] = {pos[0],pos[1],pos[2]};
134 mat = dGeomGetRotation(object[i].geom[0]);
135 float dmat[] = {mat[0],mat[1],mat[2], mat[3],
136 mat[4],mat[5],mat[6], mat[7],
137 mat[8],mat[9],mat[10],mat[11]};
138 core::Render::RenderCube(cubeid,dpos,dmat,dsides);
139 }
140 }
141
142 //! 顯示地面網格
143 void ShowGrid()
144 {
145 glPushAttrib(GL_CURRENT_BIT);
146 glPushMatrix();
147 glColor3f(0,0,1);
148 glBegin(GL_QUADS);
149 glTexCoord2f(0.0f,0.0f);
150 glVertex3i(-50,0,-50);
151 glTexCoord2f(1.0f, 0.0f);
152 glVertex3i(50,0,-50);
153 glTexCoord2f(1.0f, 1.0f);
154 glVertex3i(50,0,50);
155 glTexCoord2f(0.0f, 1.0f);
156 glVertex3i(-50,0,50);
157 glEnd();
158
159 for(float i = -50; i <= 50; i += 1)
160 {
161 glBegin(GL_LINES);
162 glVertex3f(-50, 0, i);
163 glVertex3f(50, 0, i);
164 glVertex3f(i, 0, -50);
165 glVertex3f(i, 0, 50);
166 glEnd();
167 }
168 glPopMatrix();
169 glPopAttrib();
170 }
171
顯示圖片如下:

2.

需要說明的就是函數:
dJointCreateBall(world,space)
在一般情況下第二個參數也就是space必須是空值
再看其回調函數:
1 //! 檢測碰撞回調函數
2 static void nearCallback(void *data, dGeomID o1, dGeomID o2)
3 {
4 //! 獲取幾何體對于德物理對象
5 dBodyID b1 = dGeomGetBody(o1);
6 dBodyID b2 = dGeomGetBody(o2);
7 //! 如果物體是相連的則返回之
8 if(b1 && b2 && dAreConnected(b1,b2))
9 return;
10
11 dContact contact;
12 contact.surface.mode = 0;
13 contact.surface.mu = dInfinity;
14 //! 如果物體之間發生了碰撞則關聯之
15 if(dCollide (o1,o2,1,&contact.geom,sizeof(dContactGeom)))
16 {
17 dJointID c = dJointCreateContact(engine.GetWorld(),engine.GetContactGroup(),&contact);
18 dJointAttach (c,b1,b2);
19 }
20 }
其一般描述就是先有幾何體獲取其body句柄
如果為空則返回
再者說明如果body是連接在一起的應該如何處理
接下來局勢如何發生碰撞應該如何處理
最后看看其關節生成和鏈接:
1
2 joint[i] = dJointCreateBall(engine.GetWorld(),NULL);
3 dJointAttach(joint[i],object[i].body,object[i+1].body);
4 dReal k = (i+0.5)*SIDE;
5 dJointSetBallAnchor(joint[i],k,k+0.8,k);
首先是關節生成
其次是關節連接
其次是設置關節位置
ok