ODE 与OSG的结合,很简单了
先给出个纯ODE的原型,ODE与OSG的结合就是通过这个原型改造的
#include <iostream>
#include <ode/ode.h>
#define time_step (float)0.1
int main()
{
dWorldID myWorld_id;
dBodyID mySphere_id;
dMass sphereMass;
const dReal *pos;
float time = 0.0;
/* Create a new world */
myWorld_id = dWorldCreate();
/* Create a sphere in the world */
mySphere_id = dBodyCreate( myWorld_id );
/* Set the world's global gravity vector (Mars) -- x,y,z */
dWorldSetGravity( myWorld_id, 0, 0, -3.77 );
/* Set the Sphere's position in the world -- x,y,z */
dBodySetPosition( mySphere_id, 0, 0, 100 );
/* Set the Sphere's mass (density, radius) */
dMassSetSphere( &sphereMass, 1, 2 );
dBodySetMass( mySphere_id, &sphereMass );
/* Give the sphere a small amount of upward (z) velocity */
dBodySetLinearVel( mySphere_id, 0.0, 0.0, 5.0 );
/* Run the simulation */
while (time < 5.0) {
/* Simulate the world for the defined time-step */
dWorldStep( myWorld_id, time_step );
/* Get the current position of the sphere */
pos = dBodyGetPosition( mySphere_id );
std::cout << "position (" << pos[0] << ", "
<< pos[1] << ", " << pos[2] << ")\n";
/* Next time step */
time += time_step;
}
/* Destroy the objects */
dBodyDestroy( mySphere_id );
dWorldDestroy( myWorld_id );
system("pause");
return 0;
}
ODE 与OSG的结合例子
#include <iostream>
#include <ode/ode.h>
#include <osg/Timer>
#include <osg/Shape>
#include <osg/Geometry>
#include <osg/Texture2D>
#include <osg/ShapeDrawable>
#include <osg/PositionAttitudeTransform>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osgGA/GUIEventHandler>
#include <osgGA/TrackballManipulator>
#include <osgViewer/ViewerEventHandlers>
const double ERP = 0.9;
dWorldID WorldID;
dBodyID SphereBoxyID;
dBodyID GroundBoxyID;
dBodyID BoxBodyID;
dGeomID SphereGeomID;
dGeomID BoxGeomID;
dGeomID GroundGeomID;
dJointGroupID ContactGroup;
dSpaceID SpaceID;
const osg::Vec3d SPHERE_POSITION(osg::Vec3d(0,0,30));
const osg::Vec3d BOX_POSITION(osg::Vec3d(0,50,30));
const double SPHERE_RADIUS = 5.0;
const double BOX_SIDE = 8;
/*--------------------画一个圆球-------------------------------------------------------*/
osg::Node *createSphere()
{
osg::ref_ptr<osg::Sphere> snakeSphere = new osg::Sphere(osg::Vec3(0.0, 0.0, 0.0), SPHERE_RADIUS);
osg::ref_ptr<osg::Geode>snakeGeode = new osg::Geode;
osg::ShapeDrawable *sd = new osg::ShapeDrawable(snakeSphere.get());
sd->setColor(osg::Vec4(1,0,0,0));
snakeGeode->addDrawable(sd);
return snakeGeode.release();
}
osg::Node *createBox()//正方体
{
osg::ref_ptr<osg::Box> boxBox = new osg::Box(osg::Vec3 (0.0, 0.0, 0.0), BOX_SIDE, BOX_SIDE, BOX_SIDE);
osg::ref_ptr<osg::Geode>boxGeode = new osg::Geode;
osg::ShapeDrawable *sd = new osg::ShapeDrawable(boxBox.get());
sd->setColor(osg::Vec4(0,1,0,0));
boxGeode->addDrawable(sd);
return boxGeode.release();
}
osg::Node * createGround()//地板
{
osg::ref_ptr<osg::Box> boxBox = new osg::Box(osg::Vec3 (0.0, 0.0, 0.0), 300, 300, 3);
osg::ref_ptr<osg::Geode>boxGeode = new osg::Geode;
boxGeode->addDrawable(new osg::ShapeDrawable(boxBox.get()));
return boxGeode.release();
}
/*------------------回调---------------------------------------------------------------*/
static void nearCallback (void *data, dGeomID o1, dGeomID o2)
{
dBodyID b1,b2;
dContact contact;
b1 = dGeomGetBody(o1);
b2 = dGeomGetBody(o2);
//if (b1 && b2 && dAreConnected (b1,b2)) return;
contact.surface.mode = dContactBounce | dContactSoftCFM;
contact.surface.mu = dInfinity;
contact.surface.mu2 = 0;
contact.surface.bounce = 0.1;
contact.surface.bounce_vel = 0.1;
contact.surface.soft_cfm = 0.0001;
if (dCollide (o1,o2,1,&contact.geom,sizeof(dContactGeom)))
{
dJointID c = dJointCreateContact (WorldID,ContactGroup,&contact);
dJointAttach (c,b1,b2);
}
}
int main()
{
dInitODE();
WorldID = dWorldCreate();
dWorldSetERP(WorldID, ERP);
dWorldSetGravity( WorldID, 0, 0, -9.8 );
ContactGroup = dJointGroupCreate(0);
SpaceID = dSimpleSpaceCreate(0);
/*----------------------------创建刚体、设置位置、质量等--------------------------------------------------*/
dMass mass;
SphereBoxyID = dBodyCreate( WorldID );
dBodySetPosition( SphereBoxyID, SPHERE_POSITION[0], SPHERE_POSITION[1], SPHERE_POSITION[2] );
dMassSetSphere( &mass, 1, 2 );
dBodySetMass( SphereBoxyID, &mass );
BoxBodyID = dBodyCreate( WorldID );
dBodySetPosition( BoxBodyID, BOX_POSITION[0],BOX_POSITION[1],BOX_POSITION[2]);
dMassSetSphere( &mass, 1, 2 );
dBodySetMass( SphereBoxyID, &mass );
/*-----------------------设置碰撞空间---------------------------------------------------*/
dCreatePlane(SpaceID, 0.0, 0.0, 1.0, 1.5);
SphereGeomID= dCreateSphere(SpaceID, SPHERE_RADIUS);
dGeomSetPosition(SphereGeomID, SPHERE_POSITION[0], SPHERE_POSITION[1], SPHERE_POSITION[2]);
dGeomSetBody(SphereGeomID,SphereBoxyID);
BoxGeomID= dCreateBox(SpaceID, BOX_SIDE,BOX_SIDE,BOX_SIDE);
dGeomSetPosition(BoxGeomID, BOX_POSITION[0], BOX_POSITION[1], BOX_POSITION[2]);
dGeomSetBody(BoxGeomID,BoxBodyID);
/*-------------------------OSG 设置-------------------------------------------------*/
osg::ref_ptr<osgViewer::Viewer>viewer = new osgViewer::Viewer;
osg::Group *root = new osg::Group;
osg::PositionAttitudeTransform * osgSphereNode = new osg::PositionAttitudeTransform;
osgSphereNode->setPosition(osg::Vec3d(SPHERE_POSITION[0],SPHERE_POSITION[1],SPHERE_POSITION[2]));
osgSphereNode->addChild(createSphere());
osg::PositionAttitudeTransform * osgBoxNode = new osg::PositionAttitudeTransform;
osgBoxNode->setPosition(osg::Vec3d(BOX_POSITION[0],BOX_POSITION[1],BOX_POSITION[2]));
osgBoxNode->addChild(createBox());
osg::PositionAttitudeTransform * osgGround = new osg::PositionAttitudeTransform;
osgGround->addChild(createGround());
root->addChild(osgSphereNode);
root->addChild(osgBoxNode);
root->addChild(osgGround);
viewer->setCameraManipulator(new osgGA::TrackballManipulator);
viewer->addEventHandler(new osgViewer::WindowSizeHandler);
viewer->addEventHandler(new osgViewer::StatsHandler);
viewer->setSceneData(root);
/*-----------------------增加速度、进行测试----------------------------------------------------*/
dBodySetLinearVel( SphereBoxyID, 0.0, 0.0, 50.0 );
dBodySetLinearVel( BoxBodyID, 0.0, 0.0, 50 );
dBodySetAngularVel( SphereBoxyID, 0.0, 0.0, 2);
dBodySetAngularVel( BoxBodyID, 0.0, 0.0, 1 );
/*-----------------仿真循环-----------------------------------------------------------*/
while(!viewer->done())
{
viewer->frame();
dBodySetAngularVel( BoxBodyID, 0.0, 0.0, 0.8 );
dSpaceCollide(SpaceID, 0, &nearCallback);
dWorldStep( WorldID, 0.003 );
const dReal *SpherePos = dBodyGetPosition( SphereBoxyID );
const dReal *BoxPos = dBodyGetPosition( BoxBodyID );
const dReal *BoxQuat = dBodyGetQuaternion(BoxBodyID);
osgSphereNode->setPosition(osg::Vec3d(SpherePos[0],SpherePos[1],SpherePos[2]));
osgBoxNode->setPosition(osg::Vec3d(BoxPos[0],BoxPos[1],BoxPos[2]));
osgBoxNode->setAttitude(osg::Quat(BoxQuat[1], BoxQuat[2], BoxQuat[3], BoxQuat[0]));
dJointGroupEmpty(ContactGroup);
}
/* Destroy the objects */
dBodyDestroy( SphereBoxyID );
dWorldDestroy( WorldID );
system("pause");
return 0;
}