Пример #1
0
        /// <summary>
        /// Reads Gfx Vertices
        /// </summary>
        public static Vertex[] ReadGfxVertices(ProcessReader reader, long address, int count)
        {
            // Preallocate vertex array
            Vertex[] vertices = new Vertex[count];
            // Read buffer
            var byteBuffer = reader.ReadBytes(address, count * 44);

            // Loop number of vertices we have
            for (int i = 0; i < count; i++)
            {
                // Read Struct
                var gfxVertex = ByteUtil.BytesToStruct <GfxVertex>(byteBuffer, i * 44);

                // Create new SEModel Vertex
                vertices[i] = new Vertex()
                {
                    // Set offset
                    Position = new Vector3(
                        gfxVertex.X * 2.54,
                        gfxVertex.Y * 2.54,
                        gfxVertex.Z * 2.54),
                    // Decode and set normal (from DTZxPorter - Wraith, same as XModels)
                    Normal = VertexNormalUnpacking.MethodA(gfxVertex.Normal),
                    // Set UV
                    UV = new Vector2(gfxVertex.U, 1 - gfxVertex.V)
                };
            }

            // Done
            return(vertices);
        }
Пример #2
0
        /// <summary>
        /// Reads Gfx Vertices
        /// </summary>
        public static Vertex[] ReadGfxVertices(ProcessReader reader, long positionsAddress, long uvsAddress, long normalsAddress, int count)
        {
            // Preallocate vertex array
            Vertex[] vertices = new Vertex[count];
            // Read buffer
            var positionsBuffer = reader.ReadBytes(positionsAddress, count * 12);
            var uvsBuffer       = reader.ReadBytes(uvsAddress, count * 8);
            var normalsBuffer   = reader.ReadBytes(normalsAddress, count * 4);

            // Loop number of vertices we have
            for (int i = 0; i < count; i++)
            {
                // Read Struct
                var gfxVertexPosition = ByteUtil.BytesToStruct <GfxVertexPosition>(positionsBuffer, i * 12);
                var gfxVertexUV       = ByteUtil.BytesToStruct <GfxVertexUV>(uvsBuffer, i * 8);
                var gfxVertexNormal   = ByteUtil.BytesToStruct <PackedUnitVector>(normalsBuffer, i * 4);

                // Create new SEModel Vertex
                vertices[i] = new Vertex()
                {
                    // Set offset
                    Position = new Vector3(
                        gfxVertexPosition.X * 2.54,
                        gfxVertexPosition.Y * 2.54,
                        gfxVertexPosition.Z * 2.54),
                    // Decode and set normal (from DTZxPorter - Wraith, same as XModels)
                    Normal = VertexNormalUnpacking.MethodB(gfxVertexNormal),
                    // Set UV
                    UV = new Vector2(gfxVertexUV.U, 1 - gfxVertexUV.V)
                };
            }

            // Done
            return(vertices);
        }
Пример #3
0
        public unsafe static List <IDictionary> CreateXModelDictionary(ProcessReader reader, long address, int count, List <IDictionary> MapEntities)
        {
            Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
            // Read buffer
            var byteBuffer = reader.ReadBytes(address, count * Marshal.SizeOf <GfxStaticModel>());
            // Loop number of models we have
            List <IDictionary> MapModels = new List <IDictionary>(count);

            for (int i = 0; i < count; i++)
            {
                Dictionary <string, string> ModelData = new Dictionary <string, string>();
                List <double> Position = new List <double>();
                List <double> angles   = new List <double>();
                // Read Struct
                var staticModel = ByteUtil.BytesToStruct <GfxStaticModel>(byteBuffer, i * Marshal.SizeOf <GfxStaticModel>());
                // Model Name
                var modelName = reader.ReadNullTerminatedString(reader.ReadInt32(staticModel.ModelPointer));

                var matrix = new Rotation.Matrix();
                // Copy X Values
                matrix.Values[0] = staticModel.Matrix[0];
                matrix.Values[1] = staticModel.Matrix[1];
                matrix.Values[2] = staticModel.Matrix[2];
                // Copy Y Values
                matrix.Values[4] = staticModel.Matrix[3];
                matrix.Values[5] = staticModel.Matrix[4];
                matrix.Values[6] = staticModel.Matrix[5];
                // Copy Z Values
                matrix.Values[8]  = staticModel.Matrix[6];
                matrix.Values[9]  = staticModel.Matrix[7];
                matrix.Values[10] = staticModel.Matrix[8];
                // Convert to Euler
                var euler = matrix.ToEuler();
                // Add it
                if (string.IsNullOrEmpty(modelName) == true || modelName.Contains("?") == true || modelName.Contains("'") == true || modelName.Contains("\\") == true || modelName.Contains("fx") == true || modelName.Contains("viewmodel") == true || staticModel.ModelScale < 0.001 || staticModel.ModelScale > 10)
                {
                }
                else
                {
                    ModelData.Add("Name", CleanInput(modelName));
                    ModelData.Add("PosX", string.Format("{0:0.0000}", staticModel.X));
                    ModelData.Add("PosY", string.Format("{0:0.0000}", staticModel.Y));
                    ModelData.Add("PosZ", string.Format("{0:0.0000}", staticModel.Z));
                    ModelData.Add("RotX", string.Format("{0:0.0000}", (float)Rotation.ToDegrees(euler).X).ToString(CultureInfo.InvariantCulture));
                    ModelData.Add("RotY", string.Format("{0:0.0000}", (float)Rotation.ToDegrees(euler).Y).ToString(CultureInfo.InvariantCulture));
                    ModelData.Add("RotZ", string.Format("{0:0.0000}", (float)Rotation.ToDegrees(euler).Z).ToString(CultureInfo.InvariantCulture));
                    ModelData.Add("Scale", string.Format("{0:0.0000}", staticModel.ModelScale).ToString(CultureInfo.InvariantCulture));
                    MapModels.Add(new Dictionary <string, string>(ModelData));
                }
            }
            foreach (IDictionary entity in MapEntities)
            {
                MapModels.Add(entity);
            }


            // Done
            return(MapModels);
        }
Пример #4
0
        /// <summary>
        /// Reads Static Models
        /// </summary>
        public unsafe static List <IWMap.Entity> ReadStaticModels(ProcessReader reader, long address, int count)
        {
            // Resulting Entities
            List <IWMap.Entity> entities = new List <IWMap.Entity>(count);
            // Read buffer
            var byteBuffer = reader.ReadBytes(address, count * Marshal.SizeOf <GfxStaticModel>());

            // Loop number of models we have
            for (int i = 0; i < count; i++)
            {
                // Read Struct
                var staticModel = ByteUtil.BytesToStruct <GfxStaticModel>(byteBuffer, i * Marshal.SizeOf <GfxStaticModel>());
                // Model Name
                var modelName = reader.ReadNullTerminatedString(reader.ReadInt64(staticModel.ModelPointer));
                // New Matrix
                var matrix = new Rotation.Matrix();
                // Copy X Values
                matrix.Values[0] = staticModel.Matrix[0];
                matrix.Values[1] = staticModel.Matrix[1];
                matrix.Values[2] = staticModel.Matrix[2];
                // Copy Y Values
                matrix.Values[4] = staticModel.Matrix[3];
                matrix.Values[5] = staticModel.Matrix[4];
                matrix.Values[6] = staticModel.Matrix[5];
                // Copy Z Values
                matrix.Values[8]  = staticModel.Matrix[6];
                matrix.Values[9]  = staticModel.Matrix[7];
                matrix.Values[10] = staticModel.Matrix[8];
                // Convert to Euler
                var euler = matrix.ToEuler();
                // Add it
                if (modelName.Contains("foliage"))
                {
                }
                else
                {
                    entities.Add(IWMap.Entity.CreateMiscModel(modelName, new Vector3(staticModel.X, staticModel.Y, staticModel.Z), Rotation.ToDegrees(euler), staticModel.ModelScale));
                }
            }



            // Done
            return(entities);
        }
Пример #5
0
        ///TODO: Fix this crap
        public static unsafe List <IWMap.Entity> ReadStaticModels(uint address, int count)
        {
            // Resulting Entities
            var entities = new List <IWMap.Entity>(count);
            // Read buffer
            var byteBuffer = console.GetMemory(address, (uint)(count * Marshal.SizeOf <GfxStaticModel>()));

            // Loop number of models we have
            for (var i = 0; i < count; i++)
            {
                // Read Struct
                var staticModel = ByteUtil.BytesToStruct <GfxStaticModel>(byteBuffer, i * Marshal.SizeOf <GfxStaticModel>());
                // Model Name
                var modelName = console.ReadString((uint)staticModel.ModelPointer);//reader.ReadNullTerminatedString(reader.ReadInt32(staticModel.ModelPointer));
                // New Matrix
                var matrix = new Rotation.Matrix
                {
                    Values =
                    {
                        [0]  = staticModel.Matrix[0],
                        [1]  = staticModel.Matrix[1],
                        [2]  = staticModel.Matrix[2],
                        [4]  = staticModel.Matrix[3],
                        [5]  = staticModel.Matrix[4],
                        [6]  = staticModel.Matrix[5],
                        [8]  = staticModel.Matrix[6],
                        [9]  = staticModel.Matrix[7],
                        [10] = staticModel.Matrix[8]
                    }
                };
                // Copy X Values
                // Copy Y Values
                // Copy Z Values
                // Convert to Euler
                var euler = matrix.ToEuler();
                // Add it
                entities.Add(IWMap.Entity.CreateMiscModel(modelName, new Vector3(staticModel.X, staticModel.Y, staticModel.Z), Rotation.ToDegrees(euler), staticModel.ModelScale));
            }
            // Done
            return(entities);
        }
Пример #6
0
        /// <summary>
        /// Reads BSP Data
        /// </summary>
        public static void ExportBSPData(ProcessReader reader, long assetPoolsAddress, long assetSizesAddress, string gameType, Action <object> printCallback = null)
        {
            // Found her
            printCallback?.Invoke("Found supported game: Call of Duty: Black Ops 2");
            // Validate by XModel Name
            if (reader.ReadNullTerminatedString(reader.ReadInt32(reader.ReadInt32(assetPoolsAddress + 0x14) + 4)) == "defaultvehicle")
            {
                // Load BSP Pools (they only have a size of 1 so we have no free header)
                var gfxMapAsset = reader.ReadStruct <GfxMap>(reader.ReadInt32(assetPoolsAddress + 0x44));

                // Name
                string gfxMapName = reader.ReadNullTerminatedString(gfxMapAsset.NamePointer);
                string mapName    = reader.ReadNullTerminatedString(gfxMapAsset.MapNamePointer);

                // Verify a BSP is actually loaded (if in base menu, etc, no map is loaded)
                if (String.IsNullOrWhiteSpace(gfxMapName))
                {
                    printCallback?.Invoke("No BSP loaded. Enter Main Menu or a Map to load in the required assets.");
                }
                else
                {
                    // New IW Map
                    var mapFile = new IWMap();
                    // Print Info
                    printCallback?.Invoke(String.Format("Loaded Gfx Map     -   {0}", gfxMapName));
                    printCallback?.Invoke(String.Format("Loaded Map         -   {0}", mapName));
                    printCallback?.Invoke(String.Format("Vertex Count       -   {0}", gfxMapAsset.GfxVertexCount));
                    printCallback?.Invoke(String.Format("Indices Count      -   {0}", gfxMapAsset.GfxIndicesCount));
                    printCallback?.Invoke(String.Format("Surface Count      -   {0}", gfxMapAsset.SurfaceCount));
                    printCallback?.Invoke(String.Format("Model Count        -   {0}", gfxMapAsset.GfxStaticModelsCount));

                    // Build output Folder
                    string outputName = Path.Combine("exported_maps", "black_ops_2", gameType, mapName, mapName);
                    Directory.CreateDirectory(Path.GetDirectoryName(outputName));

                    // Stop watch
                    var stopWatch = Stopwatch.StartNew();

                    // Read Vertices
                    printCallback?.Invoke("Parsing vertex data....");
                    var vertexBuffer = reader.ReadBytes(gfxMapAsset.GfxVerticesPointer, gfxMapAsset.GfxVertexBufferSize);
                    printCallback?.Invoke(String.Format("Parsed vertex data in {0:0.00} seconds.", stopWatch.ElapsedMilliseconds / 1000.0));

                    // Reset timer
                    stopWatch.Restart();

                    // Read Indices
                    printCallback?.Invoke("Parsing surface indices....");
                    var indices = ReadGfxIndices(reader, gfxMapAsset.GfxIndicesPointer, gfxMapAsset.GfxIndicesCount);
                    printCallback?.Invoke(String.Format("Parsed indices in {0:0.00} seconds.", stopWatch.ElapsedMilliseconds / 1000.0));

                    // Reset timer
                    stopWatch.Restart();

                    // Read Indices
                    printCallback?.Invoke("Parsing surfaces....");
                    var surfaces = ReadGfxSufaces(reader, gfxMapAsset.GfxSurfacesPointer, gfxMapAsset.SurfaceCount);
                    printCallback?.Invoke(String.Format("Parsed surfaces in {0:0.00} seconds.", stopWatch.ElapsedMilliseconds / 1000.0));

                    // Reset timer
                    stopWatch.Restart();

                    // Write OBJ
                    printCallback?.Invoke("Converting to OBJ....");

                    // Create new OBJ
                    var obj = new WavefrontOBJ();

                    // Image Names (for Search String)
                    HashSet <string> imageNames = new HashSet <string>();

                    // Vertex Index Tracker
                    int vertexIndex = 0;

                    // Append Faces
                    foreach (var surface in surfaces)
                    {
                        // Create new Material
                        var material = ReadMaterial(reader, surface.MaterialPointer);

                        // Add to images
                        imageNames.Add(material.DiffuseMap);

                        // Add it
                        obj.AddMaterial(material);

                        // Add points
                        for (ushort i = 0; i < surface.FaceCount; i++)
                        {
                            // Face Indices
                            var faceIndex1 = indices[i * 3 + surface.FaceIndex];
                            var faceIndex2 = indices[i * 3 + surface.FaceIndex + 1];
                            var faceIndex3 = indices[i * 3 + surface.FaceIndex + 2];

                            // Validate unique points, and write to OBJ
                            if (faceIndex1 != faceIndex2 && faceIndex1 != faceIndex3 && faceIndex2 != faceIndex3)
                            {
                                // new Obj Face
                                var objFace = new WavefrontOBJ.Face(material.Name);

                                // Unpack vertices
                                var vertex1 = UnpackVertex(ByteUtil.BytesToStruct <GfxVertex>(vertexBuffer, surface.VertexBufferOffset + (faceIndex1 * 36)));
                                var vertex2 = UnpackVertex(ByteUtil.BytesToStruct <GfxVertex>(vertexBuffer, surface.VertexBufferOffset + (faceIndex2 * 36)));
                                var vertex3 = UnpackVertex(ByteUtil.BytesToStruct <GfxVertex>(vertexBuffer, surface.VertexBufferOffset + (faceIndex3 * 36)));

                                // Add Offsets
                                obj.Vertices.Add(vertex1.Position);
                                obj.Vertices.Add(vertex2.Position);
                                obj.Vertices.Add(vertex3.Position);

                                // Add Normals
                                obj.Normals.Add(vertex1.Normal);
                                obj.Normals.Add(vertex2.Normal);
                                obj.Normals.Add(vertex3.Normal);

                                // Add UVs
                                obj.UVs.Add(vertex1.UV);
                                obj.UVs.Add(vertex2.UV);
                                obj.UVs.Add(vertex3.UV);

                                // Add points
                                objFace.Vertices[0] = new WavefrontOBJ.Face.Vertex(vertexIndex, vertexIndex, vertexIndex);
                                objFace.Vertices[2] = new WavefrontOBJ.Face.Vertex(vertexIndex + 1, vertexIndex + 1, vertexIndex + 1);
                                objFace.Vertices[1] = new WavefrontOBJ.Face.Vertex(vertexIndex + 2, vertexIndex + 2, vertexIndex + 2);

                                // Add to OBJ
                                obj.Faces.Add(objFace);

                                vertexIndex += 3;
                            }
                        }
                    }


                    // Save it
                    obj.Save(outputName + ".obj");

                    // Build search strinmg
                    string searchString = "";

                    // Loop through images, and append each to the search string (for Wraith/Greyhound)
                    foreach (string imageName in imageNames)
                    {
                        searchString += String.Format("{0},", Path.GetFileNameWithoutExtension(imageName));
                    }

                    // Dump it
                    File.WriteAllText(outputName + "_search_string.txt", searchString);

                    // Read entities and dump to map
                    mapFile.Entities.AddRange(ReadStaticModels(reader, gfxMapAsset.GfxStaticModelsPointer, gfxMapAsset.GfxStaticModelsCount));
                    mapFile.DumpToMap(outputName + ".map");

                    // Done
                    printCallback?.Invoke(String.Format("Converted to OBJ in {0:0.00} seconds.", stopWatch.ElapsedMilliseconds / 1000.0));
                }
            }
            else
            {
                printCallback?.Invoke("Call of Duty: Black Ops 2 is supported, but this EXE is not.");
            }
        }