I'm using bullet to simulate a player holding a piece of wood.
The piece of wood is offset just infront of the player pointing upward. This is the dynamic body
The player can rotate the camera, and with it a kinematic body offset to the base of the dynamic body
The wood dynamic body is linked to the players kinematic body via a hinge contraint.
So when the player rotates the camera, it rotates the kinematic body (via a motionstate) and with it the hinge
and the attached dynamic body.
This works and I can rotate around, with the wood following me.
The problem is, if I rotate too quickly, the dynamic body (wood), vibrates side to side.
Only a small distance but at a high frequency so it is noticeable.
Below is my code, I'm afraid I'm using osg bullet so it may look a little strange
Code: Select all
axeOffset = axenode->getWorldMatrices()[0];//*osg::Matrix::translate(comOffset);
_playerMotionState = new GyroAttachedMotionState(axeOffset);
btRigidBody::btRigidBodyConstructionInfo rbInfo(btScalar(0), _playerMotionState, new btBoxShape(btVector3(1.0f, 1.0f, 1.0f)),
btVector3(btScalar(0), btScalar(0), btScalar(0)));
playerBody = new btRigidBody(rbInfo);
playerBody->setCollisionFlags(playerBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
playerBody->setActivationState(DISABLE_DEACTIVATION);
osgBulletUtils::getPhysicsWorld()->addRigidBody(playerBody);
axenode->setMatrix(osg::Matrix());
axenode->getParent(0)->removeChild(axenode);
scene->asGroup()->addChild(axenode);
//create the rigid body represnting the axe
osg::ref_ptr< osgbDynamics::CreationRecord > cr = new osgbDynamics::CreationRecord;
cr->_sceneGraph = axenode; //use the axe sub graph to generate the body
cr->_mass = 1.;
cr->_shapeType = CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE; //try using tri mesh to represent the axe
cr->_parentTransform = axeOffset; //axe pivot seems to alreadt be at origin so we can use identity
//cr->setCenterOfMass(comOffset);
axeBody = osgbDynamics::createRigidBody( cr.get());
axeBody->setActivationState( DISABLE_DEACTIVATION );
//add the rigid body to the physics sim
osgBulletUtils::getPhysicsWorld()->addRigidBody(axeBody, COL_AXE, axeCollidesWith);
//compute the position of the hinges pivot
//in axeBody coord space
osg::Vec3 osgOrigin = osg::Vec3(0.0,0.0,0.0);
btTransform m = axeBody->getWorldTransform();
btVector3 v = m.getOrigin();
osg::Vec3 bulletOrigin = osgbCollision::asOsgVec3(v);
osg::Vec3 axisOffset = osgOrigin - bulletOrigin;
//create the physics hinge to constrain our rigid body
const btVector3 btPivot = osgbCollision::asBtVector3(axisOffset);
btVector3 btAxisA( 1.0f, 0.0f, 0.0f );
btVector3 btPivotB( 0.0, 0.0f, 0.0f );
hinge = new btHingeConstraint( *axeBody, *playerBody, btPivot, btPivotB, btAxisA, btAxisA );
hinge->setLimit( M_PI*0.25f, M_PI );
//apply a motor to the axe hinge so it pushes back against the log
//and back into position when removed
float targetVelocity = -100000.0f;
float maxMotorImpulse = 100000.0f;//this has to be high enough to resist the axe falling back
hinge->setMotorTarget(0, 2.0f);
hinge->enableAngularMotor(true, targetVelocity,maxMotorImpulse);
//add the hinge to the physics world
osgBulletUtils::getPhysicsWorld()->addConstraint( hinge, true );
The motor force is to stop the piece of wood falling backward, the limits then stop
it going too far forward. The idea is that the hinge will allow the user to walk
into objects and the piece of wood will lean backward a little rather then just trying
to drive straight through it (like if it was a kinematic object).
Anyhow, I hope I've explained myself. Any more info needed let me know
Cheers
Tom
PS
The sim is running at around 40 fps if it's relevant