Skip to content
Snippets Groups Projects
Commit 4fdd846f authored by slevy's avatar slevy
Browse files

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.
parent 694fa0da
No related branches found
No related tags found
No related merge requests found
......@@ -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 );
}
......
......@@ -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();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment