Beispiel #1
0
        public Model(FLVERD flver)
        {
            Type = ModelType.ModelTypeFlver;

            Submeshes = new List <FlverSubmeshRenderer>();
            var subBoundsPoints = new List <Vector3>();

            foreach (var submesh in flver.Meshes)
            {
                // Blacklist some materials that don't have good shaders and just make the viewer look like a mess
                var mtd = InterrootLoader.GetMTD(Path.GetFileName(flver.Materials[submesh.MaterialIndex].MTD));
                if (mtd != null)
                {
                    if (mtd.ShaderPath.Contains("FRPG_Water_Env"))
                    {
                        continue;
                    }
                    if (mtd.ShaderPath.Contains("FRPG_Water_Reflect.spx"))
                    {
                        continue;
                    }
                }

                if (submesh.ToTriangleList().Length > 0)
                {
                    var smm = new FlverSubmeshRenderer(this, flver, submesh);
                    Submeshes.Add(smm);
                    subBoundsPoints.Add(smm.Bounds.Min);
                    subBoundsPoints.Add(smm.Bounds.Max);
                }
            }

            //DEBUG//
            //Console.WriteLine($"{flver.Meshes[0].DefaultBoneIndex}");
            //Console.WriteLine();
            //Console.WriteLine();
            //foreach (var mat in flver.Materials)
            //{
            //    Console.WriteLine($"{mat.Name}: {mat.MTD}");
            //}
            /////////

            if (Submeshes.Count == 0)
            {
                Bounds    = new BoundingBox();
                IsVisible = false;
            }
            else
            {
                Bounds = BoundingBox.CreateFromPoints(subBoundsPoints);
            }
        }
Beispiel #2
0
        public List <Model> AddChr(int id, Transform location)
        {
            var models = InterrootLoader.LoadModelChr(id);

            var returnedModelInstances = new List <Model>();

            for (int i = 0; i < models.Count; i++)
            {
                AddModelInstance(models[i], $"c{id:D4}{(i > 0 ? $"[{i + 1}]" : "")}", location);
                returnedModelInstances.Add(models[i]);
            }

            GFX.ModelDrawer.RequestTextureLoad();

            return(returnedModelInstances);
        }
        public static void LoadMsbRegionsDS1(string mapName)
        {
            var cylinder = new DbgPrimWireCylinder(
                location: Transform.Default,
                range: 1.0f,
                height: 1,
                numSegments: 12,
                color: Color.Cyan);

            var sphere = new DbgPrimWireSphere(Transform.Default, 1f, 12, 12, Color.Red);

            var point = new DbgPrimWireSphere(Transform.Default, 0.25f, 4, 4, Color.Lime);

            var box = new DbgPrimWireBox(Transform.Default, Vector3.One, Color.Yellow);

            var msb = DataFile.LoadFromFile <MSB>(InterrootLoader.GetInterrootPath($@"map\MapStudio\{mapName}.msb"));

            foreach (var msbBox in msb.Regions.Boxes)
            {
                var newBox = box.Instantiate(msbBox.Name, new Transform(msbBox.PosX, msbBox.PosY, msbBox.PosZ,
                                                                        MathHelper.ToRadians(msbBox.RotX), MathHelper.ToRadians(msbBox.RotY), MathHelper.ToRadians(msbBox.RotZ),
                                                                        msbBox.WidthX, msbBox.HeightY, msbBox.DepthZ));
                DBG.AddPrimitive(newBox);
            }

            foreach (var msbSphere in msb.Regions.Spheres)
            {
                var newSphere = sphere.Instantiate(msbSphere.Name, new Transform(msbSphere.PosX, msbSphere.PosY, msbSphere.PosZ,
                                                                                 MathHelper.ToRadians(msbSphere.RotX), MathHelper.ToRadians(msbSphere.RotY), MathHelper.ToRadians(msbSphere.RotZ),
                                                                                 msbSphere.Radius, msbSphere.Radius, msbSphere.Radius));
                DBG.AddPrimitive(newSphere);
            }

            foreach (var msbCylinder in msb.Regions.Cylinders)
            {
                var newCylinder = cylinder.Instantiate(msbCylinder.Name, new Transform(msbCylinder.PosX, msbCylinder.PosY, msbCylinder.PosZ,
                                                                                       MathHelper.ToRadians(msbCylinder.RotX), MathHelper.ToRadians(msbCylinder.RotY), MathHelper.ToRadians(msbCylinder.RotZ),
                                                                                       msbCylinder.Radius, msbCylinder.Height, msbCylinder.Radius));
                DBG.AddPrimitive(newCylinder);
            }

            foreach (var msbPoint in msb.Regions.Points)
            {
                var newPoint = point.Instantiate(msbPoint.Name, new Transform(msbPoint.PosX, msbPoint.PosY, msbPoint.PosZ,
                                                                              MathHelper.ToRadians(msbPoint.RotX), MathHelper.ToRadians(msbPoint.RotY), MathHelper.ToRadians(msbPoint.RotZ)));
            }
        }
        public List <ModelInstance> AddObj(int id, Transform location)
        {
            var models = InterrootLoader.LoadModelObj(id);

            var returnedModelInstances = new List <ModelInstance>();

            for (int i = 0; i < models.Count; i++)
            {
                var m = new ModelInstance($"o{id:D4}{(i > 0 ? $"[{i + 1}]" : "")}", models[i], location, -1, -1, -1, -1);
                AddModelInstance(m);
                returnedModelInstances.Add(m);
            }

            GFX.ModelDrawer.RequestTextureLoad();

            return(returnedModelInstances);
        }
Beispiel #5
0
 public void AddMap(string mapName, bool excludeScenery)
 {
     SoulsFormats.BTAB btab = InterrootLoader.LoadMapBtab(mapName);
     LightmapAtlasMap      = new Dictionary <string, Vector4>();
     LightmapAtlasIndexMap = new Dictionary <string, int>();
     if (btab != null)
     {
         foreach (var entry in btab.Entries)
         {
             if (!LightmapAtlasMap.ContainsKey(entry.MSBPartName))
             {
                 LightmapAtlasMap.Add(entry.MSBPartName, new Vector4(entry.AtlasScale.X, entry.AtlasScale.Y, entry.AtlasOffset.X, entry.AtlasOffset.Y));
                 LightmapAtlasIndexMap.Add(entry.MSBPartName, entry.AtlasIndex);
             }
         }
     }
     InterrootLoader.LoadMapInBackground(mapName, excludeScenery, AddModelInstance);
 }
Beispiel #6
0
        public static void AddMapTexBXF4(int area, IProgress <double> prog)
        {
            var dir = InterrootLoader.GetInterrootPath($"map\\m{area:D2}");

            if (!Directory.Exists(dir))
            {
                return;
            }
            var mapTpfFileNames = Directory.GetFiles(dir, "*.tpfbhd");
            int fileIndex       = 0;

            foreach (var t in mapTpfFileNames)
            {
                BXF4 bxf = null;
                lock (_lock_IO)
                {
                    bxf = BXF4.Read(t, t.Substring(0, t.Length - 7) + ".tpfbdt");
                }

                for (int i = 0; i < bxf.Files.Count; i++)
                {
                    if (bxf.Files[i].Name.Contains(".tpf"))
                    {
                        var tpf = SoulsFormats.TPF.Read(bxf.Files[i].Bytes);

                        foreach (var tn in tpf.Textures)
                        {
                            AddFetch(tpf, tn.Name);
                        }

                        tpf = null;
                    }
                    GFX.ModelDrawer.RequestTextureLoad();
                    // Report each subfile as a tiny part of the bar
                    prog?.Report((1.0 * fileIndex / mapTpfFileNames.Length) + ((1.0 / mapTpfFileNames.Length) * ((i + 1.0) / bxf.Files.Count)));
                }
                bxf = null;

                fileIndex++;
                prog?.Report((1.0 * fileIndex / mapTpfFileNames.Length));
            }

            GFX.ModelDrawer.RequestTextureLoad();
        }
        public static void AddMapTexBXF4DS2(string area, IProgress <double> prog)
        {
            var dir = InterrootLoader.GetInterrootPath($"model\\map\\");

            if (!Directory.Exists(dir))
            {
                return;
            }

            BXF4 bxf = null;

            lock (_lock_IO)
            {
                bxf = BXF4.Read(dir + "\\t" + area.Substring(1) + ".tpfbhd", dir + "\\t" + area.Substring(1) + ".tpfbdt");
            }

            for (int i = 0; i < bxf.Files.Count; i++)
            {
                if (bxf.Files[i].Name.Contains(".tpf"))
                {
                    var tpf = TPF.Read(bxf.Files[i].Bytes);

                    foreach (var tn in tpf.Textures)
                    {
                        AddFetch(tpf, tn.Name);
                    }

                    tpf = null;
                }
                GFX.ModelDrawer.RequestTextureLoad();
                // Report each subfile as a tiny part of the bar
                prog?.Report((i + 1.0) / bxf.Files.Count);
            }
            bxf = null;

            //fileIndex++;
            //prog?.Report((1.0 * fileIndex / mapTpfFileNames.Length));

            GFX.ModelDrawer.RequestTextureLoad();
        }
Beispiel #8
0
        static void TestMCP_MGC(string mapName)
        {
            if (InterrootLoader.Type != InterrootLoader.InterrootType.InterrootDS1)
            {
                return;
            }

            //GFX.ModelDrawer.AddMap(mapName, false);

            var box = new DbgPrimWireBox(Transform.Default, Vector3.One, Color.Red);
            var mcp = DataFile.LoadFromFile <MCP>(InterrootLoader.GetInterrootPath($@"map\{mapName}\{mapName}.mcp"));
            int bi  = 0;

            foreach (var mcpBox in mcp.Boxes)
            {
                var min    = new Vector3(mcpBox.MinX, mcpBox.MinY, mcpBox.MinZ);
                var max    = new Vector3(mcpBox.MaxX, mcpBox.MaxY, mcpBox.MaxZ);
                var size   = max - min;
                var center = min + (size / 2f);
                DBG.AddPrimitive(box.Instantiate($"Box [{(bi++)}]", new Transform(center.X, center.Y, center.Z, 0, 0, 0, size.X, size.Y, size.Z)));
            }
            var            sphere      = new DbgPrimWireSphere(Transform.Default, 0.35f, 32, 32, Color.Cyan);
            var            mcg         = DataFile.LoadFromFile <MCG>(InterrootLoader.GetInterrootPath($@"map\{mapName}\{mapName}.mcg"));
            var            lines       = new DbgPrimWire();
            List <Vector3> startPoints = new List <Vector3>();
            List <Vector3> endPoints   = new List <Vector3>();

            for (int i = 0; i < mcg.Paths.Count; i++)
            {
                var pointsThatReferenceThisShit = mcg.Points.Where(x => x.NearbyPathIndices.Contains(i)).ToList();
                startPoints.Add(new Vector3(pointsThatReferenceThisShit[0].PosX, pointsThatReferenceThisShit[0].PosY, pointsThatReferenceThisShit[0].PosZ));
                endPoints.Add(new Vector3(pointsThatReferenceThisShit[1].PosX, pointsThatReferenceThisShit[1].PosY, pointsThatReferenceThisShit[1].PosZ));
            }
            void AddPath(int pathIndex, Color col) =>
            lines.AddLine(startPoints[pathIndex], endPoints[pathIndex], col);

            void AddPathString(int pathIndex, string str, Color col)
            {
                var position = (startPoints[pathIndex] + endPoints[pathIndex]) / 2.0f;

                lines.AddDbgLabel(position, 5f, str, col);
            }

            //for (int i = 0; i < mcg.Paths.Count; i++)
            //{
            //    AddPath(i, Color.Cyan);
            //    AddPathString(i, mcg.Paths[i].GetDebugReport(), Color.Cyan);

            //    //foreach (var edgeIndex in mcg.Edges[i].OtherEdgeIndicesA)
            //    //{
            //    //    AddEdge(edgeIndex, Color.Cyan);
            //    //}

            //    //foreach (var edgeIndex in mcg.Edges[i].OtherEdgeIndicesB)
            //    //{
            //    //    AddEdge(edgeIndex, Color.Yellow);
            //    //}

            //    //break;
            //}

            float getPathLength(int pathIndex)
            {
                var start = startPoints[pathIndex];
                var end   = endPoints[pathIndex];

                return((start - end).Length());
            }

            void addPointDbg(int pointIndex)
            {
                DBG.AddPrimitive(sphere.Instantiate($"Point [{pointIndex}]", new Transform(new Vector3(mcg.Points[pointIndex].PosX, mcg.Points[pointIndex].PosY, mcg.Points[pointIndex].PosZ), Vector3.Zero)));

                int pidx = 0;

                foreach (var adjPointIndex in mcg.Points[pointIndex].NearbyPointIndices)
                {
                    DBG.AddPrimitive(sphere.Instantiate($"INDEX IN POINT'S LIST:{pidx++}, Point Near [{adjPointIndex}]", new Transform(new Vector3(mcg.Points[adjPointIndex].PosX, mcg.Points[adjPointIndex].PosY, mcg.Points[adjPointIndex].PosZ), Vector3.Zero)));
                }

                pidx = 0;
                foreach (var path in mcg.Points[pointIndex].NearbyPathIndices)
                {
                    AddPath(path, Color.Cyan);
                    AddPathString(path, $"PATH INDEX IN POINT'S LIST:{pidx++}\n{mcg.Paths[path].GetDebugReport()}\nPATH LENGTH: {getPathLength(path)}", Color.Cyan);
                }
            }

            //addPointDbg(0);
            //addPointDbg(1);
            //addPointDbg(2);

            for (int i = 0; i < mcg.Points.Count; i++)
            {
                addPointDbg(i);
            }

            DBG.AddPrimitive(lines);

            Console.WriteLine("TEST");
        }
        public FlverSubmeshRenderer(Model parent, FLVER flvr, FLVER.Mesh mesh)
        {
            Parent = parent;

            var shortMaterialName = MiscUtil.GetFileNameWithoutDirectoryOrExtension(flvr.Materials[mesh.MaterialIndex].MTD);

            if (shortMaterialName.EndsWith("_Alp") ||
                shortMaterialName.Contains("_Edge") ||
                shortMaterialName.Contains("_Decal") ||
                shortMaterialName.Contains("_Cloth") ||
                shortMaterialName.Contains("_al") ||
                shortMaterialName.Contains("BlendOpacity"))
            {
                DrawStep = GFXDrawStep.AlphaEdge;
            }
            else
            {
                DrawStep = GFXDrawStep.Opaque;
            }

            bool hasLightmap = false;

            foreach (var matParam in flvr.Materials[mesh.MaterialIndex].Textures)
            {
                var paramNameCheck = matParam.Type.ToUpper();
                // DS3/BB
                if (paramNameCheck == "G_DIFFUSETEXTURE")
                {
                    TexNameDiffuse = matParam.Path;
                }
                else if (paramNameCheck == "G_SPECULARTEXTURE")
                {
                    TexNameSpecular = matParam.Path;
                }
                else if (paramNameCheck == "G_BUMPMAPTEXTURE")
                {
                    TexNameNormal = matParam.Path;
                }
                else if (paramNameCheck == "G_DOLTEXTURE1")
                {
                    TexNameDOL1 = matParam.Path;
                    hasLightmap = true;
                }
                else if (paramNameCheck == "G_DOLTEXTURE2")
                {
                    TexNameDOL2 = matParam.Path;
                }
                // DS1 params
                else if (paramNameCheck == "G_DIFFUSE")
                {
                    TexNameDiffuse = matParam.Path;
                }
                else if (paramNameCheck == "G_SPECULAR")
                {
                    TexNameSpecular = matParam.Path;
                }
                else if (paramNameCheck == "G_BUMPMAP")
                {
                    TexNameNormal = matParam.Path;
                }
                else if (paramNameCheck == "G_LIGHTMAP")
                {
                    TexNameDOL1 = matParam.Path;
                    hasLightmap = true;
                }
                // Alternate material params that work as diffuse
            }

            // MTD lookup
            MTD mtd = InterrootLoader.GetMTD(flvr.Materials[mesh.MaterialIndex].MTD);

            var MeshVertices = new VertexPositionColorNormalTangentTexture[mesh.Vertices.Count];

            for (int i = 0; i < mesh.Vertices.Count; i++)
            {
                var vert = mesh.Vertices[i];
                MeshVertices[i] = new VertexPositionColorNormalTangentTexture();

                MeshVertices[i].Position = new Vector3(vert.Position.X, vert.Position.Y, vert.Position.Z);

                if (vert.Normal != null && vert.Tangents != null && vert.Tangents.Count > 0)
                {
                    MeshVertices[i].Normal   = Vector3.Normalize(new Vector3(vert.Normal.X, vert.Normal.Y, vert.Normal.Z));
                    MeshVertices[i].Tangent  = Vector3.Normalize(new Vector3(vert.Tangents[0].X, vert.Tangents[0].Y, vert.Tangents[0].Z));
                    MeshVertices[i].Binormal = Vector3.Cross(Vector3.Normalize(MeshVertices[i].Normal), Vector3.Normalize(MeshVertices[i].Tangent)) * vert.Tangents[0].W;
                }

                if (vert.UVs.Count > 0)
                {
                    MeshVertices[i].TextureCoordinate = new Vector2(vert.UVs[0].X, vert.UVs[0].Y);
                    if (vert.UVs.Count > 1 && hasLightmap)
                    {
                        if (mtd == null)
                        {
                            // Really stupid heuristic to determine light map UVs without reading mtd files or something
                            if (vert.UVs.Count > 2 && flvr.Materials[mesh.MaterialIndex].Textures.Count > 11)
                            {
                                MeshVertices[i].TextureCoordinate2 = new Vector2(vert.UVs[2].X, vert.UVs[2].Y);
                            }
                            else
                            {
                                MeshVertices[i].TextureCoordinate2 = new Vector2(vert.UVs[1].X, vert.UVs[1].Y);
                            }
                        }
                        else
                        {
                            // Better heuristic with MTDs
                            int uvindex  = mtd.Textures.Find(tex => tex.Type.ToUpper() == "G_LIGHTMAP" || tex.Type.ToUpper() == "G_DOLTEXTURE1").UVNumber;
                            int uvoffset = 1;
                            for (int j = 1; j < uvindex; j++)
                            {
                                if (!mtd.Textures.Any(t => (t.UVNumber == j)))
                                {
                                    uvoffset++;
                                }
                            }
                            uvindex -= uvoffset;
                            if (vert.UVs.Count > uvindex)
                            {
                                MeshVertices[i].TextureCoordinate2 = new Vector2(vert.UVs[uvindex].X, vert.UVs[uvindex].Y);
                            }
                            else
                            {
                                MeshVertices[i].TextureCoordinate2 = new Vector2(vert.UVs[1].X, vert.UVs[1].Y);
                            }
                        }
                    }
                    else
                    {
                        MeshVertices[i].TextureCoordinate2 = Vector2.Zero;
                    }
                }
                else
                {
                    MeshVertices[i].TextureCoordinate  = Vector2.Zero;
                    MeshVertices[i].TextureCoordinate2 = Vector2.Zero;
                }
            }

            VertexCount = MeshVertices.Length;

            MeshFacesets = new List <FlverSubmeshRendererFaceSet>();

            foreach (var faceset in mesh.FaceSets)
            {
                bool is32bit = faceset.IndexSize == 0x20;

                var newFaceSet = new FlverSubmeshRendererFaceSet()
                {
                    BackfaceCulling = faceset.CullBackfaces,
                    IsTriangleStrip = faceset.TriangleStrip,
                    IndexBuffer     = new IndexBuffer(
                        GFX.Device,
                        is32bit ? IndexElementSize.ThirtyTwoBits : IndexElementSize.SixteenBits,
                        faceset.Vertices.Length,
                        BufferUsage.WriteOnly),
                    IndexCount = faceset.Vertices.Length,
                };

                if (faceset.Flags == FLVER.FaceSet.FSFlags.LodLevel1)
                {
                    newFaceSet.LOD = 1;
                    HasNoLODs      = false;
                }
                else if (faceset.Flags == FLVER.FaceSet.FSFlags.LodLevel2)
                {
                    newFaceSet.LOD = 2;
                    HasNoLODs      = false;
                }

                if (is32bit)
                {
                    newFaceSet.IndexBuffer.SetData(faceset.Vertices);
                }
                else
                {
                    newFaceSet.IndexBuffer.SetData(faceset.Vertices.Select(x => (ushort)x).ToArray());
                }

                MeshFacesets.Add(newFaceSet);
            }

            Bounds = BoundingBox.CreateFromPoints(MeshVertices.Select(x => x.Position));

            VertBuffer = new VertexBuffer(GFX.Device,
                                          typeof(VertexPositionColorNormalTangentTexture), MeshVertices.Length, BufferUsage.WriteOnly);
            VertBuffer.SetData(MeshVertices);

            VertBufferBinding = new VertexBufferBinding(VertBuffer, 0, 0);

            TryToLoadTextures();
        }
Beispiel #10
0
        public static void AddAllExternalDS1TexturesInBackground()
        {
            LoadingTaskMan.DoLoadingTask($"AddAllExternalDS1TexturesInBackground_UDSFM_MAP", $"Loading external map textures for DS1...", prog =>
            {
                //UDSFM MAP TEX
                var dir = InterrootLoader.GetInterrootPath(@"map\tx");
                if (Directory.Exists(dir))
                {
                    var mapTpfFileNames = Directory.GetFiles(dir);
                    int i = 0;
                    foreach (var t in mapTpfFileNames)
                    {
                        AddTpfFromPath(t);
                        prog?.Report(1.0 * (++i) / mapTpfFileNames.Length);
                    }
                }
                GFX.ModelDrawer.RequestTextureLoad();
            });

            LoadingTaskMan.DoLoadingTask($"AddAllExternalDS1TexturesInBackground_UDSFM_CHR", $"Loading external boss character textures for DS1...", prog =>
            {
                // UDSFM CHR TEX
                var udsfmTexFolderPath = InterrootLoader.GetInterrootPath($@"chr");
                if (Directory.Exists(udsfmTexFolderPath))
                {
                    var subDirectories = Directory.GetDirectories(udsfmTexFolderPath);
                    int i = 0;
                    foreach (var subDir in subDirectories)
                    {
                        var chrTpfFileNames = Directory.GetFiles(subDir, "*.tpf");
                        foreach (var t in chrTpfFileNames)
                        {
                            AddTpfFromPath(t);
                        }
                        prog?.Report(1.0 * (++i) / subDirectories.Length);
                    }
                }

                GFX.ModelDrawer.RequestTextureLoad();
            });

            LoadingTaskMan.DoLoadingTask($"AddAllExternalDS1TexturesInBackground_CHRBND_9", $"Loading external character textures for DS1...", prog =>
            {
                // CHRBND-9
                var chrbndsThatEndWith9 = Directory.GetFiles(InterrootLoader.GetInterrootPath(@"chr"), "*9.chrbnd");
                foreach (var ctew9 in chrbndsThatEndWith9)
                {
                    BND entityBnd = null;
                    lock (_lock_IO)
                    {
                        entityBnd = DataFile.LoadFromFile <BND>(ctew9);
                    }
                    AddTextureBnd(entityBnd, prog);
                }

                GFX.ModelDrawer.RequestTextureLoad();
            });

            LoadingTaskMan.DoLoadingTask($"AddAllExternalDS1TexturesInBackground_OBJBND_9", $"Loading external object textures for DS1...", prog =>
            {
                // CHRBND-9
                var chrbndsThatEndWith9 = Directory.GetFiles(InterrootLoader.GetInterrootPath(@"obj"), "*9.objbnd");
                foreach (var ctew9 in chrbndsThatEndWith9)
                {
                    BND entityBnd = null;
                    lock (_lock_IO)
                    {
                        entityBnd = DataFile.LoadFromFile <BND>(ctew9);
                    }
                    AddTextureBnd(entityBnd, prog);
                }

                GFX.ModelDrawer.RequestTextureLoad();
            });
        }
Beispiel #11
0
 public static void AddTpfFromPath(string path)
 {
     SoulsFormats.TPF tpf = InterrootLoader.DirectLoadTpf(path);
     AddTpf(tpf);
 }
 public void AddMap(string mapName, bool excludeScenery)
 {
     InterrootLoader.LoadMapInBackground(mapName, excludeScenery, AddModelInstance);
 }
Beispiel #13
0
        private void GameWindowForm_DragDrop(object sender, DragEventArgs e)
        {
            string[] modelFiles = (string[])e.Data.GetData(DataFormats.FileDrop, false);

            InterrootLoader.LoadDragDroppedFiles(modelFiles);
        }