public void Init(RoadSegment p, RoadSegmentValues vals, MeshCrossection shape, Material mat) { this.parentScript = p; this.values = vals; this.materialToAssign = mat; this.shape2D = shape; GenerateMeshAndInit(); }
public override void OnInspectorGUI() { mCross = target as MeshCrossection; if (GUILayout.Button("Set Normals")) { Undo.RecordObject(mCross, "SetNormals"); mCross.SetNormals(); EditorUtility.SetDirty(mCross); } base.OnInspectorGUI(); }
public void GenerateMeshAndInit(bool useScaleAsOffset = false, MeshCrossection parentC = null) { if (subMeshes != null) { for (int i = 0; i < subMeshes.Count; i++) { subMeshes[i].GenerateMeshAndInit(!scaleSubmeshes, shape2D); } } values.mesh = new Mesh(); values.mesh.name = "GeneratedMesh"; GetComponent <MeshFilter>().sharedMesh = values.mesh; GetComponent <MeshCollider>().sharedMesh = values.mesh; SetMeshMaterial(); GenerateMesh(useScaleAsOffset, parentC); }
public void CreateNewSubmesh() { GameObject go = new GameObject(); RoadSegmentSubmesh submesh = go.AddComponent <RoadSegmentSubmesh>(); submesh.Init(this, values, newShape, newMaterial); go.transform.parent = transform; go.transform.localRotation = Quaternion.identity; go.transform.localPosition = Vector3.zero; newShape = null; newMaterial = null; if (subMeshes == null) { subMeshes = new List <RoadSegmentSubmesh>(); } subMeshes.Add(submesh); }
public void DisplayMeshMenu() { EditorGUILayout.BeginHorizontal(); GUILayout.Label("Base road mesh: "); MeshCrossection shape = values.road.shape2D; shape = EditorGUILayout.ObjectField(values.road.shape2D, typeof(MeshCrossection), true) as MeshCrossection; if (shape != values.road.shape2D) { values.road.shape2D = shape; if (values.road.materialToAssign != null) { values.road.GenerateMeshAndInit(); } } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("Base road material: "); Material m = values.road.materialToAssign; m = EditorGUILayout.ObjectField(values.road.materialToAssign, typeof(Material), false) as Material; if (m != values.road.materialToAssign) { values.road.materialToAssign = m; if (values.road.shape2D != null) { values.road.GenerateMeshAndInit(); } } EditorGUILayout.EndHorizontal(); // add in submeshes when buttons are pressed if (values.isAssigningSubmesh) { GUILayout.Label(""); EditorGUI.indentLevel++; EditorGUILayout.BeginHorizontal(); GUILayout.Label("New submesh: "); MeshCrossection s = values.newShapeToAdd; s = EditorGUILayout.ObjectField(values.newShapeToAdd, typeof(MeshCrossection), false) as MeshCrossection; if (s != values.newShapeToAdd) { values.newShapeToAdd = s; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("Submesh material: "); Material mN = values.newMaterialToAdd; mN = EditorGUILayout.ObjectField(values.newMaterialToAdd, typeof(Material), false) as Material; if (mN != values.newMaterialToAdd) { values.newMaterialToAdd = mN; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if (values.newShapeToAdd == null || values.newMaterialToAdd == null) { EditorGUILayout.HelpBox("Make sure you assign a new MeshCrossection AND a new material.", MessageType.Error); } else { if (GUILayout.Button("Add submesh", GUILayout.Height(bigButtonHeight))) { values.road.AddNewSubmesh(values.newShapeToAdd, values.newMaterialToAdd); values.isAssigningSubmesh = false; } } if (GUILayout.Button("Cancel", GUILayout.Height(bigButtonHeight))) { values.isAssigningSubmesh = false; } EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel--; } else { EditorGUILayout.BeginVertical(); EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button("Add new submesh", GUILayout.Height(smallButtonHeight), GUILayout.Width(smallButtonWidth))) { values.isAssigningSubmesh = true; } GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); } GUILayout.Label(""); }
private void GenerateMesh(bool useScaleAsOffset = false, MeshCrossection parentC = null) { values.mesh.Clear(); float uSpan = shape2D.GetLinesLength(); List <Vector3> verts = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); List <Vector2> uvs = new List <Vector2>(); for (int currentEdgeRing = 0; currentEdgeRing < values.edgeRingCount; currentEdgeRing++) { float splineLength = values.spline.GetSplineLength(10f); float t = currentEdgeRing / (values.edgeRingCount - 1f); if (values.scaleToEnd) { values.scale = Mathf.Lerp(values.scaleAtStart, values.scaleAtEnd, t); } else if (values.scaleByCurve) { values.scale = values.scaleCurve.Evaluate(t); } else { values.scale = values.scaleAtStart; } values.scaleToEnd = (values.scaleAtEnd != values.scaleAtStart); float multiplier = (values.useMultiplier) ? values.scale : 1f; OrientedPoint op = values.spline.GetOrientedPoint(t); Vector3 innerNeg = new Vector3(); Vector3 innerPos = new Vector3(); if (scaleSubmeshes && parentC != null) { int inNeg = -1; int inPos = -1; float inP = 100000f; float inN = -100000f; for (int u = 0; u < parentC.VertexCount; u++) { float xpos = parentC.vertices[u].point.x; if (xpos >= inN) { inN = xpos; inNeg = u; } if (xpos <= inP) { inP = xpos; inPos = u; } } innerNeg = parentC.vertices[inNeg].point * transform.lossyScale; innerPos = parentC.vertices[inPos].point * transform.lossyScale; } for (int i = 0; i < shape2D.VertexCount; i++) { Vector3 p = (Vector3)(shape2D.vertices[i].point); if (!useScaleAsOffset) { p.x = ((values.scaleX) ? p.x * values.scale : p.x) * transform.lossyScale.x; p.y = ((values.scaleY) ? p.y * values.scale : p.y) * transform.lossyScale.y; p.z = ((values.scaleZ) ? p.z * values.scale : p.z) * transform.lossyScale.z; } else { p.x = (p.x == 0) ? p.x : ((p.x < 0) ? p.x - values.scale : p.x + values.scale) * transform.lossyScale.x; p.y = ((values.scaleY) ? p.y * values.scale : p.y) * transform.lossyScale.y; p.z = ((values.scaleZ) ? p.z * values.scale : p.z) * transform.lossyScale.z; if (p.x < 0) { float o = (innerNeg * values.scale).x; p.x = (p.x - o) + innerNeg.x + (values.scale * transform.lossyScale.x); } else if (p.x > 0) { float o = (innerPos * values.scale).x; p.x = (p.x - o) + innerPos.x - (values.scale * transform.lossyScale.x); } } verts.Add(transform.InverseTransformPoint(op.LocalToWorldPosition(p * multiplier) + values.localOffset)); normals.Add(op.LocalToWorldVector((Vector3)(shape2D.vertices[i].normal))); uvs.Add( new Vector2(values.uvOffset.x + (currentEdgeRing / (float)values.edgeRingCount - 1) * values.uMultiplier, values.uvOffset.y + (i / (float)shape2D.VertexCount) * splineLength / uSpan * (1 / values.uvRepeatScale) )); } } List <int> triangleIndices = new List <int>(); for (int r = 0; r < values.edgeRingCount - 1; r++) { int rootIndex = r * shape2D.VertexCount; int rootIndexNext = (r + 1) * shape2D.VertexCount; for (int l = 0; l < shape2D.LineCount; l += 2) { int lineIndexA = shape2D.lines[l]; int lineIndexB = shape2D.lines[l + 1]; int currentA = rootIndex + lineIndexA; int currentB = rootIndex + lineIndexB; int nextA = rootIndexNext + lineIndexA; int nextB = rootIndexNext + lineIndexB; // tri 1 triangleIndices.Add(currentA); triangleIndices.Add(nextA); triangleIndices.Add(nextB); // tri 2 triangleIndices.Add(currentA); triangleIndices.Add(nextB); triangleIndices.Add(currentB); } } values.mesh.SetVertices(verts); values.mesh.SetNormals(normals); values.mesh.SetTriangles(triangleIndices, 0); values.mesh.RecalculateBounds(); values.mesh.RecalculateNormals(); values.mesh.RecalculateTangents(); values.mesh.uv = uvs.ToArray(); GetComponent <MeshCollider>().sharedMesh = values.mesh; gameObject.layer = values.layerToAssign; }
public void AddNewSubmesh(MeshCrossection m, Material mat) { newShape = m; newMaterial = mat; CreateNewSubmesh(); }