|
这是使用盖莫游戏引擎做的基于ode物理引擎的摩擦力测试的小例子
代码如下:
//! 2010.03.05
/////////////////////////////////////////////////////
/// 盖莫游戏引擎盖莫引擎物理场景测试3
/////////////////////////////////////////////////////
#include <GEngine/Gaimo.hpp>
using namespace std;
#define LENGTH 4
#define MASS 0.4
#define FORCE 0.6
#define MU 1.0
#define GRAVITY 9.8
//! 盒子纹理
int cubeid = 0;
dGeomID ground;
core:hysicsEngine<dWorldID,dSpaceID,dJointGroupID,dBodyID,dGeomID> engine;
core::PhysicsBody<dBodyID,dGeomID,1> box[3];
//! 碰撞检测回调函数
static void nearCallback(void *data, dGeomID o1, dGeomID o2);
//! 初始化物理场景
void Init();
//! 物理场景更新
void PhysicsLoop();
int main(int argc, char **argv)
{
Init();
//! 初始化引擎设备并得到设备指针
core:evice* device = core::InitDevice("盖莫引擎物理场景-摩擦力测试");
//! 得到引擎场景指针
core::RefPtr<core::SceneManager> scenemanager = device->GetSceneManager();
//! 得到引擎资源指针
core::ResourceManager* resourcemanager = device->GetResourceManager();
//! 得到图形和其纹理
core::RefPtr<core::Image> box = resourcemanager->GetImage("box","..\\image/tile.tga");
core::RefPtr<core::Texture> boxtexture = resourcemanager->GetTexture("box",box);
boxtexture->Bind();
cubeid = boxtexture->GetTextureId();
//! 获取全局摄像机
core::RefPtr<core::Camera> camera = scenemanager->GetGlobalCamera(Vector3f(-5,100,17),
Vector3f(18,1,17),
Vector3f(0,1,0));
camera->SetViewport(0,0,640,480);
camera->SetPerspective(50.0f,640.0f/480.0f,0.1f,1000.0f);
glClearDepth(1.0f);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glShadeModel(GL_SMOOTH);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
core::Render::SetClearColor(core::Color::Blue);
BEGIN_LOOP(device)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
camera->SetPerspective(45.0f,640.0f/480.0f,0.1f,1000.0f);
camera->Render();
PhysicsLoop();
END_LOOP(device)
device->Close();
device->Drop();
return 0;
}
//! 初始化物理场景
void Init()
{
engine.SetGravity(0,-GRAVITY,0);
ground = engine.SetPlane(0,1,0,0);
engine.SetCollideCallBack(&nearCallback);
box[0].body = engine.GetBody("body1",Vector3f(2*LENGTH,0.25*LENGTH,LENGTH*2));
box[1].body = engine.GetBody("body2",Vector3f(2*LENGTH,0.25*LENGTH,LENGTH*6));
box[2].body = engine.GetBody("body3",Vector3f(2*LENGTH,0.25*LENGTH,LENGTH*10));
for(int i = 0; i < 3; i++)
{
dMass m;
dMassSetBox(&m,1,LENGTH,LENGTH*0.5,LENGTH);
dMassAdjust(&m,MASS);
dBodySetMass(box.body,&m);
box.geom[0] = dCreateBox(engine.GetSpace(),LENGTH,0.5*LENGTH,LENGTH);
dGeomSetBody(box.geom[0],box.body);
}
}
static void nearCallback(void *data, dGeomID o1, dGeomID o2)
{
int i;
//! 仅仅考虑和地面的碰撞
int g1 = (o1 == ground);
int g2 = (o2 == ground);
if (!(g1 ^ g2))
return;
dBodyID b1 = dGeomGetBody(o1);
dBodyID b2 = dGeomGetBody(o2);
dContact contact[3];
for (i=0; i<3; i++)
{
contact.surface.mode = dContactSoftCFM | dContactApprox1;
contact.surface.mu = MU;
contact.surface.soft_cfm = 0.01;
}
if(int numc = dCollide (o1,o2,3,&contact[0].geom,sizeof(dContact)))
{
for (i=0; i<numc; i++)
{
dJointID c = dJointCreateContact(engine.GetWorld(),engine.GetContactGroup(),contact+i);
dJointAttach (c,b1,b2);
}
}
}
//! 物理场景更新
void PhysicsLoop()
{
engine.Simulation();
const float sides[3] = {2*LENGTH,LENGTH*0.5f,2*LENGTH};
dBodyAddForce(box[0].body,FORCE*5,0,0);
dBodyAddForce(box[1].body,FORCE*7,0,0);
dBodyAddForce(box[2].body,FORCE*9,0,0);
const dReal* pos = dBodyGetPosition(box[0].body);
const dReal* mat = dBodyGetRotation(box[0].body);
core::Render::RenderCube(cubeid,(const float*)pos,(const float*)mat,sides);
pos = dBodyGetPosition(box[1].body);
mat = dBodyGetRotation(box[1].body);
core::Render::RenderCube(cubeid,(const float*)pos,(const float*)mat,sides);
pos = dBodyGetPosition(box[2].body);
mat = dBodyGetRotation(box[2].body);
core::Render::RenderCube(cubeid,(const float*)pos,(const float*)mat,sides);
}
可以看出三个盒子的物理属性都是一致的,除了其位置之外
在模拟过程中给3个盒子施加的力是不同的
由于例子比较简单这里就不上贴图了 |
|