/[gzz]/gzz/gfx/libcoords/Coords.cxx
ViewVC logotype

Diff of /gzz/gfx/libcoords/Coords.cxx

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.57 by tjl, Thu Dec 19 09:12:39 2002 UTC revision 1.58 by tjl, Thu Dec 19 23:06:00 2002 UTC
# Line 1  Line 1 
1  #include "libutil/Debug.hxx"  #include "libutil/Debug.hxx"
2  #include "libfisheye/Fisheye.hxx"  #include "libfisheye/Fisheye.hxx"
3  #include "Coords.hxx"  #include "Coords.hxx"
4    #include "libutil/VecGL.hxx"
5  #include <GL/gl.h>  #include <GL/gl.h>
6  #include <math.h>  #include <math.h>
7    
8    using namespace VecGL;
9    
10  namespace Coords {  namespace Coords {
11      DBGVAR(dbg, "Coords.general");  DBGVAR(dbg, "Coords.general");
12      DBGVAR(dbg_buoy, "Coords.buoy");  DBGVAR(dbg_buoy, "Coords.buoy");
13      DBGVAR(dbg_cull, "Coords.culling");  DBGVAR(dbg_cull, "Coords.culling");
14    
15      // The (STL-like) concept of transform:  // The (STL-like) concept of transform:
16      // enum { NParams = n };  // enum { NParams = n };
17      // void tr(const ZPt &from, ZPt &to) const  // void tr(const ZPt &from, ZPt &to) const
18      // float tr_radius(const ZPt &from, float radius) const  // float tr_radius(const ZPt &from, float radius) const
19      // bool canPerformGL()  // bool canPerformGL()
20      // bool performGL()  // bool performGL()
21      // float nonlinearity(const ZPt &p, float radius)  // float nonlinearity(const ZPt &p, float radius)
22      // void setParams(array/iterator i)  // void setParams(array/iterator i)
23      // typedef X InverseType;  // typedef X InverseType;
24      //  //
25      // This approach is needed because inverse transforms and transforms need  // This approach is needed because inverse transforms and transforms need
26      // to call their parents at different points.  // to call their parents at different points.
27      //  //
28      // XXX Nonlinearity is calculated wrong!  // XXX Nonlinearity is calculated wrong!
29        
30      template<class Transform> class TransformCoordSysBase : public CoordSys {  template<class Transform> class TransformCoordSysBase : public CoordSys {
31      protected:  protected:
32          Transform t;      Transform t;
33      public:  public:
34          TransformCoordSysBase() : t() { }      TransformCoordSysBase() : t() { }
35          TransformCoordSysBase(const Transform &tr) : t(tr) { }      TransformCoordSysBase(const Transform &tr) : t(tr) { }
36          virtual void setParams(float *params) {      virtual void setParams(float *params) {
37              t.setParams(params, super);          t.setParams(params, super);
38          }      }
39          bool canPerformGL() {      bool canPerformGL() {
40              return t.canPerformGL() && super->canPerformGL();            return t.canPerformGL() && super->canPerformGL();  
41          }      }
42      };  };
43    
44      template<class Transform> class InverseTransformCoordSys;  template<class Transform> class InverseTransformCoordSys;
45    
46      template<class Transform> class TransformCoordSys : public TransformCoordSysBase<Transform> {  template<class Transform> class TransformCoordSys : public TransformCoordSysBase<Transform> {
47      public:  public:
48          virtual ZPt transform(const ZPt &p) const {      virtual ZPt transform(const ZPt &p) const {
49              ZPt mp;          ZPt mp;
50              t.tr(p, mp);          t.tr(p, mp);
51              return super->transform(mp);          return super->transform(mp);
52          }      }
53          virtual void vertex(const ZPt &p) const {      virtual void vertex(const ZPt &p) const {
54              ZPt mp;          ZPt mp;
55              t.tr(p, mp);          t.tr(p, mp);
56              super->vertex(mp);          super->vertex(mp);
57          }      }
58          virtual bool performGL() {      virtual bool performGL() {
59              if(!super->performGL()) return false;          if(!super->performGL()) return false;
60              return t.performGL();          return t.performGL();
61          }      }
62    
63          virtual CoordSys *createInverse() {      virtual CoordSys *createInverse() {
64              CoordSys *sinv = super->getInverse();          CoordSys *sinv = super->getInverse();
65              typedef InverseTransformCoordSys<typename Transform::InverseType> Inv;          typedef InverseTransformCoordSys<typename Transform::InverseType> Inv;
66              Inv *ret = new Inv(sinv, t);          Inv *ret = new Inv(sinv, t);
67              ret->setOriginal(this);          ret->setOriginal(this);
68              return ret;          return ret;
69          }      }
70    
71          virtual float nonlinearity(const ZPt &p, float radius) {      virtual float nonlinearity(const ZPt &p, float radius) {
72              radius = fabs(radius);          radius = fabs(radius);
73              ZPt mp;          ZPt mp;
74              t.tr(p, mp);          t.tr(p, mp);
75              float srad = fabs(t.tr_radius(p, radius));          float srad = fabs(t.tr_radius(p, radius));
76              float snon = super->nonlinearity(mp, srad);          float snon = super->nonlinearity(mp, srad);
77              // Multiply to take into account shrinking / magnifying.          // Multiply to take into account shrinking / magnifying.
78              snon *= (srad+0.000001) / (radius+0.00001);          snon *= (srad+0.000001) / (radius+0.00001);
79              float non = t.nonlinearity(p, radius);          float non = t.nonlinearity(p, radius);
80              return (non > snon ? non : snon);          return (non > snon ? non : snon);
81          }      }
82    
83      };  };
84    
85      /** A TransformCoordSys that also uses the W, H definition of its parameter.  /** A TransformCoordSys that also uses the W, H definition of its parameter.
86       */   */
87      template<class Transform> class TransformWHCoordSys : public TransformCoordSys<Transform> {  template<class Transform> class TransformWHCoordSys : public TransformCoordSys<Transform> {
88      public:  public:
89          virtual Pt getSqSize() {      virtual Pt getSqSize() {
90              return t.getSqSize();          return t.getSqSize();
91          }      }
92    
93      };  };
94    
95      template<class Deriver>  template<class Deriver>
96              class DerivedTransformCoordSys :          class DerivedTransformCoordSys :
97                  public TransformCoordSys<typename Deriver::BaseTransform> {              public TransformCoordSys<typename Deriver::BaseTransform> {
98          CoordSys *dep[Deriver::NDetermining >? 1];      CoordSys *dep[Deriver::NDetermining >? 1];
99          float nparams[Deriver::BaseTransform::NParams];      float nparams[Deriver::BaseTransform::NParams];
100          Deriver d;      Deriver d;
101    
102    
103          virtual void setSuper(CoordSys **super) {      virtual void setSuper(CoordSys **super) {
104              CoordSys::setSuper(super);          CoordSys::setSuper(super);
105              for(int i=0; i<Deriver::NDetermining; i++)          for(int i=0; i<Deriver::NDetermining; i++)
106                  this->dep[i] = super[1 + i];              this->dep[i] = super[1 + i];
107          }      }
108    
109          virtual void setParams(float *params) {      virtual void setParams(float *params) {
110              d.derivedParams(super, dep, params, nparams);          d.derivedParams(super, dep, params, nparams);
111              t.setParams(nparams, super);          t.setParams(nparams, super);
112          }      }
113          virtual bool getOthertypeParams(int type, float *into) {      virtual bool getOthertypeParams(int type, float *into) {
114              if(type == Deriver::BaseTransform::TransId) {          if(type == Deriver::BaseTransform::TransId) {
115                  for(int i=0; i<Deriver::BaseTransform::NParams; i++)              for(int i=0; i<Deriver::BaseTransform::NParams; i++)
116                      into[i] = nparams[i];                  into[i] = nparams[i];
117                  return true;              return true;
             }  
             return false;  
         }  
         virtual bool shouldBeDrawn() {  
             return d.shouldBeDrawn();  
118          }          }
119      };          return false;
120        }
121        virtual bool shouldBeDrawn() {
122            return d.shouldBeDrawn();
123        }
124    };
125    
126      template<class Transform> class InverseTransformCoordSys : public TransformCoordSysBase<Transform> {  template<class Transform> class InverseTransformCoordSys : public TransformCoordSysBase<Transform> {
127      public:  public:
128          template<class Original> InverseTransformCoordSys(CoordSys *s, Original &o) :      template<class Original> InverseTransformCoordSys(CoordSys *s, Original &o) :
129                  TransformCoordSysBase<Transform>(o.inverseTransform()) {              TransformCoordSysBase<Transform>(o.inverseTransform()) {
130              super = s;          super = s;
131          }      }
132    
133          virtual ZPt transform(const ZPt &p) const {      virtual ZPt transform(const ZPt &p) const {
134              ZPt mp = super->transform(p);          ZPt mp = super->transform(p);
135              ZPt res;          ZPt res;
136              t.tr(mp, res);          t.tr(mp, res);
137              return res;          return res;
138          }      }
139          virtual void vertex(const ZPt &p) const {      virtual void vertex(const ZPt &p) const {
140              ZPt mp = transform(p);          ZPt mp = transform(p);
141              glVertex3f(mp.x, mp.y, mp.z);          glVertex3f(mp.x, mp.y, mp.z);
142          }      }
143          virtual bool performGL() {      virtual bool performGL() {
144              if(!t.performGL()) return false;          if(!t.performGL()) return false;
145              return super->performGL();          return super->performGL();
146          }      }
147          void setOriginal(CoordSys *orig) { inverse = orig; ownInverse = 0;}      void setOriginal(CoordSys *orig) { inverse = orig; ownInverse = 0;}
148    
149      };  };
150    
151      class RootCoords : public CoordSys {  class RootCoords : public CoordSys {
152      public:      public:
153          virtual void setParams(float *params) { }          virtual void setParams(float *params) { }
154          virtual ZPt transform(const ZPt &p) const {          virtual ZPt transform(const ZPt &p) const {
# Line 166  namespace Coords { Line 169  namespace Coords {
169          }          }
170      };      };
171    
172    
173    struct PointInterpCoordSys : public CoordSys {
174        CoordSys *cs1, *cs2;
175        float fract;
176        PointInterpCoordSys(CoordSys *cs1, CoordSys *cs2, float fract)
177                : cs1(cs1), cs2(cs2), fract(fract) { }
178        virtual CoordSys *createInverse() {
179            // XXX ARGH!
180            ownInverse = true;
181            return new RootCoords();
182        }
183        virtual void setSuper(CoordSys **super) {
184        }
185        virtual void setParams(float *params) {
186        }
187        virtual void vertex(const ZPt &p) const {
188            glVertex(transform(p));
189        }
190        virtual ZPt transform(const ZPt &p) const {
191            return lerp(cs1->transform(p),
192                        cs2->transform(p),
193                        fract);
194        }
195        virtual float nonlinearity(const ZPt &p, float radius) {
196            return lerp(cs1->nonlinearity(p, radius),
197                    cs2->nonlinearity(p, radius), fract);
198        }
199    
200        virtual bool shouldBeDrawn() {
201            return cs1->shouldBeDrawn() && cs2->shouldBeDrawn();
202        }
203        virtual Pt getSqSize() {
204            return lerp(cs1->getSqSize(), cs2->getSqSize(), fract);
205        }
206        
207        bool canPerformGL() {
208            return cs1->canPerformGL() && cs2->canPerformGL();
209        }
210        bool performGL() {
211            // XXX Allow using of vertex weighting or something
212            if(!canPerformGL()) return false;
213            GLfloat mat1[16], mat2[16];
214            glPushAttrib(GL_TRANSFORM_BIT);
215            glMatrixMode(GL_MODELVIEW);
216            glPushMatrix();
217    
218            glLoadIdentity();
219            cs1->performGL();
220            glGetFloatv(GL_MODELVIEW_MATRIX, mat1);
221    
222            glLoadIdentity();
223            cs2->performGL();
224            glGetFloatv(GL_MODELVIEW_MATRIX, mat2);
225    
226            for(int i=0; i<16; i++) mat1[i] = lerp(mat1[i], mat2[i], fract);
227    
228    
229            glPopMatrix();
230            glPopAttrib();
231    
232            glMultMatrixf(mat1);
233            return true;
234        }
235    };
236    
237      struct UnitCoords {      struct UnitCoords {
238          enum { NParams = 0 };          enum { NParams = 0 };
239          void tr(const ZPt &from, ZPt &to) const {          void tr(const ZPt &from, ZPt &to) const {
# Line 1144  namespace Coords { Line 1212  namespace Coords {
1212          return facs[typecode]->create();          return facs[typecode]->create();
1213      }      }
1214    
1215        CoordSet::CoordSet() : cs1_tmp(0), cs2_tmp(0) {
1216        }
1217        CoordSet::~CoordSet() {
1218            if(cs1_tmp) { delete cs1_tmp; cs1_tmp = 0; }
1219            if(cs2_tmp) { delete cs2_tmp; cs2_tmp = 0; }
1220        }
1221    
1222        // Once types are checked, this method checks the parents.
1223        bool CoordSet::shouldInterpolate(int cs1, int cs2, int nprev) {
1224            DBG(dbg) << "Shouldinterp "<<cs1<<" "<<cs2<<" "<<nprev<<"\n";
1225            for(int i=0; i<nprev; i++) {
1226                int par1 = inds1[cs1+1+i];
1227                if(!cs[par1]) return false;
1228                int par2 = inds1[cs2+1+i];
1229                if(par1 >= interpinds[0]) return false;
1230                if(interpinds[par1] != par2) return false;
1231            }
1232            DBG(dbg) << "DO interpolate\n";
1233            return true;
1234        }
1235    
1236      void CoordSet::setPoints( int ninds,      void CoordSet::setPoints( int ninds,
1237                                   int *inds1, float *points1,                                   int *inds1, float *points1,
1238                                   int *interpinds,                                   int *interpinds,
# Line 1157  namespace Coords { Line 1246  namespace Coords {
1246                      << points2 << " "                      << points2 << " "
1247                      << fract << " "                      << fract << " "
1248                      << show1 << "\n" ;                      << show1 << "\n" ;
1249    #define ASG(x) this->x = x;
1250            ASG(ninds)
1251            ASG(inds1)
1252            ASG(points1)
1253            ASG(interpinds)
1254            ASG(inds2)
1255            ASG(points2)
1256    
1257          params.resize(0);          params.resize(0);
1258          DBG(dbg)  << "Resized\n";          DBG(dbg)  << "Resized\n";
1259          params.reserve(3*ninds);          params.reserve(3*ninds);
# Line 1167  namespace Coords { Line 1264  namespace Coords {
1264          DBG(dbg)  << "setroot\n";          DBG(dbg)  << "setroot\n";
1265          int lastIndSize = 1;          int lastIndSize = 1;
1266    
1267          CoordSet *cs1_tmp = 0;          if(cs1_tmp) { delete cs1_tmp; cs1_tmp = 0; }
1268          CoordSet *cs2_tmp = 0;          if(cs2_tmp) { delete cs2_tmp; cs2_tmp = 0; }
1269    
1270          this->maxcs = ninds;          this->maxcs = ninds;
1271    
# Line 1185  namespace Coords { Line 1282  namespace Coords {
1282    
1283              lastIndSize = nprev + 2; // typecode, prevs and paramind              lastIndSize = nprev + 2; // typecode, prevs and paramind
1284    
             CoordSys *prev[nprev];  
1285    
1286              ind1 = inds1[i+1+nprev];              ind1 = inds1[i+1+nprev];
1287              csind2 = ((interpinds && i < interpinds[0]) ? interpinds[i] : -1);              csind2 = ((interpinds && i < interpinds[0]) ? interpinds[i] : -1);
1288              DBG(dbg) << "inds: "<<parind<<" typ:"<<tp<<" npars:"<<npars<<              DBG(dbg) << "inds: "<<parind<<" typ:"<<tp<<" npars:"<<npars<<
                             " parent:"<<prev[0]<<" "<<  
1289                              " ind1:"<<ind1<<" "<<csind2<<"\n";                              " ind1:"<<ind1<<" "<<csind2<<"\n";
1290    
1291                CoordSys *c;
1292              if(csind2 <= 0) {              int t2 = 0;
1293                int ind2 = 0;
1294                  if(show1) {              if(csind2 > 0) {
1295                      for(int j = 0; j<npars; j++) {                  t2 = inds2[csind2] & ~CSFLAGS;
1296                          params.push_back(points1[ind1 + j]);                  ind2 = inds2[csind2 + 1 + nprevious(t2)];
1297                }
1298                // We need to interpolate. Check the structural constraints:
1299                // If
1300                //   1) both are of same type
1301                //   2) all parents interpolate to each other exactly
1302                // then use parameter interpolation
1303                // Else, use pointwise interpolation
1304                if(csind2 <= 0 || (t2 == tp && shouldInterpolate(i, csind2, nprev))) {
1305    
1306                    if(csind2 <= 0) {
1307    
1308                        if(show1) {
1309                            for(int j = 0; j<npars; j++) {
1310                                params.push_back(points1[ind1 + j]);
1311                            }
1312                        } else {
1313                            continue;
1314                      }                      }
1315                  } else {                  } else {
                     continue;  
                 }  
             } else {  
                 int t2 = inds2[csind2] & ~CSFLAGS;  
                 int ind2 = inds2[csind2 + 1 + nprevious(t2)];  
                 if(t2 == tp) {  
1316                      for(int j = 0; j<npars; j++) {                      for(int j = 0; j<npars; j++) {
1317                          DBG(dbg) << "Interpolating "                          DBG(dbg) << "Interpolating "
1318                              <<(ind1+j)<<" " <<(ind2+j)<<"  = "                              <<(ind1+j)<<" " <<(ind2+j)<<"  = "
# Line 1215  namespace Coords { Line 1321  namespace Coords {
1321                              lerp(points1[ind1 + j],                              lerp(points1[ind1 + j],
1322                                   points2[ind2 + j], fract));                                   points2[ind2 + j], fract));
1323                      }                      }
                 } else {  
                     // Now, the hairy case.  
                     DBG(dbg) << "It got hairy now: "<<tp<<" "<<t2<<"\n";  
                     if(!cs1_tmp) {  
                         cs1_tmp = new CoordSet();  
                         cs1_tmp->setPoints(ninds, inds1, points1,  
                                     0,  0,      0,      0, true);  
                     }  
                     if(!cs2_tmp) {  
                         int maxind = 0;  
                         for(int k = 1; k<interpinds[0]; k++)  
                             if(interpinds[k] > maxind)  
                                 maxind = interpinds[k];  
                         cs2_tmp = new CoordSet();  
                         cs2_tmp->setPoints(maxind+1, inds2, points2, 0, 0, 0,  
                                             0, true);  
                     }  
                     CoordSys *cs1_non = cs1_tmp->get(i);  
                     CoordSys *cs2_non = cs2_tmp->get(csind2);  
   
                     if(!cs1_non || !cs2_non) goto nextInd;  
   
                     // Next, the conversion.  
                     // For now, insist on one converting directly  
                     // to the other. Later need to search  
                     // inheritance tree  
                     int cs1_np = npars;  
                     int cs2_np = nparams(t2);  
                     // Just try each conversion routine;  
                     int maxpar = cs1_np >? cs2_np; // gnu c++-ism.  
                     float newpars[maxpar];  
                     DBG(dbg) << "Try getOther: "<<maxpar<<  
                          " " << cs1_non << " "  
                          << cs2_non << "\n";  
                     if(cs1_non->getOthertypeParams(t2, newpars)) {  
                         DBG(dbg) << "Changed 1\n";  
                         for(int i=0; i<cs2_np; i++) {  
                             DBG(dbg) << "Interp "<<newpars[i]<<" "<<points2[ind2+i]<<"\n";  
                             params.push_back(  
                                     lerp(newpars[i],  
                                          points2[ind2 + i],  
                                          fract));  
                         }  
                         // NOTE!!!  
                         tp = t2;  
                         nprev = nprevious(tp);  
                         // Now, fall through, it gets created right.  
                     } else if(cs2_non->getOthertypeParams(tp, newpars)) {  
                         DBG(dbg) << "Changed 2\n";  
                         for(int i=0; i<cs1_np; i++) {  
                             DBG(dbg) << "Interp "<<points1[ind1+i]<<" "<<newpars[i]<<" "<<"\n";  
                             params.push_back(  
                                     lerp(points1[ind1 + i],  
                                          newpars[i],  
                                          fract));  
                         }  
                         // Fall through, it's the right type  
                     }  
                     DBG(dbg) << "Done getother: "<<tp<<"\n";  
1324                  }                  }
1325              }                  CoordSys *prev[nprev];
             {  
1326                                    
1327                  for(int j=0; j<nprev; j++) {                  for(int j=0; j<nprev; j++) {
1328                      int parent = inds1[i+1+j];                      int parent = inds1[i+1+j];
# Line 1293  namespace Coords { Line 1339  namespace Coords {
1339                   * params. If the initialized coordsys (according to its initialized attributes)                   * params. If the initialized coordsys (according to its initialized attributes)
1340                   * decides not to be drawn, it will be deleted and replaced with the NULL pointer.                   * decides not to be drawn, it will be deleted and replaced with the NULL pointer.
1341                   */                   */
1342                  CoordSys *c = create(tp);                  c = create(tp);
                 cs[i] = c;  
1343                  c->setSuper(prev);                  c->setSuper(prev);
1344                  c->setParams(&(params[0]) + parind);                  c->setParams(&(params[0]) + parind);
1345                } else {
1346                    // Now, the hairy case.
1347                    DBG(dbg) << "It got hairy now: "<<tp<<" "<<t2<<"\n";
1348                    if(!cs1_tmp) {
1349                        cs1_tmp = new CoordSet();
1350                        cs1_tmp->setPoints(ninds, inds1, points1,
1351                                    0,      0,      0,      0, true);
1352                    }
1353                    if(!cs2_tmp) {
1354                        int maxind = 0;
1355                        for(int k = 1; k<interpinds[0]; k++)
1356                            if(interpinds[k] > maxind)
1357                                maxind = interpinds[k];
1358                        cs2_tmp = new CoordSet();
1359                        cs2_tmp->setPoints(maxind+1, inds2, points2, 0, 0, 0,
1360                                            0, true);
1361                    }
1362                    CoordSys *cs1_non = cs1_tmp->get(i);
1363                    CoordSys *cs2_non = cs2_tmp->get(csind2);
1364    
1365                    if(!cs1_non || !cs2_non) goto nextInd;
1366    
1367                    c = new PointInterpCoordSys(cs1_non, cs2_non, fract);
1368    
1369                }
1370                {
1371                    cs[i] = c;
1372    
1373                  if (!cs[i]->shouldBeDrawn()) {                  if (!cs[i]->shouldBeDrawn()) {
1374                    DBG(dbg) << "CS should not be drawn... freeing it with delete.\n";                    DBG(dbg) << "CS should not be drawn... freeing it with delete.\n";
# Line 1306  namespace Coords { Line 1378  namespace Coords {
1378              }              }
1379          nextInd:;          nextInd:;
1380          }          }
         if(cs1_tmp) delete cs1_tmp;  
         if(cs2_tmp) delete cs2_tmp;  
1381          DBG(dbg)  << "end\n";          DBG(dbg)  << "end\n";
1382      }      }
1383    

Legend:
Removed from v.1.57  
changed lines
  Added in v.1.58

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26