I made a 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: Select all
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);
}
};
Code: Select all
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;
}
Code: Select all
_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;
Sorry for my bad english!
Thanks!