/// <summary> /// Procedurally generate an object from the data given in the OsmWay instance. /// </summary> /// <param name="way">OsmWay instance</param> /// <param name="mat">Material to apply to the instance</param> /// <param name="objectName">The name of the object (building name, road etc.)</param> protected void CreateObject(BaseOSMLib.OsmWay way, Material mat, string objectName) { // Make sure we have some name to display objectName = string.IsNullOrEmpty(objectName) ? "OsmWay" : objectName; // Create an instance of the object and place it in the centre of its points GameObject go = new GameObject(objectName); Vector3 localOrigin = GetCentre(way); go.transform.position = localOrigin - map.bounds.Centre; // Add the mesh filter and renderer components to the object MeshFilter mf = go.AddComponent <MeshFilter>(); MeshRenderer mr = go.AddComponent <MeshRenderer>(); // Apply the material mr.material = mat; // Create the collections for the object's vertices, indices, UVs etc. List <Vector3> vectors = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); List <Vector2> uvs = new List <Vector2>(); List <int> indices = new List <int>(); // Call the child class' object creation code OnObjectCreated(way, localOrigin, vectors, normals, uvs, indices); // Apply the data to the mesh mf.sharedMesh = new Mesh(); mf.sharedMesh.vertices = vectors.ToArray(); mf.sharedMesh.normals = normals.ToArray(); mf.sharedMesh.triangles = indices.ToArray(); mf.sharedMesh.uv = uvs.ToArray(); }
void GetWays(XmlNodeList xmlNodeList) { foreach (XmlNode node in xmlNodeList) { BaseOSMLib.OsmWay way = new OsmWay(node); ways.Add(way); } }
/// <summary> /// Get the centre of an object or road. /// </summary> /// <param name="way">OsmWay object</param> /// <returns>The centre point of the object</returns> protected Vector3 GetCentre(BaseOSMLib.OsmWay way) { Vector3 total = Vector3.zero; foreach (var id in way.NodeIDs) { total += map.nodes[id]; } return(total / way.NodeIDs.Count); }
protected override void OnObjectCreated(BaseOSMLib.OsmWay way, Vector3 origin, List <Vector3> vectors, List <Vector3> normals, List <Vector2> uvs, List <int> indices) { for (int i = 1; i < way.NodeIDs.Count; i++) { OsmNode p1 = map.nodes[way.NodeIDs[i - 1]]; OsmNode p2 = map.nodes[way.NodeIDs[i]]; Vector3 s1 = p1 - origin; Vector3 s2 = p2 - origin; Vector3 diff = (s2 - s1).normalized; // https://en.wikipedia.org/wiki/Lane // According to the article, it's 3.7m in Canada var cross = Vector3.Cross(diff, Vector3.up) * 3.7f * way.Lanes; // Create points that represent the width of the road Vector3 v1 = s1 + cross; Vector3 v2 = s1 - cross; Vector3 v3 = s2 + cross; Vector3 v4 = s2 - cross; vectors.Add(v1); vectors.Add(v2); vectors.Add(v3); vectors.Add(v4); uvs.Add(new Vector2(0, 0)); uvs.Add(new Vector2(1, 0)); uvs.Add(new Vector2(0, 1)); uvs.Add(new Vector2(1, 1)); normals.Add(Vector3.up); normals.Add(Vector3.up); normals.Add(Vector3.up); normals.Add(Vector3.up); int idx1, idx2, idx3, idx4; idx4 = vectors.Count - 1; idx3 = vectors.Count - 2; idx2 = vectors.Count - 3; idx1 = vectors.Count - 4; // first triangle v1, v3, v2 indices.Add(idx1); indices.Add(idx3); indices.Add(idx2); // second v3, v4, v2 indices.Add(idx3); indices.Add(idx4); indices.Add(idx2); } }
/// <summary> /// Build the object using the data from the OsmWay instance. /// </summary> /// <param name="way">OsmWay instance</param> /// <param name="origin">The origin of the structure</param> /// <param name="vectors">The vectors (vertices) list</param> /// <param name="normals">The normals list</param> /// <param name="uvs">The UVs list</param> /// <param name="indices">The indices list</param> protected override void OnObjectCreated(BaseOSMLib.OsmWay way, Vector3 origin, List <Vector3> vectors, List <Vector3> normals, List <Vector2> uvs, List <int> indices) { // Get the centre of the roof Vector3 oTop = new Vector3(0, way.Height, 0); // First vector is the middle point in the roof vectors.Add(oTop); normals.Add(Vector3.up); uvs.Add(new Vector2(0.5f, 0.5f)); for (int i = 1; i < way.NodeIDs.Count; i++) { OsmNode p1 = map.nodes[way.NodeIDs[i - 1]]; OsmNode p2 = map.nodes[way.NodeIDs[i]]; Vector3 v1 = p1 - origin; Vector3 v2 = p2 - origin; Vector3 v3 = v1 + new Vector3(0, way.Height, 0); Vector3 v4 = v2 + new Vector3(0, way.Height, 0); vectors.Add(v1); vectors.Add(v2); vectors.Add(v3); vectors.Add(v4); uvs.Add(new Vector2(0, 0)); uvs.Add(new Vector2(1, 0)); uvs.Add(new Vector2(0, 1)); uvs.Add(new Vector2(1, 1)); normals.Add(-Vector3.forward); normals.Add(-Vector3.forward); normals.Add(-Vector3.forward); normals.Add(-Vector3.forward); int idx1, idx2, idx3, idx4; idx4 = vectors.Count - 1; idx3 = vectors.Count - 2; idx2 = vectors.Count - 3; idx1 = vectors.Count - 4; // first triangle v1, v3, v2 indices.Add(idx1); indices.Add(idx3); indices.Add(idx2); // second v3, v4, v2 indices.Add(idx3); indices.Add(idx4); indices.Add(idx2); // third v2, v3, v1 indices.Add(idx2); indices.Add(idx3); indices.Add(idx1); // fourth v2, v4, v3 indices.Add(idx2); indices.Add(idx4); indices.Add(idx3); // And now the roof triangles indices.Add(0); indices.Add(idx3); indices.Add(idx4); // Don't forget the upside down one! indices.Add(idx4); indices.Add(idx3); indices.Add(0); } }
protected abstract void OnObjectCreated(BaseOSMLib.OsmWay way, Vector3 origin, List <Vector3> vectors, List <Vector3> normals, List <Vector2> uvs, List <int> indices);