Exemple #1
0
        public void LoadBSPTag(CacheBase Cache, CacheBase.IndexItem Tag)
        {
            cache = Cache;
            tag = Tag;

            sbsp = DefinitionsManager.sbsp(cache, tag);
            sbsp.BSPName = Path.GetFileNameWithoutExtension(tag.Filename + "." + tag.ClassCode);

            lblName.Text = sbsp.BSPName;
            if (cache.Version <= DefinitionSet.Halo2Vista) sbsp.LoadRaw();

            isWorking = true;
            tvRegions.Nodes.Clear();

            TreeNode ClusterNode = new TreeNode("Clusters") { Checked = true };
            foreach (var clust in sbsp.Clusters)
            {
                if (sbsp.ModelSections[clust.SectionIndex].Submeshes.Count > 0)
                    ClusterNode.Nodes.Add(new TreeNode(sbsp.Clusters.IndexOf(clust).ToString("D3")) { Tag = clust, Checked = true });
            }
            if (ClusterNode.Nodes.Count > 0)
                tvRegions.Nodes.Add(ClusterNode);

            TreeNode IGnode = new TreeNode("Instances") { Checked = true };
            foreach (var IG in sbsp.GeomInstances)
            {
                if (sbsp.ModelSections[IG.SectionIndex].Submeshes.Count > 0)
                    IGnode.Nodes.Add(new TreeNode(IG.Name) { Tag = IG, Checked = true });
            }
            if (IGnode.Nodes.Count > 0)
                tvRegions.Nodes.Add(IGnode);

            isWorking = false;
        }
Exemple #2
0
        public void LoadBitmapTag(CacheBase Cache, CacheBase.IndexItem Tag)
        {
            exportAllImagesToolStripMenuItem.Visible = true;

            cache = Cache;
            tag   = Tag;

            bitm = DefinitionsManager.bitm(cache, tag);

            lstBitmaps.Items.Clear();
            var list = GetBitmapsByTag(cache, tag, PixelFormat.Format32bppArgb);

            for (int i = 0; i < list.Count; i++)
            {
                var submap = bitm.Bitmaps[i];
                lstBitmaps.Items.Add(new ListViewItem(new string[]
                {
                    i.ToString(),
                    submap.Width.ToString(),
                    submap.Height.ToString(),
                    submap.Type.ToString(),
                    submap.Format.ToString()
                })
                {
                    Tag = (list[i] == null) ? GetErrorImage() : list[i]
                });
            }

            lstBitmaps.FocusedItem = lstBitmaps.Items[0];
            lstBitmaps_SelectedIndexChanged(null, null);
        }
Exemple #3
0
        public void LoadSoundTag(CacheBase Cache, CacheBase.IndexItem Tag)
        {
            if (Cache.Version != DefinitionSet.Halo4Retail)
            {
                throw new Exception("This is for H4 ONLY");
            }

            cache = (CacheH4R)Cache;
            tag   = Tag;

            snd = (SoundH4R)DefinitionsManager.snd_(cache, tag);

            LoadCacheSoundPacks(cache);

            lstPerms.Items.Clear();
            _perms.Clear();
            _soundbanks.Clear();

            ObjectLoadWorker();

            if (lstPerms.Items.Count > 0)
            {
                Enabled = true;
                lstPerms.SelectedIndex = 0;
                label1.Text            = _perms[0].Format.ToString();
            }
            else
            {
                label1.Text = "";
                Enabled     = false;
            }
        }
Exemple #4
0
        public static void SaveBink(string Filename, CacheBase Cache, CacheBase.IndexItem Tag)
        {
            var bik = DefinitionsManager.bink(Cache, Tag);
            var raw = Cache.GetRawFromID(bik.RawID);

            if (!Filename.EndsWith(".bik"))
            {
                Filename += ".bik";
            }

            if (!Directory.GetParent(Filename).Exists)
            {
                Directory.GetParent(Filename).Create();
            }

            var fs = new FileStream(Filename, FileMode.Create, FileAccess.Write);
            var bw = new BinaryWriter(fs);

            for (int i = 0; i < (raw.Length); i += 4)
            {
                Array.Reverse(raw, i, 4);
            }

            bw.Write(raw);

            bw.Close();
            bw.Dispose();
        }
Exemple #5
0
        private void RecursiveExtract(object SaveFolder)
        {
            List<CacheBase.IndexItem> tagsDone = new List<CacheBase.IndexItem>();

            foreach (var shader in sbsp.Shaders)
            {
                var rmshTag = cache.IndexItems.GetItemByID(shader.tagID);

                if (rmshTag == null) continue;

                var rmsh = DefinitionsManager.rmsh(cache, rmshTag);

                foreach (Definitions.shader.ShaderProperties prop in rmsh.Properties)
                {
                    foreach (Definitions.shader.ShaderProperties.ShaderMap map in prop.ShaderMaps)
                    {
                        var bitmTag = cache.IndexItems.GetItemByID(map.BitmapTagID);
                        if (bitmTag == null) continue;

                        //dont need to waste time extracting the same ones over and over
                        if (tagsDone.Contains(bitmTag)) continue;

                        try
                        {
                            BitmapExtractor.SaveAllImages((string)SaveFolder + "\\" + bitmTag.Filename, cache, bitmTag, DefaultBitmFormat, true);
                            TagExtracted(this, bitmTag);
                        }
                        catch (Exception ex) { ErrorExtracting(this, bitmTag, ex); }

                        tagsDone.Add(bitmTag);
                    }
                }
            }
            FinishedRecursiveExtract(this, tag);
        }
        /// <summary>
        /// Save all permutations of a sound tag as separate sound files.
        /// </summary>
        /// <param name="Folder">The base filename. Permutation names will be appended accordingly.</param>
        /// <param name="Cache">The CacheFile containing the tag.</param>
        /// <param name="Tag">The sound tag.</param>
        /// <param name="Format">The format in which to save the data.</param>
        public static void SaveAllAsSeparate(string Folder, CacheBase Cache, CacheBase.IndexItem Tag, SoundFormat Format, bool Overwrite)
        {
            var snd_ = DefinitionsManager.snd_(Cache, Tag);
            var ugh_ = Cache.ugh_;

            var indices = new List <int>();

            for (int i = 0; i < ugh_.PlayBacks[snd_.PlaybackIndex].PermutationCount; i++)
            {
                indices.Add(i);
            }

            SaveSelected(Folder, Cache, Tag, Format, indices, Overwrite);
        }
Exemple #7
0
        public void LoadUnicTag(CacheBase Cache, CacheBase.IndexItem Tag, Language Language)
        {
            cache = Cache;
            tag   = Tag;

            label1.Enabled = cmbLang.Enabled = true;

            cmbLang.SelectedIndex = -1;

            var reader = Cache.Reader;

            unic = DefinitionsManager.unic(Cache, tag);

            cmbLang.SelectedIndex = (int)Language;
        }
Exemple #8
0
        /// <summary>
        /// Saves all pieces of the model from a scenario_structure_bsp tag to disk.
        /// </summary>
        /// <param name="Filename">The full path and filename to save to.</param>
        /// <param name="Cache">The CacheFile containing the scenario_structure_bsp tag.</param>
        /// <param name="Tag">The scenario_structure_bsp tag.</param>
        /// <param name="Format">The format to save the model in.</param>
        public static void SaveAllBSPParts(string Filename, CacheBase Cache, CacheBase.IndexItem Tag, ModelFormat Format)
        {
            var sbsp = DefinitionsManager.sbsp(Cache, Tag);
            sbsp.LoadRaw();

            var clusters = new List<int>();
            var geoms = new List<int>();

            for (int i = 0; i < sbsp.Clusters.Count; i++)
                clusters.Add(i);

            for (int i = 0; i < sbsp.GeomInstances.Count; i++)
                geoms.Add(i);

            SaveBSPParts(Filename, Cache, sbsp, Format, clusters, geoms);
        }
