First Person Shoot Game !! Basic Physics

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

First Person Shoot Game !! Basic Physics

Post by i7.strelok » Tue Apr 25, 2017 10:41 pm

Hi, I'm going to detail my situation so that someone can help me.
First I want to clarify that I am using a translator because my English is not good.

I'm using the Ogre3D rendering engine and I need to make use of Bullet Physics for my University project.

The truth is that they have not taught us how to do it, I must learn it on my own and I find it very difficult since I have never worked with a physical simulation engine.

They were only given a class called "MyMotionState" which is as follows:

Code: Select all

#include "MyMotionState.h"

MyMotionState::MyMotionState(const btTransform &initialpos, Ogre::SceneNode *node){
  _visibleobj = node;
  _pos = initialpos;
}

MyMotionState::~MyMotionState(){ }

void MyMotionState::setNode(Ogre::SceneNode *node) {
  _visibleobj = node;
}
  
void MyMotionState::getWorldTransform(btTransform &worldTrans) const {
  worldTrans = _pos;
}
  
void MyMotionState::setWorldTransform(const btTransform &worldTrans) {
  if(NULL == _visibleobj) return; // Si no hay nodo, return 
  btQuaternion rot = worldTrans.getRotation();
  _visibleobj->setOrientation(rot.w(), rot.x(), rot.y(), rot.z());
  btVector3 pos = worldTrans.getOrigin();
  _visibleobj->setPosition(pos.x(), pos.y(), pos.z());
}
There are 2 ways to integrate Bullet with Ogre, one is to use the wrapper "OgreBullet" and the other way is to do it manually.
I can not compile OgreBullet and in the University I have not been given a solution, I only have to do manual integration.


Very well now I will explain my game.
I have the gun well positioned, and the camera also, for the moment the Player is not going to be able to move, it will only be able to move your mouse freely.

I need to know which rigid bodies I have to create, for the moment I have created a class called "Physics"

Code: Select all

#include "Physics.h"

Physics::Physics() {
}

Physics::Physics(const Physics& orig) {
}

Physics::~Physics() {
 
}

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;
}
The only rigid bodies I am creating for the moment are bullets, first I create the entity, then the node, then assign the position

Code: Select all

void PlayState::createBullet(){
  _contador++;  
  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 =  _sceneMgr->getRootSceneNode()->convertLocalToWorldPosition(_nodePerson->getPosition());
  Ogre::Quaternion oriWeapon =  _sceneMgr->getRootSceneNode()->convertLocalToWorldOrientation(_nodePerson->getOrientation());
  posWeapon.y = posWeapon.y + 3;
  posWeapon = _camera->getRealPosition();
  oriWeapon = _camera->getRealOrientation();
  nodeBullet->setPosition(posWeapon);
  nodeBullet->setOrientation(oriWeapon);

 
   MyMotionState* fallMotionState = new MyMotionState(
     btTransform(btQuaternion(0,0,0,1),btVector3(0,0,0)), 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); 

  
  btTransform weaponTransform(btQuaternion(oriWeapon.x, oriWeapon.y, oriWeapon.z, oriWeapon.w),btVector3(posWeapon.x, posWeapon.y, posWeapon.z)); 
  btTransform weaponRotation = weaponTransform;
  weaponRotation.setOrigin(btVector3(0.0, 0.0, 0.0));
  btVector3 localZ(0.0, 0.0, 1.0);
  btVector3 shootDirection = weaponRotation * localZ;
  btScalar bulletSpeed = 20000.0;
  btVector3 bulletVelocity = bulletSpeed * shootDirection;
  btScalar weaponBarrelLength = 0.5;
  btVector3 bulletPosition = weaponTransform.getOrigin() + weaponBarrelLength * (weaponRotation * localZ);
  _fallRigidBody->setLinearVelocity(bulletVelocity);
  btTransform bulletTransform = weaponRotation;
  bulletTransform.setOrigin(bulletPosition);
  _fallRigidBody->setWorldTransform(bulletTransform);
  
}
Shoot at a realistic speed, the problem is this: When I move the mouse towards the sky or towards the floor, the bullet continues to move only on the Z axis, as if it were shooting straight.
I really do not know how to solve it.

I do not mind having a good physics, I just want basic physics.
I want the bullet to move in the appropriate direction.
Then I will be interested to know about collision, but for the moment this is the problem that I want to solve.

User avatar
drleviathan
Posts: 630
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: First Person Shoot Game !! Basic Physics

Post by drleviathan » Tue Apr 25, 2017 11:32 pm

Most of your code looks okay to me. If the bullet only shoots along Z-axis then my guess is: oriWeapon is not getting the values you expect.

Print out the values of oriWeapon to verify that its values change with the mouse.

