Cpper
C/C++高级工程师 Android高级软件工程师 IT集成工程师 音频工程师 熟悉c,c++,java,c#,py,js,asp等多种语言 程序猿
本例子源于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.0f0.0f);
152             glVertex3i(50,0,-50);         
153             glTexCoord2f(1.0f1.0f);
154             glVertex3i(50,0,50); 
155             glTexCoord2f(0.0f1.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(-500, i);
163             glVertex3f(500, i);
164             glVertex3f(i, 0-50);
165             glVertex3f(i, 050);
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 
posted on 2010-03-04 11:40 ccsdu2009 阅读(1283) 评论(0)  编辑 收藏 引用 所属分类: Game引擎

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理