From 7d7491feb41bc9724bf63bef545b996226406889 Mon Sep 17 00:00:00 2001 From: Treeki Date: Sun, 13 Feb 2011 16:22:11 +0100 Subject: really messy code for materials/textures which KINDA works --- NW4RTools.userprefs | 20 ++---- NW4RTools/ColladaWriter.cs | 122 +++++++++++++++++++++++++++++++++- NW4RTools/NW4RTools.pidb | Bin 530650 -> 531637 bytes NW4RTools/Texture.cs | 18 ++++- NW4RTools/Util/IOrderedDictionary.cs | 3 + NW4RTools/Util/OrderedDictionary.cs | 6 +- NW4RTools/bin/Debug/NW4RTools.dll | Bin 164864 -> 166400 bytes NW4RTools/bin/Debug/NW4RTools.dll.mdb | Bin 90336 -> 90788 bytes TestApp/Main.cs | 4 +- TestApp/TestApp.pidb | Bin 3039 -> 2991 bytes TestApp/bin/Debug/NW4RTools.dll | Bin 164864 -> 166400 bytes TestApp/bin/Debug/NW4RTools.dll.mdb | Bin 90336 -> 90788 bytes TestApp/bin/Debug/TestApp.exe | Bin 4608 -> 4608 bytes TestApp/bin/Debug/TestApp.exe.mdb | Bin 548 -> 548 bytes 14 files changed, 153 insertions(+), 20 deletions(-) diff --git a/NW4RTools.userprefs b/NW4RTools.userprefs index 895a11a..843535e 100644 --- a/NW4RTools.userprefs +++ b/NW4RTools.userprefs @@ -1,22 +1,14 @@  - + - - - - - - - - - - - + + + - - + + diff --git a/NW4RTools/ColladaWriter.cs b/NW4RTools/ColladaWriter.cs index b7c039a..f0f5b19 100644 --- a/NW4RTools/ColladaWriter.cs +++ b/NW4RTools/ColladaWriter.cs @@ -69,7 +69,7 @@ namespace NW4RTools { img.name = "Texture-" + texName; img.id = img.name; - img.Item = texName + ".png"; + img.Item = "./images/" + texName + ".png"; ImageList.Add(img); } @@ -193,7 +193,7 @@ namespace NW4RTools { } // Apply shapes to nodes - foreach (var kv in CurrentModel.Shapes) { + /*foreach (var kv in CurrentModel.Shapes) { Shape shape = kv.Value; Node origNode = CurrentModel.Nodes[CurrentModel.MatrixIDtoNodeID[shape.MatrixID]]; node cNode = NodeDefs[origNode]; @@ -211,8 +211,107 @@ namespace NW4RTools { cNode.instance_geometry = geoArrayCopy; // TODO: Add material handling, I'll probably have to parse DrawOpa/DrawXlu for this... + }*/ + + // WARNING: THIS NEEDS REFACTORING + + int drawID = 0; + + foreach (var insn in CurrentModel.Bytecode["DrawOpa"].Instructions) { + if (insn is ByteCode.DrawShapeInstruction) { + var dsInsn = insn as ByteCode.DrawShapeInstruction; + + Shape shape = CurrentModel.Shapes[dsInsn.ShapeID]; + string shapeName = CurrentModel.Shapes.GetKeyForIndex(dsInsn.ShapeID); + + Node origNode = CurrentModel.Nodes[dsInsn.NodeID]; + node cNode = NodeDefs[origNode]; + + Material mat = CurrentModel.Materials[dsInsn.MaterialID]; + string matName = CurrentModel.Materials.GetKeyForIndex(dsInsn.MaterialID); + + var newGeoEntry = new instance_geometry(); + newGeoEntry.name = String.Format("DrawOpa{0}-{1}", drawID, shapeName); + newGeoEntry.url = String.Format("#{0}-lib", shapeName); + + // now add the material + var bindMaterial = newGeoEntry.bind_material = new bind_material(); + bindMaterial.technique_common = new instance_material[1]; + var matTechnique = bindMaterial.technique_common[0] = new instance_material(); + + // constant marker so that I don't have to set a unique material name in each primitive + // it doesn't matter, since each geometry instance only uses one material anyway + matTechnique.symbol = "NW4R_MATERIAL"; + matTechnique.target = "#Material-" + matName; + + matTechnique.bind_vertex_input = new instance_materialBind_vertex_input[1]; + matTechnique.bind_vertex_input[0] = new instance_materialBind_vertex_input(); + matTechnique.bind_vertex_input[0].semantic = "CHANNEL1"; + matTechnique.bind_vertex_input[0].input_semantic = "TEXCOORD"; + matTechnique.bind_vertex_input[0].input_set = 0; + + // ok, now add the instance_geometry into the node + instance_geometry[] geoArrayCopy = cNode.instance_geometry; + if (geoArrayCopy == null) + geoArrayCopy = new instance_geometry[1]; + else + Array.Resize(ref geoArrayCopy, geoArrayCopy.Length + 1); + geoArrayCopy[geoArrayCopy.Length - 1] = newGeoEntry; + cNode.instance_geometry = geoArrayCopy; + + drawID++; + } + } + + drawID = 0; + + foreach (var insn in CurrentModel.Bytecode["DrawXlu"].Instructions) { + if (insn is ByteCode.DrawShapeInstruction) { + var dsInsn = insn as ByteCode.DrawShapeInstruction; + + Shape shape = CurrentModel.Shapes[dsInsn.ShapeID]; + string shapeName = CurrentModel.Shapes.GetKeyForIndex(dsInsn.ShapeID); + + Node origNode = CurrentModel.Nodes[dsInsn.NodeID]; + node cNode = NodeDefs[origNode]; + + Material mat = CurrentModel.Materials[dsInsn.MaterialID]; + string matName = CurrentModel.Materials.GetKeyForIndex(dsInsn.MaterialID); + + var newGeoEntry = new instance_geometry(); + newGeoEntry.name = String.Format("DrawXlu{0}-{1}", drawID, shapeName); + newGeoEntry.url = String.Format("#{0}-lib", shapeName); + + // now add the material + var bindMaterial = newGeoEntry.bind_material = new bind_material(); + bindMaterial.technique_common = new instance_material[1]; + var matTechnique = bindMaterial.technique_common[0] = new instance_material(); + + // constant marker so that I don't have to set a unique material name in each primitive + // it doesn't matter, since each geometry instance only uses one material anyway + matTechnique.symbol = "NW4R_MATERIAL"; + matTechnique.target = "#Material-" + matName; + + matTechnique.bind_vertex_input = new instance_materialBind_vertex_input[1]; + matTechnique.bind_vertex_input[0] = new instance_materialBind_vertex_input(); + matTechnique.bind_vertex_input[0].semantic = "CHANNEL1"; + matTechnique.bind_vertex_input[0].input_semantic = "TEXCOORD"; + matTechnique.bind_vertex_input[0].input_set = 0; + + // ok, now add the instance_geometry into the node + instance_geometry[] geoArrayCopy = cNode.instance_geometry; + if (geoArrayCopy == null) + geoArrayCopy = new instance_geometry[1]; + else + Array.Resize(ref geoArrayCopy, geoArrayCopy.Length + 1); + geoArrayCopy[geoArrayCopy.Length - 1] = newGeoEntry; + cNode.instance_geometry = geoArrayCopy; + + drawID++; + } } + /*foreach (var kv in CurrentModel.Shapes) { var thisNode = new node(); @@ -277,10 +376,27 @@ namespace NW4RTools { sampler2d.source = "Surface-" + mat.TextureInfos[0].TextureName; + samplerParam.sid = "Sampler-" + mat.TextureInfos[0].TextureName; samplerParam.ItemElementName = ItemChoiceType.sampler2D; samplerParam.Item = sampler2d; profile.Items[1] = samplerParam; + // now make a technique + // should I really use blinn...? + profile.technique = new effectFx_profile_abstractProfile_COMMONTechnique(); + profile.technique.sid = "common"; + + var pShader = new effectFx_profile_abstractProfile_COMMONTechniquePhong(); + pShader.diffuse = new common_color_or_texture_type(); + + var diffuseTex = new common_color_or_texture_typeTexture(); + diffuseTex.texture = "Sampler-" + mat.TextureInfos[0].TextureName; + diffuseTex.texcoord = "CHANNEL1"; + + pShader.diffuse.Item = diffuseTex; + + profile.technique.Item = pShader; + return eff; } @@ -529,6 +645,7 @@ namespace NW4RTools { switch (prim) { case PrimitiveType.Triangles: var pTri = new triangles(); + pTri.material = "NW4R_MATERIAL"; pTri.count = (ulong)(vtxCount / 3); // should be 1? dunno pTri.input = inputArray; @@ -567,6 +684,7 @@ namespace NW4RTools { // If any tristrips were found, add them! if (triStrips.Count > 0) { var pTriStrips = new tristrips(); + pTriStrips.material = "NW4R_MATERIAL"; pTriStrips.input = inputArray; pTriStrips.count = (ulong)triStrips.Count; pTriStrips.p = triStrips.ToArray(); diff --git a/NW4RTools/NW4RTools.pidb b/NW4RTools/NW4RTools.pidb index 5cd6dc3..ff53d24 100644 Binary files a/NW4RTools/NW4RTools.pidb and b/NW4RTools/NW4RTools.pidb differ diff --git a/NW4RTools/Texture.cs b/NW4RTools/Texture.cs index 954852d..2de9ad8 100644 --- a/NW4RTools/Texture.cs +++ b/NW4RTools/Texture.cs @@ -137,6 +137,8 @@ namespace NW4RTools { case TextureFormat.RGB5A3: case TextureFormat.I4: case TextureFormat.I8: + case TextureFormat.IA4: + case TextureFormat.IA8: // I4 is stupid and breaks my parser. I'll keep some state here bool alreadyHaveI4Nybble = false; byte currentI4Byte = 0; @@ -194,6 +196,18 @@ namespace NW4RTools { } else if (format == TextureFormat.I8) { byte val = data.ReadByte(); *pPixel = 0xFF000000 | (uint)(val << 16) | (uint)(val << 8) | val; + + } else if (format == TextureFormat.IA4) { + byte val = data.ReadByte(); + uint i = (uint)(val >> 4); + uint a = (uint)((val & 0xF0) << 4); + *pPixel = (a << 24) | (i << 16) | (i << 8) | i; + + } else if (format == TextureFormat.IA8) { + byte i = data.ReadByte(); + byte a = data.ReadByte(); + *pPixel = (uint)(a << 24) | (uint)(i << 16) | (uint)(i << 8) | i; + } } } @@ -259,7 +273,9 @@ namespace NW4RTools { image.UnlockBits(bits); - + + image.RotateFlip(RotateFlipType.RotateNoneFlipY); // TODO: remove this, and fix texcoords properly + BaseImage = image; Format = format; } diff --git a/NW4RTools/Util/IOrderedDictionary.cs b/NW4RTools/Util/IOrderedDictionary.cs index a574c7c..6cf9b85 100644 --- a/NW4RTools/Util/IOrderedDictionary.cs +++ b/NW4RTools/Util/IOrderedDictionary.cs @@ -55,5 +55,8 @@ namespace NW4RTools.Util get; set; } + + + TKey GetKeyForIndex(int index); } } diff --git a/NW4RTools/Util/OrderedDictionary.cs b/NW4RTools/Util/OrderedDictionary.cs index 3dd4fb4..98e523a 100644 --- a/NW4RTools/Util/OrderedDictionary.cs +++ b/NW4RTools/Util/OrderedDictionary.cs @@ -162,11 +162,15 @@ namespace NW4RTools.Util return List.GetEnumerator(); } - IEnumerator> IEnumerable>.GetEnumerator() + IEnumerator> IEnumerable>.GetEnumerator() { return List.GetEnumerator(); } + public TKey GetKeyForIndex(int index) { + return List[index].Key; + } + /// /// Inserts a new entry into the OrderedDictionary<TKey,TValue> collection with the specified key and value at the specified index. /// diff --git a/NW4RTools/bin/Debug/NW4RTools.dll b/NW4RTools/bin/Debug/NW4RTools.dll index a87dfa6..91a4b75 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 4b18386..127ef0f 100644 Binary files a/NW4RTools/bin/Debug/NW4RTools.dll.mdb and b/NW4RTools/bin/Debug/NW4RTools.dll.mdb differ diff --git a/TestApp/Main.cs b/TestApp/Main.cs index 408c95f..3eb49a4 100644 --- a/TestApp/Main.cs +++ b/TestApp/Main.cs @@ -8,7 +8,7 @@ namespace TestApp { public static void Main(string[] args) { string mdlPath = "/home/me/Games/Newer/ModelRev/"; - string mdlName = "CS_W9"; + string mdlName = "CS_W1"; //string mdlName = "bgB_4502"; string whatever = (mdlName == "CS_W2" || mdlName == "CS_W3" || mdlName == "CS_W6") ? "a" : ""; @@ -19,7 +19,7 @@ namespace TestApp { var texs = rf.GetGroup("Textures(NW4R)"); // wtf C#?! foreach (var kv in (IEnumerable>)texs) { - kv.Value.BaseImage.Save(mdlPath + kv.Key + ".png"); + kv.Value.BaseImage.Save(mdlPath + "images/" + kv.Key + ".png"); } //var objFile = File.Open(mdlPath + mdlName + ".obj", FileMode.OpenOrCreate); diff --git a/TestApp/TestApp.pidb b/TestApp/TestApp.pidb index d59d1d6..bf2fb29 100644 Binary files a/TestApp/TestApp.pidb and b/TestApp/TestApp.pidb differ diff --git a/TestApp/bin/Debug/NW4RTools.dll b/TestApp/bin/Debug/NW4RTools.dll index a87dfa6..91a4b75 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 4b18386..127ef0f 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 5026c79..1bce1bb 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 ff5ef5f..00eab08 100644 Binary files a/TestApp/bin/Debug/TestApp.exe.mdb and b/TestApp/bin/Debug/TestApp.exe.mdb differ -- cgit v1.2.3