void ParseSidedef() { Sidedef ns = new Sidedef(); Dictionary <string, string> blockData = ParseBlock(); ns.xOffset = BlockInt(blockData, "offsetx", 0); ns.yOffset = BlockInt(blockData, "offsety", 0); ns.upper = BlockString(blockData, "texturetop", "-"); ns.lower = BlockString(blockData, "texturebottom", "-"); ns.mid = BlockString(blockData, "texturemiddle", "-"); ns.sector = BlockInt(blockData, "sector"); msidedefs.Add(ns); return; }
public void LoadSidedefs(byte[] data) { int size = 30; sidedefs = new Sidedef[data.Length / size]; for (int i = 0; i < data.Length; i += size) { Sidedef ns = new Sidedef() { xOffset = BitConverter.ToInt16(data, i), yOffset = BitConverter.ToInt16(data, i + 2), upper = FixString(new string(Encoding.ASCII.GetChars(data, i + 4, 8))), lower = FixString(new string(Encoding.ASCII.GetChars(data, i + 12, 8))), mid = FixString(new string(Encoding.ASCII.GetChars(data, i + 20, 8))), sector = BitConverter.ToInt16(data, i + 28), }; sidedefs[i / size] = ns; } }
Vector2[] CalculateUVs(float length, Vector2 bottomHeight, Vector2 topHeight, Linedef line, bool front, SideOrientation orientation) { Sidedef side = null; side = map.sidedefs[front?line.front:line.back]; float height; string texture; switch (orientation) { case SideOrientation.Upper: texture = side.upper; height = topHeight.y - topHeight.x; break; case SideOrientation.Middle: texture = side.mid; height = topHeight.x - bottomHeight.y; break; case SideOrientation.Lower: texture = side.lower; height = bottomHeight.y - bottomHeight.x; break; default: texture = "-"; height = 1f; break; } Vector2 size = Vector2.one; Vector2 offset = Vector2.zero; if (wad.textureTable.Contains(texture.ToUpper())) { var textureInfo = wad.textureTable.Get(texture.ToUpper()); Vector2 textureSize = new Vector2(textureInfo.width, textureInfo.height); size.x = length / textureSize.x; size.y = height / textureSize.y; offset.x = (float)side.xOffset / textureSize.x; offset.y = (float)side.yOffset / textureSize.y; if (orientation == SideOrientation.Middle) { if (line.lowerUnpegged && !line.upperUnpegged) { // Draw from bottom offset.y -= size.y; } else { } } if (orientation == SideOrientation.Upper) { if (!line.upperUnpegged) { // draw from height ceiling offset.y -= size.y; } } if (orientation == SideOrientation.Lower) { if (!line.lowerUnpegged) { // draw from higher ceiling offset.y += topHeight.y - bottomHeight.y; } else { // offset.y -= size.y; } } } size += offset; return(new Vector2[] { new Vector2(offset.x, size.y), new Vector2(offset.x, offset.y), new Vector2(size.x, offset.y), new Vector2(size.x, size.y) }); }
GameObject[] BuildLine(int lineIndex) { List <GameObject> output = new List <GameObject>(); Linedef line = map.linedefs[lineIndex]; Sidedef front = map.sidedefs[line.front]; Sidedef back = null; if (line.back != 0xFFFF && line.back != -1) { back = map.sidedefs[line.back]; } float floorHeight = map.sectors[front.sector].floorHeight; float ceilingHeight = map.sectors[front.sector].ceilingHeight; Vector2Int start = new Vector2Int( map.vertices[line.start].x, map.vertices[line.start].y ); Vector2Int end = new Vector2Int( map.vertices[line.end].x, map.vertices[line.end].y ); float length = Vector2Int.Distance(start, end); Vector2Int frontHeight = new Vector2Int( map.sectors[front.sector].floorHeight, map.sectors[front.sector].ceilingHeight ); Vector2Int backHeight = new Vector2Int(); if (back != null) { backHeight.x = map.sectors[back.sector].floorHeight; backHeight.y = map.sectors[back.sector].ceilingHeight; } if (back == null) { // 1-sided line Vector2Int topHeight = new Vector2Int( frontHeight.y, frontHeight.y ); Vector2Int bottomHeight = new Vector2Int( frontHeight.x, frontHeight.x ); if (frontHeight.y != frontHeight.x) { Mesh mesh = BuildQuad( start, end, frontHeight, CalculateUVs(length, bottomHeight, topHeight, line, true, SideOrientation.Middle) ); output.Add(BuildGameObject(mesh, map.sectors[front.sector], GetWallMaterial(front.mid), true)); } } else { // 2-sided line Mesh mesh; Material material; Vector2Int topHeight = new Vector2Int( Mathf.Min(backHeight.y, frontHeight.y), Mathf.Max(backHeight.y, frontHeight.y) ); Vector2Int bottomHeight = new Vector2Int( Mathf.Min(backHeight.x, frontHeight.x), Mathf.Max(backHeight.x, frontHeight.x) ); // Front Mid if (front.mid != "-") { Vector2Int height = new Vector2Int( bottomHeight.y, topHeight.x ); mesh = BuildQuad(start, end, height, CalculateUVs(length, bottomHeight, topHeight, line, true, SideOrientation.Middle)); output.Add(BuildGameObject(mesh, map.sectors[front.sector], material = GetWallMaterial(front.mid), line.impassable)); } if (frontHeight.y > backHeight.y) { // Front Upper mesh = BuildQuad(start, end, topHeight, CalculateUVs(length, bottomHeight, topHeight, line, true, SideOrientation.Upper)); if (IsSky(line, true, SideOrientation.Upper)) { material = skyMaterial; } else { material = GetWallMaterial(front.upper); } output.Add(BuildGameObject(mesh, map.sectors[front.sector], material, true)); } if (frontHeight.x < backHeight.x) { // Front Lower mesh = BuildQuad(start, end, bottomHeight, CalculateUVs(length, bottomHeight, topHeight, line, true, SideOrientation.Lower)); if (IsSky(line, true, SideOrientation.Lower)) { material = skyMaterial; } else { material = GetWallMaterial(front.lower); } output.Add(BuildGameObject(mesh, map.sectors[front.sector], material, true)); } // Back Mid if (back.mid != "-") { Vector2Int height = new Vector2Int( bottomHeight.y, topHeight.x ); mesh = BuildQuad(end, start, height, CalculateUVs(length, bottomHeight, topHeight, line, false, SideOrientation.Middle)); output.Add(BuildGameObject(mesh, map.sectors[back.sector], GetWallMaterial(back.mid), line.impassable)); } if (frontHeight.y < backHeight.y) { // Back Upper mesh = BuildQuad(end, start, topHeight, CalculateUVs(length, bottomHeight, topHeight, line, false, SideOrientation.Upper)); if (IsSky(line, false, SideOrientation.Upper)) { material = skyMaterial; } else { material = GetWallMaterial(back.upper); } output.Add(BuildGameObject(mesh, map.sectors[back.sector], material, true)); } if (frontHeight.x > backHeight.x) { // Back Lower mesh = BuildQuad(end, start, bottomHeight, CalculateUVs(length, bottomHeight, topHeight, line, false, SideOrientation.Lower)); if (IsSky(line, false, SideOrientation.Lower)) { material = skyMaterial; } else { material = GetWallMaterial(back.lower); } output.Add(BuildGameObject(mesh, map.sectors[back.sector], material, true)); } } return(output.ToArray()); }