views:

58

answers:

1

Here is what I'm trying to do. I'm trying to make a bullet out of the center of the screen. I have an x and y rotation angle. The problem is the Y (which is modified by rotation on the x) is really not working as intended. Here is what I have.

 float yrotrad, xrotrad;

    yrotrad = (Camera.roty / 180.0f * 3.141592654f);
    xrotrad = (Camera.rotx / 180.0f * 3.141592654f);
    Vertex3f Pos;

// get camera position
    pls.x = Camera.x;
    pls.y = Camera.y;
    pls.z = Camera.z;


    for(float i = 0; i < 60; i++)
    {


    //add the rotation vector

        pls.x += float(sin(yrotrad)) ;
        pls.z -= float(cos(yrotrad)) ;
        pls.y += float(sin(twopi - xrotrad));

    //translate camera coords to cube coords
        Pos.x = ceil(pls.x / 3);
        Pos.y = ceil((pls.y) / 3);
        Pos.z = ceil(pls.z / 3);

        if(!CubeIsEmpty(Pos.x,Pos.y,Pos.z)) //remove first cube that made contact
        {
            delete GetCube(Pos.x,Pos.y,Pos.z);
            SetCube(0,Pos.x,Pos.y,Pos.z);
            return;
        }
    }

This is almost identical to how I move the player, I add the directional vector to the camera then find which cube the player is on. If I remove the pls.y += float(sin(twopi - xrotrad)); then I clearly see that on the X and Z, everything is pointing as it should. When I add pls.y += float(sin(twopi - xrotrad)); then it almost works, but not quite, what I observed from rendering out spheres of the trajector is that the furthur up or down I look, the more offset it becomes rather than stay alligned to the camera's center. What am I doing wrong?

Thanks

What basically happens is very difficult to explain, I'd expect the bullet at time 0 to always be at the center of the screen, but it behaves oddly. If i'm looking straight at the horizon to +- 20 degrees upward its fine but then it starts not following any more.

I set up my matrix like this:

void CCubeGame::SetCameraMatrix()
{

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glRotatef(Camera.rotx,1,0,0);
    glRotatef(Camera.roty,0,1,0);
    glRotatef(Camera.rotz,0,0,1);

    glTranslatef(-Camera.x , -Camera.y,-Camera.z );
}

and change the angle like this:

void CCubeGame::MouseMove(int x, int y)
{
    if(!isTrapped)
        return;

    int diffx = x-lastMouse.x; 
    int diffy = y-lastMouse.y; 

    lastMouse.x = x; 
    lastMouse.y = y;
    Camera.rotx += (float) diffy * 0.2; 
    Camera.roty += (float) diffx * 0.2; 
    if(Camera.rotx > 90)
    {
        Camera.rotx = 90;
    }

    if(Camera.rotx < -90)
    {
        Camera.rotx = -90;
    }

    if(isTrapped)
    if (fabs(ScreenDimensions.x/2 - x) > 1 || fabs(ScreenDimensions.y/2 - y) > 1) {
        resetPointer();
    }

}
A: 

You need to scale X and Z by cos(xradrot). (In other words, multiply by cos(xradrot)).

Imagine you're pointing straight down the Z axis but looking straight up. You don't want the bullet to shoot down the Z axis at all, this is why you need to scale it. (It's basically the same thing that you're doing between X and Z, but now doing it on the XZ vector and Y.)

pls.x += float(sin(yrotrad)*cos(xrotrad)) ;
pls.z -= float(cos(yrotrad)*cos(xrotrad)) ;
pls.y += float(sin(twopi - xrotrad));
dash-tom-bang
@dash-tom-bang so I need to multiply x and z by 1 / sin(xrotrad) ?
Milo
@Milo looking straight down, X maps to sin and Z maps to cos. Now, move your viewpoint so that you're on the XZ plane, perpendicular to the XZ vector. Now if you're making Y map to sin, you need to make XZ map to cos. My example code should do it (sorry I had it wrong my first shot).
dash-tom-bang