接上文介绍了ode的基本函数,接下来应该考虑如何绑定Ode和游戏引擎
简单的说,单单使用ode不是什么难事情,必须网上使用ode的例子一大把
问题的关键是如何较好的结合ode和引擎,记不至于游戏引擎把ode封装的太深以至于影响其使用的灵活性.另外一方面是,也不能把过多的额外操作抛给用户操作。
不过可以先设计一个基本的框架,以后根据需要和认识的不断加深再做修改。
于是先写下物理引擎的基本框架-很简单的了:
1 ////////////////////////////////////////////////////////////
2 /// 定义物理引擎模板类
3 ////////////////////////////////////////////////////////////
4 template<class World,class Space,class JointGroup,class Geom>
5 class PhysicsEngine
6 {
7 public:
8 typedef void(*ContactNearCallback)(void *data, Geom o1, Geom o2);
9 public:
10 ///////////////////////////////////////////////////////
11 /// 构造,析构物理引擎类
12 ///////////////////////////////////////////////////////
13 PhysicsEngine();
14 ~PhysicsEngine();
15 public:
16 ///////////////////////////////////////////////////////
17 /// 设定物理引擎平面(ax+by+cz+d=0)
18 ///////////////////////////////////////////////////////
19 void SetPlane(float a = 0, float b = 0, float c = 1, float d = 0);
20
21 ///////////////////////////////////////////////////////
22 /// 设定物理世界重力加速度
23 ///////////////////////////////////////////////////////
24 void SetGravity(float x = 0, float y = 0, float z = -9.81);
25
26 ///////////////////////////////////////////////////////
27 /// 设定物理世界仿真更新值
28 ///////////////////////////////////////////////////////
29 inline void SetStepValue(float step = 0.05f, bool quick = true)
30 {
31 this->step = step; this->quick = quick;
32 }
33
34 ///////////////////////////////////////////////////////
35 /// 加载引擎物理对象碰撞回调函数
36 ///////////////////////////////////////////////////////
37 inline void SetCollideCallBack(ContactNearCallback callback)
38 {
39 this->callback = callback;
40 }
41
42 ///////////////////////////////////////////////////////
43 /// 调用物理引擎模拟
44 ///////////////////////////////////////////////////////
45 void Simulation();
46
47 ///////////////////////////////////////////////////////
48 /// 获取物理引擎世界,空间和关节组对象.
49 ///////////////////////////////////////////////////////
50 inline World GetWorld(){return world;}
51 inline Space GetSpace(){return space;}
52 inline JointGroup GetContactGroup(){return contactgroup;}
53 private:
54 World world;
55 Space space;
56 JointGroup contactgroup;
57 ContactNearCallback callback;
58 float step;
59 bool quick;
60 };
61
62 #ifdef PHYSICS_EXT_ODE
63 #include "OdePhysics.inl"
64 #endif
具体对于ode,我看可以这样使用之:
1 core::PhysicsEngine<dWorldID,dSpaceID,dJointGroupID,dGeomID> engine;
或者可以这样
1 core::PhysicsEngine<> engine;
再给出一个简单的物理对象数据结构
1 ////////////////////////////////////////////////////////////
2 /// 定义引擎物理对象数据结构(一个对象由N个几何体构成)
3 ////////////////////////////////////////////////////////////
4 /*template<class Object,class Geom,int N>
5 struct PhysicsObject
6 {
7 Object object;
8 //! 有必要设计一个定长数组了.
9 Geom geom[N];
10 };*/
一个物理对象由N个简单几何体构成
这个是简单到了极点只是不太符合要求
下一步该考虑设计物理对象类了
对象可以旋转,平移,设置质量,加挂几何体.......
最后再上几个ode函数加深一点认识吧:
1 /**
2 * @brief Set the local offset rotation matrix of a geom from its body.
3 *
4 * Sets the geom's rotational offset in local coordinates.
5 * After this call, the geom will be at a new position determined from the
6 * body's position and the offset.
7 * The geom must be attached to a body.
8 * If the geom did not have an offset, it is automatically created.
9 *
10 * @param geom the geom to set.
11 * @param R the new rotation matrix.
12 * @ingroup collide
13 */
14 ODE_API void dGeomSetOffsetRotation (dGeomID geom, const dMatrix3 R);
设置几何体相对于其物体的局部旋转平移矩阵
1 /**
2 * @brief Set the offset position of a geom from its body.
3 *
4 * Sets the geom's positional offset to move it to the new world
5 * coordinates.
6 * After this call, the geom will be at the world position passed in,
7 * and the offset will be the difference from the current body position.
8 * The geom must be attached to a body.
9 * If the geom did not have an offset, it is automatically created.
10 *
11 * @param geom the geom to set.
12 * @param x the new X coordinate.
13 * @param y the new Y coordinate.
14 * @param z the new Z coordinate.
15 * @ingroup collide
16 */
17 ODE_API void dGeomSetOffsetWorldPosition (dGeomID geom, dReal x, dReal y, dReal z);
生成,设置几何对象的函数:
1 ODE_API dGeomID dCreateSphere (dSpaceID space, dReal radius);
2 ODE_API void dGeomSphereSetRadius (dGeomID sphere, dReal radius);
3 ODE_API dReal dGeomSphereGetRadius (dGeomID sphere);
4 ODE_API dGeomID dCreateBox (dSpaceID space, dReal lx, dReal ly, dReal lz);
5 ODE_API void dGeomBoxSetLengths (dGeomID box, dReal lx, dReal ly, dReal lz);
6 ODE_API void dGeomBoxGetLengths (dGeomID box, dVector3 result);
7 ODE_API dGeomID dCreateCapsule (dSpaceID space, dReal radius, dReal length);
8 ODE_API void dGeomCapsuleSetParams (dGeomID ccylinder, dReal radius, dReal length);
9 ODE_API void dGeomCapsuleGetParams (dGeomID ccylinder, dReal *radius, dReal *length);
10 ODE_API dReal dGeomCapsulePointDepth (dGeomID ccylinder, dReal x, dReal y, dReal z);
11 ODE_API dGeomID dCreateCylinder (dSpaceID space, dReal radius, dReal length);
12 ODE_API void dGeomCylinderSetParams (dGeomID cylinder, dReal radius, dReal length);
13 ODE_API void dGeomCylinderGetParams (dGeomID cylinder, dReal *radius, dReal *length);
14 ODE_API dGeomID dCreateRay (dSpaceID space, dReal length);
15 ODE_API void dGeomRaySetLength (dGeomID ray, dReal length);
16 ODE_API dReal dGeomRayGetLength (dGeomID ray);
17 ODE_API void dGeomRaySet (dGeomID ray, dReal px, dReal py, dReal pz,
18 dReal dx, dReal dy, dReal dz);
19 ODE_API void dGeomRayGet (dGeomID ray, dVector3 start, dVector3 dir);