3D world + shooting a projectile [Quake rocket launcher]?

Started by
8 comments, last by Bahati 15 years, 3 months ago
I have a FPS style 3D world with mouse look. Transforms are done with the following function, based on camera position, look, up and right vectors.

void updateViewMatrix( void )
{
    matrix4x4f view;
    view.identity();

    g_vLook.normalize();

    g_vRight = crossProduct(g_vLook, g_vUp);
    g_vRight.normalize();

    g_vUp = crossProduct(g_vRight, g_vLook);
    g_vUp.normalize();

    view.m[0] =  g_vRight.x;
    view.m[1] =  g_vUp.x;
    view.m[2] = -g_vLook.x;
    view.m[3] =  0.0f;

    view.m[4] =  g_vRight.y;
    view.m[5] =  g_vUp.y;
    view.m[6] = -g_vLook.y;
    view.m[7] =  0.0f;

    view.m[8]  =  g_vRight.z;
    view.m[9]  =  g_vUp.z;
    view.m[10] = -g_vLook.z;
    view.m[11] =  0.0f;

    view.m[12] = -dotProduct(g_vRight, g_vCameraPos);
    view.m[13] = -dotProduct(g_vUp, g_vCameraPos);
    view.m[14] =  dotProduct(g_vLook, g_vCameraPos);
    view.m[15] =  1.0f;

    glMultMatrixf( view.m );
}

I'm trying to shoot a sphere. My first idea is to save the camera related vectors at the moment of shooting. That should be the starting point of the sphere. Then I can move it through the world using the same methods I use to move the camera. My problem is figuring out the transforms needed in the rendering function given here:

void render( void )
{
	<SNIP>COLLISION DETECTION STUFF</SNIP>


	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	
	//SET UP 3D
	glEnable(GL_DEPTH_TEST);
	glMatrixMode( GL_PROJECTION );
	glPopMatrix();
	glMatrixMode( GL_MODELVIEW );
	glPopMatrix();
	glLoadIdentity();

	updateViewMatrix();


	<SNIP>DO THE 3D STUFF</SNIP>


// ****************************************
// DO THE SPHERE/PROJECTILE ???????????????
// ****************************************


	//SET UP 2D
	glDisable(GL_DEPTH_TEST);
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	gluOrtho2D(0,screenx,0,screeny);
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();


	<SNIP>DO THE 2D STUFF (CROSSHAIR)</SNIP>


    glutSwapBuffers();
}

I kind of understand what needs to be done, but it requires special care to separate the world and sphere transforms because the player can move while the sphere is "in flight" and that shouldn't affect it. I'm very much a noob, but common sense is telling me that this sort of thing must be done all the time, so I've put it here. I'm sorry if I've judged it wrong. Thank you in advance for any tips, code, links... anything that could help me do this ASAP, as time is an issue.
Advertisement
I know it'll probably sound vague and annoying, but you need to separate your idea that you're world and the way people see your game are exactly the same.

Take the position your gun is in, and the vector it is pointing in and use that as your missiles starting point and vector it should move in. The camera should have nothing to do with where the missile is, or is facing in your world.
[ dev journal ]
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.
There is no gun. It’s like the ball is being shot from the camera.

As I understand it it's like I have two cameras. One is the sphere, and the other one is the actual camera.

At the moment of shooting I capture the camera vectors and save them as sphere vectors. From both sets of vectors I can get a transform matrix. I also know how to "move" the camera, and intend to move the sphere the same way.

It should probably go something like this, while the sphere is traveling:

Apply the sphere transform
Draw the sphere
Apply the world transform
Draw the world

The problem is that I suck at transforming. I’m pushing, popping, loading, multiplying all over the place in an effort to guess what needs to be done and I’m getting frustrated. Do I need to "reset" everything after I draw the sphere? Is that done by pushing, loading the identity matrix and eventually popping the stack? Does it involve a matrix inverse?
First take the orthogonal vectors needed to transform your bullet. Assuming Player is the player's position...

<source>
up.x = Player.m_up.x
up.y = Player.m_up.y
up.z = Player.m_up.z

fwd.x = Player.m_forward.x
fwd.y = Player.m_forward.y
fwd.z = Player.m_forward.z

rite.x = Player.m_right.x
rite.y = Player.m_right.y
rite.z = Player.m_right.z

up.x = -up.x
up.y = -up.y
up.z = -up.z


vector_add (temp, up, rite)
vector_normalize (temp)


//set bullet pos
bullet.m_x = Player.m_position.x + temp.x
bullet.m_y = Player.m_position.y + temp.y
bullet.m_z = Player.m_position.z + temp.z
//get direction vector
bullet.m_xv = Player.m_position.x + fwd.x
bullet.m_yv = Player.m_position.y + fwd.y
bullet.m_zv = Player.m_position.z + fwd.z
//normalize
dim inv_len as single
inv_len = 1.0 / sqr(bullet.m_xv^2 + bullet.m_yv^2 + bullet.m_zv^2)
bullet.m_xv = .m_xv * inv_len
bullet.m_yv = .m_yv * inv_len
bullet.m_zv = .m_zv * inv_len
bullet.m_xv = .m_xv * bulletspeed
bullet.m_yv = .m_yv * bulletspeed
bullet.m_zv = .m_zv * bulletspeed


