游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2499|回复: 0

使用盖莫游戏引擎和ode物理引擎设计的简单物理场景2

[复制链接]

50

主题

69

帖子

69

积分

注册会员

Rank: 2

积分
69
发表于 2010-3-4 11:47:00 | 显示全部楼层 |阅读模式
本例子源于ode自带的例子:demo_chain2
演示的是一个由小盒子构成的链子在受正弦力左右下的物理现象(当然还有重力因素).
其代码如下:
//! 2010.03.03
/////////////////////////////////////////////////////
/// 盖莫游戏引擎的物理引擎测试2
/////////////////////////////////////////////////////  
#include <GEngine/Gaimo.hpp>
//! 定义立方体个数
#define NUM 9
#define SIDE 2.0f
#define MASS 1.0f
core:hysicsEngine<dWorldID,dSpaceID,dJointGroupID,dGeomID> engine;
core::PhysicsBody<dBodyID,dGeomID,1> object[NUM];
dJointID joint[NUM-1];
//! 盒子表面纹理
int   cubeid;
//! 检测碰撞回调函数
static void nearCallback(void *data, dGeomID o1, dGeomID o2)
{
   //! 获取几何体对于德物理对象   
   dBodyID b1 = dGeomGetBody(o1);
   dBodyID b2 = dGeomGetBody(o2);
   //! 如果物体是相连的则返回之
   if(b1 && b2 && dAreConnected(b1,b2))
      return;

   dContact contact;
   contact.surface.mode = 0;
   contact.surface.mu = dInfinity;
   //! 如果物体之间发生了碰撞则关联之
   if(dCollide (o1,o2,1,&contact.geom,sizeof(dContactGeom)))
   {
      dJointID c = dJointCreateContact(engine.GetWorld(),engine.GetContactGroup(),&contact);
      dJointAttach (c,b1,b2);
   }
}  
void ShowGrid();
void SimLoop();
int main(int argc, char **argv)
{   
    //! 初始化引擎设备并得到设备指针
    core:evice* device = core::InitDevice("盖莫引擎物理场景测试2");
    //! 得到引擎场景指针
    core::RefPtr<core::SceneManager> scenemanager = device->GetSceneManager();
    //! 得到引擎资源指针
    core::ResourceManager* resourcemanager = device->GetResourceManager();

    //! 获取盒子图形和纹理
    core::RefPtr<core::Image>   cubeimage = resourcemanager->GetImage("cube","..\\image//tile.tga");
    core::RefPtr<core::Texture> cubetexture = resourcemanager->GetTexture("cube",cubeimage);     
    cubetexture->Bind();   
    cubeid = cubetexture->GetTextureId();
    //! 获取全局摄像机
    core::RefPtr<core::Camera> camera = scenemanager->GetGlobalCamera(Vector3f(30,11,30),
                                                                      Vector3f(0,0,0),
                                                                      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);   
    //! 设置空间重力加速度
    engine.SetGravity(0,-0.8,0);
    //! 设置空间平面
    engine.SetPlane(0,1,0,0);
    //! 加载碰撞检测回调函数
    engine.SetCollideCallBack(&nearCallback);

    for(int i=0; i<NUM; i++)
    {
        dMass m;   
        object.body = dBodyCreate(engine.GetWorld());
        dReal k = i*SIDE;
        dBodySetPosition(object.body,k,k+0.8,k);
        dMassSetBox(&m,1,SIDE,SIDE,SIDE);
        dMassAdjust(&m,MASS);
        dBodySetMass(object.body,&m);
        dBodySetData(object.body,(void*)i);
        object.geom[0] = dCreateBox(engine.GetSpace(),SIDE,SIDE,SIDE);
        dGeomSetBody(object.geom[0],object.body);
    }
    for(int i=0; i< NUM-1; i++)
    {
        //! 必须确保生成关节的空间指针为空     
        joint = dJointCreateBall(engine.GetWorld(),NULL);
        dJointAttach(joint,object.body,object[i+1].body);
        dReal k = (i+0.5)*SIDE;
        dJointSetBallAnchor(joint,k,k+0.8,k);
    }   
   
    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();   
       //! 绘制网格
       ShowGrid();
       SimLoop();      
    END_LOOP(device)
   
    device->Close();
    device->Drop();
    return 0;
}
void SimLoop()
{
    static double angle = 0;
    angle += 0.05;
    dBodyAddForce(object[NUM-1].body,0,3*(sin(angle)+1.0),0);
   
    engine.Simulation();
  
    for (int i=0; i<NUM; i++)
    {   
        dReal sides[3];
        const dReal *pos;
        const dReal *mat;
        dGeomBoxGetLengths(object.geom[0], sides);
        float dsides[] = {sides[0],sides[1],sides[2]};
        pos = dGeomGetPosition(object.geom[0]);
        float dpos[] = {pos[0],pos[1],pos[2]};
        mat = dGeomGetRotation(object.geom[0]);
        float dmat[] = {mat[0],mat[1],mat[2], mat[3],
                        mat[4],mat[5],mat[6], mat[7],
                        mat[8],mat[9],mat[10],mat[11]};
        core::Render::RenderCube(cubeid,dpos,dmat,dsides);
    }
}
//! 显示地面网格
void ShowGrid()
{   
    glPushAttrib(GL_CURRENT_BIT);
    glPushMatrix();                 
    glColor3f(0,0,1);
    glBegin(GL_QUADS);
            glTexCoord2f(0.0f,0.0f);
         glVertex3i(-50,0,-50);  
         glTexCoord2f(1.0f, 0.0f);
         glVertex3i(50,0,-50);   
         glTexCoord2f(1.0f, 1.0f);
         glVertex3i(50,0,50);
         glTexCoord2f(0.0f, 1.0f);
         glVertex3i(-50,0,50);
    glEnd();
for(float i = -50; i <= 50; i += 1)
{
  glBegin(GL_LINES);
   glVertex3f(-50, 0, i);
   glVertex3f(50, 0, i);
   glVertex3f(i, 0, -50);
   glVertex3f(i, 0, 50);
  glEnd();
}
glPopMatrix();
    glPopAttrib();
}

显示图片如下:




需要说明的就是函数:
dJointCreateBall(world,space
在一般情况下第二个参数也就是space必须是空值
再看其回调函数:
//! 检测碰撞回调函数
static void nearCallback(void *data, dGeomID o1, dGeomID o2)
{
   //! 获取几何体对于德物理对象   
   dBodyID b1 = dGeomGetBody(o1);
   dBodyID b2 = dGeomGetBody(o2);
   //! 如果物体是相连的则返回之
   if(b1 && b2 && dAreConnected(b1,b2))
      return;

   dContact contact;
   contact.surface.mode = 0;
   contact.surface.mu = dInfinity;
   //! 如果物体之间发生了碰撞则关联之
   if(dCollide (o1,o2,1,&contact.geom,sizeof(dContactGeom)))
   {
      dJointID c = dJointCreateContact(engine.GetWorld(),engine.GetContactGroup(),&contact);
      dJointAttach (c,b1,b2);
   }
} 其一般描述就是先有几何体获取其body句柄
如果为空则返回
再者说明如果body是连接在一起的应该如何处理
接下来局势如何发生碰撞应该如何处理
最后看看其关节生成和链接:

        joint = dJointCreateBall(engine.GetWorld(),NULL);
        dJointAttach(joint,object.body,object[i+1].body);
        dReal k = (i+0.5)*SIDE;
        dJointSetBallAnchor(joint,k,k+0.8,k);
首先是关节生成
其次是关节连接
其次是设置关节位置
ok
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-7-1 18:46

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表