c++ - Setting up an asymmetric frustum -


i have program in tracking user's position , setting frustum (setting camera @ user's position) change perspective of scene per user's position. until right now, had 4 corners of display screen @ same z , able set asymmetric frustum , change scene according user's perspective.

the current code looks following:

usercam::begin(){     saveglobalmatrices();       glmatrixmode(gl_projection);     glloadidentity();         glfrustum(_topleftnear.x, _bottomrightnear.x, _bottomrightnear.y, _topleftnear.y, _camznear, _camzfar);      glmatrixmode(gl_modelview);     glloadidentity();      glulookat(_wcuserhead.x, _wcuserhead.y, _topleftscreen.z, _wcuserhead.x, _wcuserhead.y, _topleftscreen.z-1, 0, 1, 0); }  usercam::end(){ loadglobalmatrices(); }  usercam::setupcam(){     this->_topleftscreen = _wctopleftscreen - _wcuserhead; //wctopleftscreen, wcbottomrightscreen , wcuserhead in same frame of reference     this->_bottomrightscreen = _wcbottomrightscreen - _wcuserhead;      this->_topleftnear = (_topleftscreen/ _topleftscreen.z) * _camznear;     this->_bottomrightnear = (_bottomrightscreen/_bottomrightscreen.z )) * _camznear; } 

however, want able same display kept tilted user and/or not have vertices @ same z.

enter image description here above can imagined sort of tilted window, vertices of have frustum defined user's position. how such frustum possible display not have vertices @ same z?

edit
there 3 planes in setup considering. middle 1 give correct asymmetric frustum since vertices @ same z, whereas left , right planes have 2 vertices each @ different z. vertices of same follows:

plane1: tl : (-426.66, 0, 200), tr: (0, 0, 0), bl : (-426.66, 320.79, 200), br : (0, 320.79, 0) plane2: tl : (0, 0, 0), tr: (426.66, 0, 0), bl : (0, 320.79, 0), br: (426.66, 320.79, 0) plane3: tl:  (426.66, 0, 0), tr: (853.32, 0, 200), bl : (426.66, 320.79, 0), br : (853.32, 320.79, 200) 

the idea in setup transform case corners have same z-coordinate. done view matrix , get:

overall_transform = (projection) * (view * world) 

or in opengl wording

overall_transform = projection * modelview 

if don't want tamper original modelview matrix, should introduce matrix in between:

overall_transform = (projection * adaption) * (view * world) 

where adaption rotation matrix maps screen's corners plane constant z-coordinate.

in order find correct parameters projection have transform screen adaption.

edit

we start arbitrary scene camera's position, direction , screen known. consider model matrices there each object:

initial situation

we need view transformation v aligns camera origin. matrix can calculated glulookat. overall matrix t = v * m:

after view transformation

up step matrices same 3 screens. part should in modelview matrix. add goes projection matrix because differs per screen.

we need apply rotation r aligns screen perpendicular z-axis. position of camera must not change @ step because represents projection center. overall transformation t = r * v * m.

in order calculate angle, can use e.g. atan2:

dx = right.x - left.x dz = right.z - left.z angle = atan2(dz, dx) 

it might necessary adapt calculation actual needs.

after rotation adaption

now time apply actual perspective transform, can done glfrustum.

we need find local edges of screen. transform screen coordinates current transform (r * v).

tl' = r * v * tl bl' = r * v * bl br' = r * v * br 

now 3 coordinates should have same z-coordinate. can use these follows:

common_z = tl'.z = bl'.z = br'.z glfrustum(tl'.x / common_z * z_near,           br'.x / common_z * z_near,           bl'.y / common_z * z_near,           tl'.y / common_z * z_near,           z_near, z_far) 

so overall t = glfrustum * r * v * m:

glmatrixmode(gl_modelview); glloadidentity(); glulookat(...); //any further model transforms  glmatrixmode(gl_projection); glfrustum(...); glrotate(...);     

Comments

Popular posts from this blog

javascript - Count length of each class -

What design pattern is this code in Javascript? -

hadoop - Restrict secondarynamenode to be installed and run on any other node in the cluster -