![]() |
【转帖】oddbviewport transformation from model space to paper space
oddbviewport transformation from model space to paper space
oddbviewport transformation from model space to paper space i have a question on obtaining the matrix for transforming a oddbviewport object from model space to paper space. in order to obtain the matrix that transforms entities in model space to fit the viewport in paper space, i'm doing the following: odabstractviewpeptr pview(pvp); odgematrix3d modeltopaper = pview->worldtoeye(pvp); but, this doesn't seem to work. what am i doing wrong? i use the following code, hope this helps : void od_ms2ps( oddbviewportptr pvp, odgematrix3d &resultmat) { // first get all the data odgevector3d viewdirection = pvp->viewdirection(); odgepoint2d centre2d = pvp->viewcenter(); odgepoint3d viewcenter = odgepoint3d( centre2d.x, centre2d.y, 0); odgepoint3d viewtarget = pvp->viewtarget (); double twistangle = -pvp->twistangle(); odgepoint3d centerpoint = pvp->centerpoint(); double viewheight = pvp->viewheight(); double height = pvp->height(); double width = pvp->width(); double scaling = viewheight / height; double lenslength = pvp->lenslength(); // prepare the transformation odgevector3d xaxis, yaxis, zaxis; zaxis = viewdirection.normal(); xaxis = odgevector3d::kzaxis.crossproduct( viewdirection ); if( !xaxis.iszerolength() ) { xaxis.normalize(); yaxis = zaxis.crossproduct( xaxis ); } else if( zaxis.z < 0 ) { xaxis = -odgevector3d::kxaxis; yaxis = odgevector3d::kyaxis; zaxis = -odgevector3d::kzaxis; } else { xaxis = odgevector3d::kxaxis; yaxis = odgevector3d::kyaxis; zaxis = odgevector3d::kzaxis; } odgematrix3d dcs2wcs; // display coordinate system (dcs) to world coordinate system (wcs) odgematrix3d ps2dcs; // paperspace to dcs // first initialise with a transformation to centerpoint ps2dcs = odgematrix3d::translation( odgepoint3d::korigin - centerpoint ); // then scale for the view ps2dcs = ps2dcs * odgematrix3d::scaling( scaling, centerpoint ); // then adjust to the viewcenter dcs2wcs = odgematrix3d::translation( viewcenter - odgepoint3d::korigin ); // then transform for the view direction odgematrix3d matcoords; matcoords.setcoordsystem( odgepoint3d::korigin, xaxis, yaxis, zaxis); dcs2wcs = matcoords * dcs2wcs; // then adjust for the viewtarget dcs2wcs = odgematrix3d::translation( viewtarget - odgepoint3d::korigin ) * dcs2wcs; // then the twist angle dcs2wcs = odgematrix3d::rotation(twistangle, zaxis, viewtarget ) * dcs2wcs; odgematrix3d perspmat; if( pvp->isperspectiveon()) { // we do special perspective handling double viewsize = viewheight; double aspectratio = width / height; double adjustfactor = 1.0 / 42.0; double adjustedlenslength = viewsize * lenslength * sqrt ( 1.0 + aspectratio * aspectratio ) * adjustfactor; double eyedistance = viewdirection.length(); double lensdistance = eyedistance - adjustedlenslength; double ed = eyedistance; double ll = adjustedlenslength; double l = lensdistance; perspmat.entry[2][2] = (ll - l ) / ll; perspmat.entry[2][3] = l * ( ed - ll ) / ll; perspmat.entry[3][2] = -1.0 / ll; perspmat.entry[3][3] = ed / ll; } resultmat = ps2dcs.inverse() * perspmat * dcs2wcs.inverse(); } // it gets a viewport and returns a transformation matrix, // with which we can move a paperspace coordinate to the model space // as looked from the given viewport void od_ps2ms ( oddbviewportptr pvp, odgematrix3d &resultmat ) { // keep life simple, just invert the other way odgematrix3d mat; od_ms2ps( pvp, mat ); resultmat = mat.inverse(); } cheers jason anderssen jason, thanks - i've been looking for this also, and yours is working much better than what i had put together. thanks again! pete |
所有的时间均为北京时间。 现在的时间是 04:41 PM. |