Пример #1
0
        //find the chunk, replace the chunk, perhaps create or remove the reference
        public static void ReplaceChunk(this GenericRCOLResource rcolResource, MLOD.Mesh mesh, string field, IResourceKey rk, ARCOLBlock block)
        {
            ARCOLBlock current = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, (GenericRCOLResource.ChunkReference)mesh[field].Value) as ARCOLBlock;

            if (block != null)
            {
                if (current != null) // replacing is easy
                {
                    if (current.Tag != block.Tag)
                    {
                        throw new Exception(string.Format("mesh field {0} is '{1}' but replacement is '{2}'.", field, current.Tag, block.Tag));
                    }
                    // ...not entirely sure if these are required...
                    current.Data = block.Data;
                    block        = current;
                }
                else // adding is okay
                {
                    rcolResource.ChunkEntries.Add(new GenericRCOLResource.ChunkEntry(0, null, new TGIBlock(0, null, rk), block));
                    mesh[field] = new TypedValue(typeof(GenericRCOLResource.ChunkReference), GenericRCOLResource.ChunkReference.CreateReference(rcolResource, rk), "X");
                }
            }
            else // deleting is not allowed - we can only null the reference, not remove the chunk
            {
                mesh[field] = new TypedValue(typeof(GenericRCOLResource.ChunkReference), new GenericRCOLResource.ChunkReference(0, null, 0), "X");
            }
        }
Пример #2
0
        //Match what Wes's compiler does
        public static void FixUVScales(this GenericRCOLResource rcolResource, MLOD.Mesh mesh)
        {
            MATD matd = GetMATDforMesh(rcolResource, mesh.MaterialIndex);

            if (matd == null)
            {
                throw new ArgumentException("No MATD found for requested mesh");
            }

            foreach (FieldType ft in new FieldType[] { FieldType.UVScales, FieldType.DiffuseUVSelector, FieldType.SpecularUVSelector, })
            {
                ShaderData data = (matd.Version < 0x0103 ? matd.Mtrl.SData : matd.Mtnf.SData).Find(x => x.Field == ft);
                if (data == null)
                {
                    continue;
                }

                if (!(data is ElementFloat3))
                {
                    throw new InvalidOperationException(String.Format("Found " + ft + " of type '{0}'; expected 'ElementFloat3'.", data.GetType().Name));
                }

                ElementFloat3 e = data as ElementFloat3;
                e.Data0 = 1f / short.MaxValue;
                e.Data1 = 0f;
                e.Data2 = 0f;
            }
        }
Пример #3
0
        void loadVPXY(Stream data)
        {
            try
            {
                rcol = new GenericRCOLResource(0, data);
            }
            catch { rcol = null; }
            if (rcol == null || rcol.ChunkEntries.Count != 1 || rcol.ChunkEntries[0].RCOLBlock.Tag != "VPXY")
            {
                throw new Exception("RCOL was not a VPXY resource.");
            }
            vpxy = rcol.ChunkEntries[0].RCOLBlock as VPXY;
            if (vpxy == null)
            {
                throw new Exception("VPXY resource contains invalid RCOL Chunk.");
            }

            FillPartsTLP();

            nudLowerX.Value = new Decimal(vpxy.Bounds.Min.X);
            nudLowerY.Value = new Decimal(vpxy.Bounds.Min.Y);
            nudLowerZ.Value = new Decimal(vpxy.Bounds.Min.Z);
            nudUpperX.Value = new Decimal(vpxy.Bounds.Max.X);
            nudUpperY.Value = new Decimal(vpxy.Bounds.Max.Y);
            nudUpperZ.Value = new Decimal(vpxy.Bounds.Max.Z);

            tbcFTPT.Enabled = ckbModular.Checked = vpxy.Modular;
            tbcFTPT.TGIBlocks = vpxy.TGIBlocks;
            tbcFTPT.SelectedIndex = vpxy.Modular && vpxy.FTPTIndex < vpxy.TGIBlocks.Count ? (int)vpxy.FTPTIndex : -1;

            rcol.ResourceChanged += new EventHandler(rcol_ResourceChanged);
        }
Пример #4
0
        void loadVPXY(Stream data)
        {
            try
            {
                rcol = new GenericRCOLResource(0, data);
            }
            catch { rcol = null; }
            if (rcol == null || rcol.ChunkEntries.Count != 1 || rcol.ChunkEntries[0].RCOLBlock.Tag != "VPXY")
            {
                throw new Exception("RCOL was not a VPXY resource.");
            }
            vpxy = rcol.ChunkEntries[0].RCOLBlock as VPXY;
            if (vpxy == null)
            {
                throw new Exception("VPXY resource contains invalid RCOL Chunk.");
            }

            FillPartsTLP();

            nudLowerX.Value = new Decimal(vpxy.Bounds.Min.X);
            nudLowerY.Value = new Decimal(vpxy.Bounds.Min.Y);
            nudLowerZ.Value = new Decimal(vpxy.Bounds.Min.Z);
            nudUpperX.Value = new Decimal(vpxy.Bounds.Max.X);
            nudUpperY.Value = new Decimal(vpxy.Bounds.Max.Y);
            nudUpperZ.Value = new Decimal(vpxy.Bounds.Max.Z);

            tbcFTPT.Enabled       = ckbModular.Checked = vpxy.Modular;
            tbcFTPT.TGIBlocks     = vpxy.TGIBlocks;
            tbcFTPT.SelectedIndex = vpxy.Modular && vpxy.FTPTIndex < vpxy.TGIBlocks.Count ? (int)vpxy.FTPTIndex : -1;

            rcol.ResourceChanged += new EventHandler(rcol_ResourceChanged);
        }
Пример #5
0
 public MainWindow(GenericRCOLResource s)
     : this()
 {
     rcol = s;
     rbTextured.Visibility = Visibility.Collapsed;
     InitScene();
     rbSolid.IsChecked = true;
 }
Пример #6
0
        public static GenericRCOLResource.ChunkReference GetMLODChunkRefforMODL(this GenericRCOLResource rcolResource)
        {
            var lodEntry = (rcolResource.ChunkEntries[0].RCOLBlock as MODL).Entries
                           .Find(l => l.ModelLodIndex.RefType == GenericRCOLResource.ReferenceType.Public ||
                                 l.ModelLodIndex.RefType == GenericRCOLResource.ReferenceType.Private);

            return(lodEntry == null ? null : lodEntry.ModelLodIndex);
        }
Пример #7
0
 public VBUF(int APIversion, EventHandler handler, uint version, FormatFlags flags, GenericRCOLResource.ChunkReference swizzleInfo, byte[] buffer)
     : this(APIversion, handler)
 {
     mVersion = version;
     mFlags = flags;
     mSwizzleInfo = swizzleInfo;
     mBuffer = buffer;
 }
Пример #8
0
        public JazzGraphContainer(int index, JazzPackage jp,
                                  IResourceIndexEntry rie, Control view, TabPage page)
        {
            this.Index     = index;
            this.UndoRedo  = new UndoManager();
            this.SaveState = JazzSaveState.Saved;
            this.Key       = new RK(rie);
            this.Comp      = rie.Compressed == 0xFFFF;
            this.JP        = jp;
            this.RIE       = rie;
            IResource           res  = null;
            GenericRCOLResource rcol = null;

            try
            {
                res = WrapperDealer.GetResource(0, jp.Package, rie);
            }
            catch (Exception ex)
            {
                MainForm.ShowException(ex,
                                       "Could not load JAZZ resource: " + this.Key + "\n",
                                       MainForm.kName + ": Unable to load JAZZ resource");
            }
            if (res != null)
            {
                rcol = res as GenericRCOLResource;
                if (rcol != null)
                {
                    this.Scene = new StateMachineScene(
                        new StateMachine(rcol), view, this);
                    KKLayoutAlgorithm <StateNode, StateEdge> layout
                        = new KKLayoutAlgorithm <StateNode, StateEdge>(
                              this.Scene.StateGraph, this.Scene);
                    layout.LengthFactor = 1.25f;
                    this.Scene.Layout   = layout;
                    layout.ShuffleNodes();
                    this.Scene.LayoutPaused = true;
                    this.Scene.StartLayout();
                }
                else
                {
                    this.Scene = null;
                }
            }
            if (!KeyNameReg.TryFindName(rie.Instance, out this.mName))
            {
                this.mName = "0x" + rie.Instance.ToString("X16");
            }
            if (this.Scene != null)
            {
                this.mPage = page;
                this.mPage.Controls.Add(view);
                this.mPage.Text         = this.mName;
                this.mPage.SizeChanged +=
                    new EventHandler(this.OnTabSizeChanged);
            }
        }
Пример #9
0
        public static VBSI FromMLOD(MLOD mlod, GenericRCOLResource container)
        {
            var vbsi = new VBSI(0, null);

            foreach (var mesh in mlod.Meshes)
            {
                var vrtf = (VRTF)GenericRCOLResource.ChunkReference.GetBlock(container, mesh.VertexFormatIndex);
                vbsi.Segments.Add(SegmentInfo.FromMesh(mesh, vrtf));
            }
            return(vbsi);
        }
Пример #10
0
        public static MATD GetMATDforMesh(this GenericRCOLResource rcolResource, GenericRCOLResource.ChunkReference reference)
        {
            IRCOLBlock materialRef = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, reference);

            if (materialRef is MATD)
            {
                return(materialRef as MATD);
            }
            if (materialRef is MTST)
            {
                return(GetMATDforMesh(rcolResource, (materialRef as MTST).Index));
            }
            return(null);
        }
Пример #11
0
        static int Main(params string[] args)
        {
#if DEBUG
            if (args.Length == 0)
            {
                TGIBlock   tgib = new TGIBlock(0, null, "ITG", 0x736884F1, 0, 0);
                ARCOLBlock rcol = GenericRCOLResourceHandler.CreateRCOLBlock(0, null, 0x736884F1);
                GenericRCOLResource.ChunkEntry ce  = new GenericRCOLResource.ChunkEntry(0, null, tgib, rcol);
                GenericRCOLResource            grr = new GenericRCOLResource(0, null);
                grr.ChunkEntries.Add(ce);
                Clipboard.SetData(DataFormats.Serializable, grr.Stream);
            }
#endif
            return(s3pi.Helpers.RunHelper.Run(typeof(MainForm), args));
        }
Пример #12
0
        static int Main(params string[] args)
        {
#if DEBUG
            if (args.Length == 0)
            {
                TGIBlock tgib = new TGIBlock(0, null, "ITG", 0x736884F1, 0, 0);
                ARCOLBlock rcol = GenericRCOLResourceHandler.CreateRCOLBlock(0, null, 0x736884F1);
                GenericRCOLResource.ChunkEntry ce = new GenericRCOLResource.ChunkEntry(0, null, tgib, rcol);
                GenericRCOLResource grr = new GenericRCOLResource(0, null);
                grr.ChunkEntries.Add(ce);
                Clipboard.SetData(DataFormats.Serializable, grr.Stream);
            }
#endif
            return s3pi.Helpers.RunHelper.Run(typeof(MainForm), args);
        }
Пример #13
0
        private void SlurpKinRCOLTGIBlocks()
        {
            GenericRCOLResource rcol = base.resource as GenericRCOLResource;

            if (rcol != null)
            {
                for (int i = 0; i < rcol.ChunkEntries.Count; i++)
                {
                    if (this.GetChunkType(rcol.ChunkEntries[i].TGIBlock) == ChunkEntryType.Kindred)
                    {
                        base.kindredRCOLChunkKeys.Add(rcol.ChunkEntries[i].TGIBlock);
                    }
                }
            }
        }
Пример #14
0
        public void Export_MLOD(StreamWriter w, GenericRCOLResource rcolResource, MLOD mlod, MLOD.Mesh mesh)
        {
            float[] uvScales = rcolResource.GetUVScales(mesh);

            if (mesh.GeometryStates.Count > 0)
            {
                w.WriteLine(";");
                w.WriteLine("; Extended format: GeoStates follow IBUF");
                w.WriteLine(";");
            }

            if (mesh.Flags != 0)
            {
                w.WriteLine(";");
                w.WriteLine("; Extended format: MeshFlags follow IBUF" + (mesh.GeometryStates.Count > 0 ? " and GeoStates" : ""));
                w.WriteLine("; (They are ignored on import.)");
                w.WriteLine(";");
            }

            VRTF vrtf      = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.VertexFormatIndex) as VRTF;
            bool isDefault = vrtf == null;

            if (isDefault)
            {
                vrtf = VRTF.CreateDefaultForMesh(mesh);
                w.WriteLine(";;-marker: vrtf is default for mesh");
            }
            w.Export_VRTF(mpb, vrtf);

            w.Export_SKIN(mpb, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.SkinControllerIndex) as SKIN, mesh);
            Export_VBUF_Main(w, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.VertexBufferIndex) as VBUF, vrtf, uvScales, mesh);
            Export_IBUF_Main(w, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.IndexBufferIndex) as IBUF, mesh);

            //For backward compatibility, these come after the IBUFs
            Export_MeshGeoStates(w, vrtf, uvScales, mlod, mesh,
                                 GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.VertexBufferIndex) as VBUF,
                                 GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.IndexBufferIndex) as IBUF);

            if (mesh.Flags != 0)
            {
                w.WriteLine(";");
                w.WriteLine("; Extended format: MeshFlags");
                w.WriteLine(";");
                w.WriteLine("flags " + mesh.Flags);
                w.Flush();
            }
        }
Пример #15
0
        public void Export_MLOD(StreamWriter w, GenericRCOLResource rcolResource, MLOD mlod, MLOD.Mesh mesh)
        {
            float[] uvScales = rcolResource.GetUVScales(mesh);

            if (mesh.GeometryStates.Count > 0)
            {
                w.WriteLine(";");
                w.WriteLine("; Extended format: GeoStates follow IBUF");
                w.WriteLine(";");
            }

            if (mesh.Flags != 0)
            {
                w.WriteLine(";");
                w.WriteLine("; Extended format: MeshFlags follow IBUF" + (mesh.GeometryStates.Count > 0 ? " and GeoStates" : ""));
                w.WriteLine("; (They are ignored on import.)");
                w.WriteLine(";");
            }

            VRTF vrtf = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.VertexFormatIndex) as VRTF;
            bool isDefault = vrtf == null;
            if (isDefault)
            {
                vrtf = VRTF.CreateDefaultForMesh(mesh);
                w.WriteLine(";;-marker: vrtf is default for mesh");
            }
            w.Export_VRTF(mpb, vrtf);

            w.Export_SKIN(mpb, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.SkinControllerIndex) as SKIN, mesh);
            Export_VBUF_Main(w, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.VertexBufferIndex) as VBUF, vrtf, uvScales, mesh);
            Export_IBUF_Main(w, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.IndexBufferIndex) as IBUF, mesh);

            //For backward compatibility, these come after the IBUFs
            Export_MeshGeoStates(w, vrtf, uvScales, mlod, mesh,
                GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.VertexBufferIndex) as VBUF,
                GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.IndexBufferIndex) as IBUF);

            if (mesh.Flags != 0)
            {
                w.WriteLine(";");
                w.WriteLine("; Extended format: MeshFlags");
                w.WriteLine(";");
                w.WriteLine("flags " + mesh.Flags);
                w.Flush();
            }
        }
Пример #16
0
        public void Export_MLOD(StreamWriter w, GenericRCOLResource rcolResource, MLOD mlod, MLOD.Mesh mesh)
        {
            float[] uvScales = rcolResource.GetUVScales(mesh);

            VRTF vrtf = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.VertexFormatIndex) as VRTF;
            bool isDefault = vrtf == null;
            if (isDefault)
            {
                vrtf = VRTF.CreateDefaultForMesh(mesh);
                w.WriteLine(";;-marker: vrtf is default for mesh");
            }
            w.Export_VRTF(mpb, vrtf);

            w.Export_SKIN(mpb, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.SkinControllerIndex) as SKIN, mesh);
            Export_VBUF_Main(w, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.VertexBufferIndex) as VBUF, vrtf, uvScales, mesh);
            Export_IBUF_Main(w, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.IndexBufferIndex) as IBUF, mesh);
        }
