Physics Simulation Forum


All times are UTC

Post new topic Reply to topic  [ 6 posts ] 
Author Message
PostPosted: Sun Mar 19, 2017 10:12 pm 

Joined: Tue Jan 31, 2017 8:07 pm
Posts: 23
I've been trying to get firing of projectiles to work in my project for a while now. I'm making a basic first person shooter with OpenGL and Bullet, but so far have only been able to fire projectiles based on the camera's position, and not it's rotation (i.e. my projectiles currently always spawn in front of the camera's XYZ position, regardless of which way I've orientated the camera).

Applying physics to an object defined at a point in XYZ coordinates isn't a problem, the problem is just firing a rigidBody from any camera angle. For example, if I'm facing forward and my gun is facing straight ahead, the projectile is created in front of me and appears just after the gun model ends. But, if I turn to the right, the projectile is still created at the same location.

My current method for trying to get this to work is to draw a projectile with OpenGL in front of the camera, and then rotate it based on the camera's orientation (like the projectile orbits the camera). Then I would get the world-coordinates from the model-to-world matrix, and give those to the rigidBody constructor (for the motionstate).

So since this is giving me some issues, does anyone have any suggestions for alternate/better ways to do this? Does anyone have experience with getting this to work?


PostPosted: Sun Mar 19, 2017 11:16 pm 

Joined: Thu Apr 14, 2016 3:44 pm
Posts: 32
Cameras tend to be represented in opengl with a view matrix and projection matrix, create a 3x3 rotation matrix or a quaternion from the view matrix and multiply that by a forward vector like (0,0,1) to get a normal that points where the camera looks. Add this to offset your rigid body's creation location and the rigid body can be shot in this direction by multiplying the normal by a magnitude; myBullet.setLinearVelocity(myForwardVector * magnitude);

PostPosted: Mon Mar 20, 2017 9:04 pm 

Joined: Tue Jan 31, 2017 8:07 pm
Posts: 23
Thanks for the tip, although I'm not entirely sure how I'd do what you suggested.

I currently have this on each click:

// This should be the bullet's world-coordinates, right now it just draws infront of the player
bulletPositions[shots] = glm::vec3(getPosition().x+0.3, getPosition().y, getPosition().z-2);
// This should be the bullet's world-rotation, right now it just takes the camera's angles with an offset
bulletRotations[shots] = glm::normalize(glm::quat(glm::vec3(1.5708-getVertical(), 0.03054326+getHorizontal(), 0)));

btDefaultMotionState* bulletMotionstate = new btDefaultMotionState(btTransform(
   btQuaternion(bulletRotations[shots].x, bulletRotations[shots].y, bulletRotations[shots].z, bulletRotations[shots].w),
   btVector3(bulletPositions[shots].x, bulletPositions[shots].y, bulletPositions[shots].z)

btRigidBody::btRigidBodyConstructionInfo bulletRigidBodyCI(bulletMass, bulletMotionstate, bulletCollisionShape, bulletInertia);
bulletRigidBody = new btRigidBody(bulletRigidBodyCI);


How can I get a rotation quaternion from the view matrix, a forward vector, where would I add the offset etc.? I'm currently doing just this:
mat4 inverseViewMatrix = inverse(ViewMatrix);
vec3 cameraPos(inverseViewMatrix[3]);

glm::quat ViewRotation = (glm::quat)ViewMatrix;
//glm::vec3 forward = (glm::vec3)(0, 0, 1); Tried this
glm::vec3 normal = normalize(ViewRotation * cameraPos);
std::cout << glm::to_string(normal) << std::endl;

I'm getting values roughly in the range of -1 to 1 for each axis in the print-out, is that correct? I'd still be unsure about where to use the normal exactly though, as I'm not too familiar with Bullet at this stage, so example code would really help. Thanks.

PostPosted: Thu Mar 23, 2017 11:21 am 

Joined: Thu Mar 23, 2017 11:17 am
Posts: 2
You can try get information in this page:!Getting-started/Camera
Here is some information about how to get and use the forward and the up vector of the camera :D :D :D

PostPosted: Thu Mar 23, 2017 9:38 pm 

Joined: Mon Jul 11, 2016 10:36 am
Posts: 2
You may want to first cast a ray and then fire. Here below is a way do it, the variable direction in the second snippet is coming from the raycast or could be the position of your camera.

glm::vec3 Camera::castRay(glm::ivec2 mousePosition) {

   logStderr(VERBOSE, "mouse position %d, %d...\n", mousePosition.x, mousePosition.y);

   float tanFOV = 1.0f / NEAR_PLANE;
   float aspect = WINDOW_WIDTH / (float)WINDOW_HEIGHT;

   glm::vec3 viewVector = -glm::normalize(m_viewVector);
   viewVector *= FAR_PLANE;

   glm::vec3 upVector = glm::normalize(m_upVector);
   upVector *= FAR_PLANE * tanFOV;

   glm::vec3 rightVector = glm::normalize(m_rightVector);
   rightVector *= FAR_PLANE * tanFOV;
   rightVector *= aspect;

   glm::vec3 center = m_cameraPosition + viewVector;                             

   glm::vec3 horizontalDistance = 1.0f / float(WINDOW_WIDTH) * rightVector;
   glm::vec3 verticalDistance = upVector / float(WINDOW_HEIGHT);

   glm::vec3 raycast = center - 0.5f * rightVector + 0.5f * upVector;

   raycast += (float)mousePosition.x * horizontalDistance;
   raycast -= (float)mousePosition.y * verticalDistance;

   logFileStderr(VERBOSE, "raycast: "); printVec3(raycast);

   return raycast;

void Inception::shootGeode(std::string typeGeode, const btVector3& direction) {

   logStderr(VERBOSE, "MESSAGE: Shooting geode(s)...\n");

   std::shared_ptr<Geode> geode;

   glm::vec3 cameraPosition = m_camera->getPosition();
   btVector3 position = glm2bullet(cameraPosition + 3.0f * glm::normalize(m_camera->getTarget() - cameraPosition));

   if (typeGeode == "cube")
      geode = m_objectFactory->createCube("cube", new btBoxShape(btVector3(1.0f, 1.0f, 1.0f)), position, "dice");

   if (typeGeode == "sphere")
      geode = m_objectFactory->createSphere("sphere", new btBoxShape(btVector3(1.0f, 1.0f, 1.0f)), position);

   btVector3 velocity = direction;
   velocity *= 25.0f;


PostPosted: Fri Mar 24, 2017 1:02 am 

Joined: Tue Jan 31, 2017 8:07 pm
Posts: 23
Thanks for the suggestions, I've looked at that tutorial but I'm still unsure unfortunately. :/

And although many games go for the "using raycast then firing" method, but unfortunately I can't since I need my bullet to appear after my gun model and look as if it's actually being fired since I'm drawing its path through the scene.

Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC

Who is online

Users browsing this forum: Google [Bot] and 16 guests

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group