public MTL ToMTL(int Model) { if (Data.Models.Length == 0 || Data.Models.Length <= Model) { return(null); } var o = new MTL(); var m = Data.Models[Model]; //foreach (CMDL m in Models) { foreach (var vv in m.Materials) { MTL.MTLMaterial mm = new MTL.MTLMaterial(vv.Name); mm.DiffuseColor = vv.MaterialColor.DiffuseU32; mm.AmbientColor = vv.MaterialColor.AmbientU32; mm.Alpha = vv.MaterialColor.Diffuse.W; mm.SpecularColor = vv.MaterialColor.Specular0U32; if (vv.Tex0 != null && vv.Tex0.TextureObject is ReferenceTexture /* && vv.TextureCoordiators[0].SourceCoordinate == 0*/) { mm.DiffuseMapPath = "Tex/" + ((ReferenceTexture)vv.Tex0.TextureObject).LinkedTextureName + ".png"; } //else if (vv.Tex1 != null && vv.Tex1.TextureObject is ReferenceTexture && vv.TextureCoordiators[1].SourceCoordinate == 0) mm.DiffuseMapPath = "Tex/" + ((ReferenceTexture)vv.Tex1.TextureObject).LinkedTextureName + ".png"; //else if (vv.Tex2 != null && vv.Tex2.TextureObject is ReferenceTexture && vv.TextureCoordiators[2].SourceCoordinate == 0) mm.DiffuseMapPath = "Tex/" + ((ReferenceTexture)vv.Tex2.TextureObject).LinkedTextureName + ".png"; o.Materials.Add(mm); } } return(o); }
public static void N3DS_NW4C_GFX_ToOBJ(String BCMDLPath, int ModelIdx, String OBJPath) { CGFX c = new CGFX(File.ReadAllBytes(BCMDLPath)); if (c.Data.Models == null || c.Data.Models.Length <= ModelIdx) { throw new Exception("Model does not exist in the specified CGFX file!"); } CMDL Model = c.Data.Models[ModelIdx]; OBJ o = Model.ToOBJ(); o.MTLPath = Path.GetFileNameWithoutExtension(OBJPath) + ".mtl"; MTL m = Model.ToMTL(Path.GetFileNameWithoutExtension(OBJPath) + "_Tex"); byte[] d = o.Write(); byte[] d2 = m.Write(); File.Create(OBJPath).Close(); File.WriteAllBytes(OBJPath, d); File.Create(Path.ChangeExtension(OBJPath, "mtl")).Close(); File.WriteAllBytes(Path.ChangeExtension(OBJPath, "mtl"), d2); Directory.CreateDirectory(Path.GetDirectoryName(OBJPath) + "\\" + Path.GetFileNameWithoutExtension(OBJPath) + "_Tex"); foreach (var v in c.Data.Textures) { if (!(v is ImageTextureCtr)) { continue; } ((ImageTextureCtr)v).GetBitmap().Save(Path.GetDirectoryName(OBJPath) + "\\" + Path.GetFileNameWithoutExtension(OBJPath) + "_Tex\\" + v.Name + ".png"); } }
public OBJ ToOBJ(out MTL mtl) { OBJ o = new OBJ(); int v = 0; HashSet <String> matnames = new HashSet <string>(); foreach (var vv in Planes) { Triangle t = GetTriangle(vv); o.Vertices.Add(t.PointA); o.Vertices.Add(t.PointB); o.Vertices.Add(t.PointC); var f = new OBJ.OBJFace(); f.Material = "mat_" + vv.CollisionType.ToString("X") + "_ID"; matnames.Add(f.Material); f.VertexIndieces.Add(v); f.VertexIndieces.Add(v + 1); f.VertexIndieces.Add(v + 2); o.Faces.Add(f); v += 3; } mtl = new MTL(); Random r = new Random(); foreach (string s in matnames) { MTL.MTLMaterial m = new MTL.MTLMaterial(s); m.AmbientColor = Color.Black; m.SpecularColor = Color.FromArgb(85, 85, 85); m.DiffuseColor = Color.FromArgb(r.Next(0, 255), r.Next(0, 255), r.Next(0, 255)); mtl.Materials.Add(m); } o.optimizeVertexCount(); return(o); }
public OBJWrapper(string path) { base_path = Path.GetDirectoryName(path); try { bool has_mtl = true; obj_data = new OBJ(File.ReadAllBytes(path)); if (obj_data.MTLPath.Length > 0) { try { obj_data.MTLPath.Replace("/", "\\"); mtl_data = new MTL(File.ReadAllBytes(base_path + "\\" + obj_data.MTLPath)); } catch { mtl_data = null; has_mtl = false; } } InitializeMaterials(has_mtl); } catch (Exception e) { MessageBox.Show("OBJ Wrapper Exception: \n\r" + e.ToString()); } }
public override Asset Import(string path) { Material material; string name = Path.GetFileNameWithoutExtension(path); MTL mat = MTL.Load(path); string fileName = mat.Textures[0]; if (fileName == null || fileName == "") { material = new Material { Name = name, Texture = new Texture() { Name = fileName } }; } else { material = new Material { Name = name, Texture = SceneManager.Current.Content.Load <Texture, TDXImporter>(fileName, Path.GetDirectoryName(path)) }; } material.SupportingDocuments["Source"] = mat; return(material); }
public bool Convert(int FilterIndex, String Path) { switch (FilterIndex) { case 0: { DAE o = ToDAE(0); File.Create(Path).Close(); File.WriteAllBytes(Path, o.Write()); Directory.CreateDirectory(System.IO.Path.GetDirectoryName(Path) + "\\Tex"); foreach (var v in Data.Textures) { if (!(v is ImageTextureCtr)) { continue; } ((ImageTextureCtr)v).GetBitmap().Save(System.IO.Path.GetDirectoryName(Path) + "\\Tex\\" + v.Name + ".png"); } return(true); } case 1: { if (Data.Models.Length == 0) { return(false); } OBJ o = ToOBJ(0); o.MTLPath = System.IO.Path.GetFileNameWithoutExtension(Path) + ".mtl"; MTL m = ToMTL(0); byte[] d = o.Write(); byte[] d2 = m.Write(); File.Create(Path).Close(); File.WriteAllBytes(Path, d); File.Create(System.IO.Path.ChangeExtension(Path, "mtl")).Close(); File.WriteAllBytes(System.IO.Path.ChangeExtension(Path, "mtl"), d2); Directory.CreateDirectory(System.IO.Path.GetDirectoryName(Path) + "\\Tex"); foreach (var v in Data.Textures) { //if (v.NrLevels > 2) v.GetBitmap(2).Save(System.IO.Path.GetDirectoryName(Path) + "\\Tex\\" + v.Name + ".png"); //else if (v.NrLevels > 1) v.GetBitmap(1).Save(System.IO.Path.GetDirectoryName(Path) + "\\Tex\\" + v.Name + ".png"); //else v.GetBitmap(0).Save(System.IO.Path.GetDirectoryName(Path) + "\\Tex\\" + v.Name + ".png"); if (!(v is ImageTextureCtr)) { continue; } ((ImageTextureCtr)v).GetBitmap().Save(System.IO.Path.GetDirectoryName(Path) + "\\Tex\\" + v.Name + ".png"); } return(true); } default: return(false); } }
private void toolStripButton1_Click(object sender, EventArgs e) { saveFileDialog1.FileName = Model.Name; if (saveFileDialog1.ShowDialog() == DialogResult.OK && saveFileDialog1.FileName.Length > 0) { switch (saveFileDialog1.FilterIndex - 1) { case 0: { DAE o = Model.ToDAE(Resource); File.Create(saveFileDialog1.FileName).Close(); File.WriteAllBytes(saveFileDialog1.FileName, o.Write()); Directory.CreateDirectory(Path.GetDirectoryName(saveFileDialog1.FileName) + "\\Tex"); foreach (var v in Resource.Data.Textures) { if (!(v is ImageTextureCtr)) { continue; } ((ImageTextureCtr)v).GetBitmap().Save(Path.GetDirectoryName(saveFileDialog1.FileName) + "\\Tex\\" + v.Name + ".png"); } break; } case 1: { OBJ o = Model.ToOBJ(); o.MTLPath = Path.GetFileNameWithoutExtension(saveFileDialog1.FileName) + ".mtl"; MTL m = Model.ToMTL("Tex"); byte[] d = o.Write(); byte[] d2 = m.Write(); File.Create(saveFileDialog1.FileName).Close(); File.WriteAllBytes(saveFileDialog1.FileName, d); File.Create(Path.ChangeExtension(saveFileDialog1.FileName, "mtl")).Close(); File.WriteAllBytes(Path.ChangeExtension(saveFileDialog1.FileName, "mtl"), d2); Directory.CreateDirectory(Path.GetDirectoryName(saveFileDialog1.FileName) + "\\Tex"); foreach (var v in Resource.Data.Textures) { //if (v.NrLevels > 2) v.GetBitmap(2).Save(System.IO.Path.GetDirectoryName(Path) + "\\Tex\\" + v.Name + ".png"); //else if (v.NrLevels > 1) v.GetBitmap(1).Save(System.IO.Path.GetDirectoryName(Path) + "\\Tex\\" + v.Name + ".png"); //else v.GetBitmap(0).Save(System.IO.Path.GetDirectoryName(Path) + "\\Tex\\" + v.Name + ".png"); if (!(v is ImageTextureCtr)) { continue; } ((ImageTextureCtr)v).GetBitmap().Save(Path.GetDirectoryName(saveFileDialog1.FileName) + "\\Tex\\" + v.Name + ".png"); } break; } } } }
public MTL ToMTL() { MTL m = new MTL(); foreach (var v in Materials) { MTL.MTLMaterial mm = new MTL.MTLMaterial("M" + v.Key + "M"); mm.DiffuseColor = Color.White; mm.DiffuseMapPath = "Tex/" + v.Key + ".png"; m.Materials.Add(mm); } return(m); }
public override Asset Import(string path) { Material material; string name = Path.GetFileNameWithoutExtension(path); ToxicRagers.Generics.Material m = null; switch (Path.GetExtension(path).ToLower()) { case ".mt2": m = MT2.Load(path); break; case ".mtl": m = MTL.Load(path); break; } if (m != null) { var mat = (m as MT2); string fileName = (mat != null ? mat.Texture : (m as MTL).Textures[0]); if (fileName == null || fileName == "") { material = new Material { Name = name, Texture = new Texture() { Name = fileName } }; } else { material = new Material { Name = name, Texture = SceneManager.Current.Content.Load <Texture, TDXImporter>(fileName, Path.GetDirectoryName(path)) }; } material.SupportingDocuments["Source"] = m; } else { material = new Material(); } return(material); }
public bool Convert(int FilterIndex, string Path) { switch (FilterIndex) { case 0: MTL mtl = null; OBJ o = ToOBJ(out mtl); string mtlPath = Path.Replace(".obj", ".mtl"); o.MTLPath = System.IO.Path.GetFileName(mtlPath); byte[] d = o.Write(); byte[] m = mtl.Write(); File.Create(Path).Close(); File.Create(mtlPath).Close(); File.WriteAllBytes(Path, d); File.WriteAllBytes(mtlPath, m); return(true); default: return(false); } }
void ConvertEFE(byte[] Data, string Name) { _3DS.NintendoWare.GFX.CGFX mod = new _3DS.NintendoWare.GFX.CGFX(Data); CommonFiles.OBJ o = mod.Data.Models[0].ToOBJ(); o.MTLPath = Path.GetFileNameWithoutExtension(Name) + ".mtl"; MTL m = mod.Data.Models[0].ToMTL("Tex"); byte[] d = o.Write(); byte[] d2 = m.Write(); File.Create(Name).Close(); File.WriteAllBytes(Name, d); File.Create(Path.ChangeExtension(Name, "mtl")).Close(); File.WriteAllBytes(Path.ChangeExtension(Name, "mtl"), d2); Directory.CreateDirectory(Path.GetDirectoryName(Name) + "\\Tex"); foreach (var v in mod.Data.Textures) { if (!(v is ImageTextureCtr)) { continue; } ((ImageTextureCtr)v).GetBitmap().Save(Path.GetDirectoryName(Name) + "\\Tex\\" + v.Name + ".png"); } }
private void FrmObjImport_Load(object sender, EventArgs e) { OpenFileDialog opn = new OpenFileDialog(); opn.Title = "Open a model file"; opn.Filter = "Supported formats (.bcmdl, .obj)|*.bcmdl; *.obj"; bool ok = true; if (opn.ShowDialog() != DialogResult.OK) { ok = false; } if (Path.GetExtension(opn.FileName).ToLower() == ".obj") { if (MessageBox.Show("The obj will be converted to bcmdl with Every File Explorer's method, this is known to have problems, especially with models made in sketchup.\r\nDo you want to continue ?", "Warning", MessageBoxButtons.YesNo) == DialogResult.Yes) { modelPath = opn.FileName; ObjModelPath = modelPath; IsObj = true; render.addModel(modelPath, "Model", new System.Windows.Media.Media3D.Vector3D(0, 0, 0), new System.Windows.Media.Media3D.Vector3D(1, 1, 1), 0, 0, 0); } else { MessageBox.Show("You can convert the model to bcmdl with the leaked tools"); this.Close(); } } else if (Path.GetExtension(opn.FileName).ToLower() == ".bcmdl") { tmpPath = Path.GetTempPath() + "TmpT4D"; string Name = tmpPath + "\\model.obj"; Directory.CreateDirectory(tmpPath); CGFX mod = null; mod = new _3DS.NintendoWare.GFX.CGFX(File.ReadAllBytes(opn.FileName)); CommonFiles.OBJ o = mod.Data.Models[0].ToOBJ(); o.MTLPath = Path.GetFileNameWithoutExtension(Name) + ".mtl"; MTL m = mod.Data.Models[0].ToMTL("Tex"); byte[] d = o.Write(); byte[] d2 = m.Write(); File.Create(Name).Close(); File.WriteAllBytes(Name, d); File.Create(Path.ChangeExtension(Name, "mtl")).Close(); File.WriteAllBytes(Path.ChangeExtension(Name, "mtl"), d2); Directory.CreateDirectory(tmpPath + "\\Tex"); foreach (var v in mod.Data.Textures) { if (!(v is ImageTextureCtr)) { continue; } ((ImageTextureCtr)v).GetBitmap().Save(tmpPath + "\\Tex\\" + v.Name + ".png"); } modelPath = opn.FileName; ObjModelPath = Name; IsObj = false; render.addModel(Name, "Model", new System.Windows.Media.Media3D.Vector3D(0, 0, 0), new System.Windows.Media.Media3D.Vector3D(1, 1, 1), 0, 0, 0); textBox1.Text = mod.Data.Models[0].Name; textBox1.Enabled = false; render.SetSortFrequency(0); } else { if (ok) { MessageBox.Show("File not supported"); } else { MessageBox.Show("You must select your model file to use this function"); } this.Close(); } }
public static void FromOBJ(CGFX c, String OBJPath, String ModelName = "EFEModel") { OBJ Model = new OBJ(File.ReadAllBytes(OBJPath)); if (Model.MTLPath == null) { throw new Exception("Model without materials not supported!"); } String MtlPath = Path.GetDirectoryName(OBJPath) + "\\" + Model.MTLPath; MTL MatLib = new MTL(File.ReadAllBytes(MtlPath)); List <String> MatNames = new List <string>(); foreach (var f in Model.Faces) { if (!MatNames.Contains(f.Material)) { MatNames.Add(f.Material); } } Bitmap[] Textures = new Bitmap[MatLib.Materials.Count]; int q = 0; int NrTextures = 0; foreach (var v in MatLib.Materials) { if (!MatNames.Contains(v.Name)) { q++; continue; } if (v.DiffuseMapPath != null) { Textures[q] = new Bitmap(new MemoryStream(File.ReadAllBytes(Path.GetDirectoryName(MtlPath) + "\\" + v.DiffuseMapPath))); NrTextures++; } q++; } c.Data.Dictionaries[0] = new DICT(); c.Data.Dictionaries[0].Add(ModelName); c.Data.Models = new CMDL[1]; c.Data.Models[0] = new CMDL(ModelName); CMDL cmdl = c.Data.Models[0]; //Mesh Node Visibility { cmdl.NrMeshNodes = 1; cmdl.MeshNodeVisibilitiesDict = new DICT(); cmdl.MeshNodeVisibilitiesDict.Add("CompleteModel"); cmdl.MeshNodeVisibilities = new CMDL.MeshNodeVisibilityCtr[] { new CMDL.MeshNodeVisibilityCtr("CompleteModel") }; } //Meshes { cmdl.NrMeshes = (uint)MatNames.Count; cmdl.Meshes = new CMDL.Mesh[MatNames.Count]; for (int i = 0; i < MatNames.Count; i++) { cmdl.Meshes[i] = new CMDL.Mesh(); cmdl.Meshes[i].MeshNodeName = "CompleteModel"; cmdl.Meshes[i].MaterialIndex = (uint)i; cmdl.Meshes[i].ShapeIndex = (uint)i; } } //Materials { cmdl.NrMaterials = (uint)MatNames.Count; cmdl.MaterialsDict = new DICT(); cmdl.Materials = new CMDL.MTOB[MatNames.Count]; for (int i = 0; i < MatNames.Count; i++) { cmdl.MaterialsDict.Add(MatNames[i]); cmdl.Materials[i] = new CMDL.MTOB(MatNames[i]); cmdl.Materials[i].FragShader.TextureCombiners[0].SrcRgb = 0xEE0; cmdl.Materials[i].FragShader.TextureCombiners[0].SrcAlpha = 0xEE0; for (int qq = 1; qq < 6; qq++) { cmdl.Materials[i].FragShader.TextureCombiners[qq].SrcRgb = 0xEEF; cmdl.Materials[i].FragShader.TextureCombiners[qq].SrcAlpha = 0xEEF; } Bitmap tex = Textures[MatLib.Materials.IndexOf(MatLib.GetMaterialByName(MatNames[i]))]; if (tex != null) { cmdl.Materials[i].NrActiveTextureCoordiators = 1; cmdl.Materials[i].TextureCoordiators[0].Scale = new LibEveryFileExplorer.Collections.Vector2(1, 1); cmdl.Materials[i].Tex0 = new CMDL.MTOB.TexInfo(MatNames[i]); cmdl.Materials[i].FragShader.TextureCombiners[0].SrcRgb = 0xE30; cmdl.Materials[i].FragShader.TextureCombiners[0].SrcAlpha = 0xE30; cmdl.Materials[i].FragShader.TextureCombiners[0].CombineRgb = 1; cmdl.Materials[i].FragShader.TextureCombiners[0].CombineAlpha = 1; } } } //Shapes { cmdl.NrShapes = (uint)MatNames.Count; cmdl.Shapes = new CMDL.SeparateDataShape[MatNames.Count]; for (int i = 0; i < MatNames.Count; i++) { cmdl.Shapes[i] = new CMDL.SeparateDataShape(); Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue); int nrfaces = 0; bool texcoords = false; foreach (var f in Model.Faces) { if (f.Material != MatNames[i]) { continue; } nrfaces++; if (f.TexCoordIndieces.Count > 0) { texcoords = true; } foreach (var qqq in f.VertexIndieces) { if (Model.Vertices[qqq].X < min.X) { min.X = Model.Vertices[qqq].X; } if (Model.Vertices[qqq].Y < min.Y) { min.Y = Model.Vertices[qqq].Y; } if (Model.Vertices[qqq].Z < min.Z) { min.Z = Model.Vertices[qqq].Z; } if (Model.Vertices[qqq].X > max.X) { max.X = Model.Vertices[qqq].X; } if (Model.Vertices[qqq].Y > max.Y) { max.Y = Model.Vertices[qqq].Y; } if (Model.Vertices[qqq].Z > max.Z) { max.Z = Model.Vertices[qqq].Z; } } } ((OrientedBoundingBox)cmdl.Shapes[i].BoundingBox).CenterPosition = (min + max) / 2; ((OrientedBoundingBox)cmdl.Shapes[i].BoundingBox).Size = max - min; cmdl.Shapes[i].NrPrimitiveSets = 1; cmdl.Shapes[i].PrimitiveSets = new CMDL.SeparateDataShape.PrimitiveSet[1]; cmdl.Shapes[i].PrimitiveSets[0] = new CMDL.SeparateDataShape.PrimitiveSet(); cmdl.Shapes[i].PrimitiveSets[0].NrPrimitives = 1; cmdl.Shapes[i].PrimitiveSets[0].Primitives = new CMDL.SeparateDataShape.PrimitiveSet.Primitive[1]; cmdl.Shapes[i].PrimitiveSets[0].Primitives[0] = new CMDL.SeparateDataShape.PrimitiveSet.Primitive(); cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].NrBufferObjects = 1; cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].BufferObjects = new uint[] { 0 }; cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].NrIndexStreams = 1; cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams = new CMDL.SeparateDataShape.PrimitiveSet.Primitive.IndexStreamCtr[1]; cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0] = new CMDL.SeparateDataShape.PrimitiveSet.Primitive.IndexStreamCtr(); if (nrfaces * 3 > 255) { cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FormatType = 0x1403; } cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceDataLength = (uint)(nrfaces * 3 * ((nrfaces * 3 > 255) ? 2 : 1)); cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData = new byte[cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceDataLength]; int offs = 0; int idx = 0; foreach (var f in Model.Faces) { if (f.Material != MatNames[i]) { continue; } if (nrfaces * 3 > 255) { IOUtil.WriteU16LE(cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData, offs, (ushort)idx); IOUtil.WriteU16LE(cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData, offs + 2, (ushort)(idx + 1)); IOUtil.WriteU16LE(cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData, offs + 4, (ushort)(idx + 2)); offs += 2 * 3; } else { cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData[idx] = (byte)idx; cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData[idx + 1] = (byte)(idx + 1); cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData[idx + 2] = (byte)(idx + 2); offs += 3; } idx += 3; } cmdl.Shapes[i].NrVertexAttributes = 2; cmdl.Shapes[i].VertexAttributes = new CMDL.SeparateDataShape.VertexAttributeCtr[2]; //interleaved cmdl.Shapes[i].VertexAttributes[0] = new CMDL.SeparateDataShape.InterleavedVertexStreamCtr(); ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).NrVertexStreams = (texcoords ? 2u : 1u); ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexStreams = new CMDL.SeparateDataShape.InterleavedVertexStreamCtr.VertexStreamCtr[texcoords ? 2 : 1]; ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexStreams[0] = new CMDL.SeparateDataShape.InterleavedVertexStreamCtr.VertexStreamCtr(CMDL.SeparateDataShape.VertexAttributeCtr.VertexAttributeUsage.Position, CMDL.SeparateDataShape.DataType.GL_FLOAT, 3, 0); if (texcoords) { ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexStreams[1] = new CMDL.SeparateDataShape.InterleavedVertexStreamCtr.VertexStreamCtr(CMDL.SeparateDataShape.VertexAttributeCtr.VertexAttributeUsage.TextureCoordinate0, CMDL.SeparateDataShape.DataType.GL_FLOAT, 2, 12); } ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexDataEntrySize = (texcoords ? 20u : 12u); byte[] Result = new byte[nrfaces * 3 * ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexDataEntrySize]; offs = 0; foreach (var f in Model.Faces) { if (f.Material != MatNames[i]) { continue; } for (int qqq = 0; qqq < 3; qqq++) { Vector3 Pos = Model.Vertices[f.VertexIndieces[qqq]]; IOUtil.WriteSingleLE(Result, offs, Pos.X); IOUtil.WriteSingleLE(Result, offs + 4, Pos.Y); IOUtil.WriteSingleLE(Result, offs + 8, Pos.Z); offs += 12; if (texcoords) { Vector2 Tex = Model.TexCoords[f.TexCoordIndieces[qqq]]; IOUtil.WriteSingleLE(Result, offs, Tex.X); IOUtil.WriteSingleLE(Result, offs + 4, Tex.Y); offs += 8; } } } ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexStreamLength = (uint)Result.Length; ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexStream = Result; //color cmdl.Shapes[i].VertexAttributes[1] = new CMDL.SeparateDataShape.VertexParamAttributeCtr(CMDL.SeparateDataShape.VertexAttributeCtr.VertexAttributeUsage.Color, 1, 1, 1, MatLib.GetMaterialByName(MatNames[i]).Alpha); } } if (NrTextures != 0) { c.Data.Dictionaries[1] = new DICT(); c.Data.Textures = new TXOB[NrTextures]; int qqq = 0; int idx = 0; foreach (Bitmap b in Textures) { if (b == null) { qqq++; continue; } c.Data.Dictionaries[1].Add(MatLib.Materials[qqq].Name); c.Data.Textures[idx] = new ImageTextureCtr(MatLib.Materials[qqq].Name, b, GPU.Textures.ImageFormat.ETC1A4); idx++; qqq++; } } }
protected override void _Read(BinaryReader reader) { List <Vector3> vertices = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); List <Vector2> uvs = new List <Vector2>(); Dictionary <int, Vertex> nodeVertices = new Dictionary <int, Vertex>(); MeshFace currentFace = null; int currentTextureIndex = -1; MTL mtl = null; Textures.Clear(); RootNode = new ModelNode(); RootNode.HasMesh = true; bool hasUV = false; bool hasNormals = false; bool faceTextureChanged = false; string[] lines = reader.ReadToEnd().Split('\n'); foreach (string line in lines) { if (line.StartsWith("#") || String.IsNullOrEmpty(line)) { continue; } else if (line.StartsWith("mtllib ")) { string[] values = line.Split(' '); if (values.Length < 2) { continue; } string mtlPath = ""; string dir = Path.GetDirectoryName(FilePath); mtlPath = String.Format("{0}\\{1}", Path.GetDirectoryName(FilePath), values[1]); if (File.Exists(mtlPath)) { mtl = new MTL(mtlPath); Textures = mtl.Textures; } } else if (line.StartsWith("v ")) { string[] values = line.Split(' '); if (values.Length < 4) { continue; } Vector3 vertex = new Vector3(); vertex.X = float.Parse(values[1], m_cultureInfo); vertex.Y = float.Parse(values[2], m_cultureInfo); vertex.Z = float.Parse(values[3], m_cultureInfo); RootNode.VertexPositions.Add(vertex); } else if (line.StartsWith("vt ")) { string[] values = line.Split(' '); if (values.Length < 3) { continue; } Vector2 uv = new Vector2(); uv.X = float.Parse(values[1], m_cultureInfo); uv.Y = float.Parse(values[2], m_cultureInfo); RootNode.VertexUVs.Add(uv); } else if (line.StartsWith("vn ")) { string[] values = line.Split(' '); if (values.Length < 4) { continue; } Vector3 normal = new Vector3(); normal.X = float.Parse(values[1], m_cultureInfo); normal.Y = float.Parse(values[2], m_cultureInfo); normal.Z = float.Parse(values[3], m_cultureInfo); RootNode.VertexNormals.Add(normal); } else if (line.StartsWith("f ")) { if (currentFace == null) { continue; } if (line.Contains("//")) { string[] stringSeparators = new string[] { "//" }; string[] values = line.Split(' '); if (values.Length < 4) { continue; } string[] vert1Values = values[1].Split(stringSeparators, StringSplitOptions.None); string[] vert2Values = values[2].Split(stringSeparators, StringSplitOptions.None); string[] vert3Values = values[3].Split(stringSeparators, StringSplitOptions.None); currentFace.PositionIndices.Add((ushort)(int.Parse(vert1Values[0]) - 1)); currentFace.NormalIndices.Add((ushort)(int.Parse(vert1Values[1]) - 1)); currentFace.PositionIndices.Add((ushort)(int.Parse(vert2Values[0]) - 1)); currentFace.NormalIndices.Add((ushort)(int.Parse(vert2Values[1]) - 1)); currentFace.PositionIndices.Add((ushort)(int.Parse(vert3Values[0]) - 1)); currentFace.NormalIndices.Add((ushort)(int.Parse(vert3Values[1]) - 1)); } else if (line.Contains("/")) { string[] stringSeparators = new string[] { "/" }; string[] values = line.Split(' '); if (values.Length < 4) { continue; } string[] vert1Values = values[1].Split(stringSeparators, StringSplitOptions.None); string[] vert2Values = values[2].Split(stringSeparators, StringSplitOptions.None); string[] vert3Values = values[3].Split(stringSeparators, StringSplitOptions.None); currentFace.PositionIndices.Add((ushort)(int.Parse(vert1Values[0]) - 1)); currentFace.UVIndices.Add((ushort)(int.Parse(vert1Values[1]) - 1)); if (vert1Values.Length > 2) { currentFace.NormalIndices.Add((ushort)(int.Parse(vert1Values[2]) - 1)); } currentFace.PositionIndices.Add((ushort)(int.Parse(vert2Values[0]) - 1)); currentFace.UVIndices.Add((ushort)(int.Parse(vert2Values[1]) - 1)); if (vert2Values.Length > 2) { currentFace.NormalIndices.Add((ushort)(int.Parse(vert2Values[2]) - 1)); } currentFace.PositionIndices.Add((ushort)(int.Parse(vert3Values[0]) - 1)); currentFace.UVIndices.Add((ushort)(int.Parse(vert3Values[1]) - 1)); if (vert3Values.Length > 2) { currentFace.NormalIndices.Add((ushort)(int.Parse(vert3Values[2]) - 1)); } } else { string[] values = line.Split(' '); if (values.Length < 4) { continue; } currentFace.PositionIndices.Add((ushort)(int.Parse(values[0]) - 1)); currentFace.PositionIndices.Add((ushort)(int.Parse(values[1]) - 1)); currentFace.PositionIndices.Add((ushort)(int.Parse(values[2]) - 1)); } } else if (line.StartsWith("usemtl ")) { if (mtl == null) { continue; } string[] values = line.Split(' '); if (values.Length < 2) { continue; } if (faceTextureChanged) { RootNode.Faces.Add(currentFace); } currentFace = new MeshFace(); currentTextureIndex = mtl.GetMaterialTextureIndex(values[1]); currentFace.TextureIndex = (uint)currentTextureIndex; faceTextureChanged = true; } else if (line.StartsWith("o ") || line.StartsWith("g ")) { if (currentFace != null) { RootNode.Faces.Add(currentFace); } currentFace = new MeshFace(); faceTextureChanged = false; } } RootNode.Faces.Add(currentFace); RootNode.ResolveFaceTextures(Textures); }
protected override void _Write(BinaryWriter writer) { int objNum = 0; int totalPositions = 0; int totalNormals = 0; int totalUVs = 0; MTL mtl = new MTL(Textures); if (String.IsNullOrEmpty(FilePath)) { //TODO: Make this somehow better throw new ArgumentException("Filepath was not given."); } string mtlPath = ""; string dir = Path.GetDirectoryName(FilePath); if (String.IsNullOrEmpty(dir) || dir == "\\" || Path.GetExtension(FilePath) == ".OBJ" || Path.GetExtension(FilePath) == ".obj") { mtlPath = Path.ChangeExtension(FilePath, ".mtl"); } else { mtlPath = String.Format("{0}\\{1}", Path.GetDirectoryName(FilePath), Path.ChangeExtension(FilePath, ".mtl")); } mtl.Write(mtlPath); writer.WriteASCII("# OBJ Generated by ShenmueDKSharp\n"); writer.WriteASCII(String.Format("mtllib {0}\n", Path.GetFileName(mtlPath))); StringBuilder sbVertices = new StringBuilder(); StringBuilder sbNormals = new StringBuilder(); StringBuilder sbUVs = new StringBuilder(); StringBuilder sbMeshes = new StringBuilder(); foreach (ModelNode node in RootNode.GetAllNodes()) { Matrix4 transformMatrix = node.GetTransformMatrix(); if (node.Faces.Count == 0) { continue; } Vector3[] positions = node.VertexPositions.ToArray(); Vector3[] normals = node.VertexNormals.ToArray(); Vector2[] uvs = node.VertexUVs.ToArray(); if (positions.Length == 0) { continue; } sbMeshes.Append(String.Format("o obj_{0}\n", objNum)); for (int i = 0; i < positions.Length; i++) { positions[i] = Vector3.TransformPosition(positions[i], transformMatrix); sbVertices.Append(String.Format(m_cultureInfo, "v {0:F6} {1:F6} {2:F6}\n", positions[i].X, positions[i].Y, positions[i].Z)); } if (uvs.Length > 0) { for (int i = 0; i < uvs.Length; i++) { sbUVs.Append(String.Format(m_cultureInfo, "vt {0:F6} {1:F6}\n", uvs[i].X, uvs[i].Y)); } } if (normals.Length > 0) { for (int i = 0; i < normals.Length; i++) { //normals[i] = Vector3.TransformPosition(normals[i], transformMatrix); sbNormals.Append(String.Format(m_cultureInfo, "vn {0:F6} {1:F6} {2:F6}\n", normals[i].X, normals[i].Y, normals[i].Z)); } } foreach (MeshFace face in node.Faces) { uint textureIndex = face.TextureIndex; Texture texture = face.Material.Texture; if (textureIndex < mtl.MaterialNames.Count) { sbMeshes.Append(String.Format("usemtl {0}\n", mtl.MaterialNames[(int)textureIndex])); } sbMeshes.Append("s 1\n"); bool hasUV = face.UVIndices.Count > 0; bool hasNormal = face.NormalIndices.Count > 0; if (face.Type == MeshFace.PrimitiveType.Triangles) { for (int i = 0; i < face.PositionIndices.Count - 2; i += 3) { int posIndex1 = face.PositionIndices[i] + totalPositions + 1; int posIndex2 = face.PositionIndices[i + 1] + totalPositions + 1; int posIndex3 = face.PositionIndices[i + 2] + totalPositions + 1; if (hasNormal) { int normIndex1 = face.NormalIndices[i] + totalNormals + 1; int normIndex2 = face.NormalIndices[i + 1] + totalNormals + 1; int normIndex3 = face.NormalIndices[i + 2] + totalNormals + 1; if (hasUV) { int uvIndex1 = face.UVIndices[i] + totalUVs + 1; int uvIndex2 = face.UVIndices[i + 1] + totalUVs + 1; int uvIndex3 = face.UVIndices[i + 2] + totalUVs + 1; sbMeshes.Append(String.Format(GetVertexFormatString(hasUV, hasNormal), posIndex1, posIndex2, posIndex3, uvIndex1, uvIndex2, uvIndex3, normIndex1, normIndex2, normIndex3)); } else { sbMeshes.Append(String.Format(GetVertexFormatString(hasUV, hasNormal), posIndex1, posIndex2, posIndex3, normIndex1, normIndex2, normIndex3)); } } else { sbMeshes.Append(String.Format(GetVertexFormatString(hasUV, hasNormal), posIndex1, posIndex2, posIndex3)); } } } else if (face.Type == MeshFace.PrimitiveType.TriangleStrip) { for (int i = 0; i < face.PositionIndices.Count - 2; i++) { int posIndex1 = face.PositionIndices[i] + totalPositions + 1; int posIndex2 = face.PositionIndices[i + 1] + totalPositions + 1; int posIndex3 = face.PositionIndices[i + 2] + totalPositions + 1; if (hasNormal) { int normIndex1 = face.NormalIndices[i] + totalNormals + 1; int normIndex2 = face.NormalIndices[i + 1] + totalNormals + 1; int normIndex3 = face.NormalIndices[i + 2] + totalNormals + 1; if (hasUV) { int uvIndex1 = face.UVIndices[i] + totalUVs + 1; int uvIndex2 = face.UVIndices[i + 1] + totalUVs + 1; int uvIndex3 = face.UVIndices[i + 2] + totalUVs + 1; if ((i & 1) == 1) { sbMeshes.Append(String.Format(GetVertexFormatString(hasUV, hasNormal), posIndex1, posIndex2, posIndex3, uvIndex1, uvIndex2, uvIndex3, normIndex1, normIndex2, normIndex3)); } else { sbMeshes.Append(String.Format(GetVertexFormatString(hasUV, hasNormal), posIndex1, posIndex3, posIndex2, uvIndex1, uvIndex3, uvIndex2, normIndex1, normIndex3, normIndex2)); } } else { if ((i & 1) == 1) { sbMeshes.Append(String.Format(GetVertexFormatString(hasUV, hasNormal), posIndex1, posIndex2, posIndex3, normIndex1, normIndex2, normIndex3)); } else { sbMeshes.Append(String.Format(GetVertexFormatString(hasUV, hasNormal), posIndex1, posIndex3, posIndex2, normIndex1, normIndex3, normIndex2)); } } } else { if ((i & 1) == 1) { sbMeshes.Append(String.Format(GetVertexFormatString(hasUV, hasNormal), posIndex1, posIndex2, posIndex3)); } else { sbMeshes.Append(String.Format(GetVertexFormatString(hasUV, hasNormal), posIndex1, posIndex3, posIndex2)); } } } } } objNum++; totalPositions += positions.Length; totalNormals += normals.Length; totalUVs += uvs.Length; } writer.WriteASCII(sbVertices.ToString()); writer.WriteASCII(sbUVs.ToString()); writer.WriteASCII(sbNormals.ToString()); writer.WriteASCII(sbMeshes.ToString()); writer.WriteASCII(String.Format("# Total Positions: {0}\n", totalPositions)); writer.WriteASCII(String.Format("# Total Normals: {0}\n", totalNormals)); writer.WriteASCII(String.Format("# Total UVs: {0}\n", totalUVs)); }
public MTL ToMTL() { MTL m = new MTL(); foreach (var v in Materials) { MTL.MTLMaterial mm = new MTL.MTLMaterial("M" + v.Key + "M"); mm.DiffuseColor = Color.White; mm.DiffuseMapPath = "Tex/" + v.Key + ".png"; m.Materials.Add(mm); } return m; }
public MTL ToMTL(String TexDir) { var o = new MTL(); var m = this;//Data.Models[Model]; //foreach (CMDL m in Models) { foreach (var vv in m.Materials) { MTL.MTLMaterial mm = new MTL.MTLMaterial(vv.Name); mm.DiffuseColor = vv.MaterialColor.DiffuseU32; mm.AmbientColor = vv.MaterialColor.AmbientU32; mm.Alpha = vv.MaterialColor.Diffuse.W; mm.SpecularColor = vv.MaterialColor.Specular0U32; if (vv.Tex0 != null && vv.Tex0.TextureObject is ReferenceTexture) mm.DiffuseMapPath = TexDir.Replace('\\', '/').TrimEnd('/') + "/" + ((ReferenceTexture)vv.Tex0.TextureObject).LinkedTextureName + ".png"; o.Materials.Add(mm); } } return o; }
public static void FromOBJ(CGFX c, String OBJPath, String ModelName = "EFEModel") { OBJ Model = new OBJ(File.ReadAllBytes(OBJPath)); if (Model.MTLPath == null) throw new Exception("Model without materials not supported!"); String MtlPath = Path.GetDirectoryName(OBJPath) + "\\" + Model.MTLPath; MTL MatLib = new MTL(File.ReadAllBytes(MtlPath)); List<String> MatNames = new List<string>(); foreach (var f in Model.Faces) { if (!MatNames.Contains(f.Material)) MatNames.Add(f.Material); } Bitmap[] Textures = new Bitmap[MatLib.Materials.Count]; int q = 0; int NrTextures = 0; foreach (var v in MatLib.Materials) { if (!MatNames.Contains(v.Name)) { q++; continue; } if (v.DiffuseMapPath != null) { Textures[q] = new Bitmap(new MemoryStream(File.ReadAllBytes(Path.GetDirectoryName(MtlPath) + "\\" + v.DiffuseMapPath))); NrTextures++; } q++; } c.Data.Dictionaries[0] = new DICT(); c.Data.Dictionaries[0].Add(ModelName); c.Data.Models = new CMDL[1]; c.Data.Models[0] = new CMDL(ModelName); CMDL cmdl = c.Data.Models[0]; //Mesh Node Visibility { cmdl.NrMeshNodes = 1; cmdl.MeshNodeVisibilitiesDict = new DICT(); cmdl.MeshNodeVisibilitiesDict.Add("CompleteModel"); cmdl.MeshNodeVisibilities = new CMDL.MeshNodeVisibilityCtr[] { new CMDL.MeshNodeVisibilityCtr("CompleteModel") }; } //Meshes { cmdl.NrMeshes = (uint)MatNames.Count; cmdl.Meshes = new CMDL.Mesh[MatNames.Count]; for (int i = 0; i < MatNames.Count; i++) { cmdl.Meshes[i] = new CMDL.Mesh(); cmdl.Meshes[i].MeshNodeName = "CompleteModel"; cmdl.Meshes[i].MaterialIndex = (uint)i; cmdl.Meshes[i].ShapeIndex = (uint)i; } } //Materials { cmdl.NrMaterials = (uint)MatNames.Count; cmdl.MaterialsDict = new DICT(); cmdl.Materials = new CMDL.MTOB[MatNames.Count]; for (int i = 0; i < MatNames.Count; i++) { cmdl.MaterialsDict.Add(MatNames[i]); cmdl.Materials[i] = new CMDL.MTOB(MatNames[i]); cmdl.Materials[i].FragShader.TextureCombiners[0].SrcRgb = 0xEE0; cmdl.Materials[i].FragShader.TextureCombiners[0].SrcAlpha = 0xEE0; for (int qq = 1; qq < 6; qq++) { cmdl.Materials[i].FragShader.TextureCombiners[qq].SrcRgb = 0xEEF; cmdl.Materials[i].FragShader.TextureCombiners[qq].SrcAlpha = 0xEEF; } Bitmap tex = Textures[MatLib.Materials.IndexOf(MatLib.GetMaterialByName(MatNames[i]))]; if (tex != null) { cmdl.Materials[i].NrActiveTextureCoordiators = 1; cmdl.Materials[i].TextureCoordiators[0].Scale = new LibEveryFileExplorer.Collections.Vector2(1, 1); cmdl.Materials[i].Tex0 = new CMDL.MTOB.TexInfo(MatNames[i]); cmdl.Materials[i].FragShader.TextureCombiners[0].SrcRgb = 0xE30; cmdl.Materials[i].FragShader.TextureCombiners[0].SrcAlpha = 0xE30; cmdl.Materials[i].FragShader.TextureCombiners[0].CombineRgb = 1; cmdl.Materials[i].FragShader.TextureCombiners[0].CombineAlpha = 1; } } } //Shapes { cmdl.NrShapes = (uint)MatNames.Count; cmdl.Shapes = new CMDL.SeparateDataShape[MatNames.Count]; for (int i = 0; i < MatNames.Count; i++) { cmdl.Shapes[i] = new CMDL.SeparateDataShape(); Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue); int nrfaces = 0; bool texcoords = false; foreach (var f in Model.Faces) { if (f.Material != MatNames[i]) continue; nrfaces++; if (f.TexCoordIndieces.Count > 0) texcoords = true; foreach (var qqq in f.VertexIndieces) { if (Model.Vertices[qqq].X < min.X) min.X = Model.Vertices[qqq].X; if (Model.Vertices[qqq].Y < min.Y) min.Y = Model.Vertices[qqq].Y; if (Model.Vertices[qqq].Z < min.Z) min.Z = Model.Vertices[qqq].Z; if (Model.Vertices[qqq].X > max.X) max.X = Model.Vertices[qqq].X; if (Model.Vertices[qqq].Y > max.Y) max.Y = Model.Vertices[qqq].Y; if (Model.Vertices[qqq].Z > max.Z) max.Z = Model.Vertices[qqq].Z; } } ((OrientedBoundingBox)cmdl.Shapes[i].BoundingBox).CenterPosition = (min + max) / 2; ((OrientedBoundingBox)cmdl.Shapes[i].BoundingBox).Size = max - min; cmdl.Shapes[i].NrPrimitiveSets = 1; cmdl.Shapes[i].PrimitiveSets = new CMDL.SeparateDataShape.PrimitiveSet[1]; cmdl.Shapes[i].PrimitiveSets[0] = new CMDL.SeparateDataShape.PrimitiveSet(); cmdl.Shapes[i].PrimitiveSets[0].NrPrimitives = 1; cmdl.Shapes[i].PrimitiveSets[0].Primitives = new CMDL.SeparateDataShape.PrimitiveSet.Primitive[1]; cmdl.Shapes[i].PrimitiveSets[0].Primitives[0] = new CMDL.SeparateDataShape.PrimitiveSet.Primitive(); cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].NrBufferObjects = 1; cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].BufferObjects = new uint[] { 0 }; cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].NrIndexStreams = 1; cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams = new CMDL.SeparateDataShape.PrimitiveSet.Primitive.IndexStreamCtr[1]; cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0] = new CMDL.SeparateDataShape.PrimitiveSet.Primitive.IndexStreamCtr(); if (nrfaces * 3 > 255) cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FormatType = 0x1403; cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceDataLength = (uint)(nrfaces * 3 * ((nrfaces * 3 > 255) ? 2 : 1)); cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData = new byte[cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceDataLength]; int offs = 0; int idx = 0; foreach (var f in Model.Faces) { if (f.Material != MatNames[i]) continue; if (nrfaces * 3 > 255) { IOUtil.WriteU16LE(cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData, offs, (ushort)idx); IOUtil.WriteU16LE(cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData, offs + 2, (ushort)(idx + 1)); IOUtil.WriteU16LE(cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData, offs + 4, (ushort)(idx + 2)); offs += 2 * 3; } else { cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData[idx] = (byte)idx; cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData[idx + 1] = (byte)(idx + 1); cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData[idx + 2] = (byte)(idx + 2); offs += 3; } idx += 3; } cmdl.Shapes[i].NrVertexAttributes = 2; cmdl.Shapes[i].VertexAttributes = new CMDL.SeparateDataShape.VertexAttributeCtr[2]; //interleaved cmdl.Shapes[i].VertexAttributes[0] = new CMDL.SeparateDataShape.InterleavedVertexStreamCtr(); ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).NrVertexStreams = (texcoords ? 2u : 1u); ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexStreams = new CMDL.SeparateDataShape.InterleavedVertexStreamCtr.VertexStreamCtr[texcoords ? 2 : 1]; ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexStreams[0] = new CMDL.SeparateDataShape.InterleavedVertexStreamCtr.VertexStreamCtr(CMDL.SeparateDataShape.VertexAttributeCtr.VertexAttributeUsage.Position, CMDL.SeparateDataShape.DataType.GL_FLOAT, 3, 0); if (texcoords) ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexStreams[1] = new CMDL.SeparateDataShape.InterleavedVertexStreamCtr.VertexStreamCtr(CMDL.SeparateDataShape.VertexAttributeCtr.VertexAttributeUsage.TextureCoordinate0, CMDL.SeparateDataShape.DataType.GL_FLOAT, 2, 12); ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexDataEntrySize = (texcoords ? 20u : 12u); byte[] Result = new byte[nrfaces * 3 * ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexDataEntrySize]; offs = 0; foreach (var f in Model.Faces) { if (f.Material != MatNames[i]) continue; for (int qqq = 0; qqq < 3; qqq++) { Vector3 Pos = Model.Vertices[f.VertexIndieces[qqq]]; IOUtil.WriteSingleLE(Result, offs, Pos.X); IOUtil.WriteSingleLE(Result, offs + 4, Pos.Y); IOUtil.WriteSingleLE(Result, offs + 8, Pos.Z); offs += 12; if (texcoords) { Vector2 Tex = Model.TexCoords[f.TexCoordIndieces[qqq]]; IOUtil.WriteSingleLE(Result, offs, Tex.X); IOUtil.WriteSingleLE(Result, offs + 4, Tex.Y); offs += 8; } } } ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexStreamLength = (uint)Result.Length; ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexStream = Result; //color cmdl.Shapes[i].VertexAttributes[1] = new CMDL.SeparateDataShape.VertexParamAttributeCtr(CMDL.SeparateDataShape.VertexAttributeCtr.VertexAttributeUsage.Color, 1, 1, 1, MatLib.GetMaterialByName(MatNames[i]).Alpha); } } if (NrTextures != 0) { c.Data.Dictionaries[1] = new DICT(); c.Data.Textures = new TXOB[NrTextures]; int qqq = 0; int idx = 0; foreach (Bitmap b in Textures) { if (b == null) { qqq++; continue; } c.Data.Dictionaries[1].Add(MatLib.Materials[qqq].Name); c.Data.Textures[idx] = new ImageTextureCtr(MatLib.Materials[qqq].Name, b, GPU.Textures.ImageFormat.ETC1A4); idx++; qqq++; } } }