Пример #17
0
        private static void Main(params String[] args)
        {
            GenericRCOLResource rcol = null;

            using (Stream s = File.OpenRead(args[0]))
            {
                rcol = new GenericRCOLResource(0, s);
            }
            var app = new Application();

            try
            {
                var self   = Process.GetCurrentProcess();
                var caller = self.GetParent();
                if (caller != null)
                {
                    caller.EnableRaisingEvents = true;
                    caller.Exited += (sender, eventArgs) => self.CloseMainWindow();;
                }
            }
            catch
            {
                MessageBox.Show(
                    "Unable to locate parent process.  If this was started through another program, you will have to close it manually.");
            }
            var win = new MainWindow(rcol);

            for (int i = 1; i < args.Length; i++)
            {
                switch (args[i])
                {
                case "-texture":
                    win.TextureSource = args[++i];
                    break;

                case "-title":
                    win.Title += " - " + args[++i];
                    break;

                default:
                    break;
                }
            }
            app.Run(win);
        }
Пример #18
0
        public void Export_MLOD(StreamWriter w, GenericRCOLResource rcolResource, MLOD mlod, MLOD.Mesh mesh)
        {
            float[] uvScales = rcolResource.GetUVScales(mesh);

            VRTF vrtf      = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.VertexFormatIndex) as VRTF;
            bool isDefault = vrtf == null;

            if (isDefault)
            {
                vrtf = VRTF.CreateDefaultForMesh(mesh);
                w.WriteLine(";;-marker: vrtf is default for mesh");
            }
            w.Export_VRTF(mpb, vrtf);

            w.Export_SKIN(mpb, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.SkinControllerIndex) as SKIN, mesh);
            Export_VBUF_Main(w, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.VertexBufferIndex) as VBUF, vrtf, uvScales, mesh);
            Export_IBUF_Main(w, GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.IndexBufferIndex) as IBUF, mesh);
        }
Пример #19
0
        private static void Main(params String[] args)
        {
            GenericRCOLResource rcol = null;
            using (Stream s = File.OpenRead(args[0]))
            {
                rcol = new GenericRCOLResource(0, s);
            }
            var app = new Application();

//            try
//            {
//                var self = Process.GetCurrentProcess();
//                var caller = self.GetParent();
//                if (caller != null)
//                {
//                    caller.EnableRaisingEvents = true;
//                    caller.Exited += (sender, eventArgs) => self.CloseMainWindow(); ;
//                }
//            }
//            catch
//            {
//                MessageBox.Show(
//                    "Unable to locate parent process.  If this was started through another program, you will have to close it manually.");
//            }
            var win = new MainWindow(rcol);
            for (int i = 1; i < args.Length; i++)
            {
                switch (args[i])
                {
                    case "-texture":
                        win.TextureSource = args[++i];
                        break;
                    case "-title":
                        win.Title += " - " + args[++i];
                        break;
                    default:
                        break;
                }
            }
            app.Run(win);
        }
Пример #20
0
        public static float[] GetUVScales(this GenericRCOLResource rcolResource, MLOD.Mesh mesh)
        {
            MATD matd = GetMATDforMesh(rcolResource, mesh.MaterialIndex);

            if (matd != null)
            {
                ShaderData data = (matd.Version < 0x0103 ? matd.Mtrl.SData : matd.Mtnf.SData).Find(x => x.Field == FieldType.UVScales);
                if (data != null)
                {
                    if (data is ElementFloat3)
                    {
                        ElementFloat3 e = data as ElementFloat3; return(new float[] { e.Data0, e.Data1, e.Data2, });
                    }
                    else
                    {
                        throw new InvalidOperationException(String.Format("Found UVScales of type '{0}'; expected 'ElementFloat3'.", data.GetType().Name));
                    }
                }
            }
            return(new float[] { 1f / 32767f, 0f, 0f, });
        }
Пример #21
0
 private static void Main(params String[] args)
 {
     byte[] buffer = null;
     using (Stream s = File.OpenRead(args[0]))
     {
         buffer = new byte[s.Length];
         s.Read(buffer, 0, buffer.Length);
     }
     var app = new Application();
     var resource = new GenericRCOLResource(0, new MemoryStream(buffer));
     var viewModel = new AnimViewModel(resource);
     var win = new MainWindow(viewModel);
     app.Run(win);
     if (viewModel.IsSaving)
     {
         byte[] output = resource.AsBytes;
         using (FileStream s = File.Create(args[0]))
         {
             s.Write(output, 0, output.Length);
         }
     }
 }
Пример #22
0
        private static MATD FindMainMATD(GenericRCOLResource rcol, IRCOLBlock material)
        {
            float[] scales = null;
            if (material == null)
            {
                return(null);
            }
            if (material is MATD)
            {
                return(material as MATD);
            }
            else if (material is MTST)
            {
                var mtst = material as MTST;
                try
                {
                    material = GenericRCOLResource.ChunkReference.GetBlock(rcol, mtst.Index);
                }
                catch (NotImplementedException e)
                {
                    MessageBox.Show("Material is external, unable to locate UV scales.");
                    return(null);
                }


                if (material is MATD)
                {
                    var matd = (MATD)material;
                    return(matd);
                }
            }
            else
            {
                throw new ArgumentException("Material must be of type MATD or MTST", "material");
            }

            return(null);
        }
Пример #23
0
 public AnimViewModel(GenericRCOLResource rcolResource)
 {
     IsSaving          = false;
     mANIM             = (ANIM)rcolResource.ChunkEntries.FirstOrDefault().RCOLBlock;
     CurrentFrameIndex = -1;
     SyncFrames();
     CommitCommand = new UserCommand <AnimViewModel>(x => true, y =>
     {
         IsSaving = true;
         Application.Current.Shutdown();
     });
     CancelCommand = new UserCommand <AnimViewModel>(x => true, y =>
     {
         IsSaving = false;
         Application.Current.Shutdown();
     });
     RemoveFrameCommand    = new UserCommand <AnimViewModel>(x => CurrentFrameIndex >= 0, RemoveFrame);
     AddFrameCommand       = new UserCommand <AnimViewModel>(x => true, AddFrame);
     ShiftFrameUpCommand   = new UserCommand <AnimViewModel>(x => x != null && x.CurrentFrameIndex > 0, ShiftFrameUp);
     ShiftFrameDownCommand = new UserCommand <AnimViewModel>(x => x != null && x.CurrentFrameIndex < x.Frames.Count - 1 && x.CurrentFrameIndex != -1, ShiftFrameDown);
     ImportCommand         = new UserCommand <AnimViewModel>(x => x != null && x.GetSelectedFrame() != null, ImportDds);
     ExportCommand         = new UserCommand <AnimViewModel>(x => x != null && x.GetSelectedFrame() != null && x.GetSelectedFrame().Frame.Stream.Length > 0, ExportDds);
 }
Пример #24
0
        private static void Main(params String[] args)
        {
            byte[] buffer = null;
            using (Stream s = File.OpenRead(args[0]))
            {
                buffer = new byte[s.Length];
                s.Read(buffer, 0, buffer.Length);
            }
            var app       = new Application();
            var resource  = new GenericRCOLResource(0, new MemoryStream(buffer));
            var viewModel = new AnimViewModel(resource);
            var win       = new MainWindow(viewModel);

            app.Run(win);
            if (viewModel.IsSaving)
            {
                byte[] output = resource.AsBytes;
                using (FileStream s = File.Create(args[0]))
                {
                    s.Write(output, 0, output.Length);
                }
            }
        }
Пример #25
0
 public AnimViewModel(GenericRCOLResource rcolResource)
 {
     IsSaving = false;
     mANIM = (ANIM) rcolResource.ChunkEntries.FirstOrDefault().RCOLBlock;
     CurrentFrameIndex = -1;
     SyncFrames();
     CommitCommand = new UserCommand<AnimViewModel>(x => true, y =>
         {
             IsSaving = true;
             Application.Current.Shutdown();
         });
     CancelCommand = new UserCommand<AnimViewModel>(x => true, y =>
         {
             IsSaving = false;
             Application.Current.Shutdown();
         });
     RemoveFrameCommand = new UserCommand<AnimViewModel>(x => CurrentFrameIndex >= 0, RemoveFrame);
     AddFrameCommand = new UserCommand<AnimViewModel>(x => true, AddFrame);
     ShiftFrameUpCommand = new UserCommand<AnimViewModel>(x => x != null && x.CurrentFrameIndex > 0, ShiftFrameUp);
     ShiftFrameDownCommand = new UserCommand<AnimViewModel>(x => x != null && x.CurrentFrameIndex < x.Frames.Count - 1 && x.CurrentFrameIndex != -1, ShiftFrameDown);
     ImportCommand = new UserCommand<AnimViewModel>(x => x != null && x.GetSelectedFrame() != null, ImportDds);
     ExportCommand = new UserCommand<AnimViewModel>(x => x != null && x.GetSelectedFrame() != null && x.GetSelectedFrame().Frame.Stream.Length > 0, ExportDds);
 }
Пример #26
0
 public static MATD GetMATDforMesh(this GenericRCOLResource rcolResource, GenericRCOLResource.ChunkReference reference)
 {
     IRCOLBlock materialRef = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, reference);
     if (materialRef is MATD) return materialRef as MATD;
     if (materialRef is MTST) return GetMATDforMesh(rcolResource, (materialRef as MTST).Index);
     return null;
 }
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (String.IsNullOrEmpty(value as string))
            {
                return(null);
            }

            var path = value as string;

            if (path != null && File.Exists(path))
            {
                using (FileStream s = File.OpenRead(path))
                {
                    var  rcol = new GenericRCOLResource(0, s);
                    MLOD mlod = rcol.ChunkEntries
                                .Where(x => x.RCOLBlock is MLOD)
                                .Select(x => x.RCOLBlock)
                                .Cast <MLOD>()
                                .FirstOrDefault();


                    double minX = double.MaxValue, minZ = double.MaxValue, maxX = double.MinValue, maxZ = double.MinValue;


                    var pnty = new List <Point[]>();
                    foreach (MLOD.Mesh mesh in mlod.Meshes)
                    {
                        var vbuf = GenericRCOLResource.ChunkReference.GetBlock(rcol, mesh.VertexBufferIndex) as VBUF;
                        var ibuf = GenericRCOLResource.ChunkReference.GetBlock(rcol, mesh.IndexBufferIndex) as IBUF;
                        var vrtf = GenericRCOLResource.ChunkReference.GetBlock(rcol, mesh.VertexFormatIndex) as VRTF;
                        if (vrtf == null)
                        {
                            continue;
                        }
                        Vertex[] verts   = vbuf.GetVertices(mesh, vrtf, null);
                        int[]    indices = ibuf.GetIndices(mesh);
                        for (int i = 0; i < indices.Length / 3; i++)
                        {
                            var tst  = new int[3];
                            var poly = new Point[3];
                            for (int j = 0; j < 3; j++)
                            {
                                Vertex vert = verts[indices[i * 3 + j]];
                                double x    = (Offset + (vert.Position[0] * Scale));
                                double z    = -(Offset + (vert.Position[2] * Scale));
                                poly[j] = new Point((int)x, (int)z);
                                if (poly[j].X > maxX)
                                {
                                    maxX = poly[j].X;
                                }

                                if (poly[j].X < minX)
                                {
                                    minX = poly[j].X;
                                }

                                if (poly[j].Y > maxZ)
                                {
                                    maxZ = poly[j].Y;
                                }

                                if (poly[j].Y < minZ)
                                {
                                    minZ = poly[j].Y;
                                }
                            }
                            pnty.Add(poly);
                        }
                    }
                    var      width  = (int)(maxX - minX);
                    var      height = (int)(maxZ - minZ);
                    var      bmp    = new Bitmap(width, height);
                    Graphics gBmp   = Graphics.FromImage(bmp);
                    gBmp.CompositingMode = CompositingMode.SourceCopy;
                    float bright            = 1.1f;
                    System.Drawing.Color c  = System.Drawing.Color.FromArgb(255, Fill.R, Fill.G, Fill.B);
                    System.Drawing.Color c2 = System.Drawing.Color.FromArgb(255, Stroke.R, Stroke.G, Stroke.B);

                    var b = new SolidBrush(c);


                    var b2  = new SolidBrush(c2);
                    var pen = new Pen(b2);
                    foreach (Point[] pointse in pnty)
                    {
                        Point[] scaled = pointse.Select(old => new Point((int)(old.X - minX), (int)(old.Y - minZ))).ToArray();
                        gBmp.FillPolygon(b, scaled);
                    }
                    foreach (Point[] pointse in pnty)
                    {
                        Point[] scaled = pointse.Select(old => new Point((int)(old.X - minX), (int)(old.Y - minZ))).ToArray();
                        gBmp.DrawPolygon(pen, scaled);
                    }
                    var bmpImg = new BitmapImage();

                    var ms = new MemoryStream();

                    bmp.Save(ms, ImageFormat.Png);
                    ms.Position = 0L;
                    bmpImg.BeginInit();
                    bmpImg.StreamSource = ms;
                    bmpImg.EndInit();
                    return(bmpImg);
                }
            }
            return(null);
        }