By the way, I notice that you set the value of oriWeapon twice before you use it. Maybe the second value is not the one you want?

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

Re: First Person Shoot Game !! Basic Physics

Post by i7.strelok » Wed Apr 26, 2017 12:21 am

drleviathan wrote:Most of your code looks okay to me. If the bullet only shoots along Z-axis then my guess is: oriWeapon is not getting the values you expect.

Print out the values of oriWeapon to verify that its values change with the mouse.

By the way, I notice that you set the value of oriWeapon twice before you use it. Maybe the second value is not the one you want?
I was doing a lot of tests so I assigned different values.
But if I point to the sky it must move in 2 axes, right? Only in Z no.

Ok, I did what you said to me:

Code: Select all

 cout<<"Orientation camera: "<<_camera->getRealOrientation()<<endl; 
 cout<<"Orientation nodeParent derivated: "<<_nodePerson->_getDerivedOrientation()<<endl; 
 Ogre::Quaternion oriWeapon =  _sceneMgr->getRootSceneNode()->convertLocalToWorldOrientation(_nodePerson->getOrientation());
 cout<<"Orientation world: "<<oriWeapon<<endl
;

Code: Select all

Orientation camera: Quaternion(0.128191, -4.23188e-05, -0.991744, -0.00410157)
Orientation nodeParent derivated: Quaternion(0.990035, -0.0216026, 0.13914, 0.00303605)
Orientation world: Quaternion(0.990035, -0.0216026, 0.13914, 0.00303605)
Orientation camera: Quaternion(0.129923, 8.30465e-05, -0.991522, -0.00323895)
Orientation nodeParent derivated: Quaternion(0.989772, -0.0224611, 0.140865, 0.00319668)
Orientation world: Quaternion(0.989772, -0.0224611, 0.140865, 0.00319668)
Orientation camera: Quaternion(0.132519, 0.000209349, -0.991181, -0.00237697)
Orientation nodeParent derivated: Quaternion(0.98938, -0.023316, 0.143453, 0.00338066)
Orientation world: Quaternion(0.98938, -0.023316, 0.143453, 0.00338066)
Orientation camera: Quaternion(0.133384, 0.000207274, -0.991064, -0.00237715)
Orientation nodeParent derivated: Quaternion(0.989254, -0.0233131, 0.144316, 0.00340101)
Orientation world: Quaternion(0.989254, -0.0233131, 0.144316, 0.00340101)
Orientation camera: Quaternion(0.135978, 0.000201049, -0.990712, -0.00237768)
Orientation nodeParent derivated: Quaternion(0.988873, -0.0233041, 0.146906, 0.00346203)
Orientation world: Quaternion(0.988873, -0.0233041, 0.146906, 0.00346203)
Orientation camera: Quaternion(0.138571, 0.000194824, -0.990353, -0.0023782)
Orientation nodeParent derivated: Quaternion(0.988485, -0.0232949, 0.149494, 0.00352303)
Orientation world: Quaternion(0.988485, -0.0232949, 0.149494, 0.00352303)
Orientation camera: Quaternion(0.141164, 0.000188598, -0.989986, -0.0023787)
Orientation nodeParent derivated: Quaternion(0.98809, -0.0232856, 0.152082, 0.003584)
Orientation world: Quaternion(0.98809, -0.0232856, 0.152082, 0.003584)
Orientation camera: Quaternion(0.143755, 0.000182369, -0.989613, -0.00237919)
Orientation nodeParent derivated: Quaternion(0.987689, -0.0232762, 0.154668, 0.00364495)
Orientation world: Quaternion(0.987689, -0.0232762, 0.154668, 0.00364495)
Orientation camera: Quaternion(0.148071, 0.000171986, -0.988977, -0.00237996)
Orientation nodeParent derivated: Quaternion(0.987004, -0.02326, 0.158976, 0.00374648)
Orientation world: Quaternion(0.987004, -0.02326, 0.158976, 0.00374648)
Orientation camera: Quaternion(0.149797, 0.000167832, -0.988717, -0.00238026)
Orientation nodeParent derivated: Quaternion(0.986726, -0.0232535, 0.160698, 0.00378707)
Orientation world: Quaternion(0.986726, -0.0232535, 0.160698, 0.00378707)
Orientation camera: Quaternion(0.152385, 0.000161601, -0.988322, -0.00238069)
Orientation nodeParent derivated: Quaternion(0.986302, -0.0232435, 0.163281, 0.00384793)
Orientation world: Quaternion(0.986302, -0.0232435, 0.163281, 0.00384793)
Orientation camera: Quaternion(0.157558, 0.000149133, -0.98751, -0.00238151)
Orientation nodeParent derivated: Quaternion(0.985433, -0.023223, 0.168443, 0.00396958)
Orientation world: Quaternion(0.985433, -0.023223, 0.168443, 0.00396958)
Orientation camera: Quaternion(0.160143, 0.000142897, -0.987094, -0.00238189)
Orientation nodeParent derivated: Quaternion(0.984989, -0.0232125, 0.171022, 0.00403036)
Orientation world: Quaternion(0.984989, -0.0232125, 0.171022, 0.00403036)
Orientation camera: Quaternion(0.161865, 0.000138741, -0.986813, -0.00238214)
Orientation nodeParent derivated: Quaternion(0.984689, -0.0232055, 0.172741, 0.00407087)
Orientation world: Quaternion(0.984689, -0.0232055, 0.172741, 0.00407087)
Orientation camera: Quaternion(0.165309, 0.000130424, -0.986242, -0.00238261)
Orientation nodeParent derivated: Quaternion(0.98408, -0.0231911, 0.176177, 0.00415185)
Orientation world: Quaternion(0.98408, -0.0231911, 0.176177, 0.00415185)
Orientation camera: Quaternion(0.16703, 0.000126266, -0.985952, -0.00238283)
Orientation nodeParent derivated: Quaternion(0.983771, -0.0231838, 0.177895, 0.00419232)
Orientation world: Quaternion(0.983771, -0.0231838, 0.177895, 0.00419232)
Orientation camera: Quaternion(0.168751, 0.000122107, -0.985659, -0.00238305)
Orientation nodeParent derivated: Quaternion(0.983459, -0.0231765, 0.179611, 0.00423278)
Orientation world: Quaternion(0.983459, -0.0231765, 0.179611, 0.00423278)
Orientation camera: Quaternion(0.17219, 0.000113788, -0.985064, -0.00238346)
Orientation nodeParent derivated: Quaternion(0.982826, -0.0231616, 0.183043, 0.00431365)
Orientation world: Quaternion(0.982826, -0.0231616, 0.183043, 0.00431365)
Orientation camera: Quaternion(0.173909, 0.000109628, -0.984762, -0.00238365)
Orientation nodeParent derivated: Quaternion(0.982505, -0.023154, 0.184758, 0.00435407)
Orientation world: Quaternion(0.982505, -0.023154, 0.184758, 0.00435407)
Orientation camera: Quaternion(0.177346, 0.000101307, -0.984149, -0.00238402)
Orientation nodeParent derivated: Quaternion(0.981854, -0.0231387, 0.188187, 0.00443487)
Orientation world: Quaternion(0.981854, -0.0231387, 0.188187, 0.00443487)
Orientation camera: Quaternion(0.182496, 8.8823e-05, -0.983207, -0.00238452)
Orientation nodeParent derivated: Quaternion(0.980856, -0.0231151, 0.193325, 0.00455596)
Orientation world: Quaternion(0.980856, -0.0231151, 0.193325, 0.00455596)
Orientation camera: Quaternion(0.183354, 8.6742e-05, -0.983048, -0.0023846)
Orientation nodeParent derivated: Quaternion(0.980686, -0.0231111, 0.194181, 0.00457613)
Orientation world: Quaternion(0.980686, -0.0231111, 0.194181, 0.00457613)
Orientation camera: Quaternion(0.186784, 7.84183e-05, -0.982402, -0.00238489)
Orientation nodeParent derivated: Quaternion(0.980003, -0.023095, 0.197603, 0.00465677)
Orientation world: Quaternion(0.980003, -0.023095, 0.197603, 0.00465677)
I have a video for you: https://1drv.ms/f/s!ArGUObDbqeovhrlTduYarEGPEUb9Vw

User avatar
drleviathan
Posts: 630
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: First Person Shoot Game !! Basic Physics

Post by drleviathan » Wed Apr 26, 2017 6:53 am

I don't know Ogre so it isn't clear to me if you are computing the correct oriWeapon. Try using the _camera->getRealOrientation() to compute the bulletDirection to see if that works.

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

Re: First Person Shoot Game !! Basic Physics

Post by i7.strelok » Wed Apr 26, 2017 9:25 am

You mean this?

Code: Select all

  btVector3 dirCam(_camera->getRealDirection().x, _camera->getRealDirection().y, _camera->getRealDirection().z);
  btVector3 shootDirection = dirCam * localZ;
It does not work, the bullet moves much more in Y

But, It is correct?

Code: Select all

   MyMotionState* fallMotionState = new MyMotionState(
     btTransform(btQuaternion(0,0,0,1),btVector3(0,0,0)), nodeBullet)
;

Or do I need to put the correct position?

User avatar
drleviathan
Posts: 630
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: First Person Shoot Game !! Basic Physics

Post by drleviathan » Wed Apr 26, 2017 3:48 pm

Code: Select all

btVector3 dirCam(_camera->getRealDirection().x, _camera->getRealDirection().y, _camera->getRealDirection().z);
btVector3 shootDirection = dirCam * localZ;
No that is not right. You're multiplying two vectors together. I think that operation multiplies each component of vectorA with the corresponding component of vectorB. Not what you want.

