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