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

  1. /*
  2.  *        ポリゴンデータ管理ライブラリ
  3.  *
  4.  *        Copyright    T.Kobayashi        1994.8.7
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <math.h>
  11. #include <assert.h>
  12.  
  13. #include "lib.h"
  14. #include "alloc.h"
  15. #include "buffer.h"
  16. #include "poly.h"
  17.  
  18. typedef    struct    {
  19.     short    flag, useflag ;
  20.     short    x, y, z ;
  21.     short    vx, vy, vz ;
  22. }
  23.     HashStruct ;
  24.  
  25. HashStruct    *HashTable = NULL;
  26. int            HashSize, HashBit ;
  27.  
  28. static    void    MakeHash( int );
  29. static    void    HashAppend( Vertex*, int, int, int );
  30. static    int        HashFunc( Vertex* );
  31. static    int        HashEqual( Vertex*, HashStruct* );
  32. static    HashStruct    *HashRead( Vertex* );
  33. /*
  34. static    void    Coefficent( int[3], Vertex*, int );
  35. */
  36. /*    セレクトされているポリゴンに法線ベクトルをつける    */
  37. void    PolyShade( sw )
  38. int        sw ;
  39. {
  40.     int        i, coe[3] ;
  41.     float    vx, vy, vz, r ;
  42.     float    pvx, pvy, pvz ;
  43.     Polygon    *poly ;
  44.     Vertex    *ver ;
  45.     HashStruct    *table ;
  46.  
  47.     if ( Selects == 0 )
  48.         return ;
  49.  
  50.     if (sw == SHADE_CREATE)
  51.     {
  52.         poly = PolyTop();
  53.         while( poly != NULL )
  54.         {
  55.             if ( poly->select == ON )
  56.             {
  57.                 ver = poly->ver ;
  58.                 poly->type |= POLY_SHADE ;
  59.                 ObjData[poly->obj].edit = TRUE ;
  60.  
  61.                 Coefficent( coe, ver, poly->vers );
  62.  
  63.                 for( i = poly->vers ; i > 0 ; i-- )
  64.                 {
  65.                     ver->vx = coe[0];
  66.                     ver->vy = coe[1];
  67.                     ver->vz = coe[2];
  68.                     ver ++ ;
  69.                 }
  70.  
  71.             }
  72.             poly = PolyNext( poly );
  73.         }
  74.     }
  75.     else if ( sw )
  76.     {
  77.         int vertexs = 0;
  78.         poly = PolyTop();
  79.         while( poly != NULL )
  80.         {
  81.             if ( poly->select == ON )
  82.             {
  83.                 vertexs += poly->vers;
  84.             }
  85.             poly = PolyNext( poly );
  86.         }
  87.         MakeHash(vertexs);
  88.  
  89.         poly = PolyTop();
  90.         while( poly != NULL )
  91.         {
  92.             if ( poly->select == ON )
  93.             {
  94.                 ver = poly->ver ;
  95.                 Coefficent( coe, ver, poly->vers );
  96.                 for( i = poly->vers ; i > 0 ; i-- )
  97.                 {
  98.                     HashAppend( ver, coe[0], coe[1], coe[2] );
  99.                     ver ++ ;
  100.                 }
  101.             }
  102.             poly = PolyNext( poly );
  103.         }
  104.  
  105.         poly = PolyTop();
  106.         while( poly != NULL )
  107.         {
  108.             if ( poly->select == ON )
  109.             {
  110.                 ver = poly->ver ;
  111.                 poly->type |= POLY_SHADE ;
  112.                 ObjData[poly->obj].edit = TRUE ;
  113.  
  114. #if 1
  115.                 Coefficent( coe, ver, poly->vers );
  116.                 for( i = poly->vers ; i > 0 ; i-- )
  117.                 {
  118.                     table = HashRead( ver );
  119.                     vx = (float)table->vx ;
  120.                     vy = (float)table->vy ;
  121.                     vz = (float)table->vz ;
  122.                     if (vx * coe[0] + vy * coe[1] + vz * coe[2] < (float)0.0 )
  123.                     {
  124.                         vx = - vx ;
  125.                         vy = - vy ;
  126.                         vz = - vz ;
  127.                     }
  128.                     r = sqrt(vx * vx + vy * vy + vz * vz);
  129.                     if (r > 0.0) r = 256.0 / r;
  130. /*                    r = 256.0 / sqrt( vx * vx + vy * vy + vz * vz );*/
  131.                     ver->vx = (int)( vx * r );
  132.                     ver->vy = (int)( vy * r );
  133.                     ver->vz = (int)( vz * r );
  134.  
  135.                     ver ++ ;
  136.                 }
  137.  
  138. #else
  139.                 for( i = 0 ; i < poly->vers ; i++ )
  140.                 {
  141.                     table = HashRead( ver );
  142.                     vx = (float)table->vx ;
  143.                     vy = (float)table->vy ;
  144.                     vz = (float)table->vz ;
  145.  
  146.                     if ( i > 0 && pvx * vx + pvy * vy + pvz * vz < (float)0.0 )
  147.                     {
  148.                         if (table->useflag == FALSE) {
  149.                             table->vx = -table->vx;
  150.                             table->vy = -table->vy;
  151.                             table->vz = -table->vz;
  152.                             vx = - vx ;
  153.                             vy = - vy ;
  154.                             vz = - vz ;
  155.                         } else {
  156.                             int j;
  157.                             for (j = 0; j < i; j++) {
  158.                                 poly->ver[j].vx = -poly->ver[j].vx;
  159.                                 poly->ver[j].vy = -poly->ver[j].vy;
  160.                                 poly->ver[j].vz = -poly->ver[j].vz;
  161.                             }
  162.                         }
  163.                     }
  164.                     table->useflag = TRUE;
  165.  
  166.                     r = sqrt(vx * vx + vy * vy + vz * vz);
  167.                     if (r > 0.0) r = 256.0 / r;
  168. /*                    r = 256.0 / sqrt( vx * vx + vy * vy + vz * vz );*/
  169.                     ver->vx = (int)( vx * r );
  170.                     ver->vy = (int)( vy * r );
  171.                     ver->vz = (int)( vz * r );
  172.                     pvx = vx ;
  173.                     pvy = vy ;
  174.                     pvz = vz ;
  175.                     ver ++ ;
  176.                 }
  177. #endif
  178. /*                HashAppend( ver, coe[0], coe[1], coe[2] );*/
  179.             }
  180.             poly = PolyNext( poly );
  181.         }
  182.         MemoryFree(HashTable);
  183.         HashTable = NULL;
  184.     }
  185.     else
  186.     {
  187.         poly = PolyTop();
  188.         while( poly != NULL )
  189.         {
  190.             if ( poly->select == ON )
  191.             {
  192.                 poly->type &= ( ~ POLY_SHADE );
  193.                 ObjData[poly->obj].edit = TRUE ;
  194.             }
  195.             poly = PolyNext( poly );
  196.         }
  197.     }
  198. }
  199.  
  200. /*    ハッシュテーブルをつくる    */
  201. static    void    MakeHash(int vertexs)
  202. {
  203.     int        i;
  204.  
  205.     HashSize = 1 ;
  206.     while( vertexs != 0 )
  207.     {
  208.         HashSize <<= 1 ;
  209.         vertexs >>= 1 ;
  210.     }
  211.     if (HashTable != NULL) {
  212.         MemoryFree(HashTable);
  213.     }
  214.     HashTable = MemoryAlloc( HashSize * sizeof( HashStruct ) );
  215.     for( i = 0 ; i < HashSize ; i++ ) {
  216.         HashTable[i].flag = FALSE ;
  217.         HashTable[i].useflag = FALSE ;
  218.     }
  219.     HashBit = HashSize - 1 ;
  220. }
  221.  
  222. /*    ハッシュテーブルに登録    */
  223. static    void    HashAppend( ver, vx, vy, vz )
  224. Vertex    *ver ;
  225. int        vx, vy, vz ;
  226. {
  227.     int        i, n ;
  228.  
  229.     i = 0 ;
  230.     n = HashFunc( ver ) & HashBit ;
  231.     while( HashEqual( ver, &HashTable[n] ) == FALSE )
  232.     {
  233.         n = ( n + 997 ) & HashBit ;
  234.         i++ ;
  235.         assert( i < HashSize );
  236.     }
  237.     if ( HashTable[n].flag )
  238.     {
  239.         if ( HashTable[n].vx * vx + HashTable[n].vy * vy + HashTable[n].vz * vz >= 0 )
  240.         {
  241.             HashTable[n].vx += (short)vx ;
  242.             HashTable[n].vy += (short)vy ;
  243.             HashTable[n].vz += (short)vz ;
  244.         }
  245.         else
  246.         {
  247.             HashTable[n].vx += - (short)vx ;
  248.             HashTable[n].vy += - (short)vy ;
  249.             HashTable[n].vz += - (short)vz ;
  250.         }
  251.     }
  252.     else
  253.     {
  254.         HashTable[n].flag = TRUE ;
  255.         HashTable[n].x = ver->x ;
  256.         HashTable[n].y = ver->y ;
  257.         HashTable[n].z = ver->z ;
  258.         HashTable[n].vx = (short)vx ;
  259.         HashTable[n].vy = (short)vy ;
  260.         HashTable[n].vz = (short)vz ;
  261.     }
  262. }
  263.  
  264. /*    ハッシュ関数    */
  265. static    int        HashFunc( ver )
  266. Vertex    *ver ;
  267. {
  268.     return ( ver->x % 181 ) + ( ver->y % 479 ) * 97 + ( ver->z % 571 ) * 997 ;
  269. }
  270.  
  271. /*    ハッシュテーブルのヒットのチェック    */
  272. static    int        HashEqual( ver, table )
  273. Vertex    *ver ;
  274. HashStruct    *table ;
  275. {
  276.     if ( table->flag == FALSE )
  277.         return TRUE ;
  278.     else if ( ver->x == table->x && ver->y == table->y && ver->z == table->z )
  279.         return TRUE ;
  280.     else
  281.         return FALSE ;
  282. }
  283.  
  284. /*    ハッシュテーブルから読み出す    */
  285. static    HashStruct    *HashRead( ver )
  286. Vertex    *ver ;
  287. {
  288.     int        n ;
  289.  
  290.     n = HashFunc( ver ) & HashBit ;
  291.     while( HashEqual( ver, &HashTable[n] ) == FALSE )
  292.     {
  293.         assert( HashTable[n].flag == TRUE );
  294.         n = ( n + 997 ) & HashBit ;
  295.     }
  296.     return &HashTable[n] ;
  297. }
  298.  
  299. void    Coefficent( coe, vers, n )
  300. int        coe[3] ;
  301. Vertex    *vers ;
  302. int        n ;
  303. {
  304.     int        i ;
  305.     float    a, b, c, r ;
  306.     const Vertex    *p1, *p2 ;
  307.  
  308.     /*    係数の計算(規格化する)    */
  309.     p1 = vers ;
  310.     p2 = vers + 1 ;
  311.     a = b = c = 0.0 ;
  312.     for( i = 0 ; i < n-1 ; ++i )
  313.     {
  314.         a += (float)( ( p1->y - p2->y ) * ( p1->z + p2->z ) );
  315.         b += (float)( ( p1->z - p2->z ) * ( p1->x + p2->x ) );
  316.         c += (float)( ( p1->x - p2->x ) * ( p1->y + p2->y ) );
  317.         p1 ++ ;
  318.         p2 ++ ;
  319.     }
  320.     p2 = vers ;
  321.     a += (float)( ( p1->y - p2->y ) * ( p1->z + p2->z ) );
  322.     b += (float)( ( p1->z - p2->z ) * ( p1->x + p2->x ) );
  323.     c += (float)( ( p1->x - p2->x ) * ( p1->y + p2->y ) );
  324.  
  325.     r = (float)sqrt(a*a+b*b+c*c);
  326.     if (r > 0.0) r = (float)256.0/r;
  327. /*
  328.     r = (float)256.0 / sqrt( a * a + b * b + c * c );
  329. */
  330.     coe[0] = (int)( a * r );
  331.     coe[1] = (int)( b * r );
  332.     coe[2] = (int)( c * r );
  333. }
  334.  
  335. /*    セレクトされているポリゴンの法線ベクトルを反転する    */
  336. void    PolyShadeInv()
  337. {
  338.     int        i ;
  339.     Polygon    *poly ;
  340.     Vertex    *ver ;
  341.  
  342.     poly = PolyTop();
  343.     while( poly != NULL )
  344.     {
  345.         if ( poly->select && ( poly->type & POLY_SHADE ) )
  346.         {
  347.             ver = poly->ver ;
  348.             for( i = 0 ; i < poly->vers ; i++ )
  349.             {
  350.                 ver->vx = - ver->vx ;
  351.                 ver->vy = - ver->vy ;
  352.                 ver->vz = - ver->vz ;
  353.                 ver++ ;
  354.             }
  355.             ObjData[poly->obj].edit = TRUE ;
  356.         }
  357.         poly = PolyNext( poly );
  358.     }
  359. }
  360.