public Vertex OfferVertexToCache(Vertex vertex) { Vector3 roundedPosition = new Vector3( Mathf.Round(vertex.position.x / MERGE_POSITION_DISTANCE), Mathf.Round(vertex.position.y / MERGE_POSITION_DISTANCE), Mathf.Round(vertex.position.z / MERGE_POSITION_DISTANCE)); if (!cachedVertices.ContainsKey(roundedPosition)) { cachedVertices.Add(roundedPosition, new List<Vertex>(){ vertex }); return vertex; } foreach (Vertex cachedVertex in cachedVertices[roundedPosition]) { float angle = Vector3.Angle(cachedVertex.normal, vertex.normal); if (angle < MERGE_NORMAL_ANGLE) { return cachedVertex; } } cachedVertices[roundedPosition].Add(vertex); return vertex; }
private Vertex[] BuildNextSection(MeshBuilder meshBuilder, Vector3 curvePt, Vector3 tangent, Quaternion quat, Vertex[] lastVerts) { Vector3 pt1 = quat * new Vector3(TRACK_RADIUS * X_SCALE_TOP, TRACK_RADIUS, 0) + curvePt; Vector3 pt2 = quat * new Vector3(TRACK_RADIUS * X_SCALE_BOTTOM, -TRACK_RADIUS, 0) + curvePt; Vector3 pt3 = quat * new Vector3(-TRACK_RADIUS * X_SCALE_BOTTOM, -TRACK_RADIUS, 0) + curvePt; Vector3 pt4 = quat * new Vector3(-TRACK_RADIUS * X_SCALE_TOP, TRACK_RADIUS, 0) + curvePt; Vertex[] verts = new Vertex[]{ meshBuilder.VertAutoNormal(pt1, new Vector2(), false), meshBuilder.VertAutoNormal(pt1, new Vector2(), false), meshBuilder.VertAutoNormal(pt2, new Vector2(), false), meshBuilder.VertAutoNormal(pt2, new Vector2(), false), meshBuilder.VertAutoNormal(pt3, new Vector2(), false), meshBuilder.VertAutoNormal(pt3, new Vector2(), false), meshBuilder.VertAutoNormal(pt4, new Vector2(), false), meshBuilder.VertAutoNormal(pt4, new Vector2(), false), }; if (lastVerts != null) { meshBuilder.AddTriangleStrip(false, new Vertex[]{ verts[2], lastVerts[2], verts[1], lastVerts[1], // right side verts[0], lastVerts[0], verts[7], lastVerts[7], // top side verts[6], lastVerts[6], verts[5], lastVerts[5], // left side verts[4], lastVerts[4], verts[3], lastVerts[3], // bottom side }); } else { AddCap(meshBuilder, new Vector3[]{pt1, pt2, pt3, pt4}, false); } return verts; }
private void BuildMeshCorner(SlopedMeshBuilder meshBuilder) { MeshBuilder mBuilder = meshBuilder.builder; float curveRadius = SlopedMeshBuilder.CURVE_RADIUS; IList<Vector2> sidePts = meshBuilder.GetOuterSlopePoints(); int nSidePts = sidePts.Count; // right side List<Vertex> edgeVerticesR = new List<Vertex>(); edgeVerticesR.AddRange( sidePts.Select(pt => mBuilder.VertAutoNormal(new Vector3(1, pt.y, pt.x), new Vector2(), true))); List<Vertex> innerVerticesR = new List<Vertex>(); innerVerticesR.AddRange( sidePts.Select(pt => mBuilder.VertAutoNormal(new Vector3(1f - curveRadius, pt.y, pt.x), new Vector2(), false))); for (int i = 1; i < nSidePts; i++) { meshBuilder.builder.AddTriangleStrip(false, edgeVerticesR[i - 1], innerVerticesR[i - 1], edgeVerticesR[i], innerVerticesR[i]); } // left side List<Vertex> edgeVerticesL = new List<Vertex>(); edgeVerticesL.AddRange( sidePts.Select(pt => mBuilder.VertAutoNormal(new Vector3(pt.x, pt.y, 1), new Vector2(), true))); List<Vertex> innerVerticesL = new List<Vertex>(); innerVerticesL.AddRange( sidePts.Select(pt => mBuilder.VertAutoNormal(new Vector3(pt.x, pt.y, 1f - curveRadius), new Vector2(), false))); edgeVerticesL[nSidePts - 1] = edgeVerticesR[nSidePts - 1]; innerVerticesL[nSidePts - 1] = innerVerticesR[nSidePts - 1]; edgeVerticesL[nSidePts - 2] = innerVerticesR[nSidePts - 1]; innerVerticesL[nSidePts - 2] = innerVerticesR[nSidePts - 2]; for (int i = 1; i < nSidePts; i++) { meshBuilder.builder.AddTriangleStrip(false, innerVerticesL[i - 1], edgeVerticesL[i - 1], innerVerticesL[i], edgeVerticesL[i]); } // center Vertex[] lastVertices = new Vertex[sidePts.Count]; Vertex[] currentVertices = new Vertex[sidePts.Count]; float radius = curveRadius; for (int i = 0; i <= SlopedMeshBuilder.CURVE_DIVISIONS; i++) { float angle = (Mathf.PI / (2f * SlopedMeshBuilder.CURVE_DIVISIONS)) * i; float cosA = Mathf.Cos(angle); float sinA = Mathf.Sin(angle); for (int j = 0; j < nSidePts - 2; j++) { if (i == 0) { currentVertices[j] = innerVerticesR[j]; } else if (i == SlopedMeshBuilder.CURVE_DIVISIONS) { currentVertices[j] = innerVerticesL[j]; } else { Vector2 pt = sidePts[j]; float h = pt.x - (1 - radius); Vector3 pos = new Vector3((sinA * h) + (1f - curveRadius), pt.y, cosA * h + curveRadius); currentVertices[j] = mBuilder.VertAutoNormal(pos, new Vector2(), false); } if(i > 0 && j > 0) { meshBuilder.builder.AddTriangleStrip(false, currentVertices[j], lastVertices[j], currentVertices[j - 1], lastVertices[j - 1]); if (j == nSidePts - 3) { meshBuilder.builder.AddTriangleStrip(false, currentVertices[j], innerVerticesR[nSidePts - 2], lastVertices[j]); } } } Vertex[] tmp = lastVertices; lastVertices = currentVertices; currentVertices = tmp; } }