Advertisement
Ember

nif1

Mar 11th, 2015
212
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.65 KB | None | 0 0
  1. bool Mesh::CreateFromNIF(String filename)
  2. {
  3.     // Temporary stuffs
  4.     File meshFile;
  5.  
  6.     // Open the mesh file
  7.     ZeroMemory(&meshFile, sizeof(File));
  8.     meshFile.Open(filename, File::Mode::Read);
  9.  
  10.     Log::Singleton->Write("Importing 3DS mesh: " + filename);
  11.  
  12.     // Begin importing the mesh
  13.  
  14.     NIF::Header header;
  15.     // Load the header
  16.     // Begin reading the string located at the beginning of the file
  17.     Byte letter;
  18.     header.Name = "";
  19.     while((letter = meshFile.Read<Byte>()) != 0x0A) { header.Name += letter; };
  20.     // Now read each data element individually because I can't be arsed to make this more efficient
  21.     header.Version = meshFile.Read<UByte4>();
  22.     header.Endianess = meshFile.Read<Byte>();
  23.     header.UserVersion = meshFile.Read<UInt>();
  24.     header.NumBlocks = meshFile.Read<UInt>();
  25.     header.UserVersion2 = meshFile.Read<UInt>();
  26.     // Export information
  27.     header.Creator.Length = meshFile.Read<UByte>();
  28.     header.Creator.Text += meshFile.Read<char>(header.Creator.Length);
  29.     header.Info1.Length = meshFile.Read<UByte>();
  30.     header.Info1.Text += meshFile.Read<char>(header.Info1.Length);
  31.     header.Info2.Length = meshFile.Read<UByte>();
  32.     header.Info2.Text += meshFile.Read<char>(header.Info2.Length);
  33.     // Header again
  34.     header.NumBlockTypes = meshFile.Read<UShort>();
  35.     // Types of Blocks
  36.     header.Types.resize(header.NumBlockTypes);
  37.     for(Byte i = 0; i < header.NumBlockTypes; ++i)
  38.     {
  39.         header.Types[i].Length = meshFile.Read<UInt>();
  40.         header.Types[i].Text += meshFile.Read<char>(header.Types[i].Length);
  41.     }
  42.     // Block Type ID linking thingy, idk
  43.     header.BlockTypeIndex.resize(header.NumBlocks);
  44.     meshFile.Read<UShort>(header.BlockTypeIndex.data(), header.NumBlocks);
  45.     // omg why
  46.     header.BlockSize.resize(header.NumBlocks);
  47.     meshFile.Read<UInt>(header.BlockSize.data(), header.NumBlocks);
  48.     // finally
  49.     header.NumStrings = meshFile.Read<UInt>();
  50.     header.MaxStringLength = meshFile.Read<UInt>();
  51.     // or not, you're killing me
  52.     header.Strings.resize(header.NumStrings);
  53.     for(Byte i = 0; i < header.NumStrings; ++i)
  54.     {
  55.         header.Strings[i].Length = meshFile.Read<UInt>();
  56.         header.Strings[i].Text += meshFile.Read<char>(header.Strings[i].Length);
  57.     }
  58.     //  I give up
  59.     header.Unknown = meshFile.Read<UInt>();
  60.  
  61.     // THE MEATY MEAT
  62.     // Set up the hash table
  63.     const UInt hNIFNode = ELFHash("NiNode");
  64.     const UInt hNIFTriShape = ELFHash("NiTriShape");
  65.  
  66.     for(Byte i = 0; i < header.NumBlocks; ++i)
  67.     {
  68.         String string = header.Types[header.BlockTypeIndex[i]].Text;
  69.         UInt hash = ELFHash(string);
  70.         //--//
  71.         if(hash == hNIFNode) // NIF::Node ("NiNode")
  72.         {
  73.             NIF::Node node;
  74.             // Now read the node
  75.             node.Name = header.Strings[meshFile.Read<Int>()].Text; // String Reference
  76.             node.NumExtraData = meshFile.Read<UInt>();
  77.             node.ExtraData.resize(node.NumExtraData);
  78.             meshFile.Read<UInt>(node.ExtraData.data(), node.NumExtraData); //[NumExtraData];
  79.             node.Controller = meshFile.Read<Int>(); // Object Reference
  80.             node.Flags = meshFile.Read<UShort>();
  81.             node.Unknown = meshFile.Read<UShort>();
  82.             node.Translation = meshFile.Read<Float3>();
  83.             node.Rotation = meshFile.Read<Float3x3>();
  84.             node.Scale = meshFile.Read<Float>();
  85.             node.CollisionObject = meshFile.Read<Int>(); // Object Reference
  86.             node.NumChildren = meshFile.Read<UInt>();
  87.             node.Children.resize(node.NumChildren);
  88.             meshFile.Read<Int>(node.Children.data(), node.NumChildren); // [NumChildren];
  89.             node.NumEffects = meshFile.Read<UInt>();
  90.             node.Effects.resize(node.NumEffects);
  91.             meshFile.Read<Int>(node.Effects.data(), node.NumEffects); // [NumEffects];
  92.  
  93.             node.Unknown = header.Unknown;
  94.         }
  95.         else if(hash == hNIFTriShape) // NIF::TriShape ("NiTriShape")
  96.         {
  97.             NIF::TriShape node;
  98.             // Now read the object data
  99.             node.Name = header.Strings[meshFile.Read<Int>()].Text; // String Reference
  100.             node.NumExtraData = meshFile.Read<UInt>();
  101.             node.ExtraData.resize(node.NumExtraData);
  102.             meshFile.Read<UInt>(node.ExtraData.data(), node.NumExtraData); //[NumExtraData];
  103.             node.Controller = meshFile.Read<Int>();
  104.             node.Flags = meshFile.Read<UShort>();
  105.             node.Unknown = meshFile.Read<UShort>();
  106.             node.Translation = meshFile.Read<Float3>();
  107.             node.Rotation = meshFile.Read<Float3x3>();
  108.             node.Scale = meshFile.Read<Float>();
  109.             node.CollisionObject = meshFile.Read<Int>();
  110.             node.Data = meshFile.Read<Int>();
  111.             node.SkinInstance = meshFile.Read<Int>();
  112.             node.NumMaterials = meshFile.Read<UInt>();
  113.             assert(node.NumMaterials == 0);
  114.             //Array<String> MaterialNames;
  115.             //node.MaterialNames.resize(node.NumMaterials);
  116.             //meshFile.Read<UInt>(node.MaterialNames.data(), node.NumMaterials); //[NumExtraData];
  117.             //Array<Int> MaterialExtraData;
  118.             node.ActiveMaterial = meshFile.Read<Int>();
  119.             node.DirtyFlag = meshFile.Read<UByte>();
  120.             node.Properties[0] = meshFile.Read<Int>();
  121.             node.Properties[1] = meshFile.Read<Int>();
  122.  
  123.             node.Unknown = header.Unknown;
  124.         }
  125.         else
  126.         {
  127.             // Skip the chunk
  128.             meshFile.Read<Byte>(header.BlockSize[i]);
  129.         }
  130.     }
  131.  
  132.     header.~Header();
  133.     meshFile.Close();
  134.  
  135.     return false;
  136. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement