How to simule shoots from a weapon with Bullet+Ogre

Post Reply
i7.strelok
Posts: 21
Joined: Fri Jan 20, 2017 10:44 pm

How to simule shoots from a weapon with Bullet+Ogre

Post by i7.strelok »

I need apply a impulse to my bullet object, but not works.

Code: Select all

void Physics::initObjects(){
    collisionConfiguration = new btDefaultCollisionConfiguration();
    dispatcher = new btCollisionDispatcher(collisionConfiguration);
    overlappingPairCache = new btDbvtBroadphase();
    solver = new btSequentialImpulseConstraintSolver();
    dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration);
        dynamicsWorld->setGravity(btVector3(0,-10,0));
}

btDiscreteDynamicsWorld* Physics::getDynamicsWorld(){
    return dynamicsWorld;
}
std::vector<btCollisionShape *> Physics::getCollisionShapes(){
    return collisionShapes;
}
Play class:

Code: Select all

physicsEngine = new Physics();
  physicsEngine->initObjects();
  _fallShape = new btSphereShape(0.1);
  _groundShape = new btStaticPlaneShape(btVector3(0,1,0),1);

Code: Select all

bool
Play::frameStarted
(const Ogre::FrameEvent& evt)
{
   _deltaT = evt.timeSinceLastFrame;
   physicsEngine->getDynamicsWorld()->stepSimulation(_deltaT, 1); 
   return true;
}

Code: Select all

bool
Play::frameEnded
(const Ogre::FrameEvent& evt)
{
  physicsEngine->getDynamicsWorld()->stepSimulation(evt.timeSinceLastFrame, 1);
  
  return true;
}

Code: Select all

void Play::createBullet(){

  //here create node+entity
 
   MyMotionState* fallMotionState = new MyMotionState(
     btTransform(btQuaternion(oriWeapon.w, -oriWeapon.x, -oriWeapon.y, -oriWeapon.z),btVector3(posWeapon.x, posWeapon.y, posWeapon.z)), nodeStems);
  btScalar mass = 1;
  btVector3 fallInertia(0,0,0);
  _fallShape->calculateLocalInertia(mass,fallInertia);
  btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(
     mass,fallMotionState,_fallShape,fallInertia);
  _fallRigidBody = new btRigidBody(fallRigidBodyCI);
  physicsEngine->getDynamicsWorld()->addRigidBody(_fallRigidBody);
  _fallRigidBody->activate(true); 
  btVector3 impulse = btVector3(0.f,0.f,20000.f);
  _fallRigidBody->setLinearVelocity(btVector3(0,0,20000));
  _fallRigidBody->applyCentralImpulse(impulse);//
  
}
I need help you, for apply a impulse or force, please.
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: How to simule shoots from a weapon with Bullet+Ogre

Post by drleviathan »

By default a btRigidBody is initialized to be static. In other words: the btCollisionObject::m_collisionFlags data member is initialized to btCollisionObject::CF_STATIC_OBJECT.

In order to create a dynamic object you need remove the static flag before you add it to the btDynamicsWorld:

Code: Select all

_fallingBody->setCollisionFlags(_fallingBody->getCollisionFlags() & ~btCollisionObject::CF_STATIC_OBJECT);
i7.strelok
Posts: 21
Joined: Fri Jan 20, 2017 10:44 pm

Re: How to simule shoots from a weapon with Bullet+Ogre

Post by i7.strelok »

So, if I add that line automatically adds a dynamic body?

My weapon moves, how can I do to shoot correctly ?. Currently it moves only in Z, but I do not understand how to make it respect the rules of the real world.
If I shoot at the sky, the bullet must move in both Y and Z, if I shoot only straight, it must move in Z only.
How can i fix this?


I used google translate.
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: How to simule shoots from a weapon with Bullet+Ogre

Post by drleviathan »

Your weapon has local XYZ axes. I will assume it shoots along the local-Z axis. In order to shoot in the correct direction in the world-frame you need to figure out the direction your weapon's Z-axis points when transformed into the world-frame.

Get the transform of your weapon in the world-frame and

Code: Select all

btTransform weaponTransform = weapon->getWorldTransform();
Get the rotation part:

Code: Select all

btTransform weqponRotation = weaponTransform;
weaponRotation.setOrigin(btVector3(0.0, 0.0, 0.0));
Compute the rotated local Z-axis of the gun:

Code: Select all

btVector3 localZ(0.0, 0.0, 1.0);
shootDirection = weaponRotation * localZ;
The velocity of the bullet is scaled by the speed

Code: Select all

btScalar bulletSpeed = 20000.0;
btVector3 bulletVelocity = bulletSpeed * shootDirection;
The starting position of the bullet is the weapon center plus an offset (I will assume 0.5 meter along z-axis)