Пример #28
0
        private void Import_Shown(object sender, EventArgs e)
        {
            try
            {
                ofdImport.Title += " -- Test version " + typeof(ImportForm).Assembly.GetName().Version.ToString();
                DialogResult dr = ofdImport.ShowDialog();
                if (dr != DialogResult.OK)
                {
                    Environment.ExitCode = 1;
                    return;
                }

                string folder = Path.GetDirectoryName(ofdImport.FileName);
                string filebase = Path.GetFileNameWithoutExtension(ofdImport.FileName).Replace("_filebase", "");

                if (!File.Exists(Path.Combine(folder, string.Format("{0}_filebase.s3asc", filebase))))
                {
                    CopyableMessageBox.Show("File name must end \"_filebase.s3asc\"",
                        "Base file not found", CopyableMessageBoxButtons.OK, CopyableMessageBoxIcon.Error);
                    Environment.ExitCode = 1;
                    return;
                }

                bool updateBBs = false;
                int q = CopyableMessageBox.Show("Update mesh bounding boxes?", Application.ProductName, CopyableMessageBoxButtons.YesNoCancel, CopyableMessageBoxIcon.Question);
                if (q == 0)
                    updateBBs = true;
                else if (q == 2)
                {
                    Environment.ExitCode = 1;
                    return;
                }

                bool updateUVs = false;
                q = CopyableMessageBox.Show("Maximise mapping area?", Application.ProductName, CopyableMessageBoxButtons.YesNoCancel, CopyableMessageBoxIcon.Question);
                if (q == 0)
                    updateUVs = true;
                else if (q == 2)
                {
                    Environment.ExitCode = 1;
                    return;
                }

                try
                {
                    GenericRCOLResource rcolResource = new GenericRCOLResource(0, stream);
                    MLOD mlod = null;
                    IResourceKey rk = null;

                    if (rcolResource.ChunkEntries[0].TGIBlock.ResourceType == 0x01661233)//MODL
                    {
                        this.Text = "Import MODL...";
                        var lodRef = rcolResource.GetMLODChunkRefforMODL();
                        if (lodRef == null)
                        {
                            CopyableMessageBox.Show("MODL (0x01661233) with no MLOD (0x01D10F34).",
                                "Invalid MODL resource", CopyableMessageBoxButtons.OK, CopyableMessageBoxIcon.Error);
                            Environment.ExitCode = 1;
                            return;
                        }

                        rk = GenericRCOLResource.ChunkReference.GetKey(rcolResource, lodRef);
                        mlod = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, lodRef) as MLOD;
                    }
                    else if (rcolResource.ChunkEntries[0].TGIBlock.ResourceType == 0x01D10F34)//MLOD
                    {
                        this.Text = "Import MLOD...";
                        rk = rcolResource.ChunkEntries[0].TGIBlock;
                        mlod = rcolResource.ChunkEntries[0].RCOLBlock as MLOD;
                    }
                    else
                    {
                        CopyableMessageBox.Show("RCOL resource must be MODL (0x01661233) or MLOD (0x01D10F34).",
                            "Invalid RCOL resource", CopyableMessageBoxButtons.OK, CopyableMessageBoxIcon.Error);
                        Environment.ExitCode = 1;
                        return;
                    }

                    Import import = new Import(new MyProgressBar(label1, pb));

                    int m = 0;
                    List<meshExpImp.ModelBlocks.Vertex[]> lmverts = new List<meshExpImp.ModelBlocks.Vertex[]>();
                    while (true)
                    {
                        string fnMesh = Path.Combine(folder, string.Format("{0}_group{1:D2}.s3ascg", filebase, m));
                        if (!File.Exists(fnMesh)) break;

                        using (FileStream fsMesh = new FileStream(fnMesh, FileMode.Open, FileAccess.Read))
                        {
                            meshExpImp.ModelBlocks.Vertex[] mverts;
                            import.Import_Mesh(new StreamReader(fsMesh), mlod.Meshes[m++], rcolResource, mlod, rk, out mverts);
                            lmverts.Add(mverts);
                            fsMesh.Close();
                        }
                    }

                    List<Import.offScale> offScales = import.VertsToVBUFs(rcolResource, mlod, rk, lmverts, updateBBs, updateUVs);
                    if (offScales.Count > 0)
                    {
                        while (true)
                        {
                            switch (
                                CopyableMessageBox.Show(
                                Application.ProductName + " has detected some off-scale UV mappings.\n" +
                                "This may mean your mapping is not stored as you intended.\n" +
                                "This is often caused by UV-mapping too close to the edge of the map.\n\n" +
                                "Click 'Commit' to commit the change or 'Cancel' to abandon.",
                                Application.ProductName, CopyableMessageBoxIcon.Warning, new String[] { "C&ommit", "&View", "C&ancel", }, 0, 2))
                            {
                                case 0: //commit
                                    goto Commit;
                                case 1: //view
                                    System.Text.StringBuilder sb = new System.Text.StringBuilder();
                                    offScales.ForEach(x => sb.AppendLine(x.ToString()));
                                    CopyableMessageBox.Show(sb.ToString(), 
                                        Application.ProductName, CopyableMessageBoxButtons.OK, CopyableMessageBoxIcon.Information);
                                    break;
                                default: //cancel
                                    Environment.ExitCode = 1;
                                    return;
                            }
                        }
                    }

                Commit:
                    result = (byte[])rcolResource.AsBytes.Clone();

                    Environment.ExitCode = 0;
                }
                catch (Exception ex)
                {
                    CopyableMessageBox.IssueException(ex, "Error processing " + Program.Filename);
                    throw ex;
                }
            }
            finally { this.Close(); }
        }
Пример #29
0
        public List<offScale> VertsToVBUFs(GenericRCOLResource rcolResource, MLOD mlod, IResourceKey defaultRK, List<meshExpImp.ModelBlocks.Vertex[]> lmverts, bool updateBBs, bool updateUVs)
        {
            // List of UV elements going off scale
            List<offScale> offScales = new List<offScale>();

            // Find everything for each mesh group
            Dictionary<GenericRCOLResource.ChunkReference, List<int>> meshGroups = new Dictionary<GenericRCOLResource.ChunkReference, List<int>>();
            Dictionary<int, VRTF> meshVRTF = new Dictionary<int, VRTF>();
            Dictionary<int, float[]> meshUVScales = new Dictionary<int, float[]>();
            for (int m = 0; m < mlod.Meshes.Count; m++)
            {
                if (meshGroups.ContainsKey(mlod.Meshes[m].MaterialIndex)) meshGroups[mlod.Meshes[m].MaterialIndex].Add(m);
                else meshGroups.Add(mlod.Meshes[m].MaterialIndex, new List<int> { m });
                VRTF vrtf = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mlod.Meshes[m].VertexFormatIndex) as VRTF ?? VRTF.CreateDefaultForMesh(mlod.Meshes[m]);
                meshVRTF.Add(m, vrtf);

                if (updateUVs)
                    rcolResource.FixUVScales(mlod.Meshes[m]);
                meshUVScales.Add(m, rcolResource.GetUVScales(mlod.Meshes[m]));
            }

            // Update the VBUFs for each mesh group and set the mesh bounds whilst we're here
            foreach (var key in meshGroups.Keys)
            {
                foreach (int m in meshGroups[key])
                {
                    VBUF vbuf = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mlod.Meshes[m].VertexBufferIndex) as VBUF;
                    if (vbuf == null)
                        vbuf = new VBUF(rcolResource.RequestedApiVersion, null) { Version = 0x00000101, Flags = VBUF.FormatFlags.None, SwizzleInfo = new GenericRCOLResource.ChunkReference(0, null, 0), };

                    offScales.AddRange(getOffScales(m, -1, lmverts[m], meshUVScales[m]));
                    vbuf.SetVertices(mlod, m, meshVRTF[m], lmverts[m], meshUVScales[m]);

                    IResourceKey vbufRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mlod.Meshes[m].VertexBufferIndex);
                    if (vbufRK == null)//means we created the VBUF: create a RK and add it
                        vbufRK = new TGIBlock(0, null, defaultRK) { ResourceType = vbuf.ResourceType, };

                    rcolResource.ReplaceChunk(mlod.Meshes[m], "VertexBufferIndex", vbufRK, vbuf);

                    if (updateBBs)
                        mlod.Meshes[m].Bounds = vbuf.GetBoundingBox(mlod.Meshes[m], meshVRTF[m]);
                }
            }

            return offScales;
        }
Пример #30
0
 public GenericRCOLResource ExportToResource(ulong instanceId, 
     IDictionary<ulong, string> nameMap, bool exportAllNames)
 {
     this.mInstanceId = instanceId;
     GenericRCOLResource rcol = new GenericRCOLResource(0, null);
     AChunkObject[] chunks = this.FindAllChunks(false);
     GenericRCOLResource.ChunkEntryList chunkEntries
         = rcol.ChunkEntries;
     for (int i = 0; i < chunks.Length; i++)
     {
         chunkEntries.Add(chunks[i].Export(nameMap, exportAllNames));
     }
     // TODO: Ensure the data in rcol is flushed to its Stream.
     // Currently this is done automatically when its Stream is
     // retrieved because adding to the chunk entry list triggers its
     // OnResourceChanged() listener, which marks it dirty, causing
     // its Unparse() to be invoked when its Stream is retrieved.
     return rcol;
 }
Пример #31
0
        private void Export_Shown(object sender, EventArgs e)
        {
            try
            {
                sfdExport.Title += " -- Test version " + typeof(ExportForm).Assembly.GetName().Version.ToString();
                DialogResult dr = sfdExport.ShowDialog();
                if (dr != DialogResult.OK)
                {
                    Environment.ExitCode = 1;
                    return;
                }

                string folder = Path.GetDirectoryName(sfdExport.FileName);
                string filebase = Path.GetFileNameWithoutExtension(sfdExport.FileName).Replace("_filebase", "");

                try
                {
                    using (FileStream fs = new FileStream(Path.Combine(folder, string.Format("{0}_filebase.s3asc", filebase)), FileMode.Create, FileAccess.Write))
                    {
                        fs.Close();
                    }

                    GenericRCOLResource rcolResource = new GenericRCOLResource(0, stream);
                    MLOD mlod = null;

                    if (rcolResource.ChunkEntries[0].TGIBlock.ResourceType == 0x01661233)//MODL
                    {
                        this.Text = "Export MODL...";
                        var lodRef = rcolResource.GetMLODChunkRefforMODL();
                        if (lodRef == null)
                        {
                            CopyableMessageBox.Show("MODL (0x01661233) with no MLOD (0x01D10F34).",
                                "Invalid MODL resource", CopyableMessageBoxButtons.OK, CopyableMessageBoxIcon.Error);
                            Environment.ExitCode = 1;
                            return;
                        }


                        mlod = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, lodRef) as MLOD;
                    }
                    else if (rcolResource.ChunkEntries[0].TGIBlock.ResourceType == 0x01D10F34)//MLOD
                    {
                        this.Text = "Export MLOD...";

                        mlod = rcolResource.ChunkEntries[0].RCOLBlock as MLOD;
                    }
                    else
                    {
                        CopyableMessageBox.Show("RCOL resource must be MODL (0x01661233) or MLOD (0x01D10F34).",
                            "Invalid RCOL resource", CopyableMessageBoxButtons.OK, CopyableMessageBoxIcon.Error);
                        Environment.ExitCode = 1;
                        return;
                    }

                    Export export = new Export(new MyProgressBar(label1, pb));

                    for (int m = 0; m < mlod.Meshes.Count; m++)
                    {
                        string fnMesh = Path.Combine(folder, string.Format("{0}_group{1:D2}.s3ascg", filebase, m));

                        using (FileStream fsMesh = new FileStream(fnMesh, FileMode.Create, FileAccess.Write))
                        {
                            export.Export_MLOD(new StreamWriter(fsMesh), rcolResource, mlod, mlod.Meshes[m]);
                            fsMesh.Close();
                        }
                    }

                    Environment.ExitCode = 0;
                }
                catch (Exception ex)
                {
                    CopyableMessageBox.IssueException(ex, "Error processing " + Program.Filename);
                    throw ex;
                }
            }
            finally { this.Close(); }
        }
Пример #32
0
        private void TattooGo_button_Click(object sender, EventArgs e)
        {
            float sortOrder;

            try
            {
                sortOrder = float.Parse(CASPsortOrder.Text);
            }
            catch
            {
                MessageBox.Show("Please enter a valid number for Sort Order in CAS");
                return;
            }
            if (String.CompareOrdinal(TattooName.Text, " ") <= 0)
            {
                MessageBox.Show("Please enter a name for the tattoo");
                return;
            }
            if (dds == null)
            {
                MessageBox.Show("Please select an image for the tattoo");
                return;
            }
            ulong  tatInstance;
            string tatName;

            if (TattooName.Text.IndexOf("uutattoo") < 0)
            {
                tatName = "uutattoo" + TattooName.Text;
            }
            else
            {
                tatName = TattooName.Text;
            }
            if (String.CompareOrdinal(TattooInstance.Text, " ") > 0)
            {
                if (!UInt64.TryParse(TattooInstance.Text, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out tatInstance))
                {
                    MessageBox.Show("Please enter a valid Tattoo Instance number in hexidecimal, or leave it blank");
                    return;
                }
            }
            else
            {
                tatInstance = FNVhash.FNV64(tatName);
            }

            PleaseWait_label.Visible = true;
            this.Refresh();

            uint  tatGroup     = FNVhash.FNV24(tatName);
            ulong txtcInstance = FNVhash.FNV64(tatName + "TattooTemplate_Top_diffuse");

            Package myPack;

            myPack = (Package)Package.NewPackage(0);

            NameMapResource.NameMapResource myMap = new NameMapResource.NameMapResource(0, null);
            myMap.Add(tatInstance, tatName);
            myMap.Add(tatGroup, tatName);
            myMap.Add(txtcInstance, tatName + "TattooTemplate_Top_diffuse");

            XmlDocument doc1 = PresetBuilder.presetXML(tatName, tatInstance, presets[0],
                                                       ChannelR_checkBox.Checked, ChannelG_checkBox.Checked, ChannelB_checkBox.Checked, ChannelA_checkBox.Checked);
            XmlDocument doc2 = PresetBuilder.presetXML(tatName, tatInstance, presets[1],
                                                       ChannelR_checkBox.Checked, ChannelG_checkBox.Checked, ChannelB_checkBox.Checked, ChannelA_checkBox.Checked);
            XmlDocument doc3 = PresetBuilder.presetXML(tatName, tatInstance, presets[2],
                                                       ChannelR_checkBox.Checked, ChannelG_checkBox.Checked, ChannelB_checkBox.Checked, ChannelA_checkBox.Checked);

            CASPartResource.CASPartResource myCasp;
            myCasp = new CASPartResource.CASPartResource(0, null);
            CASPartResource.CASPartResource.Preset pre1 = new CASPartResource.CASPartResource.Preset(0, null, doc1.OuterXml, 1);
            CASPartResource.CASPartResource.Preset pre2 = new CASPartResource.CASPartResource.Preset(0, null, doc2.OuterXml, 2);
            CASPartResource.CASPartResource.Preset pre3 = new CASPartResource.CASPartResource.Preset(0, null, doc3.OuterXml, 3);
            myCasp.Presets = new CASPartResource.CASPartResource.PresetList(null);
            myCasp.Presets.Add(pre1);
            myCasp.Presets.Add(pre2);
            myCasp.Presets.Add(pre3);
            myCasp.Unknown1     = tatName;
            myCasp.SortPriority = sortOrder;
            myCasp.Clothing     = ClothingType.TattooTemplate;
            myCasp.DataType     = DataTypeFlags.Body;
            myCasp.AgeGender    = new AgeGenderFlags(0, null, (CASPtodder_checkBox.Checked ? AgeFlags.Toddler : 0) |
                                                     (CASPchild_checkBox.Checked ? AgeFlags.Child : 0) | (CASPteen_checkBox.Checked ? AgeFlags.Teen : 0) |
                                                     (CASPadult_checkBox.Checked ? AgeFlags.YoungAdult | AgeFlags.Adult : 0) |
                                                     (CASPelder_checkBox.Checked ? AgeFlags.Elder : 0),
                                                     (CASPfemale_checkBox.Checked ? GenderFlags.Female : 0) | (CASPmale_checkBox.Checked ? GenderFlags.Male : 0),
                                                     0, 0);
            myCasp.ClothingCategory = ClothingCategoryFlags.Athletic | ClothingCategoryFlags.Career | ClothingCategoryFlags.Everyday |
                                      ClothingCategoryFlags.FireFighting | ClothingCategoryFlags.Formalwear | ClothingCategoryFlags.Makeover |
                                      ClothingCategoryFlags.MartialArts | ClothingCategoryFlags.Naked | ClothingCategoryFlags.Outerwear |
                                      ClothingCategoryFlags.SkinnyDippingTowel | ClothingCategoryFlags.Sleepwear | ClothingCategoryFlags.Swimwear |
                                      ClothingCategoryFlags.Singed | ClothingCategoryFlags.ValidForMaternity;
            myCasp.CasPart1Index         = 2;
            myCasp.CasPart2Index         = 2;
            myCasp.BlendInfoFatIndex     = 3;
            myCasp.BlendInfoFitIndex     = 4;
            myCasp.BlendInfoThinIndex    = 5;
            myCasp.BlendInfoSpecialIndex = 6;
            myCasp.OverlayPriority       = 2u;
            myCasp.VPXYIndexes           = new ByteIndexList(null);
            myCasp.VPXYIndexes.Add(7);
            myCasp.Diffuse1Indexes = new ByteIndexList(null);
            myCasp.Diffuse1Indexes.Add(8);
            myCasp.Specular1Indexes = new ByteIndexList(null);
            myCasp.Specular1Indexes.Add(9);
            myCasp.BONDIndexes = new ByteIndexList(null);
            myCasp.BONDIndexes.AddRange(new List <byte> {
                2, 2, 2, 2, 2
            });
            myCasp.Unknown4  = "bare";
            myCasp.TGIBlocks = new CountedTGIBlockList(null);
            myCasp.TGIBlocks.Add(new TGIBlock(0, null, (uint)ResourceTypes.DDS, 0, tatInstance));
            myCasp.TGIBlocks.Add(new TGIBlock(0, null, (uint)ResourceTypes.XML, 0, 0xF7FC14B9EA85B390));
            myCasp.TGIBlocks.Add(new TGIBlock(0, null, 0, 0, 0));
            myCasp.TGIBlocks.Add(new TGIBlock(0, null, (uint)ResourceTypes.BBLN, 0, 0xCBE03A305F80FF50));
            myCasp.TGIBlocks.Add(new TGIBlock(0, null, (uint)ResourceTypes.BBLN, 0, 0xCBE032305F80F1F8));
            myCasp.TGIBlocks.Add(new TGIBlock(0, null, (uint)ResourceTypes.BBLN, 0, 0x540F4B31F0B42342));
            myCasp.TGIBlocks.Add(new TGIBlock(0, null, (uint)ResourceTypes.BBLN, 0, 0x82F02E48897E22B4));
            myCasp.TGIBlocks.Add(new TGIBlock(0, null, (uint)ResourceTypes.VPXY, 1, tatGroup));
            myCasp.TGIBlocks.Add(new TGIBlock(0, null, (uint)ResourceTypes.TXTC, tatGroup, txtcInstance));
            myCasp.TGIBlocks.Add(new TGIBlock(0, null, (uint)ResourceTypes.TXTC, tatGroup, 0xCBF29CE484222325));

            uint  fakeType     = (uint)tatInstance;
            uint  fakeGroup    = (uint)(tatInstance >> 32);
            ulong fakeInstance = (ulong)ResourceTypes.DDS << 32;

            TxtcResource.TxtcResource txtc = TattooTextureCompositor.TattooTxtc(new TGIBlock(0, null, fakeType, fakeGroup, fakeInstance));

            VPXY vpxy = new VPXY(0, null, 4, null, 2,
                                 new BoundingBox(0, null, new Vertex(0, null, -.0060f, 1.7157f, -.0060f), new Vertex(0, null, .0060f, 1.7277f, .0060f)),
                                 new byte[] { 0, 0, 0, 0 }, 0, 0, new TGIBlockList(null));
            GenericRCOLResource vpxyRcol = new GenericRCOLResource(0, null);

            vpxyRcol.Version      = 3;
            vpxyRcol.PublicChunks = 1;
            vpxyRcol.ChunkEntries = new GenericRCOLResource.ChunkEntryList(null);
            GenericRCOLResource.ChunkEntry vpxyChunk = new GenericRCOLResource.ChunkEntry(0, null, new TGIBlock(0, null, "ITG", (uint)ResourceTypes.VPXY, 1, tatGroup), vpxy);
            vpxyRcol.ChunkEntries.Add(vpxyChunk);
            IResourceIndexEntry rs = myPack.AddResource(new TGIBlock(0, null, (uint)ResourceTypes.KEY, 0, tatInstance), myMap.Stream, true);

            rs.Compressed = (ushort)0xFFFF;
            rs            = myPack.AddResource(new TGIBlock(0, null, (uint)ResourceTypes.CASP, 0, tatInstance), myCasp.Stream, true);
            rs.Compressed = (ushort)0xFFFF;
            rs            = myPack.AddResource(new TGIBlock(0, null, (uint)ResourceTypes.TXTC, tatGroup, txtcInstance), txtc.Stream, true);
            rs.Compressed = (ushort)0xFFFF;
            rs            = myPack.AddResource(new TGIBlock(0, null, (uint)ResourceTypes.VPXY, 1, tatGroup), vpxyRcol.Stream, true);
            rs.Compressed = (ushort)0xFFFF;
            MemoryStream ms = new MemoryStream();

            doc1.Save(ms);
            rs            = myPack.AddResource(new TGIBlock(0, null, (uint)ResourceTypes.XML, 0, tatInstance), ms, true);
            rs.Compressed = (ushort)0xFFFF;
            MemoryStream ms2 = new MemoryStream();

            dds.UseDXT          = false;
            dds.AlphaDepth      = 8;
            dds.GenerateMipmaps = true;
            dds.Save(ms2);
            rs            = myPack.AddResource(new TGIBlock(0, null, (uint)ResourceTypes.DDS, 0, tatInstance), ms2, true);
            rs.Compressed = (ushort)0xFFFF;
            if (thumbNail != null)
            {
                MemoryStream ms3 = new MemoryStream();
                thumbNail.Save(ms3, System.Drawing.Imaging.ImageFormat.Png);
                rs            = myPack.AddResource(new TGIBlock(0, null, (uint)ResourceTypes.THUM, 1, tatInstance), ms3, true);
                rs.Compressed = (ushort)0xFFFF;
            }

            PleaseWait_label.Visible = false;

            SaveFileDialog saveFileDialog1 = new SaveFileDialog();

            saveFileDialog1.Filter          = PackageFilter;
            saveFileDialog1.Title           = "Save as a new package";
            saveFileDialog1.FileName        = TattooName.Text + ".package";
            saveFileDialog1.FilterIndex     = 1;
            saveFileDialog1.CheckFileExists = false;
            saveFileDialog1.CheckPathExists = true;
            saveFileDialog1.OverwritePrompt = true;
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                myPack.SaveAs(saveFileDialog1.FileName);
            }
            ms.Dispose();
            ms2.Dispose();
        }
Пример #33
0
        //--


        public void Import_Mesh(StreamReader r, MLOD.Mesh mesh, GenericRCOLResource rcolResource, MLOD mlod, IResourceKey defaultRK, out meshExpImp.ModelBlocks.Vertex[] mverts)
        {
            #region Import VRTF
            bool isDefaultVRTF  = false;
            VRTF defaultForMesh = VRTF.CreateDefaultForMesh(mesh);

            VRTF vrtf = new VRTF(rcolResource.RequestedApiVersion, null)
            {
                Version = 2, Layouts = null,
            };
            r.Import_VRTF(mpb, vrtf);

            IResourceKey vrtfRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.VertexFormatIndex);
            if (vrtfRK == null)
            {
                vrtfRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.SkinControllerIndex);
                if (vrtfRK == null)
                {
                    vrtfRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.ScaleOffsetIndex);
                }
                if (vrtfRK == null)
                {
                    vrtfRK = new TGIBlock(0, null, 0, 0,
                                          System.Security.Cryptography.FNV64.GetHash(DateTime.UtcNow.ToString() + defaultRK.ToString()));
                }
                vrtfRK = new TGIBlock(0, null, vrtfRK)
                {
                    ResourceType = vrtf.ResourceType,
                };
            }

            if (vrtf.Equals(defaultForMesh))
            {
                isDefaultVRTF          = true;
                mesh.VertexFormatIndex = new GenericRCOLResource.ChunkReference(0, null, 0);//Clear the reference
            }
            else
            {
                rcolResource.ReplaceChunk(mesh, "VertexFormatIndex", vrtfRK, vrtf);
            }
            #endregion

            #region Import SKIN
            // we need to read the data in the file...
            SKIN skin = new SKIN(rcolResource.RequestedApiVersion, null)
            {
                Version = 1, Bones = null,
            };
            r.Import_SKIN(mpb, skin);

            // However, we do *NOT* want to update the RCOL with what we read - we are not replacing the object skeleton here
#if UNDEF
            if (skin.Bones != null)
            {
                IResourceKey skinRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.SkinControllerIndex);
                if (skinRK == null)
                {
                    skinRK = new TGIBlock(0, null, vrtfRK)
                    {
                        ResourceType = skin.ResourceType,
                    }
                }
                ;

                rcolResource.ReplaceChunk(mesh, "SkinControllerIndex", skinRK, skin);
            }
#endif
            #endregion

            mverts = Import_VBUF_Main(r, mlod, mesh, vrtf, isDefaultVRTF);

            #region Import IBUF
            IBUF ibuf = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.IndexBufferIndex) as IBUF;
            if (ibuf == null)
            {
                ibuf = new IBUF(rcolResource.RequestedApiVersion, null)
                {
                    Version = 2, Flags = IBUF.FormatFlags.DifferencedIndices, DisplayListUsage = 0,
                }
            }
            ;
            Import_IBUF_Main(r, mlod, mesh, ibuf);

            IResourceKey ibufRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.IndexBufferIndex);
            if (ibufRK == null)
            {
                ibufRK = new TGIBlock(0, null, defaultRK)
                {
                    ResourceType = ibuf.ResourceType,
                }
            }
            ;

            rcolResource.ReplaceChunk(mesh, "IndexBufferIndex", ibufRK, ibuf);
            #endregion

            #region Update the JointReferences
            UIntList joints = CreateJointReferences(mesh, mverts, skin);

            List <uint> added   = new List <uint>(joints);
            List <uint> removed = new List <uint>();
            foreach (var j in mesh.JointReferences)
            {
                if (joints.Contains(j))
                {
                    added.Remove(j);
                }
                else
                {
                    removed.Add(j);
                }
            }

            // Remove root
            removed.Remove(0xCD68F001);

            if (added.Count != 0)
            {
                mesh.JointReferences.AddRange(added);

                System.Windows.Forms.CopyableMessageBox.Show(String.Format("Mesh: 0x{0:X8}\nJointReferences with newly assigned (via BlendIndex) vertex: {1}\n({2})",
                                                                           mesh.Name,
                                                                           added.Count,
                                                                           String.Join(", ", added.ConvertAll <string>(a => "0x" + a.ToString("X8")).ToArray())),
                                                             "Warning", System.Windows.Forms.CopyableMessageBoxButtons.OK, System.Windows.Forms.CopyableMessageBoxIcon.Warning);
            }

            // with the 20120601 change to export, this warning on import has lost its severity... and been dropped.
#if UNDEF
            if (removed.Count != 0)
            {
//#if UNDEF
                // http://dino.drealm.info/den/denforum/index.php?topic=394.msg3876#msg3876
                removed.ForEach(j => mesh.JointReferences[mesh.JointReferences.IndexOf(j)] = 0);
//#endif
                // However, OM felt more comfortable if there was some indication something a little odd was going on.
                System.Windows.Forms.CopyableMessageBox.Show(String.Format("Mesh: 0x{0:X8}\nJointReferences with no assigned (via BlendIndex) vertex: {1}\n({2})",
                                                                           mesh.Name,
                                                                           removed.Count,
                                                                           String.Join(", ", removed.ConvertAll <string>(a => "0x" + a.ToString("X8")).ToArray())),
                                                             "Warning", System.Windows.Forms.CopyableMessageBoxButtons.OK, System.Windows.Forms.CopyableMessageBoxIcon.Warning);
            }
#endif
            #endregion
        }

        ModelBlocks.Vertex[] Import_VBUF_Main(StreamReader r, MLOD mlod, MLOD.Mesh mesh, VRTF vrtf, bool isDefaultVRTF)
        {
            string tagLine = r.ReadTag();

            string[] split = tagLine.Split(new char[] { ' ', }, StringSplitOptions.RemoveEmptyEntries);
            if (split.Length != 2)
            {
                throw new InvalidDataException("Invalid tag line read for 'vbuf'.");
            }
            if (split[0] != "vbuf")
            {
                throw new InvalidDataException("Expected line tag 'vbuf' not found.");
            }
            int count;

            if (!int.TryParse(split[1], out count))
            {
                throw new InvalidDataException("'vbuf' line has invalid count.");
            }

            //Wes's MilkShape plug-in sends back the first line in all subsequent lines of a dropShadow.
            return(r.Import_VBUF(mpb, count, vrtf, (mesh.Flags & MeshFlags.ShadowCaster) == 0));
        }

        void Import_IBUF_Main(StreamReader r, MLOD mlod, MLOD.Mesh mesh, IBUF ibuf)
        {
            string tagLine = r.ReadTag();

            string[] split = tagLine.Split(new char[] { ' ', }, StringSplitOptions.RemoveEmptyEntries);
            if (split.Length != 2)
            {
                throw new InvalidDataException("Invalid tag line read for 'ibuf'.");
            }
            if (split[0] != "ibuf")
            {
                throw new InvalidDataException("Expected line tag 'ibuf' not found.");
            }
            int count;

            if (!int.TryParse(split[1], out count))
            {
                throw new InvalidDataException("'ibuf' line has invalid count.");
            }

            ibuf.SetIndices(mlod, mesh, r.Import_IBUF(mpb, IBUF.IndexCountFromPrimitiveType(mesh.PrimitiveType), count));
        }

        UIntList CreateJointReferences(MLOD.Mesh mesh, ModelBlocks.Vertex[] mverts, SKIN skin)
        {
            if (skin == null || skin.Bones == null)
            {
                return(new UIntList(null));
            }

            int maxReference = -1;

            foreach (var vert in mverts)
            {
                if (vert.BlendIndices != null)
                {
                    foreach (var reference in vert.BlendIndices)
                    {
                        if ((sbyte)reference > maxReference)
                        {
                            maxReference = reference;
                        }
                    }
                }
            }

            return(maxReference > -1 ? new UIntList(null, skin.Bones.GetRange(0, maxReference + 1).ConvertAll <uint>(x => x.NameHash)) : new UIntList(null));
        }
