// Calculate the length of the array's private void CalculateArrayLengths(MeshSettingsContainer mesh) { int amountVertices, amountTriangles; if (!mesh.isSeperateObj) { amountVertices = DataTools.curvePoints.Count * mesh.amountVertex; int trianglesPerMesh = (mesh.amountVertex * 6) - (mesh.loopMesh ? 0 : 6); // Triangles used for to connect two pieces together amountTriangles = (DataTools.curvePoints.Count * trianglesPerMesh - trianglesPerMesh); if (mesh.symmetry) // Add extra space in the arrays for symmetry mode { amountVertices *= 2; amountTriangles *= 2; } } else { amountVertices = DataTools.curvePoints.Count * mesh.amountVertex; amountTriangles = DataTools.curvePoints.Count * mesh.amountTriangle; } // Init the array's mesh.vertices = new Vector3[amountVertices]; mesh.triangles = new int[amountTriangles]; mesh.normals = new Vector3[amountVertices]; mesh.UVs = new Vector2[amountVertices]; }
/// <summary> /// Function to clean up a used mesh by trying to index the vertices correctly /// This will assume that the vertices are placed ontop of each other in the y-axis /// It will also assume that when the vertices need to come down it will be in the negative x-axis /// </summary> public void CleanMesh(MeshSettingsContainer mesh) { // Reset local mesh data mesh.localVerticeData = null; mesh.localTriangleData = null; mesh.localUVData = null; mesh.localNormalData = null; // The code will use the reordered vertices. If those are not available because the mesh already has faces and a order, it will set this reference if (mesh.isSeperateObj) { mesh.newVerticeOrder = mesh.localVerticeData; return; } mesh.newVerticeOrder = new Vector3[mesh.amountVertex]; for (int iVert = 0; iVert < mesh.amountVertex; iVert++) { // Start at the highest index possible int newIndex = (mesh.localVerticeData[iVert].x < 0) ? mesh.amountVertex / 2 : mesh.amountVertex / 2 - 1; for (int otherVert = 0; otherVert < mesh.amountVertex; otherVert++) { if (otherVert == iVert) // Skip if same { continue; } float vertDataX = mesh.localVerticeData[iVert].x; float vertDataY = mesh.localVerticeData[iVert].y; float otherVertDataX = mesh.localVerticeData[otherVert].x; float otherVertDataY = mesh.localVerticeData[otherVert].y; // Vertices need to be ordered by going up on the positive side and down the negative side if (vertDataX < 0 && otherVertDataX < 0) // Check if both vertices are on the negative sides { if (vertDataY < otherVertDataY) // Increase index when the otherVert is higher { newIndex++; } } else if (vertDataX > 0 && otherVertDataX > 0) // Check if both vertices are on the positive sides { if (vertDataY < otherVertDataY) // Lower index when the otherVert is higher { newIndex--; } } } mesh.newVerticeOrder[newIndex] = mesh.localVerticeData[iVert]; } }
private void LoopThroughMeshes(bool doSeperateObj) { foreach (MeshSettingsContainer mesh in MeshEditor.settings.container) { if (mesh.isAllowedToGenerate && (doSeperateObj == mesh.isSeperateObj)) { m = mesh; // Set current mesh TrackManager.meshTools.InitData(m); CreateMesh(); } } }
// Draw for each mesh setting container the settings private void DrawMeshSettings(MeshSettingsContainer mesh, int meshIndex) { GUILayout.Space(10); GUILayout.Label("Settings", style.titleStyle); // Mesh reference EditorGUI.BeginChangeCheck(); style.DrawObjectField("Mesh Object", ref mesh.usedMesh); // Clean the mesh when it changed if (EditorGUI.EndChangeCheck()) { TrackManager.meshTools.CleanMesh(mesh); } if (mesh.usedMesh) { // Draw this mesh y/n style.DrawToggle("Create Mesh", ref mesh.createMesh); if (mesh.createMesh) { // Draw settings for object without a triangle in the input mesh if (!mesh.isSeperateObj) { // Draw symmetry mode GUILayout.Label("Mesh Settings", style.textStyle); style.DrawToggle("Symmetry Mode", ref mesh.symmetry); // Draw loop mesh setting style.DrawToggle("Loop Mesh Around", ref mesh.loopMesh); } // Settings unavailable for mesh with triangles else if (settings.showInfo) { mesh.symmetry = false; mesh.loopMesh = false; style.DrawInfo("Loop Mesh and symmetry modes are not available when the mesh has faces."); } // Draw flip normal setting style.DrawToggle("Flip Normals", ref mesh.flipNormals); // Draw offset settings GUILayout.Label("Offset of the mesh", style.textStyle); style.DrawFloatField("Offset Mesh X", ref mesh.offsetFromCurveX, -100, 100); style.DrawFloatField("Offset Mesh Y", ref mesh.offsetFromCurveY, -100, 100); // Draw size settings GUILayout.Label("Size of the mesh", style.textStyle); style.DrawFloatField("Mesh Size X", ref mesh.localSizeOfMeshX, 0.01f); style.DrawFloatField("Mesh Size Y", ref mesh.localSizeOfMeshY, 0.01f); if (mesh.isSeperateObj) { style.DrawFloatField("Mesh Size Z", ref mesh.localSizeOfMeshZ, 0.01f); } else if (settings.showInfo) { mesh.localSizeOfMeshZ = 0; style.DrawInfo("The size of the mesh in the Z axis is unavailable when the mesh does not have faces."); } // Check if mesh size is not too small if (mesh.localSizeOfMeshX < 0.1f || mesh.localSizeOfMeshY < 0.1f || (mesh.isSeperateObj && mesh.localSizeOfMeshZ < 0.1f)) { SendMessageRequest("Size of the mesh is really small! Mesh might not be visible.", meshIndex, WarningStatus.Warning); } GUILayout.Label("Materials", style.textStyle); style.DrawObjectField("Main Material", ref mesh.materialInput); if (!mesh.materialInput) { SendMessageRequest("Material is not assigned, mesh will display as error material.", meshIndex, WarningStatus.Warning); } } else if (settings.showInfo) { style.DrawInfo("This mesh will not be generated."); } } else { SendMessageRequest("The settings need a mesh to operate!", meshIndex, WarningStatus.Error); } }
private int indexOffsetForSymmetry; // Calculate the offset for when the mesh uses symmetry mode public void InitData(MeshSettingsContainer m) { this.m = m; indexOffsetForSymmetry = m.vertices.Length / 2; }