Code: Select all

btScalar weaponBarrelLength = 0.5;
btVector3 bulletPosition = weaponTransform.getOrigin() + weaponBarrelLength * (weaponRotation * localZ);
Set the velocity and position of the bullet:

Code: Select all

bullet->setLinearVelocity(bulletVelocity);
btTransform bulletTransform = weaponRotation;
bulletTransform.setOrigin(bulletPosition);
bullet->setWorldTransform(bulletTransform);
i7.strelok
Posts: 21
Joined: Fri Jan 20, 2017 10:44 pm

Re: How to simule shoots from a weapon with Bullet+Ogre

Post by i7.strelok »

I'm very noob in bullet,

This is my full code:

Code: Select all

string idBullet = static_cast<std::ostringstream*>(&(std::ostringstream() << _contador))->str(); 
  Ogre::Entity* entBullet = _sceneMgr->createEntity("Bullet"+idBullet+"Ent", "Circle.mesh");
  Ogre::SceneNode* nodeBullet =  _sceneMgr->getRootSceneNode()->createChildSceneNode("NodeBullet" + idBullet);
  nodeBullet->attachObject(entBullet);
  Ogre::Vector3 posWeapon =  _nodeParentWeapon->convertLocalToWorldPosition(_sceneMgr->getSceneNode("NodeWeapon2")->getPosition());
  Ogre::Quaternion oriWeapon =  _nodeParentWeapon->convertLocalToWorldOrientation(_sceneMgr->getSceneNode("NodeWeapon2")->getOrientation());
  posWeapon = _camera->getRealPosition();
  posWeapon.y += 0.8;
  posWeapon.z += 0.8;
  nodeBullet->setPosition(posWeapon);
  nodeBullet->setOrientation(_camera->getRealOrientation());
 
   MyMotionState* fallMotionState = new MyMotionState(
     btTransform(btQuaternion(oriWeapon.w, -oriWeapon.x, -oriWeapon.y, -oriWeapon.z),btVector3(posWeapon.x, posWeapon.y, posWeapon.z)), nodeBullet);
  btScalar mass = 0.1;
  btVector3 fallInertia(0,0,0);
  _fallShape->calculateLocalInertia(mass,fallInertia);
  btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(
     mass,fallMotionState,_fallShape,fallInertia);
  _fallRigidBody = new btRigidBody(fallRigidBodyCI);
  _fallRigidBody->setCollisionFlags(_fallRigidBody->getCollisionFlags() & ~btCollisionObject::CF_STATIC_OBJECT);
  physicsEngine->getDynamicsWorld()->addRigidBody(_fallRigidBody);
  _fallRigidBody->activate(true); 
  btVector3 impulse = btVector3(10,0,0);
  _fallRigidBody->setLinearFactor( btVector3 ( 1 , 0 , 0 ));
  _fallRigidBody->applyCentralImpulse(impulse);

What is your "weapon" is a node ogre or rigid body?
Currently my weapon is simply an Ogre node, it is not included in the physics.
Do I need to include it?
i7.strelok
Posts: 21
Joined: Fri Jan 20, 2017 10:44 pm

Re: How to simule shoots from a weapon with Bullet+Ogre

Post by i7.strelok »

drleviathan wrote:Your weapon has local XYZ axes. I will assume it shoots along the local-Z axis. In order to shoot in the correct direction in the world-frame you need to figure out the direction your weapon's Z-axis points when transformed into the world-frame.

Get the transform of your weapon in the world-frame and

Code: Select all

btTransform weaponTransform = weapon->getWorldTransform();
Get the rotation part:

Code: Select all

btTransform weqponRotation = weaponTransform;
weaponRotation.setOrigin(btVector3(0.0, 0.0, 0.0));
Compute the rotated local Z-axis of the gun:

Code: Select all

btVector3 localZ(0.0, 0.0, 1.0);
shootDirection = weaponRotation * localZ;
The velocity of the bullet is scaled by the speed

Code: Select all

btScalar bulletSpeed = 20000.0;
btVector3 bulletVelocity = bulletSpeed * shootDirection;
The starting position of the bullet is the weapon center plus an offset (I will assume 0.5 meter along z-axis)

Code: Select all

btScalar weaponBarrelLength = 0.5;
btVector3 bulletPosition = weaponTransform.getOrigin() + weaponBarrelLength * (weaponRotation * localZ);
Set the velocity and position of the bullet:

Code: Select all

bullet->setLinearVelocity(bulletVelocity);
btTransform bulletTransform = weaponRotation;
bulletTransform.setOrigin(bulletPosition);
bullet->setWorldTransform(bulletTransform);

Please you could show me how you would do the full code of the "createBullet" function using another graphic engine that you know, so I will replace that part with the one of ogre and that's it. I'm frustrated
Post Reply