/** * Interpolates a list of points, inserting amt points between each vertex equally spaced * TODO: Try this formula to space by distance (this avoids dense clumping on small lists) * dx = x1 - x0 * dy = y1 - y0 * l = Sqrt(dx^2 + dy^2) * x = x0 + dx/l * t * y = y0 + dy/l * t */ public static List <Vector3> InsertPoints(List <Vector3> p, int amt) { int MaxInsertions = 200; List <Vector3> vout = new List <Vector3>(); Vector3 first = p[0]; for (int i = 0; i < p.Count; i++) { vout.Add(p[i]); if (i < p.Count - 1) { Vector3 n = p[i + 1]; Vector3 dif = n - p[i]; float stepsize = (1.0f / (float)amt); Vector3 dir = dif.normalized; float dist = Vector3.Distance(p[i], n); for (float f = 0; f < MaxInsertions; f++) { Vector3 inb = MeshTools.LerpByDistance(p[i], n, f * amt); if (Vector3.Distance(first, inb) > Vector3.Distance(first, n)) { break; } vout.Add(inb); } /* * for ( float f = stepsize; f< 1; f += stepsize) { * Vector3 inb = Vector3.Lerp(p[i], n, f); * vout.Add(inb); * } */ } } return(vout); }
public void CreateRoadGeometry() { foreach (Road r in Roads) { for (int i = 0; i < r.nodes.Count - 1; i++) { Node o1 = r.nodes[i]; Node o2 = r.nodes[i + 1]; Vector3 v1 = o1.pos - r.go.transform.position + this.transform.position; //v1 = Adjust(r, v1); //v1 += new Vector3( 0, MeshTools.GetMeshHeight(TileBoundsMeters, r.go.transform.position, mc, v1), 0); Vector3 v2 = o2.pos - r.go.transform.position + this.transform.position; //v2 = Adjust(r, v2); //v2 += new Vector3(0, MeshTools.GetMeshHeight(TileBoundsMeters, r.go.transform.position, mc, v2), 0); //TODO: if the straight angle between 2 consecutive nodes is low, skip generating connections and join directly //float angle = MeshTools.AngleBetween2D(v2-v1, v3-v2); //Debug.Log(angle); //calculate connection offsets (pull back from end point to fit intersection) Vector3 mv1s = MeshTools.LerpByDistance(v1, v2, r.width); //GameObject go1 = GameObject.CreatePrimitive(PrimitiveType.Sphere); //go1.transform.position = mv1; Vector3 mv1e = MeshTools.LerpByDistance(v2, v1, r.width); //GameObject go2 = GameObject.CreatePrimitive(PrimitiveType.Sphere); //go2.transform.position = mv2; //float dist = (v2.pos - v1.pos).magnitude; Vector3 n1 = MeshTools.GetNormal(v1, v1, v2) * r.width; // if (RoadHighQuality == true) { r.CreateHQStraight(mv1s, mv1e, n1, mc); } else { r.CreateStraight(mv1s, mv1e, n1); } //create connecting geometry between 2 connected line nodes, e.g. an elbow or t if (i < r.nodes.Count - 2) { Node o3 = r.nodes[i + 2]; Vector3 v3 = o3.pos - r.go.transform.position + this.transform.position; //v3 += new Vector3(0, MeshTools.GetMeshHeight(TileBoundsMeters, r.go.transform.position, mc, v3), 0); //v3 = Adjust(r, v3); Vector3 mv2s = MeshTools.LerpByDistance(v2, v3, r.width); //GameObject go3 = GameObject.CreatePrimitive(PrimitiveType.Sphere); //go3.transform.position = mv3; //v2 = MeshTools.LerpByDistance(v3, v2, r.width); Vector3 n2 = MeshTools.GetNormal(v2, v2, v3) * r.width; // r.CreateConnection(mv2, mv3, n1, n2); r.CreateSmoothConnection(v1, v2, v2, v3, mv1e, mv2s, n1, n2); } } r.CreateMesh(); //MeshTools.FitMeshToTerrain(TileBoundsMeters, r.go.transform.position - this.transform.position, mc, r.m); //MeshTools.UpdatePivot(r.go, r.m); r.go.AddComponent <MeshFilter>().mesh = r.m; MeshRenderer re = r.go.AddComponent <MeshRenderer>(); re.material = GetMaterialForKind(r.kind, r.kind_detail); r.m.RecalculateBounds(); re.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; re.receiveShadows = true; r.go.AddComponent <MeshCollider>(); } this.transform.position = new Vector3(0, 0.1f, 0); }
//n2 is used for the end angle // v1,v2 = point2 pulled away from intersection public void CreateHQStraight(Vector3 v1, Vector3 v2, Vector3 n1, MeshCollider Terrain) { float dist = Vector3.Distance(v1, v2); int i; float steps = dist / MetersPerTile; int isteps = Mathf.FloorToInt(steps); for (i = 0; i <= isteps; i++) { Vector3 vv1 = MeshTools.LerpByDistance(v1, v2, i * MetersPerTile); Vector3 vv2; //if we are on the last step (always equal or smaller than MetersPerTile) then use v2 rather than lerp if (i > isteps - 1) { vv2 = v2; vscale = steps - isteps; } else //otherwise create a segment MetersPerTile long { vv2 = MeshTools.LerpByDistance(v1, v2, i * MetersPerTile + MetersPerTile); vscale = 1; } vv1 += new Vector3(0, MeshTools.GetMeshHeightSimple(Terrain, vv1) + 1, 0); vv2 += new Vector3(0, MeshTools.GetMeshHeightSimple(Terrain, vv2) + 1, 0); v.Add(vv1 - n1); t.Add(v.Count - 1); v.Add(vv1 + n1); t.Add(v.Count - 1); v.Add(vv2 - n1); t.Add(v.Count - 1); u.Add(new Vector2(0, 0)); u.Add(new Vector2(1, 0)); u.Add(new Vector2(0, vscale)); v.Add(vv1 + n1); t.Add(v.Count - 1); v.Add(vv2 + n1); t.Add(v.Count - 1); v.Add(vv2 - n1); t.Add(v.Count - 1); u.Add(new Vector2(1, 0)); u.Add(new Vector2(1, vscale)); u.Add(new Vector2(0, vscale)); if (kind != KIND_PATH) { //add sidewalk v.Add(vv1 - n1 * 2 + new Vector3(0, -3, 0)); t.Add(v.Count - 1); v.Add(vv1 - n1); t.Add(v.Count - 1); v.Add(vv2 - n1); t.Add(v.Count - 1); u.Add(new Vector2(0, 0)); u.Add(new Vector2(1, 0)); u.Add(new Vector2(0, vscale)); v.Add(vv1 - n1 * 2 + new Vector3(0, -3, 0)); t.Add(v.Count - 1); v.Add(vv2 - n1); t.Add(v.Count - 1); v.Add(vv2 - n1 * 2 + new Vector3(0, -3, 0)); t.Add(v.Count - 1); u.Add(new Vector2(0, 0)); u.Add(new Vector2(1, 0)); u.Add(new Vector2(0, vscale)); //add sidewalk 2 v.Add(vv2 + n1); t.Add(v.Count - 1); v.Add(vv1 + n1); t.Add(v.Count - 1); v.Add(vv1 + n1 * 2 + new Vector3(0, -3, 0)); t.Add(v.Count - 1); u.Add(new Vector2(0, 0)); u.Add(new Vector2(1, 0)); u.Add(new Vector2(0, vscale)); v.Add(vv2 + n1 * 2 + new Vector3(0, -3, 0)); t.Add(v.Count - 1); v.Add(vv2 + n1); t.Add(v.Count - 1); v.Add(vv1 + n1 * 2 + new Vector3(0, -3, 0)); t.Add(v.Count - 1); u.Add(new Vector2(0, 0)); u.Add(new Vector2(1, 0)); u.Add(new Vector2(0, vscale)); } } //Debug.Log("d:" + (dist - i)); }