Пример #34
0
        private void Import_Shown(object sender, EventArgs e)
        {
            try
            {
                ofdImport.Title += " -- Test version " + typeof(ImportForm).Assembly.GetName().Version.ToString();
                DialogResult dr = ofdImport.ShowDialog();
                if (dr != DialogResult.OK)
                {
                    Environment.ExitCode = 1;
                    return;
                }

                string folder   = Path.GetDirectoryName(ofdImport.FileName);
                string filebase = Path.GetFileNameWithoutExtension(ofdImport.FileName).Replace("_filebase", "");

                if (!File.Exists(Path.Combine(folder, string.Format("{0}_filebase.s3m2b", filebase))))
                {
                    CopyableMessageBox.Show("File name must end \"_filebase.s3m2b\"",
                                            "Base file not found", CopyableMessageBoxButtons.OK, CopyableMessageBoxIcon.Error);
                    Environment.ExitCode = 1;
                    return;
                }

                bool updateBBs = false;
                int  q         = CopyableMessageBox.Show("Update mesh bounding boxes?", Application.ProductName, CopyableMessageBoxButtons.YesNoCancel, CopyableMessageBoxIcon.Question);
                if (q == 0)
                {
                    updateBBs = true;
                }
                else if (q == 2)
                {
                    Environment.ExitCode = 1;
                    return;
                }

                bool updateUVs = false;
                q = CopyableMessageBox.Show("Maximise mapping area?", Application.ProductName, CopyableMessageBoxButtons.YesNoCancel, CopyableMessageBoxIcon.Question);
                if (q == 0)
                {
                    updateUVs = true;
                }
                else if (q == 2)
                {
                    Environment.ExitCode = 1;
                    return;
                }

                try
                {
                    GenericRCOLResource rcolResource = new GenericRCOLResource(0, stream);
                    MLOD         mlod = null;
                    IResourceKey rk   = null;

                    if (rcolResource.ChunkEntries[0].TGIBlock.ResourceType == 0x01661233)//MODL
                    {
                        this.Text = "Import MODL...";
                        var lodRef = rcolResource.GetMLODChunkRefforMODL();
                        if (lodRef == null)
                        {
                            CopyableMessageBox.Show("MODL (0x01661233) with no MLOD (0x01D10F34).",
                                                    "Invalid MODL resource", CopyableMessageBoxButtons.OK, CopyableMessageBoxIcon.Error);
                            Environment.ExitCode = 1;
                            return;
                        }

                        rk   = GenericRCOLResource.ChunkReference.GetKey(rcolResource, lodRef);
                        mlod = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, lodRef) as MLOD;
                    }
                    else if (rcolResource.ChunkEntries[0].TGIBlock.ResourceType == 0x01D10F34)//MLOD
                    {
                        this.Text = "Import MLOD...";
                        rk        = rcolResource.ChunkEntries[0].TGIBlock;
                        mlod      = rcolResource.ChunkEntries[0].RCOLBlock as MLOD;
                    }
                    else
                    {
                        CopyableMessageBox.Show("RCOL resource must be MODL (0x01661233) or MLOD (0x01D10F34).",
                                                "Invalid RCOL resource", CopyableMessageBoxButtons.OK, CopyableMessageBoxIcon.Error);
                        Environment.ExitCode = 1;
                        return;
                    }

                    Import import = new Import(new MyProgressBar(label1, pb));

                    int m = 0;
                    List <meshExpImp.ModelBlocks.Vertex[]>         lmverts = new List <meshExpImp.ModelBlocks.Vertex[]>();
                    List <List <meshExpImp.ModelBlocks.Vertex[]> > llverts = new List <List <meshExpImp.ModelBlocks.Vertex[]> >();
                    while (true)
                    {
                        string fnMesh = Path.Combine(folder, string.Format("{0}_group{1:D2}.s3m2bg", filebase, m));
                        if (!File.Exists(fnMesh))
                        {
                            break;
                        }

                        using (FileStream fsMesh = new FileStream(fnMesh, FileMode.Open, FileAccess.Read))
                        {
                            meshExpImp.ModelBlocks.Vertex[]        mverts;
                            List <meshExpImp.ModelBlocks.Vertex[]> lverts;
                            import.Import_Mesh(new StreamReader(fsMesh), mlod.Meshes[m++], rcolResource, mlod, rk, out mverts, out lverts);
                            lmverts.Add(mverts);
                            llverts.Add(lverts);
                            fsMesh.Close();
                        }
                    }

                    List <Import.offScale> offScales = import.VertsToVBUFs(rcolResource, mlod, rk, lmverts, llverts, updateBBs, updateUVs);
                    if (offScales.Count > 0)
                    {
                        while (true)
                        {
                            switch (
                                CopyableMessageBox.Show(
                                    Application.ProductName + " has detected some off-scale UV mappings.\n" +
                                    "This may mean your mapping is not stored as you intended.\n" +
                                    "This is often caused by UV-mapping too close to the edge of the map.\n\n" +
                                    "Click 'Commit' to commit the change or 'Cancel' to abandon.",
                                    Application.ProductName, CopyableMessageBoxIcon.Warning, new String[] { "C&ommit", "&View", "C&ancel", }, 0, 2))
                            {
                            case 0:     //commit
                                goto Commit;

                            case 1:     //view
                                System.Text.StringBuilder sb = new System.Text.StringBuilder();
                                offScales.ForEach(x => sb.AppendLine(x.ToString()));
                                CopyableMessageBox.Show(sb.ToString(),
                                                        Application.ProductName, CopyableMessageBoxButtons.OK, CopyableMessageBoxIcon.Information);
                                break;

                            default:     //cancel
                                Environment.ExitCode = 1;
                                return;
                            }
                        }
                    }

Commit:
                    result = (byte[])rcolResource.AsBytes.Clone();

                    Environment.ExitCode = 0;
                }
                catch (Exception ex)
                {
                    CopyableMessageBox.IssueException(ex, "Error processing " + Program.Filename);
                    throw ex;
                }
            }
            finally { this.Close(); }
        }
Пример #35
0
        //--


        public void Import_Mesh(StreamReader r, MLOD.Mesh mesh, GenericRCOLResource rcolResource, MLOD mlod, IResourceKey defaultRK, out meshExpImp.ModelBlocks.Vertex[] mverts, out List <meshExpImp.ModelBlocks.Vertex[]> lverts)
        {
            #region Import VRTF
            bool isDefaultVRTF  = false;
            VRTF defaultForMesh = VRTF.CreateDefaultForMesh(mesh);

            VRTF vrtf = new VRTF(rcolResource.RequestedApiVersion, null)
            {
                Version = 2, Layouts = null,
            };
            r.Import_VRTF(mpb, vrtf);

            IResourceKey vrtfRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.VertexFormatIndex);
            if (vrtfRK == null)
            {
                vrtfRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.SkinControllerIndex);
                if (vrtfRK == null)
                {
                    vrtfRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.ScaleOffsetIndex);
                }
                if (vrtfRK == null)
                {
                    vrtfRK = new TGIBlock(0, null, 0, 0,
                                          System.Security.Cryptography.FNV64.GetHash(DateTime.UtcNow.ToString() + defaultRK.ToString()));
                }
                vrtfRK = new TGIBlock(0, null, vrtfRK)
                {
                    ResourceType = vrtf.ResourceType,
                };
            }

            if (vrtf.Equals(defaultForMesh))
            {
                isDefaultVRTF          = true;
                mesh.VertexFormatIndex = new GenericRCOLResource.ChunkReference(0, null, 0);//Clear the reference
            }
            else
            {
                rcolResource.ReplaceChunk(mesh, "VertexFormatIndex", vrtfRK, vrtf);
            }
            #endregion

            #region Import SKIN
            // we need to read the data in the file...
            SKIN skin = new SKIN(rcolResource.RequestedApiVersion, null)
            {
                Version = 1, Bones = null,
            };
            r.Import_SKIN(mpb, skin);

            // However, we do *NOT* want to update the RCOL with what we read - we are not replacing the object skeleton here
#if UNDEF
            if (skin.Bones != null)
            {
                IResourceKey skinRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.SkinControllerIndex);
                if (skinRK == null)
                {
                    skinRK = new TGIBlock(0, null, vrtfRK)
                    {
                        ResourceType = skin.ResourceType,
                    }
                }
                ;

                rcolResource.ReplaceChunk(mesh, "SkinControllerIndex", skinRK, skin);
            }
#endif
            #endregion

            mverts = Import_VBUF_Main(r, mlod, mesh, vrtf, isDefaultVRTF);

            #region Import IBUF
            IBUF ibuf = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.IndexBufferIndex) as IBUF;
            if (ibuf == null)
            {
                ibuf = new IBUF(rcolResource.RequestedApiVersion, null)
                {
                    Version = 2, Flags = IBUF.FormatFlags.DifferencedIndices, DisplayListUsage = 0,
                }
            }
            ;
            Import_IBUF_Main(r, mlod, mesh, ibuf);

            IResourceKey ibufRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.IndexBufferIndex);
            if (ibufRK == null)
            {
                ibufRK = new TGIBlock(0, null, defaultRK)
                {
                    ResourceType = ibuf.ResourceType,
                }
            }
            ;

            rcolResource.ReplaceChunk(mesh, "IndexBufferIndex", ibufRK, ibuf);
            #endregion

            // This reads both VBUF Vertex[]s and the ibufs; but the ibufs just go straight in quite happily
            lverts = Import_MeshGeoStates(r, mlod, mesh, vrtf, isDefaultVRTF, ibuf);

            #region Update the JointReferences
            UIntList joints = CreateJointReferences(mesh, mverts, lverts ?? new List <meshExpImp.ModelBlocks.Vertex[]>(), skin);

            List <uint> added   = new List <uint>(joints);
            List <uint> removed = new List <uint>();
            foreach (var j in mesh.JointReferences)
            {
                if (joints.Contains(j))
                {
                    added.Remove(j);
                }
                else
                {
                    removed.Add(j);
                }
            }

            // Remove root
            removed.Remove(0xCD68F001);

            if (added.Count != 0)
            {
                mesh.JointReferences.AddRange(added);

                System.Windows.Forms.CopyableMessageBox.Show(String.Format("Mesh: 0x{0:X8}\nJointReferences with newly assigned (via BlendIndex) vertex: {1}\n({2})",
                                                                           mesh.Name,
                                                                           added.Count,
                                                                           String.Join(", ", added.ConvertAll <string>(a => "0x" + a.ToString("X8")).ToArray())),
                                                             "Warning", System.Windows.Forms.CopyableMessageBoxButtons.OK, System.Windows.Forms.CopyableMessageBoxIcon.Warning);
            }

// with the 20120601 change to export, this warning on import has lost its severity... and been dropped.
#if UNDEF
            if (removed.Count != 0)
            {
//#if UNDEF
                // http://dino.drealm.info/den/denforum/index.php?topic=394.msg3876#msg3876
                removed.ForEach(j => mesh.JointReferences[mesh.JointReferences.IndexOf(j)] = 0);
//#endif
                // However, OM felt more comfortable if there was some indication something a little odd was going on.
                System.Windows.Forms.CopyableMessageBox.Show(String.Format("Mesh: 0x{0:X8}\nJointReferences with no assigned (via BlendIndex) vertex: {1}\n({2})",
                                                                           mesh.Name,
                                                                           removed.Count,
                                                                           String.Join(", ", removed.ConvertAll <string>(a => "0x" + a.ToString("X8")).ToArray())),
                                                             "Warning", System.Windows.Forms.CopyableMessageBoxButtons.OK, System.Windows.Forms.CopyableMessageBoxIcon.Warning);
            }
#endif
            #endregion
        }

        meshExpImp.ModelBlocks.Vertex[] Import_VBUF_Main(StreamReader r, MLOD mlod, MLOD.Mesh mesh, VRTF vrtf, bool isDefaultVRTF)
        {
            string tagLine = r.ReadTag();

            string[] split = tagLine.Split(new char[] { ' ', }, StringSplitOptions.RemoveEmptyEntries);
            if (split.Length != 2)
            {
                throw new InvalidDataException("Invalid tag line read for 'vbuf'.");
            }
            if (split[0] != "vbuf")
            {
                throw new InvalidDataException("Expected line tag 'vbuf' not found.");
            }
            int count;

            if (!int.TryParse(split[1], out count))
            {
                throw new InvalidDataException("'vbuf' line has invalid count.");
            }

            return(r.Import_VBUF(mpb, count, vrtf));
        }

        void Import_IBUF_Main(StreamReader r, MLOD mlod, MLOD.Mesh mesh, IBUF ibuf)
        {
            string tagLine = r.ReadTag();

            string[] split = tagLine.Split(new char[] { ' ', }, StringSplitOptions.RemoveEmptyEntries);
            if (split.Length != 2)
            {
                throw new InvalidDataException("Invalid tag line read for 'ibuf'.");
            }
            if (split[0] != "ibuf")
            {
                throw new InvalidDataException("Expected line tag 'ibuf' not found.");
            }
            int count;

            if (!int.TryParse(split[1], out count))
            {
                throw new InvalidDataException("'ibuf' line has invalid count.");
            }

            ibuf.SetIndices(mlod, mesh, r.Import_IBUF(mpb, IBUF.IndexCountFromPrimitiveType(mesh.PrimitiveType), count));
        }

        List <meshExpImp.ModelBlocks.Vertex[]> Import_MeshGeoStates(StreamReader r, MLOD mlod, MLOD.Mesh mesh, VRTF vrtf, bool isDefaultVRTF, IBUF ibuf)
        {
            MLOD.GeometryStateList oldGeos = new MLOD.GeometryStateList(null, mesh.GeometryStates);
            r.Import_GEOS(mpb, mesh);
            if (mesh.GeometryStates.Count <= 0)
            {
                return(null);
            }

            List <meshExpImp.ModelBlocks.Vertex[]> lverts = new List <meshExpImp.ModelBlocks.Vertex[]>();

            for (int g = 0; g < mesh.GeometryStates.Count; g++)
            {
                lverts.Add(Import_VBUF_Geos(r, mlod, mesh, g, vrtf, isDefaultVRTF));
                Import_IBUF_Geos(r, mlod, mesh, g, ibuf);
            }
            return(lverts);
        }

        UIntList CreateJointReferences(MLOD.Mesh mesh, meshExpImp.ModelBlocks.Vertex[] mverts, List <meshExpImp.ModelBlocks.Vertex[]> lverts, SKIN skin)
        {
            if (skin == null || skin.Bones == null)
            {
                return(new UIntList(null));
            }

            int maxReference = -1;

            lverts.Insert(0, mverts);
            foreach (var vertices in lverts)
            {
                if (vertices != null)
                {
                    foreach (var vert in vertices)
                    {
                        if (vert.BlendIndices != null)
                        {
                            foreach (var reference in vert.BlendIndices)
                            {
                                if ((sbyte)reference > maxReference)
                                {
                                    maxReference = reference;
                                }
                            }
                        }
                    }
                }
            }
            lverts.Remove(mverts);

            return(maxReference > -1 ? new UIntList(null, skin.Bones.GetRange(0, maxReference + 1).ConvertAll <uint>(x => x.NameHash)) : new UIntList(null));
        }

        meshExpImp.ModelBlocks.Vertex[] Import_VBUF_Geos(StreamReader r, MLOD mlod, MLOD.Mesh mesh, int geoStateIndex, VRTF vrtf, bool isDefaultVRTF)
        {
            //w.WriteLine(string.Format("vbuf {0} {1} {2}", geoStateIndex, mesh.GeometryStates[geoStateIndex].MinVertexIndex, mesh.GeometryStates[geoStateIndex].VertexCount));
            string tagLine = r.ReadTag();

            string[] split = tagLine.Split(new char[] { ' ', }, StringSplitOptions.RemoveEmptyEntries);
            if (split.Length != 4)
            {
                throw new InvalidDataException(string.Format("Invalid tag line read for geoState {0} 'vbuf'.", geoStateIndex));
            }
            if (split[0] != "vbuf")
            {
                throw new InvalidDataException("Expected line tag 'vbuf' not found.");
            }
            int lineIndex;

            if (!int.TryParse(split[1], out lineIndex))
            {
                throw new InvalidDataException(string.Format("geoState {0} 'vbuf' line has invalid geoStateIndex.", geoStateIndex));
            }
            if (lineIndex != geoStateIndex)
            {
                throw new InvalidDataException(string.Format("geoState {0} 'vbuf' line has incorrect geoStateIndex value {1}.", geoStateIndex, lineIndex));
            }
            int minVertexIndex;

            if (!int.TryParse(split[2], out minVertexIndex))
            {
                throw new InvalidDataException(string.Format("geoState {0} 'vbuf' line has invalid MinVertexIndex.", geoStateIndex));
            }
            int vertexCount;

            if (!int.TryParse(split[3], out vertexCount))
            {
                throw new InvalidDataException(string.Format("geoState {0} 'vbuf' line has invalid VertexCount.", geoStateIndex));
            }

            if (minVertexIndex + vertexCount <= mesh.MinVertexIndex + mesh.VertexCount)
            {
                mesh.GeometryStates[geoStateIndex].MinVertexIndex = minVertexIndex;
                mesh.GeometryStates[geoStateIndex].VertexCount    = vertexCount;
                return(null);
            }

            if (minVertexIndex != mesh.GeometryStates[geoStateIndex].MinVertexIndex)
            {
                throw new InvalidDataException(string.Format("geoState {0} 'vbuf' line has unexpected MinVertexIndex {1}; expected {2}.", geoStateIndex, minVertexIndex, mesh.GeometryStates[geoStateIndex].MinVertexIndex));
            }
            return(r.Import_VBUF(mpb, vertexCount, vrtf));
        }

        void Import_IBUF_Geos(StreamReader r, MLOD mlod, MLOD.Mesh mesh, int geoStateIndex, IBUF ibuf)
        {
            //w.WriteLine(string.Format("ibuf {0} {1} {2}", geoStateIndex, mesh.GeometryStates[geoStateIndex].StartIndex, mesh.GeometryStates[geoStateIndex].PrimitiveCount));
            string tagLine = r.ReadTag();

            string[] split = tagLine.Split(new char[] { ' ', }, StringSplitOptions.RemoveEmptyEntries);
            if (split.Length != 4)
            {
                throw new InvalidDataException("Invalid tag line read for 'ibuf'.");
            }
            if (split[0] != "ibuf")
            {
                throw new InvalidDataException("Expected line tag 'ibuf' not found.");
            }
            int lineIndex;

            if (!int.TryParse(split[1], out lineIndex))
            {
                throw new InvalidDataException(string.Format("geoState {0} 'ibuf' line has invalid geoStateIndex.", geoStateIndex));
            }
            if (lineIndex != geoStateIndex)
            {
                throw new InvalidDataException(string.Format("geoState {0} 'ibuf' line has incorrect geoStateIndex value {1}.", geoStateIndex, lineIndex));
            }
            int startIndex;

            if (!int.TryParse(split[2], out startIndex))
            {
                throw new InvalidDataException(string.Format("geoState {0} 'ibuf' line has invalid StartIndex.", geoStateIndex));
            }
            int primitiveCount;

            if (!int.TryParse(split[3], out primitiveCount))
            {
                throw new InvalidDataException(string.Format("geoState {0} 'ibuf' line has invalid PrimitiveCount.", geoStateIndex));
            }

            int sizePerPrimitive = IBUF.IndexCountFromPrimitiveType(mesh.PrimitiveType);

            if (startIndex + primitiveCount * sizePerPrimitive <= mesh.StartIndex + mesh.PrimitiveCount * sizePerPrimitive)
            {
                mesh.GeometryStates[geoStateIndex].StartIndex     = startIndex;
                mesh.GeometryStates[geoStateIndex].PrimitiveCount = primitiveCount;
                return;
            }

            if (startIndex != mesh.GeometryStates[geoStateIndex].StartIndex)
            {
                throw new InvalidDataException(string.Format("geoState {0} 'ibuf' line has unexpected StartIndex {1}; expected {2}.", geoStateIndex, startIndex, mesh.GeometryStates[geoStateIndex].StartIndex));
            }
            ibuf.SetIndices(mlod, mesh, geoStateIndex, r.Import_IBUF(mpb, IBUF.IndexCountFromPrimitiveType(mesh.PrimitiveType), primitiveCount));
        }
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (String.IsNullOrEmpty(value as string))
            {
                return null;
            }

            var path = value as string;
            if (path != null && File.Exists(path))
            {
                using (FileStream s = File.OpenRead(path))
                {
                    var rcol = new GenericRCOLResource(0, s);
                    MLOD mlod = rcol.ChunkEntries
                        .Where(x => x.RCOLBlock is MLOD)
                        .Select(x => x.RCOLBlock)
                        .Cast<MLOD>()
                        .FirstOrDefault();

                    double minX = double.MaxValue, minZ = double.MaxValue, maxX = double.MinValue, maxZ = double.MinValue;

                    var pnty = new List<Point[]>();
                    foreach (MLOD.Mesh mesh in mlod.Meshes)
                    {
                        var vbuf = GenericRCOLResource.ChunkReference.GetBlock(rcol, mesh.VertexBufferIndex) as VBUF;
                        var ibuf = GenericRCOLResource.ChunkReference.GetBlock(rcol, mesh.IndexBufferIndex) as IBUF;
                        var vrtf = GenericRCOLResource.ChunkReference.GetBlock(rcol, mesh.VertexFormatIndex) as VRTF;
                        if (vrtf == null)
                            continue;
                        Vertex[] verts = vbuf.GetVertices(mesh, vrtf, null);
                        int[] indices = ibuf.GetIndices(mesh);
                        for (int i = 0; i < indices.Length/3; i++)
                        {
                            var tst = new int[3];
                            var poly = new Point[3];
                            for (int j = 0; j < 3; j++)
                            {
                                Vertex vert = verts[indices[i*3 + j]];
                                double x = (Offset + (vert.Position[0]*Scale));
                                double z = -(Offset + (vert.Position[2]*Scale));
                                poly[j] = new Point((int) x, (int) z);
                                if (poly[j].X > maxX)
                                    maxX = poly[j].X;

                                if (poly[j].X < minX)
                                    minX = poly[j].X;

                                if (poly[j].Y > maxZ)
                                    maxZ = poly[j].Y;

                                if (poly[j].Y < minZ)
                                    minZ = poly[j].Y;
                            }
                            pnty.Add(poly);
                        }
                    }
                    var width = (int) (maxX - minX);
                    var height = (int) (maxZ - minZ);
                    var bmp = new Bitmap(width, height);
                    Graphics gBmp = Graphics.FromImage(bmp);
                    gBmp.CompositingMode = CompositingMode.SourceCopy;
                    float bright = 1.1f;
                    System.Drawing.Color c = System.Drawing.Color.FromArgb(255, Fill.R, Fill.G, Fill.B);
                    System.Drawing.Color c2 = System.Drawing.Color.FromArgb(255, Stroke.R, Stroke.G, Stroke.B);

                    var b = new SolidBrush(c);

                    var b2 = new SolidBrush(c2);
                    var pen = new Pen(b2);
                    foreach (Point[] pointse in pnty)
                    {
                        Point[] scaled = pointse.Select(old => new Point((int) (old.X - minX), (int) (old.Y - minZ))).ToArray();
                        gBmp.FillPolygon(b, scaled);
                    }
                    foreach (Point[] pointse in pnty)
                    {
                        Point[] scaled = pointse.Select(old => new Point((int) (old.X - minX), (int) (old.Y - minZ))).ToArray();
                        gBmp.DrawPolygon(pen, scaled);
                    }
                    var bmpImg = new BitmapImage();

                    var ms = new MemoryStream();

                    bmp.Save(ms, ImageFormat.Png);
                    ms.Position = 0L;
                    bmpImg.BeginInit();
                    bmpImg.StreamSource = ms;
                    bmpImg.EndInit();
                    return bmpImg;
                }
            }
            return null;
        }
