赞
踩
1.初始化:
dInitODE();
2.创建世界
world = dWorldCreate();
3.设置重力加速度
dWorldSetGravity(world, 0, 0, -9.8);
2.创建 s p a c e space space:
space = dSimpleSpaceCreate(0);
4.设置质量、质心、惯性张量:
dMass mass;
dMassSetBox(&mass, 1, 1, 1, 1);
dBodySetMass(obj[0].body, &mass);
5.创建几何体:
obj[0].geom = dCreateBox(space, 1, 1, 1);
6.将几何体与物体关联:
dGeomSetBody(obj[0].geom, obj[0].body);
6.创建关节、设置轴与锚点:
joint = dJointCreateHinge(world, 0);
dJointSetHingeAxis(joint, 0, 0, 1);
dJointSetHingeAnchor(joint, 0, 0, 0.5);
7.连接关节与物体:
dJointAttach(joint, obj[0].body, obj[1].body);
8.设置物体初始速度:
dReal x1 = 0.0;
dReal y1 = 0.0;
dReal z1 = 0.0;
dReal x2 = 0.5;
dReal y2 = 0.5;
dReal z2 = 0.0;
dBodySetLinearVel(obj[0].body, x1, y1, z1);
dBodySetLinearVel(obj[1].body, x2, y2, z2);
1.首先进行碰撞检测,对整个 s p a c e space space内的物体首先进行粗略碰撞检测,再进行精细检测
dSpaceCollide(space, 0, &nearCallback);
d C o l l i d e dCollide dCollide函数对候选几何体再做一次检测,返回碰撞点的个数
n = dCollide(o1, o2, N, &contact[0].geom, sizeof(dContact));
若检测到碰撞点,创建碰撞关节并连接两个几何体
dJointID c = dJointCreateContact(world, contactgroup, contact + i);
dJointAttach(c, dGeomGetBody(o1), dGeomGetBody(o2));
碰撞处理
contact[i].surface.mu = 0.5;
contact[i].surface.slip1 = 0.0;
contact[i].surface.slip2 = 0.0;
contact[i].surface.soft_erp = 0.8;
contact[i].surface.soft_cfm = 0.01;
2.更新世界
dWorldStep(world, 0.002);
3.可视化
for (int i = 0; i < 2; i++)
{
drawGeom(obj[i].geom);
}
#include <ode/ode.h> #include <drawstuff/drawstuff.h> #include "texturepath.h" #define dsDrawBox dsDrawBoxD struct Object { dBodyID body; // the body dGeomID geom; // geometries representing this body }; dWorldID world; dSpaceID space; dJointID joint; Object obj[2]; static dJointGroupID contactgroup; static void nearCallback(void*, dGeomID o1, dGeomID o2) { int i, n; dBodyID b1 = dGeomGetBody(o1); dBodyID b2 = dGeomGetBody(o2); if (b1 && b2 && dAreConnected(b1, b2)) return; const int N = 4; dContact contact[N]; n = dCollide(o1, o2, N, &contact[0].geom, sizeof(dContact)); if (n > 0) { for (i = 0; i < n; i++) { contact[i].surface.mode = dContactSlip1 | dContactSlip2 | dContactSoftERP | dContactSoftCFM | dContactApprox1; contact[i].surface.mu = 0.5; contact[i].surface.slip1 = 0.0; contact[i].surface.slip2 = 0.0; contact[i].surface.soft_erp = 0.8; contact[i].surface.soft_cfm = 0.01; dJointID c = dJointCreateContact(world, contactgroup, contact + i); dJointAttach(c, dGeomGetBody(o1), dGeomGetBody(o2)); } } } void start() { // initial camera position float xyz[3] = { 3.8966, -2.0614, 4.0300 }; float hpr[3] = { 153.5, -16.5, 0 }; dsSetViewpoint(xyz, hpr); } void stop() { dSpaceDestroy(space); dWorldDestroy(world); } void drawGeom(dGeomID g) { int gclass = dGeomGetClass(g); const dReal* pos = dGeomGetPosition(g); const dReal* rot = dGeomGetRotation(g); dVector3 lengths; dsSetColorAlpha(1, 1, 0, 1); dsSetTexture(DS_WOOD); dGeomBoxGetLengths(g, lengths); dsDrawBox(pos, rot, lengths); } void simLoop(int pause) { dSpaceCollide(space, 0, &nearCallback); if (!pause) /*可选择添加外力*/ //dBodyAddForce(obj[0].body, 1, 0, 0); dWorldStep(world, 0.002); // now we draw everything for (int i = 0; i < 2; i++) { drawGeom(obj[i].geom); } } int main(int argc, char** argv) { //setup pointers to drawstuff callback functions dsFunctions fn; fn.version = DS_VERSION; fn.start = &start; fn.step = &simLoop; fn.command = 0; fn.stop = stop; fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH; //create world dInitODE(); world = dWorldCreate(); dWorldSetGravity(world, 0, 0, -0.5); dWorldSetDamping(world, 1e-4, 1e-5); dWorldSetERP(world, 1); space = dSimpleSpaceCreate(0); dCreatePlane(space, 0, 0, 1, 0); obj[0].body = dBodyCreate(world); obj[1].body = dBodyCreate(world); dMass mass; dBodySetPosition(obj[0].body, -1, 0, 0.5); dBodySetPosition(obj[1].body, 1, 0, 0.5); obj[0].geom = dCreateBox(space, 1, 1, 1); dGeomSetBody(obj[0].geom, obj[0].body); dMassSetBox(&mass, 1, 1, 1, 1); dBodySetMass(obj[0].body, &mass); obj[1].geom = dCreateBox(space, 1, 1, 1); dGeomSetBody(obj[1].geom, obj[1].body); dMassSetBox(&mass, 1, 1, 1, 1); dBodySetMass(obj[1].body, &mass); joint = dJointCreateHinge(world, 0); dJointSetHingeAxis(joint, 0, 0, 1); dJointSetHingeAnchor(joint, 0, 0, 0.5); dJointAttach(joint, obj[0].body, obj[1].body); dReal x1 = 0.0; dReal y1 = 0.0; dReal z1 = 0.0; dReal x2 = 0.5; dReal y2 = 0.5; dReal z2 = 0.0; dBodySetLinearVel(obj[0].body, x1, y1, z1); dBodySetLinearVel(obj[1].body, x2, y2, z2); //run demo dsSimulationLoop(argc, argv, DS_SIMULATION_DEFAULT_WIDTH, DS_SIMULATION_DEFAULT_HEIGHT, &fn); dCloseODE(); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。