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); } }
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); }
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); }
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(); }
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(); }
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(); }); }
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); }
private void GameWindowForm_DragDrop(object sender, DragEventArgs e) { string[] modelFiles = (string[])e.Data.GetData(DataFormats.FileDrop, false); InterrootLoader.LoadDragDroppedFiles(modelFiles); }