Exemple #9
0
        public static List <string> GetUnicStrings(CacheBase Cache, CacheBase.IndexItem Tag, Language Language)
        {
            List <string> strings = new List <string>();

            var reader = Cache.Reader;
            var unic   = DefinitionsManager.unic(Cache, Tag);

            int index  = unic.Indices[(int)Language];
            int length = unic.Lengths[(int)Language];

            for (int i = index; i < (index + length); i++)
            {
                strings.Add(Cache.LocaleTables[(int)Language][i]);
            }


            return(strings);
        }
        /// <summary>
        /// Saves all pieces of the model from a render_model tag to disk.
        /// </summary>
        /// <param name="Filename">The full path and filename to save to.</param>
        /// <param name="Cache">The CacheFile containing the render_model tag.</param>
        /// <param name="Tag">The render_model tag.</param>
        /// <param name="Format">The format to save the model in.</param>
        /// <param name="SplitMeshes">Whether to split the pieces into individual submeshes. Only applies when saving in EMF format.</param>
        public static void SaveAllModelParts(string Filename, CacheBase Cache, CacheBase.IndexItem Tag, ModelFormat Format, bool SplitMeshes)
        {
            var mode = DefinitionsManager.mode(Cache, Tag);

            mode.LoadRaw();

            List <int> Parts = new List <int>();

            for (int i = 0; i < mode.ModelSections.Count; i++)
            {
                if (mode.ModelSections[i].Submeshes.Count > 0)
                {
                    Parts.Add(i);
                }
            }

            SaveModelParts(Filename, Cache, mode, Format, Parts, SplitMeshes);
        }
        public override bool Execute(List <string> args)
        {
            if (args.Count != 1)
            {
                return(false);
            }

            CacheBase.IndexItem item = null;

            Console.WriteLine("Verifying blam shader tag...");

            var shaderName = args[0];

            foreach (var tag in BlamCache.IndexItems)
            {
                if ((tag.ParentClass == "rm") && tag.Filename == shaderName)
                {
                    item = tag;
                    break;
                }
            }

            if (item == null)
            {
                Console.WriteLine("Blam shader tag does not exist: " + shaderName);
                return(false);
            }

            var renderMethod = DefinitionsManager.rmsh(BlamCache, item);

            var templateItem = BlamCache.IndexItems.Find(i =>
                                                         i.ID == renderMethod.Properties[0].TemplateTagID);

            var template = DefinitionsManager.rmt2(BlamCache, templateItem);

            for (var i = 0; i < template.UsageBlocks.Count; i++)
            {
                var bitmItem = BlamCache.IndexItems.Find(j =>
                                                         j.ID == renderMethod.Properties[0].ShaderMaps[i].BitmapTagID);
                Console.WriteLine(bitmItem);
            }

            return(true);
        }
        public void LoadModelTag(CacheBase Cache, CacheBase.IndexItem Tag)
        {
            cache = Cache;
            tag   = Tag;

            mode = DefinitionsManager.mode(cache, tag);

            if (mode.InstancedGeometryIndex != -1)
            {
                mode.LoadRaw();
            }

            lblName.Text = mode.Name;

            tvRegions.Nodes.Clear();
            foreach (var region in mode.Regions)
            {
                TreeNode node = new TreeNode(region.Name)
                {
                    Checked = true, Tag = region
                };
                foreach (var perm in region.Permutations)
                {
                    if (perm.PieceIndex != -1)
                    {
                        if (mode.ModelSections[perm.PieceIndex].Submeshes.Count > 0)
                        {
                            node.Nodes.Add(new TreeNode(perm.Name)
                            {
                                Checked = true, Tag = perm
                            });
                        }
                    }
                }
                if (node.Nodes.Count > 0)
                {
                    tvRegions.Nodes.Add(node);
                }
            }
        }
Exemple #13
0
        public static void SaveUnicStrings(string Filename, CacheBase Cache, CacheBase.IndexItem Tag, Language Language)
        {
            List <string> sList = new List <string>();

            var reader = Cache.Reader;
            var unic   = DefinitionsManager.unic(Cache, Tag);

            int index  = unic.Indices[(int)Language];
            int length = unic.Lengths[(int)Language];

            for (int i = index; i < (index + length); i++)
            {
                sList.Add(Cache.LocaleTables[(int)Language][i]);
            }

            if (!Directory.GetParent(Filename).Exists)
            {
                Directory.GetParent(Filename).Create();
            }
            if (!Filename.EndsWith(".txt"))
            {
                Filename += ".txt";
            }

            var fs    = new FileStream(Filename, FileMode.Create);
            int start = unic.Indices[(int)Language];

            for (int i = 0; i < sList.Count; i++)
            {
                string line   = (i + start).ToString("D6") + "\t" + sList[i].Replace("\r\n", " ") + "\r\n";
                byte[] buffer = Encoding.UTF8.GetBytes(line);
                fs.Write(buffer, 0, buffer.Length);
            }

            fs.Close();
            fs.Dispose();
        }
        public void LoadSoundTag(CacheBase Cache, CacheBase.IndexItem Tag)
        {
            cache = Cache;
            tag   = Tag;

            snd = DefinitionsManager.snd_(cache, tag);

            if (cache.ugh_ == null)
            {
                lstPerms.Items.Clear();
                Enabled = false;
                return;
            }
            else
            {
                Enabled = true;
            }

            ugh      = cache.ugh_;
            playback = ugh.PlayBacks[snd.PlaybackIndex];

            Perms = new List <ugh_.SoundPermutation>();

            for (int i = 0; i < playback.PermutationCount; i++)
            {
                Perms.Add(ugh.SoundPermutations[playback.FirstPermutation + i]);
            }

            lstPerms.Items.Clear();

            foreach (var perm in Perms)
            {
                lstPerms.Items.Add(ugh.SoundNames[perm.NameIndex]);
            }

            lstPerms.SelectedIndex = 0;
        }
