Jump to content
  • Advertisement
Sign in to follow this  
Xperience

Camera looking by mouse(smooth)

This topic is 1494 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello,

I'm trying to implement camera which is controlled by mouse. This is my Yaw and Pitch function:

if (lookingDir.x)
{
	float desiredYaw = currentYaw + DirectX::XMConvertToRadians(lookingDir.x);
	float newYaw = lerp(currentYaw, desiredYaw, 0.1f / DeltaTime);
	m_pCamera->Yaw(newYaw - currentYaw);
	currentYaw = newYaw;
}
if (lookingDir.y)
{
	float desiredPitch = currentPitch + DirectX::XMConvertToRadians(lookingDir.y);
	float newPitch = lerp(currentPitch, desiredPitch, 0.1f / DeltaTime);
	m_pCamera->Pitch(newPitch - currentPitch);
	currentPitch = newPitch;
}

lookingDir is just vector of deltas

 

It works, but looking is not smooth(like 10fps). I'm using weighted average as my lerp function and I tried many combinations of parameters, but I didn't find solution which has nice smooth effect(like in AAA games).

Any advice?

Edited by Xperience

Share this post


Link to post
Share on other sites
Advertisement
 

 

this is the generic mouse aimed camera code from my Z game library...

 

i THINK i have all the parts cut and pasted into here...

 

the commented out code that refers to intox_mul implements a drunkcam

 

 

 

 
 
 
// mouse position and button state
int mousex,mousey,mouselb,mouserb;
 
 
 
 
 
 
 
 

// gets mouse position and button state as of the last mouse message
void Zgetmouse(int *x,int *y,int *b)
{
*x=mousex;
*y=mousey;
if (mouselb) *b=1; else *b=0;
if (mouserb) *b+=2;
}
 
 
 
 
 
void Zputmouse(int x,int y)
{
SetCursorPos(x,y);
}
 
 
 
 

 
 
// process windows messages
void Zdomessages()
{
MSG Zwinmsg;
mousewheel=0;    // reset mouse wheel delta to zero before processing windows messages.
                 // windows messages may include new wheel delta.
while (PeekMessage(&Zwinmsg,NULL,0,0,PM_REMOVE)) 
    {
    TranslateMessage(&Zwinmsg);
    DispatchMessage(&Zwinmsg);
    }
}
 
 
 


 
 
 
// message handler 
LRESULT WINAPI Zmsgproc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
    {
    case WM_DESTROY:        Zshutdown();
                            PostQuitMessage(0);
                            exit(0);
    case WM_MOUSEMOVE:
    case WM_LBUTTONDOWN:
    case WM_RBUTTONDOWN:
    case WM_LBUTTONUP:
    case WM_RBUTTONUP:
/*
Remarks
Use the following code to obtain the horizontal and vertical position:
xPos = GET_X_LPARAM(lParam);
yPos = GET_Y_LPARAM(lParam);
 
Important  Do not use the LOWORD or HIWORD macros to extract the x- and y- coordinates of the 
cursor position because these macros return incorrect results on systems with multiple monitors. 
Systems with multiple monitors can have negative x- and y- coordinates, and LOWORD and HIWORD 
treat the coordinates as unsigned quantities.
 
TODO: change code to support multiple monitors.
*/
mousex=(lParam & 0x0000FFFF);        // mouse x = low order word of lParam
                            mousey=(lParam >> 16);               // mouse y = high order word of lParam
                            if (wParam & MK_LBUTTON) mouselb=1; else mouselb=0;
                            if (wParam & MK_RBUTTON) mouserb=1; else mouserb=0;
                            return(0);
    case WM_MOUSEWHEEL:     mousewheel=(int) GET_WHEEL_DELTA_WPARAM(wParam);
                            // wParam >> 16;     // distance rotated = high order word of wParam
                            // if (mousewheel > 32767) mousewheel = 65536 - mousewheel;
                            return(0);
    }
