#include <btBulletDynamicsCommon.h>
#include <osgViewer/Viewer>
#include <map>
#include <osg/ShapeDrawable>
#include <osg/MatrixTransform>
#include <osgGA/StateSetManipulator>
#include <osgViewer/ViewerEventHandlers>
#pragma comment(lib, "osgd.lib")
#pragma comment(lib, "osgDBd.lib")
#pragma comment(lib, "osgGAd.lib")
#pragma comment(lib, "osgViewerd.lib") class BulletInterface : public osg::Referenced
{
public:
static BulletInterface * Instance();
btDiscreteDynamicsWorld * GetScene() {return _scene;} void CreateWorld(const osg::Plane & plane, const osg::Vec3 & gravity);
void CreateBox(int id, const osg::Vec3 & dim, double mass);
void CreateSphere(int id, double radius, double mass);
void SetVelocity(int id, const osg::Vec3 & pos);
void SetMatrix(int id, const osg::Matrix & matrix);
osg::Matrix GetMatrix(int id); void Simulate(double step);
protected:
BulletInterface();
virtual ~BulletInterface(); typedef std::map<int , btRigidBody *> ActorMap;
ActorMap _actors;
btDiscreteDynamicsWorld * _scene;
btDefaultCollisionConfiguration * _configuration;
btCollisionDispatcher * _dispatcher;
btBroadphaseInterface * _overlappingPairCache;
btSequentialImpulseConstraintSolver * _solver;
}; BulletInterface * BulletInterface::Instance()
{
static osg::ref_ptr<BulletInterface> s_registry = new BulletInterface;
return s_registry.get();
} void BulletInterface::CreateWorld( const osg::Plane & plane, const osg::Vec3 & gravity )
{
_scene = new btDiscreteDynamicsWorld(_dispatcher, _overlappingPairCache, _solver, _configuration);
_scene->setGravity(btVector3(gravity[], gravity[], gravity[])); osg::Vec3 normal = plane.getNormal();
btCollisionShape * groundShape = new btStaticPlaneShape(btVector3(normal[], normal[], normal[]), plane[]); btTransform groundTransform;
groundTransform.setIdentity(); btDefaultMotionState * motionState = new btDefaultMotionState(groundTransform);
btRigidBody::btRigidBodyConstructionInfo rigidInfo(0.0, motionState, groundShape, btVector3(0.0, 0.0, 0.0));
btRigidBody * body = new btRigidBody(rigidInfo);
_scene->addRigidBody(body);
} void BulletInterface::CreateBox( int id, const osg::Vec3 & dim, double mass )
{
btCollisionShape * boxShape = new btBoxShape(btVector3(dim[], dim[], dim[]));
btTransform boxTransform;
boxTransform.setIdentity(); btVector3 localInertia(0.0, 0.0, 0.0);
if (mass > 0.0)
{
boxShape->calculateLocalInertia(mass, localInertia);
} btDefaultMotionState * motionState = new btDefaultMotionState(boxTransform);
btRigidBody::btRigidBodyConstructionInfo rigidInfo(mass, motionState, boxShape, localInertia);
btRigidBody * body = new btRigidBody(rigidInfo);
_scene->addRigidBody(body);
_actors[id] = body;
} void BulletInterface::CreateSphere( int id, double radius, double mass )
{
btCollisionShape * sphereShape = new btSphereShape(radius); btTransform sphereTransform;
sphereTransform.setIdentity(); btVector3 localInertia(0.0, 0.0, 0.0);
if (mass > 0.0)
{
sphereShape->calculateLocalInertia(mass, localInertia);
}
btDefaultMotionState * motionState = new btDefaultMotionState(sphereTransform);
btRigidBody::btRigidBodyConstructionInfo rigidInfo(mass, motionState, sphereShape, localInertia);
btRigidBody * body = new btRigidBody(rigidInfo);
_scene->addRigidBody(body);
_actors[id] = body;
} void BulletInterface::SetVelocity( int id, const osg::Vec3 & pos )
{
btRigidBody * actor = _actors[id];
if (actor)
{
actor->setLinearVelocity(btVector3(pos._v[], pos._v[], pos._v[]));
}
} void BulletInterface::SetMatrix( int id, const osg::Matrix & matrix )
{
btRigidBody * actor = _actors[id];
if (actor)
{
btTransform trans;
trans.setFromOpenGLMatrix(osg::Matrixf(matrix).ptr());
actor->setWorldTransform(trans);
}
} osg::Matrix BulletInterface::GetMatrix( int id )
{
btRigidBody * actor = _actors[id];
if (actor)
{
btTransform trans = actor->getWorldTransform();
osg::Matrixf matrix;
trans.getOpenGLMatrix(matrix.ptr());
return matrix;
}
return osg::Matrix();
} void BulletInterface::Simulate( double step )
{
_scene->stepSimulation(step, );
} BulletInterface::BulletInterface()
:_scene(NULL)
{
_configuration = new btDefaultCollisionConfiguration;
_dispatcher = new btCollisionDispatcher(_configuration);
_overlappingPairCache = new btDbvtBroadphase;
_solver = new btSequentialImpulseConstraintSolver;
} BulletInterface::~BulletInterface()
{
if (_scene)
{
for (int i = _scene->getNumCollisionObjects() - ; i >= ; --i)
{
btCollisionObject * obj = _scene->getCollisionObjectArray()[i];
btRigidBody * body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
{
delete body->getMotionState();
}
_scene->removeCollisionObject(obj);
delete obj;
}
delete _scene;
}
delete _solver;
delete _overlappingPairCache;
delete _dispatcher;
delete _configuration;
} class SampleRigidUpdater : public osgGA::GUIEventHandler
{
public:
SampleRigidUpdater(osg::Group * root)
:_root(root)
{ } void AddGround(const osg::Vec3 & gravity)
{
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(0.0f, 0.0f, -0.5f), 100.0f, 100.0f, 1.0f))); osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;
mt->addChild(geode.get());
_root->addChild(mt.get()); BulletInterface::Instance()->CreateWorld(osg::Plane(0.0f, 0.0f, 1.0f, 0.0f), gravity);
} void AddPhysicsBox(osg::Box * shape, const osg::Vec3 & pos, const osg::Vec3 & vel, double mass)
{
int id = _physicsNodes.size();
BulletInterface::Instance()->CreateBox(id, shape->getHalfLengths(), mass);
AddPhysicsData(id, shape, pos, vel, mass);
} void AddPhysicsSphere(osg::Sphere * sphere, const osg::Vec3 & pos, const osg::Vec3 & vel, double mass)
{
int id = _physicsNodes.size();
BulletInterface::Instance()->CreateSphere(id, sphere->getRadius(), mass);
AddPhysicsData(id, sphere, pos, vel, mass);
} bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
osgViewer::View * view = dynamic_cast<osgViewer::Viewer *>(&aa);
if (!view || !_root)
{
return false;
}
switch (ea.getEventType())
{
case osgGA::GUIEventAdapter::KEYUP:
{
osg::Vec3 eye, center, up, dir;
view->getCamera()->getViewMatrixAsLookAt(eye, center, up);
dir = center - eye;
dir.normalize();
AddPhysicsSphere(new osg::Sphere(osg::Vec3(), 0.5f), eye, dir * 60.0f, 2.0);
}
break;
case osgGA::GUIEventAdapter::FRAME:
{
BulletInterface::Instance()->Simulate(0.02);
for (NodeMap::iterator iter = _physicsNodes.begin(); iter != _physicsNodes.end(); ++iter)
{
osg::Matrix matrix = BulletInterface::Instance()->GetMatrix(iter->first);
iter->second->setMatrix(matrix);
}
}
break;
default:
break;
}
return false;
}
protected:
void AddPhysicsData(int id, osg::Shape * shape, const osg::Vec3 & pos, const osg::Vec3 & vel, double mass)
{
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(new osg::ShapeDrawable(shape));
osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;
mt->addChild(geode.get());
_root->addChild(mt.get());
BulletInterface::Instance()->SetMatrix(id, osg::Matrix::translate(pos));
BulletInterface::Instance()->SetVelocity(id, vel);
_physicsNodes[id] = mt;
} protected:
typedef std::map<int, osg::observer_ptr<osg::MatrixTransform> > NodeMap;
NodeMap _physicsNodes;
osg::observer_ptr<osg::Group > _root;
};
int main()
{
int mode = ; osg::ref_ptr<osg::Group> root = new osg::Group;
osg::ref_ptr<osgGA::GUIEventHandler> updater;
switch ( mode )
{
case :
{
SampleRigidUpdater* rigidUpdater = new SampleRigidUpdater( root.get() );
rigidUpdater->AddGround( osg::Vec3(0.0f, 0.0f,-9.8f) );
for ( unsigned int i=; i<; ++i )
{
for ( unsigned int j=; j<; ++j )
{
rigidUpdater->AddPhysicsBox( new osg::Box(osg::Vec3(), 0.99f),
osg::Vec3((float)i, 0.0f, (float)j+0.5f), osg::Vec3(), 1.0f );
}
}
updater = rigidUpdater;
}
break;
case :
break;
default: break;
} osgViewer::Viewer viewer;
viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
viewer.addEventHandler( new osgViewer::StatsHandler );
viewer.addEventHandler( new osgViewer::WindowSizeHandler );
if ( updater.valid() )
viewer.addEventHandler( updater.get() );
viewer.setSceneData( root.get() );
return viewer.run();
}