Пример #37
0
        private List <IResourceConnection> MATD_GetDiffuseSpecular()
        {
            string rootStr = this.GetContentPathRootName();
            List <IResourceConnection> results = new List <IResourceConnection>();
            GenericRCOLResource        rcol    = base.Resource as GenericRCOLResource;

            if (rcol == null)
            {
                return(results);
            }
            string absolutePath, absoluteName;

            Diagnostics.Log("MATD_GetDiffuseSpecular: " +
                            ResourceGraph.PrintRKTag(base.originalKey, rootStr));
            for (int i = 0; i < rcol.ChunkEntries.Count; i++)
            {
                MATD matd = rcol.ChunkEntries[i].RCOLBlock as MATD;
                if (matd == null)
                {
                    continue;
                }

                ShaderDataList sdataList;
                if (matd.ContentFields.Contains("Mtnf"))
                {
                    sdataList    = matd.Mtnf.SData;
                    absolutePath = rootStr + ".ChunkEntries[" + i + "].RCOLBlock.Mtnf.SData[";
                }
                else
                {
                    sdataList    = matd.Mtrl.SData;
                    absolutePath = rootStr + ".ChunkEntries[" + i + "].RCOLBlock.Mtrl.SData[";
                }

                for (int j = 0; j < sdataList.Count; j++)
                {
                    ElementTextureRef texRef = sdataList[i] as ElementTextureRef;
                    if (texRef != null && IsWantedImage(texRef.Field))
                    {
                        TGIBlock tgiblock = rcol.Resources[texRef.Data.TGIBlockIndex];
                        if (ResourceGraph.IsDDS(tgiblock.ResourceType))
                        {
                            absoluteName = rootStr + ".Resources[" + texRef.Data.TGIBlockIndex + "]";
                            results.Add(new DefaultConnection(tgiblock, tgiblock,
                                                              ResourceDataActions.FindWrite, absoluteName));
                        }
                    }
                    else
                    {
                        ElementTextureKey texKey = sdataList[i] as ElementTextureKey;
                        if (texKey != null && IsWantedImage(texKey.Field))
                        {
                            if (ResourceGraph.IsDDS(texKey.Data.ResourceType))
                            {
                                absoluteName = absolutePath + j + "].Data";
                                results.Add(new DefaultConnection(texKey.Data, texKey,
                                                                  ResourceDataActions.FindWrite, absoluteName, rootStr + ".Data"));
                            }
                        }
                    }
                }
            }
            return(results);
        }
Пример #38
0
        protected List <IResourceConnection> SlurpAllRKs()
        {
            List <IResourceConnection> results = new List <IResourceConnection>();
            string rootStr = this.GetContentPathRootName();

            if (!RKContainer.IsLegalFieldName(rootStr))
            {
                Diagnostics.Log("Illegal Root Field Name for "
                                + ResourceGraph.PrintRK(base.originalKey) + ":" + rootStr);
                rootStr = "root";
            }
            if (base.resource is GenericRCOLResource)
            {
                Diagnostics.Log("Slurping RCOL Resource RKs for "
                                + rootStr + ":" + ResourceGraph.PrintRK(base.originalKey));
                GenericRCOLResource rcol = base.resource as GenericRCOLResource;
                TGIBlock            tgiBlock;
                int i, count = rcol.Resources.Count;
                for (i = 0; i < count; i++)
                {
                    tgiBlock = rcol.Resources[i];
                    if (includeDDSes || !ResourceGraph.IsDDS(tgiBlock.ResourceType))
                    {
                        results.Add(new DefaultConnection(tgiBlock, tgiBlock,
                                                          ResourceDataActions.FindWrite, rootStr + ".Resources[" + i + "]"));
                    }
                }
                Diagnostics.Log("Slurping RCOL ChunkEntry RKs for "
                                + rootStr + ":" + ResourceGraph.PrintRK(base.originalKey));
                string absolutePath;
                GenericRCOLResource.ChunkEntry chunk;
                count = rcol.ChunkEntries.Count;
                for (i = 0; i < count; i++)
                {
                    absolutePath = rootStr + ".ChunkEntries[" + i + "].RCOLBlock";
                    chunk        = rcol.ChunkEntries[i];
                    tgiBlock     = chunk.TGIBlock;
                    switch (GetChunkType(tgiBlock))
                    {
                    case ChunkEntryType.Kindred:
                        this.kindredRCOLChunkKeys.Add(tgiBlock);
                        results.AddRange(RKContainer.SlurpRKsFromField(absolutePath,
                                                                       chunk.RCOLBlock, this.rkContainers, this.ICanSlurpRK));
                        break;

                    case ChunkEntryType.Internal:
                        results.AddRange(RKContainer.SlurpRKsFromField(absolutePath,
                                                                       chunk.RCOLBlock, this.rkContainers, this.ICanSlurpRK));
                        break;

                    case ChunkEntryType.Unique:
                        results.Add(new DefaultConnection(tgiBlock,
                                                          chunk.RCOLBlock, ResourceDataActions.None, absolutePath));
                        break;
                    }
                }
            }
            else if (base.resource is AApiVersionedFields)
            {
                Diagnostics.Log("Slurping RKs for "
                                + rootStr + ":" + ResourceGraph.PrintRK(base.originalKey));
                results.AddRange(RKContainer.SlurpRKsFromField(rootStr,
                                                               base.resource as AApiVersionedFields,
                                                               this.rkContainers, this.ICanSlurpRK));
            }
            return(results);
        }
Пример #39
0
        //--


        public void Import_Mesh(StreamReader r, MLOD.Mesh mesh, GenericRCOLResource rcolResource, MLOD mlod, IResourceKey defaultRK, out meshExpImp.ModelBlocks.Vertex[] mverts)
        {
            #region Import VRTF
            bool isDefaultVRTF = false;
            VRTF defaultForMesh = VRTF.CreateDefaultForMesh(mesh);

            VRTF vrtf = new VRTF(rcolResource.RequestedApiVersion, null) { Version = 2, Layouts = null, };
            r.Import_VRTF(mpb, vrtf);

            IResourceKey vrtfRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.VertexFormatIndex);
            if (vrtfRK == null)
            {
                vrtfRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.SkinControllerIndex);
                if (vrtfRK == null) vrtfRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.ScaleOffsetIndex);
                if (vrtfRK == null) vrtfRK = new TGIBlock(0, null, 0, 0,
                    System.Security.Cryptography.FNV64.GetHash(DateTime.UtcNow.ToString() + defaultRK.ToString()));
                vrtfRK = new TGIBlock(0, null, vrtfRK) { ResourceType = vrtf.ResourceType, };
            }

            if (vrtf.Equals(defaultForMesh))
            {
                isDefaultVRTF = true;
                mesh.VertexFormatIndex = new GenericRCOLResource.ChunkReference(0, null, 0);//Clear the reference
            }
            else
                rcolResource.ReplaceChunk(mesh, "VertexFormatIndex", vrtfRK, vrtf);
            #endregion

            #region Import SKIN
            // we need to read the data in the file...
            SKIN skin = new SKIN(rcolResource.RequestedApiVersion, null) { Version = 1, Bones = null, };
            r.Import_SKIN(mpb, skin);

            // However, we do *NOT* want to update the RCOL with what we read - we are not replacing the object skeleton here
#if UNDEF
            if (skin.Bones != null)
            {
                IResourceKey skinRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.SkinControllerIndex);
                if (skinRK == null)
                    skinRK = new TGIBlock(0, null, vrtfRK) { ResourceType = skin.ResourceType, };

                rcolResource.ReplaceChunk(mesh, "SkinControllerIndex", skinRK, skin);
            }
#endif
            #endregion

            mverts = Import_VBUF_Main(r, mlod, mesh, vrtf, isDefaultVRTF);

            #region Import IBUF
            IBUF ibuf = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mesh.IndexBufferIndex) as IBUF;
            if (ibuf == null)
                ibuf = new IBUF(rcolResource.RequestedApiVersion, null) { Version = 2, Flags = IBUF.FormatFlags.DifferencedIndices, DisplayListUsage = 0, };
            Import_IBUF_Main(r, mlod, mesh, ibuf);

            IResourceKey ibufRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mesh.IndexBufferIndex);
            if (ibufRK == null)
                ibufRK = new TGIBlock(0, null, defaultRK) { ResourceType = ibuf.ResourceType, };

            rcolResource.ReplaceChunk(mesh, "IndexBufferIndex", ibufRK, ibuf);
            #endregion

            #region Update the JointReferences
            UIntList joints = CreateJointReferences(mesh, mverts, skin);

            List<uint> added = new List<uint>(joints);
            List<uint> removed = new List<uint>();
            foreach (var j in mesh.JointReferences)
            {
                if (joints.Contains(j)) added.Remove(j);
                else removed.Add(j);
            }

            // Remove root
            removed.Remove(0xCD68F001);

            if (added.Count != 0)
            {
                mesh.JointReferences.AddRange(added);

                System.Windows.Forms.CopyableMessageBox.Show(String.Format("Mesh: 0x{0:X8}\nJointReferences with newly assigned (via BlendIndex) vertex: {1}\n({2})",
                    mesh.Name,
                    added.Count,
                    String.Join(", ", added.ConvertAll<string>(a => "0x" + a.ToString("X8")).ToArray())),
                    "Warning", System.Windows.Forms.CopyableMessageBoxButtons.OK, System.Windows.Forms.CopyableMessageBoxIcon.Warning);
            }

            // with the 20120601 change to export, this warning on import has lost its severity... and been dropped.