Exemple #15
0
        public override bool Execute(List <string> args)
        {
            var initialStringIDCount = Info.StringIDs.Strings.Count;

            bool isNew = false;

            if (args.Count == 3)
            {
                if (args[0] != "new")
                {
                    return(false);
                }
                isNew = true;
                args.Remove("new");
            }

            if (args.Count != 2)
            {
                return(false);
            }

            //
            // Verify the Blam render_model tag
            //

            var renderModelName = args[0];

            CacheBase.IndexItem item = null;

            Console.WriteLine("Verifying Blam tag...");

            foreach (var tag in BlamCache.IndexItems)
            {
                if ((tag.ClassCode == "mode" || tag.ClassCode == "sbsp") && tag.Filename == renderModelName)
                {
                    item = tag;
                    break;
                }
            }

            if (item == null)
            {
                Console.WriteLine("Blam tag does not exist: " + args[0]);
                return(false);
            }

            //
            // Verify the ED render_model tag
            //

            Console.WriteLine("Verifying ED tag index...");

            int edRenderModelIndex;

            if (!int.TryParse(args[1], NumberStyles.HexNumber, null, out edRenderModelIndex) ||
                (edRenderModelIndex >= Info.Cache.Tags.Count))
            {
                Console.WriteLine("Invalid tag index: " + args[1]);
                return(false);
            }

            var edTag = Info.Cache.Tags[edRenderModelIndex];

            if (edTag.Group.Name != Info.StringIDs.GetStringID("render_model"))
            {
                Console.WriteLine("Specified tag index is not a render_model: " + args[1]);
                return(false);
            }

            //
            // Deserialize the selected render_model
            //

            Console.WriteLine("Loading ED render_model tag...");

            TagDefinitions.RenderModel renderModel;

            using (var cacheStream = Info.CacheFile.Open(FileMode.Open, FileAccess.ReadWrite))
            {
                try
                {
                    var context = new Serialization.TagSerializationContext(cacheStream, Info.Cache, Info.StringIDs, Info.Cache.Tags[(int)edRenderModelIndex]);
                    renderModel = Info.Deserializer.Deserialize <TagDefinitions.RenderModel>(context);
                }
                catch
                {
                    Console.WriteLine("Failed to deserialize selected render_model tag: " + edRenderModelIndex);
                    return(true);
                }
            }

            //
            // Load the Blam render_model tag raw
            //

            var isBSP = item.ClassCode == "sbsp";

            scenario_structure_bsp sbsp = null;
            render_model           mode = null;

            if (isBSP)
            {
                sbsp = DefinitionsManager.sbsp(BlamCache, item);
                sbsp.LoadRaw();
            }
            else
            {
                mode = DefinitionsManager.mode(BlamCache, item);
                mode.LoadRaw();
            }

            //
            // Duplicate the render_model tag we're injecting over
            //

            TagInstance newTag;

            if (isNew)
            {
                Console.WriteLine("Duplicating selected render_model tag...");

                if (!new DuplicateTagCommand(Info).Execute(new List <string> {
                    edRenderModelIndex.ToString("X8")
                }))
                {
                    Console.WriteLine("Failed to duplicate render_model tag: " + edRenderModelIndex);
                    return(false);
                }

                newTag = Info.Cache.Tags[Info.Cache.Tags.Count - 1];
            }
            else
            {
                newTag = edTag;
            }

            //
            // Start porting the model
            //

            RenderModelBuilder builder = new RenderModelBuilder(DefinitionSet.HaloOnline106708);

            var blamNodes = isBSP ?
                            new List <render_model.Node>
            {
                new render_model.Node
                {
                    Name             = "default",
                    ParentIndex      = -1,
                    FirstChildIndex  = -1,
                    NextSiblingIndex = -1,
                    Position         = new Vector(),
                    Rotation         = new Vector(0, 0, 0, -1),
                    TransformScale   = 1,
                    TransformMatrix  = new Matrix4x3(
                        1, 0, 0,
                        0, 1, 0,
                        0, 0, 1,
                        0, 0, 0),
                    DistanceFromParent = 0
                }
            } : mode.Nodes;

            foreach (var node in blamNodes)
            {
                var nodeNameId = Info.StringIDs.GetStringID(node.Name);

                builder.AddNode(
                    new TagDefinitions.RenderModel.Node
                {
                    Name               = nodeNameId.Index == 0 && node.Name != "" ? nodeNameId = Info.StringIDs.Add(node.Name) : nodeNameId,
                    ParentNode         = (short)node.ParentIndex,
                    FirstChildNode     = (short)node.FirstChildIndex,
                    NextSiblingNode    = (short)node.NextSiblingIndex,
                    ImportNode         = 0,
                    DefaultTranslation = new Common.Vector3(node.Position.X, node.Position.Y, node.Position.Z),
                    DefaultRotation    = new Common.Vector4(node.Rotation.X, node.Rotation.Y, node.Rotation.Z, node.Rotation.W),
                    DefaultScale       = node.TransformScale,
                    InverseForward     = new Common.Vector3(node.TransformMatrix.m11, node.TransformMatrix.m12, node.TransformMatrix.m13),
                    InverseLeft        = new Common.Vector3(node.TransformMatrix.m21, node.TransformMatrix.m22, node.TransformMatrix.m23),
                    InverseUp          = new Common.Vector3(node.TransformMatrix.m31, node.TransformMatrix.m32, node.TransformMatrix.m33),
                    InversePosition    = new Common.Vector3(node.TransformMatrix.m41, node.TransformMatrix.m42, node.TransformMatrix.m43),
                    DistanceFromParent = node.DistanceFromParent
                });
            }

            //
            // Create empty materials for now...
            //

            var blamShaders = isBSP ? sbsp.Shaders : mode.Shaders;

            foreach (var shader in blamShaders)
            {
                builder.AddMaterial(
                    new RenderMaterial
                {
                    RenderMethod = Info.Cache.Tags[0x101F]
                });
            }

            //
            // Build the model regions
            //

            if (isBSP)
            {
                builder.BeginRegion(Info.StringIDs.GetStringID("default"));
                builder.BeginPermutation(Info.StringIDs.GetStringID("default"));

                foreach (var section in sbsp.ModelSections)
                {
                    if (section.Submeshes.Count == 0)
                    {
                        continue;
                    }

                    var rigidVertices = new List <RigidVertex>();

                    VertexValue v;
                    if (section.Vertices != null)
                    {
                        foreach (var vertex in section.Vertices)
                        {
                            vertex.TryGetValue("position", 0, out v);
                            var position = new Common.Vector4(v.Data.X, v.Data.Y, v.Data.Z, 1);

                            vertex.TryGetValue("normal", 0, out v);
                            var normal = new Common.Vector3(v.Data.I, v.Data.J, v.Data.K);

                            vertex.TryGetValue("texcoords", 0, out v);
                            var texcoord = new Common.Vector2(v.Data.X, v.Data.Y);

                            vertex.TryGetValue("tangent", 0, out v);
                            var tangent = new Common.Vector4(v.Data.X, v.Data.Y, v.Data.Z, 1);

                            vertex.TryGetValue("binormal", 0, out v);
                            var binormal = new Common.Vector3(v.Data.X, v.Data.Y, v.Data.Z);

                            rigidVertices.Add(
                                new RigidVertex
                            {
                                Position = position,
                                Normal   = normal,
                                Texcoord = texcoord,
                                Tangent  = tangent,
                                Binormal = binormal
                            });
                        }
                    }

                    // Build the section's subparts

                    builder.BeginMesh();

                    var indices = new List <ushort>();

                    foreach (var submesh in section.Submeshes)
                    {
                        builder.BeginPart((short)submesh.ShaderIndex, (ushort)submesh.FaceIndex, (ushort)submesh.FaceCount, (ushort)submesh.VertexCount);
                        for (var j = 0; j < submesh.SubsetCount; j++)
                        {
                            var subpart = section.Subsets[submesh.SubsetIndex + j];
                            builder.DefineSubPart((ushort)subpart.FaceIndex, (ushort)subpart.FaceCount, (ushort)subpart.VertexCount);
                        }
                        builder.EndPart();
                    }

                    builder.BindRigidVertexBuffer(rigidVertices, 0);
                    builder.BindIndexBuffer(section.Indices.Select(index => (ushort)index), PrimitiveType.TriangleList);

                    builder.EndMesh();
                }

                builder.EndPermutation();
                builder.EndRegion();

                foreach (var instance in sbsp.GeomInstances)
                {
                    var mesh = builder.Meshes[instance.SectionIndex];

                    if (mesh.VertexFormat == VertexBufferFormat.Rigid)
                    {
                        foreach (var i in mesh.RigidVertices)
                        {
                            i.Position = new Common.Vector4(
                                i.Position.X + instance.TransformMatrix.m41,
                                i.Position.Y + instance.TransformMatrix.m42,
                                i.Position.Z + instance.TransformMatrix.m43,
                                i.Position.W);
                        }
                    }

                    else if (mesh.VertexFormat == VertexBufferFormat.World)
                    {
                        foreach (var i in mesh.WorldVertices)
                        {
                            i.Position = new Common.Vector4(
                                i.Position.X + instance.TransformMatrix.m41,
                                i.Position.Y + instance.TransformMatrix.m42,
                                i.Position.Z + instance.TransformMatrix.m43,
                                i.Position.W);
                        }
                    }

                    else if (mesh.VertexFormat == VertexBufferFormat.Skinned)
                    {
                        foreach (var i in mesh.SkinnedVertices)
                        {
                            i.Position = new Common.Vector4(
                                i.Position.X + instance.TransformMatrix.m41,
                                i.Position.Y + instance.TransformMatrix.m42,
                                i.Position.Z + instance.TransformMatrix.m43,
                                i.Position.W);
                        }
                    }
                }
            }

            else
            {
                foreach (var region in mode.Regions)
                {
                    var regionNameId = Info.StringIDs.GetStringID(region.Name);

                    builder.BeginRegion(regionNameId.Index == 0 && region.Name != "" ? regionNameId = Info.StringIDs.Add(region.Name) : regionNameId);

                    foreach (var permutation in region.Permutations)
                    {
                        if (permutation.PieceCount <= 0 || permutation.PieceIndex == -1)
                        {
                            continue;
                        }

                        var permutationNameId = Info.StringIDs.GetStringID(permutation.Name);

                        builder.BeginPermutation(permutationNameId.Index == 0 && permutation.Name != "" ? permutationNameId = Info.StringIDs.Add(permutation.Name) : permutationNameId);

                        for (var i = permutation.PieceIndex; i < permutation.PieceIndex + permutation.PieceCount; i++)
                        {
                            var section = mode.ModelSections[i];

                            if (section.Submeshes.Count == 0 || section.Vertices == null)
                            {
                                continue;
                            }

                            //
                            // Collect the section's vertices
                            //

                            var skinnedVertices = new List <SkinnedVertex>();
                            var rigidVertices   = new List <RigidVertex>();

                            VertexValue v;
                            bool        isSkinned = section.Vertices[0].TryGetValue("blendindices", 0, out v) && section.NodeIndex == 255;
                            bool        isBoned   = section.Vertices[0].FormatName.Contains("rigid_boned");

                            foreach (var vertex in section.Vertices)
                            {
                                vertex.TryGetValue("position", 0, out v);
                                var position = new Common.Vector4(v.Data.X, v.Data.Y, v.Data.Z, 1);

                                vertex.TryGetValue("normal", 0, out v);
                                var normal = new Common.Vector3(v.Data.I, v.Data.J, v.Data.K);

                                vertex.TryGetValue("texcoords", 0, out v);
                                var texcoord = new Common.Vector2(v.Data.X, v.Data.Y);

                                vertex.TryGetValue("tangent", 0, out v);
                                var tangent = new Common.Vector4(v.Data.X, v.Data.Y, v.Data.Z, 1);

                                vertex.TryGetValue("binormal", 0, out v);
                                var binormal = new Common.Vector3(v.Data.X, v.Data.Y, v.Data.Z);

                                rigidVertices.Add(
                                    new RigidVertex
                                {
                                    Position = position,
                                    Normal   = normal,
                                    Texcoord = texcoord,
                                    Tangent  = tangent,
                                    Binormal = binormal
                                });

                                if (isBoned)
                                {
                                    var blendIndices = new List <byte>();

                                    vertex.TryGetValue("blendindices", 0, out v);

                                    blendIndices.Add((byte)v.Data.A);
                                    blendIndices.Add((byte)v.Data.B);
                                    blendIndices.Add((byte)v.Data.C);
                                    blendIndices.Add((byte)v.Data.D);

                                    skinnedVertices.Add(new SkinnedVertex
                                    {
                                        Position     = position,
                                        Normal       = normal,
                                        Texcoord     = texcoord,
                                        Tangent      = tangent,
                                        Binormal     = binormal,
                                        BlendIndices = blendIndices.ToArray(),
                                        BlendWeights = new[] { 1.0f, 0.0f, 0.0f, 0.0f }
                                    });
                                }
                                else if (isSkinned)
                                {
                                    var blendIndices = new List <byte>();
                                    var blendWeights = new List <float>();

                                    vertex.TryGetValue("blendindices", 0, out v);

                                    blendIndices.Add((byte)v.Data.A);
                                    blendIndices.Add((byte)v.Data.B);
                                    blendIndices.Add((byte)v.Data.C);
                                    blendIndices.Add((byte)v.Data.D);

                                    vertex.TryGetValue("blendweight", 0, out v);

                                    blendWeights.Add(v.Data.A);
                                    blendWeights.Add(v.Data.B);
                                    blendWeights.Add(v.Data.C);
                                    blendWeights.Add(v.Data.D);

                                    skinnedVertices.Add(new SkinnedVertex
                                    {
                                        Position     = position,
                                        Normal       = normal,
                                        Texcoord     = texcoord,
                                        Tangent      = tangent,
                                        Binormal     = binormal,
                                        BlendIndices = blendIndices.ToArray(),
                                        BlendWeights = blendWeights.ToArray()
                                    });
                                }
                            }

                            bool isRigid = false;

                            if (skinnedVertices.Count == 0)
                            {
                                isRigid = rigidVertices.Count != 0;
                            }

                            //
                            // Build the section's submeshes
                            //

                            builder.BeginMesh();

                            var indices = new List <ushort>();

                            foreach (var submesh in section.Submeshes)
                            {
                                builder.BeginPart((short)submesh.ShaderIndex, (ushort)submesh.FaceIndex, (ushort)submesh.FaceCount, (ushort)submesh.VertexCount);
                                for (var j = 0; j < submesh.SubsetCount; j++)
                                {
                                    var subpart = section.Subsets[submesh.SubsetIndex + j];
                                    builder.DefineSubPart((ushort)subpart.FaceIndex, (ushort)subpart.FaceCount, (ushort)subpart.VertexCount);
                                }
                                builder.EndPart();
                            }

                            if (isRigid)
                            {
                                builder.BindRigidVertexBuffer(rigidVertices, (sbyte)section.NodeIndex);
                            }
                            else if (isSkinned || isBoned)
                            {
                                builder.BindSkinnedVertexBuffer(skinnedVertices);
                            }
                            builder.BindIndexBuffer(section.Indices.Select(index => (ushort)index), PrimitiveType.TriangleStrip);

                            builder.EndMesh();
                        }

                        builder.EndPermutation();
                    }

                    builder.EndRegion();
                }
            }

            //
            // Finalize the new render_model tag
            //

            var resourceStream = new MemoryStream();
            var newRenderModel = builder.Build(Info.Serializer, resourceStream);

            var renderModelNameStringID = Info.StringIDs.GetStringID(isBSP ? "default" : mode.Name);

            newRenderModel.Name = renderModelNameStringID.Index == -1 ?
                                  renderModelNameStringID = Info.StringIDs.Add(isBSP ? "default" : mode.Name) :
                                                            renderModelNameStringID;

            //
            // Add the markers to the new render_model
            //

            newRenderModel.MarkerGroups = new List <TagDefinitions.RenderModel.MarkerGroup>();

            var blamMarkerGroups = isBSP ? new List <render_model.MarkerGroup>() : mode.MarkerGroups;

            foreach (var markerGroup in blamMarkerGroups)
            {
                var markerGroupNameId = Info.StringIDs.GetStringID(markerGroup.Name);

                if (markerGroupNameId.Index == -1)
                {
                    markerGroupNameId = Info.StringIDs.Add(markerGroup.Name);
                }

                newRenderModel.MarkerGroups.Add(
                    new TagDefinitions.RenderModel.MarkerGroup
                {
                    Name    = markerGroupNameId,
                    Markers = markerGroup.Markers.Select(marker =>
                                                         new TagDefinitions.RenderModel.MarkerGroup.Marker
                    {
                        RegionIndex      = (sbyte)marker.RegionIndex,
                        PermutationIndex = (sbyte)marker.PermutationIndex,
                        NodeIndex        = (sbyte)marker.NodeIndex,
                        Unknown3         = 0,
                        Translation      = new Common.Vector3(marker.Position.X, marker.Position.Y, marker.Position.Z),
                        Rotation         = new Common.Vector4(marker.Rotation.X, marker.Rotation.Y, marker.Rotation.Z, marker.Rotation.W),
                        Scale            = marker.Scale
                    }).ToList()
                });
            }

            //
            // Disable rigid nodes on skinned meshes
            //

            foreach (var mesh in newRenderModel.Geometry.Meshes)
            {
                if (mesh.Type == VertexType.Skinned)
                {
                    mesh.RigidNodeIndex = -1;
                }
            }

            //
            // Add a new resource for the model data
            //

            Console.WriteLine("Writing resource data...");

            var resources = new ResourceDataManager();

            resources.LoadCachesFromDirectory(Info.CacheFile.DirectoryName);
            resourceStream.Position = 0;
            resources.Add(newRenderModel.Geometry.Resource, ResourceLocation.Resources, resourceStream);

            using (var cacheStream = Info.CacheFile.Open(FileMode.Open, FileAccess.ReadWrite))
            {
                Console.WriteLine("Writing tag data...");

                newRenderModel.Geometry.Resource.Owner = newTag;

                var context = new Serialization.TagSerializationContext(cacheStream, Info.Cache, Info.StringIDs, newTag);
                Info.Serializer.Serialize(context, newRenderModel);
            }

            resourceStream.Close();

            //
            // Save new string_ids
            //

            if (Info.StringIDs.Strings.Count != initialStringIDCount)
            {
                Console.WriteLine("Saving string_ids...");

                using (var stringIdStream = Info.StringIDsFile.Open(FileMode.Open, FileAccess.ReadWrite))
                    Info.StringIDs.Save(stringIdStream);
            }

            //
            // Done!
            //

            Console.WriteLine("Ported render_model \"" + renderModelName + "\" successfully!");

            return(true);
        }
