private static void WriteMaterialLib(Geometry_000F g, StreamWriter MTLWriter, ref int untexturedMaterials) { string textureName; if (g.materialList.materialList[0].materialStruct.isTextured != 0) { textureName = g.materialList.materialList[0].texture.diffuseTextureName.stringString; } else { textureName = "default_" + untexturedMaterials.ToString(); untexturedMaterials++; } MTLWriter.WriteLine("newmtl " + textureName + "_m"); MTLWriter.WriteLine("Ka 0.2 0.2 0.2"); MTLWriter.WriteLine("Kd 0.8 0.8 0.8"); MTLWriter.WriteLine("Ks 0 0 0"); MTLWriter.WriteLine("Ns 10"); MTLWriter.WriteLine("d 1.0"); MTLWriter.WriteLine("illum 4"); if (g.materialList.materialList[0].materialStruct.isTextured != 0) { MTLWriter.WriteLine("map_Kd " + textureName + ".png"); } MTLWriter.WriteLine(); }
private void AddGeometry(SharpDevice device, Geometry_000F g, Matrix transformMatrix) { List <string> materialList = new List <string>(); foreach (Material_0007 m in g.materialList.materialList) { if (m.texture != null) { string textureName = m.texture.diffuseTextureName.stringString; materialList.Add(textureName); } else { materialList.Add(DefaultTexture); } } if ((g.geometryStruct.geometryFlags2 & GeometryFlags2.isNativeGeometry) != 0) { AddNativeData(device, g.geometryExtension, materialList, transformMatrix); return; } List <Vector3> vertexList1 = new List <Vector3>(); List <Vector3> normalList = new List <Vector3>(); List <Vector2> textCoordList = new List <Vector2>(); List <SharpDX.Color> colorList = new List <SharpDX.Color>(); if ((g.geometryStruct.geometryFlags & GeometryFlags.hasVertexPositions) != 0) { MorphTarget m = g.geometryStruct.morphTargets[0]; foreach (Vertex3 v in m.vertices) { Vector3 pos = (Vector3)Vector3.Transform(new Vector3(v.X, v.Y, v.Z), transformMatrix); vertexList1.Add(pos); vertexListG.Add(pos); } } if ((g.geometryStruct.geometryFlags & GeometryFlags.hasNormals) != 0) { for (int i = 0; i < vertexList1.Count; i++) { normalList.Add(new Vector3(g.geometryStruct.morphTargets[0].normals[i].X, g.geometryStruct.morphTargets[0].normals[i].Y, g.geometryStruct.morphTargets[0].normals[i].Z)); } } if ((g.geometryStruct.geometryFlags & GeometryFlags.hasVertexColors) != 0) { for (int i = 0; i < vertexList1.Count; i++) { RenderWareFile.Color c = g.geometryStruct.vertexColors[i]; colorList.Add(new SharpDX.Color(c.R, c.G, c.B, c.A)); } } else { for (int i = 0; i < vertexList1.Count; i++) { colorList.Add(new SharpDX.Color(1f, 1f, 1f, 1f)); } } if ((g.geometryStruct.geometryFlags & GeometryFlags.hasTextCoords) != 0) { for (int i = 0; i < vertexList1.Count; i++) { Vertex2 tc = g.geometryStruct.textCoords[i]; textCoordList.Add(new Vector2(tc.X, tc.Y)); } } else { for (int i = 0; i < vertexList1.Count; i++) { textCoordList.Add(new Vector2()); } } List <SharpSubSet> SubsetList = new List <SharpSubSet>(); List <int> indexList = new List <int>(); int previousIndexCount = 0; for (int i = 0; i < materialList.Count; i++) { foreach (Triangle t in g.geometryStruct.triangles) { if (t.materialIndex == i) { indexList.Add(t.vertex1); indexList.Add(t.vertex2); indexList.Add(t.vertex3); triangleList.Add(new Triangle(t.materialIndex, (ushort)(t.vertex1 + triangleListOffset), (ushort)(t.vertex2 + triangleListOffset), (ushort)(t.vertex3 + triangleListOffset))); } } if (indexList.Count - previousIndexCount > 0) { SubsetList.Add(new SharpSubSet(previousIndexCount, indexList.Count - previousIndexCount, TextureManager.GetTextureFromDictionary(materialList[i]), materialList[i])); } previousIndexCount = indexList.Count(); } triangleListOffset += vertexList1.Count; if (SubsetList.Count > 0) { VertexColoredTextured[] vertices = new VertexColoredTextured[vertexList1.Count]; for (int i = 0; i < vertices.Length; i++) { vertices[i] = new VertexColoredTextured(vertexList1[i], textCoordList[i], colorList[i]); } AddToMeshList(SharpMesh.Create(device, vertices, indexList.ToArray(), SubsetList)); } else { AddToMeshList(null); } }
private static void WriteNativeData(StreamWriter writer, Geometry_000F g) { NativeDataGC n = null; foreach (RWSection rw in g.geometryExtension.extensionSectionList) { if (rw is BinMeshPLG_050E binmesh) { if (binmesh.numMeshes == 0) { return; } } if (rw is NativeDataPLG_0510 native) { n = native.nativeDataStruct.nativeData; break; } } if (n == null) { throw new Exception(); } List <Vertex3> vertexList_init = new List <Vertex3>(); List <Color> colorList_init = new List <Color>(); List <TextCoord> textCoordList_init = new List <TextCoord>(); List <Vertex3> normalList_init = new List <Vertex3>(); List <Triangle> triangleList = new List <Triangle>(); foreach (Declaration d in n.declarations) { if (d.declarationType == Declarations.Vertex) { foreach (Vertex3 v in d.entryList) { vertexList_init.Add(v); } } else if (d.declarationType == Declarations.Color) { foreach (Color c in d.entryList) { colorList_init.Add(c); } } else if (d.declarationType == Declarations.TextCoord) { foreach (TextCoord t in d.entryList) { textCoordList_init.Add(t); } } else if (d.declarationType == Declarations.Normal) { foreach (Vertex3 v in d.entryList) { normalList_init.Add(v); } } else { throw new Exception(); } } foreach (TriangleDeclaration td in n.triangleDeclarations) { foreach (TriangleList tl in td.TriangleListList) { List <Vertex3> vertexList_final = new List <Vertex3>(); List <Color> colorList_final = new List <Color>(); List <TextCoord> textCoordList_final = new List <TextCoord>(); List <Vertex3> normalList_final = new List <Vertex3>(); foreach (int[] objectList in tl.entries) { for (int j = 0; j < objectList.Count(); j++) { if (n.declarations[j].declarationType == Declarations.Vertex) { vertexList_final.Add(vertexList_init[objectList[j]]); } else if (n.declarations[j].declarationType == Declarations.Color) { colorList_final.Add(colorList_init[objectList[j]]); } else if (n.declarations[j].declarationType == Declarations.TextCoord) { textCoordList_final.Add(textCoordList_init[objectList[j]]); } else if (n.declarations[j].declarationType == Declarations.Normal) { normalList_final.Add(normalList_init[objectList[j]]); } else { throw new Exception(); } } } bool control = true; for (int i = 2; i < vertexList_final.Count(); i++) { if (control) { triangleList.Add(new Triangle { materialIndex = (ushort)td.MaterialIndex, vertex1 = (ushort)(i - 2), vertex2 = (ushort)(i - 1), vertex3 = (ushort)(i) }); } else { triangleList.Add(new Triangle { materialIndex = (ushort)td.MaterialIndex, vertex1 = (ushort)(i - 2), vertex2 = (ushort)(i), vertex3 = (ushort)(i - 1) }); } control = !control; } //Write vertex list to obj foreach (Vertex3 i in vertexList_final) { writer.WriteLine("v " + i.X.ToString() + " " + i.Y.ToString() + " " + i.Z.ToString()); } writer.WriteLine(); //Write uv list to obj if (textCoordList_final.Count() > 0) { foreach (TextCoord i in textCoordList_final) { writer.WriteLine("vt " + i.X.ToString() + " " + (-i.Y).ToString()); } } writer.WriteLine(); //Write normal list to obj if (normalList_final.Count() > 0) { foreach (Vertex3 i in normalList_final) { writer.WriteLine("vn " + i.X.ToString() + " " + i.Y.ToString() + " " + i.Z.ToString()); } } writer.WriteLine(); // Write vcolors to obj if (colorList_final.Count() > 0) { foreach (Color i in colorList_final) { writer.WriteLine("vc " + i.R.ToString() + " " + i.G.ToString() + " " + i.B.ToString() + " " + i.A.ToString()); } } writer.WriteLine(); foreach (Triangle t in triangleList) { List <char> v1 = new List <char>(8); List <char> v2 = new List <char>(8); List <char> v3 = new List <char>(8); int n1 = t.vertex1 + totalVertexIndices; int n2 = t.vertex2 + totalVertexIndices; int n3 = t.vertex3 + totalVertexIndices; v1.AddRange(n1.ToString()); v2.AddRange(n2.ToString()); v3.AddRange(n3.ToString()); if (((g.geometryStruct.geometryFlags & (int)GeometryFlags.hasTextCoords) != 0) & (g.geometryStruct.geometryFlags & (int)GeometryFlags.hasNormals) != 0) { v1.AddRange("/" + n1.ToString() + "/" + n1.ToString()); v2.AddRange("/" + n2.ToString() + "/" + n2.ToString()); v3.AddRange("/" + n3.ToString() + "/" + n3.ToString()); } else if ((g.geometryStruct.geometryFlags & (int)GeometryFlags.hasTextCoords) != 0) { v1.AddRange("/" + n1.ToString()); v2.AddRange("/" + n2.ToString()); v3.AddRange("/" + n3.ToString()); } else if ((g.geometryStruct.geometryFlags & (int)GeometryFlags.hasNormals) != 0) { v1.AddRange("//" + n1.ToString()); v2.AddRange("//" + n2.ToString()); v3.AddRange("//" + n3.ToString()); } writer.WriteLine("f " + new string(v1.ToArray()) + " " + new string(v2.ToArray()) + " " + new string(v3.ToArray())); } writer.WriteLine(); totalVertexIndices += vertexList_final.Count(); } } }
private static void ExportGeometryToOBJ(StreamWriter writer, Geometry_000F g, ref int untexturedMaterials) { List <string> MaterialList = new List <string>(); foreach (Material_0007 m in g.materialList.materialList) { if (m.texture != null) { string textureName = m.texture.diffuseTextureName.stringString; //if (!MaterialList.Contains(textureName)) MaterialList.Add(textureName); } else { MaterialList.Add("default"); } } GeometryStruct_0001 gs = g.geometryStruct; if (g.materialList.materialList[0].materialStruct.isTextured != 0) { writer.WriteLine("g obj_" + g.materialList.materialList[0].texture.diffuseTextureName.stringString); writer.WriteLine("usemtl " + g.materialList.materialList[0].texture.diffuseTextureName.stringString + "_m"); } else { writer.WriteLine("g obj_default_" + untexturedMaterials.ToString()); writer.WriteLine("usemtl default_" + untexturedMaterials.ToString() + "_m"); untexturedMaterials++; } writer.WriteLine(); if (gs.geometryFlags2 == 0x0101) { WriteNativeData(writer, g); return; } foreach (MorphTarget m in gs.morphTargets) { if (m.hasVertices != 0) { foreach (Vertex3 v in m.vertices) { writer.WriteLine("v " + v.X.ToString() + " " + v.Y.ToString() + " " + v.Z.ToString()); } writer.WriteLine(); } if (m.hasNormals != 0) { foreach (Vertex3 vn in m.normals) { writer.WriteLine("vn " + vn.X.ToString() + " " + vn.Y.ToString() + " " + vn.Z.ToString()); } writer.WriteLine(); } if ((gs.geometryFlags & (int)GeometryFlags.hasVertexColors) != 0) { foreach (Color c in gs.vertexColors) { writer.WriteLine("vc " + c.R.ToString() + " " + c.G.ToString() + " " + c.B.ToString() + " " + c.A.ToString()); } writer.WriteLine(); } if ((gs.geometryFlags & (int)GeometryFlags.hasTextCoords) != 0) { foreach (TextCoord tc in gs.textCoords) { writer.WriteLine("vt " + tc.X.ToString() + " " + tc.Y.ToString()); } writer.WriteLine(); } foreach (Triangle t in gs.triangles) { List <char> v1 = new List <char>(8); List <char> v2 = new List <char>(8); List <char> v3 = new List <char>(8); int n1 = t.vertex1 + totalVertexIndices; int n2 = t.vertex2 + totalVertexIndices; int n3 = t.vertex3 + totalVertexIndices; if (m.hasVertices != 0) { v1.AddRange(n1.ToString()); v2.AddRange(n2.ToString()); v3.AddRange(n3.ToString()); } if (((gs.geometryFlags & (int)GeometryFlags.hasTextCoords) != 0) & (m.hasNormals != 0)) { v1.AddRange("/" + n1.ToString() + "/" + n1.ToString()); v2.AddRange("/" + n2.ToString() + "/" + n2.ToString()); v3.AddRange("/" + n3.ToString() + "/" + n3.ToString()); } else if ((gs.geometryFlags & (int)GeometryFlags.hasTextCoords) != 0) { v1.AddRange("/" + n1.ToString()); v2.AddRange("/" + n2.ToString()); v3.AddRange("/" + n3.ToString()); } else if (m.hasNormals != 0) { v1.AddRange("//" + n1.ToString()); v2.AddRange("//" + n2.ToString()); v3.AddRange("//" + n3.ToString()); } writer.WriteLine("f " + new string(v1.ToArray()) + " " + new string(v2.ToArray()) + " " + new string(v3.ToArray())); } totalVertexIndices += m.vertices.Count(); writer.WriteLine(); } }
void AddGeometry(Geometry_000F g) { List <string> MaterialList = new List <string>(); foreach (Material_0007 m in g.materialList.materialList) { if (m.texture != null) { string textureName = m.texture.diffuseTextureName.stringString; if (!MaterialList.Contains(textureName)) { MaterialList.Add(textureName); } } else { MaterialList.Add(DefaultTexture); } } if (g.geometryStruct.geometryFlags2 == 0x0101) { AddNativeData(g.geometryExtension, MaterialList); return; } List <VertexColoredTextured> vertexList = new List <VertexColoredTextured>(); if ((g.geometryStruct.geometryFlags & (int)GeometryFlags.hasVertexPositions) != 0) { foreach (Vertex3 v in g.geometryStruct.morphTargets[0].vertices) { vertexList.Add(new VertexColoredTextured(new Vector3(v.X, v.Y, v.Z), new Vector2(), SharpDX.Color.White )); this.vertexList.Add(new Vector3(v.X, v.Y, v.Z)); } } if ((g.geometryStruct.geometryFlags & (int)GeometryFlags.hasVertexColors) != 0) { for (int i = 0; i < vertexList.Count; i++) { RenderWareFile.Color c = g.geometryStruct.vertexColors[i]; VertexColoredTextured v = vertexList[i]; v.Color = new SharpDX.Color(c.R, c.G, c.B, c.A); vertexList[i] = v; } } else { for (int i = 0; i < vertexList.Count; i++) { VertexColoredTextured v = vertexList[i]; v.Color = SharpDX.Color.White; vertexList[i] = v; } } if ((g.geometryStruct.geometryFlags & (int)GeometryFlags.hasTextCoords) != 0) { for (int i = 0; i < vertexList.Count; i++) { TextCoord tc = g.geometryStruct.textCoords[i]; VertexColoredTextured v = vertexList[i]; v.TextureCoordinate = new Vector2(tc.X, tc.Y); vertexList[i] = v; } } List <SharpSubSet> SubsetList = new List <SharpSubSet>(); List <int> indexList = new List <int>(); int previousIndexCount = 0; for (int i = 0; i < MaterialList.Count; i++) { foreach (Triangle t in g.geometryStruct.triangles) { if (t.materialIndex == i) { indexList.Add(t.vertex1); indexList.Add(t.vertex2); indexList.Add(t.vertex3); triangleList.Add(t); } } if (indexList.Count - previousIndexCount > 0) { if (BSPRenderer.TextureStream.ContainsKey(MaterialList[i])) { SubsetList.Add(new SharpSubSet(previousIndexCount, indexList.Count - previousIndexCount, BSPRenderer.TextureStream[MaterialList[i]])); } else { SubsetList.Add(new SharpSubSet(previousIndexCount, indexList.Count - previousIndexCount, BSPRenderer.whiteDefault)); } } previousIndexCount = indexList.Count(); } if (SubsetList.Count > 0) { meshList.Add(SharpMesh.Create(SharpRenderer.device, vertexList.ToArray(), indexList.ToArray(), SubsetList)); } }
private void AddGeometry(SharpDevice device, Geometry_000F g, Matrix transformMatrix) { List <string> MaterialList = new List <string>(); foreach (Material_0007 m in g.materialList.materialList) { if (m.texture != null) { string textureName = m.texture.diffuseTextureName.stringString; if (!MaterialList.Contains(textureName)) { MaterialList.Add(textureName); } } else { MaterialList.Add(DefaultTexture); } } if ((g.geometryStruct.geometryFlags2 & GeometryFlags2.isNativeGeometry) != 0) { AddNativeData(device, g.geometryExtension, MaterialList, transformMatrix); return; } List <VertexColoredTextured> vertexList = new List <VertexColoredTextured>(); if ((g.geometryStruct.geometryFlags & GeometryFlags.hasVertexPositions) != 0) { foreach (Vertex3 v in g.geometryStruct.morphTargets[0].vertices) { Vector3 Position = (Vector3)Vector3.Transform(new Vector3(v.X, v.Y, v.Z), transformMatrix); vertexList.Add(new VertexColoredTextured(Position, new Vector2(), SharpDX.Color.White)); vertexListG.Add(Position); } } if ((g.geometryStruct.geometryFlags & GeometryFlags.hasVertexColors) != 0) { for (int i = 0; i < vertexList.Count; i++) { RenderWareFile.Color c = g.geometryStruct.vertexColors[i]; VertexColoredTextured v = vertexList[i]; v.Color = new SharpDX.Color(c.R, c.G, c.B, c.A); vertexList[i] = v; } } else { for (int i = 0; i < vertexList.Count; i++) { VertexColoredTextured v = vertexList[i]; v.Color = SharpDX.Color.White; vertexList[i] = v; } } if ((g.geometryStruct.geometryFlags & GeometryFlags.hasTextCoords) != 0) { for (int i = 0; i < vertexList.Count; i++) { Vertex2 tc = g.geometryStruct.textCoords[i]; VertexColoredTextured v = vertexList[i]; v.TextureCoordinate = new Vector2(tc.X, tc.Y); vertexList[i] = v; } } List <SharpSubSet> SubsetList = new List <SharpSubSet>(); List <int> indexList = new List <int>(); int previousIndexCount = 0; for (int i = 0; i < MaterialList.Count; i++) { foreach (Triangle t in g.geometryStruct.triangles) { if (t.materialIndex == i) { indexList.Add(t.vertex1); indexList.Add(t.vertex2); indexList.Add(t.vertex3); triangleList.Add(new Triangle(t.materialIndex, (ushort)(t.vertex1 + triangleListOffset), (ushort)(t.vertex2 + triangleListOffset), (ushort)(t.vertex3 + triangleListOffset))); } } if (indexList.Count - previousIndexCount > 0) { SubsetList.Add(new SharpSubSet(previousIndexCount, indexList.Count - previousIndexCount, TextureManager.GetTextureFromDictionary(MaterialList[i]), MaterialList[i])); } previousIndexCount = indexList.Count(); } triangleListOffset += vertexList.Count; if (SubsetList.Count > 0) { meshList.Add(SharpMesh.Create(device, vertexList.ToArray(), indexList.ToArray(), SubsetList)); } }
private static void ExportGeometryToOBJ(StreamWriter writer, Geometry_000F g, ref List <Triangle> triangleList, ref int totalVertexIndices, ref int untexturedMaterials, bool flipUVs) { List <string> materialList = new List <string>(); foreach (Material_0007 m in g.materialList.materialList) { if (m.texture != null) { string textureName = m.texture.diffuseTextureName.stringString; //if (!MaterialList.Contains(textureName)) materialList.Add(textureName); } else { materialList.Add("default"); } } GeometryStruct_0001 gs = g.geometryStruct; if (gs.geometryFlags2 == (GeometryFlags2)0x0101) { GetNativeTriangleList(writer, g.geometryExtension, materialList, ref triangleList, ref totalVertexIndices, flipUVs); return; } if (g.materialList.materialList[0].materialStruct.isTextured != 0) { string mn = g.materialList.materialList[0].texture.diffuseTextureName.stringString; if (string.IsNullOrEmpty(lastMaterial) || lastMaterial != mn) { writer.WriteLine("g obj_" + mn); writer.WriteLine("usemtl " + mn + "_m"); } lastMaterial = mn; } else { writer.WriteLine("g obj_default_" + untexturedMaterials.ToString()); writer.WriteLine("usemtl default_" + untexturedMaterials.ToString() + "_m"); untexturedMaterials++; } writer.WriteLine(); foreach (MorphTarget m in gs.morphTargets) { if (m.hasVertices != 0) { foreach (Vertex3 v in m.vertices) { writer.WriteLine("v " + v.X.ToString() + " " + v.Y.ToString() + " " + v.Z.ToString()); } writer.WriteLine(); } if (m.hasNormals != 0) { foreach (Vertex3 vn in m.normals) { writer.WriteLine("vn " + vn.X.ToString() + " " + vn.Y.ToString() + " " + vn.Z.ToString()); } writer.WriteLine(); } if ((gs.geometryFlags & GeometryFlags.hasVertexColors) != 0) { foreach (Color c in gs.vertexColors) { writer.WriteLine("vc " + c.R.ToString() + " " + c.G.ToString() + " " + c.B.ToString() + " " + c.A.ToString()); } writer.WriteLine(); } if ((gs.geometryFlags & GeometryFlags.hasTextCoords) != 0) { foreach (Vertex2 tc in gs.textCoords) { writer.WriteLine("vt " + tc.X.ToString() + " " + tc.Y.ToString()); } writer.WriteLine(); } foreach (RenderWareFile.Triangle t in gs.triangles) { List <char> v1 = new List <char>(8); List <char> v2 = new List <char>(8); List <char> v3 = new List <char>(8); int n1 = t.vertex1 + totalVertexIndices; int n2 = t.vertex2 + totalVertexIndices; int n3 = t.vertex3 + totalVertexIndices; if (m.hasVertices != 0) { v1.AddRange(n1.ToString()); v2.AddRange(n2.ToString()); v3.AddRange(n3.ToString()); } if (((gs.geometryFlags & GeometryFlags.hasTextCoords) != 0) & (m.hasNormals != 0)) { v1.AddRange("/" + n1.ToString() + "/" + n1.ToString()); v2.AddRange("/" + n2.ToString() + "/" + n2.ToString()); v3.AddRange("/" + n3.ToString() + "/" + n3.ToString()); } else if ((gs.geometryFlags & GeometryFlags.hasTextCoords) != 0) { v1.AddRange("/" + n1.ToString()); v2.AddRange("/" + n2.ToString()); v3.AddRange("/" + n3.ToString()); } else if (m.hasNormals != 0) { v1.AddRange("//" + n1.ToString()); v2.AddRange("//" + n2.ToString()); v3.AddRange("//" + n3.ToString()); } writer.WriteLine("f " + new string(v1.ToArray()) + " " + new string(v2.ToArray()) + " " + new string(v3.ToArray())); } totalVertexIndices += m.vertices.Count(); writer.WriteLine(); } }