bullet_01的更多相关文章

随机推荐

  1. IPython与notebook 安装

    基于 python2.7.13 32-bit版本安装 1.安装pyreadline https://pypi.python.org/pypi/pyreadline 下载对应的32位版本 2.用pip安 ...

  2. 浅谈javascript中stopImmediatePropagation函数和stopPropagation函数的区别

    在事件处理程序中,每个事件处理程序中间都会有一个event对象,而这个event对象有两个方法,一个是stopPropagation方法,一个是stopImmediatePropagation方法,两 ...

  3. PAT乙级1001. 害死人不偿命的(3n+1)猜想 (15)

    卡拉兹(Callatz)猜想: 对任何一个自然数n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把(3n+1)砍掉一半.这样一直反复砍下去,最后一定在某一步得到n=1.卡拉兹在1950年的世界数 ...

  4. 超实用 JS 代码段笔记(一)

    序1:30段简单代码段(有删减) 1 . 区分 IE 和 非 IE 浏览器 if(!+[1,]){ console.log('ie浏览器'); }else{ console.log('非ie浏览器') ...

  5. Java 并发 关键字volatile

    Java 并发 关键字volatile @author ixenos volatile只是保证了共享变量的可见性,不保证同步操作的原子性 同步块 和 volatile 关键字机制 synchroniz ...

  6. CentOS 7中将Tomcat设置为系统服务

    tomcat 需要增加一个pid文件,在tomca/bin 目录下面,增加 setenv.sh 配置,catalina.sh启动的时候会调用,在该文件中添加如下内容 CATALINA_PID=&quo ...

  7. 四大高质量且实用的chrome翻译插件推荐

    Google英译汉的质量怎么样?日常生活用语翻译还可以,但是一到专业性术语就歇菜了,翻译出来的东西简直就是惨不忍睹,惨绝人寰..对于酷爱英语学习又有强迫症的患者来说,一款既实用又方便,无疑就是雪中送炭 ...

  8. hdu 2188 选拔志愿者(sg博弈)

    Problem Description 对于四川同胞遭受的灾难,全国人民纷纷伸出援助之手,几乎每个省市都派出了大量的救援人员,这其中包括抢险救灾的武警部队,治疗和防疫的医护人员,以及进行心理疏导的心理 ...

  9. mysql中文显示问号

    mysql插入中文后显示为?,查到http://blog.csdn.net/chenxingzhen001/article/details/7567812中方法,即 在my.ini配置文件中的[myd ...

  10. Using YARN with Cgroups testing in sparkml cluster

    部署服务器: sparkml 集群 ########### sparkml ########## sparkml-node1 # yarn resource manager sparkml-node2 ...