Ejemplo n.º 1
0
 public ListVariantsCommand(OpenTagCache info, Model model)
     : base(CommandFlags.Inherit,
     "listvariants",
     "List available variants of the current model definition.",
     "listvariants",
     "Lists available variants of the current model definition which can be used with \"extractmodel\".")
 {
     Info = info;
     Definition = model;
 }
Ejemplo n.º 2
0
        public static CommandContext Create(CommandContext parent, OpenTagCache info, TagInstance tag, Model model)
        {
            var groupName = info.StringIDs.GetString(tag.Group.Name);

            var context = new CommandContext(parent,
                string.Format("{0:X8}.{1}", tag.Index, groupName));

            Populate(context, info, tag, model);

            return context;
        }
Ejemplo n.º 3
0
 public ExtractModelCommand(OpenTagCache info, Model model)
     : base(CommandFlags.Inherit,
           "extractmodel",
           "Extracts a render model from the current model definition.",
           "extractmodel <variant> <filetype> <filename>",
           "Extracts a variant of the render model to a file.\n" +
           "Use the \"listvariants\" command to list available variants.\n" +
           "If the model does not have any variants, just use \"default\".\n" +
           "Supported file types: obj")
 {
     Info = info;
     Definition = model;
 }
Ejemplo n.º 4
0
 public static void Populate(CommandContext context, OpenTagCache info, TagInstance tag, Model model)
 {
     context.AddCommand(new ListVariantsCommand(info, model));
     context.AddCommand(new ExtractModelCommand(info, model));
 }