#if UNDEF
            if (removed.Count != 0)
            {
//#if UNDEF
                // http://dino.drealm.info/den/denforum/index.php?topic=394.msg3876#msg3876
                removed.ForEach(j => mesh.JointReferences[mesh.JointReferences.IndexOf(j)] = 0);
//#endif
                // However, OM felt more comfortable if there was some indication something a little odd was going on.
                System.Windows.Forms.CopyableMessageBox.Show(String.Format("Mesh: 0x{0:X8}\nJointReferences with no assigned (via BlendIndex) vertex: {1}\n({2})",
                    mesh.Name,
                    removed.Count,
                    String.Join(", ", removed.ConvertAll<string>(a => "0x" + a.ToString("X8")).ToArray())),
                    "Warning", System.Windows.Forms.CopyableMessageBoxButtons.OK, System.Windows.Forms.CopyableMessageBoxIcon.Warning);
            }
#endif
            #endregion
        }
Пример #40
0
        private void Export_Shown(object sender, EventArgs e)
        {
            try
            {
                sfdExport.Title += " -- Test version " + typeof(ExportForm).Assembly.GetName().Version.ToString();
                DialogResult dr = sfdExport.ShowDialog();
                if (dr != DialogResult.OK)
                {
                    Environment.ExitCode = 1;
                    return;
                }

                string folder   = Path.GetDirectoryName(sfdExport.FileName);
                string filebase = Path.GetFileNameWithoutExtension(sfdExport.FileName).Replace("_filebase", "");

                try
                {
                    using (FileStream fs = new FileStream(Path.Combine(folder, string.Format("{0}_filebase.s3asc", filebase)), FileMode.Create, FileAccess.Write))
                    {
                        fs.Close();
                    }

                    GenericRCOLResource rcolResource = new GenericRCOLResource(0, stream);
                    MLOD mlod = null;

                    if (rcolResource.ChunkEntries[0].TGIBlock.ResourceType == 0x01661233)//MODL
                    {
                        this.Text = "Export MODL...";
                        var lodRef = rcolResource.GetMLODChunkRefforMODL();
                        if (lodRef == null)
                        {
                            CopyableMessageBox.Show("MODL (0x01661233) with no MLOD (0x01D10F34).",
                                                    "Invalid MODL resource", CopyableMessageBoxButtons.OK, CopyableMessageBoxIcon.Error);
                            Environment.ExitCode = 1;
                            return;
                        }


                        mlod = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, lodRef) as MLOD;
                    }
                    else if (rcolResource.ChunkEntries[0].TGIBlock.ResourceType == 0x01D10F34)//MLOD
                    {
                        this.Text = "Export MLOD...";

                        mlod = rcolResource.ChunkEntries[0].RCOLBlock as MLOD;
                    }
                    else
                    {
                        CopyableMessageBox.Show("RCOL resource must be MODL (0x01661233) or MLOD (0x01D10F34).",
                                                "Invalid RCOL resource", CopyableMessageBoxButtons.OK, CopyableMessageBoxIcon.Error);
                        Environment.ExitCode = 1;
                        return;
                    }

                    Export export = new Export(new MyProgressBar(label1, pb));

                    for (int m = 0; m < mlod.Meshes.Count; m++)
                    {
                        string fnMesh = Path.Combine(folder, string.Format("{0}_group{1:D2}.s3ascg", filebase, m));

                        using (FileStream fsMesh = new FileStream(fnMesh, FileMode.Create, FileAccess.Write))
                        {
                            export.Export_MLOD(new StreamWriter(fsMesh), rcolResource, mlod, mlod.Meshes[m]);
                            fsMesh.Close();
                        }
                    }

                    Environment.ExitCode = 0;
                }
                catch (Exception ex)
                {
                    CopyableMessageBox.IssueException(ex, "Error processing " + Program.Filename);
                    throw ex;
                }
            }
            finally { this.Close(); }
        }
Пример #41
0
        public FootprintEditorViewModel(GenericRCOLResource rcol)
        {
            mRcol           = rcol;
            mFootprint      = rcol.ChunkEntries[0].RCOLBlock as FTPT;
            mFootprintAreas = new ObservableCollection <AreaViewModel>(mFootprint.FootprintAreas.Select(x => new AreaViewModel(this, x)));
            mSlotAreas      = new ObservableCollection <AreaViewModel>(mFootprint.SlotAreas.Select(x => new AreaViewModel(this, x)));

            AddSlotCommand    = new UserCommand <FootprintEditorViewModel>(x => x != null, x => x.AddSlotArea());
            CloneSlotCommand  = new UserCommand <FootprintEditorViewModel>(x => x != null && x.CheckSlotArea(), x => x.CopySlotArea());
            DeleteSlotCommand = new UserCommand <FootprintEditorViewModel>(x => x != null && x.CheckSlotArea(), x => x.DeleteArea());


            AddFootprintCommand    = new UserCommand <FootprintEditorViewModel>(x => x != null, x => x.AddFootprintArea());
            CloneFootprintCommand  = new UserCommand <FootprintEditorViewModel>(x => x != null && x.CheckFootprintArea(), x => x.CopyFootprintArea());
            DeleteFootprintCommand = new UserCommand <FootprintEditorViewModel>(x => x != null && x.CheckFootprintArea(), x => x.DeleteArea());


            CommitCommand = new UserCommand <FootprintEditorViewModel>(x => true, y =>
            {
                mIsSaving = true;
                Application.Current.Shutdown();
            });
            CancelCommand = new UserCommand <FootprintEditorViewModel>(x => true, y =>
            {
                mIsSaving = false;
                Application.Current.Shutdown();
            });


            SetBackgroundImageCommand = new UserCommand <FootprintEditorViewModel>(
                x => true,
                y =>
            {
                var d = new OpenFileDialog {
                    CheckFileExists = true, Multiselect = false
                };
                if (d.ShowDialog() == true)
                {
                    BackgroundImagePath = d.FileName;
                }
            }
                );
            ClearBackgroundImageCommand = new UserCommand <FootprintEditorViewModel>(
                x => x != null && !String.IsNullOrEmpty(x.BackgroundImagePath),
                y => y.BackgroundImagePath = null
                );
            SetReferenceMeshCommand = new UserCommand <FootprintEditorViewModel>(
                x => true,
                y =>
            {
                var d = new OpenFileDialog {
                    CheckFileExists = true, Multiselect = false
                };
                if (d.ShowDialog() == true)
                {
                    ReferenceMesh = d.FileName;
                }
            }
                );
            ClearReferenceMeshCommand = new UserCommand <FootprintEditorViewModel>(
                x => x != null && !String.IsNullOrEmpty(x.ReferenceMesh),
                y => y.ReferenceMesh = null
                );
            SelectedFootprint = FootprintAreas.FirstOrDefault();
            if (SelectedArea == null)
            {
                SelectedSlot = SlotAreas.FirstOrDefault();
            }
        }
Пример #42
0
        public List <offScale> VertsToVBUFs(GenericRCOLResource rcolResource, MLOD mlod, IResourceKey defaultRK, List <meshExpImp.ModelBlocks.Vertex[]> lmverts, List <List <meshExpImp.ModelBlocks.Vertex[]> > llverts, bool updateBBs, bool updateUVs)
        {
            // List of UV elements going off scale
            List <offScale> offScales = new List <offScale>();

            // Find everything for each mesh group
            Dictionary <GenericRCOLResource.ChunkReference, List <int> > meshGroups = new Dictionary <GenericRCOLResource.ChunkReference, List <int> >();
            Dictionary <int, VRTF>    meshVRTF     = new Dictionary <int, VRTF>();
            Dictionary <int, float[]> meshUVScales = new Dictionary <int, float[]>();

            for (int m = 0; m < mlod.Meshes.Count; m++)
            {
                if (meshGroups.ContainsKey(mlod.Meshes[m].MaterialIndex))
                {
                    meshGroups[mlod.Meshes[m].MaterialIndex].Add(m);
                }
                else
                {
                    meshGroups.Add(mlod.Meshes[m].MaterialIndex, new List <int> {
                        m
                    });
                }
                VRTF vrtf = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mlod.Meshes[m].VertexFormatIndex) as VRTF ?? VRTF.CreateDefaultForMesh(mlod.Meshes[m]);
                meshVRTF.Add(m, vrtf);

                if (updateUVs)
                {
                    rcolResource.FixUVScales(mlod.Meshes[m]);
                }
                meshUVScales.Add(m, rcolResource.GetUVScales(mlod.Meshes[m]));
            }

            // Update the VBUFs for each mesh group and set the mesh bounds whilst we're here
            foreach (var key in meshGroups.Keys)
            {
                foreach (int m in meshGroups[key])
                {
                    VBUF vbuf = GenericRCOLResource.ChunkReference.GetBlock(rcolResource, mlod.Meshes[m].VertexBufferIndex) as VBUF;
                    if (vbuf == null)
                    {
                        vbuf = new VBUF(rcolResource.RequestedApiVersion, null)
                        {
                            Version = 0x00000101, Flags = VBUF.FormatFlags.None, SwizzleInfo = new GenericRCOLResource.ChunkReference(0, null, 0),
                        }
                    }
                    ;

                    offScales.AddRange(getOffScales(m, -1, lmverts[m], meshUVScales[m]));
                    vbuf.SetVertices(mlod, m, meshVRTF[m], lmverts[m], meshUVScales[m]);

                    if (llverts[m] != null)
                    {
                        for (int g = 0; g < llverts[m].Count; g++)
                        {
                            if (llverts[m][g] != null)
                            {
                                offScales.AddRange(getOffScales(m, g, llverts[m][g], meshUVScales[m]));
                                vbuf.SetVertices(mlod, mlod.Meshes[m], g, meshVRTF[m], llverts[m][g], meshUVScales[m]);
                            }
                        }
                    }

                    IResourceKey vbufRK = GenericRCOLResource.ChunkReference.GetKey(rcolResource, mlod.Meshes[m].VertexBufferIndex);
                    if (vbufRK == null)//means we created the VBUF: create a RK and add it
                    {
                        vbufRK = new TGIBlock(0, null, defaultRK)
                        {
                            ResourceType = vbuf.ResourceType,
                        }
                    }
                    ;

                    rcolResource.ReplaceChunk(mlod.Meshes[m], "VertexBufferIndex", vbufRK, vbuf);

                    if (updateBBs)
                    {
                        mlod.Meshes[m].Bounds = vbuf.GetBoundingBox(mlod.Meshes[m], meshVRTF[m]);
                    }
                }
            }

            return(offScales);
        }
