Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

FPS style Camera movement anomalies

Options
  • 28-09-2004 5:44am
    #1
    Registered Users Posts: 885 ✭✭✭


    Hi

    I am just getting into programming with the DirectX api and have been working on a small First Person Shooter style application. (Mouse looks arround. W,A,S,D controls movement and Spacebar to jump). I have got this working OK using a camera class that I put together. Some of the functions are.
    void Camera::RotateX(float angle)
    {
    	if(up.y > .05 || angle > 0)
    	{
    		look = rotateAroundAxis(look, right, angle);
    		
    		if(up.y < 0)
    			look = rotateAroundAxis(look, right, .015);
    		
    		CrossProduct(look, right, up); // Up
    	}
    
    
    }
    
    void Camera::RotateY(float angle)
    {
    	float xxx, zzz;
    	float sinAng, cosAng;
    	
    	// Get sin()/cos() of angle
    	sinAng = sinf(angle);
    	cosAng = cosf(angle);
    	
    	// Save off look components for computation
    	xxx = look.x;
    	zzz = look.z;
    	
    	// Rotate look vector
    	look.x = xxx * cosAng + zzz * sinAng;
    	look.z = xxx * -sinAng + zzz * cosAng;
    	
    	// Save off up components for computation
    	xxx = up.x;
    	zzz = up.z;
    	
    	// Rotate up vector
    	up.x = xxx * cosAng + zzz * sinAng;
    	up.z = xxx * -sinAng + zzz * cosAng;
    	
    	// Save off right components for computation
    	xxx = right.x;
    	zzz = right.z;
    	
    	// Rotate right vector
    	right.x = xxx * cosAng + zzz * sinAng;
    	right.z = xxx * -sinAng + zzz * cosAng;
    }
    
    
    void Camera::Move(float amt)
    {
    	amt = amt * jump;
    	pos += D3DXVECTOR3(look.x, 0, look.z ) * amt;
    }
    
    void Camera::Strafe(float amt)
    {
    	amt = amt * jump;
    	pos += D3DXVECTOR3(right.x, 0, right.z ) * amt;
    }
    
    void Camera::Jump()
    {
    	if(jumping)
    	{
    		//jump = 2;
    		velY = velY - accel;
    		pos += D3DXVECTOR3(0, 1, 0) * velY;
    		if(pos.y <= 0)
    		{
    			jump = 1;
    			velY = .5f;
    			accel = .003f;
    			pos.y =	 1;
    			jumping = false;
    		}
    	}
    }
    

    My first problem is with the RotateX function. This is called when the mouse is moved up or down along the X axis. Like in a real game I want the rotation to stop when the person is looking directly at the ground or at the sky. Does anyone know the proper way of doing this. The method I have used above will stop the view at the ground but it is really just a cheap hack and is very buggy.

    My second problem lies in the Move function. This moves the camera forwards and backwards. It uses the look vector to accomplish this. This works fine if you are looking straight ahead but the more you look towards the ground or the sky the slower you move until you stop when you are directly facing the ground or the sky. This is because you are trying to move along the look z axis which becomes 0 at 90 degree angles. Anybody got a solution for this.

    Thanks
    John.


Comments

  • Registered Users Posts: 1,481 ✭✭✭satchmo


    For the RotateX problem try keeping a track of the current absolute angle. Then if the current angle is greater than 90 or less than -90 simply don't let them rotate any more in that direction.

    As for the move problem, normalize the x,0,z vector before adding it to position. You'll still a problem if the look vector is straight up (ie 0,1,0), so either restrict looking up and down to something like -89...89, or use seperate move and look vectors.


  • Registered Users Posts: 885 ✭✭✭clearz


    Thanks satchmo. I implemented a move vector into it that only gets updated in the RotateY() function and I use it instead of the look vector in the Move() function. It works perfectly.

    I still for the life of me cant come up with a decent robust way of stoping the x rotation at the ground or sky.

    In the method Move(float angle); angle is accually the relativeX of the mouses last position so it is 0 when the mouse is at rest or depending on the speed of mouse movement upto around +- 2

    look.x and look.z are both 0 at vertical angles. Can anybody think up a solution

    You can view what im talking about here:
    DXTest.zip


  • Registered Users Posts: 1,481 ✭✭✭satchmo


    Error!
    Could not create direct3d object
    :confused:

    When you say Move(float angle); I presume you mean RotateX(float angle);. Did you try keeping track of the absolute angle? In other words...
    float currentPitch=0;
    
    void Camera::RotateX(float angle)
    {
            if((currentPitch+angle)>=90 || (currentPitch+angle)<=-90)return;
            currentPitch+=angle;
    
    	if(up.y > .05 || angle > 0)
    	{
                    //and so on as before....
    


  • Registered Users Posts: 885 ✭✭✭clearz


    :confused:

    Error!
    Could not create direct3d object

    Dam do you have the DirectX9 Runtime installed.

    Sorry I ment RotateX before( no sleep last night )
    That simple if statement works perfectly. ;) Again thanks a million satchmo. now I can move on having finnished the camera class.


  • Registered Users Posts: 1,481 ✭✭✭satchmo


    Glad to help. It works on my FX5900 at home with 9.0c, but not on my 9800xt in work. I'm almost sure I have DX9 in there, I'll check tomorrow.

    Edit: Yeah I have 9.0c in work too. Maybe it's an XP/Win2K thing?


  • Advertisement
Advertisement