summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreeki <treeki@gmail.com>2011-03-10 03:00:09 +0100
committerTreeki <treeki@gmail.com>2011-03-10 03:00:09 +0100
commit5926616de2bd346f1a1c69c93ff2aaa3c453a2b3 (patch)
treef282b05ae5616a05fb4db167fad20ec242775c27
parent7d391e33a0b3d9793c95fce832abb2c6d9002186 (diff)
downloadnw4rtools-5926616de2bd346f1a1c69c93ff2aaa3c453a2b3.tar.gz
nw4rtools-5926616de2bd346f1a1c69c93ff2aaa3c453a2b3.zip
kinda hackish, but mostly working NSMBW lightmap support
-rw-r--r--NW4RTools.userprefs21
-rw-r--r--NW4RTools/ColladaExporter.cs72
-rw-r--r--NW4RTools/ColladaWriter.cs732
-rw-r--r--NW4RTools/Models/OpenGL/GLModel.cs2
-rw-r--r--NW4RTools/NW4RTools.pidbbin579951 -> 582467 bytes
-rwxr-xr-xNW4RTools/ObjImporter.cs309
-rw-r--r--NW4RTools/ObjWriter.cs187
-rwxr-xr-xNW4RTools/bin/Debug/NW4RTools.dllbin235008 -> 235008 bytes
-rw-r--r--NW4RTools/bin/Debug/NW4RTools.dll.mdbbin113704 -> 113949 bytes
-rw-r--r--TestApp/Main.cs19
-rw-r--r--TestApp/RenderWindow.cs4
-rw-r--r--TestApp/TestApp.pidbbin4427 -> 4427 bytes
-rwxr-xr-xTestApp/bin/Debug/NW4RTools.dllbin233472 -> 235008 bytes
-rw-r--r--TestApp/bin/Debug/NW4RTools.dll.mdbbin112974 -> 113949 bytes
-rwxr-xr-xTestApp/bin/Debug/TestApp.exebin7168 -> 7680 bytes
-rw-r--r--TestApp/bin/Debug/TestApp.exe.mdbbin1243 -> 1226 bytes
16 files changed, 284 insertions, 1062 deletions
diff --git a/NW4RTools.userprefs b/NW4RTools.userprefs
index 5273e53..e852c49 100644
--- a/NW4RTools.userprefs
+++ b/NW4RTools.userprefs
@@ -1,23 +1,26 @@
<Properties>
<MonoDevelop.Ide.Workspace ActiveConfiguration="Debug" />
- <MonoDevelop.Ide.Workbench ActiveDocument="NW4RTools/ObjImporter.cs">
+ <MonoDevelop.Ide.Workbench ActiveDocument="NW4RTools/BrresWriter.cs">
<Files>
- <File FileName="NW4RTools/ObjImporter.cs" Line="244" Column="37" />
+ <File FileName="NW4RTools/ObjImporter.cs" Line="29" Column="35" />
<File FileName="NW4RTools/ObjExporter.cs" Line="105" Column="25" />
- <File FileName="NW4RTools/BrresReader.cs" Line="784" Column="11" />
- <File FileName="NW4RTools/BrresWriter.cs" Line="499" Column="36" />
+ <File FileName="NW4RTools/BrresReader.cs" Line="654" Column="30" />
+ <File FileName="NW4RTools/BrresWriter.cs" Line="1013" Column="32" />
<File FileName="NW4RTools/Models/Model.cs" Line="1" Column="1" />
<File FileName="NW4RTools/Models/ByteCode.cs" Line="1" Column="1" />
- <File FileName="TestApp/Main.cs" Line="76" Column="1" />
+ <File FileName="TestApp/Main.cs" Line="82" Column="27" />
<File FileName="NW4RTools/Types.cs" Line="1" Column="1" />
- <File FileName="NW4RTools/Models/Material.cs" Line="27" Column="18" />
+ <File FileName="NW4RTools/Models/Material.cs" Line="70" Column="1" />
<File FileName="NW4RTools/VertexSettings.cs" Line="184" Column="46" />
<File FileName="NW4RTools/Models/VertexData.cs" Line="238" Column="31" />
- <File FileName="NW4RTools/Enums.cs" Line="23" Column="27" />
- <File FileName="NW4RTools/Models/OpenGL/GLModel.cs" Line="218" Column="7" />
+ <File FileName="NW4RTools/Models/OpenGL/GLModel.cs" Line="218" Column="9" />
<File FileName="NW4RTools/InputStream.cs" Line="86" Column="1" />
- <File FileName="TestApp/RenderWindow.cs" Line="36" Column="78" />
+ <File FileName="TestApp/RenderWindow.cs" Line="65" Column="57" />
<File FileName="NW4RTools/Models/OpenGL/GLDisplayList.cs" Line="20" Column="1" />
+ <File FileName="NW4RTools/Enums.cs" Line="25" Column="25" />
+ <File FileName="NW4RTools/DisplayListWriter.cs" Line="76" Column="21" />
+ <File FileName="NW4RTools/OutputStream.cs" Line="62" Column="32" />
+ <File FileName="NW4RTools/ColladaExporter.cs" Line="273" Column="7" />
</Files>
</MonoDevelop.Ide.Workbench>
<MonoDevelop.Ide.DebuggingService.Breakpoints>
diff --git a/NW4RTools/ColladaExporter.cs b/NW4RTools/ColladaExporter.cs
index f18bfed..cd5aaf1 100644
--- a/NW4RTools/ColladaExporter.cs
+++ b/NW4RTools/ColladaExporter.cs
@@ -264,50 +264,52 @@ namespace NW4RTools {
}
drawID = 0;
-
- foreach (var insn in CurrentModel.Bytecode["DrawXlu"].Instructions) {
- if (insn is ByteCode.DrawShapeInstruction) {
- var dsInsn = insn as ByteCode.DrawShapeInstruction;
+
+ if (CurrentModel.Bytecode.ContainsKey("DrawXlu")) {
+ 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);
+ Shape shape = CurrentModel.Shapes[dsInsn.ShapeID];
+ string shapeName = CurrentModel.Shapes.GetKeyForIndex(dsInsn.ShapeID);
- Node origNode = CurrentModel.Nodes[dsInsn.NodeID];
- node cNode = NodeDefs[origNode];
+ Node origNode = CurrentModel.Nodes[dsInsn.NodeID];
+ node cNode = NodeDefs[origNode];
- Material mat = CurrentModel.Materials[dsInsn.MaterialID];
- string matName = CurrentModel.Materials.GetKeyForIndex(dsInsn.MaterialID);
+ 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);
+ 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();
+ // 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;
+ // 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;
+ 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<instance_geometry>(ref geoArrayCopy, geoArrayCopy.Length + 1);
- geoArrayCopy[geoArrayCopy.Length - 1] = newGeoEntry;
- cNode.instance_geometry = geoArrayCopy;
+ // 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<instance_geometry>(ref geoArrayCopy, geoArrayCopy.Length + 1);
+ geoArrayCopy[geoArrayCopy.Length - 1] = newGeoEntry;
+ cNode.instance_geometry = geoArrayCopy;
- drawID++;
+ drawID++;
+ }
}
}
diff --git a/NW4RTools/ColladaWriter.cs b/NW4RTools/ColladaWriter.cs
deleted file mode 100644
index 2c57d7e..0000000
--- a/NW4RTools/ColladaWriter.cs
+++ /dev/null
@@ -1,732 +0,0 @@
-using System;
-using System.IO;
-using System.Collections.Generic;
-using System.Text;
-using NW4RTools.Models;
-using Collada141;
-
-namespace NW4RTools {
- public class ColladaWriter {
- public static void WriteModel(Stream outputStream, ResFile file, string modelName) {
- new ColladaWriter(file).SaveModel(outputStream, modelName);
- }
-
-
-
- ResFile CurrentFile;
- Models.Model CurrentModel;
- COLLADA Collada;
-
- library_geometries LibGeometries;
- library_visual_scenes LibVisualScenes;
- library_images LibImages;
- library_materials LibMaterials;
- library_effects LibEffects;
-
- private ColladaWriter(ResFile file) {
- CurrentFile = file;
- }
-
- public void SaveModel(Stream outputStream, string modelName) {
- CurrentModel = CurrentFile.GetGroup<Model>("3DModels(NW4R)")[modelName];
- Collada = new COLLADA();
-
- Collada.asset = new asset();
-
- Collada.asset.contributor = new assetContributor[1];
- Collada.asset.contributor[0] = new assetContributor();
- Collada.asset.contributor[0].authoring_tool = "NW4RTools Collada exporter by Treeki";
- Collada.asset.contributor[0].source_data = "NW4R model: " + modelName;
- //Collada.asset.created = DateTime.Now;
- //Collada.asset.modified = DateTime.Now;
- Collada.asset.unit = new assetUnit();
- Collada.asset.unit.meter = 1.0;
- Collada.asset.up_axis = UpAxisType.Y_UP;
-
- var ColladaItems = new List<object>();
-
- // First up, before anything else: images and materials
- // Compile a list of every texture we use in the model
- var usedTextures = new List<string>();
-
- foreach (var kv in CurrentModel.Materials) {
- foreach (var texInfo in kv.Value.TextureInfos) {
- if (!usedTextures.Contains(texInfo.TextureName))
- usedTextures.Add(texInfo.TextureName);
- }
- }
-
- // Create a Collada image for these
- LibImages = new library_images();
- ColladaItems.Add(LibImages);
-
- var ImageList = new List<image>();
- var TexGroup = CurrentFile.GetGroup<Texture>("Textures(NW4R)");
-
- foreach (var texName in usedTextures) {
- var img = new image();
- var tex = TexGroup[texName];
-
- img.name = "Texture-" + texName;
- img.id = img.name;
- img.Item = "./images/" + texName + ".png";
-
- ImageList.Add(img);
- }
-
- LibImages.image = ImageList.ToArray();
-
- // Make a quick reference material for each one
- LibMaterials = new library_materials();
- ColladaItems.Add(LibMaterials);
-
- var MaterialList = new List<material>();
-
- foreach (var kv in CurrentModel.Materials) {
- var mat = new material();
-
- mat.name = "Material-" + kv.Key;
- mat.id = mat.name;
- mat.instance_effect = new instance_effect();
- mat.instance_effect.url = "#Material-Effect-" + kv.Key;
-
- MaterialList.Add(mat);
- }
-
- LibMaterials.material = MaterialList.ToArray();
-
- // Now create an effect for each material (this is where all the real work is done!)
- LibEffects = new library_effects();
- ColladaItems.Add(LibEffects);
-
- var EffectList = new List<effect>();
- foreach (var kv in CurrentModel.Materials) {
- EffectList.Add(CreateEffectFromMaterial(kv.Key, kv.Value));
- }
-
- LibEffects.effect = EffectList.ToArray();
-
- // Now shapes
- LibGeometries = new library_geometries();
- ColladaItems.Add(LibGeometries);
-
- var GeometryList = new List<geometry>();
- foreach (var kv in CurrentModel.Shapes) {
- GeometryList.Add(CreateGeometryFromShape(kv.Key, kv.Value));
- }
-
- LibGeometries.geometry = GeometryList.ToArray();
-
- // SHAPES ARE DONE.
- // Next up: Visual Scenes (I will just create one atm)
-
- LibVisualScenes = new library_visual_scenes();
- ColladaItems.Add(LibVisualScenes);
-
- LibVisualScenes.visual_scene = new visual_scene[1];
- var mainScene = LibVisualScenes.visual_scene[0] = new visual_scene();
-
- // TODO: Change this so it doesn't have the possibility of name collisions with shapes
- mainScene.id = "RootNode";
- mainScene.name = "RootNode";
- var mainSceneNodeList = new List<node>();
-
- // OK, so here's what's up: first off, we must create a definition for every node
- var NodeDefs = new Dictionary<Node, node>();
-
- foreach (var kv in CurrentModel.Nodes) {
- string nodeName = kv.Key;
- Node origNode = kv.Value;
- var cNode = new node();
-
- cNode.id = nodeName;
- cNode.name = nodeName;
- //cNode.type = NodeType.JOINT;
- cNode.node1 = new node[0];
-
- double cosX = Math.Cos(origNode.Rotation.x / 180 * Math.PI);
- double cosY = Math.Cos(origNode.Rotation.y / 180 * Math.PI);
- double cosZ = Math.Cos(origNode.Rotation.z / 180 * Math.PI);
- double sinX = Math.Sin(origNode.Rotation.x / 180 * Math.PI);
- double sinY = Math.Sin(origNode.Rotation.y / 180 * Math.PI);
- double sinZ = Math.Sin(origNode.Rotation.z / 180 * Math.PI);
-
- var nodeMatrix = new matrix();
- nodeMatrix.Values = new double[] {
- origNode.Scale.x * cosY * cosZ,
- origNode.Scale.y * (sinX * cosZ * sinY - cosX * sinZ),
- origNode.Scale.z * (sinX * sinZ + cosX * cosZ * sinY),
- origNode.Translation.x,
- origNode.Scale.x * sinZ * cosY,
- origNode.Scale.y * (sinX * sinZ * sinY + cosZ * cosX),
- origNode.Scale.z * (cosX * sinZ * sinY - sinX * cosZ),
- origNode.Translation.y,
- -origNode.Scale.x * sinY,
- origNode.Scale.y * sinX * cosY,
- origNode.Scale.z * cosX * cosY,
- origNode.Translation.z,
- 0, 0, 0, 1
- };
-
- cNode.Items = new object[] { nodeMatrix };
- cNode.ItemsElementName = new ItemsChoiceType2[] { ItemsChoiceType2.matrix };
-
- NodeDefs[origNode] = cNode;
- }
-
- // Now add them to the hierarchy
- foreach (var kv in NodeDefs) {
- Node origNode = kv.Key;
- node cNode = kv.Value;
-
- if (origNode.Parent == null) {
- mainSceneNodeList.Add(cNode);
- } else {
- var parentNode = NodeDefs[origNode.Parent];
-
- // this is stupid, thanks C#
- node[] nodeArrayCopy = parentNode.node1;
- Array.Resize<node>(ref nodeArrayCopy, nodeArrayCopy.Length + 1);
- nodeArrayCopy[nodeArrayCopy.Length - 1] = cNode;
- parentNode.node1 = nodeArrayCopy;
- }
- }
-
- // Apply shapes to nodes
- /*foreach (var kv in CurrentModel.Shapes) {
- Shape shape = kv.Value;
- Node origNode = CurrentModel.Nodes[CurrentModel.MatrixIDtoNodeID[shape.MatrixID]];
- node cNode = NodeDefs[origNode];
-
- var newGeoEntry = new instance_geometry();
- newGeoEntry.name = kv.Key;
- newGeoEntry.url = String.Format("#{0}-lib", kv.Key);
-
- instance_geometry[] geoArrayCopy = cNode.instance_geometry;
- if (geoArrayCopy == null)
- geoArrayCopy = new instance_geometry[1];
- else
- Array.Resize<instance_geometry>(ref geoArrayCopy, geoArrayCopy.Length + 1);
- geoArrayCopy[geoArrayCopy.Length - 1] = newGeoEntry;
- 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<instance_geometry>(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<instance_geometry>(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();
-
- thisNode.id = kv.Key;
- thisNode.name = kv.Key;
- thisNode.instance_geometry = new instance_geometry[1];
- thisNode.instance_geometry[0] = new instance_geometry();
- thisNode.instance_geometry[0].url = String.Format("#{0}-lib", kv.Key);
-
- mainSceneNodeList.Add(thisNode);
- }*/
-
- mainScene.node = mainSceneNodeList.ToArray();
-
-
- // Finally, create a scene
- Collada.scene = new COLLADAScene();
- Collada.scene.instance_visual_scene = new InstanceWithExtra();
- Collada.scene.instance_visual_scene.url = "#RootNode";
-
- Collada.Items = ColladaItems.ToArray();
- Collada.Save(outputStream);
- }
-
-
-
- private effect CreateEffectFromMaterial(string name, Material mat) {
- var eff = new effect();
-
- eff.id = "Material-Effect-" + name;
- eff.name = eff.id;
-
-
- // HACK!!
- if (mat.TextureInfos.Count == 0)
- return eff;
-
- // this is based off what colladamax outputs
- eff.Items = new effectFx_profile_abstractProfile_COMMON[1];
- var profile = eff.Items[0] = new effectFx_profile_abstractProfile_COMMON();
-
- // TODO: handle this correctly for multiple textures ETC and check how bb does it
-
- profile.Items = new object[2];
-
- // create a surface newparam
- var surfaceParam = new common_newparam_type();
- var surface = new fx_surface_common();
-
- surface.type = fx_surface_type_enum.Item2D;
- surface.init_from = new fx_surface_init_from_common[1];
- surface.init_from[0] = new fx_surface_init_from_common();
- surface.init_from[0].Value = "Texture-" + mat.TextureInfos[0].TextureName;
-
- surfaceParam.sid = "Surface-" + mat.TextureInfos[0].TextureName;
- surfaceParam.ItemElementName = ItemChoiceType.surface;
- surfaceParam.Item = surface;
- profile.Items[0] = surfaceParam;
-
- // now create a sampler newparam
- var samplerParam = new common_newparam_type();
- var sampler2d = new fx_sampler2D_common();
-
- // add wrapping
- sampler2d.source = "Surface-" + mat.TextureInfos[0].TextureName;
- sampler2d.wrap_s = mat.TextureInfos[0].WrapS.ToColladaSamplerWrap();
- sampler2d.wrap_t = mat.TextureInfos[0].WrapT.ToColladaSamplerWrap();
-
- 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;
-
- pShader.emission = new common_color_or_texture_type();
- var emissionClr = new common_color_or_texture_typeColor();
- emissionClr.Values = new double[] { 0, 0, 0, 1 };
- pShader.emission.Item = emissionClr;
-
- pShader.ambient = new common_color_or_texture_type();
- var ambientClr = new common_color_or_texture_typeColor();
- ambientClr.Values = new double[] { 0, 0, 0, 1 };
- pShader.ambient.Item = ambientClr;
-
- pShader.transparent = new common_transparent_type();
- pShader.transparent.opaque = fx_opaque_enum.A_ONE;
- var transparentClr = new common_color_or_texture_typeColor();
- transparentClr.Values = new double[] { 1, 1, 1, 1 };
- pShader.transparent.Item = transparentClr;
- pShader.transparency = new common_float_or_param_type();
- var bs = new common_float_or_param_typeFloat();
- bs.Value = 1;
- pShader.transparency.Item = bs;
- // we can reuse DiffuseTex!
- pShader.transparent.Item = diffuseTex;
-
- profile.technique.Item = pShader;
-
- return eff;
- }
-
-
-
- private geometry CreateGeometryFromShape(string name, Shape shape) {
- var geo = new geometry();
-
- geo.id = name + "-lib";
- geo.name = name + "Mesh";
-
- var m = new mesh();
- geo.Item = m;
-
- // Vertex settings
- var firstDL = new InputStream(shape.DisplayList1);
- firstDL.Seek(0x0C);
- UInt32 vtxDesc1 = firstDL.ReadUInt32();
- firstDL.Seek(0x12);
- UInt32 vtxDesc2 = firstDL.ReadUInt32();
- firstDL.Seek(0x22);
- UInt32 vtxAttr1 = firstDL.ReadUInt32();
- firstDL.Seek(0x28);
- UInt32 vtxAttr2 = firstDL.ReadUInt32();
- firstDL.Seek(0x2E);
- UInt32 vtxAttr3 = firstDL.ReadUInt32();
-
- var vs = new VertexSettings();
- vs.SetDesc(vtxDesc1, vtxDesc2);
- vs.SetAttrFmt(vtxAttr1, vtxAttr2, vtxAttr3);
-
- // Figure out how many elements we need in the Source array
- // Position data ALWAYS exists
- int sourceCount = 1;
- sourceCount += (shape.NrmData != null) ? 1 : 0;
- for (int i = 0; i < 8; i++)
- sourceCount += (shape.TexCoordData[i] != null) ? 1 : 0;
-
- m.source = new source[sourceCount];
- int currentSource = 0;
-
- // TODO: Refactor this messy code!
-
- int dest;
-
- // Write position data
- var posData = shape.PosData;
- var posSource = new source();
- posSource.id = name + "-lib-Position";
- m.source[currentSource++] = posSource;
-
- var posArray = new float_array();
- posArray.id = name + "-lib-Position-array";
- posArray.count = (ulong)(posData.GetRealCount() * posData.EntryCount);
- posArray.Values = new double[posArray.count];
-
- dest = 0;
- for (int i = 0; i < posData.EntryCount; i++) {
- float[] data = posData.GetEntry(i);
- for (int j = 0; j < data.Length; j++) {
- posArray.Values[dest++] = data[j];
- }
- }
-
- posSource.Item = posArray;
-
- // Write position technique
- posSource.technique_common = new sourceTechnique_common();
- var posAcc = posSource.technique_common.accessor = new accessor();
- posAcc.source = String.Format("#{0}-lib-Position-array", name);
- posAcc.count = posData.EntryCount;
- posAcc.stride = (ulong)posData.GetRealCount();
-
- posAcc.param = new param[posData.GetRealCount()];
- string[] posParamNames = new string[] { "X", "Y", "Z" };
-
- for (int i = 0; i < posAcc.param.Length; i++) {
- posAcc.param[i] = new param();
- posAcc.param[i].name = posParamNames[i];
- posAcc.param[i].type = "float";
- }
-
-
- // Write normal data
- if (shape.NrmData != null) {
- var nrmData = shape.NrmData;
- var nrmSource = new source();
- nrmSource.id = name + "-lib-Normal";
- m.source[currentSource++] = nrmSource;
-
- var nrmArray = new float_array();
- nrmArray.id = name + "-lib-Normal-array";
- nrmArray.count = (ulong)(nrmData.GetRealCount() * nrmData.EntryCount);
- nrmArray.Values = new double[nrmArray.count];
-
- dest = 0;
- for (int i = 0; i < nrmData.EntryCount; i++) {
- float[] data = nrmData.GetEntry(i);
- for (int j = 0; j < data.Length; j++) {
- nrmArray.Values[dest++] = data[j];
- }
- }
-
- nrmSource.Item = nrmArray;
-
- // Write normal technique
- nrmSource.technique_common = new sourceTechnique_common();
- var nrmAcc = nrmSource.technique_common.accessor = new accessor();
- nrmAcc.source = String.Format("#{0}-lib-Normal-array", name);
- nrmAcc.count = nrmData.EntryCount;
- nrmAcc.stride = (ulong)nrmData.GetRealCount();
-
- nrmAcc.param = new param[nrmData.GetRealCount()];
- string[] nrmParamNames = new string[] { "X", "Y", "Z" };
-
- for (int i = 0; i < nrmAcc.param.Length; i++) {
- nrmAcc.param[i] = new param();
- nrmAcc.param[i].name = nrmParamNames[i];
- nrmAcc.param[i].type = "float";
- }
- }
-
-
- // Write TexCoord data
- for (int tcIndex = 0; tcIndex < 8; tcIndex++) {
- if (shape.TexCoordData[tcIndex] != null) {
- var tcData = shape.TexCoordData[tcIndex];
- var tcSource = new source();
- tcSource.id = String.Format("{0}-lib-TexCoord{1}", name, tcIndex);
- m.source[currentSource++] = tcSource;
-
- var tcArray = new float_array();
- tcArray.id = String.Format("{0}-lib-TexCoord{1}-array", name, tcIndex);
- tcArray.count = (ulong)(tcData.GetRealCount() * tcData.EntryCount);
- tcArray.Values = new double[tcArray.count];
-
- dest = 0;
- for (int i = 0; i < tcData.EntryCount; i++) {
- float[] data = tcData.GetEntry(i);
- for (int j = 0; j < data.Length; j++) {
- // flip T (Y axis) coordinate
- if (j == 1)
- tcArray.Values[dest++] = 1.0 - data[j];
- else
- tcArray.Values[dest++] = data[j];
- }
- }
-
- tcSource.Item = tcArray;
-
- // Write texcoord technique
- tcSource.technique_common = new sourceTechnique_common();
- var tcAcc = tcSource.technique_common.accessor = new accessor();
- tcAcc.source = String.Format("#{0}-lib-TexCoord{1}-array", name, tcIndex);
- tcAcc.count = tcData.EntryCount;
- tcAcc.stride = (ulong)tcData.GetRealCount();
-
- tcAcc.param = new param[tcData.GetRealCount()];
- string[] tcParamNames = new string[] { "S", "T" };
-
- for (int i = 0; i < tcAcc.param.Length; i++) {
- tcAcc.param[i] = new param();
- tcAcc.param[i].name = tcParamNames[i];
- tcAcc.param[i].type = "float";
- }
- }
- }
-
-
-
- // Ok, we've written all the raw float data, now set up vertices
- // TODO: Vertex colours
- m.vertices = new vertices();
- m.vertices.id = String.Format("{0}-lib-Vertex", name);
- m.vertices.input = new InputLocal[1];
- m.vertices.input[0] = new InputLocal();
- m.vertices.input[0].semantic = "POSITION";
- m.vertices.input[0].source = String.Format("#{0}-lib-Position", name);
-
- // And before we finish, write the polygon data of course
- var dl = new InputStream(shape.DisplayList2);
-
- List<object> meshItems = new List<object>();
-
- // create the Input array -- we can reuse sourceCount!
- var inputArray = new InputLocalOffset[sourceCount];
- currentSource = 0;
-
- var posInput = inputArray[currentSource] = new InputLocalOffset();
- posInput.semantic = "VERTEX";
- posInput.offset = (ulong)currentSource;
- posInput.source = String.Format("#{0}-lib-Vertex", name);
- currentSource++;
-
- if (shape.NrmData != null) {
- var nrmInput = inputArray[currentSource] = new InputLocalOffset();
- nrmInput.semantic = "NORMAL";
- nrmInput.offset = (ulong)currentSource;
- nrmInput.source = String.Format("#{0}-lib-Normal", name);
- currentSource++;
- }
-
- for (int i = 0; i < 8; i++) {
- if (shape.TexCoordData[i] != null) {
- var tcInput = inputArray[currentSource] = new InputLocalOffset();
- tcInput.semantic = "TEXCOORD";
- tcInput.offset = (ulong)currentSource;
- tcInput.@set = (ulong)i;
- tcInput.source = String.Format("#{0}-lib-TexCoord{1}", name, i);
- currentSource++;
- }
- }
-
-
- // Create a list for tristrips beforehand, because they're THE most common
- List<string> triStrips = new List<string>();
-
-
- // Now go through the display list
- while (true) {
- if (dl.AtEnd)
- break;
-
- byte cmd = dl.ReadByte();
- if (cmd == 0)
- break;
-
- PrimitiveType prim = (PrimitiveType)((cmd >> 3) & 7);
- int vtxCount = dl.ReadUInt16();
-
- // first, parse it into a list of vertices
- GXIndexedVertex[] vtxs = new GXIndexedVertex[vtxCount];
- string[] pVtxs = new string[vtxCount];
-
- for (int i = 0; i < vtxCount; i++) {
- vtxs[i].LoadFrom(dl, vs);
-
- pVtxs[i] = vtxs[i].Position.ToString();
-
- if (vs.NormalDesc != VertexSettings.DescType.None)
- pVtxs[i] += " " + vtxs[i].Normal.ToString();
-
- for (int j = 0; j < 8; j++) {
- if (vs.TexCoordDesc[j] != VertexSettings.DescType.None) {
- pVtxs[i] += " " + vtxs[i].TexCoords[j].ToString();
- }
- }
- }
-
- 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;
-
- StringBuilder pTriData = new StringBuilder();
-
- for (int i = 0; i < vtxCount; i++) {
- pTriData.AppendFormat("{0} ", pVtxs[i]);
- }
-
-
- pTri.p = pTriData.ToString();
-
- meshItems.Add(pTri);
- break;
-
- case PrimitiveType.TriangleStrip:
- StringBuilder pTriStripData = new StringBuilder();
-
- for (int i = 0; i < vtxCount; i++) {
- pTriStripData.AppendFormat("{0} ", pVtxs[i]);
- }
-
-
- triStrips.Add(pTriStripData.ToString());
- break;
- default:
-
-
- Console.WriteLine("UNIMPLEMENTED PRIMITIVE TYPE");
- return geo;
- }
- }
-
-
- // 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();
- meshItems.Add(pTriStrips);
- }
-
-
- m.Items = meshItems.ToArray();
-
- // FINALLY DONE!
- return geo;
- }
- }
-}
-
diff --git a/NW4RTools/Models/OpenGL/GLModel.cs b/NW4RTools/Models/OpenGL/GLModel.cs
index 18e5f6f..7de560e 100644
--- a/NW4RTools/Models/OpenGL/GLModel.cs
+++ b/NW4RTools/Models/OpenGL/GLModel.cs
@@ -215,7 +215,7 @@ namespace NW4RTools.Models.OpenGL {
GL.BindTexture(TextureTarget.Texture2D, 0);
} else {
BindTextureInfo(texInfoArray[i]);
- GL.Enable(EnableCap.Texture2D);
+ //GL.Enable(EnableCap.Texture2D);
}
}
diff --git a/NW4RTools/NW4RTools.pidb b/NW4RTools/NW4RTools.pidb
index e7aef3c..6bd6989 100644
--- a/NW4RTools/NW4RTools.pidb
+++ b/NW4RTools/NW4RTools.pidb
Binary files differ
diff --git a/NW4RTools/ObjImporter.cs b/NW4RTools/ObjImporter.cs
index 81fcf81..1606028 100755
--- a/NW4RTools/ObjImporter.cs
+++ b/NW4RTools/ObjImporter.cs
@@ -239,86 +239,165 @@ namespace NW4RTools {
// Create a new material and initialise everything
// Default settings taken from Test_Lift material
currentMaterial = new Material();
-
- currentMaterial.TexCoordGenCount = 1;
- currentMaterial.ChanCount = 1;
- currentMaterial.TevStageCount = 2;
- currentMaterial.IndStageCount = 0;
-
- // This might need changing
- currentMaterial.CullMode = 2;
-
- currentMaterial.SRTSettings[0] = new SRTSettingInfo();
-
- currentMaterial.ChanCtrls[0] = new ChanCtrl();
- currentMaterial.ChanCtrls[0].Flags = 0x3F;
- currentMaterial.ChanCtrls[0].MatColor.Rgba = 0xFFFFFFFF;
- currentMaterial.ChanCtrls[0].AmbColor.Rgba = 0xFFFFFFFF;
- currentMaterial.ChanCtrls[0].FlagC = 0x702;
- currentMaterial.ChanCtrls[0].FlagA = 0x700;
-
- currentMaterial.ChanCtrls[1] = new ChanCtrl();
- currentMaterial.ChanCtrls[1].Flags = 0xF;
- currentMaterial.ChanCtrls[1].MatColor.Rgba = 0x000000FF;
- currentMaterial.ChanCtrls[1].AmbColor.Rgba = 0x00000000;
- currentMaterial.ChanCtrls[1].FlagC = 0;
+
+ currentMaterial.ChanCtrls[0] = new ChanCtrl();
+ currentMaterial.ChanCtrls[0].Flags = 0x3F;
+ currentMaterial.ChanCtrls[0].MatColor.Rgba = 0xFFFFFFFF;
+ currentMaterial.ChanCtrls[0].AmbColor.Rgba = 0xFFFFFFFF;
+ currentMaterial.ChanCtrls[0].FlagC = Lightmaps ? (uint)0x701 : (uint)0x702;
+ currentMaterial.ChanCtrls[0].FlagA = 0x700;
+
+ currentMaterial.ChanCtrls[1] = new ChanCtrl();
+ currentMaterial.ChanCtrls[1].Flags = 0xF;
+ currentMaterial.ChanCtrls[1].MatColor.Rgba = 0x000000FF;
+ currentMaterial.ChanCtrls[1].AmbColor.Rgba = 0x00000000;
+ currentMaterial.ChanCtrls[1].FlagC = 0;
currentMaterial.ChanCtrls[1].FlagA = 0;
- currentMaterial.LightSetID = 1;
+ if (!Lightmaps) {
+ currentMaterial.TexCoordGenCount = 1;
+ currentMaterial.ChanCount = 1;
+ currentMaterial.TevStageCount = 2;
+ currentMaterial.IndStageCount = 0;
+
+ // This might need changing
+ currentMaterial.CullMode = 2;
+
+ currentMaterial.LightSetID = 1;
+
+ currentMaterial.SRTSettings[0] = new SRTSettingInfo();
- // Default display lists, taken from test_lift
- var pixDL = new DisplayListWriter();
- pixDL.LoadBPReg(0xF31EFF80);
- pixDL.LoadBPReg(0x40000017);
- pixDL.LoadBPReg(0xFE00FFE3);
- pixDL.LoadBPReg(0x410034A0);
- pixDL.LoadBPReg(0x42000000);
- pixDL.End();
-
- currentMaterial.PixDL = pixDL.GetBuffer();
-
- var tevColorDL = new DisplayListWriter();
- tevColorDL.LoadBPReg(0xE20000FF);
- tevColorDL.LoadBPReg(0xE30FF0FF);
- tevColorDL.LoadBPReg(0xE30FF0FF);
- tevColorDL.LoadBPReg(0xE30FF0FF);
- tevColorDL.LoadBPReg(0xE4000000);
- tevColorDL.LoadBPReg(0xE5000000);
- tevColorDL.LoadBPReg(0xE5000000);
- tevColorDL.LoadBPReg(0xE5000000);
- tevColorDL.LoadBPReg(0xE6000000);
- tevColorDL.LoadBPReg(0xE7000000);
- tevColorDL.LoadBPReg(0xE7000000);
- tevColorDL.LoadBPReg(0xE7000000);
- tevColorDL.AddPadding(4);
- tevColorDL.LoadBPReg(0xE0800000);
- tevColorDL.LoadBPReg(0xE1800000);
- tevColorDL.LoadBPReg(0xE2800000);
- tevColorDL.LoadBPReg(0xE3800000);
- tevColorDL.LoadBPReg(0xE4800000);
- tevColorDL.LoadBPReg(0xE5800000);
- tevColorDL.LoadBPReg(0xE6800000);
- tevColorDL.LoadBPReg(0xE7800000);
- tevColorDL.AddPadding(24);
- tevColorDL.End();
-
- currentMaterial.TevColorDL = tevColorDL.GetBuffer();
-
- var indMtxAndScaleDL = new DisplayListWriter();
- indMtxAndScaleDL.LoadBPReg(0x25000000);
- indMtxAndScaleDL.LoadBPReg(0x26000000);
- indMtxAndScaleDL.AddPadding(54);
- indMtxAndScaleDL.End();
-
- currentMaterial.IndMtxAndScaleDL = indMtxAndScaleDL.GetBuffer();
-
- var texCoordGenDL = new DisplayListWriter();
- texCoordGenDL.LoadXFReg(0x1040, new byte[] { 0x00, 0x00, 0x52, 0x80 });
- texCoordGenDL.LoadXFReg(0x1050, new byte[] { 0x00, 0x00, 0x00, 0x00 });
- texCoordGenDL.AddPadding(110);
- texCoordGenDL.End();
-
- currentMaterial.TexCoordGenDL = texCoordGenDL.GetBuffer();
+ // Default display lists, taken from test_lift
+ var pixDL = new DisplayListWriter();
+ pixDL.LoadBPReg(0xF31EFF80);
+ pixDL.LoadBPReg(0x40000017);
+ pixDL.LoadBPReg(0xFE00FFE3);
+ pixDL.LoadBPReg(0x410034A0);
+ pixDL.LoadBPReg(0x42000000);
+ pixDL.End();
+
+ currentMaterial.PixDL = pixDL.GetBuffer();
+
+ var tevColorDL = new DisplayListWriter();
+ tevColorDL.LoadBPReg(0xE20000FF);
+ tevColorDL.LoadBPReg(0xE30FF0FF);
+ tevColorDL.LoadBPReg(0xE30FF0FF);
+ tevColorDL.LoadBPReg(0xE30FF0FF);
+ tevColorDL.LoadBPReg(0xE4000000);
+ tevColorDL.LoadBPReg(0xE5000000);
+ tevColorDL.LoadBPReg(0xE5000000);
+ tevColorDL.LoadBPReg(0xE5000000);
+ tevColorDL.LoadBPReg(0xE6000000);
+ tevColorDL.LoadBPReg(0xE7000000);
+ tevColorDL.LoadBPReg(0xE7000000);
+ tevColorDL.LoadBPReg(0xE7000000);
+ tevColorDL.AddPadding(4);
+ tevColorDL.LoadBPReg(0xE0800000);
+ tevColorDL.LoadBPReg(0xE1800000);
+ tevColorDL.LoadBPReg(0xE2800000);
+ tevColorDL.LoadBPReg(0xE3800000);
+ tevColorDL.LoadBPReg(0xE4800000);
+ tevColorDL.LoadBPReg(0xE5800000);
+ tevColorDL.LoadBPReg(0xE6800000);
+ tevColorDL.LoadBPReg(0xE7800000);
+ tevColorDL.AddPadding(24);
+ tevColorDL.End();
+
+ currentMaterial.TevColorDL = tevColorDL.GetBuffer();
+
+ var indMtxAndScaleDL = new DisplayListWriter();
+ indMtxAndScaleDL.LoadBPReg(0x25000000);
+ indMtxAndScaleDL.LoadBPReg(0x26000000);
+ indMtxAndScaleDL.AddPadding(54);
+ indMtxAndScaleDL.End();
+
+ currentMaterial.IndMtxAndScaleDL = indMtxAndScaleDL.GetBuffer();
+
+ var texCoordGenDL = new DisplayListWriter();
+ texCoordGenDL.LoadXFReg(0x1040, new byte[] { 0x00, 0x00, 0x52, 0x80 });
+ texCoordGenDL.LoadXFReg(0x1050, new byte[] { 0x00, 0x00, 0x00, 0x00 });
+ texCoordGenDL.AddPadding(110);
+ texCoordGenDL.End();
+
+ currentMaterial.TexCoordGenDL = texCoordGenDL.GetBuffer();
+
+ } else {
+ // These are taken from mtSand on CS_W1
+ currentMaterial.TexCoordGenCount = 3;
+ currentMaterial.ChanCount = 1;
+ currentMaterial.TevStageCount = 3;
+ currentMaterial.IndStageCount = 0;
+
+ currentMaterial.CullMode = 2;
+
+ currentMaterial.ZCompLoc = 1;
+ currentMaterial.LightSetID = 0xFF;
+ currentMaterial.FogID = 1;
+
+ currentMaterial.SRTSettings[0] = new SRTSettingInfo();
+ currentMaterial.SRTSettings[1] = new SRTSettingInfo();
+ currentMaterial.SRTSettings[2] = new SRTSettingInfo();
+
+ currentMaterial.SRTSettings[1].MapType = 1;
+ currentMaterial.SRTSettings[2].MapType = 1;
+
+ var pixDL = new DisplayListWriter();
+ pixDL.LoadBPReg(0xF33F0000);
+ pixDL.LoadBPReg(0x40000017);
+ pixDL.LoadBPReg(0xFE00FFE3);
+ pixDL.LoadBPReg(0x410034A0);
+ pixDL.LoadBPReg(0x42000000);
+ pixDL.End();
+
+ currentMaterial.PixDL = pixDL.GetBuffer();
+
+ var tevColorDL = new DisplayListWriter();
+ tevColorDL.LoadBPReg(0xE2000000);
+ tevColorDL.LoadBPReg(0xE3000000);
+ tevColorDL.LoadBPReg(0xE3000000);
+ tevColorDL.LoadBPReg(0xE3000000);
+ tevColorDL.LoadBPReg(0xE4000000);
+ tevColorDL.LoadBPReg(0xE5000000);
+ tevColorDL.LoadBPReg(0xE5000000);
+ tevColorDL.LoadBPReg(0xE5000000);
+ tevColorDL.LoadBPReg(0xE6000000);
+ tevColorDL.LoadBPReg(0xE7000000);
+ tevColorDL.LoadBPReg(0xE7000000);
+ tevColorDL.LoadBPReg(0xE7000000);
+ tevColorDL.AddPadding(4);
+ tevColorDL.LoadBPReg(0xE0800000);
+ tevColorDL.LoadBPReg(0xE1800000);
+ tevColorDL.LoadBPReg(0xE2800000);
+ tevColorDL.LoadBPReg(0xE3800000);
+ tevColorDL.LoadBPReg(0xE4800000);
+ tevColorDL.LoadBPReg(0xE5800000);
+ tevColorDL.LoadBPReg(0xE68FF000);
+ tevColorDL.LoadBPReg(0xE7800000);
+ tevColorDL.AddPadding(24);
+ tevColorDL.End();
+
+ currentMaterial.TevColorDL = tevColorDL.GetBuffer();
+
+ var indMtxAndScaleDL = new DisplayListWriter();
+ indMtxAndScaleDL.LoadBPReg(0x25000000);
+ indMtxAndScaleDL.LoadBPReg(0x26000000);
+ indMtxAndScaleDL.AddPadding(54);
+ indMtxAndScaleDL.End();
+
+ currentMaterial.IndMtxAndScaleDL = indMtxAndScaleDL.GetBuffer();
+
+ var texCoordGenDL = new DisplayListWriter();
+ texCoordGenDL.LoadXFReg(0x1040, new byte[] { 0x00, 0x00, 0x52, 0x80 });
+ texCoordGenDL.LoadXFReg(0x1050, new byte[] { 0x00, 0x00, 0x00, 0x00 });
+ texCoordGenDL.LoadXFReg(0x1041, new byte[] { 0x00, 0x00, 0x50, 0x86 });
+ texCoordGenDL.LoadXFReg(0x1051, new byte[] { 0x00, 0x00, 0x01, 0x03 });
+ texCoordGenDL.LoadXFReg(0x1042, new byte[] { 0x00, 0x00, 0x50, 0x86 });
+ texCoordGenDL.LoadXFReg(0x1052, new byte[] { 0x00, 0x00, 0x01, 0x06 });
+ texCoordGenDL.PadToSize(0xA0);
+ texCoordGenDL.End();
+
+ currentMaterial.TexCoordGenDL = texCoordGenDL.GetBuffer();
+ }
CurrentModel.Materials.Add(parsed[1], currentMaterial);
@@ -348,6 +427,26 @@ namespace NW4RTools {
texInfo.MagFilt = 1;
currentMaterial.TextureInfos.Add(texInfo);
+
+ // Now add the lm_01m and lm_02m
+ var lm01m = new TextureInfo();
+ lm01m.TextureName = "lm_01m";
+ lm01m.TexMapID = 1;
+ lm01m.TlutID = 1;
+
+ lm01m.MinFilt = 1;
+ lm01m.MagFilt = 1;
+
+ var lm02m = new TextureInfo();
+ lm02m.TextureName = "lm_02m";
+ lm02m.TexMapID = 2;
+ lm02m.TlutID = 2;
+
+ lm02m.MinFilt = 1;
+ lm02m.MagFilt = 1;
+
+ currentMaterial.TextureInfos.Add(lm01m);
+ currentMaterial.TextureInfos.Add(lm02m);
break;
@@ -373,12 +472,8 @@ namespace NW4RTools {
private Shader CreateShader() {
var shader = new Shader();
-
- shader.TevStageCount = 2;
- shader.Unk1 = 0x00FFFFFF;
- shader.Unk2 = 0xFFFFFFFF;
-
var dl = new DisplayListWriter();
+
dl.LoadBPReg(0xFE00000F);
dl.LoadBPReg(0xF6000004);
dl.LoadBPReg(0xFE00000F);
@@ -397,15 +492,47 @@ namespace NW4RTools {
dl.LoadBPReg(0xFD00000E);
dl.LoadBPReg(0x27FFFFFF);
dl.AddPadding(11);
- dl.LoadBPReg(0xFEFFFFF0);
- dl.LoadBPReg(0xF6E338C0);
- dl.LoadBPReg(0x2803F040);
- dl.LoadBPReg(0xC008F8AF);
- dl.LoadBPReg(0xC208F20F);
- dl.LoadBPReg(0xC108F2F0);
- dl.LoadBPReg(0xC3081FF0);
- dl.LoadBPReg(0x10000000);
- dl.LoadBPReg(0x11000000);
+
+ if (!Lightmaps) {
+ shader.TevStageCount = 2;
+ shader.Unk1 = 0x00FFFFFF;
+ shader.Unk2 = 0xFFFFFFFF;
+
+ dl.LoadBPReg(0xFEFFFFF0);
+ dl.LoadBPReg(0xF6E338C0);
+ dl.LoadBPReg(0x2803F040);
+ dl.LoadBPReg(0xC008F8AF);
+ dl.LoadBPReg(0xC208F20F);
+ dl.LoadBPReg(0xC108F2F0);
+ dl.LoadBPReg(0xC3081FF0);
+ dl.LoadBPReg(0x10000000);
+ dl.LoadBPReg(0x11000000);
+
+ } else {
+ shader.TevStageCount = 3;
+ shader.Unk1 = 0x000102FF;
+ shader.Unk2 = 0xFFFFFFFF;
+
+ dl.LoadBPReg(0xFEFFFFF0);
+ dl.LoadBPReg(0xF6E338C0);
+ dl.LoadBPReg(0x283C0049);
+ dl.LoadBPReg(0xC008F8AF);
+ dl.LoadBPReg(0xC208F80F);
+ dl.LoadBPReg(0xC108FFD0);
+ dl.LoadBPReg(0xC308E270);
+ dl.LoadBPReg(0x10000000);
+ dl.LoadBPReg(0x11000000);
+ dl.AddPadding(3);
+ dl.LoadBPReg(0xFEFFFFF0);
+ dl.LoadBPReg(0xF7003EF0);
+ dl.LoadBPReg(0x293BF052);
+ dl.LoadBPReg(0xC4080A8E);
+ dl.AddPadding(5);
+ dl.LoadBPReg(0xC508E370);
+ dl.AddPadding(5);
+ dl.LoadBPReg(0x12000000);
+ }
+
dl.PadToSize(0x1E0);
dl.End();
diff --git a/NW4RTools/ObjWriter.cs b/NW4RTools/ObjWriter.cs
deleted file mode 100644
index 592347b..0000000
--- a/NW4RTools/ObjWriter.cs
+++ /dev/null
@@ -1,187 +0,0 @@
-using System;
-using System.IO;
-using System.Collections.Generic;
-using NW4RTools.Models;
-
-namespace NW4RTools {
- public class ObjWriter {
- public static void WriteModel(TextWriter tw, ResFile file, string modelName) {
- new ObjWriter(file).SaveModel(tw, modelName);
- }
-
-
-
- ResFile CurrentFile;
- Models.Model CurrentModel;
- TextWriter Output;
-
- private ObjWriter(ResFile file) {
- CurrentFile = file;
- }
-
- Dictionary<Models.VertexPosData, int> VtxPosOffsets;
- Dictionary<Models.VertexNrmData, int> VtxNrmOffsets;
- Dictionary<Models.VertexTexCoordData, int> VtxTexCoordOffsets;
-
- public void SaveModel(TextWriter tw, string modelName) {
- Output = tw;
- CurrentModel = CurrentFile.GetGroup<Model>("3DModels(NW4R)")[modelName];
-
- Output.WriteLine("# {0} exported by Treeki's NW4RTools", modelName);
- Output.WriteLine("# {0}", DateTime.Now);
- Output.WriteLine();
-
- // Write vertex data pool
- int Offset;
-
- VtxPosOffsets = new Dictionary<VertexPosData, int>();
- Offset = 1;
- foreach (var kv in CurrentModel.VtxPosData) {
- VtxPosOffsets[kv.Value] = Offset;
- Output.WriteLine("# Vertex Positions: {0} [offset {1}]", kv.Key, Offset);
-
- for (int i = 0; i < kv.Value.EntryCount; i++) {
- float[] v = kv.Value.GetEntry(i);
- Output.WriteLine("v {0} {1} {2}", v[0], v[1], v[2]);
- }
-
- Offset += kv.Value.EntryCount;
- }
-
- VtxNrmOffsets = new Dictionary<VertexNrmData, int>();
- Offset = 1;
- foreach (var kv in CurrentModel.VtxNrmData) {
- VtxNrmOffsets[kv.Value] = Offset;
- Output.WriteLine("# Vertex Normals: {0} [offset {1}]", kv.Key, Offset);
-
- for (int i = 0; i < kv.Value.EntryCount; i++) {
- float[] v = kv.Value.GetEntry(i);
- Output.WriteLine("vn {0} {1} {2}", v[0], v[1], v[2]);
- }
-
- Offset += kv.Value.EntryCount;
- }
-
- VtxTexCoordOffsets = new Dictionary<VertexTexCoordData, int>();
- Offset = 1;
- foreach (var kv in CurrentModel.VtxTexCoordData) {
- VtxTexCoordOffsets[kv.Value] = Offset;
- Output.WriteLine("# Vertex TexCoords: {0} [offset {1}]", kv.Key, Offset);
-
- for (int i = 0; i < kv.Value.EntryCount; i++) {
- float[] v = kv.Value.GetEntry(i);
- Output.WriteLine("vt {0} {1}", v[0], v[1]);
- }
-
- Offset += kv.Value.EntryCount;
- }
-
- Output.WriteLine();
-
- // Write shapes
- // TODO: replace with something using the Bytecode
- foreach (var kv in CurrentModel.Shapes) {
- Output.WriteLine("g {0}", kv.Key);
-
- WriteShape(kv.Value);
-
- Output.WriteLine();
- }
-
- Output.Flush();
- }
-
-
- private void WriteShape(Models.Shape shape) {
- // first, parse the first DisplayList to get the attr info
- // for now we'll hardcode the offsets. must be fixed later
-
- var firstDL = new InputStream(shape.DisplayList1);
- firstDL.Seek(0x0C);
- UInt32 vtxDesc1 = firstDL.ReadUInt32();
- firstDL.Seek(0x12);
- UInt32 vtxDesc2 = firstDL.ReadUInt32();
- firstDL.Seek(0x22);
- UInt32 vtxAttr1 = firstDL.ReadUInt32();
- firstDL.Seek(0x28);
- UInt32 vtxAttr2 = firstDL.ReadUInt32();
- firstDL.Seek(0x2E);
- UInt32 vtxAttr3 = firstDL.ReadUInt32();
-
- var vs = new VertexSettings();
- vs.SetDesc(vtxDesc1, vtxDesc2);
- vs.SetAttrFmt(vtxAttr1, vtxAttr2, vtxAttr3);
-
- // get the Matrix to use
- // todo: how to apply this?!
- Matrix m = CurrentModel.Nodes[CurrentModel.MatrixIDtoNodeID[shape.MatrixID]].NodeMatrix;
-
- // now parse the second DisplayList
-
- int posOffset = VtxPosOffsets[shape.PosData];
- int nrmOffset = shape.NrmData == null ? -1 : VtxNrmOffsets[shape.NrmData];
- int tcOffset = shape.TexCoordData[0] == null ? -1 : VtxTexCoordOffsets[shape.TexCoordData[0]];
- // TODO: Better DisplayList parsing, in a similar fashion to ByteCode
- var dl = new InputStream(shape.DisplayList2);
-
- while (true) {
- if (dl.AtEnd)
- break;
-
- byte cmd = dl.ReadByte();
- if (cmd == 0)
- break;
-
- PrimitiveType prim = (PrimitiveType)((cmd >> 3) & 7);
- int vtxCount = dl.ReadUInt16();
- Output.WriteLine("# Primitive: {0} ({1} vertices)", prim, vtxCount);
-
- // first, parse it into a list of vertices
- GXIndexedVertex[] vtxs = new GXIndexedVertex[vtxCount];
- string[] pVtxs = new string[vtxCount];
-
- for (int i = 0; i < vtxCount; i++) {
- vtxs[i].LoadFrom(dl, vs);
-
- string tc = (vtxs[i].TexCoords[0] == -1) ? "" : (tcOffset + vtxs[i].TexCoords[0]).ToString();
- string n = (vtxs[i].Normal == -1) ? "" : (nrmOffset + vtxs[i].Normal).ToString();
- pVtxs[i] = String.Format(" {0}/{1}/{2}", posOffset + vtxs[i].Position, tc, n);
- }
-
- switch (prim) {
- case PrimitiveType.Triangles:
- for (int i = 0; i < vtxCount; i += 3) {
- Output.WriteLine("f {0} {1} {2}", pVtxs[i], pVtxs[i + 1], pVtxs[i + 2]);
- }
-
- break;
-
- case PrimitiveType.TriangleStrip:
- // De-stripify it!
- for (int i = 2; i < vtxCount; i++) {
- Output.Write("f");
- if ((i & 1) == 0) {
- // Even number
- Output.Write(pVtxs[i - 2]);
- Output.Write(pVtxs[i - 1]);
- Output.Write(pVtxs[i]);
- } else {
- // Odd number
- Output.Write(pVtxs[i - 1]);
- Output.Write(pVtxs[i - 2]);
- Output.Write(pVtxs[i]);
- }
- Output.WriteLine();
- }
-
- break;
-
- default:
- Output.WriteLine("# UNIMPLEMENTED");
- return;
- }
- }
- }
- }
-}
-
diff --git a/NW4RTools/bin/Debug/NW4RTools.dll b/NW4RTools/bin/Debug/NW4RTools.dll
index 497cebb..d8f19a2 100755
--- a/NW4RTools/bin/Debug/NW4RTools.dll
+++ b/NW4RTools/bin/Debug/NW4RTools.dll
Binary files differ
diff --git a/NW4RTools/bin/Debug/NW4RTools.dll.mdb b/NW4RTools/bin/Debug/NW4RTools.dll.mdb
index e36c23e..330c38e 100644
--- a/NW4RTools/bin/Debug/NW4RTools.dll.mdb
+++ b/NW4RTools/bin/Debug/NW4RTools.dll.mdb
Binary files differ
diff --git a/TestApp/Main.cs b/TestApp/Main.cs
index fbaa7dc..3d7f063 100644
--- a/TestApp/Main.cs
+++ b/TestApp/Main.cs
@@ -28,12 +28,12 @@ namespace TestApp {
File.WriteAllBytes(mdlPath + filename + ".brres", BrresWriter.WriteFile(rf));
- ResFile rf2 = BrresReader.LoadFile(File.ReadAllBytes(mdlPath + filename + ".brres"));
+ /*ResFile rf2 = BrresReader.LoadFile(File.ReadAllBytes(mdlPath + filename + ".brres"));
using (var gw = new RenderWindow()) {
gw.Title = filename;
gw.SetModel(rf2, resmdlname);
gw.Run(1, 1);
- }
+ }*/
@@ -73,7 +73,7 @@ namespace TestApp {
private static void oldBehaviour() {
string mdlPath = "/home/me/Games/Newer/ModelRev/";
- string mdlName = "CS_W1";
+ string mdlName = "lift_han_wood";
//string mdlName = "bgB_4502";
//string mdlName = "cobKoopaCastle";
//string mdlName = "waterPlate_W4boss";
@@ -84,14 +84,23 @@ namespace TestApp {
byte[] file = File.ReadAllBytes(mdlPath + mdlName + ".brres");
ResFile rf = BrresReader.LoadFile(file);
- using (var gw = new RenderWindow()) {
+ /*using (var gw = new RenderWindow()) {
gw.Title = mdlName;
gw.SetModel(rf, mdlName);
gw.Run(1, 1);
- }
+ }*/
//File.WriteAllBytes(mdlPath + mdlName + "_rewritten.brres", BrresWriter.WriteFile(rf));
+ var texs = rf.GetGroup<Texture>("Textures(NW4R)");
+ // wtf C#?!
+ foreach (var kv in (IEnumerable<KeyValuePair<string,Texture>>)texs) {
+ kv.Value.Images[0].Save(mdlPath + "images/" + kv.Key + ".png");
+ }
+
+ var objFile = File.Open(mdlPath + "lift_han_wood_M.dae", FileMode.OpenOrCreate);
+ ColladaExporter.WriteModel(objFile, rf, "lift_han_wood_M");
+ objFile.Close();
}
}
}
diff --git a/TestApp/RenderWindow.cs b/TestApp/RenderWindow.cs
index 6013724..f314146 100644
--- a/TestApp/RenderWindow.cs
+++ b/TestApp/RenderWindow.cs
@@ -61,8 +61,8 @@ namespace TestApp {
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
- Matrix4 modelview = Matrix4.LookAt(new Vector3(1000, 400, 1000), new Vector3(1000, 0, 0), Vector3.UnitY);
- //Matrix4 modelview = Matrix4.LookAt(new Vector3(-3, 2, 3), new Vector3(0, 0, 0), Vector3.UnitY);
+ //Matrix4 modelview = Matrix4.LookAt(new Vector3(1000, 400, 1000), new Vector3(1000, 0, 0), Vector3.UnitY);
+ Matrix4 modelview = Matrix4.LookAt(new Vector3(-50, 20, 50), new Vector3(0, 0, 0), Vector3.UnitY);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadMatrix(ref modelview);
diff --git a/TestApp/TestApp.pidb b/TestApp/TestApp.pidb
index e8df7af..9242abe 100644
--- a/TestApp/TestApp.pidb
+++ b/TestApp/TestApp.pidb
Binary files differ
diff --git a/TestApp/bin/Debug/NW4RTools.dll b/TestApp/bin/Debug/NW4RTools.dll
index 40356de..d8f19a2 100755
--- a/TestApp/bin/Debug/NW4RTools.dll
+++ b/TestApp/bin/Debug/NW4RTools.dll
Binary files differ
diff --git a/TestApp/bin/Debug/NW4RTools.dll.mdb b/TestApp/bin/Debug/NW4RTools.dll.mdb
index 92742d0..330c38e 100644
--- a/TestApp/bin/Debug/NW4RTools.dll.mdb
+++ b/TestApp/bin/Debug/NW4RTools.dll.mdb
Binary files differ
diff --git a/TestApp/bin/Debug/TestApp.exe b/TestApp/bin/Debug/TestApp.exe
index 5b808e0..75cf443 100755
--- a/TestApp/bin/Debug/TestApp.exe
+++ b/TestApp/bin/Debug/TestApp.exe
Binary files differ
diff --git a/TestApp/bin/Debug/TestApp.exe.mdb b/TestApp/bin/Debug/TestApp.exe.mdb
index 8ec2779..f6489a1 100644
--- a/TestApp/bin/Debug/TestApp.exe.mdb
+++ b/TestApp/bin/Debug/TestApp.exe.mdb
Binary files differ