home *** CD-ROM | disk | FTP | other *** search
/ Cutting-Edge 3D Game Programming with C++ / CE3DC++.ISO / BOOK / CHAP14 / POLYOBJ.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-14  |  24.9 KB  |  857 lines

  1. //
  2. //
  3. // File name: PolyObj.CPP
  4. //
  5. // Description: The support file for the PolyObj.HPP header
  6. //
  7. // Author: John De Goes
  8. //
  9. // Project: Cutting Edge 3D Game Programming
  10. //
  11.  
  12. #include <Math.H>
  13. #include <CType.H>
  14. #include <Stdio.H>
  15. #include <String.H>
  16.  
  17. // Temp include:
  18. #include <ConIO.H>
  19. #include <IOStream.H>
  20.  
  21. #include "PolyObj.HPP"
  22. #include "Matrix3D.HPP"
  23. #include "Point3D.HPP"
  24. #include "LightP.HPP"
  25. #include "TextType.HPP"
  26. #include "PalShade.HPP"
  27.  
  28. extern float GlobalStep;
  29.  
  30. // Logical replacement for "strcmp" - returns true
  31. // if strings match:
  32. int inline Match ( char *S1, char *S2 )
  33.   {
  34.   return !strcmp ( S1, S2 );
  35.   }
  36.  
  37.  
  38. int GetLine ( FILE *InFile, char *String )
  39.    {
  40.    // Reads a line of text from a text file:
  41.    int NextByte = fgetc ( InFile );
  42.    int Index = 0;
  43.    
  44.    // Loop until we reach a new-line character:
  45.    while ( NextByte != '\n' )
  46.          {
  47.          // Check for end of file:
  48.          if ( NextByte == EOF )
  49.             {
  50.             // If found, close off string
  51.             // and return EOF:
  52.             String [ Index ] = '\0';
  53.             return EOF;
  54.             }
  55.  
  56.          // If the next byte is not a space....
  57.          if ( !isspace ( NextByte ) )
  58.             {
  59.             // ....record it:
  60.             String [ Index++ ] = ( char ) NextByte;
  61.             }
  62.             
  63.          // Get the next character:
  64.          NextByte = fgetc ( InFile );
  65.          }
  66.    // Close off the string and return success (true):
  67.    String [ Index ] = '\0';//*/
  68.    return 1;
  69.    }
  70.    
  71. void PanelObject::CalcRadius ()
  72.    {
  73.    // Calculates the radius of the object:
  74.    }
  75.    
  76. void PanelObject::Transform ( Matrix3D &M )
  77.    {
  78.    // Translates/rotates/morphs entire vertex list:
  79.    unsigned int Count;
  80.  
  81.    // Transform the vertex list:
  82.    if ( ( Morph ) && ( StartMorph ) )
  83.       {
  84.       for ( Count = 0; Count < VCount; Count++ )
  85.           {
  86.           M.Transform ( VList [ Count ] );
  87.           // Perform the morph:
  88.           VList [ Count ] += MList [ Count ];
  89.           }
  90.       }
  91.  
  92.    else {
  93.         for ( Count = 0; Count < VCount; Count++ )
  94.             {
  95.             M.Transform ( VList [ Count ] );
  96.             }
  97.         }
  98.  
  99.    // Update the normal and other panel-specific data:
  100.    for ( Count = 0; Count < PCount; Count++ )
  101.        {
  102.        PList [ Count ].Update ( M );
  103.        }
  104.    }
  105.  
  106. void PanelObject::Display ( Matrix3D &M, unsigned char *Buffer )
  107.    {
  108.    // Displays a world on screen buffer "Buffer"
  109.    const False = 0;
  110.    // Declare variables:
  111.    unsigned int Count;
  112.  
  113.    // Transform the vertex points:
  114.    Transform ( M );
  115.  
  116.    // Display selected panels in the off-screen buffer:
  117.    for ( Count = 0; Count < PCount; Count++ )
  118.        {
  119.        // Determine if polygon is invisible:
  120.        if ( PList [ Count ].Invisible () == False )
  121.           {
  122.           // If the panel is visible in 3D....
  123.           if ( PList [ Count ].IsVisible3D () )
  124.              {
  125.              // ....project it:
  126.              PList [ Count ].Project ();
  127.  
  128.              // If panel is visible in 2D....
  129.              if ( PList [ Count ].IsVisible2D () )
  130.                 {
  131.                 // ....display it:
  132.                 PList [ Count ].Display ( Buffer );
  133.                 }
  134.  
  135.              }
  136.           }
  137.        }
  138.    } 
  139.  
  140.  
  141. void PanelObject::MoveText ( int Ox, int Oy, int Tx, int Ty )
  142.    {
  143.    float Dist [ 5 ], X, Y;
  144.    long Count, ScreenCount, MinDist;
  145.    // Make sure selection is in allowed range:
  146.    if ( ( Select >= 0 ) && ( Select < PCount ) )
  147.       {
  148.       PList [ Select ].Project ();
  149.       ScreenCount = PList [ Select ].SPCount;
  150.       if ( ScreenCount > 4 )
  151.          ScreenCount = 4;
  152.       // Calculate the distance from each vertex to (Ox, Oy):
  153.       for ( Count = 0; Count < ScreenCount; Count++ )
  154.           {
  155.           X = PList [ Select ].SPoint [ Count ].X;
  156.           Y = PList [ Select ].SPoint [ Count ].Y;
  157.           Dist [ Count ] = sqrt ( ( X - Ox ) * ( X - Ox ) +
  158.                                   ( Y - Oy ) * ( Y - Oy ) );
  159.           }
  160.       // Select minimum distance:
  161.       MinDist = 0;
  162.       for ( Count = 1; Count < ScreenCount; Count++ )
  163.           {
  164.           if ( Dist [ Count ] < Dist [ MinDist ] )
  165.              MinDist = Count;
  166.           }
  167.       // Translate texture vertex by specified amount:
  168.       PList [ Select ].Attrib [ MinDist ].U += Tx;
  169.       PList [ Select ].Attrib [ MinDist ].V += Ty;
  170.       // Clip selected translation:
  171.       if ( PList [ Select ].Attrib [ MinDist ].U < 0 )
  172.          PList [ Select ].Attrib [ MinDist ].U = 0;
  173.  
  174.       if ( PList [ Select ].Attrib [ MinDist ].V < 0 )
  175.          PList [ Select ].Attrib [ MinDist ].V = 0;
  176.  
  177.       if ( PList [ Select ].Attrib [ MinDist ].U >=
  178.            TextDat.TMap [ PList [ Select ].TextHan ].Width )
  179.          {
  180.          PList [ Select ].Attrib [ MinDist ].U = 
  181.              ( TextDat.TMap [ PList [ Select ].TextHan ].Width 
  182.                - 1 );
  183.          }
  184.  
  185.       if ( PList [ Select ].Attrib [ MinDist ].V >=
  186.            TextDat.TMap [ PList [ Select ].TextHan ].Height )
  187.          {
  188.          PList [ Select ].Attrib [ MinDist ].V = 
  189.              ( TextDat.TMap [ PList [ Select ].TextHan ].Height 
  190.                - 1 );
  191.          }
  192.       }
  193.    }
  194.  
  195. void PanelObject::NextInten ( int Sx, int Sy )
  196.    {
  197.    float Dist [ 5 ], X, Y;
  198.    long Count, ScreenCount, MinDist;
  199.    // Make sure selection is in allowed range:
  200.    if ( ( Select >= 0 ) && ( Select < PCount ) )
  201.       {
  202.       PList [ Select ].Project ();
  203.       ScreenCount = PList [ Select ].SPCount;
  204.       if ( ScreenCount > 4 )
  205.          ScreenCount = 4;
  206.       // Calculate the distance from each vertex to (Sx, Sy):
  207.       for ( Count = 0; Count < ScreenCount; Count++ )
  208.           {
  209.           X = PList [ Select ].SPoint [ Count ].X;
  210.           Y = PList [ Select ].SPoint [ Count ].Y;
  211.           Dist [ Count ] = sqrt ( ( X - Sx ) * ( X - Sx ) +
  212.                                   ( Y - Sy ) * ( Y - Sy ) );
  213.           }
  214.       // Select minimum distance:
  215.       MinDist = 0;
  216.       for ( Count = 1; Count < ScreenCount; Count++ )
  217.           {
  218.           if ( Dist [ Count ] < Dist [ MinDist ] )
  219.              MinDist = Count;
  220.           }
  221.       // Select next intensity:
  222.       ++PList [ Select ].Attrib [ MinDist ].I;
  223.       if ( PList [ Select ].Attrib [ MinDist ].I > ( SHADE_COUNT - 1 ) )
  224.          PList [ Select ].Attrib [ MinDist ].I = 0;
  225.       }
  226.    }
  227.  
  228. void PanelObject::InitDefText ()
  229.    {
  230.    float IPer;
  231.    long Count, Odd, Tri;
  232.    cout << "\nInitializing texture-shade data:\n";
  233.    for ( Count = 0; Count < PCount; Count++ )
  234.        {
  235.        IPer = ( ( float ) Count / ( float ) PCount ) * 101.0F;
  236.        cout << ( long ) IPer << "%\r";
  237.        Odd = Count % 2;
  238.        PList [ Count ].TextHan = 0;
  239.        Tri = 0;
  240.        if ( ( *PList [ Count ].VPoint [ 0 ] ) == 
  241.             ( *PList [ Count ].VPoint [ 1 ] ) )
  242.           Tri = 1;
  243.        else if ( ( *PList [ Count ].VPoint [ 0 ] ) == 
  244.                  ( *PList [ Count ].VPoint [ 2 ] ) )
  245.                Tri = 1;
  246.        else if ( ( *PList [ Count ].VPoint [ 0 ] ) == 
  247.                  ( *PList [ Count ].VPoint [ 3 ] ) )
  248.                Tri = 1;
  249.  
  250.        else if ( ( *PList [ Count ].VPoint [ 1 ] ) == 
  251.                  ( *PList [ Count ].VPoint [ 2 ] ) )
  252.                Tri = 1;
  253.        else if ( ( *PList [ Count ].VPoint [ 1 ] ) == 
  254.                  ( *PList [ Count ].VPoint [ 3 ] ) )
  255.                Tri = 1;
  256.  
  257.        else if ( ( *PList [ Count ].VPoint [ 2 ] ) == 
  258.                  ( *PList [ Count ].VPoint [ 3 ] ) )
  259.                Tri = 1;
  260.  
  261.        if ( Tri )
  262.           {
  263.           if ( !Odd )
  264.              {
  265.              PList [ Count ].Attrib [ 3 ].U = 0;
  266.              PList [ Count ].Attrib [ 3 ].V = 0;
  267.              PList [ Count ].Attrib [ 3 ].I = PList [ Count ].Color;
  268.  
  269.              PList [ Count ].Attrib [ 2 ].U = TextDat.TMap [ 0 ].Width - 1;
  270.              PList [ Count ].Attrib [ 2 ].V = 0;
  271.              PList [ Count ].Attrib [ 2 ].I = PList [ Count ].Color;
  272.  
  273.              PList [ Count ].Attrib [ 1 ].U = TextDat.TMap [ 0 ].Width - 1;
  274.              PList [ Count ].Attrib [ 1 ].V = TextDat.TMap [ 0 ].Height - 1;
  275.              PList [ Count ].Attrib [ 1 ].I = PList [ Count ].Color;
  276.  
  277.              PList [ Count ].Attrib [ 0 ].U = TextDat.TMap [ 0 ].Width - 1;
  278.              PList [ Count ].Attrib [ 0 ].V = TextDat.TMap [ 0 ].Height - 1;
  279.              PList [ Count ].Attrib [ 0 ].I = PList [ Count ].Color;
  280.              }
  281.           if ( Odd )
  282.              {
  283.              PList [ Count ].Attrib [ 3 ].U = 0;
  284.              PList [ Count ].Attrib [ 3 ].V = 0;
  285.              PList [ Count ].Attrib [ 3 ].I = PList [ Count ].Color;
  286.  
  287.              PList [ Count ].Attrib [ 2 ].U = TextDat.TMap [ 0 ].Width - 1;
  288.              PList [ Count ].Attrib [ 2 ].V = TextDat.TMap [ 0 ].Height - 1;
  289.              PList [ Count ].Attrib [ 2 ].I = PList [ Count ].Color;
  290.  
  291.              PList [ Count ].Attrib [ 1 ].U = 0;
  292.              PList [ Count ].Attrib [ 1 ].V = TextDat.TMap [ 0 ].Height - 1;
  293.              PList [ Count ].Attrib [ 1 ].I = PList [ Count ].Color;
  294.  
  295.              PList [ Count ].Attrib [ 0 ].U = 0;
  296.              PList [ Count ].Attrib [ 0 ].V = TextDat.TMap [ 0 ].Height - 1;
  297.              PList [ Count ].Attrib [ 0 ].I = PList [ Count ].Color;
  298.              }
  299.            }
  300.        else {
  301.             PList [ Count ].Attrib [ 0 ].U = 0;
  302.             PList [ Count ].Attrib [ 0 ].V = 0;
  303.             PList [ Count ].Attrib [ 0 ].I = PList [ Count ].Color;
  304.  
  305.             PList [ Count ].Attrib [ 1 ].U = TextDat.TMap [ 0 ].Width - 1;
  306.             PList [ Count ].Attrib [ 1 ].V = 0;
  307.             PList [ Count ].Attrib [ 1 ].I = PList [ Count ].Color;
  308.  
  309.             PList [ Count ].Attrib [ 2 ].U = TextDat.TMap [ 0 ].Width - 1;
  310.             PList [ Count ].Attrib [ 2 ].V = TextDat.TMap [ 0 ].Height - 1;
  311.             PList [ Count ].Attrib [ 2 ].I = PList [ Count ].Color;
  312.  
  313.             PList [ Count ].Attrib [ 3 ].U = 0;
  314.             PList [ Count ].Attrib [ 3 ].V = TextDat.TMap [ 0 ].Height - 1;
  315.             PList [ Count ].Attrib [ 3 ].I = PList [ Count ].Color;
  316.             }
  317.        }
  318.    }
  319.  
  320. int PanelObject::MorphTo ( char *FileName, float Steps )
  321.   {
  322.   // Note: FileName must be a BIN file
  323.   // Load an object from a BIN binary file:
  324.    unsigned int VertCount, PanelCount, Count;
  325.    Point3D TVert;
  326.    FILE *InFile;
  327.  
  328.    StartMorph = 1;
  329.  
  330.    if ( ( InFile = fopen ( FileName, "rb" ) ) == NULL )
  331.       return 0;
  332.    fread ( &VertCount, sizeof VertCount, 1, InFile );
  333.    fread ( &PanelCount, sizeof PanelCount, 1, InFile );
  334.  
  335.    if ( VertCount != VCount )
  336.       {
  337.       fclose ( InFile );
  338.       return 0;
  339.       }
  340.  
  341.    // Allocate memory:
  342.    TList = new Point3D [ VertCount ];
  343.  
  344.    if ( !Morph )
  345.       {
  346.       Morph = 1;
  347.       MList = new Point3D [ VertCount ];
  348.       }
  349.  
  350.    // Load vertices:
  351.    for ( Count = 0; Count < VertCount; Count++ )
  352.        {
  353.        TList [ Count ].Read ( InFile );
  354.        }
  355.  
  356.   // Generate morphing data to morph VList to TList:
  357.   for ( Count = 0; Count < VertCount; Count++ )
  358.       {
  359.       MList [ Count ] = ( TList [ Count ] - VList [ Count ] ) /
  360.                         Steps;
  361.       }
  362.  
  363.   // Delete memory:
  364.   delete [] TList;
  365.  
  366.   // Close file:
  367.   fclose ( InFile );
  368.  
  369.   // Return success:
  370.   return 1;
  371.   }
  372.  
  373. void PanelObject::MorphRev ()
  374.    {
  375.    // Reverse the direction of the morph:
  376.    DWORD Count;
  377.    for ( Count = 0; Count < VCount; Count++ )
  378.        {
  379.        MList [ Count ] = MList [ Count ] * -1.0F;
  380.        }
  381.    }
  382.  
  383. void WRITE ( char *Message, float Value )
  384.    {
  385.    static int Opened = 0;
  386.    FILE *File;
  387.    if ( !Opened )
  388.       {
  389.       File = fopen ( "Debug.DAT", "wt" );
  390.       Opened = 1;
  391.       }
  392.    else File = fopen ( "Debug.DAT", "at" );
  393.    fprintf ( File, Message, Value );
  394.    fclose ( File );
  395.    }
  396.  
  397. int PanelObject::Collide ( float &X, float &Y, float &Z,
  398.                            float Rad )
  399.   {
  400.   long Count;
  401.   float Dist, X2, Y2, Z2, A, B, C, D, Sign, MinDist, NormY;
  402.   const float NOSE = 300.0F, VIEW_HEIGHT = 700.0F;
  403.   Y -= VIEW_HEIGHT;
  404.   for ( Count = 0; Count < PCount; Count++ )
  405.       {
  406.       X2 = ( PList [ Count ].VPoint [ 0 ]->Wx +
  407.              PList [ Count ].VPoint [ 1 ]->Wx +
  408.              PList [ Count ].VPoint [ 2 ]->Wx +
  409.              PList [ Count ].VPoint [ 3 ]->Wx ) / 4.0F;
  410.  
  411.       Y2 = ( PList [ Count ].VPoint [ 0 ]->Wy +
  412.              PList [ Count ].VPoint [ 1 ]->Wy +
  413.              PList [ Count ].VPoint [ 2 ]->Wy +
  414.              PList [ Count ].VPoint [ 3 ]->Wy ) / 4.0F;
  415.  
  416.       Z2 = ( PList [ Count ].VPoint [ 0 ]->Wz +
  417.              PList [ Count ].VPoint [ 1 ]->Wz +
  418.              PList [ Count ].VPoint [ 2 ]->Wz +
  419.              PList [ Count ].VPoint [ 3 ]->Wz ) / 4.0F;
  420.  
  421.       // Calculate distance to panel:
  422.       Dist = sqrt ( ( X2 - X ) * ( X2 - X ) +
  423.                     ( Y2 - Y ) * ( Y2 - Y ) +
  424.                     ( Z2 - Z ) * ( Z2 - Z ) );
  425.       // Check for possible collision by using bounding sphere:
  426.       MinDist = Rad + PList [ Count ].Radius;
  427.       if ( Dist <= MinDist )
  428.          {
  429.          // Confirm/reject collision warning by calculating
  430.          // which side of the plane the viewer will be on:
  431.          A = ( PList [ Count ].Normal.Tx -
  432.                PList [ Count ].VPoint [ 0 ]->Wx );
  433.          B = ( PList [ Count ].Normal.Ty -
  434.                PList [ Count ].VPoint [ 0 ]->Wy );
  435.          C = ( PList [ Count ].Normal.Tz -
  436.                PList [ Count ].VPoint [ 0 ]->Wz );
  437.          D = -( A * PList [ Count ].VPoint [ 0 ]->Wx +
  438.                 B * PList [ Count ].VPoint [ 0 ]->Wy +
  439.                 C * PList [ Count ].VPoint [ 0 ]->Wz );
  440.          Sign = A * X + B * Y + C * ( Z + NOSE ) + D;
  441.          if ( Sign <= 0.0F )
  442.             {
  443.             // Collision is definite:
  444.  
  445.             // Store the Y component of the panel normal:
  446.             NormY = B;
  447.  
  448.             // If panel is a wall....
  449.             if ( fabs ( NormY ) < sqrt ( 0.5F ) )
  450.                {
  451.                if ( A )
  452.                   {
  453.                   Z = ( A * X + B * Y + D ) / ( -C ) + 1.0F - NOSE;
  454.                   X = ( B * Y + C * ( Z + NOSE ) + D ) / ( -A );
  455.                   }
  456.                else X = Z = 0.0F;
  457.                }
  458.             // Else panel is a floor or ceiling....
  459.             else {
  460.                  // Determine if panel is a floor:
  461.                  if ( NormY > 0.0F )
  462.                     {
  463.                     Y = ( A * X + C * Z + D ) / ( - B );
  464.                     }
  465.                  }
  466.             }
  467.          }
  468.       }
  469.   Y += VIEW_HEIGHT;
  470.   return 0;
  471.   }
  472.  
  473. Point3D PanelObject::LoadCoord ( FILE *InFile )
  474.    {
  475.    // Loads a single coordinate from a text file:
  476.    int PCount = 0;
  477.    char String [ 100 ] = "";
  478.    Point3D Coord;
  479.    while ( PCount < 3 )
  480.          {
  481.          if ( GetLine ( InFile, String ) == EOF )
  482.             {
  483.             Coord.Lx = 0;
  484.             Coord.Ly = 0;
  485.             Coord.Lz = 0;
  486.             break;
  487.             }
  488.  
  489.          // Check for the first X coordinate:
  490.          if ( Match ( String, "10" ) )
  491.             {
  492.             GetLine ( InFile, String );
  493.             Coord.Lx = atof ( String );
  494.             ++PCount;
  495.             }
  496.          // Check for the second X coordinate:
  497.          else if ( Match ( String, "11" ) )
  498.                  {
  499.                  GetLine ( InFile, String );
  500.                  Coord.Lx = atof ( String );
  501.                  ++PCount;
  502.                  }
  503.          // Check for the third X coordinate:
  504.          else if ( Match ( String, "12" ) )
  505.                  {
  506.                  GetLine ( InFile, String );
  507.                  Coord.Lx = atof ( String );
  508.                  ++PCount;
  509.                  }
  510.          // Check for the fourth X coordinate:
  511.          else if ( Match ( String, "13" ) )
  512.                  {
  513.                  GetLine ( InFile, String );
  514.                  Coord.Lx = atof ( String );
  515.                  ++PCount;
  516.                  }
  517.          // Check for the first Y coordinate:
  518.          else if ( Match ( String, "20" ) )
  519.                  {
  520.                  GetLine ( InFile, String );
  521.                  Coord.Ly = atof ( String );
  522.                  ++PCount;
  523.                  }
  524.          // Check for the second Y coordinate:
  525.          else if ( Match ( String, "21" ) )
  526.                  {
  527.                  GetLine ( InFile, String );
  528.                  Coord.Ly = atof ( String );
  529.                  ++PCount;
  530.                  }
  531.          // Check for the third Y coordinate:
  532.          else if ( Match ( String, "22" ) )
  533.                  {
  534.                  GetLine ( InFile, String );
  535.                  Coord.Ly = atof ( String );
  536.                  ++PCount;
  537.                  }
  538.          // Check for the fourth Y coordinate:
  539.          else if ( Match ( String, "23" ) )
  540.                  {
  541.                  GetLine ( InFile, String );
  542.                  Coord.Ly = atof ( String );
  543.                  ++PCount;
  544.                  }
  545.          // Check for the first Z coordinate:
  546.          else if ( Match ( String, "30" ) )
  547.                  {
  548.                  GetLine ( InFile, String );
  549.                  Coord.Lz = atof ( String );
  550.                  ++PCount;
  551.                  }
  552.          // Check for the second Z coordinate:
  553.          else if ( Match ( String, "31" ) )
  554.                  {
  555.                  GetLine ( InFile, String );
  556.                  Coord.Lz = atof ( String );
  557.                  ++PCount;
  558.                  }
  559.          // Check for the third Z coordinate:
  560.          else if ( Match ( String, "32" ) )
  561.                  {
  562.                  GetLine ( InFile, String );
  563.                  Coord.Lz = atof ( String );
  564.                  ++PCount;
  565.                  }
  566.          // Check for the fourth Z coordinate:
  567.          else if ( Match ( String, "33" ) )
  568.                  {
  569.                  GetLine ( InFile, String );
  570.                  Coord.Lz = atof ( String );
  571.                  ++PCount;
  572.                  }
  573.          }
  574.  
  575.    // Return a copy of the loaded vertex:
  576.    return Coord;
  577.    }
  578.  
  579. DWORD PanelObject::CountPanels ( char *FileName )
  580.   {
  581.   // Count the number of panels in a text file:
  582.   char String [ 100 ] = "";
  583.   DWORD PanelCount = 0;
  584.   FILE *InFile;
  585.  
  586.   // Open the file:
  587.   if ( ( InFile = fopen ( FileName, "rt" ) ) == 0 )
  588.      return 0;
  589.  
  590.   // Loop until we come to the end of the file:
  591.   for ( ;; )
  592.       {
  593.       // Get a line of text:
  594.       if ( GetLine ( InFile, String ) == EOF )
  595.          break;
  596.  
  597.       // Search for a panel (3DFACE):
  598.       if ( Match ( String, "3DFACE" ) )
  599.          ++PanelCount;
  600.       }
  601.  
  602.   // Close the file:
  603.   fclose ( InFile );
  604.  
  605.   // Return number of vertices:
  606.   return PanelCount;
  607.   }
  608.    
  609. WORD PanelObject::LoadVerts ( char *FileName )
  610.   {
  611.   // Load all vertices from a DXF text file:
  612.  
  613.   // Declare/initialize variables:
  614.  
  615.   PCount = CountPanels ( FileName );
  616.  
  617.   // Allocate memory for temporary list:
  618.   if ( ( TList = new Point3D [ PCount * 4 ] ) == 0 )
  619.      return 0;
  620.  
  621.   // The vertex index in the temporary list:
  622.   unsigned int VIndex = 0, Count;
  623.  
  624.   // A file structure:
  625.   FILE *InFile;
  626.   
  627.   // Open file - abort if error:
  628.   if ( ( InFile = fopen ( FileName, "rt" ) ) == 0 )
  629.      return 0;
  630.  
  631.   // An all-purpose string:
  632.   char String [ 100 ] = "";
  633.   
  634.   // Loop until we come to the end of the file:
  635.   for ( ;; )
  636.       {
  637.       // Get a line of text:
  638.       if ( GetLine ( InFile, String ) == EOF )
  639.          break;
  640.  
  641.       // If a 3DFACE entity is encountered....
  642.       if ( Match ( "3DFACE", String ) )
  643.          {
  644.          // Load four vertices:
  645.          for ( Count = 0; Count < 4; Count++ )
  646.              {
  647.              // Load the next coordinate:
  648.              Point3D TPoint3D = LoadCoord ( InFile );
  649.              TList [ VIndex++ ] = TPoint3D;   
  650.              }
  651.          }
  652.       }
  653.  
  654.   // Close the file:
  655.   fclose ( InFile );
  656.  
  657.   // Set the vertex count at zero:
  658.   VCount = 0;
  659.  
  660.   // Allocate memory for vertex list - abort if error:
  661.   if ( ( VList = new Point3D [ VIndex ] ) == 0 )
  662.      return 0;
  663.  
  664.   // Copy TList to VList:
  665.   for ( Count = 0; Count < VIndex; Count++ )
  666.       {
  667.       if ( UniqueVert ( TList [ Count ], VList, VCount ) )
  668.          {
  669.          VList [ VCount ] = TList [ Count ];
  670.  
  671.          // Increment the vertex count/index:
  672.          ++VCount;
  673.          }
  674.       }
  675.   
  676.   // Return true (success):
  677.   return 1;
  678.   }
  679.  
  680. WORD PanelObject::LoadPanelData ()
  681.    {
  682.    // Read the panel data from a DXF file:
  683.    // Note: Assumes all vertices have been loaded via member
  684.    //       function "LoadVerts"
  685.  
  686.    // Allocate memory for files:
  687.    if ( ( PList = new Panel3D [ PCount ] ) == 0 )
  688.       return 0;
  689.  
  690.    int VIndex = 0;
  691.  
  692.    // Loop until we come to the end of the file:
  693.    for ( unsigned int PIndex = 0; PIndex < PCount; PIndex++ )
  694.        {
  695.        // Load an entire panel:
  696.        LoadPanel ( VIndex, PIndex );
  697.        }
  698.  
  699.    // Deallocate temporary list data
  700.    delete [] TList;
  701.  
  702.    // Return true (success):
  703.    return 1;
  704.    }
  705.  
  706. WORD PanelObject::LoadPanel ( int &VIndex, int Index )
  707.    {
  708.    // Load a panel from a DXF text file:
  709.  
  710.    // 3DFACE has been found - load four coordinates:
  711.    for ( unsigned int Count = 0; Count < 4; Count++ )
  712.        {
  713.        // Assign a vertex to the panel:
  714.        PList [ Index ].VPoint [ Count ] = 
  715.              &VList [ GetVertIndex (  TList [ VIndex ], 
  716.              VList, VCount ) ];
  717.  
  718.        // Increment the vertex index:
  719.        ++VIndex;
  720.        }
  721.  
  722.    // Calculate panel normal:
  723.    PList [ Index ].InitPosition ();
  724.  
  725.    // Calculate panel's intensity:
  726.    PList [ Index ].CalcInten ();
  727.  
  728.    // Return true (success):
  729.    return 1;
  730.    }
  731.  
  732. void PanelObject::LoadDXF ( char *FileName )
  733.    {
  734.    // Load an object from a DXF text file:
  735.    LoadVerts ( FileName );
  736.    LoadPanelData ();
  737.    }
  738.  
  739. void PanelObject::ReadBIN ( char *FileName )
  740.    {
  741.    // Load an object from a BIN binary file:
  742.    unsigned int VertCount, PanelCount, Count;
  743.    unsigned int short PIndex, VIndex;
  744.    float IPer;
  745.    Point3D TVert;
  746.    FILE *InFile;
  747.    if ( ( InFile = fopen ( FileName, "rb" ) ) == NULL )
  748.       return;
  749.    fread ( &VertCount, sizeof VertCount, 1, InFile );
  750.    fread ( &PanelCount, sizeof PanelCount, 1, InFile );
  751.    // Allocate memory:
  752.    VList = new Point3D [ VertCount ];
  753.    PList = new Panel3D [ PanelCount ];
  754.  
  755.    // Load vertices:
  756.    for ( Count = 0; Count < VertCount; Count++ )
  757.        {
  758.        VList [ Count ].Read ( InFile );
  759.        }
  760.    VCount = VertCount;
  761.    PCount = PanelCount;
  762.  
  763.    cout << "\nReading Polygon Dataset:\n";
  764.    // Load panel data:
  765.    for ( Count = 0; Count < PCount; Count++ )
  766.        {
  767.        IPer = ( ( float ) Count / ( float ) PCount ) * 101.0F;
  768.        cout << ( long ) IPer << "%\r";
  769.        for ( VIndex = 0; VIndex < 4; VIndex++ )
  770.            {
  771.            fread ( &PIndex, sizeof PIndex, 1, InFile );
  772.            PList [ Count ].VPoint [ VIndex ] = &VList [ PIndex ];
  773.            }
  774.        // Calculate the panel normal:
  775.        PList [ Count ].InitPosition ();
  776.  
  777.        // Calculate the panel's intensity:
  778.        PList [ Count ].CalcInten ();
  779.        }
  780.    fclose ( InFile );
  781.    }
  782.  
  783. void PanelObject::WriteBIN ( char *FileName )
  784.    {
  785.    // Write a BIN binary file:
  786.    unsigned int VertCount = VCount, PanelCount = PCount, Count;
  787.    unsigned int short PIndex, VIndex;
  788.    Point3D *PVert;
  789.    FILE *OutFile;
  790.    if ( ( OutFile = fopen ( FileName, "wb" ) ) == NULL )
  791.       return;
  792.    fwrite ( &VertCount, sizeof VertCount, 1, OutFile );
  793.    fwrite ( &PanelCount, sizeof PanelCount, 1, OutFile );
  794.  
  795.    // Write vertex data:
  796.    for ( Count = 0; Count < VCount; Count++ )
  797.        {
  798.        VList [ Count ].Write ( OutFile );
  799.        }
  800.  
  801.    // Write panel data:
  802.    for ( Count = 0; Count < PCount; Count++ )
  803.        {
  804.        for ( VIndex = 0; VIndex < 4; VIndex++ )
  805.            {
  806.            PVert = PList [ Count ].VPoint [ VIndex ];
  807.            PIndex = ( unsigned short ) GetVertIndex ( *PVert, VList, VCount );
  808.            fwrite ( &PIndex, sizeof PIndex, 1, OutFile );
  809.            }
  810.        }
  811.    fclose ( OutFile );
  812.    }
  813.  
  814. int PanelObject::ReadText ( char *FileName )
  815.   {
  816.   long Count;
  817.   FILE *InFile;
  818.   if ( ( InFile = fopen ( FileName, "rb" ) ) == 0 )
  819.      return 0;
  820.   // Load the textures:
  821.   TextDat.LoadBT ( InFile );
  822.  
  823.   // Load the texture coordinates and handles:
  824.   for ( Count = 0; Count < PCount; Count++ )
  825.       {
  826.       fread ( &PList [ Count ].TextHan, 
  827.               sizeof PList [ Count ].TextHan, 1, InFile );
  828.       fread ( PList [ Count ].Attrib, sizeof ( Detail3D ), 4, 
  829.               InFile );
  830.       }
  831.   fclose ( InFile );
  832.  
  833.   return 1;
  834.   }
  835.  
  836. int PanelObject::WriteText ( char *FileName )
  837.   {
  838.   long Count;
  839.   FILE *OutFile;
  840.   if ( ( OutFile = fopen ( FileName, "wb" ) ) == 0 )
  841.      return 0;
  842.   // Save the textures:
  843.   TextDat.SaveBT ( OutFile );
  844.  
  845.   // Save the texture coordinates and handles:
  846.   for ( Count = 0; Count < PCount; Count++ )
  847.       {
  848.       fwrite ( &PList [ Count ].TextHan, 
  849.                sizeof PList [ Count ].TextHan, 1, OutFile );
  850.       fwrite ( PList [ Count ].Attrib, sizeof ( Detail3D ), 4, 
  851.                OutFile );
  852.       }
  853.   fclose ( OutFile );
  854.  
  855.   return 1;
  856.   }
  857.