# include "sgl_links.h" /******************************************************* * link :: ~link *******************************************************/ Link :: ~Link () { linkptr * lp; lp = head; while (lp!=NULL) { head = lp->next; delete lp; lp=head; } tail=head; } /******************************************************* * link :: add *******************************************************/ void Link :: add(Shape & newlink) { if (head==NULL) { tail=head= new linkptr(newlink); } else { head = new linkptr(newlink, *head); } } /******************************************************* * link :: active *******************************************************/ boolean Link :: active() { if (getMode()==NO_ACTION) return false; if (getStartTime()<0) return true; if (getStartTime()>gettime()) return false; if (getEndTime()<0) return true; if (getEndTime()>gettime()) return true; return false; } /******************************************************* * link :: setmode * * NO_ACTION POINT_TO_POINT, * ROTATE_ABOUT_POINT SCALE_FACTOR *******************************************************/ void Link :: setMode(SGLLinkMode modei) { mode=modei; switch (mode) { case POINT_TO_POINT: dx=dy=dz=1.0; setIterMode(LINEAR); break; case ROTATE_ABOUT_POINT: dz=360.0;dx=130;dy=23.0; setIterMode(LINEAR); break; case SCALE_FACTOR: dx=dy=dz=0.0; setIterMode(LINEAR); break; case NO_ACTION: default: break; } } void Link :: setMode(SGLLinkMode modei, SGLLinkIterMode imodei) { setMode(modei); setIterMode(imodei); } void Link :: setMode(SGLLinkMode modei, SGLLinkIterMode imodei, GLdouble dxi, GLdouble dyi, GLdouble dzi) { setMode(modei); setChange(dxi,dyi,dxi); setIterMode(imodei); } /******************************************************* * link :: set iter mode * * LINEAR SINE * QUADRATIC USERDEFINED *******************************************************/ void Link :: setIterMode(SGLLinkIterMode imodei) { /* GLdouble dt=0; if (getStartTime()>0 && getEndTime()>0) dt=getEndTime()-getStartTime(); if (dt>0) p2=PI/2.0/dt; */ switch (imodei) { case LINEAR: imode=LINEAR; break; case QUADRATIC: setIterMode(QUADRATIC,1.0,0.0,0.0); // (a,b,c) <=> a*t^2+b*t+c break; case SINE: setIterMode(SINE,1,0.0,1.0); // (frequency = 1/period, displacement, amplitud) break; default: break; } } void Link :: setIterMode(SGLLinkIterMode imodei, GLdouble p0i, GLdouble p1i, GLdouble p2i) { imode=imodei; p0=p0i; p1=p1i; p2=p2i; } /******************************************************* * link :: print *******************************************************/ void Link :: print () { linkptr * lp; cout << "Link @ (" << x << "," << y << "," << z << ")" << endl; lp=head; while (lp!=NULL) { lp->link->print(); lp=lp->next; } } # define DEGTORAD 0.01745329252 /******************************************************* * link :: iterate *******************************************************/ void Link :: iterate () { GLdouble deltax,deltay,deltaz; GLdouble t=gettime(); GLdouble factor; if (getStartTime()>=0) t-=getStartTime(); if (getIterMode()==LINEAR) factor=t; else if (getIterMode()==QUADRATIC) factor=p0*t*t+p1*t+p2; else factor=p2*sin((t*p0+p1)*DEGTORAD); //cout << "<"<=0 && getEndTime()>=0) { if (getIterMode()==SINE) factor*=p2*sin((factor*p0+p1)*DEGTORAD); else { GLdouble divider; divider = getEndTime()-getStartTime(); if (getIterMode()==QUADRATIC) divider=p0*factor*factor+p1*factor+p2; if (divider!=0.0) factor/=divider; else cerr << " Inconsistent Iteration Parameters." << endl; } } deltax=dx*factor; deltay=dy*factor; deltaz=dz*factor; switch (getMode()) { case POINT_TO_POINT: glTranslatef(deltax,deltay,deltaz); break; case ROTATE_ABOUT_POINT: glTranslatef(-x,-y,-z); glRotatef(deltax, 1.0, 0.0, 0.0); glRotatef(deltay, 0.0, 1.0, 0.0); glRotatef(deltaz, 0.0, 0.0, 1.0); glTranslatef(x,y,z); //cout << deltaz << "." << endl; break; case SCALE_FACTOR: glTranslatef(-x,-y,-z); glScalef(deltax,deltay,deltaz); glTranslatef(x,y,z); break; case NO_ACTION: default: break; } } /******************************************************* * link :: paint *******************************************************/ void Link :: paint () { linkptr * lp; boolean animate; animate=active(); if (animate || isEnabled() ) { glPushMatrix(); if (animate) iterate(); glTranslatef(x,y,z); glRotatef(rot_x, 1.0, 0.0, 0.0); glRotatef(rot_y, 0.0, 1.0, 0.0); glRotatef(rot_z, 0.0, 0.0, 1.0); glScalef(xf,yf,zf); lp=head; while (lp!=NULL) { if (lp->link->optimized()) glCallList(lp->link->getIndex()); else lp->link->paint(); lp=lp->next; } glPopMatrix(); //cout << "!"; } } /******************************************************* * link :: optimizable *******************************************************/ boolean Link :: linksOptimizable() { linkptr * lp=head; boolean all=true; while (lp!=NULL) { all = lp->link->optimizable() ? all : false; lp=lp->next; } return all; } boolean Link :: optimizable() { if (mode!=NO_ACTION) return false; if (optimized()) return true; return linksOptimizable(); } /******************************************************* * link :: optimizePaint *******************************************************/ void Link :: optimizePaint () { if (linksOptimizable()) Shape::optimizePaint(); else { linkptr * lp=head; while (lp!=NULL) { lp->link->optimizePaint(); lp=lp->next; } } }