## [SOLVED] Best method for firing projectiles from camera?

jimjamjack
Posts: 39
Joined: Tue Jan 31, 2017 8:07 pm

### [SOLVED] Best method for firing projectiles from camera?

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?

Cheers.

ktfh
Posts: 44
Joined: Thu Apr 14, 2016 3:44 pm

### Re: Best method for firing projectiles from camera?

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);

jimjamjack
Posts: 39
Joined: Tue Jan 31, 2017 8:07 pm

### Re: Best method for firing projectiles from camera?

Thanks for the tip, although I'm not entirely sure how I'd do what you suggested.

How can I get a rotation quaternion from the view matrix, a forward vector, where would I add the offset etc.?
Last edited by jimjamjack on Mon May 01, 2017 9:52 pm, edited 1 time in total.

Ziket
Posts: 3
Joined: Thu Mar 23, 2017 11:17 am

### Re: Best method for firing projectiles from camera?

Hi!.
Here is some information about how to get and use the forward and the up vector of the camera

LastBlow
Posts: 6
Joined: Mon Jul 11, 2016 10:36 am

### Re: Best method for firing projectiles from camera?

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.

Code: Select all

``````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.normalize();
velocity *= 25.0f;

geode->getRigidBody()->setLinearVelocity(velocity);
}``````

jimjamjack
Posts: 39
Joined: Tue Jan 31, 2017 8:07 pm

### Re: Best method for firing projectiles from camera?

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.

ktfh
Posts: 44
Joined: Thu Apr 14, 2016 3:44 pm

### Re: Best method for firing projectiles from camera?

still stuck on this? I think you almost had it figure out.
something like this should offset and shoot your bullet forward or backward.

Code: Select all

``````float power = 10.f;
glm::vec3 forward = glm::mat3(glm::inverse(ViewMatrix)) * glm::vec3(0,0,1);
glm::vec3 origin = cameraPos + forward;
glm::vec3 vel = forward * power;
myBulletBody.getWorldTransform().setOrigin(btVector3(origin.x,origin,y,origin.z));
myBulletBody.setLinearVelocity(vel.x,vel.y,vel.z);
``````

jimjamjack
Posts: 39
Joined: Tue Jan 31, 2017 8:07 pm

### Re: Best method for firing projectiles from camera?

Thanks guys, works perfectly now. I was just infuriatingly close :p

Using ktfh's method was definitely the best way of doing this (and here I was, trying to do some complex matrix manipulation in OpenGL). Really helped, so cheers.