From fe451ef6fb5ea07b45fdaf4218001558bb171ef0 Mon Sep 17 00:00:00 2001 From: Treeki Date: Sat, 5 Feb 2011 04:34:12 +0100 Subject: progress on material reading. still need to add DL handling and figure out what the shader data offset is for (probably points to an entry in the Shaders dict) --- NW4RTools/BrresReader.cs | 160 ++++++++++++++++++++++++++++++++++ NW4RTools/Models/Material.cs | 11 +++ NW4RTools/Models/Model.cs | 1 + NW4RTools/Types.cs | 12 --- NW4RTools/bin/Debug/NW4RTools.dll | Bin 25600 -> 28160 bytes NW4RTools/bin/Debug/NW4RTools.dll.mdb | Bin 8825 -> 9806 bytes TestApp/bin/Debug/NW4RTools.dll | Bin 25600 -> 28160 bytes TestApp/bin/Debug/NW4RTools.dll.mdb | Bin 8825 -> 9806 bytes TestApp/bin/Debug/TestApp.exe | Bin 3584 -> 3584 bytes TestApp/bin/Debug/TestApp.exe.mdb | Bin 416 -> 416 bytes 10 files changed, 172 insertions(+), 12 deletions(-) diff --git a/NW4RTools/BrresReader.cs b/NW4RTools/BrresReader.cs index a157fe9..4c63926 100644 --- a/NW4RTools/BrresReader.cs +++ b/NW4RTools/BrresReader.cs @@ -145,6 +145,8 @@ namespace NW4RTools { FinishNodeLoading(); // Load vertex data + // COMMENTED OUT TO MAKE DEUBG OUTPUT CLEARER FOR NOW + /* using (var c2 = Debug.Push("Vertex Position Data")) mdl.VtxPosData = ReadAndConvertDict(ins.At(startPos + vtxPosOffset), ConvertVtxPosData); using (var c2 = Debug.Push("Vertex Normal Data")) @@ -153,6 +155,11 @@ namespace NW4RTools { mdl.VtxClrData = ReadAndConvertDict(ins.At(startPos + vtxClrOffset), ConvertVtxClrData); using (var c2 = Debug.Push("Vertex TexCoord Data")) mdl.VtxTexCoordData = ReadAndConvertDict(ins.At(startPos + texCoordOffset), ConvertVtxTexCoordData); + */ + + // Load materials + using (var c2 = Debug.Push("Materials")) + mdl.Materials = ReadAndConvertDict(ins.At(startPos + materialOffset), ConvertModelMaterial); return mdl; } @@ -371,6 +378,159 @@ namespace NW4RTools { + private Models.Material ConvertModelMaterial(string name, InputStream ins) { + Debug.Send("Reading {0}...", name); + + var m = new Models.Material(); + + int startPos = ins.Position; + OffsetMap.Add(ins.Position, "Material: " + name); + + UInt32 size = ins.ReadUInt32(); + Int32 mdlOffset = ins.ReadInt32(); + Int32 nameOffset = ins.ReadInt32(); + m.Index = ins.ReadUInt32(); + m.Flags = ins.ReadUInt32(); + + // ResGenMode + m.TexCoordGenCount = ins.ReadByte(); + m.ChanCount = ins.ReadByte(); + m.TevStageCount = ins.ReadByte(); + m.IndStageCount = ins.ReadByte(); + m.CullMode = ins.ReadUInt32(); + + // ResMatMisc + m.ZCompLoc = ins.ReadByte(); + m.LightSetID = ins.ReadByte(); + m.FogID = ins.ReadByte(); + + m.IndirectTexMtxCalcMethod1 = ins.ReadBytes(4); + m.IndirectTexMtxCalcMethod2 = ins.ReadBytes(4); + ins.Skip(1); + + // Other stuff + Int32 shaderOffset = ins.ReadInt32(); + UInt32 boundTexCount = ins.ReadUInt32(); + Int32 boundTexOffset = ins.ReadInt32(); + Int32 furOffset = ins.ReadInt32(); + Int32 unkOffset = ins.ReadInt32(); + Int32 dlOffset = ins.ReadInt32(); + + // ResTexObj + int ResTexObjPos = ins.Position; + OffsetMap.Add(ins.Position, "Material ResTexObj: " + name); + + UInt32 textureFlag = ins.ReadUInt32(); + m.TexObj = new byte[8][]; + + for (int i = 0; i < 8; i++) { + if ((textureFlag & (1 << i)) != 0) { + m.TexObj[i] = ins.ReadBytes(0x20); + } + } + + ins.Seek(ResTexObjPos + 0x104); + + // ResTlutObj + int ResTlutObjPos = ins.Position; + OffsetMap.Add(ins.Position, "Material ResTlutObj: " + name); + + UInt32 tlutFlag = ins.ReadUInt32(); + if ((tlutFlag & 0xFC) == 0) { + m.TlutObj = ins.ReadBytes(0x20); + } else if ((tlutFlag & 0xE0) == 0) { + m.TlutObj = ins.ReadBytes(0x40); + } else { + m.TlutObj = ins.ReadBytes(0x60); + } + + ins.Seek(ResTlutObjPos + 0x64); + + // ResTexSrt + int ResTexSrtPos = ins.Position; + OffsetMap.Add(ins.Position, "Material ResTexSrt: " + name); + + UInt32 srtFlag = ins.ReadUInt32(); + m.TexMatrixType = ins.ReadUInt32(); + + m.SRTSettings = new SRTSettingInfo[8]; + InputStream texSrtStream = ins.At(ins.Position); + InputStream texSetStream = ins.At(ins.Position + (0x14 * 8)); + + for (int i = 0; i < 8; i++) { + if ((srtFlag & (0xF << (i * 4))) != 0) { + var srtInfo = m.SRTSettings[i] = new SRTSettingInfo(); + + srtInfo.ScaleX = texSrtStream.ReadFloat(); + srtInfo.ScaleY = texSrtStream.ReadFloat(); + srtInfo.Rotate = texSrtStream.ReadFloat(); + srtInfo.TranslateX = texSrtStream.ReadFloat(); + srtInfo.TranslateY = texSrtStream.ReadFloat(); + + srtInfo.CameraID = texSetStream.ReadByte(); + srtInfo.LightID = texSetStream.ReadByte(); + srtInfo.MapType = texSetStream.ReadByte(); + srtInfo.Flags = texSetStream.ReadByte(); + srtInfo.TexMatrix = texSetStream.ReadMatrix(); + } + } + + ins.Seek(ResTexSrtPos + 8 + (0x14 * 8) + (0x34 * 8)); + + // ResMatChan + OffsetMap.Add(ins.Position, "Material ResMatChan: " + name); + + m.ChanCtrls = new ChanCtrl[2]; + + for (int i = 0; i < 2; i++) { + var chanInfo = m.ChanCtrls[i] = new ChanCtrl(); + + chanInfo.Flags = ins.ReadUInt32(); + chanInfo.MatColor = ins.ReadColor(); + chanInfo.AmbColor = ins.ReadColor(); + chanInfo.FlagC = ins.ReadUInt32(); + chanInfo.FlagA = ins.ReadUInt32(); + } + + // Bound Textures + ins.Seek(startPos + boundTexOffset); + m.BoundTextures = new List((int)boundTexCount); + + for (int i = 0; i < boundTexCount; i++) { + Debug.Send("Reading {0} bound texture at {1:X}", i, ins.Position); + + int bPos = ins.Position; + var bTex = new BoundTextureInfo(); + m.BoundTextures.Add(bTex); + + Int32 texOffs = ins.ReadInt32(); + bTex.TextureName = texOffs == 0 ? null : ins.At(bPos + texOffs - 4).ReadName(); + Int32 palOffs = ins.ReadInt32(); + bTex.PaletteName = palOffs == 0 ? null : ins.At(bPos + palOffs - 4).ReadName(); + + Debug.Send("<{0}> <{1}>", bTex.TextureName, bTex.PaletteName); + + // placeholder pointers, don't need these + ins.Skip(8); + + bTex.TexMapID = ins.ReadUInt32(); + bTex.TlutID = ins.ReadUInt32(); + bTex.WrapS = ins.ReadUInt32(); + bTex.WrapT = ins.ReadUInt32(); + bTex.MinFilt = ins.ReadUInt32(); + bTex.MagFilt = ins.ReadUInt32(); + bTex.LODBias = ins.ReadFloat(); + bTex.MaxAniso = ins.ReadUInt32(); + bTex.BiasClamp = (ins.ReadByte() != 0); + bTex.DoEdgeLOD = (ins.ReadByte() != 0); + ins.Skip(2); + } + + return m; + } + + + private RawStreamResDict ReadDict(InputStream ins) { RawStreamResDict output = new RawStreamResDict(); diff --git a/NW4RTools/Models/Material.cs b/NW4RTools/Models/Material.cs index bb1b85a..4540b0d 100644 --- a/NW4RTools/Models/Material.cs +++ b/NW4RTools/Models/Material.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace NW4RTools.Models { public class ChanCtrl { @@ -7,6 +8,8 @@ namespace NW4RTools.Models { public UInt32 FlagC, FlagA; } + + // TODO: Rename this class? public class SRTSettingInfo { public float ScaleX, ScaleY, Rotate, TranslateX, TranslateY; @@ -22,6 +25,7 @@ namespace NW4RTools.Models { public UInt32 TexMapID, TlutID, WrapS, WrapT, MinFilt, MagFilt; public float LODBias; public UInt32 MaxAniso; + public bool BiasClamp, DoEdgeLOD; } @@ -43,8 +47,15 @@ namespace NW4RTools.Models { public byte[] TlutObj; // ResTexSrt + public UInt32 TexMatrixType; public SRTSettingInfo[] SRTSettings; + // ResMatChan + public ChanCtrl[] ChanCtrls; + + // Other + public List BoundTextures; + // UNFINISHED public Material() { diff --git a/NW4RTools/Models/Model.cs b/NW4RTools/Models/Model.cs index ea95f4f..8fa576e 100644 --- a/NW4RTools/Models/Model.cs +++ b/NW4RTools/Models/Model.cs @@ -15,6 +15,7 @@ namespace NW4RTools.Models { public ResDict VtxNrmData; public ResDict VtxClrData; public ResDict VtxTexCoordData; + public ResDict Materials; /*public ResDict Bytecode, Nodes, VtxPosData, VtsNrmData, VtxClrData, VtxTexCoordData; public ResDict VtxFurVecData, VtxFurPosData, Materials, Shaders, Shapes; diff --git a/NW4RTools/Types.cs b/NW4RTools/Types.cs index 7887f1c..78723dc 100644 --- a/NW4RTools/Types.cs +++ b/NW4RTools/Types.cs @@ -29,48 +29,36 @@ namespace NW4RTools { switch (x) { case 0: return v00; - break; case 1: return v01; - break; case 2: return v02; - break; case 3: return v03; - break; } break; case 1: switch (x) { case 0: return v10; - break; case 1: return v11; - break; case 2: return v12; - break; case 3: return v13; - break; } break; case 2: switch (x) { case 0: return v20; - break; case 1: return v21; - break; case 2: return v22; - break; case 3: return v23; - break; } break; } diff --git a/NW4RTools/bin/Debug/NW4RTools.dll b/NW4RTools/bin/Debug/NW4RTools.dll index adab05f..7e28e2a 100755 Binary files a/NW4RTools/bin/Debug/NW4RTools.dll and b/NW4RTools/bin/Debug/NW4RTools.dll differ diff --git a/NW4RTools/bin/Debug/NW4RTools.dll.mdb b/NW4RTools/bin/Debug/NW4RTools.dll.mdb index 51a7fb0..8183184 100644 Binary files a/NW4RTools/bin/Debug/NW4RTools.dll.mdb and b/NW4RTools/bin/Debug/NW4RTools.dll.mdb differ diff --git a/TestApp/bin/Debug/NW4RTools.dll b/TestApp/bin/Debug/NW4RTools.dll index adab05f..7e28e2a 100755 Binary files a/TestApp/bin/Debug/NW4RTools.dll and b/TestApp/bin/Debug/NW4RTools.dll differ diff --git a/TestApp/bin/Debug/NW4RTools.dll.mdb b/TestApp/bin/Debug/NW4RTools.dll.mdb index 51a7fb0..8183184 100644 Binary files a/TestApp/bin/Debug/NW4RTools.dll.mdb and b/TestApp/bin/Debug/NW4RTools.dll.mdb differ diff --git a/TestApp/bin/Debug/TestApp.exe b/TestApp/bin/Debug/TestApp.exe index 7adcab2..1e59f00 100755 Binary files a/TestApp/bin/Debug/TestApp.exe and b/TestApp/bin/Debug/TestApp.exe differ diff --git a/TestApp/bin/Debug/TestApp.exe.mdb b/TestApp/bin/Debug/TestApp.exe.mdb index 7e547e0..174701f 100644 Binary files a/TestApp/bin/Debug/TestApp.exe.mdb and b/TestApp/bin/Debug/TestApp.exe.mdb differ -- cgit v1.2.3