SOLVED? Where (in 2D) is the horizon?

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Hiroo
Posts: 10
Joined: Sun Dec 28, 2014 6:59 am

SOLVED? Where (in 2D) is the horizon?

Post by Hiroo »

Now that I got the 3DoF camera motion figured out, I am onto the next challenge. Overlaying some 2D elements on top of the 3D depiction. Starting with something simple (or so I thought). Drawing a 2D line on the screen where the horizon should be in 3D. To do that, I wanted to start with where the "center" of the horizon should be within the screen. The thinking here is that since no matter which direction I am facing in the compass direction, the horizon surrounds me so the horizon can be reduced to the pitch displacement and the tilt angle that corresponds to the "roll" of the camera.

So, I took a very simplistic approach where I figure out how many pixels on the screen corresponds to "one degree" on the pitch, then count up (or down) from the center of the screen to determine where the horizon should be at the center of the screen. Well, clearly that is not the right answer as when I run the code, as the pitch angle decreases, the horizon depicted graphically will rise faster than the white "+" sign I put where I think it should be.

Any clue where I turned wrong in my logic?

Code: Select all

 
        f32 cam_fov = camera->getFOV() * core::RADTODEG;
        f32 cam_aspect = camera->getAspectRatio();
        core::dimension2du screen = driver->getCurrentRenderTargetSize();
        core::dimension2df ppd(screen.Width / cam_fov, screen.Height / (cam_fov / cam_aspect));
        
        f32 pitch_displacement = ppd.Height * pitch;
        core::vector2di horizonCenter(screen.Width / 2, (screen.Height / 2) - pitch_displacement / 2);
 
        driver->draw2DLine(horizonCenter + core::dimension2di(2, 0), horizonCenter - core::dimension2di(2, 0), video::SColor(255, 255, 255, 255));
        driver->draw2DLine(horizonCenter + core::dimension2di(0, 2), horizonCenter - core::dimension2di(0, 2), video::SColor(255, 255, 255, 255));
 
 
Hiroo
Posts: 10
Joined: Sun Dec 28, 2014 6:59 am

Re: SOLVED? Where (in 2D) is the horizon?

Post by Hiroo »

I think I got to a reasonable results. There are couple assumptions that were false. First, the screen is not equirectangular projection. It seems that the it takes more of a Lambert projection. So I can't simply apply linear displacement. Instead, I need to actually compute the distance from the eye to the screen and then compute the offset using trig function.

Second is that CameraFOV is actually a diagonal value indicating edge to edge diagonal angle of the camera. So, in order to compute the eye distance I mentioned above, I need to correct the FoV into H and V component and then apply trig function. Having done these two corrections, the "center dot" no longer creep up.

For your reference, here is my latest version.

Code: Select all

 
        f32 cam_fov = camera->getFOV() * core::RADTODEG;
        f32 cam_aspect = camera->getAspectRatio();
        f32 cam_fov_v = camera->getFOV() / sqrtf(1.0f + (cam_aspect * cam_aspect));
        f32 cam_fov_h = cam_fov_v * cam_aspect;
 
        core::dimension2du screen = driver->getCurrentRenderTargetSize();
 
        f32 scr_r = ((f32)screen.Width / 2.0f) / cos(cam_fov_h/2.0f);
        f32 scr_disp = scr_r * sin(pitch * core::DEGTORAD);
 
        core::vector2di horizonCenter(screen.Width / 2, (screen.Height / 2) - scr_disp);
 
 
        driver->draw2DLine(horizonCenter + core::dimension2di(2, 0), horizonCenter - core::dimension2di(2, 0), video::SColor(255, 255, 255, 255));
        driver->draw2DLine(horizonCenter + core::dimension2di(0, 2), horizonCenter - core::dimension2di(0, 2), video::SColor(255, 255, 255, 255));
 
Post Reply