public static void CreateMeshes() { Transform holder = new GameObject("MapMeshes").transform; holder.transform.SetParent(GameManager.Instance.transform); //walls { int index = 0; foreach (Linedef l in MapLoader.linedefs) { //if (l.lineType > 0 || l.lineTag > 0) //Debug.Log("Line " + index + " type: " + l.lineType + " tag: " + l.lineTag); //add linedef to the fast lookup cache AxMath.CartesianLineF(l.start.Position, l.end.Position).Perform((n) => { int gridX = n.Data.x - TheGrid.origoX; int gridY = n.Data.y - TheGrid.origoY; TheGrid.linedefs[gridX, gridY].Add(l); TheGrid.existenceBox.data[gridX, gridY] = true; }); if (l.Back != null) { //top part (front) if (l.Front.Sector.ceilingHeight > l.Back.Sector.ceilingHeight) { l.TopFrontObject = CreateLineQuad ( l.Front, l.Back.Sector.ceilingHeight, l.Front.Sector.ceilingHeight + (l.Back.Sector.ceilingHeight - l.Back.Sector.minimumCeilingHeight), l.Front.tHigh, l.Front.offsetX, (l.flags & (1 << 3)) != 0 ? l.Front.offsetY : -l.Front.offsetY, (l.flags & (1 << 3)) != 0 ? 0 : 1, false, l.Front.Sector.brightness, true, "Wall_" + index + "_top_front", holder ); } //lowering ceiling (front) else if (l.Front.Sector.ceilingHeight > l.Back.Sector.minimumCeilingHeight) { l.TopFrontObject = CreateLineQuad ( l.Front, l.Back.Sector.ceilingHeight, l.Front.Sector.ceilingHeight + (l.Back.Sector.ceilingHeight - l.Back.Sector.minimumCeilingHeight), l.Front.tHigh, l.Front.offsetX, (l.flags & (1 << 3)) != 0 ? l.Front.offsetY : -l.Front.offsetY, (l.flags & (1 << 3)) != 0 ? 0 : 1, false, l.Front.Sector.brightness, true, "Wall_" + index + "_top_front", holder ); } //top part (back) if (l.Front.Sector.ceilingHeight < l.Back.Sector.ceilingHeight) { l.TopBackObject = CreateLineQuad ( l.Back, l.Front.Sector.ceilingHeight, l.Back.Sector.ceilingHeight, l.Back.tHigh, l.Back.offsetX, (l.flags & (1 << 3)) != 0 ? l.Back.offsetY : l.Back.offsetY, (l.flags & (1 << 3)) != 0 ? 0 : 1, true, l.Back.Sector.brightness, true, "Wall_" + index + "_top_back", holder ); } //bottom part (front) if (l.Front.Sector.minimumFloorHeight < l.Back.Sector.floorHeight) { l.BotFrontObject = CreateLineQuad ( l.Front, l.Front.Sector.minimumFloorHeight, l.Back.Sector.floorHeight, l.Front.tLow, l.Front.offsetX, l.Front.offsetY, ((l.flags & (1 << 4)) != 0) ? 2 : 0, false, l.Front.Sector.brightness, true, "Wall_" + index + "_bot_front", holder ); } //rising floor (front) else if (l.Front.Sector.maximumFloorHeight > l.Back.Sector.floorHeight && l.Front.Sector.maximumFloorHeight > l.Front.Sector.floorHeight) { l.BotFrontObject = CreateLineQuad ( l.Front, l.Front.Sector.floorHeight - (l.Front.Sector.maximumFloorHeight - l.Back.Sector.floorHeight), l.Front.Sector.floorHeight, l.Front.tLow, l.Front.offsetX, l.Front.offsetY, ((l.flags & (1 << 4)) != 0) ? 2 : 0, false, l.Front.Sector.brightness, true, "Wall_" + index + "_bot_front", holder ); } //bottom part (back) if (l.Front.Sector.floorHeight > l.Back.Sector.minimumFloorHeight) { l.BotBackObject = CreateLineQuad ( l.Back, l.Back.Sector.minimumFloorHeight, l.Front.Sector.floorHeight, l.Back.tLow, l.Back.offsetX, l.Front.offsetY, ((l.flags & (1 << 4)) != 0) ? 2 : 0, true, l.Back.Sector.brightness, true, "Wall_" + index + "_bot_back", holder ); } //rising floor (back) else if (l.Back.Sector.maximumFloorHeight > l.Front.Sector.floorHeight && l.Back.Sector.maximumFloorHeight > l.Back.Sector.floorHeight) { l.BotBackObject = CreateLineQuad ( l.Front, l.Back.Sector.floorHeight - (l.Back.Sector.maximumFloorHeight - l.Front.Sector.floorHeight), l.Back.Sector.floorHeight, l.Front.tLow, l.Front.offsetX, l.Front.offsetY, ((l.flags & (1 << 4)) != 0) ? 2 : 0, false, l.Front.Sector.brightness, true, "Wall_" + index + "_bot_front", holder ); } //middle (front) if (l.Front.tMid != "-") { l.MidFrontObject = CreateLineQuad ( l.Front, Mathf.Max(l.Front.Sector.floorHeight, l.Back.Sector.floorHeight), Mathf.Min(l.Front.Sector.ceilingHeight, l.Back.Sector.ceilingHeight), l.Front.tMid, l.Front.offsetX, l.Front.offsetY, ((l.flags & (1 << 4)) != 0) ? 1 : 0, false, l.Front.Sector.brightness, false, "Wall_" + index + "_mid_front", holder ); } //middle (back) if (l.Back.tMid != "-") { l.MidBackObject = CreateLineQuad ( l.Back, Mathf.Max(l.Front.Sector.floorHeight, l.Back.Sector.floorHeight), Mathf.Min(l.Front.Sector.ceilingHeight, l.Back.Sector.ceilingHeight), l.Back.tMid, l.Back.offsetX, l.Back.offsetY, ((l.flags & (1 << 4)) != 0) ? 1 : 0, true, l.Back.Sector.brightness, false, "Wall_" + index + "_mid_back", holder ); } if ((l.flags & (1 << 0)) != 0) { CreateInvisibleBlocker ( l, Mathf.Max(l.Front.Sector.floorHeight, l.Back.Sector.floorHeight), Mathf.Min(l.Front.Sector.ceilingHeight, l.Back.Sector.ceilingHeight), "Wall_" + index + "_blocker", holder ); } } else //solid wall { l.MidFrontObject = CreateLineQuad ( l.Front, l.Front.Sector.minimumFloorHeight, l.Front.Sector.maximumCeilingHeight, l.Front.tMid, l.Front.offsetX, l.Front.offsetY, ((l.flags & (1 << 4)) != 0) ? 1 : 0, false, l.Front.Sector.brightness, true, "Wall_" + index, holder ); } index++; } } //sectors { Triangulator triangulator = new Triangulator(); int index = 0; foreach (Sector s in MapLoader.sectors) { //if (s.specialType > 0 || s.tag > 0) //Debug.Log("Sector " + index + " type: " + s.specialType + " tag: " + s.tag); triangulator.Triangulate(s); if (Triangulator.vertices.Count == 0) { Debug.Log("Triangulation failed for sector " + index); } //floor { GameObject sectorObject = new GameObject("Sector_" + index + "_floor"); s.floorObject = sectorObject.AddComponent <SectorController>(); sectorObject.transform.SetParent(holder); MeshRenderer mr = sectorObject.AddComponent <MeshRenderer>(); MeshFilter meshFilter = sectorObject.AddComponent <MeshFilter>(); Mesh mesh = new Mesh(); meshFilter.mesh = mesh; if (!MaterialManager.Instance.OverridesFlat(s.floorTexture, sectorObject, mr)) { mr.material = MaterialManager.Instance.defaultMaterial; } if (mr.material.mainTexture == null) { MaterialPropertyBlock materialProperties = new MaterialPropertyBlock(); materialProperties.SetTexture("_MainTex", TextureLoader.Instance.GetFlatTexture(s.floorTexture)); mr.SetPropertyBlock(materialProperties); } mesh.name = "Sector_" + index + "_floor_mesh"; int vc = Triangulator.vertices.Count; Vector3[] vertices = new Vector3[vc]; Vector3[] normals = new Vector3[vc]; Vector2[] uvs = new Vector2[vc]; Color[] colors = new Color[vc]; int[] indices = new int[vc]; int v = 0; int i = 0; int g = 0; Triangle t = null; BooleanBox[] bboxes = new BooleanBox[Triangulator.vertices.Count / 3]; foreach (Vector2 p in Triangulator.vertices) { vertices[v] = new Vector3(p.x, s.floorHeight, p.y); indices[v] = v; normals[v] = Vector3.up; uvs[v] = new Vector2(p.x / MapLoader.flatUVdividor, 1 - (p.y / MapLoader.flatUVdividor)); colors[v] = Color.white * s.brightness; v++; //add the triangle to the fast lookup cache if (i == 0) { t = new Triangle(); } t.vertices[i] = p; i++; if (i == 3) { i = 0; t.sector = s; s.triangles.Add(t); BooleanBox bbox = t.SelectBox; if (bbox != null) { for (int y = 0; y < bbox.size.y; y++) { for (int x = 0; x < bbox.size.x; x++) { if (bbox.data[x, y]) { int gridX = bbox.origo.x - TheGrid.origoX + x; int gridY = bbox.origo.y - TheGrid.origoY + y; TheGrid.triangles[gridX, gridY].Add(t); TheGrid.existenceBox.data[gridX, gridY] = true; } } } } bboxes[g++] = bbox; } } //combine all triangles and add the sector to the fast lookup cache BooleanBox sectorBox = BooleanBox.Combine(bboxes); for (int y = 0; y < sectorBox.size.y; y++) { for (int x = 0; x < sectorBox.size.x; x++) { if (sectorBox.data[x, y]) { int gridX = sectorBox.origo.x - TheGrid.origoX + x; int gridY = sectorBox.origo.y - TheGrid.origoY + y; TheGrid.sectors[gridX, gridY].Add(s); TheGrid.existenceBox.data[gridX, gridY] = true; } } } mesh.vertices = vertices; mesh.triangles = indices; mesh.normals = normals; mesh.uv = uvs; mesh.colors = colors; mesh.RecalculateBounds(); MeshCollider mc = sectorObject.AddComponent <MeshCollider>(); mc.sharedMesh = mesh; } //ceiling Triangulator.vertices.Reverse(); { GameObject sectorObject = new GameObject("Sector_" + index + "_ceiling"); s.ceilingObject = sectorObject; sectorObject.transform.SetParent(holder); MeshRenderer mr = sectorObject.AddComponent <MeshRenderer>(); MeshFilter meshFilter = sectorObject.AddComponent <MeshFilter>(); Mesh mesh = new Mesh(); meshFilter.mesh = mesh; mesh.name = "Sector_" + index + "_ceiling_mesh"; if (!MaterialManager.Instance.OverridesFlat(s.ceilingTexture, sectorObject, mr)) { mr.material = MaterialManager.Instance.defaultMaterial; } if (mr.material.mainTexture == null) { MaterialPropertyBlock materialProperties = new MaterialPropertyBlock(); materialProperties.SetTexture("_MainTex", TextureLoader.Instance.GetFlatTexture(s.ceilingTexture)); mr.SetPropertyBlock(materialProperties); } int vc = Triangulator.vertices.Count; Vector3[] vertices = new Vector3[vc]; Vector3[] normals = new Vector3[vc]; Vector2[] uvs = new Vector2[vc]; Color[] colors = new Color[vc]; int[] indices = new int[vc]; int v = 0; foreach (Vector2 p in Triangulator.vertices) { vertices[v] = new Vector3(p.x, s.ceilingHeight, p.y); indices[v] = v; normals[v] = -Vector3.up; uvs[v] = new Vector2(p.x / MapLoader.flatUVdividor, 1 - (p.y / MapLoader.flatUVdividor)); colors[v] = Color.white * s.brightness; v++; } mesh.vertices = vertices; mesh.triangles = indices; mesh.normals = normals; mesh.uv = uvs; mesh.colors = colors; mesh.RecalculateBounds(); MeshCollider mc = sectorObject.AddComponent <MeshCollider>(); mc.sharedMesh = mesh; } s.floorObject.sector = s; s.floorObject.Init(); index++; } } }