private void AddFace(Group curGroup, string[] line) { var fg = new FaceGroup(); curGroup.fg.Add(fg); for (var i = 1; i < line.Length; i++) { var x = line[i]; var arr = x.Split(new[] { "/" }, StringSplitOptions.None); var face = new Face(); switch (arr.Length) { case 1: face.v = Convert.ToInt32(arr[0]); break; case 2: face.v = Convert.ToInt32(arr[0]); face.t = arr[1] == ""?-1: Convert.ToInt32(arr[1]); break; case 3: face.v = Convert.ToInt32(arr[0]); face.t = arr[1] == ""?-1:Convert.ToInt32(arr[1]); face.n = arr[2] == ""?-1:Convert.ToInt32(arr[2]); break; default: throw new Exception("Face with too many values"); } fg.f.Add(face); } }
public Soil(FaceGroup geometry, int id, string code, Grid grid, string name) { ID = id; Geometry = geometry; Material = CreateMaterial(Material.DEFAULT_SOIL, code); Name = name ?? "SoilGroup"; SetMatrix(grid); }
public Source(FaceGroup geometry, int id, Grid grid, string name = " ") { ID = id; Geometry = geometry; Material = CreateMaterial(Material.DEFAULT_SOURCE); Name = name ?? "SourceGroup"; SetMatrix(grid); }
public Plant2d(FaceGroup geometry, int id, string code, Grid grid, string name) { ID = id; Geometry = geometry; Material = CreateMaterial(Material.DEFAULT_PLANT_2D, code); Name = name ?? "PlantGroup"; SetMatrix(grid); }
public Building(FaceGroup geometry, int id, Material material, Grid grid, string name = " ") { ID = id; Geometry = geometry; Material = material; Name = name; SetMatrix(grid); }
public Building(Grid grid, FaceGroup geometry, int id, Material material, string name) { ID = id; Geometry = geometry; Material = material ?? CreateMaterial(null, null, null, null); Name = name ?? "Building"; SetMatrix(grid); }
public Source(Grid grid, FaceGroup geometry, int id, string code, string name) { ID = id; Geometry = geometry; Material = (code != null) ? CreateMaterial(Material.DEFAULT_SOURCE, code) : CreateMaterial(Material.DEFAULT_SOURCE); Name = name ?? "SourceGroup"; SetMatrix(grid); }
public Building(FaceGroup geometry, int id, Grid grid, string name = " ") { ID = id; Geometry = geometry; Material = CreateMaterial(null, null, null, null); Name = name; SetMatrix(grid); }
public void AddTriangle(Vector3 v1, Vector3 v2, Vector3 v3, Vector2 uv1, Vector2 uv2, Vector2 uv3, Material m) { var a = v1 - v2; var b = v3 - v2; var norm = Vector3.Cross(a, b); norm.Normalize(); Normals.Add(norm); Normals.Add(norm); Normals.Add(norm); Positions.Add(v1); Positions.Add(v2); Positions.Add(v3); UV.Add(uv1); UV.Add(uv2); UV.Add(uv3); var facegroup = FaceGroups.Find(x => x.Material == m); if (facegroup != null) { if (facegroup.Indices == null) { facegroup.Indices = new List <int>(); } facegroup.Indices.Add(NetIndices.Count); NetIndices.Add(NetIndices.Count); facegroup.Indices.Add(NetIndices.Count); NetIndices.Add(NetIndices.Count); facegroup.Indices.Add(NetIndices.Count); NetIndices.Add(NetIndices.Count); facegroup.Material = m; } else { facegroup = new FaceGroup(); facegroup.Indices = new List <int>(); facegroup.Indices.Add(NetIndices.Count); NetIndices.Add(NetIndices.Count); facegroup.Indices.Add(NetIndices.Count); NetIndices.Add(NetIndices.Count); facegroup.Indices.Add(NetIndices.Count); NetIndices.Add(NetIndices.Count); facegroup.Material = m; FaceGroups.Add(facegroup); } }
public void CloneFace() { if (initFace == null) { Debug.Log("缺少初始化脸型"); return; } faceGroups.Clear(); FacePincher initFacePicher = initFace.GetComponent <FacePincher>(); foreach (FaceGroup faceGroup in initFacePicher.faceGroups) { // 初始化faceGroup数据 FaceGroup tempGroup = new FaceGroup(); faceGroups.Add(tempGroup); tempGroup.ResetData(tempGroup); foreach (FaceGroupPart faceGroupPart in faceGroup.faceGroupParts) { // 初始化faceGroupPart数据 FaceGroupPart tempFaceGroupPart = new FaceGroupPart(); tempGroup.faceGroupParts.Add(tempFaceGroupPart); tempFaceGroupPart.ResetData(faceGroupPart); foreach (FaceBone faceBone in faceGroupPart.faceBones) { // 初始化faceBone数据 FaceBone tempFaceBones = new FaceBone(); tempFaceGroupPart.faceBones.Add(tempFaceBones); string path = ""; Transform tempTrans = faceBone.bone; Transform root = faceBone.bone.root; while (tempTrans != root) { path = tempTrans.name + path; if (tempTrans.parent != root) { path = "/" + path; } tempTrans = tempTrans.parent; } Transform bone = transform.Find(path); tempFaceBones.ResetData(faceBone, bone, bone); } } } OnValidate(); }
LOD readLOD(BinaryReader reader) { LOD newLOD = new LOD(); newLOD.relativeDistance = reader.ReadSingle(); var vertexCount = reader.ReadUInt16(); newLOD.vertices = new List <Vertex>(); for (var i = 0; i < vertexCount; i++) { Vertex newVertex = new Vertex(); newVertex.pos = ReadVector3(reader); newVertex.normal = ReadVector3(reader); newVertex.uv = ReadVector2(reader); newLOD.vertices.Add(newVertex); } var faceGroupCount = reader.ReadByte(); newLOD.faceGroups = new List <FaceGroup>(); for (var i = 0; i < faceGroupCount; i++) { FaceGroup newFaceGroup = new FaceGroup(); newFaceGroup.faces = new List <Face>(); var faceCount = reader.ReadUInt16(); for (var j = 0; j < faceCount; j++) { Face newFace = new Face(); newFace.a = reader.ReadUInt16(); newFace.b = reader.ReadUInt16(); newFace.c = reader.ReadUInt16(); newFaceGroup.faces.Add(newFace); } newFaceGroup.materialID = reader.ReadUInt16(); newLOD.faceGroups.Add(newFaceGroup); } return(newLOD); }
public static List <Ray> GetRayFromFacegroup(Grid grid, FaceGroup facegroup) { MorphoGeometry.BoundaryBox box = new MorphoGeometry.BoundaryBox(facegroup); Vector minPt = box.MinPoint; Vector maxPt = box.MaxPoint; var rayXcomponent = Util.FilterByMinMax(grid.Xaxis, maxPt.x, minPt.x); var rayYcomponent = Util.FilterByMinMax(grid.Yaxis, maxPt.y, minPt.y); List <Ray> rays = new List <Ray>(); foreach (double y in rayYcomponent) { foreach (double x in rayXcomponent) { rays.Add(new Ray(new Vector((float)x, (float)y, 0), new Vector(0, 0, 1))); } } return(rays); }
private static Mesh Convert(FaceGroup group, IEnumerable <Face> faces, IEnumerable <Vertex> vertices) { return(Convert(faces.Skip(group.StartFace).Take(1 + group.EndFace - group.StartFace), vertices)); }
public static IEnumerable <Vector> Raycasting(List <Ray> rays, FaceGroup facegroup, bool reverse = false, bool project = false) { return(Intersection.RaysFaceGroupIntersect(rays, facegroup, reverse, project)); }
private static Mesh Convert(FaceGroup group, ICollection <Face> faces, ICollection <Vertex> vertices) { int numFaces = 1 + group.EndFace - group.StartFace; return(Convert(faces.Skip(group.StartFace).Take(numFaces), numFaces, vertices, vertices.Count)); }
/// <summary> /// Reads a model from a Wavefront OBJ (.obj) model file. /// </summary> /// <param name="path">File path to the file to parse</param> /// <returns>Model parsed from the specified file</returns> public static Model FromFile(String path) { int vertCount = 0, txuvCount = 0, normCount = 0, faceCount = 0; var vertGroups = new List<FaceGroup>(); FaceGroup lastGroup = null; // Read all lines from the file and store them as a string array var lines = File.ReadAllLines(path); // Loop through each line in the array, counting how many vertices, // normals, texture UV coordinates, and faces there are. Also, find // the start indices and lengths of any face groups. foreach (var line in lines) { // If the line specifies the start of a face group... if (_sREObjc.IsMatch(line)) { // If this isn't the first group in the file... if (lastGroup != null) { // Update the last group to record that the group // ended at the last face read lastGroup.Length = faceCount - lastGroup.StartIndex; } // Start a new face group with the name given by this line, and // with the start index being that of the next face read lastGroup = new FaceGroup(line.Substring(line.IndexOf(' ') + 1)) { StartIndex = faceCount }; // Add the face group to the list of groups in this file vertGroups.Add(lastGroup); continue; } // If the line specifies a vertex position, increment the vertex count if (_sREVert.IsMatch(line)) { ++vertCount; continue; } // If the line specifies a texture coordinate, increment the UV count if (_sRETxUV.IsMatch(line)) { ++txuvCount; continue; } // If the line specifies a vertex normal, increment the normal count if (_sRENorm.IsMatch(line)) { ++normCount; continue; } // If the line specifies a face, increment the face count if (_sREFace.IsMatch(line)) { ++faceCount; continue; } } // If there is a face group that has not been completed... if (lastGroup != null) { // Update the last group to record that the group // ended at the last face read lastGroup.Length = faceCount - lastGroup.StartIndex; } // Set up the arrays for vertex positions, UV coordinates, normals, and faces var verts = new Vector3[vertCount]; int vi = 0; var txuvs = new Vector2[txuvCount]; int ti = 0; var norms = new Vector3[normCount]; int ni = 0; var faces = new Face[faceCount]; int fi = 0; // Create a model instance with these arrays, which will be populated after var model = new Model(vertGroups.ToArray(), verts, txuvs, norms, faces); // Loop through each line again, but this time actually parsing vertex values foreach (var line in lines) { // Chop off the identifier token from the start of the string var data = line.Substring(line.IndexOf(' ') + 1); // If the line is a vertex position, parse it and store it if (_sREVert.IsMatch(line)) { verts[vi++] = ParseVector3(data); continue; } // If the line is a texture UV coordinate, parse it and store it if (_sRETxUV.IsMatch(line)) { txuvs[ti++] = ParseVector2(data); continue; } // If the line is a vertex normal, parse it and store it if (_sRENorm.IsMatch(line)) { norms[ni++] = ParseVector3(data); continue; } // If the line is a face, parse its indices and store it if (_sREFace.IsMatch(line)) { faces[fi++] = Face.Parse(data); continue; } } // Update the model's VBO with the newly parsed data, then return it model.UpdateVertices(); return model; }
public void ResetData(FaceGroup initFaceGroup) { name = initFaceGroup.name; }
public static OptFile RhinoToOpt(string rhinoPath, bool scale) { string rhinoDirectory = Path.GetDirectoryName(rhinoPath); var opt = new OptFile(); using (var file = Rhino.FileIO.File3dm.Read(rhinoPath)) { float scaleFactor = scale ? (1.0f / OptFile.ScaleFactor) : 1.0f; if (file.Settings.ModelUnitSystem != Rhino.UnitSystem.Meters) { scaleFactor *= (float)Rhino.RhinoMath.UnitScale(file.Settings.ModelUnitSystem, Rhino.UnitSystem.Meters); scale = true; } var groups = file.Objects .Where(t => { using (var geometry = t.Geometry) { return(geometry.ObjectType == Rhino.DocObjects.ObjectType.Mesh); } }) .GroupBy(t => { using (var attributes = t.Attributes) { return(attributes.LayerIndex); } }) .ToList(); foreach (var group in groups) { var mesh = new Mesh(); opt.Meshes.Add(mesh); var lod = new MeshLod(); mesh.Lods.Add(lod); foreach (var obj in group) { var faceGroup = new FaceGroup(); lod.FaceGroups.Add(faceGroup); int baseIndex = mesh.Vertices.Count; using (var geometry = (Rhino.Geometry.Mesh)obj.Geometry) { if (scale) { foreach (var vertex in geometry.Vertices) { mesh.Vertices.Add(new Vector(vertex.X * scaleFactor, vertex.Y * scaleFactor, vertex.Z * scaleFactor)); } } else { foreach (var vertex in geometry.Vertices) { mesh.Vertices.Add(new Vector(vertex.X, vertex.Y, vertex.Z)); } } foreach (var texCoords in geometry.TextureCoordinates) { mesh.TextureCoordinates.Add(new TextureCoordinates(texCoords.X, -texCoords.Y)); } foreach (var normal in geometry.Normals) { mesh.VertexNormals.Add(new Vector(normal.X, normal.Y, normal.Z)); } foreach (var geoFace in geometry.Faces) { var face = new Face(); faceGroup.Faces.Add(face); Index index = geoFace.IsTriangle ? new Index(baseIndex + geoFace.C, baseIndex + geoFace.B, baseIndex + geoFace.A) : new Index(baseIndex + geoFace.D, baseIndex + geoFace.C, baseIndex + geoFace.B, baseIndex + geoFace.A); face.VerticesIndex = index; face.VertexNormalsIndex = index; face.TextureCoordinatesIndex = index; face.Normal = Vector.Normal(mesh.Vertices[index.A], mesh.Vertices[index.B], mesh.Vertices[index.C]); } } using (var attributes = obj.Attributes) { if (attributes.MaterialIndex != -1) { using (var material = file.Materials[attributes.MaterialIndex]) { faceGroup.Textures.Add(material.Name); } } } } } opt.CompactBuffers(); opt.ComputeHitzones(); for (int materialIndex = 0; materialIndex < file.Materials.Count; materialIndex++) { using (var material = file.Materials[materialIndex]) { if (opt.Textures.ContainsKey(material.Name)) { continue; } string colorMap = null; string alphaMap = null; using (var tex = material.GetBitmapTexture()) { if (tex != null && !string.IsNullOrEmpty(tex.FileName)) { colorMap = Path.GetFileName(tex.FileName); } } using (var tex = material.GetTransparencyTexture()) { if (tex != null && !string.IsNullOrEmpty(tex.FileName)) { alphaMap = Path.GetFileName(tex.FileName); } } Texture texture; if (colorMap == null) { var color = material.DiffuseColor; byte r = color.R; byte g = color.G; byte b = color.B; int width = 8; int height = 8; int length = width * height; byte[] data = new byte[length * 4]; for (int i = 0; i < length; i++) { data[i * 4 + 0] = b; data[i * 4 + 1] = g; data[i * 4 + 2] = r; data[i * 4 + 3] = 255; } texture = new Texture(); texture.Name = material.Name; texture.Width = width; texture.Height = height; texture.ImageData = data; } else { string colorFileName = Path.Combine(rhinoDirectory, colorMap); texture = Texture.FromFile(colorFileName); texture.Name = material.Name; } if (alphaMap != null) { string alphaFileName = Path.Combine(rhinoDirectory, alphaMap); texture.SetAlphaMap(alphaFileName); } else if (material.Transparency > 0.0 && material.Transparency < 1.0) { byte alpha = (byte)(material.Transparency * 255.0f); int length = texture.Width * texture.Height; byte[] alphaData = new byte[length]; var data = texture.ImageData; for (int i = 0; i < length; i++) { alphaData[i] = alpha; data[i * 4 + 3] = alpha; } texture.AlphaData = alphaData; } opt.Textures.Add(texture.Name, texture); } } opt.GenerateTexturesMipmaps(); } return(opt); }
/// <summary> /// Reads a model from a Wavefront OBJ (.obj) model file. /// </summary> /// <param name="path">File path to the file to parse</param> /// <returns>Model parsed from the specified file</returns> public static Model FromFile(String path) { int vertCount = 0, txuvCount = 0, normCount = 0, faceCount = 0; var vertGroups = new List <FaceGroup>(); FaceGroup lastGroup = null; // Read all lines from the file and store them as a string array var lines = File.ReadAllLines(path); // Loop through each line in the array, counting how many vertices, // normals, texture UV coordinates, and faces there are. Also, find // the start indices and lengths of any face groups. foreach (var line in lines) { // If the line specifies the start of a face group... if (_sREObjc.IsMatch(line)) { // If this isn't the first group in the file... if (lastGroup != null) { // Update the last group to record that the group // ended at the last face read lastGroup.Length = faceCount - lastGroup.StartIndex; } // Start a new face group with the name given by this line, and // with the start index being that of the next face read lastGroup = new FaceGroup(line.Substring(line.IndexOf(' ') + 1)) { StartIndex = faceCount }; // Add the face group to the list of groups in this file vertGroups.Add(lastGroup); continue; } // If the line specifies a vertex position, increment the vertex count if (_sREVert.IsMatch(line)) { ++vertCount; continue; } // If the line specifies a texture coordinate, increment the UV count if (_sRETxUV.IsMatch(line)) { ++txuvCount; continue; } // If the line specifies a vertex normal, increment the normal count if (_sRENorm.IsMatch(line)) { ++normCount; continue; } // If the line specifies a face, increment the face count if (_sREFace.IsMatch(line)) { ++faceCount; continue; } } // If there is a face group that has not been completed... if (lastGroup != null) { // Update the last group to record that the group // ended at the last face read lastGroup.Length = faceCount - lastGroup.StartIndex; } // Set up the arrays for vertex positions, UV coordinates, normals, and faces var verts = new Vector3[vertCount]; int vi = 0; var txuvs = new Vector2[txuvCount]; int ti = 0; var norms = new Vector3[normCount]; int ni = 0; var faces = new Face[faceCount]; int fi = 0; // Create a model instance with these arrays, which will be populated after var model = new Model(vertGroups.ToArray(), verts, txuvs, norms, faces); // Loop through each line again, but this time actually parsing vertex values foreach (var line in lines) { // Chop off the identifier token from the start of the string var data = line.Substring(line.IndexOf(' ') + 1); // If the line is a vertex position, parse it and store it if (_sREVert.IsMatch(line)) { verts[vi++] = ParseVector3(data); continue; } // If the line is a texture UV coordinate, parse it and store it if (_sRETxUV.IsMatch(line)) { txuvs[ti++] = ParseVector2(data); continue; } // If the line is a vertex normal, parse it and store it if (_sRENorm.IsMatch(line)) { norms[ni++] = ParseVector3(data); continue; } // If the line is a face, parse its indices and store it if (_sREFace.IsMatch(line)) { faces[fi++] = Face.Parse(data); continue; } } // Update the model's VBO with the newly parsed data, then return it model.UpdateVertices(); return(model); }
public static OptFile An8ToOpt(string an8Path, bool scale) { string an8Directory = Path.GetDirectoryName(an8Path); var an8 = An8File.FromFile(an8Path); var opt = new OptFile(); foreach (var mesh in an8.Objects .SelectMany(t => t.Components) .SelectMany(t => Converter.EnumMeshes(t))) { var optMesh = new Mesh(); opt.Meshes.Add(optMesh); if (scale) { foreach (var v in mesh.Points) { optMesh.Vertices.Add(new Vector(v.X / OptFile.ScaleFactor, v.Z / OptFile.ScaleFactor, v.Y / OptFile.ScaleFactor)); } } else { foreach (var v in mesh.Points) { optMesh.Vertices.Add(new Vector(v.X, v.Z, v.Y)); } } foreach (var v in mesh.TexCoords) { optMesh.TextureCoordinates.Add(new TextureCoordinates(v.U, -v.V)); } foreach (var v in mesh.Normals) { optMesh.VertexNormals.Add(new Vector(v.X, v.Z, v.Y)); } optMesh.TextureCoordinates.Add(new TextureCoordinates(0, 0)); optMesh.TextureCoordinates.Add(new TextureCoordinates(1, 0)); optMesh.TextureCoordinates.Add(new TextureCoordinates(1, 1)); optMesh.TextureCoordinates.Add(new TextureCoordinates(0, 1)); var optLod = new MeshLod(); optMesh.Lods.Add(optLod); foreach (var face in mesh.Faces) { if (face.PointIndexes.Length < 3) { continue; } bool isQuad = face.PointIndexes.Length > 3; var optFaceGroup = new FaceGroup(); optLod.FaceGroups.Add(optFaceGroup); var materialName = mesh.MaterialList.ElementAtOrDefault(face.MaterialIndex); if (!string.IsNullOrEmpty(materialName)) { optFaceGroup.Textures.Add(materialName); } Index verticesIndex = new Index( face.PointIndexes[0], face.PointIndexes[1], face.PointIndexes[2], isQuad ? face.PointIndexes[3] : -1); if (verticesIndex.A >= optMesh.Vertices.Count) { verticesIndex.A = 0; } if (verticesIndex.B >= optMesh.Vertices.Count) { verticesIndex.B = 0; } if (verticesIndex.C >= optMesh.Vertices.Count) { verticesIndex.C = 0; } if (verticesIndex.D >= optMesh.Vertices.Count) { verticesIndex.D = 0; } Index textureCoordinatesIndex = new Index( face.TexCoordIndexes[0], face.TexCoordIndexes[1], face.TexCoordIndexes[2], isQuad ? face.TexCoordIndexes[3] : -1); if (textureCoordinatesIndex.A >= optMesh.TextureCoordinates.Count) { textureCoordinatesIndex.A = 0; } if (textureCoordinatesIndex.B >= optMesh.TextureCoordinates.Count) { textureCoordinatesIndex.B = 0; } if (textureCoordinatesIndex.C >= optMesh.TextureCoordinates.Count) { textureCoordinatesIndex.C = 0; } if (textureCoordinatesIndex.D >= optMesh.TextureCoordinates.Count) { textureCoordinatesIndex.D = 0; } Index vertexNormalsIndex = new Index( face.NormalIndexes[0], face.NormalIndexes[1], face.NormalIndexes[2], isQuad ? face.NormalIndexes[3] : -1); if (vertexNormalsIndex.A >= optMesh.VertexNormals.Count) { vertexNormalsIndex.A = 0; } if (vertexNormalsIndex.B >= optMesh.VertexNormals.Count) { vertexNormalsIndex.B = 0; } if (vertexNormalsIndex.C >= optMesh.VertexNormals.Count) { vertexNormalsIndex.C = 0; } if (vertexNormalsIndex.D >= optMesh.VertexNormals.Count) { vertexNormalsIndex.D = 0; } if (textureCoordinatesIndex.A < 0 || textureCoordinatesIndex.B < 0 || textureCoordinatesIndex.C < 0 || (verticesIndex.D >= 0 && textureCoordinatesIndex.D < 0)) { textureCoordinatesIndex.A = optMesh.TextureCoordinates.Count - 4; textureCoordinatesIndex.B = optMesh.TextureCoordinates.Count - 3; textureCoordinatesIndex.C = optMesh.TextureCoordinates.Count - 2; textureCoordinatesIndex.D = verticesIndex.D < 0 ? -1 : optMesh.TextureCoordinates.Count - 1; } Vector normal = Vector.Normal( optMesh.Vertices.ElementAtOrDefault(verticesIndex.A), optMesh.Vertices.ElementAtOrDefault(verticesIndex.B), optMesh.Vertices.ElementAtOrDefault(verticesIndex.C)); if (vertexNormalsIndex.A < 0 || vertexNormalsIndex.B < 0 || vertexNormalsIndex.C < 0 || (verticesIndex.D >= 0 && vertexNormalsIndex.D < 0)) { optMesh.VertexNormals.Add(normal); vertexNormalsIndex.A = optMesh.VertexNormals.Count - 1; vertexNormalsIndex.B = optMesh.VertexNormals.Count - 1; vertexNormalsIndex.C = optMesh.VertexNormals.Count - 1; vertexNormalsIndex.D = verticesIndex.D < 0 ? -1 : optMesh.VertexNormals.Count - 1; } var optFace = new Face() { VerticesIndex = verticesIndex, TextureCoordinatesIndex = textureCoordinatesIndex, VertexNormalsIndex = vertexNormalsIndex, Normal = normal }; optFaceGroup.Faces.Add(optFace); } } opt.CompactBuffers(); opt.ComputeHitzones(); foreach (var material in an8.Materials .Concat(an8.Objects.SelectMany(t => t.Materials)) .Where(t => t.FrontSurface != null) .Select(t => new { Name = t.Name, Diffuse = t.FrontSurface.Diffuse, Alpha = t.FrontSurface.Alpha })) { Texture texture; var an8Texture = material.Diffuse.TextureName != null? an8.Textures.FirstOrDefault(t => string.Equals(t.Name, material.Diffuse.TextureName, StringComparison.Ordinal)) : null; if (an8Texture == null) { byte r = material.Diffuse.Red; byte g = material.Diffuse.Green; byte b = material.Diffuse.Blue; int width = 8; int height = 8; int length = width * height; byte[] data = new byte[length * 4]; for (int i = 0; i < length; i++) { data[i * 4 + 0] = b; data[i * 4 + 1] = g; data[i * 4 + 2] = r; data[i * 4 + 3] = 255; } texture = new Texture(); texture.Name = material.Name; texture.Width = width; texture.Height = height; texture.ImageData = data; } else { string colorFileName = Path.Combine(an8Directory, Path.GetFileName(an8Texture.Files[0])); texture = Texture.FromFile(colorFileName); texture.Name = material.Name; } if (material.Alpha > 0 && material.Alpha < 255) { byte alpha = (byte)material.Alpha; int length = texture.Width * texture.Height; byte[] alphaData = new byte[length]; var data = texture.ImageData; for (int i = 0; i < length; i++) { alphaData[i] = alpha; data[i * 4 + 3] = alpha; } texture.AlphaData = alphaData; } opt.Textures.Add(texture.Name, texture); } opt.GenerateTexturesMipmaps(); return(opt); }
public static OptFile ObjToOpt(string objPath, bool scale) { string objDirectory = Path.GetDirectoryName(objPath); var obj = ObjFile.FromFile(objPath); var opt = new OptFile(); foreach (var mesh in obj.Meshes) { var optMesh = new Mesh(); opt.Meshes.Add(optMesh); if (scale) { foreach (var v in obj.Vertices) { optMesh.Vertices.Add(new Vector(v.X / OptFile.ScaleFactor, v.Z / OptFile.ScaleFactor, v.Y / OptFile.ScaleFactor)); } } else { foreach (var v in obj.Vertices) { optMesh.Vertices.Add(new Vector(v.X, v.Z, v.Y)); } } foreach (var v in obj.VertexTexCoords) { optMesh.TextureCoordinates.Add(new TextureCoordinates(v.U, -v.V)); } foreach (var v in obj.VertexNormals) { optMesh.VertexNormals.Add(new Vector(v.X, v.Z, v.Y)); } optMesh.TextureCoordinates.Add(new TextureCoordinates(0, 0)); optMesh.TextureCoordinates.Add(new TextureCoordinates(1, 0)); optMesh.TextureCoordinates.Add(new TextureCoordinates(1, 1)); optMesh.TextureCoordinates.Add(new TextureCoordinates(0, 1)); var optLod = new MeshLod(); optMesh.Lods.Add(optLod); foreach (var faceGroup in mesh.FaceGroups) { var optFaceGroup = new FaceGroup(); optLod.FaceGroups.Add(optFaceGroup); if (!string.IsNullOrEmpty(faceGroup.MaterialName)) { optFaceGroup.Textures.Add(faceGroup.MaterialName); } foreach (var face in faceGroup.Faces) { Index verticesIndex = new Index( face.VerticesIndex.A, face.VerticesIndex.B, face.VerticesIndex.C, face.VerticesIndex.D); if (verticesIndex.A >= optMesh.Vertices.Count) { verticesIndex.A = 0; } if (verticesIndex.B >= optMesh.Vertices.Count) { verticesIndex.B = 0; } if (verticesIndex.C >= optMesh.Vertices.Count) { verticesIndex.C = 0; } if (verticesIndex.D >= optMesh.Vertices.Count) { verticesIndex.D = 0; } Index textureCoordinatesIndex = new Index( face.VertexTexCoordsIndex.A, face.VertexTexCoordsIndex.B, face.VertexTexCoordsIndex.C, face.VertexTexCoordsIndex.D); if (textureCoordinatesIndex.A >= optMesh.TextureCoordinates.Count) { textureCoordinatesIndex.A = 0; } if (textureCoordinatesIndex.B >= optMesh.TextureCoordinates.Count) { textureCoordinatesIndex.B = 0; } if (textureCoordinatesIndex.C >= optMesh.TextureCoordinates.Count) { textureCoordinatesIndex.C = 0; } if (textureCoordinatesIndex.D >= optMesh.TextureCoordinates.Count) { textureCoordinatesIndex.D = 0; } Index vertexNormalsIndex = new Index( face.VertexNormalsIndex.A, face.VertexNormalsIndex.B, face.VertexNormalsIndex.C, face.VertexNormalsIndex.D); if (vertexNormalsIndex.A >= optMesh.VertexNormals.Count) { vertexNormalsIndex.A = 0; } if (vertexNormalsIndex.B >= optMesh.VertexNormals.Count) { vertexNormalsIndex.B = 0; } if (vertexNormalsIndex.C >= optMesh.VertexNormals.Count) { vertexNormalsIndex.C = 0; } if (vertexNormalsIndex.D >= optMesh.VertexNormals.Count) { vertexNormalsIndex.D = 0; } if (textureCoordinatesIndex.A < 0 || textureCoordinatesIndex.B < 0 || textureCoordinatesIndex.C < 0 || (verticesIndex.D >= 0 && textureCoordinatesIndex.D < 0)) { textureCoordinatesIndex.A = optMesh.TextureCoordinates.Count - 4; textureCoordinatesIndex.B = optMesh.TextureCoordinates.Count - 3; textureCoordinatesIndex.C = optMesh.TextureCoordinates.Count - 2; textureCoordinatesIndex.D = verticesIndex.D < 0 ? -1 : optMesh.TextureCoordinates.Count - 1; } Vector normal = Vector.Normal( optMesh.Vertices.ElementAtOrDefault(verticesIndex.A), optMesh.Vertices.ElementAtOrDefault(verticesIndex.B), optMesh.Vertices.ElementAtOrDefault(verticesIndex.C)); if (vertexNormalsIndex.A < 0 || vertexNormalsIndex.B < 0 || vertexNormalsIndex.C < 0 || (verticesIndex.D >= 0 && vertexNormalsIndex.D < 0)) { optMesh.VertexNormals.Add(normal); vertexNormalsIndex.A = optMesh.VertexNormals.Count - 1; vertexNormalsIndex.B = optMesh.VertexNormals.Count - 1; vertexNormalsIndex.C = optMesh.VertexNormals.Count - 1; vertexNormalsIndex.D = verticesIndex.D < 0 ? -1 : optMesh.VertexNormals.Count - 1; } var optFace = new Face() { VerticesIndex = verticesIndex, TextureCoordinatesIndex = textureCoordinatesIndex, VertexNormalsIndex = vertexNormalsIndex, Normal = normal }; optFaceGroup.Faces.Add(optFace); } } } opt.CompactBuffers(); opt.ComputeHitzones(); foreach (var material in obj.Materials.Values) { Texture texture; if (material.DiffuseMapFileName == null) { var color = material.DiffuseColor; byte r = (byte)(color.X * 255.0f); byte g = (byte)(color.Y * 255.0f); byte b = (byte)(color.Z * 255.0f); int width = 8; int height = 8; int length = width * height; byte[] data = new byte[length * 4]; for (int i = 0; i < length; i++) { data[i * 4 + 0] = b; data[i * 4 + 1] = g; data[i * 4 + 2] = r; data[i * 4 + 3] = 255; } texture = new Texture(); texture.Name = material.Name; texture.Width = width; texture.Height = height; texture.ImageData = data; } else { string colorFileName = Path.Combine(objDirectory, material.DiffuseMapFileName); texture = Texture.FromFile(colorFileName); texture.Name = material.Name; } if (material.AlphaMapFileName != null) { string alphaFileName = Path.Combine(objDirectory, material.AlphaMapFileName); texture.SetAlphaMap(alphaFileName); } else if (material.DissolveFactor > 0.0f && material.DissolveFactor < 1.0f) { byte alpha = (byte)(material.DissolveFactor * 255.0f); int length = texture.Width * texture.Height; byte[] alphaData = new byte[length]; var data = texture.ImageData; for (int i = 0; i < length; i++) { alphaData[i] = alpha; data[i * 4 + 3] = alpha; } texture.AlphaData = alphaData; } opt.Textures.Add(texture.Name, texture); } opt.GenerateTexturesMipmaps(); return(opt); }
internal MeshLodFace(Mesh mesh, MeshLod lod, FaceGroup face) { this.Mesh = mesh; this.Lod = lod; this.Face = face; }
/// <summary> /// Private constructor to create a new instance of Model. /// </summary> /// <param name="faceGroups">Array of face groups within the model</param> /// <param name="verts">Array of vertex positions</param> /// <param name="txuvs">Array of texture UV coordinates</param> /// <param name="norms">Array of vertex normals</param> /// <param name="faces">Array of faces within the model</param> private Model(FaceGroup[] faceGroups, Vector3[] verts, Vector2[] txuvs, Vector3[] norms, Face[] faces) { FaceGroups = faceGroups; _verts = verts; _txuvs = txuvs; _norms = norms; _faces = faces; // Create a vertex buffer to store the vertex data, with a stride // of 8 (position:3 + uv:2 + normal:3) _vb = new VertexBuffer(8); }