Advertisement
kiwidog

Rime Mesh Plugin

Jul 21st, 2015
487
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.17 KB | None | 0 0
  1. // By: kiwidog (http://kiwidog.me)
  2. // Use with: https://github.com/kiwidoggie/RimeExamplePlugin
  3. // http://modders.link
  4.  
  5. using System.Collections.Generic;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Windows.Controls;
  9. using Microsoft.Win32;
  10. using RimeCommon.Content.Messages;
  11. using RimeCommon.Messaging;
  12. using RimeCommon.Mounting;
  13. using RimeCommon.Mounting.Messages;
  14. using RimeCommon.Plugins;
  15. using RimeLib;
  16. using RimeLib.Frostbite.Content.Mesh;
  17. using RimeLib.Helpers.Mesh;
  18. using RimeLib.IO;
  19.  
  20. namespace Rime.Core.Plugins.Rendering
  21. {
  22.     public class MeshPlugin : RimePlugin
  23.     {
  24.         public override string Name { get { return "Mesh Exporter"; } }
  25.         public override string Author { get { return "kiwidog"; } }
  26.         public override string Version { get { return "2.2"; } }
  27.         public override string Description { get { return "Model exporter"; } }
  28.         public override string Extension { get { return ".meshset"; } }
  29.         public override UserControl MainControl { get { return null; } }
  30.         public override MountPoint Mount { get { return MountPoint.Center; } }
  31.  
  32.         public override void Init(params object[] p_Params)
  33.         {
  34.             RegisterListener(MessagingSubSystem.Content);
  35.  
  36.             RegisterMessageCallback(typeof(ContentRequestOpen), OnContentReqest);
  37.         }
  38.  
  39.         private void OnContentReqest(RimeMessage p_Obj)
  40.         {
  41.             var s_Message = (ContentRequestOpen) p_Obj;
  42.             if (s_Message.Extension != Extension)
  43.                 return;
  44.  
  45.             var s_List = new List<MountEntry>();
  46.  
  47.             MessageManager.SendMessage(new MountRequestEntry
  48.                 {
  49.                     Hash = s_Message.Hash
  50.                 }, (p_Msg) =>
  51.                 {
  52.                     var s_Msg = (MountRespondEntry) p_Msg;
  53.                     if (!s_Msg.Success)
  54.                         return;
  55.  
  56.                     s_List = s_Msg.Entries.ToList();
  57.                 });
  58.  
  59.             if (s_List.Count < 1)
  60.                 return;
  61.  
  62.             LoadModel(s_List[0]);
  63.         }
  64.  
  65.         private void LoadModel(MountEntry p_Entry)
  66.         {
  67.             // Get our resource data
  68.             var s_MeshSetResourceData = p_Entry.GetData();
  69.             if (s_MeshSetResourceData == null)
  70.                 return;
  71.  
  72.             // Decompress the resource
  73.             var s_MeshSetData = RimeHelper.ResourceDecompress(s_MeshSetResourceData);
  74.  
  75.             // Hold the class of MeshSetLayout
  76.             MeshSetLayout s_Layout = null;
  77.             using (var s_Reader = new RimeReader(new MemoryStream(s_MeshSetData)))
  78.                 s_Layout = new MeshSetLayout(s_Reader);
  79.  
  80.             // Check to see if we have at least one level of detail
  81.             if (!s_Layout.Lods.Any())
  82.                 return;
  83.  
  84.             // Select the highest quality model by default
  85.             var s_MeshSet = s_Layout.Lods[0];
  86.             byte[] s_LodData = null;
  87.  
  88.             MessageManager.SendMessage(new MountRequestEntry
  89.                 {
  90.                     Hash = s_MeshSet.DataChunkID.ToString()
  91.                 }, (p_Msg) =>
  92.                 {
  93.                     var s_Msg = (MountRespondEntry) p_Msg;
  94.                     if (!s_Msg.Success)
  95.                         return;
  96.  
  97.                     if (s_Msg.Entries.Length < 1)
  98.                         return;
  99.  
  100.                     var s_Entry = s_Msg.Entries[0];
  101.  
  102.                     s_LodData = s_Entry.GetData();
  103.                 });
  104.  
  105.             if (s_LodData == null)
  106.                 return;
  107.  
  108.             var s_SaveFileDialog = new SaveFileDialog
  109.             {
  110.                 Title = "Save model file...",
  111.                 FileName = s_Layout.ShortName,
  112.                 DefaultExt = ".obj",
  113.                 Filter = "Waveform Object file (.obj)|*.obj"
  114.             };
  115.  
  116.             if (s_SaveFileDialog.ShowDialog() != true)
  117.                 return;
  118.  
  119.             ConvertToObj(s_SaveFileDialog.FileName, s_MeshSet, s_LodData);
  120.         }
  121.  
  122.         public void ConvertToObj(string p_SavePath, MeshLayout p_Layout, byte[] p_Data)
  123.         {
  124.             using (var s_Reader = new RimeReader(new MemoryStream(p_Data)))
  125.             {
  126.                 using (TextWriter s_Writer = new StreamWriter(p_SavePath))
  127.                 {
  128.                     // Ensure that there is a subset to read from
  129.                     if (!p_Layout.Subsets.Any())
  130.                         return;
  131.  
  132.                     // Write our our comment
  133.                     s_Writer.WriteLine("# Generated with Rime, the ultimate frostbite mod tool");
  134.  
  135.                     // Get the first subset.
  136.                     var s_Subset = p_Layout.Subsets[0];
  137.  
  138.                     // Iterate through all of the vertices and write it out with UV information
  139.                     for (var i = 0; i < s_Subset.VertexCount; ++i)
  140.                     {
  141.                         s_Reader.BaseStream.Position = (s_Subset.VertexStride*i) + s_Subset.VertexOffset;
  142.  
  143.                         var l_VertexBlock = new VertexData(s_Reader);
  144.  
  145.                         s_Writer.WriteLine("v {0} {1} {2}", l_VertexBlock.X.ToString("F6"), l_VertexBlock.Y.ToString("F6"), l_VertexBlock.Z.ToString("F6"));
  146.                         s_Writer.WriteLine("vt {0} {1}", l_VertexBlock.UV[0].ToString("F6"), l_VertexBlock.UV[1].ToString("F6"));
  147.                         s_Writer.Flush();
  148.                     }
  149.  
  150.                     // Write out the mat name
  151.                     s_Writer.WriteLine("g {0}", s_Subset.MaterialName);
  152.  
  153.                     // Go to the start of the primitive data
  154.                     s_Reader.BaseStream.Position = p_Layout.VertexDataSize;
  155.  
  156.                     // Iterate through all of the primitives and write out the faces
  157.                     for (var i = 0; i < s_Subset.PrimitiveCount; ++i)
  158.                     {
  159.                         var l_x = s_Reader.ReadUInt16();
  160.                         var l_y = s_Reader.ReadUInt16();
  161.                         var l_z = s_Reader.ReadUInt16();
  162.  
  163.                         s_Writer.WriteLine("f {0}/{0} {1}/{1} {2}/{2}", (l_x + 1), (l_y + 1), (l_z + 1));
  164.                         s_Writer.Flush();
  165.                     }
  166.                 }
  167.             }
  168.         }
  169.     }
  170. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement