這是使用蓋莫游戲引擎做的基于ode物理引擎的摩擦力測試的小例子
代碼如下:
1 //! 2010.03.05
2 /////////////////////////////////////////////////////
3 /// 蓋莫游戲引擎蓋莫引擎物理場景測試3
4 /////////////////////////////////////////////////////
5 #include <GEngine/Gaimo.hpp>
6 using namespace std;
7
8 #define LENGTH 4
9 #define MASS 0.4
10 #define FORCE 0.6
11 #define MU 1.0
12 #define GRAVITY 9.8
13
14 //! 盒子紋理
15 int cubeid = 0;
16
17 dGeomID ground;
18 core::PhysicsEngine<dWorldID,dSpaceID,dJointGroupID,dBodyID,dGeomID> engine;
19 core::PhysicsBody<dBodyID,dGeomID,1> box[3];
20
21 //! 碰撞檢測回調函數
22 static void nearCallback(void *data, dGeomID o1, dGeomID o2);
23
24 //! 初始化物理場景
25 void Init();
26 //! 物理場景更新
27 void PhysicsLoop();
28
29 int main(int argc, char **argv)
30 {
31 Init();
32
33 //! 初始化引擎設備并得到設備指針
34 core::Device* device = core::InitDevice("蓋莫引擎物理場景-摩擦力測試");
35 //! 得到引擎場景指針
36 core::RefPtr<core::SceneManager> scenemanager = device->GetSceneManager();
37 //! 得到引擎資源指針
38 core::ResourceManager* resourcemanager = device->GetResourceManager();
39
40 //! 得到圖形和其紋理
41 core::RefPtr<core::Image> box = resourcemanager->GetImage("box","..\\image/tile.tga");
42 core::RefPtr<core::Texture> boxtexture = resourcemanager->GetTexture("box",box);
43 boxtexture->Bind();
44 cubeid = boxtexture->GetTextureId();
45
46 //! 獲取全局攝像機
47 core::RefPtr<core::Camera> camera = scenemanager->GetGlobalCamera(Vector3f(-5,100,17),
48 Vector3f(18,1,17),
49 Vector3f(0,1,0));
50 camera->SetViewport(0,0,640,480);
51 camera->SetPerspective(50.0f,640.0f/480.0f,0.1f,1000.0f);
52 glClearDepth(1.0f);
53 glDepthFunc(GL_LEQUAL);
54 glEnable(GL_DEPTH_TEST);
55 glEnable(GL_CULL_FACE);
56 glShadeModel(GL_SMOOTH);
57 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
58 core::Render::SetClearColor(core::Color::Blue);
59
60 BEGIN_LOOP(device)
61 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
62 glLoadIdentity();
63 camera->SetPerspective(45.0f,640.0f/480.0f,0.1f,1000.0f);
64 camera->Render();
65 PhysicsLoop();
66 END_LOOP(device)
67
68 device->Close();
69 device->Drop();
70
71 return 0;
72 }
73
74 //! 初始化物理場景
75 void Init()
76 {
77 engine.SetGravity(0,-GRAVITY,0);
78 ground = engine.SetPlane(0,1,0,0);
79 engine.SetCollideCallBack(&nearCallback);
80
81 box[0].body = engine.GetBody("body1",Vector3f(2*LENGTH,0.25*LENGTH,LENGTH*2));
82 box[1].body = engine.GetBody("body2",Vector3f(2*LENGTH,0.25*LENGTH,LENGTH*6));
83 box[2].body = engine.GetBody("body3",Vector3f(2*LENGTH,0.25*LENGTH,LENGTH*10));
84 for(int i = 0; i < 3; i++)
85 {
86 dMass m;
87 dMassSetBox(&m,1,LENGTH,LENGTH*0.5,LENGTH);
88 dMassAdjust(&m,MASS);
89 dBodySetMass(box[i].body,&m);
90 box[i].geom[0] = dCreateBox(engine.GetSpace(),LENGTH,0.5*LENGTH,LENGTH);
91 dGeomSetBody(box[i].geom[0],box[i].body);
92 }
93 }
94
95 static void nearCallback(void *data, dGeomID o1, dGeomID o2)
96 {
97 int i;
98
99 //! 僅僅考慮和地面的碰撞
100 int g1 = (o1 == ground);
101 int g2 = (o2 == ground);
102 if (!(g1 ^ g2))
103 return;
104
105 dBodyID b1 = dGeomGetBody(o1);
106 dBodyID b2 = dGeomGetBody(o2);
107
108 dContact contact[3];
109 for (i=0; i<3; i++)
110 {
111 contact[i].surface.mode = dContactSoftCFM | dContactApprox1;
112 contact[i].surface.mu = MU;
113 contact[i].surface.soft_cfm = 0.01;
114 }
115 if(int numc = dCollide (o1,o2,3,&contact[0].geom,sizeof(dContact)))
116 {
117 for (i=0; i<numc; i++)
118 {
119 dJointID c = dJointCreateContact(engine.GetWorld(),engine.GetContactGroup(),contact+i);
120 dJointAttach (c,b1,b2);
121 }
122 }
123 }
124
125 //! 物理場景更新
126 void PhysicsLoop()
127 {
128 engine.Simulation();
129
130 const float sides[3] = {2*LENGTH,LENGTH*0.5f,2*LENGTH};
131
132 dBodyAddForce(box[0].body,FORCE*5,0,0);
133 dBodyAddForce(box[1].body,FORCE*7,0,0);
134 dBodyAddForce(box[2].body,FORCE*9,0,0);
135
136 const dReal* pos = dBodyGetPosition(box[0].body);
137 const dReal* mat = dBodyGetRotation(box[0].body);
138 core::Render::RenderCube(cubeid,(const float*)pos,(const float*)mat,sides);
139 pos = dBodyGetPosition(box[1].body);
140 mat = dBodyGetRotation(box[1].body);
141 core::Render::RenderCube(cubeid,(const float*)pos,(const float*)mat,sides);
142 pos = dBodyGetPosition(box[2].body);
143 mat = dBodyGetRotation(box[2].body);
144 core::Render::RenderCube(cubeid,(const float*)pos,(const float*)mat,sides);
145 }
可以看出三個盒子的物理屬性都是一致的,除了其位置之外
在模擬過程中給3個盒子施加的力是不同的