home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 March / VPR9703A.ISO / VPR_DATA / DOGA / SOURCES / POLYEDIT.LZH / MODEL / VERSET.C < prev    next >
C/C++ Source or Header  |  1996-07-25  |  8KB  |  385 lines

  1. /*
  2.  *    エッジ
  3.  *
  4.  *        Copyright T.Kobayashi    1994.7.9
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <assert.h>
  11. #include <math.h>
  12.  
  13. #include "matrix.h"
  14. #include "vector.h"
  15. #include "matclass.h"
  16. #include "strclass.h"
  17. #include "ml.h"
  18.  
  19. #include "poly.h"
  20. #include "view.h"
  21.  
  22. extern    int        VertexSetClassID ;
  23.  
  24. #define VERTEXALLOCUNIT    256
  25.  
  26. #ifndef __GNUC__
  27. #define inline
  28. #endif
  29.  
  30. static    inline int    VertexEqual(Vertex *v1, Vertex *v2)
  31. {
  32.     return memcmp(v1, v2, sizeof(Vertex)) == 0;
  33. }
  34.  
  35. /* このコードは Vertex がshort x 8 = int * 4 であることに依存*/
  36. static inline int VertexCompare(Vertex *v1, Vertex *v2)
  37. {
  38.     int *i1, *i2;
  39.     int c;
  40.     i1 = (int*)v1;
  41.     i2 = (int*)v2;
  42.     if ((c = i1[0] - i2[0]) != 0) return c;
  43.     if ((c = i1[1] - i2[1]) != 0) return c;
  44.     if ((c = i1[2] - i2[2]) != 0) return c;
  45.     return i1[3] - i2[3];
  46. }
  47.  
  48. static VertexSetClass    *VertexRealloc(VertexSetClass *verset, int size)
  49. {
  50.     VertexSetClass *newverset;
  51.     newverset = (VertexSetClass*)ObjectAlloc(sizeof(VertexSetClass) + sizeof(Vertex) * size, VertexSetClassID);
  52.     if (size > verset->allocsize) {
  53.         memcpy(newverset->ver, verset->ver, sizeof(Vertex) * verset->allocsize);
  54.     } else {
  55.         memcpy(newverset->ver, verset->ver, sizeof(Vertex) * size);
  56.     }
  57.     newverset->vers = verset->vers;
  58.     newverset->allocsize = size;
  59.  
  60.     ObjectFree((Object*)verset);
  61.     return newverset;
  62. }
  63.  
  64. static    VertexSetClass    *VertexDeletePos(VertexSetClass *verset, int pos)
  65. {
  66.     if (pos < 0 || verset->vers <= pos) {
  67.         return verset;
  68.     }
  69.     if (pos != verset->vers-1) {
  70.         memmove(&verset->ver[pos], &verset->ver[pos+1], sizeof(Vertex) * (verset->vers-pos-1));
  71.     }
  72.     verset->vers--;
  73.     return verset;
  74. }
  75.  
  76. int    VertexSearch(VertexSetClass *verset, Vertex *vd)
  77. {
  78.     int i, j;
  79.     int begin, end;
  80.     begin = -1;
  81.     end = verset->vers;
  82.     while (begin < end-1) {
  83.         i = (begin+end)/2;
  84.         j = VertexCompare(&verset->ver[i], vd);
  85.         if (j == 0) {
  86.             return i;
  87.         } else if (j < 0) {
  88.             end = i;
  89.         } else {
  90.             begin = i;
  91.         }
  92.     }
  93.     return -1;
  94. }
  95.  
  96. VertexSetClass    *VertexAppend(VertexSetClass *verset, Vertex *vd)
  97. {
  98.     int pos;
  99.     int j, begin, end;
  100.     if (verset->allocsize <= verset->vers) {
  101.         verset = VertexRealloc(verset, verset->allocsize + VERTEXALLOCUNIT);
  102.     }
  103.     begin = -1;
  104.     pos = end = verset->vers;
  105.     while (begin < end-1) {
  106.         pos = (begin+end)/2;
  107.         j = VertexCompare(&verset->ver[pos], vd);
  108.         if (j == 0) {
  109. /*            verset->ver[pos].count++;*/
  110.             return verset;
  111.         } else if (j < 0) {
  112.             end = pos;
  113.         } else {
  114.             begin = pos;
  115.         }
  116.     }
  117.     pos = end;
  118.     if (pos < verset->vers) {
  119.         memmove(&verset->ver[pos+1], &verset->ver[pos], sizeof(Vertex) * (verset->vers-pos));
  120.     }
  121.     verset->ver[pos] = *vd;
  122.  
  123.     verset->vers++;
  124.     return verset;
  125. }
  126.  
  127. VertexSetClass    *VertexDelete(VertexSetClass *verset, Vertex *vd)
  128. {
  129.     int pos;
  130.  
  131.     if ((pos = VertexSearch(verset, vd)) >= 0) {
  132.         verset = VertexDeletePos(verset, pos);
  133.     }
  134.     return verset;
  135. }
  136.  
  137. VertexSetClass    *VertexAlloc(int size)
  138. {
  139.     VertexSetClass *verset;
  140.     if (size < VERTEXALLOCUNIT) {
  141.         size = VERTEXALLOCUNIT;
  142.     } else {
  143.         size = ((size / VERTEXALLOCUNIT) + 1) * VERTEXALLOCUNIT;
  144.     }
  145.     verset = (VertexSetClass*)ObjectAlloc(sizeof(VertexSetClass) + sizeof(Vertex) * size, VertexSetClassID);
  146.     verset->allocsize = size;
  147.     verset->vers = 0;
  148.     return verset;
  149. }
  150.  
  151. static    int    VertexSearchPoly(VertexSetClass *verset, Polygon *poly)
  152. {
  153.     int i;
  154.     int vers = poly->vers ;
  155.  
  156.     for( i = 0 ; i < vers ; i++ )
  157.     {
  158.         if (VertexSearch(verset, &poly->ver[i]) >= 0) {
  159.             return TRUE;
  160.         }
  161.     }
  162.     return FALSE;
  163. }
  164.  
  165. VertexSetClass    *VertexMulMatrix(VertexSetClass *verset, MatrixClass* mat)
  166. {
  167.  
  168.     int    imat[5][3];
  169.     int    imatit[5][3];
  170.     Matrix    matit;
  171.     int i, x, y, z;
  172.     Vertex *ed;
  173.  
  174.     MatCopy(matit, mat->mat);
  175.     MatInv(matit);
  176.     MatTra(matit);
  177.     MatToInt( imat, mat->mat );
  178.     MatToInt( imatit, matit );
  179.  
  180.     ed = verset->ver;
  181.     for (i = 0; i < verset->vers; i++) {
  182.         float r;
  183.         x = (int)ed->x * imat[0][0]
  184.           + (int)ed->y * imat[1][0]
  185.           + (int)ed->z * imat[2][0]
  186.           + imat[4][0] ;
  187.         y = (int)ed->x * imat[0][1]
  188.           + (int)ed->y * imat[1][1]
  189.           + (int)ed->z * imat[2][1]
  190.           + imat[4][1] ;
  191.         z = (int)ed->x * imat[0][2]
  192.           + (int)ed->y * imat[1][2]
  193.           + (int)ed->z * imat[2][2]
  194.           + imat[4][2] ;
  195.         ed->x = (short)imat[3][0] + (short)( x >> 16 );
  196.         ed->y = (short)imat[3][1] + (short)( y >> 16 );
  197.         ed->z = (short)imat[3][2] + (short)( z >> 16 );
  198.  
  199.         x = (int)ed->vx * imatit[0][0]
  200.           + (int)ed->vy * imatit[1][0]
  201.           + (int)ed->vz * imatit[2][0];
  202.         y = (int)ed->vx * imatit[0][1]
  203.           + (int)ed->vy * imatit[1][1]
  204.           + (int)ed->vz * imatit[2][1];
  205.         z = (int)ed->vx * imatit[0][2]
  206.           + (int)ed->vy * imatit[1][2]
  207.           + (int)ed->vz * imatit[2][2];
  208.         r = sqrt((float)x * (float)x + (float)y * (float)y + (float)z * (float)z);
  209.         if (r > 0.0) r = 256.0 / r;
  210.         ed->vx = (short)(r * (float)x);
  211.         ed->vy = (short)(r * (float)y);
  212.         ed->vz = (short)(r * (float)z);
  213.  
  214.         ed++;
  215.     }
  216.     return verset;
  217. }
  218.  
  219. VertexSetClass    *VertexLogicalOr(VertexSetClass *e1, VertexSetClass *e2)
  220. {
  221.     int i;
  222.     for (i = 0; i < e2->vers; i++) {
  223.         e1 = VertexAppend(e1, &e2->ver[i]);
  224.     }
  225.     return e1;
  226. }
  227.  
  228. VertexSetClass    *VertexLogicalSub(VertexSetClass *e1, VertexSetClass *e2)
  229. {
  230.     int i, pos;
  231.     for (i = 0; i < e2->vers; i++) {
  232.         if ((pos = VertexSearch(e1, &e2->ver[i])) >= 0) {
  233.             e1 = VertexDeletePos(e1, pos);
  234.         }
  235.     }
  236.     return e1;
  237. }
  238.  
  239. VertexSetClass    *VertexLogicalAnd(VertexSetClass *e1, VertexSetClass *e2)
  240. {
  241.     int i, pos;
  242.     VertexSetClass *verset;
  243.     verset = VertexAlloc(0);
  244.     for (i = 0; i < e2->vers; i++) {
  245.         if ((pos = VertexSearch(e1, &e2->ver[i])) >= 0) {
  246.             verset = VertexAppend(verset, &e1->ver[pos]);
  247.         }
  248.     }
  249.     ObjectFree((Object*)e1);
  250.     return verset;
  251. }
  252.  
  253. VertexSetClass    *VertexLogicalXor(VertexSetClass *e1, VertexSetClass *e2)
  254. {
  255.     int i, pos;
  256.     for (i = 0; i < e2->vers; i++) {
  257.         if ((pos = VertexSearch(e1, &e2->ver[i])) >= 0) {
  258.             e1 = VertexDeletePos(e1, pos);
  259.         } else {
  260.             e1 = VertexAppend(e1, &e2->ver[i]);
  261.         }
  262.     }
  263.     return e1;
  264. }
  265.  
  266. int    VertexLogicalEqual(VertexSetClass *e1, VertexSetClass *e2)
  267. {
  268.     int i;
  269.     if (e1->vers != e2->vers) {
  270.         return FALSE;
  271.     }
  272.     for (i = 0; i < e1->vers; i++) {
  273.         if (!VertexEqual(&e1->ver[i], &e2->ver[i])) {
  274.             return FALSE;
  275.         }
  276.     }
  277.     return TRUE;
  278. }
  279.  
  280. VertexSetClass    *VertexSelect(void)
  281. {
  282.     int i;
  283.     VertexSetClass *verset;
  284.     Vertex v;
  285.     Polygon    *poly ;
  286.     verset = VertexAlloc(0);
  287.     poly = PolyTop();
  288.     while( poly != NULL )
  289.     {
  290.         if ( poly->select == ON ) {
  291.             for( i = 0; i < poly->vers; ++i) {
  292.                 v = poly->ver[i];
  293.                 if (( poly->type & POLY_SHADE) == 0) {
  294.                     v.vx = v.vy = v.vz = 0;
  295.                 }
  296.                 if (( poly->type & POLY_UV) == 0) {
  297.                     v.u = v.v = 0;
  298.                 }
  299.                 verset = VertexAppend(verset, &v);
  300.             }
  301.         }
  302.         poly = BufferNext( poly );
  303.     }
  304.     return verset;
  305. }
  306.  
  307.  
  308. static    void    SelectPoly(Polygon *poly, int sel, int flag, int sw )
  309. /* flag :     ON | OFF    */
  310. /* sw :       UPDATE | AND | OR | XOR    */
  311. {
  312.     if ( poly->mode & MODE_INVISIBLE )
  313.         return ;
  314.  
  315.     if ( ! sel )
  316.         flag = ! flag ;
  317.  
  318.     switch( sw & SELECT_LOG )
  319.     {
  320.         case SELECT_UPDATE:
  321.             poly->select = flag ;
  322.             break ;
  323.         case SELECT_AND:
  324.             poly->select &= flag ;
  325.             break ;
  326.         case SELECT_OR:
  327.             poly->select |= flag ;
  328.             break ;
  329.         case SELECT_XOR:
  330.             poly->select ^= flag ;
  331.             break ;
  332.         default:
  333.             assert( FALSE );
  334.     }
  335.  
  336.     if ( poly->select )
  337.         Selects ++ ;
  338. }
  339.  
  340. void    PolySelectVertex( VertexSetClass *verset, int flag, int sw)
  341. {
  342.     Polygon    *poly ;
  343.     PolyPtr = NULL ;
  344.  
  345.     Selects = 0 ;
  346.     poly = PolyTop();
  347.     while( poly != NULL )
  348.     {
  349.         SelectPoly( poly, VertexSearchPoly(verset, poly), flag, sw );
  350.         poly = BufferNext( poly );
  351.     }
  352. }
  353.  
  354. VertexSetClass    *VertexPositionVertex(VertexSetClass *e1)
  355. {
  356.     int i, pos;
  357.     VertexSetClass *ret;
  358.     Vertex v;
  359.     memset(&v, 0, sizeof(Vertex));
  360.     ret = VertexAlloc(0);
  361.     for (i = 0; i < e1->vers; i++) {
  362.         v.x = e1->ver[i].x;
  363.         v.y = e1->ver[i].y;
  364.         v.z = e1->ver[i].z;
  365.         ret = VertexAppend(ret, &v);
  366.     }
  367.     return ret;
  368. }
  369.  
  370. VertexSetClass    *VertexSelectPosition(VertexSetClass *verset, Vertex *v)
  371. {
  372.     int i, pos;
  373.     VertexSetClass *ret;
  374.     ret = VertexAlloc(0);
  375.     for (i = 0; i < verset->vers; i++) {
  376.         if (verset->ver[i].x == v->x
  377.          && verset->ver[i].y == v->y
  378.          && verset->ver[i].z == v->z) {
  379.             ret = VertexAppend(ret, &verset->ver[i]);
  380.         }
  381.     }
  382.     return ret;
  383. }
  384.  
  385.