Try this:

Code: Select all

Ogre::Vector3 cameraDirection = _camera->getRealDirection();
btVector3 shootDirection(cameraDirection.x, cameraDirection.y, cameraDirection.z);
In other words: shoot in the direction the camera points.

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

Re: First Person Shoot Game !! Basic Physics

Post by i7.strelok » Wed Apr 26, 2017 5:11 pm

Hi, I tried.
Can you watch my video?: https://1drv.ms/f/s!ArGUObDbqeovhrlTduYarEGPEUb9Vw

My full code is:

Code: Select all

void PlayState::createBullet(){
  _contador++;  
  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 =  _sceneMgr->getRootSceneNode()->convertLocalToWorldPosition(_nodePerson->getPosition());
  Ogre::Quaternion oriWeapon =  _sceneMgr->getRootSceneNode()->convertLocalToWorldOrientation(_nodePerson->getOrientation());
  posWeapon.y = posWeapon.y + 5;
  //posWeapon = _camera->getRealPosition();
  //oriWeapon = oriWeapon.Inverse();
  nodeBullet->setPosition(posWeapon);
  nodeBullet->setOrientation(oriWeapon);
  //nodeBullet->pitch(Ogre::Degree(270), Ogre::Node::TS_LOCAL);
  //nodeBullet->setScale(0.05,0.05,0.05);
  
 Ogre::ParticleSystem* sunParticle = _sceneMgr->createParticleSystem("Ps"+idBullet,"ringOfFire");
 sunParticle->setDefaultDimensions(0.01, 0.01);
 Ogre::SceneNode* particleNode = _sceneMgr->createSceneNode("NodeParticle"+idBullet);
 particleNode->attachObject(sunParticle);
 particleNode->setScale(0.001, 0.001, 0.001);
 particleNode->translate(posWeapon);
 nodeBullet->addChild(particleNode);

 // oriWeapon = oriWeapon.Inverse();
   MyMotionState* fallMotionState = new MyMotionState(
     btTransform(btQuaternion(oriWeapon.x, oriWeapon.y, oriWeapon.z, oriWeapon.w),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); 

  btTransform weaponTransform(btQuaternion(oriWeapon.x, oriWeapon.y, oriWeapon.z, oriWeapon.w),btVector3(posWeapon.x, posWeapon.y, posWeapon.z)); 
  btTransform weaponRotation = weaponTransform;
  weaponRotation.setOrigin(btVector3(0.0, 0.0, 0.0));
  btVector3 localZ(0.0, 0.0, 1.0);
  Ogre::Vector3 cameraDirection = _camera->getRealDirection();
  btVector3 shootDirection(cameraDirection.x, cameraDirection.y, cameraDirection.z);
  btScalar bulletSpeed = 20000.0;
  btVector3 bulletVelocity = bulletSpeed * shootDirection;
  btScalar weaponBarrelLength = 0.5;
  btVector3 bulletPosition = weaponTransform.getOrigin() + weaponBarrelLength * (weaponRotation * localZ);
  std::cout<<"Position: "<<bulletPosition<<" Direction: "<<shootDirection<<std::endl;
  _fallRigidBody->setLinearVelocity(bulletVelocity);
  btTransform bulletTransform = weaponRotation;
  bulletTransform.setOrigin(bulletPosition);
  _fallRigidBody->setWorldTransform(bulletTransform);
  
}
Please, help me!

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

Re: First Person Shoot Game !! Basic Physics

Post by i7.strelok » Wed Apr 26, 2017 8:04 pm

Sr. @drleviathan
Maybe what I need is easier. Maybe I'm making my problem even more complicated. Please watch the video that is in Outlook, I am trying to make a basic FPS game, I have a machine to shoot, that machine has animations, I need to detect when it shoots and hits one of those 4 targets.
I have never worked with a physics engine, I am pleased that Bullet is the first, but I find it very difficult.
I think I have to create 4 kinematic bodies and update their MotionState at the same time they run the animations, then make use of the "Ray" query or something like that.
However, you are the Expert, please recommend that I can use.

User avatar
drleviathan
Posts: 630
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: First Person Shoot Game !! Basic Physics

Post by drleviathan » Thu Apr 27, 2017 5:02 pm

i7.strelok, I'm happy to try to help but I don't think I will be effective at debugging your code remotely via the Bullet forums. If you have a particular question or problem please describe it clearly here. If I think I know the answer then I will reply.

Post Reply