From 4fdd846f89d0f81aec2b948d246f0383111662ab Mon Sep 17 00:00:00 2001 From: slevy <slevy> Date: Sat, 30 Jun 2001 18:04:58 +0000 Subject: [PATCH] Add parent-to-camera (objparent()) support: objects with parent GV_ID_CAMERA have "o2w" transforms that are really interpreted relative to camera space. Also start adding per-object clip support; this requires change to subcameras, supplying projection parameters subc_lrbt() rather than a (clip-dependent) projection matrix. --- src/Gview.H | 20 ++++++++--- src/Gview.cc | 93 +++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 82 insertions(+), 31 deletions(-) diff --git a/src/Gview.H b/src/Gview.H index 19ec915..71fec46 100644 --- a/src/Gview.H +++ b/src/Gview.H @@ -17,7 +17,7 @@ typedef struct _Fl_Gview Fl_Gview; int Gview_add_drawer( Fl_Gview *gview, void (*func)( Fl_Gview *, void *obj, void *arg ), void *obj, void *arg, int id ); -void Gview_get_o2w( Fl_Gview *gview, Matrix *pos, int drawer ); +void Gview_get_o2w( Fl_Gview *gview, Matrix *pos, int drawer ); /* returns parent */ void Gview_set_o2w( Fl_Gview *gview, CONST Matrix *pos, int drawer ); int Gview_inpick( Fl_Gview *gview ); /* for plain-C drawers */ void Gview_setpick( Fl_Gview *gview, void (*pickcb)(Fl_Gview *, int hits, int ents, GLuint *buf) ); @@ -103,11 +103,13 @@ class Fl_Gview : public Fl_Gl_Window { int usesubcam() const { return use_subc_; }; void Tc2subc( Matrix *newT ) { Tc2subc_ = *newT; } const Matrix *Tc2subc() const { return &Tc2subc_; } - void Tsubcproj( Matrix *newT ) { Tsubcproj_ = *newT; } - const Matrix *Tsubcproj() const { return &Tsubcproj_; } + void subc_lrbt( float lrbt[4] ); + const float *subc_lrbt() const { return subclrbt_; } const Matrix *To2w( int drawerno ) const; /* returns &Tidentity if invalid */ int To2w( int drawerno, const Matrix * ); /* returns zero if invalid */ + int objparent( int drawerno ) const; /* parent object id (0=world, -1=camera) */ + void objparent( int drawerno, int id ); int perspective() { return persp_; } void perspective(int persp); @@ -188,6 +190,9 @@ class Fl_Gview : public Fl_Gl_Window { static void idlepick( void *me ); protected: + + void glprojection( float nearclip, float farclip, const Matrix *postproj ); + Point qc2w_; Matrix Tc2w_, Tw2c_; @@ -196,7 +201,8 @@ class Fl_Gview : public Fl_Gl_Window { float focallen_, halfyfov_, near_, far_; float aspect_, stereosep_; - Matrix Tc2subc_, Tsubcproj_; + Matrix Tc2subc_; + float subclrbt_[4]; // subcam frustum tan(left),tan(right),tan(bot),tan(top) int use_subc_; int target_; @@ -236,6 +242,9 @@ class Fl_Gview : public Fl_Gl_Window { Matrix To2w; char *name; int id; + int parent; /* 0=world, GV_ID_CAMERA=attach-to-camera */ + int objclip; /* object has custom clip planes? */ + float objnear, objfar; }; int ndrawers_, maxdrawers_; struct drawer *drawers_; @@ -275,7 +284,8 @@ class Fl_Gview : public Fl_Gl_Window { hasfocus_ = 0; use_subc_ = 0; Tc2subc_ = Tidentity; - Tsubcproj_ = Tidentity; + subclrbt_[0] = subclrbt_[2] = -1; + subclrbt_[1] = subclrbt_[3] = 1; nav( GV_ORBIT ); reset( GV_ID_CAMERA ); } diff --git a/src/Gview.cc b/src/Gview.cc index befa32d..602246f 100644 --- a/src/Gview.cc +++ b/src/Gview.cc @@ -152,12 +152,13 @@ int Fl_Gview::add_drawer( void (*func)( Fl_Gview *, void *obj, void *arg ), dp->To2w = Tidentity; dp->name = name; dp->id = id; + dp->parent = 0; notify(); redraw(); return id; } -int Fl_Gview::withid( int id ) const { +int Fl_Gview::withid( int id ) const { // Which drawer[] slot is id in? for(int dno = 0; dno < ndrawers_; dno++) if(drawers_[dno].id == id) return dno; @@ -184,10 +185,54 @@ int Fl_Gview::To2w( int id, const Matrix *newT ) { return 1; } +void Fl_Gview::objparent( int id, int parent ) { + int drawerno = withid( id ); + if(drawerno >= 0) + drawers_[drawerno].parent = parent; +} + +int Fl_Gview::objparent( int id ) const { + int drawerno = withid( id ); + return (drawerno >= 0) ? drawers_[drawerno].parent : 0; +} + +void Fl_Gview::subc_lrbt( float subclrbt[4] ) { + for(int k = 0; k < 4; k++) + subclrbt_[k] = subclrbt[k]; +} + #define VIEW_CLEAR 0x1 #define VIEW_RED 0x2 #define VIEW_CYAN 0x4 +void Fl_Gview::glprojection( float nearclip, float farclip, const Matrix *postproj ) +{ + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + if(inpick()) { + GLint vp[4] = {0, 0, w(), h()}; + gluPickMatrix( pickx_, picky_, pickwidth_, pickheight_, vp ); + } + if(use_subc_) { + glFrustum( nearclip * subclrbt_[0], nearclip * subclrbt_[1], + nearclip * subclrbt_[2], nearclip * subclrbt_[3], + nearclip, farclip ); + + } else if(persp_) { + float nthf = nearclip * halfyfov_ / focallen_; + glFrustum( -nthf * aspect_, nthf * aspect_, + -nthf, nthf, + nearclip, farclip ); + } else { + glOrtho( -aspect_*halfyfov_, aspect_*halfyfov_, + -halfyfov_, halfyfov_, + nearclip, farclip ); + } + if(postproj) + glMultMatrixf( postproj->m ); + glMatrixMode( GL_MODELVIEW ); +} + void Fl_Gview::draw_scene( int how, const Matrix *postproj ) { /* draw scene */ @@ -211,27 +256,7 @@ void Fl_Gview::draw_scene( int how, const Matrix *postproj ) { glDisable( GL_COLOR_MATERIAL ); if(how || postproj) { - glMatrixMode( GL_PROJECTION ); - glLoadIdentity(); - if(inpick()) { - GLint vp[4] = {0, 0, w(), h()}; - gluPickMatrix( pickx_, picky_, pickwidth_, pickheight_, vp ); - } - if(use_subc_) { - glMultMatrixf( Tsubcproj_.m ); - - } else if(persp_) { - float nthf = near_ * halfyfov_ / focallen_; - glFrustum( -nthf * aspect_, nthf * aspect_, - -nthf, nthf, - near_, far_ ); - } else { - glOrtho( -aspect_*halfyfov_, aspect_*halfyfov_, - -halfyfov_, halfyfov_, - near_, far_ ); - } - if(postproj) - glMultMatrixf( postproj->m ); + glprojection( near_, far_, postproj ); glMatrixMode( GL_MODELVIEW ); if(use_subc_) { @@ -242,15 +267,31 @@ void Fl_Gview::draw_scene( int how, const Matrix *postproj ) { } } + int curclip = 0; + for(int i = 0; i < ndrawers_; i++) { - if(drawers_[i].func != NULL) { + struct drawer *dp = &drawers_[i]; + if(dp->func != NULL) { + int wantclip = dp->objclip; + if(wantclip) + glprojection( dp->objnear, dp->objfar, postproj ); + else if(curclip) + glprojection( near_, far_, postproj ); + curclip = wantclip; + glPushMatrix(); - glMultMatrixf( drawers_[i].To2w.m ); + if(dp->parent == GV_ID_CAMERA) { + if(use_subc_) + glLoadMatrixf( Tc2subc()->m ); + else + glLoadIdentity(); + } + glMultMatrixf( dp->To2w.m ); if(inpick_) { - glLoadName( drawers_[i].id ); + glLoadName( dp->id ); glPushName(0); } - (*drawers_[i].func)(this, drawers_[i].obj, drawers_[i].arg); + (*dp->func)(this, dp->obj, dp->arg); if(inpick_) glPopName(); glPopMatrix(); -- GitLab