ODE 与 OSG 的结合

4 篇文章 1 订阅

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;
}




  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值