void GenerateGeometry(List <List <Vector3> > segments, GameObject container, IDictionary properties, string type) { string pname = OSMTools.GetProperty(properties, "name"); // Debug.Log( "Processing:" + pname); //List<Vector2> points = new List<Vector2>(); GameObject go = new GameObject("building"); go.transform.parent = container.transform; go.layer = LayerMask.NameToLayer("Buildings"); go.name = pname; //go.transform.position = segments[0][0]; go.transform.localPosition = Vector3.zero; //go.name = properties["kind"].ToString(); MassiveFeature f = go.AddComponent <MassiveFeature>(); f.SetProperties(properties); f.SetSegments(segments); f.SetType(type); //if height it not present assume 1 floor height = f.height == 0 ? 5 : f.height; CreateRoof(segments, go); CreateWalls(segments, go); MeshTools.MoveGameObjectToTerrain(TileBoundsMeters, this.transform.position, mc, go, Walls.GetComponent <MeshFilter>().sharedMesh); //create roof //MeshTools.FitMeshToTerrain(TileBoundsMeters, this.transform.position, mc, msh); //MeshTools.MoveMeshToTerrain(TileBoundsMeters, this.transform.position, mc, msh, f.height, go); }
void CreateWall(UnityEngine.Mesh m, List <Vector3> wall, float height, GameObject parent) { if (MeshTools.IsClockwise(wall)) { wall.Reverse(); } List <Vector3> v = new List <Vector3>(); m.GetVertices(v); List <int> t = new List <int>(); m.GetTriangles(t, 0); List <Vector2> uv = new List <Vector2>(); m.GetUVs(0, uv); Vector3 h = new Vector3(0, height, 0); for (int i = 0; i < wall.Count - 1; i++) { Vector3 v1b = wall[i]; Vector3 v2b = wall[i + 1]; Vector3 v1t = v1b + h; Vector3 v2t = v2b + h; v.Add(v1b); t.Add(v.Count - 1); uv.Add(new Vector2(0, 1 * height)); v.Add(v1t); t.Add(v.Count - 1); uv.Add(new Vector2(0, 0)); v.Add(v2b); t.Add(v.Count - 1); uv.Add(new Vector2(1, 1 * height)); v.Add(v1t); t.Add(v.Count - 1); uv.Add(new Vector2(0, 0)); v.Add(v2t); t.Add(v.Count - 1); uv.Add(new Vector2(1, 0)); v.Add(v2b); t.Add(v.Count - 1); uv.Add(new Vector2(1, 1 * height)); } m.SetVertices(v); m.SetTriangles(t, 0); m.SetUVs(0, uv); }
/** * 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); }
void CreateRoof(List <List <Vector3> > segments, GameObject parent) { GameObject Roof = new GameObject("roof"); Roof.transform.parent = parent.transform; Roof.transform.localPosition = Vector3.zero; Roof.layer = LayerMask.NameToLayer("Buildings"); UnityEngine.Mesh msh = new UnityEngine.Mesh(); msh = MeshTools.Triangulate(segments); List <Vector3> v = new List <Vector3>(); msh.GetVertices(v); for (int i = 0; i < v.Count; i++) { if (i == 0) { Roof.transform.position = v[i]; } v[i] = new Vector3(v[i].x, height, v[i].z) - Roof.transform.position + this.transform.position; } msh.SetVertices(v); MeshTools.CreateUVS(TileBoundsMeters, msh); msh.RecalculateNormals(); msh.RecalculateTangents(); msh.RecalculateBounds(); // Set up game object with mesh; MeshRenderer r = Roof.AddComponent <MeshRenderer>(); r.material = RoofMaterial; r.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On; MeshFilter filter = Roof.AddComponent(typeof(MeshFilter)) as MeshFilter; filter.mesh = msh; //Roof.AddComponent<MeshCollider>(); //required for mesh fix }
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)); }