return(DefWindowProc(hWnd,msg,wParam,lParam));
}
 
 
 
 
 
//######################################### mouse aim camera ##################################################
 
 
 
int old_mousex=0;
int old_mousey=0;
 
 
 
void Zresetmouse()
{
int b;
Zputmouse(800,450);
Zdomessages();
Zgetmouse(&old_mousex,&old_mousey,&b);
nobutton();
}
 
 
float cam_xr=0.0f;
float cam_yr=0.0f;
 
 
#define screen_width 1600
#define screen_height 900
 
 
int Zmouse_aim_camera()
{
int x,y,b;
Zdomessages();
Zgetmouse(&x,&y,&b);
if (x != old_mousex)
    {
    //if (intox_mul < 1) 
cam_yr+=(float)(x-old_mousex)/1000.0f;
    //else cm[cm0].vyr+=(float)(x-old_mousex)/1000.0f*9.0f*(float)intox_mul;     // bigger = more acceleration (touchier)
    old_mousex=x;
    // handle edges of screen
    if (x<screen_width/10)
        {
        old_mousex+=screen_width/2;
        Zputmouse(x+screen_width/2,y);
        }
    else if (x>=screen_width*9/10)
        {
        old_mousex-=screen_width/2;
        Zputmouse(x-screen_width/2,y);
        }
    }
//if (intox_mul > 0)
//    {
//    cm[cm0].vyr*=0.98f;          // bigger = less decelleration       (less stable)
//    cm[cm0].yr+=cm[cm0].vyr;
//    }
while (cam_yr>=2*D3DX_PI) cam_yr-=2*D3DX_PI;
while (cam_yr<0) cam_yr+=2*D3DX_PI;
if (y != old_mousey)
    {
    //if (intox_mul < 1) 
cam_xr+=(float)(y-old_mousey)/1000.0f;
    //  else cm[cm0].vxr+=(float)(y-old_mousey)/1000.0f*9.0f*(float)intox_mul;     // bigger = more acceleration      (touchier)
    old_mousey=y;
    // handle edges of screen
    if (y<screen_height/10)
        {
        old_mousey+=screen_height/2;
        Zputmouse(x,y+screen_height/2);
        }
    else if (y>=screen_height*9/10)
        {
        old_mousey-=screen_height/2;
        Zputmouse(x,y-screen_height/2);
        }
    }
//if (intox_mul > 0)
//    {
//    cm[cm0].vxr*=0.98f;          // bigger = less decelleration   (less stable)
//    cm[cm0].xr+=cm[cm0].vxr;
///    }
while (cam_xr >= 2.0f*pi) cam_xr-=2.0f*pi;
while (cam_xr < 0.0f) cam_xr+=2.0f*pi;
if ((cam_xr>pi) && (cam_xr<3.0f*pi/2.0f)) cam_xr=3.0f*pi/2.0f;
if ((cam_xr>pi/2.0f) && (cam_xr<=pi)) cam_xr=pi/2.0f;
return(b);
}
 
 
 
//##################################### end mouse aim camera ##########################################
 
 
 
 
 
 
 

Share this post


Link to post
Share on other sites

Note:

 

Zresetmouse is hardcoded for 1600x900.

 

you'll want to change Zputmouse(800,450); to Zputmouse(screen_width/2,screen_height/2);

 

 

 

Share this post


Link to post
Share on other sites

How did you go with this ?

Are you using DirectInput ? Because that can drop frames as it's unreliable and not supported. If that turns out to be problem use raw-input or windows messages.

Share this post


Link to post
Share on other sites

Thanks a lot for your code, but it didn't work. I did something wrong(probably). I found a camera code from nvidia demos and they used lerp for mouse deltas and it works.

 

 

How did you go with this ?

Are you using DirectInput ? Because that can drop frames as it's unreliable and not supported. If that turns out to be problem use raw-input or windows messages.

 

I'm using windows messages

Edited by Xperience

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!