home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 March / VPR9703A.ISO / VPR_DATA / DOGA / SOURCES / REND.LZH / READER / OBJREAD.C < prev    next >
C/C++ Source or Header  |  1996-07-09  |  11KB  |  527 lines

  1. /*
  2.         形状ファイル入力関数
  3.  
  4.         Copyright T.Kobayashi
  5. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <math.h>
  9. #include <string.h>
  10. #include <assert.h>
  11.  
  12. #include "reader.h"
  13. #include "word.h"
  14.  
  15. #define POINT_UNIT        4
  16. #define ATR_UNIT        10
  17.  
  18. #define OLD_FASION        1
  19. #define PRIVATE_OP        2
  20.  
  21. #define ALREADY_EXIST    11
  22. #define NOT_FOUND        12
  23. #define BAD_EXIST        13
  24. #define NOT_SUF_MODEL    14
  25. #define NOT_IMPLIMENTED 15
  26. #define ATR_NOT_FOUND    16
  27. #define OBJ_NOT_FOUND    17
  28. #define LESS_POINT        18
  29. #define ATR_NO_EXIST    19
  30.  
  31. #define UNEXPECTED_EOF    21
  32. #define NOT_OBJ_FILE    22
  33.  
  34. static    AtrName    *atrname ;
  35. static    int        atrnum ;
  36. static    Pointer(Object*)    top ;
  37. static    int        matflag ;
  38.  
  39. /*
  40.     proto -s objread.c > temp
  41. */
  42. static    void    get_obj_data( Object*, int, Matrix );
  43. static    void    get_prim_data( Poly*, Matrix );
  44. static    void    coefficent( Float[4], Point*, int );
  45. static    Pointer(Object*)    search_obj( char* );
  46. static    int        search_atr( char* );
  47. static    void    objerror( int, char* );
  48.  
  49.  
  50. Pointer(Object*)    objread( filename, objlist )
  51. char    *filename ;
  52. Pointer(Object*)    objlist ;
  53. {
  54.     Pointer(Poly*)    pp ;
  55.     Object    obj, *objp ;
  56.     Point    *point ;
  57.     Poly    *poly ;
  58.     Matrix    c_mat ;
  59.     int        i, j, k, n ;
  60.     Pointer(AtrName*) cp ;
  61.  
  62.     /*    エラー処理の初期化    */
  63.     errlevel = 1 ;
  64.  
  65.     /*    ファイルのオープン    */
  66.     fileopen( filename );
  67.     if ( wordid != WORD_OBJ )
  68.         objerror( NOT_OBJ_FILE, "" );
  69.  
  70.     top = objlist ;
  71. #if 1
  72.     if (objlist != NULL) {
  73.         while (objlist->next != NULL) {
  74.             objlist = objlist->next;
  75.         }
  76.     }
  77. #endif
  78.  
  79.     while( ! end_of_file )
  80.     {
  81.         /*    obj の検出    */
  82.         if ( wordid != WORD_OBJ )
  83.         {
  84.             objerror( NOT_FOUND, "obj" ) ;
  85.             skip( "obj" );
  86.             if ( end_of_file )
  87.                 break ;
  88.         }
  89.         get() ;
  90.  
  91.         /*    private の検出(警告)    */
  92.         if ( wordid == WORD_PRIVATE )
  93.         {
  94.             objerror( PRIVATE_OP, "" );
  95.             get() ;
  96.         }
  97.  
  98.         /*    suf の検出    */
  99.         if ( wordid != WORD_SUF )
  100.             objerror( NOT_SUF_MODEL, "" ) ;
  101.         else
  102.             get() ;
  103.  
  104.         /*    オブジェクト名のリード    */
  105.         getname( obj.name );
  106.  
  107.         for( objp = pointer(top) ; objp != NULL ; objp = pointer(objp->next) )
  108.         {
  109.             if ( strcmpi( objp->name, obj.name ) == 0 )
  110.                 objerror( ALREADY_EXIST, obj.name );
  111.         }
  112.  
  113.         if ( wordid != WORD_OPEN2 )
  114.             objerror( NOT_FOUND, "{" );
  115.         else
  116.             get() ;
  117.  
  118.         /*    オブジェクト本体のリード    */
  119.         m_unit( c_mat ) ;
  120.         matflag = FALSE ;
  121.         atrnum = 0 ;
  122.         obj.polynum = 0 ;
  123.         obj.poly = NULL ;
  124.         obj.objpos = NULL ;
  125.         get_obj_data( &obj, 0, c_mat );
  126.  
  127.         /*    アトリビュート名配列の設定    */
  128.         obj.atrnum = atrnum ;
  129.         obj.atrname = dataalloc( sizeof( AtrName ) * atrnum );
  130.         cp = pointer( obj.atrname );
  131.         memcpy( cp, atrname, sizeof( AtrName ) * atrnum );
  132.         tempfree( atrname );
  133.  
  134.         /*    各座標の最大値、最小値の計算    */
  135.         pp = obj.poly ;
  136.         poly = pointer( pp );
  137.         point = (Point*)pointer( poly->point );
  138.         v_copy( obj.max, point[0] );
  139.         v_copy( obj.min, point[0] );
  140.         for( i = 0 ; i < obj.polynum ; ++i )
  141.         {
  142.             poly = pointer( pp );
  143.             pp = poly->next ;
  144.             n = poly->pointnum ;
  145.             point = (Point*)pointer( poly->point );
  146.             for( j = 0 ; j < n ; ++j )
  147.             {
  148.                 for( k = 0 ; k < 3 ; ++k )
  149.                 {
  150.                     if ( point[j][k] > obj.max[k] )
  151.                         obj.max[k] = point[j][k];
  152.                     if ( point[j][k] < obj.min[k] )
  153.                         obj.min[k] = point[j][k];
  154.                 }
  155.             }
  156.         }
  157.  
  158.         /*    リストの結合    */
  159. #if 0
  160.         obj.next = top ;
  161.         po = dataalloc( sizeof( Object ) );
  162.         memcpy( pointer( po ), &obj, sizeof( Object ) );
  163.         top = po ;
  164. #else
  165.         obj.next = NULL;
  166.         objp = dataalloc( sizeof( Object ) );
  167.         memcpy( pointer( objp ), &obj, sizeof( Object ) );
  168.         if (objlist == NULL) {
  169.             objlist = top = objp;
  170.         } else {
  171.             objlist->next = objp;
  172.             objlist = objlist->next;
  173.         }
  174. #endif
  175.     }
  176.  
  177.     fileclose() ;
  178.     if ( errlevel < 10 )
  179.         return( top ) ;
  180.     return( NULL ) ;
  181. }
  182.  
  183. static    void    get_obj_data( obj, atrid, mat )
  184. Object    *obj ;
  185. int        atrid ;
  186. Matrix    mat ;
  187. {
  188.     Matrix    c_mat, m ;
  189.     char    name[MAXWORD] ;
  190.     Pointer(Poly*)    pp ;
  191.     Pointer(ObjPos*) pop;
  192.     Poly    *poly ;
  193.     ObjPos    *objpos ;
  194.     int        lockid ;
  195.  
  196.     m_copy( c_mat, mat ) ;
  197.  
  198.     while( wordid != WORD_CLOSE2 )
  199.     {
  200.         switch( wordid )
  201.         {
  202.             case WORD_ATR :
  203.                 get() ;
  204.                 getname( name );
  205. #if 0
  206.                 if ( strcmpi( name, "no" ) == 0 )
  207.                     objerror( ATR_NO_EXIST, "" );
  208. #endif
  209.                 atrid = search_atr( name );
  210.                 break ;
  211.             case WORD_PRIM :
  212.                 get() ;
  213.                 ++ obj->polynum ;
  214.                 pp = dataalloc( sizeof( Poly ) );
  215.                 poly = pointer( pp );
  216.                 lockid = datalock();
  217.                 poly->atr = NULL ;
  218.                 poly->atrid = atrid ;
  219.                 poly->next = obj->poly ;
  220.                 get_prim_data( poly, c_mat );
  221.                 dataunlock( lockid );
  222.                 obj->poly = pp ;
  223.                 break ;
  224.             case WORD_PARTS :
  225.                 get() ;
  226.                 getname( name );
  227.                 pop = dataalloc( sizeof( ObjPos ) );
  228.                 objpos = pointer( pop );
  229.                 lockid = datalock();
  230.                 objpos->obj = search_obj( name );
  231.                 m_copy( objpos->mat, c_mat );
  232.                 objpos->next = obj->objpos ;
  233.                 dataunlock( lockid );
  234.                 obj->objpos = pop ;
  235.                 break ;
  236.             case WORD_OPEN2 :
  237.                 get() ;
  238.                 get_obj_data( obj, atrid, c_mat ) ;
  239.                 break ;
  240.             default :
  241.                 getmat( m );
  242.                 m_mult( c_mat, m, c_mat ) ;
  243.                 matflag = TRUE ;
  244.                 break ;
  245.         }
  246.     }
  247.     get() ;
  248. }
  249.  
  250. #ifdef V70
  251.     static    int        bufsize = 0 ;
  252.     static    Point    *point, *vec, *uv ;
  253. #endif
  254. static    void    get_prim_data( poly, c_mat )
  255. Poly    *poly ;
  256. Matrix    c_mat ;
  257. {
  258.     int        n, i ;
  259.     Point    *pp ;
  260. #ifndef V70
  261.     static    int        bufsize = 0 ;
  262.     static    Point    *point, *vec, *uv ;
  263. #endif
  264.     if ( bufsize == 0 )
  265.     {
  266.         bufsize = POINT_UNIT ;
  267.         point = (Point*)tempalloc( sizeof( Point ) * bufsize );
  268.         vec = (Vector*)tempalloc( sizeof( Vector ) * bufsize );
  269.         uv = (Point*)tempalloc( sizeof( Point ) * bufsize );
  270.     }
  271.  
  272.     switch( wordid )
  273.     {
  274.         case WORD_POLY :
  275.             poly->type = POLY ;
  276.             break ;
  277.         case WORD_SHADE :
  278.             poly->type = SHADE ;
  279.             break ;
  280.         case WORD_UVPOLY :
  281.             poly->type = UVPOLY ;
  282.             break ;
  283.         case WORD_UVSHADE :
  284.             poly->type = UVSHADE ;
  285.             break ;
  286.         default :
  287.             objerror( BAD_EXIST, nextword ) ;
  288.     }
  289.     get() ;
  290.  
  291.     if ( wordid != WORD_OPEN1 )
  292.         objerror( NOT_FOUND, "(" ) ;
  293.     get() ;
  294.  
  295.     /*    頂点数のカウントとテンポラリへの保存  */
  296.     for( n = 0 ; ; ++n )
  297.     {
  298.         if ( end_of_file )
  299.             objerror( UNEXPECTED_EOF, "" );
  300.  
  301.         if ( wordid == WORD_CLOSE1 )
  302.             break ;
  303.  
  304.         /*    サイズの確認    */
  305.         if ( n == bufsize )
  306.         {
  307.             bufsize += POINT_UNIT ;
  308.             point = (Point*)temprealloc( point, sizeof( Point ) * bufsize );                vec = (Vector*)temprealloc( vec, sizeof( Vector ) * bufsize );
  309.             uv = (Point*)temprealloc( uv, sizeof( Point ) * bufsize );
  310.         }
  311.  
  312.         assert( n < bufsize );
  313.  
  314.         /*    データリード    */
  315.         getvector( point[n] ) ;            /*    頂点座標  */
  316.         if ( poly->type & SHADE )
  317.             getvector( vec[n] ) ;        /*    法線ベクトル  */
  318.         if ( poly->type & UVPOLY )
  319.         {
  320.             uv[n][0] = getFloat() ;    /*    UV座標  */
  321.             uv[n][1] = getFloat() ;
  322.         }
  323.     }
  324.     /*    エラーチェック    */
  325.     if ( n <= 2 )
  326.     {
  327.         objerror( LESS_POINT, "" );
  328.         return ;
  329.     }
  330.     poly->pointnum = n ;
  331.     get() ;
  332.  
  333.     /*    データバッファの確保    */
  334.     poly->point = dataalloc( sizeof( Point ) * n );
  335.     if ( poly->type & SHADE )
  336.         poly->vec = dataalloc( sizeof( Vector ) * n );
  337.     if ( poly->type & UVPOLY )
  338.         poly->uv = dataalloc( sizeof( Vector ) * n );
  339.  
  340.     /*    頂点データのコピー    */
  341.     pp = (Point*)pointer( poly->point );
  342.     for( i = 0 ; i < n ; ++i )
  343.         v_copy( pp[i],  point[i] ) ;
  344.  
  345.     if ( poly->type & SHADE )
  346.     {
  347.         pp = (Vector*)pointer( poly->vec );
  348.         for( i = 0 ; i < n ; ++i )
  349.             v_copy( pp[i], vec[i] ) ;
  350.     }
  351.  
  352.     if ( poly->type & UVPOLY )
  353.     {
  354.         pp = (Point*)pointer( poly->uv );
  355.         for( i = 0 ; i < n ; ++i )
  356.         {
  357.             pp[i][0] = uv[i][0] ;
  358.             pp[i][1] = uv[i][1] ;
  359.         }
  360.     }
  361.  
  362.     /*    座標変換    */
  363.     if ( matflag )
  364.     {
  365.         pp = (Point*)pointer( poly->point );
  366.         vec_mult_mat( pp, pp, c_mat, n, 1 );
  367.         if ( poly->type & SHADE )
  368.         {
  369.             pp = (Vector*)pointer( poly->vec );
  370.             vec_mult_mat( pp, pp, c_mat, n, 0 );
  371.         }
  372.     }
  373.  
  374.     /*    係数の計算    */
  375.     pp = (Point*)pointer( poly->point );
  376.     coefficent( poly->coe, pp, n );
  377. }
  378.  
  379. /*    係数の計算(規格化する)    */
  380. static    void    coefficent( coe, point, n )
  381. Float    coe[4] ;
  382. Point    *point ;
  383. int n ;
  384. {
  385.     int i ;
  386.     Point    *p1, *p2 ;
  387.  
  388.     p1 = point ;
  389.     p2 = point + 1 ;
  390.     coe[0] = coe[1] = coe[2] = 0.0 ;
  391.     for( i = 0 ; i < n-1 ; ++i )
  392.     {
  393.         coe[0] += ( p1[0][1] - p2[0][1] ) * ( p1[0][2] + p2[0][2] ) ;
  394.         coe[1] += ( p1[0][2] - p2[0][2] ) * ( p1[0][0] + p2[0][0] ) ;
  395.         coe[2] += ( p1[0][0] - p2[0][0] ) * ( p1[0][1] + p2[0][1] ) ;
  396.         ++p1 ;
  397.         ++p2 ;
  398.     }
  399.     p2 = point ;
  400.     coe[0] += ( p1[0][1] - p2[0][1] ) * ( p1[0][2] + p2[0][2] ) ;
  401.     coe[1] += ( p1[0][2] - p2[0][2] ) * ( p1[0][0] + p2[0][0] ) ;
  402.     coe[2] += ( p1[0][0] - p2[0][0] ) * ( p1[0][1] + p2[0][1] ) ;
  403.  
  404.     v_unit( coe, coe );
  405.  
  406.     coe[3] = 0.0 ;
  407.     for( i = 0 ; i < 3 ; ++i )
  408.         coe[3] -= coe[i] * point[0][i] ;
  409. }
  410.  
  411. static    Pointer(Object*)    search_obj( name )
  412. char    *name ;
  413. {
  414.     Pointer(Object*)    p ;
  415.     Object    *obj ;
  416.  
  417.     for( p = top ; p != NULL ; p = obj->next )
  418.     {
  419.         obj = pointer( p );
  420.         if ( strcmpi( obj->name, name ) == 0 )
  421.             break ;
  422.     }
  423.     if ( p == NULL )
  424.         objerror( OBJ_NOT_FOUND, name );
  425.  
  426.     return( p );
  427. }
  428.  
  429. /*    アトリビュート名の検索    */
  430. static    int        search_atr( name )
  431. char    *name ;
  432. {
  433.     int        i ;
  434.     AtrName *an ;
  435.  
  436.     for( i = 0 ; i < atrnum ; ++i )
  437.     {
  438.         if ( strcmpi( atrname[i], name )     == 0 )
  439.             break ;
  440.     }
  441.     if ( i == atrnum )
  442.     {
  443.         if ( atrnum % ATR_UNIT == 0 )
  444.         {
  445.             an = atrname ;
  446.             atrname =
  447.                 (AtrName*)tempalloc( sizeof( AtrName ) * (atrnum+ATR_UNIT) );
  448.             if ( atrnum > 0 )
  449.             {
  450.                 memcpy( atrname, an, sizeof( AtrName )*atrnum );
  451.                 tempfree( an );
  452.             }
  453.         }
  454.         strcpy( atrname[ atrnum++ ], name );
  455.     }
  456.     return( i );
  457. }
  458.  
  459. static    void    objerror( n, arg )
  460. int        n ;
  461. char    *arg ;
  462. {
  463.     char    *msg ;
  464.     int        level ;
  465.  
  466.     switch( n )
  467.     {
  468.         case OLD_FASION :
  469.             msg = "警告:古い規格の書式です。:%s" ;
  470.             level = 1 ;
  471.             break ;
  472.         case PRIVATE_OP :
  473.             msg = "警告:private 処理はサポートしていません。" ;
  474.             level = 3 ;
  475.             break ;
  476.         case ALREADY_EXIST :
  477.             msg = "オブジェクト名 %s が二度宣言されています。" ;
  478.             level = 10 ;
  479.             break ;
  480.         case NOT_FOUND :
  481.             msg = " %s がありません。" ;
  482.             level = 10 ;
  483.             break ;
  484.         case BAD_EXIST :
  485.             msg = " %s が存在します。" ;
  486.             level = 10 ;
  487.             break ;
  488.         case NOT_SUF_MODEL :
  489.             msg = "サーフィスモデルではありません。" ;
  490.             level = 10 ;
  491.             break ;
  492.         case NOT_IMPLIMENTED :
  493.             msg = " %s はサポートしていません。" ;
  494.             level = 10 ;
  495.             break ;
  496.         case ATR_NOT_FOUND :
  497.             msg = "アトリビュート名 %s は登録されていません。" ;
  498.             level = 10 ;
  499.             break ;
  500.         case OBJ_NOT_FOUND :
  501.             msg = "オブジェクト名 %s は登録されていません。" ;
  502.             level = 10 ;
  503.             break ;
  504.         case LESS_POINT :
  505.             msg = "多角形の頂点が2つ以下しかありません。" ;
  506.             level = 10 ;
  507.             break ;
  508.         case ATR_NO_EXIST :
  509.             msg = "atr no があります。" ;
  510.             level = 10 ;
  511.             break ;
  512.         case UNEXPECTED_EOF :
  513.             msg = "エンドオブファイルになりました" ;
  514.             level = 20 ;
  515.             break ;
  516.         case NOT_OBJ_FILE :
  517.             msg = "形状ファイルではありません。" ;
  518.             level = 20 ;
  519.             break ;
  520.         default :
  521.             msg = "エラーコードの誤り。( objread.c )" ;
  522.             level = 20 ;
  523.             break ;
  524.     }
  525.     errormessage( level, msg, arg );
  526. }
  527.