您的位置:首页 > 其它

ODE 3D图形的简单绘制

2012-09-03 20:24 211 查看




drawstuff能绘制的形状的一部分:左起分别是球、立方体、圆柱、胶囊、线。

进入暑假有时间了,所以ODE初级讲座第四讲开讲。这次学习ODE(Open Dynamics Eng
ine)的3D图形函数。运行ODE的演示程序,飘动的云和地面的纹理不错,仿真的外观很好。
这是ODE付带的3D图形库drawstuff的工作。在ODE中,drawstuff只是用于演示程序的显示
,因此只有简单的功能。drawstuff画多边形慢,所以ODE不完善的场合用其它的库为好。
除了Windows,Linux下也想使用的话,irrlicht和Ogre3D可以做为补充,我想。

drawstuff是用叫做OpenGL的3D图形库写成的非常简单的库。由于简单也适合学习Ope
nGL。还有,drawstuff相关的API(函数)以小写字母ds开头,和ODE相关的API以小写字母
d开头。

drawstuff的使用方法

·加入头文件
#include <drawstuff/drawstuff.h>

·设置
为了使用drawstuff必须设置下面的dsFunctions结构体。
以下内容为程序代码:

//drawstuff使用的dsFunctions结构体的定义
typedef struct dsFunctions
{
int version;      /*放入DS_VERSION*/
void (*start)();  /*在开始仿真前调用*/
void (*step)(int pause); /*每次仿真循环调用*/
void (*command)(int cmd); /*按下按键时被调用*/
void (*stop)(); /*仿真循环的最后被调用*/
const char *path_to_textures; /*纹理文件的路径*/
}
dsFunctions;

·版本: 放入DS_VERSION
+ fn.version = DS_VERSION
·预处理函数:在仿真循环开始前被调用。在这里一般设置摄像机的视点和视线。
+ fn.start = &start;
+ 设置摄像机的视点和视线
dsSetViewpoint(视点,视线);
·仿真循环函数:仿真的每个循环被调用。在这里写动力学计算函数、碰撞检测和绘
图相关的处理。在演示程序中,写与绘图相关的处理。
+ fn.step = &simLoop;
+ 写与绘图相关的API
·按键处理函数:每次按键被调用.不需要的场合填入NULL(空指针)。NULL是指向
0号地址的特殊的指针。
+ fn.command = &command;
·后处理函数:仿真循环结束之后被调用。不需要的场合填入NULL(空指针)。
+ fn.stop = &stop;
·纹理文件的路径
+ fn.path_to_textures = "路径";
* 运  行
·调用下面的API一次就可以绘图了。它里面有while循环。

dsSimulationLoop(argc, argv, witdh, height, &fn);
+ argc, argv: main函数的参数
+ width: 窗口的宽度
+ height: 窗口的高度
+ fn: drawstuff结构体dsFunctions的变量

例程序
以下内容为程序代码:

/* ODE tutorial  by Kosei Demura */
/* Lesson 4 3D Graphics          */
// 绘制球,圆柱,胶囊,立方体,线的程序
// 没有碰撞检测和动力学计算
#include <ode/ode.h>
#include <drawstuff/drawstuff.h>
#ifdef _MSC_VER
#pragma warning(disable:4244 4305)  // 禁用VC++警告
#endif
#ifdef dDOUBLE
#define dsDrawBox      dsDrawBoxD
#define dsDrawSphere   dsDrawSphereD
#define dsDrawCylinder dsDrawCylinderD
#define dsDrawCapsule  dsDrawCapsuleD
#define dsDrawLine     dsDrawLineD
#endif

#define DENSITY (5.0)	// 密度

struct MyObject {
dBodyID body;		// Body(刚体)
};

dReal radius = 0.25; // 半径
dReal length = 1.0;  // 长度
dReal sides[3] = {0.5,0.5,1.0}; // 边长
static dWorldID world;  // 动力学计算world
static MyObject sphere, box, capsule, cylinder; // 物体

// start simulation
static void start()
{
static float xyz[3] = {5,3,0.5};    // 视点[m]
static float hpr[3] = {-180, 0, 0}; // 视线[°]
dsSetViewpoint (xyz,hpr);           // 设定视点和视线
}

// 仿真循环
static void simLoop (int pause)
{
const dReal *pos1,*R1,*pos2,*R2,*pos3,*R3;    //  绘制球
dsSetColor(1,0,0);      // 颜色的设定(红,绿,蓝)各分量从0到1
dsSetSphereQuality(3);  // 让球的口质高些
pos1 = dBodyGetPosition(sphere.body); // 获取位置
R1   = dBodyGetRotation(sphere.body); // 获得姿势(旋转矩阵)
dsDrawSphere(pos1,R1,radius);         // 画球

// 画圆柱
dsSetColorAlpha (0,1,0,1);
pos2 = dBodyGetPosition(cylinder.body);
R2   = dBodyGetRotation(cylinder.body);
dsDrawCylinder(pos2,R2,length,radius);  // 画圆柱

// 画胶囊
dsSetColorAlpha (1,1,1,1);
pos2 = dBodyGetPosition(capsule.body);
R2   = dBodyGetRotation(capsule.body);
dsDrawCapsule(pos2,R2,length,radius);  // 画胶囊

// 画立方体
dsSetColorAlpha (0,0,1,1);
pos3 = dBodyGetPosition(box.body);
R3   = dBodyGetRotation(box.body);
dsDrawBox(pos3,R3,sides);             // 画立方体

// 画线
dReal posA[3] = {0, 5, 0}, posB[3]={0, 5, 1.9};
dsDrawLine(posA,posB); // 画线
}

int main (int argc, char **argv)
{
// drawstuff的设定
dsFunctions fn;
fn.version = DS_VERSION;
fn.start   = &start;
fn.step    = &simLoop;
fn.command = NULL;
fn.stop    = NULL;
fn.path_to_textures = "../../drawstuff/textures";

dInitODE();              // ODE的初始化
world = dWorldCreate();  // 生成动力学计算用world的生成

dMass m;                 // 质量参数
dMassSetZero (&m);  // 质量参数的设定

//  球
sphere.body = dBodyCreate (world);     // 生成body
dReal radius = 0.5;                    // 半径 [m]
dMassSetSphere (&m,DENSITY,radius);

// 质量参数的计算
dBodySetMass (sphere.body,&m);  // 为body设定参数
dBodySetPosition (sphere.body,0,1, 1); // 设定body的位置

// 立方体
box.body = dBodyCreate (world);
dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]);
dBodySetMass (box.body,&m);   dBodySetPosition (box.body,0,2,1);

// 胶囊
capsule.body = dBodyCreate (world);
dMassSetCapsule(&m,DENSITY,3,radius,length);
dBodySetMass (capsule.body,&m);
dBodySetPosition (capsule.body,0,4,1);

// 圆柱
cylinder.body = dBodyCreate (world);
dMassSetCylinder(&m,DENSITY,3,radius,length);
dBodySetMass (cylinder.body,&m);
dBodySetPosition (cylinder.body,0,3,1);

// 运行仿真
dsSimulationLoop (argc,argv,960,480,&fn);
dWorldDestroy (world); // 销毁world
dCloseODE();           // ODE的结束
return 0;
}

转载源地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: