Ejemplo n.º 1
0
        private void LoadFLVER2(FLVER2 flver, bool useSecondUV, Dictionary <string, int> boneIndexRemap = null,
                                bool ignoreStaticTransforms = false)
        {
            lock (_lock_submeshes)
            {
                Submeshes = new List <FlverSubmeshRenderer>();
            }

            foreach (var submesh in flver.Meshes)
            {
                // Blacklist some materials that don't have good shaders and just make the viewer look like a mess
                MTD mtd = null;// 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;
                    }
                }
                var smm = new FlverSubmeshRenderer(this, flver, submesh, useSecondUV, boneIndexRemap, ignoreStaticTransforms);

                Bounds = new BoundingBox();

                lock (_lock_submeshes)
                {
                    Submeshes.Add(smm);
                    Bounds = BoundingBox.CreateMerged(Bounds, smm.Bounds);
                }
            }
        }
Ejemplo n.º 2
0
        public static void ReloadMtds()
        {
            IBinder mtdBinder = null;

            if (AssetLocator.Type == GameType.DarkSoulsIII || AssetLocator.Type == GameType.Sekiro)
            {
                mtdBinder = BND4.Read(AssetLocator.GetAssetPath($@"mtd\allmaterialbnd.mtdbnd.dcx"));
            }

            if (mtdBinder == null)
            {
                return;
            }

            _mtds = new Dictionary <string, MTD>();
            foreach (var f in mtdBinder.Files)
            {
                var mtdname = Path.GetFileNameWithoutExtension(f.Name);
                // Because *certain* mods contain duplicate entries for the same material
                if (!_mtds.ContainsKey(mtdname))
                {
                    _mtds.Add(mtdname, MTD.Read(f.Bytes));
                }
            }
        }
Ejemplo n.º 3
0
    public void InitializeFromMTD(MTD mtd, string virtualPath)
    {
        VirtualPath = virtualPath;
        ShaderPath  = mtd.ShaderPath;
        Textures    = new List <TextureDefinition>();
        foreach (var tex in mtd.Textures)
        {
            var def = new TextureDefinition();
            def.Name            = tex.Type;
            def.UVNumber        = tex.UVNumber;
            def.ShaderDataIndex = tex.ShaderDataIndex;
            if (tex.Extended)
            {
                def.TexturePath = tex.Path;
            }

            // Calculate the uv set index
            int uvoffset = 1;
            for (int j = 1; j < tex.UVNumber; j++)
            {
                if (!mtd.Textures.Any(t => (t.UVNumber == j)))
                {
                    uvoffset++;
                }
            }
            def.UVIndex = tex.UVNumber - uvoffset;

            if (tex.Type.ToUpper() == "G_LIGHTMAP" || tex.Type.ToUpper() == "G_DOLTEXTURE1" || tex.Type.ToUpper() == "G_GITEXTURE")
            {
                LightmapUVIndex = def.UVIndex;
            }

            Textures.Add(def);
        }
    }
Ejemplo n.º 4
0
        private void CmbMTD_SelectedIndexChanged(object sender, EventArgs e)
        {
            dgvParams.DataSource   = null;
            dgvTextures.DataSource = null;
            MTDWrapper item = cmbMTD.SelectedItem as MTDWrapper;

            mtd = item.MTD;
            LoadMTD(mtd);
        }
Ejemplo n.º 5
0
        public Model(FLVER0 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
                MTD mtd = null;// 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);
            }
        }
Ejemplo n.º 6
0
        private void LoadMTD(MTD mtd)
        {
            txtDescription.DataBindings.Clear();
            txtDescription.DataBindings.Add("Text", mtd, "Description");
            txtDescriptionTranslated.Text = MTDTranslations.GetTranslation(mtd.Description);

            txtShader.DataBindings.Clear();
            txtShader.DataBindings.Add("Text", mtd, "ShaderPath");

            dgvTextures.DataSource = mtd.Textures;
            bool extended = mtd.Textures.Any(t => t.Extended);

            dgvTexturesFloatsCol.Visible = extended;
            dgvTexturesPathCol.Visible   = extended;

            dgvParams.DataSource = mtd.Params;
        }
Ejemplo n.º 7
0
        public static void LoadMTDBND()
        {
            MtdDict.Clear();
            MTDBND = null;

            if (GameType == GameTypes.SDT)
            {
                MTDBND = BND4.Read(GetInterrootPath($@"mtd\allmaterialbnd.mtdbnd.dcx"));

                foreach (var f in MTDBND.Files)
                {
                    var key = Utils.GetShortIngameFileName(f.Name);
                    if (!MtdDict.ContainsKey(key))
                    {
                        MtdDict.Add(key, MTD.Read(f.Bytes));
                    }
                    else
                    {
                        MtdDict[key] = MTD.Read(f.Bytes);
                    }
                }
            }
        }
Ejemplo n.º 8
0
 private void Awake()
 {
     if (_instance == null)
     {
         _instance = this;
         transform.SetParent(null);
         DontDestroyOnLoad(this);
     }
     else
     {
         if (_instance != this)
         {
             if (GetComponents <Component>().Length <= 2)
             {
                 Destroy(gameObject);
             }
             else
             {
                 Destroy(this);
             }
         }
     }
 }
        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();
        }
Ejemplo n.º 10
0
 public MTDWrapper(MTD mtd, string name)
 {
     MTD  = mtd;
     Name = name;
 }
Ejemplo n.º 11
0
        private void LoadFile(string path, bool silent = false)
        {
            statusStripMTDPath.Text = "";
            if (!File.Exists(path))
            {
                ShowError($"File not found:\r\n{path}", silent);
                return;
            }

            string filename  = Path.GetFileName(path);
            string extension = SFUtil.GetRealExtension(filename);

            cmbMTD.Enabled = false;
            cmbMTD.Items.Clear();

            mtdBnd = null;
            mtd    = null;

            var mtdItems = new List <MTDWrapper>();

            try
            {
                if (MTD.Is(path))
                {
                    mtdItems.Add(new MTDWrapper(MTD.Read(path), filename));
                }
                else if (BND3.Is(path))
                {
                    mtdBnd = BND3.Read(path);
                    foreach (BinderFile file in mtdBnd.Files)
                    {
                        if (MTD.Is(file.Bytes))
                        {
                            mtdItems.Add(new MTDWrapper(MTD.Read(file.Bytes), file.Name));
                        }
                    }
                }
                else if (BND4.Is(path))
                {
                    mtdBnd = BND4.Read(path);
                    foreach (BinderFile file in mtdBnd.Files)
                    {
                        if (MTD.Is(file.Bytes))
                        {
                            mtdItems.Add(new MTDWrapper(MTD.Read(file.Bytes), file.Name));
                        }
                    }
                }
                else
                {
                    ShowError($"Unrecognized file type:\r\n{path}", silent);
                    return;
                }
            }
            catch (Exception ex)
            {
                ShowError($"Failed to load file:\r\n{path}\r\n{ex}", silent);
                return;
            }

            statusStripMTDPath.Text = path;
            mtdItems.Sort((i1, i2) => i1.Name.CompareTo(i2.Name));
            cmbMTD.Items.AddRange(mtdItems.ToArray());
            cmbMTD.SelectedIndex = 0;

            if (mtdItems.Count > 1)
            {
                cmbMTD.Enabled = true;
            }
        }