</source>

Hi.
Quote:Original post by Bahati
There is no gun. It’s like the ball is being shot from the camera.

As I understand it it's like I have two cameras. One is the sphere, and the other one is the actual camera.


The ball and the camera are completely independant. All you need to store is the ball's current position in world-space coordinates, and it's velocity. Once the ball has been fired, the camera can move around where ever it likes.

In fact, the only time the camera has any effect on the ball is when you first fire it - the ball starts out at the same position as the camera and with a velocity in the direction the camera is facing. But after that, they have nothing to do with each other.

You should to think of the camera just like a real-world camera - when you're shooting a movie, you can put the camera where ever you like and you don't need to worry about relative positions or anything like that.
Yes, something like that. All that "two camera" stuff is just to indicate that, if left untransformed, both the camera and the sphere are at (0,0,0) at the time of "creation", and indeed at the same position at the moment of firing. It's just a complicated way of saying: I'm shooting a sphere from my camera and moving that sphere the same way I would a camera.

It would be immensely helpful if I could just mark the current camera position with a sphere for the time being.

Imagine this: you're walking around in a 3D world, you click a mouse button, a sphere is generated where your eye/camera is at that moment and remains there after you move. No velocity, no direction, no nothing, just the position.

Any ideas on how to achieve that?
Quote:Original post by Bahati
Yes, something like that. All that "two camera" stuff is just to indicate that, if left untransformed, both the camera and the sphere are at (0,0,0) at the time of "creation", and indeed at the same position at the moment of firing. It's just a complicated way of saying: I'm shooting a sphere from my camera and moving that sphere the same way I would a camera.

It would be immensely helpful if I could just mark the current camera position with a sphere for the time being.

Imagine this: you're walking around in a 3D world, you click a mouse button, a sphere is generated where your eye/camera is at that moment and remains there after you move. No velocity, no direction, no nothing, just the position.

Any ideas on how to achieve that?


Wait, so you're trying to do these computations when you're in camera space, when everything is at 0,0? To me, this is something _much_ better suited to perform in world space.

Sphere's intial position = camera's position
Sphere's velocity = whatever you want (you could do a normalized camera view vector by some speed to make it shoot straight out)
I've got it!

I'm not sure what was the problem, my poor understanding of that weird (for me at least) way of transforming using glMultMatrix(), or my equally poor matrix stack manipulating skills. Most probably both.

In the end I've changed the scene transforming way to the one used in NeHe Lesson 10, and my render now looks like this:

void render( void ){		//<SNIP>COLLISION STUFF</SNIP>	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );	glMatrixMode(GL_MODELVIEW);	glPushMatrix();	glLoadIdentity();	glRotatef(g_lookupdown,1.0f,0,0); // up/down look	glRotatef(360.0f - g_yrot,0,1.0f,0); // left/right look	glTranslatef(-g_vCameraPos.x, -g_vCameraPos.y, -g_vCameraPos.z); //movement	//<SNIP>3D STUFF</SNIP>	if(proj_draw)	{		glColor3f(1.0f,0.0f,0.0f);		glPushMatrix();		glTranslatef(g_vSpherePos.x,g_vSpherePos.y,g_vSpherePos.z);		glutWireSphere(0.3f,20,20);		glPopMatrix();		glColor3f(1.0f,1.0f,1.0f);	}	glPopMatrix();		//SETUP 2D	glMatrixMode(GL_PROJECTION);	glPushMatrix();	glLoadIdentity();	gluOrtho2D(0,screenx,0,screeny);	//<SNIP>2D STUFF</SNIP>	glPopMatrix();	// Swap The Buffers To Become Our Rendering Visible	glutSwapBuffers();}


Thanks to everyone!
Quote:Original post by freeworld
I know it'll probably sound vague and annoying, but you need to separate your idea that you're world and the way people see your game are exactly the same.

Take the position your gun is in, and the vector it is pointing in and use that as your missiles starting point and vector it should move in. The camera should have nothing to do with where the missile is, or is facing in your world.


I've put "quake rocket launcher" in the title for the sake of keywords, but my intention was always to shoot from the "eyes". Then you said all this about the gun position and I said to myself "That's cool, but seems harder, I'll try that after I make it work like I wanted in the first place".

But can it be actually done? I think not.

It would be like shooting from the hip. You would need to control the gun with your mouse, not the view. And that's no good... In other words, the world and the way a player sees it are very much connected in a FPS. The way you see it is the way you aim in it, and the way you influence it. It's like shooting from a rifle, except the sights are always aligned to wherever you look.

I looked at the way Q3 does it and it shoots from the eyes. A little blast and a movement of the rocket launcher creates an illusion of firing it.
Quote:Original post by Iced_Eagle
Wait, so you're trying to do these computations when you're in camera space, when everything is at 0,0? To me, this is something _much_ better suited to perform in world space.

Sphere's intial position = camera's position
Sphere's velocity = whatever you want (you could do a normalized camera view vector by some speed to make it shoot straight out)

Can you please point me in the direction of a nice article/tutorial/whatever where I can learn about camera space/world space and such? At the moment I don't even understand what those mean and I feel impaired. :|

Much appreciated!

This topic is closed to new replies.

Advertisement