Example #1
0
        public I3DSpline(BigEndianBinaryReader br)
        {
            try
            {
                Unknown1 = br.ReadUInt32();
                Name     = br.BaseStream.ReadNullTerminatedString();

                br.BaseStream.Align(2); // Align the stream to short

                do
                {
                    ShapeId = br.ReadUInt16();
                } while (ShapeId == 0);

                Unknown2    = br.ReadUInt32();
                VertexCount = br.ReadUInt32();

                Vertices = new Vector3[VertexCount];
                for (int i = 0; i < VertexCount; i++)
                {
                    Vertices[i] = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                }
            }
            catch (Exception e)
            {
                if (string.IsNullOrEmpty(Name))
                {
                    throw;
                }

                if (ShapeId > 0)
                {
                    throw new Exception($"Failed to parse I3DSpline {Name}, ShapeID: {ShapeId}", e);
                }

                throw new Exception($"Failed to parse I3DSpline {Name}", e);
            }
        }
Example #2
0
        public static I3DShape[] LoadShapesFile(string path)
        {
            if (Cache.ContainsKey(path))
            {
                return(Cache[path]);
            }

            List <I3DShape> shapes;

            using (FileStream fs = File.OpenRead(path))
            {
                string fileName = Path.GetFileName(fs.Name) ?? "N/A";
                Debug.Log("Loading file: " + fileName);

                Debug.Log("File Size: " + new FileInfo(fs.Name).Length + " bytes");

                I3DShapesHeader header = ParseFileHeader(fs);

                Debug.Log("File Seed: " + header.Seed);
                Debug.Log("File Version: " + header.Version);

                if (header.Version != 2 && header.Version != 3)
                {
                    throw new NotSupportedException("Unsupported version");
                }

                Debug.Log("");

                using (I3DDecryptorStream dfs = new I3DDecryptorStream(fs, header.Seed))
                {
                    int itemCount = dfs.ReadInt32L();
                    shapes = new List <I3DShape>();

                    Debug.Log("Found " + itemCount + " shapes");
                    Debug.Log("");
                    for (int i = 0; i < itemCount; i++)
                    {
                        int    type = dfs.ReadInt32L();
                        int    size = dfs.ReadInt32L();
                        byte[] data = dfs.ReadBytes(size);

                        //Debug.Log($"{i+1}: (Type {type}) {size} bytes");

                        string binFileName = $"{i+1}-{type}.bin";
                        //File.WriteAllBytes(Path.Combine(@"F:\SteamLibrary\steamapps\common\Farming Simulator 15\data\maps\decompile", binFileName), data);
                        //File.WriteAllBytes(Path.Combine(@"D:\SteamLibrary\steamapps\common\Farming Simulator 2013\data\maps\decompile\chickenmesh", binFileName), data);

                        using (MemoryStream ms = new MemoryStream(data))
                        {
                            using (BigEndianBinaryReader br = new BigEndianBinaryReader(ms))
                            {
                                try
                                {
                                    switch (type)
                                    {
                                    case 1:
                                        shapes.Add(new I3DShape(br));
                                        break;

                                    case 2:
                                        new I3DSpline(br);
                                        break;

                                    case 3:
                                        new I3DNavMesh(br);
                                        break;
                                    }
                                }
                                catch (Exception e)
                                {
                                    Debug.Log(e.Message);
                                }
                            }
                        }
                    }
                    Debug.Log($"Loaded {shapes.Count} shapes");
                }
            }

            I3DShape[] shapesArr = shapes.ToArray();

            Cache[path] = shapesArr;

            return(shapesArr);
        }
Example #3
0
        public I3DShape(BigEndianBinaryReader br)
        {
            try
            {
                Unknown1 = br.ReadUInt32();
                Name     = br.BaseStream.ReadNullTerminatedString();

                br.BaseStream.Align(2); // Align the stream to short

                //This is pretty ugly, but they pretty much zero-pad after the alignment
                //So we read the padding until we found the shapeid
                do
                {
                    ShapeId = br.ReadUInt16();
                } while (ShapeId == 0);

                BVCenterX    = br.ReadSingle();
                BVCenterY    = br.ReadSingle();
                BVCenterZ    = br.ReadSingle();
                BVRadius     = br.ReadSingle();
                VertexCount  = br.ReadUInt32();
                Unknown6     = br.ReadUInt32();
                Vertices     = br.ReadUInt32();
                Unknown7     = br.ReadUInt32();
                Unknown8     = br.ReadUInt32();
                UvCount      = br.ReadUInt32();
                Unknown9     = br.ReadUInt32();
                VertexCount2 = br.ReadUInt32();

                Mesh = new Mesh();

                int[] tris = new int[VertexCount];
                for (int i = 0; i < VertexCount; i++)
                {
                    tris[i] = br.ReadUInt16();
                }

                br.BaseStream.Align(4);

                Vector3[] vertices = new Vector3[Vertices];
                for (int i = 0; i < Vertices; i++)
                {
                    vertices[i] = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                }

                Vector3[] normals = new Vector3[Vertices];
                for (int i = 0; i < Vertices; i++)
                {
                    normals[i] = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                }

                Vector2[] uvs = new Vector2[UvCount];
                for (int i = 0; i < UvCount; i++)
                {
                    uvs[i] = new Vector2(br.ReadSingle(), br.ReadSingle());
                }

                Mesh.vertices  = vertices;
                Mesh.normals   = normals;
                Mesh.triangles = tris;
                Mesh.uv        = uvs;
            }
            catch (Exception e)
            {
                if (string.IsNullOrEmpty(Name))
                {
                    throw;
                }

                if (ShapeId > 0)
                {
                    throw new Exception($"Failed to parse I3DShape {Name}, ShapeID: {ShapeId}", e);
                }

                throw new Exception($"Failed to parse I3DShape {Name}", e);
            }
        }