[osg-users] osg::Node and Bullet Physic

Marco Bigolin marco.bigolin at gmail.com
Mon Apr 4 22:31:57 PDT 2011


Hi

I made my own osg::Node (osg::Group) with Physics. This works great if i insert the node on position (0,0,0)
If i made a positionattitudeTransform with the physics-Node the node is on the new position but the physics-Node / Object is still at 0,0,0

here is the code:
h-File:

Code:

class PhysicsCube :
         public osg::Group
      {
      public:
         PhysicsCube();
         ~PhysicsCube(void);
         osg::MatrixTransform* createNode(double length, double mass, btDynamicsWorld* dynamicsWorld, osg::Vec3d position);
         void setColor(osg::Vec4d color);
         btRigidBody *getBody(void);

      private:
         void createGeometry(void);
         osg::ShapeDrawable* _boxDrawable;
         double _length;
         double _mass;
         btDynamicsWorld* _dynamicsWorld;
         btRigidBody* _body;
      };

      class BallUpdateCallback : public osg::NodeCallback
      {
      private:
         btRigidBody *_body;

      public:
         BallUpdateCallback(btRigidBody *body) :
           _body(body)
           {}

           virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
           {
              btScalar m[16];

              btDefaultMotionState* myMotionState = ( btDefaultMotionState*)_body->getMotionState();
              myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(m);

               double t = nv->getFrameStamp()->getReferenceTime();
               osg::Matrix mat = osg::computeLocalToWorld(nv->getNodePath());


              //osg::Matrixf mat(m);

              osg::PositionAttitudeTransform *pat = dynamic_cast<osg::PositionAttitudeTransform *>(node);
              pat->setPosition(mat.getTrans());
              pat->setAttitude(mat.getRotate());

              I3D_LOG(notification) << mat.getTrans().x() << ", " << mat.getTrans().y() << ", " << mat.getTrans().z() << std::endl;

              traverse(node, nv);
           }
      };




cpp:

Code:

osg::MatrixTransform* PhysicsCube::createNode(double length, double mass, btDynamicsWorld* dynamicsWorld, osg::Vec3d position)
{

   _length = length;
   _mass = mass;
   _dynamicsWorld = dynamicsWorld;

   position = osg::Vec3d(0,0,0);
   
   // OSG CODE
   osg::ref_ptr< osg::MatrixTransform > node = new osg::MatrixTransform;
   

   osg::Geode* geodeBox = new osg::Geode();

   osg::Box* box = new osg::Box(position, _length );
   _boxDrawable = new osg::ShapeDrawable(box);

   _boxDrawable->setColor(osg::Vec4d(0.5, 0.5, 1.0, 1.0));

   geodeBox->addDrawable(_boxDrawable);

   node->addChild(geodeBox);

   // OSGBBULLET CODE
   osgbBullet::MotionState * motion = new osgbBullet::MotionState;
   motion->setTransform( node.get() );
   btCollisionShape * collision = osgbBullet::btConvexTriMeshCollisionShapeFromOSG( node.get() );

   
   // BULLET CODE
   btTransform bodyTransform;
   bodyTransform.setIdentity();
   bodyTransform.setOrigin( btVector3( 0, 0, 0 ) );
   motion->setWorldTransform( bodyTransform );

   btScalar objectMass( mass );
   btVector3 inertia;
   collision->calculateLocalInertia( objectMass, inertia );
   btRigidBody::btRigidBodyConstructionInfo rbinfo( objectMass, motion, collision, inertia );
    _body = new btRigidBody( rbinfo );
   //   body->setLinearVelocity( btVector3( -5, -1, 0 ) );
   //  body->setAngularVelocity( btVector3( 1, 0, 0 ) );
   dynamicsWorld->addRigidBody(_body );


   return( node.release() );
}

void PhysicsCube::createGeometry(void)
{
}

void PhysicsCube::setColor( osg::Vec4d color )
{
   _boxDrawable->setColor(color);
}

btRigidBody * PhysicsCube::getBody( void )
{
   return _body;
}





I use the physicsCube like this:

Code:

_cNode = new I3DENGINE::Physics::PhysicsCube;
osg::PositionAttitudeTransform *temp = new osg::PositionAttitudeTransform;
temp->addChild(_cNode->createNode(length, mass, dynamicsWorld, position));
temp->addChild(_sNode);

temp->setPosition(osg::Vec3d(0,0,100)); // <- does not work correctly

temp->setUpdateCallback(new I3DENGINE::Physics::BallUpdateCallback(_cNode->getBody()));
return temp;





What has to be changed so that the node's position will be updated according to the physic's node location?
Sorry for my bad english!

Thank you!

Cheers,
Marco

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=38211#38211








More information about the osg-users mailing list