Exemple #16
0
        /// <summary>
        /// Saves all images from a bitmap tag to disk.
        /// </summary>
        /// <param name="Filename">The full path and filename of the first bitmap to save. All subsequent images will be named accordingly.</param>
        /// <param name="Cache">The CacheFile containing the bitmap tag.</param>
        /// <param name="Tag">The bitmap tag.</param>
        /// <param name="Format">The format to save the images in.</param>
        /// <param name="Alpha">Whether to include the alpha channel in the images. Only applies when saving in TIF format.</param>
        public static void SaveAllImages(string Filename, CacheBase Cache, CacheBase.IndexItem Tag, BitmapFormat Format, bool Alpha)
        {
            var bitm = DefinitionsManager.bitm(Cache, Tag);

            SaveAllImages(Filename, Cache, bitm, Format, Alpha);
        }
Exemple #17
0
        private void loadBspTag(CacheBase Cache, CacheBase.IndexItem Tag, bool Specular, bool Force)
        {
            if (!this.Enabled)
            {
                this.Enabled = true;
            }
            tvRegions.Nodes.Clear();
            if (renderer1.Running)
            {
                renderer1.Stop("Loading...");
            }
            Refresh();

            cache = Cache;
            tag   = Tag;

            sbsp         = DefinitionsManager.sbsp(cache, tag);
            sbsp.BSPName = Path.GetFileNameWithoutExtension(tag.Filename + "." + tag.ClassCode);
            sbsp.LoadRaw();

            isWorking = true;

            #region Build Tree
            TreeNode ClusterNode = new TreeNode("Clusters")
            {
                Checked = true
            };
            foreach (var clust in sbsp.Clusters)
            {
                if (clust.SectionIndex >= sbsp.ModelSections.Count)
                {
                    continue;
                }
                if (sbsp.ModelSections[clust.SectionIndex].Submeshes.Count > 0)
                {
                    ClusterNode.Nodes.Add(new TreeNode(sbsp.Clusters.IndexOf(clust).ToString("D3"))
                    {
                        Tag = clust, Checked = true
                    });
                }
            }
            if (ClusterNode.Nodes.Count > 0)
            {
                tvRegions.Nodes.Add(ClusterNode);
            }

            TreeNode IGnode = new TreeNode("Instances")
            {
                Checked = true
            };
            foreach (var IG in sbsp.GeomInstances)
            {
                if (IG.SectionIndex >= sbsp.ModelSections.Count)
                {
                    continue;
                }
                if (sbsp.ModelSections[IG.SectionIndex].Submeshes.Count > 0)
                {
                    IGnode.Nodes.Add(new TreeNode(IG.Name)
                    {
                        Tag = IG, Checked = true
                    });
                }
            }
            if (IGnode.Nodes.Count > 0)
            {
                tvRegions.Nodes.Add(IGnode);
            }

            tvRegions.Sort(); //much easier for looking through IGs
            #endregion

            isWorking = false;

            #region Load Stuff
            LoadShaders(false);
            LoadSections();

            foreach (var clust in sbsp.Clusters)
            {
                AddCluster(clust, Force);
            }

            foreach (var ig in sbsp.GeomInstances)
            {
                AddGeomInstance(ig, Force);
            }
            #endregion

            #region BoundingBox Stuff
            PerspectiveCamera camera = (PerspectiveCamera)renderer1.Viewport.Camera;

            var XBounds = new RealBounds(float.MaxValue, float.MinValue);
            var YBounds = new RealBounds(float.MaxValue, float.MinValue);
            var ZBounds = new RealBounds(float.MaxValue, float.MinValue);

            #region Get Bounds
            foreach (var c in sbsp.Clusters)
            {
                if (c.SectionIndex >= sbsp.ModelSections.Count)
                {
                    continue;
                }
                if (sbsp.ModelSections[c.SectionIndex].Submeshes.Count == 0)
                {
                    continue;
                }

                if (c.XBounds.Min < XBounds.Min)
                {
                    XBounds.Min = c.XBounds.Min;
                }
                if (c.YBounds.Min < YBounds.Min)
                {
                    YBounds.Min = c.YBounds.Min;
                }
                if (c.ZBounds.Min < ZBounds.Min)
                {
                    ZBounds.Min = c.ZBounds.Min;
                }

                if (c.XBounds.Max > XBounds.Max)
                {
                    XBounds.Max = c.XBounds.Max;
                }
                if (c.YBounds.Max > YBounds.Max)
                {
                    YBounds.Max = c.YBounds.Max;
                }
                if (c.ZBounds.Max > ZBounds.Max)
                {
                    ZBounds.Max = c.ZBounds.Max;
                }
            }

            //foreach (var bb in sbsp.BoundingBoxes)
            //{
            //    if (bb.XBounds.Min < XBounds.Min) XBounds.Min = bb.XBounds.Min;
            //    if (bb.YBounds.Min < YBounds.Min) YBounds.Min = bb.YBounds.Min;
            //    if (bb.ZBounds.Min < ZBounds.Min) ZBounds.Min = bb.ZBounds.Min;

            //    if (bb.XBounds.Max > XBounds.Max) XBounds.Max = bb.XBounds.Max;
            //    if (bb.YBounds.Max > YBounds.Max) YBounds.Max = bb.YBounds.Max;
            //    if (bb.ZBounds.Max > ZBounds.Max) ZBounds.Max = bb.ZBounds.Max;
            //}
            #endregion

            double pythagoras3d = Math.Sqrt(
                Math.Pow(XBounds.Length, 2) +
                Math.Pow(YBounds.Length, 2) +
                Math.Pow(ZBounds.Length, 2));

            if (double.IsInfinity(pythagoras3d) || pythagoras3d == 0) //no clusters
            {
                XBounds = sbsp.XBounds;
                YBounds = sbsp.YBounds;
                ZBounds = sbsp.ZBounds;

                pythagoras3d = Math.Sqrt(
                    Math.Pow(XBounds.Length, 2) +
                    Math.Pow(YBounds.Length, 2) +
                    Math.Pow(ZBounds.Length, 2));
            }

            if (XBounds.Length / 2 > (YBounds.Length)) //side view
            {
                var p = new Point3D(
                    XBounds.MidPoint,
                    YBounds.Max + pythagoras3d * 0.5,
                    ZBounds.MidPoint);
                renderer1.MoveCamera(p, new Vector3D(0, 0, -2));
            }
            else //normal camera position
            {
                var p = new Point3D(
                    XBounds.Max + pythagoras3d * 0.5,
                    YBounds.MidPoint,
                    ZBounds.MidPoint);
                renderer1.MoveCamera(p, new Vector3D(-1, 0, 0));
            }

            renderer1.CameraSpeed    = Math.Ceiling(pythagoras3d * 3) / 1000;
            renderer1.MaxCameraSpeed = Math.Ceiling(pythagoras3d * 3) * 5 / 1000;
            renderer1.MaxPosition    = new Point3D(
                sbsp.XBounds.Max + pythagoras3d * 2,
                sbsp.YBounds.Max + pythagoras3d * 2,
                sbsp.ZBounds.Max + pythagoras3d * 2);
            renderer1.MinPosition = new Point3D(
                sbsp.XBounds.Min - pythagoras3d * 2,
                sbsp.YBounds.Min - pythagoras3d * 2,
                sbsp.ZBounds.Min - pythagoras3d * 2);
            renderer1.FarPlaneMin = pythagoras3d * 0.1;
            renderer1.FarPlane    = pythagoras3d;
            renderer1.FarPlaneMax = pythagoras3d;
            #endregion

            renderer1.Start();
            RenderSelected();
        }
        /// <summary>
        /// Saves selected permutations of a sound tag.
        /// </summary>
        /// <param name="Folder">The folder to save all files in. Each file will be named as the permutation name.</param>
        /// <param name="Cache">The CacheFile containing the tag.</param>
        /// <param name="Tag">The sound tag.</param>
        /// <param name="Format">The format in which to save the data.</param>
        /// <param name="Indices">The indices of the permutations to extract.</param>
        public static void SaveSelected(string Folder, CacheBase Cache, CacheBase.IndexItem Tag, SoundFormat Format, List <int> Indices, bool Overwrite)
        {
            var           snd_  = DefinitionsManager.snd_(Cache, Tag);
            List <byte[]> perms = new List <byte[]>();

            var ugh_     = Cache.ugh_;
            var playback = ugh_.PlayBacks[snd_.PlaybackIndex];
            var data     = Cache.GetSoundRaw(snd_.RawID, GetTotalSize(ugh_, playback));

            if (playback.PermutationCount == 1)
            {
                perms.Add(data);
            }
            else
            {
                Folder = Directory.GetParent(Folder) + "\\" + Path.GetFileNameWithoutExtension(Folder);

                for (int i = 0; i < playback.PermutationCount; i++)
                {
                    var perm = Cache.ugh_.SoundPermutations[playback.FirstPermutation + i];
                    perms.Add(GetPermData(data, ugh_, perm));
                }
            }

            #region XMA
            if (Format == SoundFormat.XMA)
            {
                foreach (int index in Indices)
                {
                    string Filename = (playback.PermutationCount == 1) ? Folder : Folder + "\\" + ugh_.SoundNames[ugh_.SoundPermutations[playback.FirstPermutation + index].NameIndex].Name + ".xma";
                    if (!Filename.EndsWith(".xma"))
                    {
                        Filename += ".xma";
                    }

                    if (File.Exists(Filename) && !Overwrite)
                    {
                        continue;
                    }

                    byte[] buffer = perms[index];
                    var    codec  = Cache.ugh_.Codecs[snd_.CodecIndex];
                    var    xma    = GetXMA(buffer, snd_.SampleRate, codec.Type);

                    if (!Directory.GetParent(Filename).Exists)
                    {
                        Directory.GetParent(Filename).Create();
                    }

                    var          fs = new FileStream(Filename, FileMode.Create);
                    EndianWriter sw = new EndianWriter(fs, EndianFormat.BigEndian);
                    sw.Write(xma);

                    sw.Close();
                    sw.Dispose();
                }
            }
            #endregion
            #region WAV
            else if (Format == SoundFormat.WAV)
            {
                foreach (int index in Indices)
                {
                    string Filename = (playback.PermutationCount == 1) ? Folder : Folder + "\\" + ugh_.SoundNames[ugh_.SoundPermutations[playback.FirstPermutation + index].NameIndex].Name + ".wav";
                    if (!Filename.EndsWith(".wav"))
                    {
                        Filename += ".wav";
                    }

                    if (File.Exists(Filename) && !Overwrite)
                    {
                        continue;
                    }

                    var tempName = Path.GetTempFileName();

                    #region Write XMA
                    var buffer = perms[index];
                    var codec  = Cache.ugh_.Codecs[snd_.CodecIndex];
                    var xma    = GetXMA(buffer, snd_.SampleRate, codec.Type);

                    var          fs = File.OpenWrite(tempName);
                    EndianWriter sw = new EndianWriter(fs, EndianFormat.BigEndian);
                    sw.Write(xma);

                    sw.Close();
                    sw.Dispose();
                    #endregion

                    var info = new ProcessStartInfo(towav, tempName)
                    {
                        CreateNoWindow   = true,
                        UseShellExecute  = false,
                        WorkingDirectory = Directory.GetParent(tempName).FullName
                    };

                    Process.Start(info).WaitForExit();

                    if (File.Exists(Filename))
                    {
                        File.Delete(Filename);
                    }
                    if (!Directory.GetParent(Filename).Exists)
                    {
                        Directory.GetParent(Filename).Create();
                    }
                    File.Move(Path.ChangeExtension(tempName, "wav"), Filename);
                    if (File.Exists(tempName))
                    {
                        File.Delete(tempName);
                    }
                }
            }
            #endregion
            #region RAW
            else if (Format == SoundFormat.RAW)
            {
                foreach (int index in Indices)
                {
                    string Filename = (playback.PermutationCount == 1) ? Folder : Folder + "\\" + ugh_.SoundNames[ugh_.SoundPermutations[playback.FirstPermutation + index].NameIndex].Name + ".bin";
                    if (!Filename.EndsWith(".bin"))
                    {
                        Filename += ".bin";
                    }

                    if (File.Exists(Filename) && !Overwrite)
                    {
                        continue;
                    }

                    byte[] buffer = perms[index];

                    if (!Directory.GetParent(Filename).Exists)
                    {
                        Directory.GetParent(Filename).Create();
                    }

                    var          fs = new FileStream(Filename, FileMode.Create);
                    BinaryWriter sw = new BinaryWriter(fs);

                    sw.Write(buffer);
                    sw.Close();
                    sw.Dispose();
                }
            }
            #endregion
        }
        private void RecursiveExtract(object SaveFolder)
        {
            List <CacheBase.IndexItem> tagsDone = new List <CacheBase.IndexItem>();

            foreach (render_model.Shader shader in mode.Shaders)
            {
                var rmshTag = cache.IndexItems.GetItemByID(shader.tagID);
                if (rmshTag == null)
                {
                    continue;
                }
                var rmsh = DefinitionsManager.rmsh(cache, rmshTag);

                #region Halo 2 Extract
                if (cache.Version == DefinitionSet.Halo2Xbox)
                {
                    var h2rmsh = rmsh as Definitions.Halo2Xbox.shader;
                    for (int i = 0; i < h2rmsh.BitmIDs.Length; i++)
                    {
                        var bitmTag = cache.IndexItems.GetItemByID(h2rmsh.BitmIDs[i]);
                        if (bitmTag == null)
                        {
                            continue;
                        }

                        //dont need to waste time extracting the same ones over and over
                        if (tagsDone.Contains(bitmTag))
                        {
                            continue;
                        }

                        try
                        {
                            BitmapExtractor.SaveAllImages((string)SaveFolder + "\\" + bitmTag.Filename, cache, bitmTag, DefaultBitmFormat, true);
                            TagExtracted(this, bitmTag);
                        }
                        catch (Exception ex) { ErrorExtracting(this, bitmTag, ex); }

                        tagsDone.Add(bitmTag);
                    }
                    continue;
                }
                #endregion

                foreach (Definitions.shader.ShaderProperties prop in rmsh.Properties)
                {
                    foreach (Definitions.shader.ShaderProperties.ShaderMap map in prop.ShaderMaps)
                    {
                        var bitmTag = cache.IndexItems.GetItemByID(map.BitmapTagID);
                        if (bitmTag == null)
                        {
                            continue;
                        }

                        //dont need to waste time extracting the same ones over and over
                        if (tagsDone.Contains(bitmTag))
                        {
                            continue;
                        }

                        try
                        {
                            BitmapExtractor.SaveAllImages((string)SaveFolder + "\\" + bitmTag.Filename, cache, bitmTag, DefaultBitmFormat, true);
                            TagExtracted(this, bitmTag);
                        }
                        catch (Exception ex) { ErrorExtracting(this, bitmTag, ex); }

                        tagsDone.Add(bitmTag);
                    }
                }
            }
            FinishedRecursiveExtract(this, tag);
        }
