#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. STM32驱动ht1621b显示LCD

    这几天在写ht1621b显示LCD的程序,主芯片是Stm32f10的芯片.对于stm32和ht1621b的运用和操作本人是新手,属于赶鸭子上架,通过查看datasheet等资料和网上查看前人写的程序终 ...

  2. 图片添加border 不占用图片的大小

    因为设计稿中的分割线大多分为两种情况:1.在图片右侧:2.在图片右侧+下方. 那么使用伪类before和after以及绝对定位很容易在不改变原布局的情况使图片按照设计稿输出和保留分割线. 例div.i ...

  3. USACO 3.3 TEXT Eulerian Tour中的Cows on Parade一点理解

    Cows on Parade Farmer John has two types of cows: black Angus and white Jerseys. While marching 19 o ...

  4. DOM小解

    现在来说说DOM 文档对象模型DOM(Document Object Model)定义访问和处理html文档的标准方法.DOM将html文档呈现为带有元素   ,属性和文本的树结构(节点树) 先来看看 ...

  5. ubuntu16.04 禁用Guest用户

    .打开终端(快捷键 Ctrl+Alt+T) .编辑50-no-guest.conf文件,按照以下命令编辑, sudo gedit /usr/share/lightdm/lightdm.conf.d/- ...

  6. 数据库中Schema、Database、User、Table的关系[转]

    数据库的初学者往往会对关系型数据库模式(schema).数据库(database).表(table).用户(user)之间感到迷惘,总感觉他们的关系千丝万缕,但又不知道他们的联系和区别在哪里,对一些问 ...

  7. c++中宽字节表示

    1.C++语言中_T Visual C++里边定义字符串的时候,用_T来保证兼容性,VC支持ascii和unicode两种字符类型,用_T可以保证从ascii编码类型转换到unicode编码类型的时候 ...

  8. Nginx redirect

    if ($host != 'www.xxxxx.com' ) { rewrite ^/(.*)$ http://www.xxxx.com/$1 permanent; }

  9. 移动HTML 5前端性能优化指南(转载)

    前端工程师的菜!最近移动Html 5越来越火,想有一个体验流畅的Html 5 应用,这篇优化指南就别放过咯.腾讯的同学将关键的注意点与优化方法都总结出来,全文高能干货,非常值得深度学习 >> ...

  10. ajax写法

    $.ajax({ type:'post', url:'<%=path%>/login', cache:false, dataType:'json', success:function(da ...