diff options
author | Treeki <treeki@gmail.com> | 2011-03-10 03:00:09 +0100 |
---|---|---|
committer | Treeki <treeki@gmail.com> | 2011-03-10 03:00:09 +0100 |
commit | 5926616de2bd346f1a1c69c93ff2aaa3c453a2b3 (patch) | |
tree | f282b05ae5616a05fb4db167fad20ec242775c27 /NW4RTools/ColladaWriter.cs | |
parent | 7d391e33a0b3d9793c95fce832abb2c6d9002186 (diff) | |
download | nw4rtools-5926616de2bd346f1a1c69c93ff2aaa3c453a2b3.tar.gz nw4rtools-5926616de2bd346f1a1c69c93ff2aaa3c453a2b3.zip |
kinda hackish, but mostly working NSMBW lightmap support
Diffstat (limited to 'NW4RTools/ColladaWriter.cs')
-rw-r--r-- | NW4RTools/ColladaWriter.cs | 732 |
1 files changed, 0 insertions, 732 deletions
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; - } - } -} - |