public void CompactFaceGroups() { var groups = new List <FaceGroup>(this.FaceGroups.Count); foreach (var faceGroup in this.FaceGroups) { FaceGroup index = null; foreach (var group in groups) { if (group.Textures.Count != faceGroup.Textures.Count) { continue; } if (group.Textures.Count == 0) { index = group; break; } int t = 0; for (; t < group.Textures.Count; t++) { if (group.Textures[t] != faceGroup.Textures[t]) { break; } } if (t == group.Textures.Count) { index = group; break; } } if (index == null) { groups.Add(faceGroup); } else { foreach (var face in faceGroup.Faces) { index.Faces.Add(face); } } } groups.TrimExcess(); this.FaceGroups = groups; foreach (var faceGroup in this.FaceGroups) { faceGroup.ComputeEdges(); } }
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 FromFile(string path) { OptFile opt = new OptFile(); opt.FileName = path; OptFileNodes optNodes = OptFileNodes.FromFile(path); List<string> globalTexture = null; for (int meshId = 0; meshId < optNodes.Nodes.Count; meshId++) { if (meshId == 0 && optNodes.Nodes[meshId].NodeType == NodeType.Texture) { TextureNode textureNode = (TextureNode)optNodes.Nodes[meshId]; opt.CreateTexture(textureNode); globalTexture = new List<string>() { textureNode.Name }; continue; } if (optNodes.Nodes[meshId].NodeType != NodeType.NodeGroup) { throw new InvalidDataException("invalid mesh"); } NodeGroupNode meshNode = (NodeGroupNode)optNodes.Nodes[meshId]; var meshNodes = meshNode.Nodes.Union((meshNode.Nodes.Where(t => t.NodeType == NodeType.NodeGroup).FirstOrDefault() ?? new NodeGroupNode()).Nodes).ToList(); RotationScaleNode rotationScaleNode = (RotationScaleNode)meshNodes.FirstOrDefault(t => t.NodeType == NodeType.RotationScale); MeshDescriptorNode descriptorNode = (MeshDescriptorNode)meshNodes.FirstOrDefault(t => t.NodeType == NodeType.MeshDescriptor); MeshVerticesNode verticesNode = (MeshVerticesNode)meshNodes.First(t => t.NodeType == NodeType.MeshVertices); TextureCoordinatesNode textureVerticesNode = (TextureCoordinatesNode)meshNodes.First(t => t.NodeType == NodeType.TextureCoordinates); VertexNormalsNode vertexNormalsNode = (VertexNormalsNode)meshNodes.First(t => t.NodeType == NodeType.VertexNormals); var hardpointsNodes = meshNodes.Where(t => t.NodeType == NodeType.Hardpoint).Select(t => (HardpointNode)t).ToList(); var engineGlowsNodes = meshNodes.Where(t => t.NodeType == NodeType.EngineGlow).Select(t => (EngineGlowNode)t).ToList(); FaceGroupingNode faceGroupingNode = (FaceGroupingNode)meshNodes.First(t => t.NodeType == NodeType.FaceGrouping); Mesh mesh = new Mesh(); if (rotationScaleNode != null) { mesh.RotationScale.Pivot = rotationScaleNode.Pivot; mesh.RotationScale.Look = rotationScaleNode.Look; mesh.RotationScale.Up = rotationScaleNode.Up; mesh.RotationScale.Right = rotationScaleNode.Right; } if (descriptorNode != null) { mesh.Descriptor.MeshType = descriptorNode.MeshType; mesh.Descriptor.ExplosionType = descriptorNode.ExplosionType; mesh.Descriptor.Span = descriptorNode.Span; mesh.Descriptor.Center = descriptorNode.Center; mesh.Descriptor.Min = descriptorNode.Min; mesh.Descriptor.Max = descriptorNode.Max; mesh.Descriptor.TargetId = descriptorNode.TargetId; mesh.Descriptor.Target = descriptorNode.Target; } foreach (Vector vertex in verticesNode.Vertices) { mesh.Vertices.Add(vertex); } foreach (TextureCoordinates textureVertex in textureVerticesNode.TextureVertices) { mesh.TextureCoordinates.Add(textureVertex); } foreach (Vector normal in vertexNormalsNode.Normals) { mesh.VertexNormals.Add(normal); } foreach (var hardpoint in hardpointsNodes) { mesh.Hardpoints.Add(new Hardpoint() { HardpointType = hardpoint.HardpointType, Position = hardpoint.Position }); } foreach (var engineGlow in engineGlowsNodes) { mesh.EngineGlows.Add(new EngineGlow() { IsDisabled = engineGlow.IsDisabled, CoreColor = engineGlow.CoreColor, OuterColor = engineGlow.OuterColor, Position = engineGlow.Position, Format = engineGlow.Format, Look = engineGlow.Look, Up = engineGlow.Up, Right = engineGlow.Right }); } if (faceGroupingNode.Distances.Count != faceGroupingNode.Nodes.Count) { throw new InvalidDataException("invalid face groups count in face grouping"); } for (int lodId = 0; lodId < faceGroupingNode.Distances.Count; lodId++) { List<string> texture = globalTexture; MeshLod lod = new MeshLod(); lod.Distance = faceGroupingNode.Distances[lodId]; foreach (Node node in faceGroupingNode.Nodes[lodId].Nodes) { switch (node.NodeType) { case NodeType.Texture: { TextureNode textureNode = (TextureNode)node; opt.CreateTexture(textureNode); texture = new List<string>() { textureNode.Name }; break; } case NodeType.NodeReference: texture = new List<string>() { ((NodeReferenceNode)node).Reference }; break; case NodeType.NodeSwitch: { NodeSwitchNode switchNode = (NodeSwitchNode)node; texture = new List<string>(); foreach (Node nodeSwitch in switchNode.Nodes) { switch (nodeSwitch.NodeType) { case NodeType.Texture: { TextureNode textureNode = (TextureNode)nodeSwitch; opt.CreateTexture(textureNode); texture.Add(textureNode.Name); break; } case NodeType.NodeReference: texture.Add(((NodeReferenceNode)nodeSwitch).Reference); break; } } break; } case NodeType.FaceData: { FaceDataNode faceDataNode = (FaceDataNode)node; FaceGroup faceGroup = new FaceGroup(); if (texture != null) { foreach (var name in texture) { faceGroup.Textures.Add(name); } } foreach (var face in faceDataNode.Faces) { faceGroup.Faces.Add(new Face() { VerticesIndex = face.VerticesIndex, EdgesIndex = face.EdgesIndex, TextureCoordinatesIndex = face.TextureCoordinatesIndex, VertexNormalsIndex = face.VertexNormalsIndex, Normal = face.Normal, TexturingDirection = face.TexturingDirection, TexturingMagniture = face.TexturingMagniture }); } foreach (var face in faceGroup.Faces) { if (face.VertexNormalsIndex.A >= mesh.VertexNormals.Count) { face.VertexNormalsIndex = face.VertexNormalsIndex.SetA(0); } if (face.VertexNormalsIndex.B >= mesh.VertexNormals.Count) { face.VertexNormalsIndex = face.VertexNormalsIndex.SetB(0); } if (face.VertexNormalsIndex.C >= mesh.VertexNormals.Count) { face.VertexNormalsIndex = face.VertexNormalsIndex.SetC(0); } if (face.VertexNormalsIndex.D >= mesh.VertexNormals.Count) { face.VertexNormalsIndex = face.VertexNormalsIndex.SetD(0); } if (face.TextureCoordinatesIndex.A >= mesh.TextureCoordinates.Count) { face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetA(0); } if (face.TextureCoordinatesIndex.B >= mesh.TextureCoordinates.Count) { face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetB(0); } if (face.TextureCoordinatesIndex.C >= mesh.TextureCoordinates.Count) { face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetC(0); } if (face.TextureCoordinatesIndex.D >= mesh.TextureCoordinates.Count) { face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetD(0); } if (face.VerticesIndex.A >= 0 && face.TextureCoordinatesIndex.A < 0) { face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetA(0); } if (face.VerticesIndex.B >= 0 && face.TextureCoordinatesIndex.B < 0) { face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetB(0); } if (face.VerticesIndex.C >= 0 && face.TextureCoordinatesIndex.C < 0) { face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetC(0); } if (face.VerticesIndex.D >= 0 && face.TextureCoordinatesIndex.D < 0) { face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetD(0); } } lod.FaceGroups.Add(faceGroup); texture = null; break; } } } mesh.Lods.Add(lod); } opt.Meshes.Add(mesh); } opt.SetFaceGroupTextureWhenEmpty(); 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; }
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; }
public Mesh Duplicate() { var newMesh = new Mesh(); foreach (var vertex in this.Vertices) { newMesh.Vertices.Add(vertex); } foreach (var textureCoordinate in this.TextureCoordinates) { newMesh.TextureCoordinates.Add(textureCoordinate); } foreach (var vertexNormal in this.VertexNormals) { newMesh.VertexNormals.Add(vertexNormal); } newMesh.Descriptor.MeshType = this.Descriptor.MeshType; newMesh.Descriptor.ExplosionType = this.Descriptor.ExplosionType; newMesh.Descriptor.Span = this.Descriptor.Span; newMesh.Descriptor.Center = this.Descriptor.Center; newMesh.Descriptor.Min = this.Descriptor.Min; newMesh.Descriptor.Max = this.Descriptor.Max; newMesh.Descriptor.TargetId = this.Descriptor.TargetId; newMesh.Descriptor.Target = this.Descriptor.Target; newMesh.RotationScale.Pivot = this.RotationScale.Pivot; newMesh.RotationScale.Look = this.RotationScale.Look; newMesh.RotationScale.Up = this.RotationScale.Up; newMesh.RotationScale.Right = this.RotationScale.Right; foreach (var lod in this.Lods) { var newLod = new MeshLod(); newLod.Distance = lod.Distance; foreach (var faceGroup in lod.FaceGroups) { var newFaceGroup = new FaceGroup(); foreach (var face in faceGroup.Faces) { newFaceGroup.Faces.Add(new Face { VerticesIndex = face.VerticesIndex, EdgesIndex = face.EdgesIndex, TextureCoordinatesIndex = face.TextureCoordinatesIndex, VertexNormalsIndex = face.VertexNormalsIndex, Normal = face.Normal, TexturingDirection = face.TexturingDirection, TexturingMagniture = face.TexturingMagniture }); } foreach (var texture in faceGroup.Textures) { newFaceGroup.Textures.Add(texture); } newLod.FaceGroups.Add(newFaceGroup); } newMesh.Lods.Add(newLod); } foreach (var hardpoint in this.Hardpoints) { newMesh.Hardpoints.Add(new Hardpoint { HardpointType = hardpoint.HardpointType, Position = hardpoint.Position }); } foreach (var engineGlow in this.EngineGlows) { newMesh.EngineGlows.Add(new EngineGlow { IsDisabled = engineGlow.IsDisabled, CoreColor = engineGlow.CoreColor, OuterColor = engineGlow.OuterColor, Format = engineGlow.Format, Position = engineGlow.Position, Look = engineGlow.Look, Up = engineGlow.Up, Right = engineGlow.Right }); } var center = newMesh.Descriptor.Center; newMesh.Move(-center.X, -center.Y, -center.Z); return newMesh; }
public static OptFile FromFile(string path) { OptFile opt = new OptFile(); opt.FileName = path; OptFileNodes optNodes = OptFileNodes.FromFile(path); List <string> globalTexture = null; for (int meshId = 0; meshId < optNodes.Nodes.Count; meshId++) { if (meshId == 0 && optNodes.Nodes[meshId].NodeType == NodeType.Texture) { TextureNode textureNode = (TextureNode)optNodes.Nodes[meshId]; opt.CreateTexture(textureNode); globalTexture = new List <string>() { textureNode.Name }; continue; } if (optNodes.Nodes[meshId].NodeType != NodeType.NodeGroup) { throw new InvalidDataException("invalid mesh"); } NodeGroupNode meshNode = (NodeGroupNode)optNodes.Nodes[meshId]; var meshNodes = meshNode.Nodes.Union((meshNode.Nodes.Where(t => t.NodeType == NodeType.NodeGroup).FirstOrDefault() ?? new NodeGroupNode()).Nodes).ToList(); RotationScaleNode rotationScaleNode = (RotationScaleNode)meshNodes.FirstOrDefault(t => t.NodeType == NodeType.RotationScale); MeshDescriptorNode descriptorNode = (MeshDescriptorNode)meshNodes.FirstOrDefault(t => t.NodeType == NodeType.MeshDescriptor); MeshVerticesNode verticesNode = (MeshVerticesNode)meshNodes.First(t => t.NodeType == NodeType.MeshVertices); TextureCoordinatesNode textureVerticesNode = (TextureCoordinatesNode)meshNodes.First(t => t.NodeType == NodeType.TextureCoordinates); VertexNormalsNode vertexNormalsNode = (VertexNormalsNode)meshNodes.First(t => t.NodeType == NodeType.VertexNormals); var hardpointsNodes = meshNodes.Where(t => t.NodeType == NodeType.Hardpoint).Select(t => (HardpointNode)t).ToList(); var engineGlowsNodes = meshNodes.Where(t => t.NodeType == NodeType.EngineGlow).Select(t => (EngineGlowNode)t).ToList(); FaceGroupingNode faceGroupingNode = (FaceGroupingNode)meshNodes.First(t => t.NodeType == NodeType.FaceGrouping); Mesh mesh = new Mesh(); if (rotationScaleNode != null) { mesh.RotationScale.Pivot = rotationScaleNode.Pivot; mesh.RotationScale.Look = rotationScaleNode.Look; mesh.RotationScale.Up = rotationScaleNode.Up; mesh.RotationScale.Right = rotationScaleNode.Right; } if (descriptorNode != null) { mesh.Descriptor.MeshType = descriptorNode.MeshType; mesh.Descriptor.ExplosionType = descriptorNode.ExplosionType; mesh.Descriptor.Span = descriptorNode.Span; mesh.Descriptor.Center = descriptorNode.Center; mesh.Descriptor.Min = descriptorNode.Min; mesh.Descriptor.Max = descriptorNode.Max; mesh.Descriptor.TargetId = descriptorNode.TargetId; mesh.Descriptor.Target = descriptorNode.Target; } foreach (Vector vertex in verticesNode.Vertices) { mesh.Vertices.Add(vertex); } foreach (TextureCoordinates textureVertex in textureVerticesNode.TextureVertices) { mesh.TextureCoordinates.Add(textureVertex); } foreach (Vector normal in vertexNormalsNode.Normals) { mesh.VertexNormals.Add(normal); } foreach (var hardpoint in hardpointsNodes) { mesh.Hardpoints.Add(new Hardpoint() { HardpointType = hardpoint.HardpointType, Position = hardpoint.Position }); } foreach (var engineGlow in engineGlowsNodes) { mesh.EngineGlows.Add(new EngineGlow() { IsDisabled = engineGlow.IsDisabled, CoreColor = engineGlow.CoreColor, OuterColor = engineGlow.OuterColor, Position = engineGlow.Position, Format = engineGlow.Format, Look = engineGlow.Look, Up = engineGlow.Up, Right = engineGlow.Right }); } if (faceGroupingNode.Distances.Count != faceGroupingNode.Nodes.Count) { throw new InvalidDataException("invalid face groups count in face grouping"); } for (int lodId = 0; lodId < faceGroupingNode.Distances.Count; lodId++) { List <string> texture = globalTexture; MeshLod lod = new MeshLod(); lod.Distance = faceGroupingNode.Distances[lodId]; foreach (Node node in faceGroupingNode.Nodes[lodId].Nodes) { switch (node.NodeType) { case NodeType.Texture: { TextureNode textureNode = (TextureNode)node; opt.CreateTexture(textureNode); texture = new List <string>() { textureNode.Name }; break; } case NodeType.NodeReference: texture = new List <string>() { ((NodeReferenceNode)node).Reference }; break; case NodeType.NodeSwitch: { NodeSwitchNode switchNode = (NodeSwitchNode)node; texture = new List <string>(); foreach (Node nodeSwitch in switchNode.Nodes) { switch (nodeSwitch.NodeType) { case NodeType.Texture: { TextureNode textureNode = (TextureNode)nodeSwitch; opt.CreateTexture(textureNode); texture.Add(textureNode.Name); break; } case NodeType.NodeReference: texture.Add(((NodeReferenceNode)nodeSwitch).Reference); break; } } break; } case NodeType.FaceData: { FaceDataNode faceDataNode = (FaceDataNode)node; FaceGroup faceGroup = new FaceGroup(); if (texture != null) { foreach (var name in texture) { faceGroup.Textures.Add(name); } } foreach (var face in faceDataNode.Faces) { faceGroup.Faces.Add(new Face() { VerticesIndex = face.VerticesIndex, EdgesIndex = face.EdgesIndex, TextureCoordinatesIndex = face.TextureCoordinatesIndex, VertexNormalsIndex = face.VertexNormalsIndex, Normal = face.Normal, TexturingDirection = face.TexturingDirection, TexturingMagniture = face.TexturingMagniture }); } foreach (var face in faceGroup.Faces) { if (face.VertexNormalsIndex.A >= mesh.VertexNormals.Count) { face.VertexNormalsIndex = face.VertexNormalsIndex.SetA(0); } if (face.VertexNormalsIndex.B >= mesh.VertexNormals.Count) { face.VertexNormalsIndex = face.VertexNormalsIndex.SetB(0); } if (face.VertexNormalsIndex.C >= mesh.VertexNormals.Count) { face.VertexNormalsIndex = face.VertexNormalsIndex.SetC(0); } if (face.VertexNormalsIndex.D >= mesh.VertexNormals.Count) { face.VertexNormalsIndex = face.VertexNormalsIndex.SetD(0); } if (face.TextureCoordinatesIndex.A >= mesh.TextureCoordinates.Count) { face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetA(0); } if (face.TextureCoordinatesIndex.B >= mesh.TextureCoordinates.Count) { face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetB(0); } if (face.TextureCoordinatesIndex.C >= mesh.TextureCoordinates.Count) { face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetC(0); } if (face.TextureCoordinatesIndex.D >= mesh.TextureCoordinates.Count) { face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetD(0); } if (face.VerticesIndex.A >= 0 && face.TextureCoordinatesIndex.A < 0) { face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetA(0); } if (face.VerticesIndex.B >= 0 && face.TextureCoordinatesIndex.B < 0) { face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetB(0); } if (face.VerticesIndex.C >= 0 && face.TextureCoordinatesIndex.C < 0) { face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetC(0); } if (face.VerticesIndex.D >= 0 && face.TextureCoordinatesIndex.D < 0) { face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetD(0); } } lod.FaceGroups.Add(faceGroup); texture = null; break; } } } mesh.Lods.Add(lod); } opt.Meshes.Add(mesh); } opt.SetFaceGroupTextureWhenEmpty(); return(opt); }
public Mesh Duplicate() { var newMesh = new Mesh(); foreach (var vertex in this.Vertices) { newMesh.Vertices.Add(vertex); } foreach (var textureCoordinate in this.TextureCoordinates) { newMesh.TextureCoordinates.Add(textureCoordinate); } foreach (var vertexNormal in this.VertexNormals) { newMesh.VertexNormals.Add(vertexNormal); } newMesh.Descriptor.MeshType = this.Descriptor.MeshType; newMesh.Descriptor.ExplosionType = this.Descriptor.ExplosionType; newMesh.Descriptor.Span = this.Descriptor.Span; newMesh.Descriptor.Center = this.Descriptor.Center; newMesh.Descriptor.Min = this.Descriptor.Min; newMesh.Descriptor.Max = this.Descriptor.Max; newMesh.Descriptor.TargetId = this.Descriptor.TargetId; newMesh.Descriptor.Target = this.Descriptor.Target; newMesh.RotationScale.Pivot = this.RotationScale.Pivot; newMesh.RotationScale.Look = this.RotationScale.Look; newMesh.RotationScale.Up = this.RotationScale.Up; newMesh.RotationScale.Right = this.RotationScale.Right; foreach (var lod in this.Lods) { var newLod = new MeshLod(); newLod.Distance = lod.Distance; foreach (var faceGroup in lod.FaceGroups) { var newFaceGroup = new FaceGroup(); foreach (var face in faceGroup.Faces) { newFaceGroup.Faces.Add(new Face { VerticesIndex = face.VerticesIndex, EdgesIndex = face.EdgesIndex, TextureCoordinatesIndex = face.TextureCoordinatesIndex, VertexNormalsIndex = face.VertexNormalsIndex, Normal = face.Normal, TexturingDirection = face.TexturingDirection, TexturingMagniture = face.TexturingMagniture }); } foreach (var texture in faceGroup.Textures) { newFaceGroup.Textures.Add(texture); } newLod.FaceGroups.Add(newFaceGroup); } newMesh.Lods.Add(newLod); } foreach (var hardpoint in this.Hardpoints) { newMesh.Hardpoints.Add(new Hardpoint { HardpointType = hardpoint.HardpointType, Position = hardpoint.Position }); } foreach (var engineGlow in this.EngineGlows) { newMesh.EngineGlows.Add(new EngineGlow { IsDisabled = engineGlow.IsDisabled, CoreColor = engineGlow.CoreColor, OuterColor = engineGlow.OuterColor, Format = engineGlow.Format, Position = engineGlow.Position, Look = engineGlow.Look, Up = engineGlow.Up, Right = engineGlow.Right }); } var center = newMesh.Descriptor.Center; newMesh.Move(-center.X, -center.Y, -center.Z); return(newMesh); }