Ejemplo n.º 5
0
        private bool ExtractAMF(Model.Variant variant, string fileName)
        {
            // Load resource caches
            Console.WriteLine("Loading resource caches...");
            var resourceManager = new ResourceDataManager();
            try
            {
                resourceManager.LoadCachesFromDirectory(Info.CacheFile.DirectoryName);
            }
            catch
            {
                Console.WriteLine("Unable to load the resource .dat files.");
                Console.WriteLine("Make sure that they all exist and are valid.");
                return true;
            }

            // Deserialize the render model tag
            Console.WriteLine("Reading model data...");
            RenderModel renderModel;
            using (var cacheStream = Info.CacheFile.OpenRead())
            {
                var renderModelContext = new TagSerializationContext(cacheStream, Info.Cache, Info.StringIDs, Definition.RenderModel);
                renderModel = Info.Deserializer.Deserialize<RenderModel>(renderModelContext);
            }

            if (renderModel.Geometry.Resource == null)
            {
                Console.WriteLine("Render model does not have a resource associated with it");
                return true;
            }

            // Deserialize the resource definition
            var resourceContext = new ResourceSerializationContext(renderModel.Geometry.Resource);
            var definition = Info.Deserializer.Deserialize<RenderGeometryResourceDefinition>(resourceContext);

            using (var resourceStream = new MemoryStream())
            {
                // Extract the resource data
                resourceManager.Extract(renderModel.Geometry.Resource, resourceStream);

                var regionMeshes = new Dictionary<string, Mesh>();

                foreach (var region in variant.Regions)
                {
                    regionMeshes[Info.StringIDs.GetString(region.Name)] = renderModel.Geometry.Meshes[region.RenderModelRegionIndex];
                }

                var headerAddressList = new List<int>();
                var headerValueList = new List<int>();
                var markerAddressList = new List<int>();
                var markerValueList = new List<int>();
                var permAddressList = new List<int>();
                var permValueList = new List<int>();
                var vertAddressList = new List<int>();
                var indxAddressList = new List<int>();
                var meshAddressList = new List<int>();

                using (var bw = new BinaryWriter(File.Create(fileName)))
                {
                    #region Header
                    bw.Write("AMF!".ToCharArray());
                    bw.Write(2.0f); //format version
                    bw.Write((Info.StringIDs.GetString(renderModel.Name) + "\0").ToCharArray());

                    bw.Write(renderModel.Nodes.Count);
                    headerAddressList.Add((int)bw.BaseStream.Position);
                    bw.Write(0);

                    bw.Write(renderModel.MarkerGroups.Count);
                    headerAddressList.Add((int)bw.BaseStream.Position);
                    bw.Write(0);

                    bw.Write(regionMeshes.Count);
                    headerAddressList.Add((int)bw.BaseStream.Position);
                    bw.Write(0);

                    bw.Write(renderModel.Materials.Count);
                    headerAddressList.Add((int)bw.BaseStream.Position);
                    bw.Write(0);
                    #endregion
                    #region Nodes
                    headerValueList.Add((int)bw.BaseStream.Position);
                    foreach (var node in renderModel.Nodes)
                    {
                        bw.Write((Info.StringIDs.GetString(node.Name) + "\0").ToCharArray());
                        bw.Write((short)node.ParentNode);
                        bw.Write((short)node.FirstChildNode);
                        bw.Write((short)node.NextSiblingNode);
                        bw.Write(node.DefaultTranslation.X * 100);
                        bw.Write(node.DefaultTranslation.Y * 100);
                        bw.Write(node.DefaultTranslation.Z * 100);
                        bw.Write(node.DefaultRotation.X);
                        bw.Write(node.DefaultRotation.Y);
                        bw.Write(node.DefaultRotation.Z);
                        bw.Write(node.DefaultRotation.W);
                    }
                    #endregion
                    #region Marker Groups
                    headerValueList.Add((int)bw.BaseStream.Position);
                    foreach (var group in renderModel.MarkerGroups)
                    {
                        bw.Write((Info.StringIDs.GetString(group.Name) + "\0").ToCharArray());
                        bw.Write(group.Markers.Count);
                        markerAddressList.Add((int)bw.BaseStream.Position);
                        bw.Write(0);
                    }
                    #endregion
                    #region Markers
                    foreach (var group in renderModel.MarkerGroups)
                    {
                        markerValueList.Add((int)bw.BaseStream.Position);
                        foreach (var marker in group.Markers)
                        {
                            bw.Write((byte)marker.RegionIndex);
                            bw.Write((byte)marker.PermutationIndex);
                            bw.Write((short)marker.NodeIndex);
                            bw.Write(marker.Translation.X * 100);
                            bw.Write(marker.Translation.Y * 100);
                            bw.Write(marker.Translation.Z * 100);
                            bw.Write(marker.Rotation.X);
                            bw.Write(marker.Rotation.Y);
                            bw.Write(marker.Rotation.Z);
                            bw.Write(marker.Rotation.W);
                        }
                    }
                    #endregion
                    #region Regions
                    headerValueList.Add((int)bw.BaseStream.Position);
                    foreach (var region in renderModel.Regions)
                    {
                        bw.Write((Info.StringIDs.GetString(region.Name) + "\0").ToCharArray());
                        bw.Write(regionMeshes.Count);
                        permAddressList.Add((int)bw.BaseStream.Position);
                        bw.Write(0);
                    }
                    #endregion
                    #region Permutations
                    foreach (var part in regionMeshes)
                    {
                        permValueList.Add((int)bw.BaseStream.Position);
                        bw.Write((Info.StringIDs.GetString(variant.Name) + "\0").ToCharArray());

                        if (part.Value.Type == VertexType.Rigid)
                            bw.Write((byte)1);
                        else if (part.Value.Type == VertexType.Skinned)
                            bw.Write((byte)2);
                        else
                            throw new NotImplementedException();

                        bw.Write((byte)part.Value.RigidNodeIndex);

                        bw.Write(definition.VertexBuffers[part.Value.VertexBuffers[0]].Definition.Count);
                        vertAddressList.Add((int)bw.BaseStream.Position);
                        bw.Write(0);

                        int count = 0;
                        foreach (var submesh in part.Value.SubParts)
                            count += submesh.IndexCount;

                        bw.Write(count);
                        indxAddressList.Add((int)bw.BaseStream.Position);
                        bw.Write(0);

                        bw.Write(part.Value.SubParts.Count);
                        meshAddressList.Add((int)bw.BaseStream.Position);
                        bw.Write(0);

                        bw.Write(float.NaN); //no transforms (render_models are pre-transformed)
                    }
                    #endregion
                }
            }

            return true;
        }