Exemple #20
0
        private void LoadShaders(bool spec)
        {
            var errMat = GetErrorMaterial();

            if (mode.Shaders.Count == 0)
            {
                var matGroup = new MaterialGroup();
                matGroup.Children.Add(errMat);
                shaders.Add(matGroup);
            }

            foreach (render_model.Shader s in mode.Shaders)
            {
                #region Skip Unused
                bool found = false;
                foreach (var sec in mode.ModelSections)
                {
                    foreach (var sub in sec.Submeshes)
                    {
                        if (sub.ShaderIndex == mode.Shaders.IndexOf(s))
                        {
                            found = true;
                            break;
                        }
                    }
                    if (found)
                    {
                        break;
                    }
                }

                if (!found)
                {
                    shaders.Add(null);
                    continue;
                }
                #endregion

                var matGroup = new MaterialGroup();

                try
                {
                    var rmshTag = cache.IndexItems.GetItemByID(s.tagID);
                    var rmsh    = DefinitionsManager.rmsh(cache, rmshTag);

                    int mapIndex = 0;
                    if (cache.Version >= DefinitionSet.Halo3Beta && cache.Version <= DefinitionSet.HaloReachRetail)
                    {
                        var rmt2Tag = cache.IndexItems.GetItemByID(rmsh.Properties[0].TemplateTagID);
                        var rmt2    = DefinitionsManager.rmt2(cache, rmt2Tag);

                        for (int i = 0; i < rmt2.UsageBlocks.Count; i++)
                        {
                            if (rmt2.UsageBlocks[i].Usage == "base_map")
                            {
                                mapIndex = i;
                                break;
                            }
                        }
                    }

                    var bitmTag = cache.IndexItems.GetItemByID(rmsh.Properties[0].ShaderMaps[mapIndex].BitmapTagID);
                    var image   = BitmapExtractor.GetBitmapByTag(cache, bitmTag, 0, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

                    if (image == null)
                    {
                        matGroup.Children.Add(errMat);
                        shaders.Add(matGroup);
                        continue;
                    }

                    int   tileIndex = rmsh.Properties[0].ShaderMaps[mapIndex].TilingIndex;
                    float uTiling;
                    try { uTiling = rmsh.Properties[0].Tilings[tileIndex].UTiling; }
                    catch { uTiling = 1; }

                    float vTiling;
                    try { vTiling = rmsh.Properties[0].Tilings[tileIndex].VTiling; }
                    catch { vTiling = 1; }

                    MemoryStream stream = new MemoryStream();                                                        //PNG for transparency
                    image.Save(stream, (rmshTag.ClassCode == "rmsh" || rmshTag.ClassCode == "mat") ? ImageFormat.Bmp : ImageFormat.Bmp);

                    var diffuse = new BitmapImage();

                    diffuse.BeginInit();
                    diffuse.StreamSource = new MemoryStream(stream.ToArray());
                    diffuse.EndInit();

                    matGroup.Children.Add(new DiffuseMaterial()
                    {
                        Brush = new ImageBrush(diffuse)
                        {
                            ViewportUnits = BrushMappingMode.Absolute,
                            TileMode      = TileMode.Tile,
                            Viewport      = new System.Windows.Rect(0, 0, 1f / Math.Abs(uTiling), 1f / Math.Abs(vTiling))
                        }
                    });

                    if (spec && rmshTag.ClassCode == "rmsh")
                    {
                        stream = new MemoryStream();
                        image.Save(stream, ImageFormat.Png);

                        var specular = new BitmapImage();

                        specular.BeginInit();
                        specular.StreamSource = new MemoryStream(stream.ToArray());
                        specular.EndInit();

                        matGroup.Children.Add(new SpecularMaterial()
                        {
                            SpecularPower = 10,
                            Brush         = new ImageBrush(specular)
                            {
                                ViewportUnits = BrushMappingMode.Absolute,
                                TileMode      = TileMode.Tile,
                                Viewport      = new System.Windows.Rect(0, 0, 1f / Math.Abs(uTiling), 1f / Math.Abs(vTiling))
                            }
                        });
                    }

                    shaders.Add(matGroup);
                }
                catch
                {
                    matGroup.Children.Add(errMat);
                    shaders.Add(matGroup);
                }
            }
        }
Exemple #21
0
        /// <summary>
        /// Save all permutations of a sound tag as separate sound files.
        /// </summary>
        /// <param name="Folder">The base filename. Permutation names will be appended accordingly.</param>
        /// <param name="Cache">The CacheFile containing the tag.</param>
        /// <param name="Tag">The sound tag.</param>
        /// <param name="Format">The format in which to save the data.</param>
        public void SaveAllAsSeparate(string Folder, CacheBase Cache, CacheBase.IndexItem Tag, SoundFormat Format, bool Overwrite)
        {
            if (Format != SoundFormat.WAV)
            {
                throw new NotSupportedException("Halo4Retail only supports WAV.");
            }
            if (Cache.Version != DefinitionSet.Halo4Retail)
            {
                throw new Exception("This is for H4 ONLY");
            }

            if (scanner == null)
            {
                scanner = new SoundScanner();
                scanner.FoundSoundBankFile += FoundSoundBankFile;
                scanner.FoundSoundPackFile += FoundSoundPackFile;
            }

            cache = (CacheH4R)Cache;
            tag   = Tag;

            snd = (SoundH4R)DefinitionsManager.snd_(cache, tag);

            LoadCacheSoundPacks(cache);

            if (cache.SoundFiles == null)
            {
                cache.SoundFiles = new Dictionary <uint, List <SoundFileInfo> >();
                ObjectLoadWorker();
            }

            bool s1, s2;
            List <SoundFileInfo> sfi1, sfi2, sfi3;

            s1 = cache.SoundFiles.TryGetValue(snd.SoundAddress1, out sfi1);
            s2 = cache.SoundFiles.TryGetValue(snd.SoundAddress2, out sfi2);

            if (!s1 && !s2)
            {
                throw new Exception("No permutations found.");
            }

            sfi3 = new List <SoundFileInfo>();
            if (s1)
            {
                sfi3.AddRange(sfi1);
            }
            if (s2)
            {
                sfi3.AddRange(sfi2);
            }

            for (int i = 0; i < sfi3.Count; i++)
            {
                var info = sfi3[i];

                var fName = Path.GetFileName(tag.Filename);

                fName = Folder + "\\" + fName + " [" + i.ToString() + "]" + ".wav";

                if (File.Exists(fName) && !Overwrite)
                {
                    return;
                }

                RIFX rifx = ReadRIFX(info);

                switch (info.Format)
                {
                case Composer.SoundFormat.XMA:
                    if (!Directory.GetParent(fName).Exists)
                    {
                        Directory.GetParent(fName).Create();
                    }
                    SoundExtraction.ExtractXMAToWAV(info.Reader, info.Offset, rifx, fName);
                    break;

                case Composer.SoundFormat.WwiseOGG:
                    if (!Directory.GetParent(fName).Exists)
                    {
                        Directory.GetParent(fName).Create();
                    }
                    SoundExtraction.ExtractWwiseToOGG(info.Reader, info.Offset, info.Size, fName);
                    break;

                default:
                    throw new NotSupportedException(info.Format.ToString() + " not supported.");
                }
            }
        }
Exemple #22
0
        private void loadModelTag(CacheBase Cache, CacheBase.IndexItem Tag, bool Specular, bool UserPermFilter, bool Force)
        {
            if (!this.Enabled)
            {
                this.Enabled = true;
            }
            tvRegions.Nodes.Clear();
            if (renderer1.Running)
            {
                renderer1.Stop("Loading...");
            }
            Refresh();

            cache = Cache;
            tag   = Tag;

            mode = DefinitionsManager.mode(cache, tag);
            mode.LoadRaw();

            isWorking = true;

            #region Build Tree
            foreach (var region in mode.Regions)
            {
                TreeNode node = new TreeNode(region.Name)
                {
                    Tag = region
                };
                foreach (var perm in region.Permutations)
                {
                    if (perm.PieceIndex != -1)
                    {
                        if (mode.ModelSections[perm.PieceIndex].Submeshes.Count > 0)
                        {
                            node.Nodes.Add(new TreeNode(perm.Name)
                            {
                                Tag = perm
                            });
                        }
                    }
                }
                if (node.Nodes.Count > 0)
                {
                    tvRegions.Nodes.Add(node);
                }
            }

            if (UserPermFilter)
            {
                foreach (TreeNode node in tvRegions.Nodes)
                {
                    foreach (TreeNode child in node.Nodes)
                    {
                        if (PermutationFilter.Contains((child.Tag as render_model.Region.Permutation).Name))
                        {
                            child.Checked = node.Checked = true;
                        }
                    }
                }
            }
            else
            {
                foreach (TreeNode node in tvRegions.Nodes)
                {
                    node.Nodes[0].Checked = node.Checked = true;
                }
            }
            #endregion

            isWorking = false;

            LoadShaders(Specular);
            LoadMeshes(Force);

            #region BoundingBox Stuff
            PerspectiveCamera camera = (PerspectiveCamera)renderer1.Viewport.Camera;

            var bb = mode.BoundingBoxes[0];

            double pythagoras3d = Math.Sqrt(
                Math.Pow(bb.XBounds.Length, 2) +
                Math.Pow(bb.YBounds.Length, 2) +
                Math.Pow(bb.ZBounds.Length, 2));

            if (bb.XBounds.Length / 2 > (bb.YBounds.Length)) //side view for long models like weapons
            {
                var p = new Point3D(
                    bb.XBounds.MidPoint,
                    bb.YBounds.Max + pythagoras3d * 0.75,
                    bb.ZBounds.MidPoint);
                renderer1.MoveCamera(p, new Vector3D(0, 0, -2));
            }
            else //normal camera position
            {
                var p = new Point3D(
                    bb.XBounds.Max + pythagoras3d * 0.75,
                    bb.YBounds.MidPoint,
                    bb.ZBounds.MidPoint);
                renderer1.MoveCamera(p, new Vector3D(-1, 0, 0));
            }

            renderer1.CameraSpeed    = Math.Ceiling(pythagoras3d * 5) / 1000;
            renderer1.MaxCameraSpeed = Math.Ceiling(pythagoras3d * 5) * 7 / 1000;
            renderer1.MaxPosition    = new Point3D(
                bb.XBounds.Max + pythagoras3d * 3,
                bb.YBounds.Max + pythagoras3d * 3,
                bb.ZBounds.Max + pythagoras3d * 3);
            renderer1.MinPosition = new Point3D(
                bb.XBounds.Min - pythagoras3d * 3,
                bb.YBounds.Min - pythagoras3d * 3,
                bb.ZBounds.Min - pythagoras3d * 3);
            renderer1.FarPlaneMin = 100;
            renderer1.FarPlane    = 1000;
            renderer1.FarPlaneMax = 5000;
            #endregion

            RenderSelected();
            renderer1.Start();
        }
        /// <summary>
        /// Saves all permutations of a sound tag concatenated as a single sound file.
        /// </summary>
        /// <param name="Filename">The file to save the data to.</param>
        /// <param name="Cache">The CacheFile containing the tag.</param>
        /// <param name="Tag">The sound tag.</param>
        /// <param name="Format">The format in which to save the data.</param>
        public static void SaveAllAsSingle(string Filename, CacheBase Cache, CacheBase.IndexItem Tag, SoundFormat Format)
        {
            var snd_ = DefinitionsManager.snd_(Cache, Tag);

            #region XMA
            if (Format == SoundFormat.XMA)
            {
                var total = GetTotalSize(Cache.ugh_, Cache.ugh_.PlayBacks[snd_.PlaybackIndex]);

                byte[] buffer = Cache.GetSoundRaw(snd_.RawID, total);

                if (buffer.Length == 0)
                {
                    throw new Exception("Empty raw data.");
                }
                var codec = Cache.ugh_.Codecs[snd_.CodecIndex];
                var xma   = GetXMA(buffer, snd_.SampleRate, codec.Type);

                if (!Directory.GetParent(Filename).Exists)
                {
                    Directory.GetParent(Filename).Create();
                }

                var          fs = File.OpenWrite(Filename);
                EndianWriter sw = new EndianWriter(fs, EndianFormat.BigEndian);
                sw.Write(xma);

                sw.Close();
                sw.Dispose();
            }
            #endregion
            #region WAV
            else if (Format == SoundFormat.WAV)
            {
                var tempName = Path.GetTempFileName();

                SaveAllAsSingle(tempName, Cache, Tag, SoundFormat.XMA);

                var info = new ProcessStartInfo(towav, tempName)
                {
                    CreateNoWindow   = true,
                    UseShellExecute  = false,
                    WorkingDirectory = Directory.GetParent(tempName).FullName
                };

                Process.Start(info).WaitForExit();

                if (File.Exists(Filename))
                {
                    File.Delete(Filename);
                }
                if (!Directory.GetParent(Filename).Exists)
                {
                    Directory.GetParent(Filename).Create();
                }
                File.Move(Path.ChangeExtension(tempName, "wav"), Filename);
                if (File.Exists(tempName))
                {
                    File.Delete(tempName);
                }
            }
            #endregion
            #region RAW
            else if (Format == SoundFormat.RAW)
            {
                byte[] buffer = Cache.GetSoundRaw(snd_.RawID, GetTotalSize(Cache.ugh_, Cache.ugh_.PlayBacks[snd_.PlaybackIndex]));

                if (!Directory.GetParent(Filename).Exists)
                {
                    Directory.GetParent(Filename).Create();
                }

                var          fs = new FileStream(Filename, FileMode.Create);
                BinaryWriter sw = new BinaryWriter(fs);

                sw.Write(buffer);
                sw.Close();
                sw.Dispose();
            }
            #endregion
            #region Other
            else
            {
                throw new InvalidOperationException("Invalid sound format received.");
            }
            #endregion
        }
Exemple #24
0
        /// <summary>
        /// Gets an image from a bitmap tag.
        /// </summary>
        /// <param name="Cache">The CacheFile containing the bitmap tag.</param>
        /// <param name="Tag">The bitmap tag.</param>
        /// <param name="Index">The index of the BitmapData chunk to use.</param>
        /// <param name="Alpha">Whether to include the alpha channel in the image.</param>
        /// <returns>The image from the bitmap tag as a Bitmap.</returns>
        public static Bitmap GetBitmapByTag(CacheBase Cache, CacheBase.IndexItem Tag, int Index, PixelFormat PF)
        {
            var bitm = DefinitionsManager.bitm(Cache, Tag);

            return(GetBitmapByTag(Cache, bitm, Index, PF));
        }
Exemple #25
0
        /// <summary>
        /// Gets all images from the a bitmap tag.
        /// </summary>
        /// <param name="Cache">The CacheFile containing the bitmap tag.</param>
        /// <param name="Tag">The bitmap tag.</param>
        /// <param name="Alpha">Whether to include the alpha channels in the images.</param>
        /// <returns>A List containing each image as a Bitmap.</returns>
        public static List <Bitmap> GetBitmapsByTag(CacheBase Cache, CacheBase.IndexItem Tag, PixelFormat PF)
        {
            var bitm = DefinitionsManager.bitm(Cache, Tag);

            return(GetBitmapsByTag(Cache, bitm, PF));
        }
        public override bool Execute(List <string> args)
        {
            if (args.Count != 1)
            {
                return(false);
            }

            //
            // Verify and load the blam shader
            //

            var shaderName = args[0];

            CacheBase.IndexItem item = null;

            Console.WriteLine("Verifying blam shader tag...");

            foreach (var tag in BlamCache.IndexItems)
            {
                if ((tag.ParentClass == "rm") && tag.Filename == shaderName)
                {
                    item = tag;
                    break;
                }
            }

            if (item == null)
            {
                Console.WriteLine("Blam shader tag does not exist: " + shaderName);
                return(false);
            }

            var renderMethod = DefinitionsManager.rmsh(BlamCache, item);

            var templateItem = BlamCache.IndexItems.Find(i =>
                                                         i.ID == renderMethod.Properties[0].TemplateTagID);

            var template = DefinitionsManager.rmt2(BlamCache, templateItem);

            //
            // Determine the blam shader's base bitmap
            //

            var bitmapIndex   = -1;
            var bitmapArgName = "";

            for (var i = 0; i < template.UsageBlocks.Count; i++)
            {
                var entry = template.UsageBlocks[i];

                if (entry.Usage.StartsWith("base_map") ||
                    entry.Usage.StartsWith("diffuse_map") ||
                    entry.Usage == "foam_texture")
                {
                    bitmapIndex   = i;
                    bitmapArgName = entry.Usage;
                    break;
                }
            }

            //
            // Load and decode the blam shader's base bitmap
            //

            var bitmItem = BlamCache.IndexItems.Find(i =>
                                                     i.ID == renderMethod.Properties[0].ShaderMaps[bitmapIndex].BitmapTagID);

            var bitm   = DefinitionsManager.bitm(BlamCache, bitmItem);
            var submap = bitm.Bitmaps[0];

            byte[] raw;

            if (BlamCache.Version <= DefinitionSet.Halo2Vista)
            {
                raw = BlamCache.GetRawFromID(submap.PixelsOffset, submap.RawSize);
            }
            else
            {
                if (bitm.RawChunkBs.Count > 0)
                {
                    int    rawID  = bitm.RawChunkBs[submap.InterleavedIndex].RawID;
                    byte[] buffer = BlamCache.GetRawFromID(rawID);
                    raw = new byte[submap.RawSize];
                    Array.Copy(buffer, submap.Index2 * submap.RawSize, raw, 0, submap.RawSize);
                }
                else
                {
                    int rawID = bitm.RawChunkAs[0].RawID;
                    raw = BlamCache.GetRawFromID(rawID, submap.RawSize);
                }
            }

            var vHeight = submap.VirtualHeight;
            var vWidth  = submap.VirtualWidth;

            var ms = new MemoryStream();
            var bw = new BinaryWriter(ms);

            if (submap.Flags.Values[3])
            {
                raw = DXTDecoder.ConvertToLinearTexture(raw, vWidth, vHeight, submap.Format);
            }

            if (submap.Format != BitmapFormat.A8R8G8B8)
            {
                for (int i = 0; i < raw.Length; i += 2)
                {
                    Array.Reverse(raw, i, 2);
                }
            }
            else
            {
                for (int i = 0; i < (raw.Length); i += 4)
                {
                    Array.Reverse(raw, i, 4);
                }
            }

            new DDS(submap).Write(bw);
            bw.Write(raw);

            raw = ms.ToArray();

            bw.Close();
            bw.Dispose();

            //
            // ElDorado Serialization
            //

            using (var cacheStream = Info.CacheFile.Open(FileMode.Open, FileAccess.ReadWrite))
            {
                //
                // Create the new eldorado bitmap
                //

                var resourceManager = new ResourceDataManager();
                resourceManager.LoadCachesFromDirectory(Info.CacheFile.DirectoryName);

                var newBitm = Info.Cache.DuplicateTag(cacheStream, Info.Cache.Tags[0x101F]);

                var bitmap = new TagDefinitions.Bitmap
                {
                    Flags     = TagDefinitions.Bitmap.RuntimeFlags.UseResource,
                    Sequences = new List <TagDefinitions.Bitmap.Sequence>
                    {
                        new TagDefinitions.Bitmap.Sequence
                        {
                            Name             = "",
                            FirstBitmapIndex = 0,
                            BitmapCount      = 1
                        }
                    },
                    Images = new List <TagDefinitions.Bitmap.Image>
                    {
                        new TagDefinitions.Bitmap.Image
                        {
                            Signature = new Tag("bitm").Value,
                            Unknown28 = -1
                        }
                    },
                    Resources = new List <TagDefinitions.Bitmap.BitmapResource>
                    {
                        new TagDefinitions.Bitmap.BitmapResource()
                    }
                };

                using (var imageStream = new MemoryStream(raw))
                {
                    var injector = new BitmapDdsInjector(resourceManager);
                    imageStream.Seek(0, SeekOrigin.Begin);
                    injector.InjectDds(Info.Serializer, Info.Deserializer, bitmap, 0, imageStream);
                }

                var context = new TagSerializationContext(cacheStream, Info.Cache, Info.StringIDs, newBitm);
                Info.Serializer.Serialize(context, bitmap);

                //
                // Create the new eldorado shader
                //

                var newRmsh = Info.Cache.DuplicateTag(cacheStream, Info.Cache.Tags[0x331A]);
                context = new TagSerializationContext(cacheStream, Info.Cache, Info.StringIDs, newRmsh);
                var shader = Info.Deserializer.Deserialize <TagDefinitions.Shader>(context);

                shader.ShaderProperties[0].ShaderMaps[0].Bitmap = newBitm;

                Info.Serializer.Serialize(context, shader);

                Console.WriteLine("Done! New shader tag is 0x" + newRmsh.Index.ToString("X8"));
            }

            return(true);
        }