public void CreateIcosphere(float radius, int subdivisionSteps) { this.radius = radius; this.subdivisionSteps = subdivisionSteps; // Clear lists Points = new PointList(); Triangles = new TriangleList(); var t = (1.0f + Mathf.Sqrt(5.0f)) / 2.0f; // Vertices // XY plane addVertex(new Point(-1, t, 0)); addVertex(new Point(1, t, 0)); addVertex(new Point(-1, -t, 0)); addVertex(new Point(1, -t, 0)); // YZ plane addVertex(new Point(0, -1, t)); addVertex(new Point(0, 1, t)); addVertex(new Point(0, -1, -t)); addVertex(new Point(0, 1, -t)); // XZ plane addVertex(new Point(t, 0, -1)); addVertex(new Point(t, 0, 1)); addVertex(new Point(-t, 0, -1)); addVertex(new Point(-t, 0, 1)); // Triangles Triangles.Add(new Triangle(0, 11, 5)); Triangles.Add(new Triangle(0, 5, 1)); Triangles.Add(new Triangle(0, 1, 7)); Triangles.Add(new Triangle(0, 7, 10)); Triangles.Add(new Triangle(0, 10, 11)); // 5 adjacent triangles Triangles.Add(new Triangle(1, 5, 9)); Triangles.Add(new Triangle(5, 11, 4)); Triangles.Add(new Triangle(11, 10, 2)); Triangles.Add(new Triangle(10, 7, 6)); Triangles.Add(new Triangle(7, 1, 8)); // 5 triangles around point 3 Triangles.Add(new Triangle(3, 9, 4)); Triangles.Add(new Triangle(3, 4, 2)); Triangles.Add(new Triangle(3, 2, 6)); Triangles.Add(new Triangle(3, 6, 8)); Triangles.Add(new Triangle(3, 8, 9)); // 5 adjacent triangles Triangles.Add(new Triangle(4, 9, 5)); Triangles.Add(new Triangle(2, 4, 11)); Triangles.Add(new Triangle(6, 2, 10)); Triangles.Add(new Triangle(8, 6, 7)); Triangles.Add(new Triangle(9, 8, 1)); Subdivide(subdivisionSteps); Debug.Log("Triangle count " + Triangles.Count + " Vertex count " + Points.Count); }
public void Add(TriangleList triangles) { for (Triangle t = triangles.head; t != null; t = t.next) { Add(t); } }
public void CreatePlane(float width, float depth, int subdivisionSteps) { this.sizeX = width; this.sizeZ = depth; this.subdivisionSteps = subdivisionSteps; // Clear lists Points = new PointList(); Triangles = new TriangleList(); // Vertices // XZ plane addVertex(new Point(sizeX / 2.0f, 0, -sizeZ / 2.0f)); addVertex(new Point(sizeX / 2.0f, 0, sizeZ / 2.0f)); addVertex(new Point(-sizeX / 2.0f, 0, -sizeZ / 2.0f)); addVertex(new Point(-sizeX / 2.0f, 0, sizeZ / 2.0f)); // Triangles Triangles.Add(new Triangle(1, 0, 2)); Triangles.Add(new Triangle(3, 1, 2)); Subdivide(subdivisionSteps); Debug.Log("Triangle count " + Triangles.Count + " Vertex count " + Points.Count); }
public void reset() { if (children != null) { foreach (Chunk2 c in children) { if (c != null) { c.reset(); } } } meshFilter = null; meshRenderer = null; meshData = null; children = null; init(); // Delete all existing children for (int i = 0; i < transform.childCount; i++) { DestroyImmediate(transform.GetChild(i).gameObject); i--; } }
//Функция отрисовки вершин портируемого объекта. Вершины за порталом не отрисовываются private void DrawVertices() { var vertices = new List <Vector3>(StartedVecticles); var Triangles = new TriangleList(StartedTriangles); //Ищем вершины которые находятся за поратлом //И удаляем их for (int i = 0; i < vertices.Count; i++) { Vector3 GlobalVertexCoord = transform.TransformPoint(vertices[i]); if (BehingThePortal(GlobalVertexCoord, ThisPortal)) { vertices.Remove(vertices[i]); Triangles.DeleteVertex(i); --i; } } //Перестраиваем меш meshFilter.mesh = new Mesh(); meshFilter.mesh.vertices = vertices.ToArray(); meshFilter.mesh.triangles = Triangles.ToArray(); meshFilter.mesh.RecalculateBounds(); meshFilter.mesh.RecalculateNormals(); }
public TriangleList(TriangleList data) : this() { for (Triangle t = head; t != null; t = t.next) { Add(t); } }
protected override void Build() { var numTriangles = m_indices.Length / 3; var triangleBounds = new Bounds[numTriangles]; var index = 0; var nodeList = new List <TreeNode>(); TreeNode rootNode; rootNode.m_bounds = m_bounds; rootNode.m_childIndex = -1; rootNode.m_triangles = null; var triangleList = new List <int>(); for (var i = 0; i < numTriangles; ++i) { triangleList.Add(index); var v0 = m_vertices[m_indices[index++]]; var v1 = m_vertices[m_indices[index++]]; var v2 = m_vertices[m_indices[index++]]; Vector3 min, max; min.x = Mathf.Min(Mathf.Min(v0.x, v1.x), v2.x); min.y = Mathf.Min(Mathf.Min(v0.y, v1.y), v2.y); min.z = Mathf.Min(Mathf.Min(v0.z, v1.z), v2.z); max.x = Mathf.Max(Mathf.Max(v0.x, v1.x), v2.x); max.y = Mathf.Max(Mathf.Max(v0.y, v1.y), v2.y); max.z = Mathf.Max(Mathf.Max(v0.z, v1.z), v2.z); triangleBounds[i].SetMinMax(min, max); } BuildMeshTree(nodeList, ref rootNode, triangleList, triangleBounds); nodeList.Add(rootNode); #if UNITY_EDITOR && (UNITY_4_0 || UNITY_4_1 || UNITY_4_2 || UNITY_4_3) int numNodes = nodeList.Count; int[] childNodes = new int[numNodes]; TriangleList[] triangleLists = new TriangleList[numNodes]; Vector3[] nodeBoundsCenter = new Vector3[numNodes]; Vector3[] nodeBoundsExtent = new Vector3[numNodes]; for (int i = 0; i < numNodes; ++i) { TreeNode node = nodeList[i]; nodeBoundsCenter[i] = node.m_bounds.center; nodeBoundsExtent[i] = node.m_bounds.extents; childNodes[i] = node.m_childIndex; if (node.m_triangles != null) { triangleLists[i] = new TriangleList(); triangleLists[i].triangles = node.m_triangles; } else { triangleLists[i] = null; } } m_childNodes = childNodes; m_triangleLists = triangleLists; m_nodeBoundsCenter = nodeBoundsCenter; m_nodeBoundsExtent = nodeBoundsExtent; #endif m_treeNodes = nodeList.ToArray(); }
public void Load() { wmos = MODFList .Select(modf => _wmoLoader.Load(modf)) .ToList(); m2S = MDDFList.Select(mmdf => _m2Loader.Load(mmdf)) .ToList(); triangeList = GenerateVertexAndIndices(); triangeListH2O = GenerateVertexAndIndicesH2O(); }
public void generate(int numberOfChunks, int quadsPerChunk, Algorithm algorithm) { if (meshFilter == null) { meshFilter = GetComponent <MeshFilter>(); } meshFilter.sharedMesh = null; meshData = null; init(); // Delete all existing chunks for (int i = 0; i < transform.childCount; i++) { DestroyImmediate(transform.GetChild(i).gameObject); i--; } // Generate chunk data chunks = new Chunk[numberOfChunks, numberOfChunks]; float chunkSize = algorithm.getBaseRadius() / (float)numberOfChunks; for (int i = 0; i < numberOfChunks; i++) { for (int j = 0; j < numberOfChunks; j++) { float g = (float)i * chunkSize; float h = (float)j * chunkSize; Vector3 chunkPos = new Vector3(g, 0, h); chunkPos = transform.TransformPoint(chunkPos); chunks[i, j] = (Instantiate(chunkPrefab, chunkPos, transform.rotation) as GameObject).GetComponent <Chunk>(); chunks[i, j].transform.parent = transform; chunks[i, j].name = "Chunk " + i + "_" + j; chunks[i, j].generate(chunkSize, quadsPerChunk, algorithm); } } // Generate simplified data float quads = 10f; float quadSize = algorithm.getBaseRadius() / quads; for (int i = 0; i < quads; i++) { for (int j = 0; j < quads; j++) { Chunk.createQuad((float)i * quadSize, (float)j * quadSize, quadSize, algorithm, meshData, transform); } } }
private Vector3[] TravelVectors; //Vectors set in the start below void Start() { //Contoller events for thumbstick InteractionManager.InteractionSourcePressed += OnControllerPressed; InteractionManager.InteractionSourceUpdated += OnSourceUpdated; for (int m = 0; m < numOfVectors; m++) { colorArrayAlpha[m] = 1.0f; } //TriangleList.emitType = TriangleList.EmitType.Beam; TravelVectors = TriangleList.GetVectorList(); numOfVectors = TriangleList.GetVectorCount(); //myarrays = new Vector3[numOfVectors][]; }
public void GenerateMesh() { var mesh = new Mesh(); if (!transform.GetComponent <MeshFilter>()) //If you havent got any meshrenderer or filter { transform.gameObject.AddComponent <MeshFilter>(); } transform.GetComponent <MeshFilter>().mesh = mesh; //create empty color list Color[] colors = new Color[TriangleList.GetVectorCount()]; for (int i = 0; i < TriangleList.GetVectorCount(); i++) { float alpha = waveEmitter.colorArrayAlpha[i]; float maxAlpha = 1f; colors[i] = new Color(0f, 0f, 1f, alpha * maxAlpha); } // mesh.vertices = waveEmitter.GetVectorsListAtIndex(0); mesh.triangles = TriangleList.GetTriangleList(); mesh.colors = colors; mesh.RecalculateNormals(); Color c = transform.GetComponent <MeshRenderer>().material.color; float newAlpha = waveEmitter.colorArrayAlpha[0] * 0.1f; float rimAlpha = waveEmitter.colorArrayAlpha[0] * 0.2f; Color c_base = new Color(newAlpha, newAlpha, newAlpha); float a = waveEmitter.colorArrayAlpha[0]; c.a = waveEmitter.colorArrayAlpha[0]; c.r = 0.09131362f * rimAlpha; c.g = 0.2332605f * rimAlpha; c.b = 0.3396226f * rimAlpha; transform.GetComponent <MeshRenderer>().material.SetColor("_Color", c_base); transform.GetComponent <MeshRenderer>().material.SetColor("_RimColor", c); }
private static Model LoadM2(string fileName) { string path = fileName; if (path.Substring(path.Length - 4) == ".mdx") { path = path.Substring(0, path.Length - 4) + ".m2"; } var fileInfo = FileInfoFactory.Create(); if (!fileInfo.Exists(path)) { throw new Exception(String.Format("File does not exist: {0}", path)); } using (var br = new BinaryReader(fileInfo.OpenRead(path))) { br.BaseStream.Position = 60; //wotlk uint numberOfVerts = br.ReadUInt32(); uint vertsOffset = br.ReadUInt32(); uint numberOfViews = br.ReadUInt32(); //UInt32 viewsOffset = br.ReadUInt32(); //now in skins br.BaseStream.Position = 216; //wotlk uint nBoundingTriangles = br.ReadUInt32(); uint ofsBoundingTriangles = br.ReadUInt32(); uint nBoundingVertices = br.ReadUInt32(); uint ofsBoundingVertices = br.ReadUInt32(); uint nBoundingNormals = br.ReadUInt32(); uint ofsBoundingNormals = br.ReadUInt32(); var indices = new IndicesParser(br, ofsBoundingTriangles, nBoundingTriangles).Parse(); var vectors = new VectorsListParser(br, ofsBoundingVertices, nBoundingVertices).Parse(); //var normals = new VectorsListParser(br, ofsBoundingNormals, nBoundingNormals).Parse(); var vertices = vectors .Select(t => new VertexPositionNormalColored(t, Color.Red, Vector3.Up)) .ToList(); var list = new TriangleList(indices, vertices); return(new Model(list)); } }
static void ConvertOBJtoCL(string InputFile) { Console.WriteLine("Reading" + InputFile); UseHeader = new Header(); QuadNodeList.Clear(); TriangleList.Clear(); VertexList.Clear(); byte DepthLevel = 11; bool AutoDepth; Console.WriteLine("Please choose a depth level for the quadtree. It depends on how large/complex your model is."); Console.WriteLine("The maximum you should use is 10. Type 0 for it to be chosen automatically."); while (DepthLevel < 0 | DepthLevel > 10) { DepthLevel = Convert.ToByte(Console.ReadLine()); } if (DepthLevel == 0) { AutoDepth = true; } else { AutoDepth = false; } if (ReadOBJFile(InputFile)) { if (GenerateCollision(AutoDepth, DepthLevel)) { CreateCLFile(InputFile); } else { Console.WriteLine("Error."); } } else { Console.WriteLine("Error."); } }
/** * Add new Triangle */ private void AddTriangle(BSTriangle triangle, bool bCheckHalfEdge = true) { // see if it's same vertices for (int i = 0; i < TriangleList.Count; ++i) { if (triangle == TriangleList[i]) { return; } if (bCheckHalfEdge && triangle.HasSameHalfEdge(TriangleList[i])) { return; } } TriangleList.Add(new BSTriangle(triangle.Vertices[0], triangle.Vertices[1], triangle.Vertices[2])); }
void init() { if (meshFilter == null) { meshFilter = GetComponent <MeshFilter>(); } if (meshRenderer == null) { meshRenderer = GetComponent <MeshRenderer>(); } if (meshFilter.sharedMesh == null) { meshFilter.sharedMesh = new Mesh(); meshFilter.sharedMesh.name = transform.name + "Mesh"; } if (meshData == null) { meshData = new TriangleList(); } }
public void DrawTriangle(JVector p0, JVector p1, JVector p2, Color color) { triangleIndex += 3; if (triangleIndex == TriangleList.Length) { VertexPositionColor[] temp = new VertexPositionColor[TriangleList.Length + 300]; TriangleList.CopyTo(temp, 0); TriangleList = temp; } TriangleList[triangleIndex - 2].Color = color; TriangleList[triangleIndex - 2].Position = Conversion.ToXNAVector3(p0); TriangleList[triangleIndex - 1].Color = color; TriangleList[triangleIndex - 1].Position = Conversion.ToXNAVector3(p1); TriangleList[triangleIndex - 3].Color = color; TriangleList[triangleIndex - 3].Position = Conversion.ToXNAVector3(p2); }
private void Subdivide(int subdivisionSteps) { middlePointIndexCache = new Dictionary <Int64, int>(); for (int i = 0; i < subdivisionSteps; i++) { var triangles2 = new TriangleList(); foreach (var tri in Triangles) { // replace triangle by 4 triangles int a = GetMiddlePoint(tri.v1, tri.v2); int b = GetMiddlePoint(tri.v2, tri.v3); int c = GetMiddlePoint(tri.v3, tri.v1); triangles2.Add(new Triangle(tri.v1, a, c)); triangles2.Add(new Triangle(tri.v2, b, a)); triangles2.Add(new Triangle(tri.v3, c, b)); triangles2.Add(new Triangle(a, b, c)); } Triangles = triangles2; } }
private Vector3[] TravelVectors; //Vectors set in the start below void Start() { //Contoller events for thumbstick #if UNITY_WSA InteractionManager.InteractionSourcePressed += OnControllerPressed; InteractionManager.InteractionSourceUpdated += OnSourceUpdated; #endif for (int m = 0; m < numOfVectors; m++) { colorArrayAlpha[m] = 1.0f; } TravelVectors = TriangleList.GetVectorList(TriangleList.EmitType.Beam); numOfVectors = TriangleList.GetVectorCount(TriangleList.EmitType.Beam); Quaternion rot = gameObject.transform.rotation; for (int i = 0; i < numOfVectors; i++) { TravelVectors[i] = rot * TravelVectors[i]; } }
public static void AddToCollision(Form_AreaEditor @base, VertexList vlist, Vertex[] vs, TriangleList tlist, Triangle[] ts) { foreach (Vertex v in vs) { vlist.Add(v); } foreach (Triangle t in ts) { tlist.Add(t); } @base.maps.ReloadCollisionInOpenGL(); }
public static void Export(string FileName, ExportSettings settings, List <STGenericObject> Meshes, List <STGenericMaterial> Materials, List <STGenericTexture> Textures, STSkeleton skeleton = null, List <int> NodeArray = null) { if (Materials == null) { Materials = new List <STGenericMaterial>(); } if (skeleton != null && skeleton.BoneIndices != null) { NodeArray = skeleton.BoneIndices.ToList(); } List <string> failedTextureExport = new List <string>(); STProgressBar progressBar = new STProgressBar(); progressBar.Task = "Exporting Model..."; progressBar.Value = 0; progressBar.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; progressBar.Show(); progressBar.Refresh(); if (settings.UseOldExporter) { AssimpSaver saver = new AssimpSaver(); STGenericModel model = new STGenericModel(); model.Objects = Meshes; model.Materials = Materials; saver.SaveFromModel(model, FileName, Textures, skeleton, NodeArray); return; } string TexturePath = System.IO.Path.GetDirectoryName(FileName); Dictionary <string, STGenericMaterial> MaterialRemapper = new Dictionary <string, STGenericMaterial>(); using (ColladaWriter writer = new ColladaWriter(FileName, settings)) { writer.WriteAsset(); if (Materials.Count > 0) { List <string> textureNames = new List <string>(); for (int i = 0; i < Textures?.Count; i++) { if (!textureNames.Contains(Textures[i].Text)) { textureNames.Add(Textures[i].Text); } if (settings.ExportTextures) { progressBar.Task = $"Exporting Texture {Textures[i].Text}"; progressBar.Value = ((i * 100) / Textures.Count); progressBar.Refresh(); try { var bitmap = Textures[i].GetBitmap(); if (bitmap != null) { if (settings.UseTextureChannelComponents) { bitmap = Textures[i].GetComponentBitmap(bitmap); } string textureName = Textures[i].Text; if (textureName.RemoveIllegaleFileNameCharacters() != textureName) { string properName = textureName.RemoveIllegaleFileNameCharacters(); for (int m = 0; m < Materials?.Count; m++) { foreach (var tex in Materials[m].TextureMaps) { if (tex.Name == textureName) { tex.Name = properName; } } } textureName = properName; } bitmap.Save($"{TexturePath}/{textureName}.png"); bitmap.Dispose(); GC.Collect(); } } catch (Exception ex) { failedTextureExport.Add(Textures[i].Text); } } } List <Material> materials = new List <Material>(); foreach (var mat in Materials) { Material material = new Material(); material.Name = mat.Text; if (!MaterialRemapper.ContainsKey(mat.Text)) { MaterialRemapper.Add(mat.Text, mat); } else { string name = Utils.RenameDuplicateString(MaterialRemapper.Keys.ToList(), mat.Text); MaterialRemapper.Add(name, mat); material.Name = name; } materials.Add(material); foreach (var tex in mat.TextureMaps) { TextureMap texMap = new TextureMap(); texMap.Name = tex.Name; if (tex.Type == STGenericMatTexture.TextureType.Diffuse) { texMap.Type = PhongTextureType.diffuse; } else if (tex.Type == STGenericMatTexture.TextureType.Normal) { texMap.Type = PhongTextureType.bump; } else if (tex.Type == STGenericMatTexture.TextureType.Specular) { texMap.Type = PhongTextureType.specular; } else if (tex.Type == STGenericMatTexture.TextureType.Emission) { texMap.Type = PhongTextureType.emission; } else { continue; //Skip adding unknown types } if (tex.WrapModeS == STTextureWrapMode.Repeat) { texMap.WrapModeS = SamplerWrapMode.WRAP; } else if (tex.WrapModeS == STTextureWrapMode.Mirror) { texMap.WrapModeS = SamplerWrapMode.MIRROR; } else if (tex.WrapModeS == STTextureWrapMode.Clamp) { texMap.WrapModeS = SamplerWrapMode.CLAMP; } if (tex.WrapModeT == STTextureWrapMode.Repeat) { texMap.WrapModeT = SamplerWrapMode.WRAP; } else if (tex.WrapModeT == STTextureWrapMode.Mirror) { texMap.WrapModeT = SamplerWrapMode.MIRROR; } else if (tex.WrapModeT == STTextureWrapMode.Clamp) { texMap.WrapModeT = SamplerWrapMode.CLAMP; } //If no textures are saved, still keep images references //So the user can still dump textures after if (Textures?.Count == 0 && !textureNames.Contains(texMap.Name)) { textureNames.Add($"{texMap.Name}"); } material.Textures.Add(texMap); } } writer.WriteLibraryImages(textureNames.ToArray()); writer.WriteLibraryMaterials(materials); writer.WriteLibraryEffects(materials); } else { writer.WriteLibraryImages(); } if (skeleton != null) { //Search for bones with rigging first List <string> riggedBones = new List <string>(); if (settings.OnlyExportRiggedBones) { for (int i = 0; i < Meshes.Count; i++) { for (int v = 0; v < Meshes[i].vertices.Count; v++) { var vertex = Meshes[i].vertices[v]; for (int j = 0; j < vertex.boneIds.Count; j++) { int id = -1; if (NodeArray != null && NodeArray.Count > vertex.boneIds[j]) { id = NodeArray[vertex.boneIds[j]]; } else { id = vertex.boneIds[j]; } if (id < skeleton.bones.Count && id != -1) { riggedBones.Add(skeleton.bones[id].Text); } } } } } foreach (var bone in skeleton.bones) { if (settings.OnlyExportRiggedBones && !riggedBones.Contains(bone.Text)) { Console.WriteLine("Skipping " + bone.Text); continue; } //Set the inverse matrix var inverse = skeleton.GetBoneTransform(bone).Inverted(); var transform = bone.GetTransform(); float[] Transform = new float[] { transform.M11, transform.M21, transform.M31, transform.M41, transform.M12, transform.M22, transform.M32, transform.M42, transform.M13, transform.M23, transform.M33, transform.M43, transform.M14, transform.M24, transform.M34, transform.M44 }; float[] InvTransform = new float[] { inverse.M11, inverse.M21, inverse.M31, inverse.M41, inverse.M12, inverse.M22, inverse.M32, inverse.M42, inverse.M13, inverse.M23, inverse.M33, inverse.M43, inverse.M14, inverse.M24, inverse.M34, inverse.M44 }; writer.AddJoint(bone.Text, bone.parentIndex == -1 ? "" : skeleton.bones[bone.parentIndex].Text, Transform, InvTransform, new float[3] { bone.Position.X, bone.Position.Y, bone.Position.Z }, new float[3] { bone.EulerRotation.X *Rad2Deg, bone.EulerRotation.Y *Rad2Deg, bone.EulerRotation.Z *Rad2Deg }, new float[3] { bone.Scale.X, bone.Scale.Y, bone.Scale.Z }); } } int meshIndex = 0; writer.StartLibraryGeometries(); foreach (var mesh in Meshes) { progressBar.Task = $"Exporting Mesh {mesh.Text}"; progressBar.Value = ((meshIndex++ *100) / Meshes.Count); progressBar.Refresh(); int[] IndexTable = null; if (NodeArray != null) { IndexTable = NodeArray.ToArray(); } writer.StartGeometry(mesh.Text); if (mesh.MaterialIndex != -1 && Materials.Count > mesh.MaterialIndex) { writer.CurrentMaterial = Materials[mesh.MaterialIndex].Text; Console.WriteLine($"MaterialIndex {mesh.MaterialIndex } {Materials[mesh.MaterialIndex].Text}"); } if (settings.TransformColorUVs) { List <Vertex> transformedVertices = new List <Vertex>(); foreach (var poly in mesh.PolygonGroups) { var mat = poly.Material; if (mat == null) { continue; } var faces = poly.GetDisplayFace(); for (int v = 0; v < poly.displayFaceSize; v += 3) { if (faces.Count < v + 2) { break; } var diffuse = mat.TextureMaps.FirstOrDefault(x => x.Type == STGenericMatTexture.TextureType.Diffuse); STTextureTransform transform = new STTextureTransform(); if (diffuse != null) { transform = diffuse.Transform; } var vertexA = mesh.vertices[faces[v]]; var vertexB = mesh.vertices[faces[v + 1]]; var vertexC = mesh.vertices[faces[v + 2]]; if (!transformedVertices.Contains(vertexA)) { vertexA.uv0 = (vertexA.uv0 * transform.Scale) + transform.Translate; transformedVertices.Add(vertexA); } if (!transformedVertices.Contains(vertexB)) { vertexB.uv0 = (vertexB.uv0 * transform.Scale) + transform.Translate; transformedVertices.Add(vertexB); } if (!transformedVertices.Contains(vertexC)) { vertexC.uv0 = (vertexC.uv0 * transform.Scale) + transform.Translate; transformedVertices.Add(vertexC); } } } } // collect sources List <float> Position = new List <float>(); List <float> Normal = new List <float>(); List <float> UV0 = new List <float>(); List <float> UV1 = new List <float>(); List <float> UV2 = new List <float>(); List <float> UV3 = new List <float>(); List <float> Color = new List <float>(); List <float> Color2 = new List <float>(); List <int[]> BoneIndices = new List <int[]>(); List <float[]> BoneWeights = new List <float[]>(); bool HasNormals = false; bool HasColors = false; bool HasColors2 = false; bool HasUV0 = false; bool HasUV1 = false; bool HasUV2 = false; bool HasBoneIds = false; foreach (var vertex in mesh.vertices) { if (vertex.nrm != Vector3.Zero) { HasNormals = true; } if (vertex.col != Vector4.One && settings.UseVertexColors) { HasColors = true; } if (vertex.col2 != Vector4.One && settings.UseVertexColors) { HasColors2 = true; } if (vertex.uv0 != Vector2.Zero) { HasUV0 = true; } if (vertex.uv1 != Vector2.Zero) { HasUV1 = true; } if (vertex.uv2 != Vector2.Zero) { HasUV2 = true; } if (vertex.boneIds.Count > 0) { HasBoneIds = true; } Position.Add(vertex.pos.X); Position.Add(vertex.pos.Y); Position.Add(vertex.pos.Z); Normal.Add(vertex.nrm.X); Normal.Add(vertex.nrm.Y); Normal.Add(vertex.nrm.Z); if (settings.FlipTexCoordsVertical) { UV0.Add(vertex.uv0.X); UV0.Add(1 - vertex.uv0.Y); UV1.Add(vertex.uv1.X); UV1.Add(1 - vertex.uv1.Y); UV2.Add(vertex.uv2.X); UV2.Add(1 - vertex.uv2.Y); } else { UV0.Add(vertex.uv0.X); UV0.Add(vertex.uv0.Y); UV1.Add(vertex.uv1.X); UV1.Add(vertex.uv1.Y); UV2.Add(vertex.uv2.X); UV2.Add(vertex.uv2.Y); } Color.AddRange(new float[] { vertex.col.X, vertex.col.Y, vertex.col.Z, vertex.col.W }); Color2.AddRange(new float[] { vertex.col2.X, vertex.col2.Y, vertex.col2.Z, vertex.col2.W }); List <int> bIndices = new List <int>(); List <float> bWeights = new List <float>(); for (int b = 0; b < vertex.boneIds.Count; b++) { if (b > mesh.VertexSkinCount - 1) { continue; } //Skip 0 weights if (vertex.boneWeights.Count > b) { if (vertex.boneWeights[b] == 0) { continue; } } int index = -1; if (IndexTable != null) { index = (int)IndexTable[vertex.boneIds[b]]; } else { index = (int)vertex.boneIds[b]; } //Only map for valid weights/indices bool hasValidIndex = index != -1 && index < skeleton?.bones.Count; bool hasValidWeight = vertex.boneWeights.Count > b; if (hasValidIndex) { bIndices.Add(index); } if (hasValidWeight && hasValidIndex) { bWeights.Add(vertex.boneWeights[b]); } } //Rigid bodies with no direct bone indices if (bIndices.Count == 0 && mesh.BoneIndex != -1) { HasBoneIds = true; bIndices.Add(mesh.BoneIndex); bWeights.Add(1); } //Bone indices with no weights directly mapped if (bWeights.Count == 0 && bIndices.Count > 0) { bWeights.Add(1.0f); } BoneIndices.Add(bIndices.ToArray()); BoneWeights.Add(bWeights.ToArray()); } List <TriangleList> triangleLists = new List <TriangleList>(); if (mesh.lodMeshes.Count > 0) { TriangleList triangleList = new TriangleList(); triangleLists.Add(triangleList); var lodMesh = mesh.lodMeshes[mesh.DisplayLODIndex]; List <int> faces = new List <int>(); if (lodMesh.PrimativeType == STPrimitiveType.TrangleStrips) { faces = STGenericObject.ConvertTriangleStripsToTriangles(lodMesh.faces); } else { faces = lodMesh.faces; } for (int i = 0; i < faces.Count; i++) { triangleList.Indices.Add((uint)faces[i]); } } if (mesh.PolygonGroups.Count > 0) { foreach (var group in mesh.PolygonGroups) { TriangleList triangleList = new TriangleList(); triangleLists.Add(triangleList); STGenericMaterial material = new STGenericMaterial(); if (group.MaterialIndex != -1 && Materials.Count > group.MaterialIndex) { material = Materials[group.MaterialIndex]; } if (group.Material != null) { material = group.Material; } if (MaterialRemapper.Values.Any(x => x == material)) { var key = MaterialRemapper.FirstOrDefault(x => x.Value == material).Key; triangleList.Material = key; } else if (material.Text != string.Empty) { triangleList.Material = material.Text; } List <int> faces = new List <int>(); if (group.PrimativeType == STPrimitiveType.TrangleStrips) { faces = STGenericObject.ConvertTriangleStripsToTriangles(group.faces); } else { faces = group.faces; } for (int i = 0; i < faces.Count; i++) { triangleList.Indices.Add((uint)faces[i]); } } } // write sources writer.WriteGeometrySource(mesh.Text, SemanticType.POSITION, Position.ToArray(), triangleLists.ToArray()); if (HasNormals) { writer.WriteGeometrySource(mesh.Text, SemanticType.NORMAL, Normal.ToArray(), triangleLists.ToArray()); } if (HasColors) { writer.WriteGeometrySource(mesh.Text, SemanticType.COLOR, Color.ToArray(), triangleLists.ToArray(), 0); } if (HasColors2) { writer.WriteGeometrySource(mesh.Text, SemanticType.COLOR, Color2.ToArray(), triangleLists.ToArray(), 1); } if (HasUV0) { writer.WriteGeometrySource(mesh.Text, SemanticType.TEXCOORD, UV0.ToArray(), triangleLists.ToArray(), 0); } if (HasUV1) { writer.WriteGeometrySource(mesh.Text, SemanticType.TEXCOORD, UV1.ToArray(), triangleLists.ToArray(), 1); } if (HasUV2) { writer.WriteGeometrySource(mesh.Text, SemanticType.TEXCOORD, UV2.ToArray(), triangleLists.ToArray(), 2); } if (HasBoneIds) { writer.AttachGeometryController(BoneIndices, BoneWeights); } writer.EndGeometryMesh(); } writer.EndGeometrySection(); } progressBar?.Close(); if (!settings.SuppressConfirmDialog) { System.Windows.Forms.MessageBox.Show($"Exported {FileName} Successfuly!"); } }
public static void Export(string FileName, ExportSettings settings, List <STGenericObject> Meshes, List <STGenericMaterial> Materials, List <STGenericTexture> Textures, STSkeleton skeleton = null, List <int> NodeArray = null) { if (Materials == null) { Materials = new List <STGenericMaterial>(); } List <string> failedTextureExport = new List <string>(); STProgressBar progressBar = new STProgressBar(); progressBar.Task = "Exporting Model..."; progressBar.Value = 0; progressBar.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; progressBar.Show(); progressBar.Refresh(); if (settings.UseOldExporter) { AssimpSaver saver = new AssimpSaver(); STGenericModel model = new STGenericModel(); model.Objects = Meshes; model.Materials = Materials; saver.SaveFromModel(model, FileName, Textures, skeleton, NodeArray); return; } string TexturePath = System.IO.Path.GetDirectoryName(FileName); using (ColladaWriter writer = new ColladaWriter(FileName, settings)) { writer.WriteAsset(); if (Materials.Count > 0) { List <string> textureNames = new List <string>(); for (int i = 0; i < Textures?.Count; i++) { textureNames.Add(Textures[i].Text); if (settings.ExportTextures) { progressBar.Task = $"Exporting Texture {Textures[i].Text}"; progressBar.Value = ((i * 100) / Textures.Count); progressBar.Refresh(); try { var bitmap = Textures[i].GetBitmap(); if (bitmap != null) { string textureName = Textures[i].Text; if (textureName.RemoveIllegaleFileNameCharacters() != textureName) { string properName = textureName.RemoveIllegaleFileNameCharacters(); for (int m = 0; m < Materials?.Count; m++) { foreach (var tex in Materials[m].TextureMaps) { if (tex.Name == textureName) { tex.Name = properName; } } } textureName = properName; } bitmap.Save($"{TexturePath}/{textureName}.png"); bitmap.Dispose(); GC.Collect(); } } catch (Exception ex) { failedTextureExport.Add(Textures[i].Text); } } } List <Material> materials = new List <Material>(); foreach (var mat in Materials) { Material material = new Material(); material.Name = mat.Text; materials.Add(material); foreach (var tex in mat.TextureMaps) { TextureMap texMap = new TextureMap(); texMap.Name = tex.Name; if (tex.Type == STGenericMatTexture.TextureType.Diffuse) { texMap.Type = PhongTextureType.diffuse; } else if (tex.Type == STGenericMatTexture.TextureType.Normal) { texMap.Type = PhongTextureType.bump; } else if (tex.Type == STGenericMatTexture.TextureType.Specular) { texMap.Type = PhongTextureType.specular; } else if (tex.Type == STGenericMatTexture.TextureType.Emission) { texMap.Type = PhongTextureType.emission; } else { continue; //Skip adding unknown types } if (tex.WrapModeS == STTextureWrapMode.Repeat) { texMap.WrapModeS = SamplerWrapMode.WRAP; } else if (tex.WrapModeS == STTextureWrapMode.Mirror) { texMap.WrapModeS = SamplerWrapMode.MIRROR; } else if (tex.WrapModeS == STTextureWrapMode.Clamp) { texMap.WrapModeS = SamplerWrapMode.CLAMP; } if (tex.WrapModeT == STTextureWrapMode.Repeat) { texMap.WrapModeT = SamplerWrapMode.WRAP; } else if (tex.WrapModeT == STTextureWrapMode.Mirror) { texMap.WrapModeT = SamplerWrapMode.MIRROR; } else if (tex.WrapModeT == STTextureWrapMode.Clamp) { texMap.WrapModeT = SamplerWrapMode.CLAMP; } //If no textures are saved, still keep images references //So the user can still dump textures after if (Textures?.Count == 0) { textureNames.Add($"{texMap.Name}"); } material.Textures.Add(texMap); } } writer.WriteLibraryImages(textureNames.ToArray()); writer.WriteLibraryMaterials(materials); writer.WriteLibraryEffects(materials); } else { writer.WriteLibraryImages(); } if (skeleton != null) { foreach (var bone in skeleton.bones) { //Set the inverse matrix var inverse = skeleton.GetBoneTransform(bone).Inverted(); var transform = bone.GetTransform(); float[] Transform = new float[] { transform.M11, transform.M21, transform.M31, transform.M41, transform.M12, transform.M22, transform.M32, transform.M42, transform.M13, transform.M23, transform.M33, transform.M43, transform.M14, transform.M24, transform.M34, transform.M44 }; float[] InvTransform = new float[] { inverse.M11, inverse.M21, inverse.M31, inverse.M41, inverse.M12, inverse.M22, inverse.M32, inverse.M42, inverse.M13, inverse.M23, inverse.M33, inverse.M43, inverse.M14, inverse.M24, inverse.M34, inverse.M44 }; writer.AddJoint(bone.Text, bone.parentIndex == -1 ? "" : skeleton.bones[bone.parentIndex].Text, Transform, InvTransform); } } int meshIndex = 0; writer.StartLibraryGeometries(); foreach (var mesh in Meshes) { progressBar.Task = $"Exporting Mesh {mesh.Text}"; progressBar.Value = ((meshIndex++ *100) / Meshes.Count); progressBar.Refresh(); int[] IndexTable = null; if (NodeArray != null) { IndexTable = NodeArray.ToArray(); } writer.StartGeometry(mesh.Text); if (mesh.MaterialIndex != -1 && Materials.Count > mesh.MaterialIndex) { writer.CurrentMaterial = Materials[mesh.MaterialIndex].Text; } // collect sources List <float> Position = new List <float>(); List <float> Normal = new List <float>(); List <float> UV0 = new List <float>(); List <float> UV1 = new List <float>(); List <float> UV2 = new List <float>(); List <float> UV3 = new List <float>(); List <float> Color = new List <float>(); List <int[]> BoneIndices = new List <int[]>(); List <float[]> BoneWeights = new List <float[]>(); bool HasNormals = false; bool HasColors = false; bool HasUV0 = false; bool HasUV1 = false; bool HasUV2 = false; bool HasBoneIds = false; foreach (var vertex in mesh.vertices) { //Remove zero weights if (settings.OptmizeZeroWeights) { float MaxWeight = 1; for (int i = 0; i < 4; i++) { if (vertex.boneWeights.Count <= i) { continue; } if (vertex.boneIds.Count < i + 1) { vertex.boneWeights[i] = 0; MaxWeight = 0; } else { float weight = vertex.boneWeights[i]; if (vertex.boneWeights.Count == i + 1) { weight = MaxWeight; } if (weight >= MaxWeight) { weight = MaxWeight; MaxWeight = 0; } else { MaxWeight -= weight; } vertex.boneWeights[i] = weight; } } } if (vertex.nrm != Vector3.Zero) { HasNormals = true; } if (vertex.col != Vector4.One && settings.UseVertexColors) { HasColors = true; } if (vertex.uv0 != Vector2.Zero) { HasUV0 = true; } if (vertex.uv1 != Vector2.Zero) { HasUV1 = true; } if (vertex.uv2 != Vector2.Zero) { HasUV2 = true; } if (vertex.boneIds.Count > 0) { HasBoneIds = true; } Position.Add(vertex.pos.X); Position.Add(vertex.pos.Y); Position.Add(vertex.pos.Z); Normal.Add(vertex.nrm.X); Normal.Add(vertex.nrm.Y); Normal.Add(vertex.nrm.Z); if (settings.FlipTexCoordsVertical) { UV0.Add(vertex.uv0.X); UV0.Add(1 - vertex.uv0.Y); UV1.Add(vertex.uv1.X); UV1.Add(1 - vertex.uv1.Y); UV2.Add(vertex.uv2.X); UV2.Add(1 - vertex.uv2.Y); } else { UV0.Add(vertex.uv0.X); UV0.Add(vertex.uv0.Y); UV1.Add(vertex.uv1.X); UV1.Add(vertex.uv1.Y); UV2.Add(vertex.uv2.X); UV2.Add(vertex.uv2.Y); } Color.AddRange(new float[] { vertex.col.X, vertex.col.Y, vertex.col.Z, vertex.col.W }); List <int> bIndices = new List <int>(); List <float> bWeights = new List <float>(); for (int b = 0; b < vertex.boneIds.Count; b++) { if (b > mesh.VertexSkinCount - 1) { continue; } if (vertex.boneWeights.Count > b) { if (vertex.boneWeights[b] == 0) { continue; } } int index = -1; if (IndexTable != null) { index = (int)IndexTable[vertex.boneIds[b]]; } else { index = (int)vertex.boneIds[b]; } if (index != -1 && index < skeleton?.bones.Count) { bIndices.Add(index); } //Some models may only use indices (single bind, rigid skin) if (vertex.boneWeights.Count > b) { bWeights.Add(vertex.boneWeights[b]); } else { bWeights.Add(1); } } if (bIndices.Count == 0 && mesh.BoneIndex != -1) { HasBoneIds = true; bIndices.Add(mesh.BoneIndex); bWeights.Add(1); } BoneIndices.Add(bIndices.ToArray()); BoneWeights.Add(bWeights.ToArray()); } List <TriangleList> triangleLists = new List <TriangleList>(); if (mesh.lodMeshes.Count > 0) { TriangleList triangleList = new TriangleList(); triangleLists.Add(triangleList); var lodMesh = mesh.lodMeshes[mesh.DisplayLODIndex]; List <int> faces = new List <int>(); if (lodMesh.PrimativeType == STPrimitiveType.TrangleStrips) { faces = STGenericObject.ConvertTriangleStripsToTriangles(lodMesh.faces); } else { faces = lodMesh.faces; } for (int i = 0; i < faces.Count; i++) { triangleList.Indices.Add((uint)faces[i]); } } if (mesh.PolygonGroups.Count > 0) { foreach (var group in mesh.PolygonGroups) { TriangleList triangleList = new TriangleList(); triangleLists.Add(triangleList); if (group.MaterialIndex != -1 && Materials.Count > group.MaterialIndex) { triangleList.Material = Materials[group.MaterialIndex].Text; } List <int> faces = new List <int>(); if (group.PrimativeType == STPrimitiveType.TrangleStrips) { faces = STGenericObject.ConvertTriangleStripsToTriangles(group.faces); } else { faces = group.faces; } for (int i = 0; i < faces.Count; i++) { triangleList.Indices.Add((uint)faces[i]); } } } // write sources writer.WriteGeometrySource(mesh.Text, SemanticType.POSITION, Position.ToArray(), triangleLists.ToArray()); if (HasNormals) { writer.WriteGeometrySource(mesh.Text, SemanticType.NORMAL, Normal.ToArray(), triangleLists.ToArray()); } if (HasColors) { writer.WriteGeometrySource(mesh.Text, SemanticType.COLOR, Color.ToArray(), triangleLists.ToArray()); } if (HasUV0) { writer.WriteGeometrySource(mesh.Text, SemanticType.TEXCOORD, UV0.ToArray(), triangleLists.ToArray(), 0); } if (HasUV1) { writer.WriteGeometrySource(mesh.Text, SemanticType.TEXCOORD, UV1.ToArray(), triangleLists.ToArray(), 1); } if (HasUV2) { writer.WriteGeometrySource(mesh.Text, SemanticType.TEXCOORD, UV2.ToArray(), triangleLists.ToArray(), 2); } if (HasBoneIds) { writer.AttachGeometryController(BoneIndices, BoneWeights); } writer.EndGeometryMesh(); } writer.EndGeometrySection(); } progressBar?.Close(); if (!settings.SuppressConfirmDialog) { System.Windows.Forms.MessageBox.Show($"Exported {FileName} Successfuly!"); } }
public static void createQuad(float i, float j, float quadSize, Algorithm2 algorithm, TriangleList meshData, Transform transform) { // North Vertex a = new Vertex(i, 0, j); Vertex b = new Vertex(i, 0, j + quadSize); Vertex c = new Vertex(i + quadSize, 0, j + quadSize); Vertex d = new Vertex(i + quadSize, 0, j); // Apply terrain features based on the algorithm /*a.position = transform.TransformPoint(a.position); * b.position = transform.TransformPoint(b.position); * c.position = transform.TransformPoint(c.position); * d.position = transform.TransformPoint(d.position); * a.position = transform.InverseTransformPoint(a.position.normalized * algorithm.getHeight(a.position)); * b.position = transform.InverseTransformPoint(b.position.normalized * algorithm.getHeight(b.position)); * c.position = transform.InverseTransformPoint(c.position.normalized * algorithm.getHeight(c.position)); * d.position = transform.InverseTransformPoint(d.position.normalized * algorithm.getHeight(d.position));*/ // Texture coordinates a.uv = calcUV(a.position); b.uv = calcUV(b.position); c.uv = calcUV(c.position); d.uv = calcUV(d.position); // Add to geometry meshData.Add(new Triangle(a, b, c)); meshData.Add(new Triangle(c, d, a)); }
public void ClearTriangles() { TriangleList.Clear(); }
/** * Used as incremental step to triangulate all points * Create triangles TotalNum of PointList */ private int GenerateTriangles(List <BSPoint> PointList, int TotalNum) { if (TotalNum == 3) { if (IsEligibleForTriangulation(PointList[0], PointList[1], PointList[2])) { BSTriangle Triangle = new BSTriangle(PointList[0], PointList[1], PointList[2]); AddTriangle(Triangle); } } else if (TriangleList.Count == 0) { BSPoint TestPoint = PointList[TotalNum - 1]; // so far no triangle is made, try to make it with new points that are just entered for (int I = 0; I < TotalNum - 2; ++I) { if (IsEligibleForTriangulation(PointList[I], PointList[I + 1], TestPoint)) { BSTriangle NewTriangle = new BSTriangle(PointList[I], PointList[I + 1], TestPoint); AddTriangle(NewTriangle); } } } else { // get the last addition BSPoint TestPoint = PointList[TotalNum - 1]; int TriangleNum = TriangleList.Count; for (int I = 0; I < TriangleList.Count; ++I) { BSTriangle Triangle = TriangleList[I]; if (IsEligibleForTriangulation(Triangle.Vertices[0], Triangle.Vertices[1], TestPoint)) { BSTriangle NewTriangle = new BSTriangle(Triangle.Vertices[0], Triangle.Vertices[1], TestPoint); AddTriangle(NewTriangle); } if (IsEligibleForTriangulation(Triangle.Vertices[0], Triangle.Vertices[2], TestPoint)) { BSTriangle NewTriangle = new BSTriangle(Triangle.Vertices[0], Triangle.Vertices[2], TestPoint); AddTriangle(NewTriangle); } if (IsEligibleForTriangulation(Triangle.Vertices[1], Triangle.Vertices[2], TestPoint)) { BSTriangle NewTriangle = new BSTriangle(Triangle.Vertices[1], Triangle.Vertices[2], TestPoint); AddTriangle(NewTriangle); } } // this is locally optimization part // we need to make sure all triangles are locally optimized. If not optimize it. for (int I = 0; I < TriangleList.Count; ++I) { BSTriangle A = TriangleList[I]; for (int J = I + 1; J < TriangleList.Count; ++J) { BSTriangle B = TriangleList[J]; // does share same edge if (A.DoesShareSameEdge(B)) { // then test to see if locally optimized if (FlipTriangles(I, J)) { //// if this flips, remove current triangle //delete TriangleList[I]; //delete TriangleList[J]; //I need to remove J first because other wise, // index J isn't valid anymore TriangleList.RemoveAt(J); TriangleList.RemoveAt(I); // start over since we modified triangle // once we don't have any more to flip, we're good to go! I = -1; break; } } } } } return(TriangleList.Count); }