Page 1 of 1

.HIM Handler

PostPosted: Fri Jun 19, 2009 1:39 am
by rl-1
So as many of you know, we just started a map editor project. We are coding this in C# with XNA. So far I have the handlers for .ZON and .TIL perfectly, but I can't figure out the last part of the .HIM structure. Here is my handler so far :
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.IO;
  6.  
  7. namespace OSRose_Map_Viewer.FileHandlers
  8. {
  9.     public class HIM
  10.     {
  11.         public class Block0
  12.         {
  13.             public struct HIMPart
  14.             {
  15.                 public float height2 { get; set; }
  16.             };
  17.             public int width { get; set; }
  18.             public int height { get; set; }
  19.             public int grid_count { get; set; }
  20.             public float grid_size { get; set; }
  21.             public HIMPart[,] HIMParts { get; set; }
  22.         }
  23.         public enum collision_type
  24.         {
  25.  
  26.         }
  27.         public class quadentry_count
  28.         {
  29.             public float minZ { get; set; }
  30.             public float maxZ { get; set; }
  31.         }
  32.  
  33.  
  34.  
  35.         public string FilePath { get; set; }
  36.  
  37.         #region Data Declarations
  38.         Block0 HIMInfo { get; set; }
  39.         quadentry_count quadentry_counts { get; set; }
  40.         #endregion
  41.  
  42.         public HIM()
  43.         {
  44.         }
  45.         public HIM(string filePath)
  46.         {
  47.             Load(filePath);
  48.         }
  49.         public void Load(string filePath)
  50.         {
  51.             FilePath = filePath;
  52.             BinaryReader fh = new BinaryReader(File.OpenRead(filePath));
  53.             HIMInfo = new Block0()
  54.             {
  55.                 width = fh.ReadInt32(),
  56.                 height = fh.ReadInt32(),
  57.                 grid_count = fh.ReadInt32(),
  58.                 grid_size = fh.ReadSingle()
  59.             };
  60.             HIMInfo.HIMParts = new Block0.HIMPart[HIMInfo.height, HIMInfo.width];
  61.             for (int j = 0; j < HIMInfo.width; j++)
  62.             {
  63.                 for (int k = 0; k < HIMInfo.height; k++)
  64.                 {
  65.                     HIMInfo.HIMParts[j, k] = new Block0.HIMPart()
  66.                     {
  67.                         height2 = fh.ReadSingle()
  68.                     };
  69.                 }
  70.             }
  71.             quadentry_counts = new quadentry_count()
  72.             {
  73.                 minZ = fh.ReadSingle(),
  74.                 maxZ = fh.ReadSingle()
  75.             };
  76.         }
  77.         public void Save(string filePath)
  78.         {
  79.             FilePath = filePath;
  80.  
  81.             BinaryWriter fh = new BinaryWriter(File.OpenWrite(filePath));
  82.             fh.Write(HIMInfo.width);
  83.             fh.Write(HIMInfo.height);
  84.             fh.Write(HIMInfo.grid_count);
  85.             fh.Write(HIMInfo.grid_size);
  86.             for (int x = 0; x < HIMInfo.width; x++)
  87.             {
  88.                 for (int y = 0; y < HIMInfo.height; y++)
  89.                 {
  90.                     fh.Write(HIMInfo.HIMParts[x,y].height2);
  91.                 }
  92.             }
  93.             fh.Write(quadentry_counts.minZ);
  94.             fh.Write(quadentry_counts.maxZ);
  95.         }
  96.     }
  97. }
  98.  

But I am having trouble with this part of the structure:
  1. DEFINE quadtree_count = 1 + 4 + 16 + 32
  2. DWORD quadtree_count
  3. CALL writequadnode( 256 )
  4. CALL writequadnode( 128 )
  5. CALL writequadnode( 64 )
  6. CALL writequadnode( 32 )
  7.  
  8. FUNCTION writequadnode( divisonsize )
  9. // I can't really write the pseudo-format for this, but it writes the min and max heights for each quadratic division of the map quadtree
  10.  

This structure comes from Bretts website : http://rose.br19.com/?fid=4

If anyone has any insight on how to handle this, it would be much appreciated :D

rl-1

Re: .HIM Handler

PostPosted: Fri Jun 19, 2009 1:56 am
by lmame
Did you see the vel's code and explanation?

Re: .HIM Handler

PostPosted: Fri Jun 19, 2009 2:04 am
by twunk32
Take a look at here

Re: .HIM Handler

PostPosted: Fri Jun 19, 2009 3:19 am
by Raven0123
I can help you, if you need help with the .HIM files. check PMs

Re: .HIM Handler

PostPosted: Fri Jun 19, 2009 11:16 am
by Souleater
By the way, this is not right :
  1. fh.Write(quadentry_counts.minZ);
  2. fh.Write(quadentry_counts.maxZ);


Instead of that call this method :
  1. this.WriteQuadTree(fh);


And here is it's code :
  1.             public void WriteQuadTree(BinaryWriter fh)                  
  2.       {        
  3.                             fh.Write((byte) 0x04);  // b len
  4.                     fh.Write((int) 0x64617571);// "quad"
  5.  
  6.                   // Quadtree List 1
  7.  
  8.                   // 16 * 16 quads
  9.                   fh.Write((int)256);
  10.  
  11.                   float[] Vals;
  12.                   for ( int a = 0; a < 16; a++){
  13.                      for ( int b = 0; b < 16; b++){
  14.                         Vals = GetHighLow(HIMInfo.HIMParts, a * 4, b * 4, a * 4 + 4, b * 4 + 4);
  15.                         fh.Write((float)Vals[0]);
  16.                         fh.Write((float)Vals[1]);
  17.                      }
  18.                   }
  19.  
  20.                   // Quadtree List 2
  21.  
  22.                   // List of values to get the start and end index to get the high and low values in the loops.
  23.                   int[,] P1 = new int[4,2]{ {0,0},{0,32},{32,32},{32,0}};
  24.                   int[,] P2 = new int[4,2]{ {0,0},{0,16},{16,16},{16,0}};
  25.                   int[,] P3 = new int[4,2]{ {0,0},{0,8},{8,8},{8,0}};
  26.                  
  27.                   // 1 + 4 + 16 + 64 = 85
  28.                   fh.Write((int)85);
  29.  
  30.                   // Root
  31.                   Vals = GetHighLow(HIMInfo.HIMParts, 0, 0, 64, 64);
  32.                   fh.Write((float)Vals[0]);
  33.                   fh.Write((float)Vals[1]);
  34.  
  35.                   // split root in 4 -> 4 results
  36.                   // 64, 64 splitted into 4 => block size = 32, 32
  37.  
  38.                   for(int i = 0; i < 4; i++)
  39.                   {
  40.                      Vals = GetHighLow(HIMInfo.HIMParts, P1[i,0], P1[i,1], P1[i,0] + 32, P1[i,1] + 32);
  41.                      fh.Write((float)Vals[0]);
  42.                      fh.Write((float)Vals[1]);
  43.                   }
  44.  
  45.                   // split each subnode in 4 -> (4 * 4 = 16 results )
  46.                   // 32, 32 splitted into 4 => block size = 16, 16
  47.  
  48.                   for(int i = 0; i < 4; i++){
  49.                      for(int a = 0; a < 4; a++){
  50.                         Vals = GetHighLow(HIMInfo.HIMParts, P1[i,0] + P2[a,0], P1[i,1] + P2[a,1], P1[i,0] + P2[a,0] + 16, P1[i,1] + P2[a,1] + 16);
  51.                         fh.Write((float)Vals[0]);
  52.                         fh.Write((float)Vals[1]);
  53.                      }
  54.                   }
  55.  
  56.                   // split each subsubnode  in 4 -> (4 * 4 * 4 = 64 results)
  57.                   // 16, 16 splitted into 4 => block size = 8, 8
  58.  
  59.                   for(int i = 0; i < 4; i++){
  60.                      for(int a = 0; a < 4; a++){
  61.                         for(int b = 0; b < 4; b++){
  62.                            Vals = GetHighLow(HIMInfo.HIMParts, P1[i,0] + P2[a,0] + P3[b,0], P1[i,1] + P2[a,1] + P3[b,1], P1[i,0] + P2[a,0] + P3[b,0] + 8, P1[i,1] + P2[a,1] + P3[b,1] + 8);
  63.                            fh.Write((float)Vals[0]);
  64.                            fh.Write((float)Vals[1]);
  65.                         }
  66.                      }
  67.                   }
  68.  
  69.             }
  70.  
  71.       private float GetHighLow(float[,] Values, float MinX, float MinY, float MaxX, float MaxY)
  72.       {
  73.          int high = -9999999;
  74.          int low = 9999999;
  75.  
  76.          for(int x = MinX; x <= MaxX; x++)
  77.          {
  78.             for(int y = MinY; y <= MaxY; y++)
  79.                 {
  80.                if (  Values[x, y] > high)
  81.                   high = Values[x, y];
  82.                if (  Values[x, y] < low)
  83.                   low = Values[x, y];
  84.             }
  85.          }
  86.  
  87.          return new float[2]{high, low};
  88.       }


Credits for this code goes to MaTT, I just ported it to C# ( and it's not tested =-*)

And also your Load method is not right starting from the point you finish reading up the Height points. Moreover, at this point, you really don't need to read the quadtree since you won't be using it anyway and it can be generated from the height points.

Re: .HIM Handler

PostPosted: Fri Jun 19, 2009 7:32 pm
by rl-1
Hrmmm....the code you gave me almost works. However it is having trouble recognizing that HIMInfo.HIMParts is a float value. So now I am confused as to why. It clearly looks to me like HIMInfo.HIMParts is a float....hrmmm....any suggestions?

Re: .HIM Handler

PostPosted: Sat Jun 20, 2009 12:01 am
by AkramMaTT
The code I posted still seemed to have some problems, you could look through the terrain when your camera was close to the ground.

Here's the fixed code: http://pastebin.ca/1466914

Re: .HIM Handler

PostPosted: Sat Jun 20, 2009 1:41 pm
by Souleater
Thanks MaTT.

The problem is rl-1, you've defined a HIMPart multidim array whereas it should be a float multidim array so that matt's code work. You'll just have to change your HIMInfo.HIMParts type and set it as float[,] instead of HIMPart [,] .

If I have time I'll port matt's new code to C#.