Пример #43
0
        public StateMachine(GenericRCOLResource jazzResource)
            : this("")
        {
            if (jazzResource == null)
            {
                throw new ArgumentNullException("jazzResource");
            }
            GenericRCOLResource.ChunkEntryList chunkEntries
                = jazzResource.ChunkEntries;
            if (chunkEntries == null || chunkEntries.Count == 0)
            {
                throw new ArgumentException(
                    "RCOL Resource is empty", "jazzResource");
            }
            KeyNameReg.RefreshKeyNameMaps();
            uint hash;
            string name;
            int i, j, index = -1;
            State state;
            ActorDefinition ad;
            ParamDefinition pd;
            DecisionGraphNode dgn;
            JazzStateMachine jazzSM = null;
            GenericRCOLResource.ChunkEntry ce;
            AChunkObject[] chunks = new AChunkObject[chunkEntries.Count];
            List<ActorDefinition> actorDefs = new List<ActorDefinition>();
            List<ParamDefinition> paramDefs = new List<ParamDefinition>();

            #region Phase 1: Instantiate Chunks and Copy over value fields
            for (i = 0; i < chunkEntries.Count; i++)
            {
                ce = chunkEntries[i];
                hash = ce.TGIBlock.ResourceType;
                switch (hash)
                {
                    case PlayAnimationNode.ResourceType:
                        JazzPlayAnimationNode jpan
                            = ce.RCOLBlock as JazzPlayAnimationNode;
                        PlayAnimationNode lan = new PlayAnimationNode();
                        lan.ClipKey = new RK(jpan.ClipResource);
                        lan.TrackMaskKey = new RK(jpan.TkmkResource);
                        // lan.SlotSetup copied over later
                        lan.AdditiveClipKey
                            = new RK(jpan.AdditiveClipResource);
                        lan.ClipPattern = jpan.Animation;
                        lan.AdditiveClipPattern = jpan.AdditiveAnimation;
                        lan.Flags = jpan.AnimationNodeFlags;
                        lan.Priority = jpan.AnimationPriority1;
                        lan.BlendInTime = jpan.BlendInTime;
                        lan.BlendOutTime = jpan.BlendOutTime;
                        lan.Speed = jpan.Speed;
                        // lan.Actor set later
                        lan.TimingPriority = jpan.TimingPriority;
                        chunks[i] = lan;
                        break;
                    case StopAnimationNode.ResourceType:
                        JazzStopAnimationNode jsan
                            = ce.RCOLBlock as JazzStopAnimationNode;
                        StopAnimationNode san = new StopAnimationNode();
                        san.Flags = jsan.AnimationFlags;
                        san.Priority = jsan.AnimationPriority1;
                        san.BlendInTime = jsan.BlendInTime;
                        san.BlendOutTime = jsan.BlendOutTime;
                        san.Speed = jsan.Speed;
                        // san.Actor set later
                        san.TimingPriority = jsan.TimingPriority;
                        chunks[i] = san;
                        break;
                    case ActorOperationNode.ResourceType:
                        JazzActorOperationNode jaon
                            = ce.RCOLBlock as JazzActorOperationNode;
                        ActorOperationNode aon
                            = new ActorOperationNode(jaon.ActorOp);
                        // aon.Target set later
                        aon.Operand = jaon.Operand != 0;
                        chunks[i] = aon;
                        break;
                    case CreatePropNode.ResourceType:
                        JazzCreatePropNode jcpn
                            = ce.RCOLBlock as JazzCreatePropNode;
                        CreatePropNode cpn = new CreatePropNode();
                        // cpn.PropActor set later
                        // cpn.PropParameter set later
                        cpn.PropKey = new RK(jcpn.PropResource);
                        chunks[i] = cpn;
                        break;
                    case RandomNode.ResourceType:
                        JazzRandomNode jrand
                            = ce.RCOLBlock as JazzRandomNode;
                        RandomNode rand = new RandomNode();
                        // rand.Slices set later
                        rand.Flags = jrand.Properties;
                        chunks[i] = rand;
                        break;
                    case SelectOnParameterNode.ResourceType:
                        // sopn.Parameter set later
                        // sopn.Cases set later
                        chunks[i] = new SelectOnParameterNode();
                        break;
                    case SelectOnDestinationNode.ResourceType:
                        // sodn.Cases set later
                        chunks[i] = new SelectOnDestinationNode();
                        break;
                    case NextStateNode.ResourceType:
                        // nsn.NextState set later
                        chunks[i] = new NextStateNode();
                        break;
                    case DecisionGraph.ResourceType:
                        // dg.State set later
                        // dg.DecisionMakers set later
                        // dg.EntryPoints set later
                        chunks[i] = new DecisionGraph();
                        break;
                    case State.ResourceType:
                        JazzState js = ce.RCOLBlock as JazzState;
                        hash = js.NameHash;
                        if (!KeyNameReg.TryFindName(hash, out name))
                            name = KeyNameReg.UnhashName(hash);
                        state = new State(name);
                        state.Flags = js.Properties;
                        // state.DecisionGraph set later
                        // state.Transitions set later
                        state.AwarenessOverlayLevel
                            = js.AwarenessOverlayLevel;
                        chunks[i] = state;
                        break;
                    case ParamDefinition.ResourceType:
                        JazzParameterDefinition jpd
                            = ce.RCOLBlock as JazzParameterDefinition;
                        hash = jpd.NameHash;
                        if (!KeyNameReg.TryFindName(hash, out name))
                            name = KeyNameReg.UnhashName(hash);
                        pd = new ParamDefinition(name);

                        hash = jpd.DefaultValue;
                        if (!KeyNameReg.TryFindName(hash, out name))
                            name = KeyNameReg.UnhashName(hash);
                        pd.DefaultValue = name;
                        chunks[i] = pd;
                        paramDefs.Add(pd);
                        break;
                    case ActorDefinition.ResourceType:
                        JazzActorDefinition jad
                            = ce.RCOLBlock as JazzActorDefinition;
                        hash = jad.NameHash;
                        if (!KeyNameReg.TryFindName(hash, out name))
                            name = KeyNameReg.UnhashName(hash);
                        ad = new ActorDefinition(name);
                        chunks[i] = ad;
                        actorDefs.Add(ad);
                        break;
                    case StateMachine.ResourceType:
                        if (index != -1)
                        {
                            throw new Exception(
                                "More than one State Machine in RCOL");
                        }
                        index = i;
                        jazzSM = ce.RCOLBlock as JazzStateMachine;
                        hash = jazzSM.NameHash;
                        if (hash == 0)
                        {
                            name = null;
                            this.bNameIsHash = true;
                        }
                        else if (!KeyNameReg.TryFindName(hash, out name))
                        {
                            name = KeyNameReg.UnhashName(hash);
                            this.bNameIsHash = true;
                        }
                        else
                        {
                            this.bNameIsHash = false;
                        }
                        this.mName = name;
                        this.mNameHash = hash;
                        // this.mActorDefinitions set later
                        // this.mParameterDefinitions set later
                        // this.mStates set later
                        this.mFlags = jazzSM.Properties;
                        this.mDefaultPriority = jazzSM.AutomationPriority;
                        this.mAwarenessOverlayLevel
                            = jazzSM.AwarenessOverlayLevel;
                        chunks[i] = this;
                        break;
                }
            }
            if (index == -1)
            {
                throw new Exception("RCOL does not contain a Jazz Graph");
            }
            #endregion

            #region Phase 2: Copy over fields referencing other chunks
            for (i = 0; i < chunkEntries.Count; i++)
            {
                ce = chunkEntries[i];
                switch (ce.TGIBlock.ResourceType)
                {
                    case PlayAnimationNode.ResourceType:
                        JazzPlayAnimationNode jpan
                            = ce.RCOLBlock as JazzPlayAnimationNode;
                        PlayAnimationNode lan
                            = chunks[i] as PlayAnimationNode;
                        index = jpan.ActorDefinitionIndex.TGIBlockIndex;
                        lan.Actor = index < 0
                            ? null : chunks[index + 1] as ActorDefinition;
                        break;
                    case StopAnimationNode.ResourceType:
                        JazzStopAnimationNode jsan
                            = ce.RCOLBlock as JazzStopAnimationNode;
                        StopAnimationNode san
                            = chunks[i] as StopAnimationNode;
                        index = jsan.ActorDefinitionIndex.TGIBlockIndex;
                        san.Actor = index < 0
                            ? null : chunks[index + 1] as ActorDefinition;
                        break;
                    case ActorOperationNode.ResourceType:
                        JazzActorOperationNode jaon
                            = ce.RCOLBlock as JazzActorOperationNode;
                        ActorOperationNode aon
                            = chunks[i] as ActorOperationNode;
                        index = jaon.ActorDefinitionIndex.TGIBlockIndex;
                        aon.Actor = index < 0
                            ? null : chunks[index + 1] as ActorDefinition;
                        break;
                    case CreatePropNode.ResourceType:
                        JazzCreatePropNode jcpn
                            = ce.RCOLBlock as JazzCreatePropNode;
                        CreatePropNode cpn = chunks[i] as CreatePropNode;
                        index = jcpn.ActorDefinitionIndex.TGIBlockIndex;
                        cpn.PropActor = index < 0
                            ? null : chunks[index + 1] as ActorDefinition;
                        index = jcpn.ParameterDefinitionIndex.TGIBlockIndex;
                        cpn.PropParam = index < 0
                            ? null : chunks[index + 1] as ParamDefinition;
                        break;
                    case RandomNode.ResourceType:
                        JazzRandomNode jrand = ce.RCOLBlock as JazzRandomNode;
                        RandomNode rand = chunks[i] as RandomNode;
                        RandomNode.Slice slice;
                        List<RandomNode.Slice> slices = rand.Slices;
                        foreach (JazzRandomNode.Outcome oc in jrand.Outcomes)
                        {
                            slice = new RandomNode.Slice(oc.Weight);
                            foreach (GenericRCOLResource.ChunkReference cr
                                in oc.DecisionGraphIndexes)
                            {
                                index = cr.TGIBlockIndex;
                                dgn = index < 0 ? null
                                    : chunks[index + 1] as DecisionGraphNode;
                                slice.Targets.Add(dgn);
                            }
                            slices.Add(slice);
                        }
                        break;
                    case SelectOnParameterNode.ResourceType:
                        JazzSelectOnParameterNode jsopn
                            = ce.RCOLBlock as JazzSelectOnParameterNode;
                        SelectOnParameterNode sopn
                            = chunks[i] as SelectOnParameterNode;
                        index = jsopn.ParameterDefinitionIndex.TGIBlockIndex;
                        sopn.Parameter = index < 0 ? null
                            : chunks[index + 1] as ParamDefinition;
                        foreach (JazzSelectOnParameterNode.Match mp
                            in jsopn.Matches)
                        {
                            hash = mp.TestValue;
                            if (!KeyNameReg.TryFindName(hash, out name))
                                name = KeyNameReg.UnhashName(hash);
                            foreach (GenericRCOLResource.ChunkReference cr
                                in mp.DecisionGraphIndexes)
                            {
                                index = cr.TGIBlockIndex;
                                dgn = index < 0 ? null
                                    : chunks[index + 1] as DecisionGraphNode;
                                sopn.AddCaseTarget(name, dgn);
                            }
                        }
                        break;
                    case SelectOnDestinationNode.ResourceType:
                        JazzSelectOnDestinationNode jsodn
                            = ce.RCOLBlock as JazzSelectOnDestinationNode;
                        SelectOnDestinationNode sodn
                            = chunks[i] as SelectOnDestinationNode;
                        foreach (JazzSelectOnDestinationNode.Match md
                            in jsodn.Matches)
                        {
                            index = md.StateIndex.TGIBlockIndex;
                            state = index < 0 ? null
                                : chunks[index + 1] as State;
                            foreach (GenericRCOLResource.ChunkReference cr
                                in md.DecisionGraphIndexes)
                            {
                                index = cr.TGIBlockIndex;
                                dgn = index < 0 ? null
                                    : chunks[index + 1] as DecisionGraphNode;
                                sodn.AddCaseTarget(state, dgn);
                            }
                        }
                        break;
                    case NextStateNode.ResourceType:
                        JazzNextStateNode jnsn
                            = ce.RCOLBlock as JazzNextStateNode;
                        NextStateNode nsn = chunks[i] as NextStateNode;
                        index = jnsn.StateIndex.TGIBlockIndex;
                        nsn.NextState = index < 0 ? null
                            : chunks[index + 1] as State;
                        break;
                    case DecisionGraph.ResourceType:
                        JazzDecisionGraph jdg
                            = ce.RCOLBlock as JazzDecisionGraph;
                        DecisionGraph dg = chunks[i] as DecisionGraph;
                        foreach (GenericRCOLResource.ChunkReference dm
                            in jdg.OutboundDecisionGraphIndexes)
                        {
                            index = dm.TGIBlockIndex;
                            dgn = index < 0 ? null
                                : chunks[index + 1] as DecisionGraphNode;
                            dg.AddDecisionMaker(dgn);
                        }
                        foreach (GenericRCOLResource.ChunkReference ep
                            in jdg.InboundDecisionGraphIndexes)
                        {
                            index = ep.TGIBlockIndex;
                            dgn = index < 0 ? null
                                : chunks[index + 1] as DecisionGraphNode;
                            dg.AddEntryPoint(dgn);
                        }
                        break;
                    case State.ResourceType:
                        State transition;
                        JazzState js = ce.RCOLBlock as JazzState;
                        state = chunks[i] as State;
                        index = js.DecisionGraphIndex.TGIBlockIndex;
                        state.DecisionGraph = index < 0 ? null
                            : chunks[index + 1] as DecisionGraph;
                        foreach (GenericRCOLResource.ChunkReference trans
                            in js.OutboundStateIndexes)
                        {
                            index = trans.TGIBlockIndex;
                            transition = index < 0 ? null
                                : chunks[index + 1] as State;
                            state.AddTransition(transition);
                        }
                        break;
                    case ParamDefinition.ResourceType:
                    case ActorDefinition.ResourceType:
                        break;
                    case StateMachine.ResourceType:
                        jazzSM = ce.RCOLBlock as JazzStateMachine;
                        foreach (GenericRCOLResource.ChunkReference jad
                            in jazzSM.ActorDefinitionIndexes)
                        {
                            index = jad.TGIBlockIndex;
                            ad = index < 0 ? null
                                : chunks[index + 1] as ActorDefinition;
                            this.AddActorDefinition(ad);
                        }
                        foreach (GenericRCOLResource.ChunkReference jpd
                            in jazzSM.PropertyDefinitionIndexes)
                        {
                            index = jpd.TGIBlockIndex;
                            pd = index < 0 ? null
                                : chunks[index + 1] as ParamDefinition;
                            this.AddParamDefinition(pd);
                        }
                        foreach (GenericRCOLResource.ChunkReference jst
                            in jazzSM.StateIndexes)
                        {
                            index = jst.TGIBlockIndex;
                            state = index < 0  ? null
                                : chunks[index + 1] as State;
                            this.AddState(state);
                        }
                        break;
                }
            }
            #endregion

            #region Phase 3: Copy over animation slots and Find "Extras"
            for (i = 0; i < chunkEntries.Count; i++)
            {
                ce = chunkEntries[i];
                switch (ce.TGIBlock.ResourceType)
                {
                    case PlayAnimationNode.ResourceType:
                        JazzPlayAnimationNode jpan
                            = ce.RCOLBlock as JazzPlayAnimationNode;
                        PlayAnimationNode lan
                            = chunks[i] as PlayAnimationNode;
                        SlotSetupBuilder ssb = lan.SlotSetup;
                        foreach (JazzPlayAnimationNode.ActorSlot slot
                            in jpan.ActorSlots)
                        {
                            ssb.AddSlotAssignment(slot.ChainId, slot.SlotId,
                                slot.ActorNameHash, slot.SlotNameHash);
                        }
                        foreach (JazzPlayAnimationNode.ActorSuffix suffix
                            in jpan.ActorSuffixes)
                        {
                            hash = suffix.ActorNameHash;
                            ad = null;
                            if (hash != 0)
                            {
                                index = -1;
                                for (i = actorDefs.Count - 1;
                                     i >= 0 && index == -1; i--)
                                {
                                    ad = actorDefs[i];
                                    if (ad.NameHash == hash)
                                    {
                                        index = i;
                                    }
                                }
                                if (index < 0)
                                {
                                    if (!KeyNameReg.TryFindName(hash, out name))
                                        name = KeyNameReg.UnhashName(hash);
                                    ad = new ActorDefinition(name);
                                    actorDefs.Add(ad);
                                    this.mExtraActors.Add(ad);
                                }
                            }
                            hash = suffix.SuffixHash;
                            pd = null;
                            if (hash != 0)
                            {
                                index = -1;
                                for (i = paramDefs.Count - 1;
                                     i >= 0 && index == -1; i--)
                                {
                                    pd = paramDefs[i];
                                    if (pd.NameHash == hash)
                                    {
                                        index = i;
                                    }
                                }
                                if (index < 0)
                                {
                                    if (!KeyNameReg.TryFindName(hash, out name))
                                        name = KeyNameReg.UnhashName(hash);
                                    pd = new ParamDefinition(name);
                                    paramDefs.Add(pd);
                                    this.mExtraParams.Add(pd);
                                }
                            }
                            ssb.AddNamespaceSlotSuffix(ad, pd);
                        }
                        break;
                    case State.ResourceType:
                        state = chunks[i] as State;
                        index = this.mStates.IndexOf(state);
                        if (index < 0)
                        {
                            this.mExtraStates.Add(state);
                        }
                        break;
                    case ParamDefinition.ResourceType:
                        pd = chunks[i] as ParamDefinition;
                        index = this.mParamDefinitions.IndexOf(pd);
                        if (index < 0)
                        {
                            this.mExtraParams.Add(pd);
                        }
                        break;
                    case ActorDefinition.ResourceType:
                        ad = chunks[i] as ActorDefinition;
                        index = this.mActorDefinitions.IndexOf(ad);
                        if (index < 0)
                        {
                            this.mExtraActors.Add(ad);
                        }
                        break;
                }
            }
            #endregion

            #region Phase 4: Copy over Animation CLIP Namespace Map
            RK rk;
            List<RK> rks = this.SlurpReferencedRKs();
            List<uint> foldedClipInstances = new List<uint>(rks.Count);
            for (i = rks.Count - 1; i >= 0; i--)
            {
                rk = rks[i];
                if (rk.TID == 0x6b20c4f3)
                {
                    hash = (uint)((rk.IID >> 0x20) ^ (rk.IID & 0xffffffff));
                    foldedClipInstances.Add(hash);
                }
                else
                {
                    rks.RemoveAt(i);
                }
            }
            index = 0;
            Anim animation;
            Anim[] animations = new Anim[jazzSM.Animations.Count];
            foreach (JazzStateMachine.Animation anim in jazzSM.Animations)
            {
                hash = anim.NameHash;
                if (!foldedClipInstances.Contains(hash))
                {
                    animation = new Anim();
                    animation.SrcFileHash = hash;
                    if (KeyNameReg.TryFindName(hash, out name))
                    {
                        animation.SrcFileName = name;
                        animation.SrcFileIsValid = true;
                    }
                    else
                    {
                        animation.SrcFileName
                            = KeyNameReg.UnhashName(hash);
                        animation.SrcFileIsValid = false;
                    }
                    hash = anim.Actor1Hash;
                    if (KeyNameReg.TryFindName(hash, out name))
                    {
                        animation.Namespace = name;
                    }
                    else
                    {
                        animation.Namespace
                            = string.Concat("0x", hash.ToString("X8"));
                    }
                    hash = anim.Actor2Hash;
                    ad = null;
                    if (hash != 0)
                    {
                        j = -1;
                        for (i = actorDefs.Count - 1; i >= 0 && j < 0; i--)
                        {
                            ad = actorDefs[i];
                            if (ad.NameHash == hash)
                            {
                                j = i;
                            }
                        }
                        if (j < 0)
                        {
                            if (!KeyNameReg.TryFindName(hash, out name))
                                name = KeyNameReg.UnhashName(hash);
                            ad = new ActorDefinition(name);
                            actorDefs.Add(ad);
                            this.mExtraActors.Add(ad);
                        }
                    }
                    animation.Actor = ad;
                    animations[index++] = animation;
                }
            }
            ulong clipHash;
            Dictionary<ulong, string> keyNameMap
                = new Dictionary<ulong, string>();
            for (i = index - 1; i >= 0; i--)
            {
                animation = animations[i];
                this.mNamespaceMap.SetNamespaceMap(
                    animation.SrcFileName,
                    animation.Namespace,
                    animation.Actor);
                if (animation.SrcFileIsValid)
                {
                    clipHash = FNVHash.HashString64(animation.SrcFileName);
                    keyNameMap[clipHash] = animation.SrcFileName;
                }
            }
            // Update the Key to Filename Map of the Namespace Map
            SortedDictionary<RK, string> k2fn
                = this.mNamespaceMap.KeyToFilenameMap;
            k2fn.Clear();
            for (i = rks.Count - 1; i >= 0; i--)
            {
                rk = rks[i];
                if (keyNameMap.TryGetValue(rk.IID, out name) ||
                    KeyNameReg.TryFindName(rk.IID, out name))
                {
                    k2fn[rk] = name;
                }
            }
            #endregion
        }