private byte ParseShape(OreTypes ore, MarchingSquaresGrid marchingGrid, OreGrid oreGrid, int x, int y) { byte shape = 0; for (int i = 0; i < 7; i += 2) { if (GetNode(i, x, y, marchingGrid) > 0.5f && oreGrid.GetTileByIndex(i, x, y) == (int)ore) { shape |= (byte)(1 << i); int nextIndex = Mod(i + 2, 8); int prevIndex = Mod(i - 2, 8); int nextIntermediate = Mod(i + 1, 8); int prevIntermediate = Mod(i - 1, 8); //If the next node is a different type, or below the rendering threshold, add the intermediate node if (GetNode(nextIndex, x, y, marchingGrid) < 0.5f || oreGrid.GetTileByIndex(nextIndex, x, y) != (int)ore) { shape |= (byte)(1 << (nextIntermediate)); } if (GetNode(prevIndex, x, y, marchingGrid) < 0.5f || oreGrid.GetTileByIndex(prevIndex, x, y) != (int)ore) { shape |= (byte)(1 << (prevIntermediate)); } } } return(shape); // return (byte) 1 +( 1<< 1) + (1 << 7); }
public MarchingSquaresCutTools(MarchingSquaresGrid marchingSquaresGrid, bool[,] destructArray) { nodeArray = (marchingSquaresGrid).GetNodeArray(); tileXSize = nodeArray.GetLength(0); tileYSize = nodeArray.GetLength(1); destructableArray = destructArray; }
public void ApplyStamp(MarchingSquaresGrid marchingGrid, OreGrid oreGrid) { TransformToCircle(); new MarchingSquaresCutTools(marchingGrid).DigCircleFromWorld(position, radius, isSolid); // Topography topography = (Topography)FindObjectOfType (typeof(Topography)); // topography.DigCircle (this.transform.position, radius, isSolid); Destroy(this.gameObject); }
public void ApplyStamp(MarchingSquaresGrid marchingGrid, OreGrid oreGrid) { TransformToRect(); // Vector2 position2d = new Vector2 (this.transform.position.x, this.transform.position.y); // QuadToHulls quad = new QuadToHulls(position2d, 0f, 20f, 20f); QuadToHulls quad = new QuadToHulls(position, angle, width, height); new MarchingSquaresCutTools(marchingGrid).DigConvexHullFromWorld(quad.GetUpperHull(), quad.GetLowerHull(), isSolid); Destroy(this.gameObject); }
public void ApplyStamp(MarchingSquaresGrid marchingGrid, OreGrid oreGrid) { IStampable[] stampables = this.transform.GetComponentsInChildren <IStampable> (); foreach (IStampable stampable in stampables) { if (!stampable.Equals(this)) { stampable.ApplyStamp(marchingGrid, oreGrid); } } }
public void BuildMesh(MarchingSquaresGrid marchingGrid, OreGrid oreGrid) { //Loop through marchingGrid starting from your own coordinate for (int i = chunkCoord.X * chunkSize; i < chunkCoord.X * chunkSize + chunkSize; i++) { for (int j = chunkCoord.Y * chunkSize; j < chunkCoord.Y * chunkSize + chunkSize; j++) { BuildSquare(i, j, marchingGrid, oreGrid); } } UpdateMesh(); }
public void ApplyStamp(MarchingSquaresGrid marchingGrid, OreGrid oreGrid) { TransformToRect(); // Vector2 position2d = new Vector2 (this.transform.position.x, this.transform.position.y); // QuadToHulls quad = new QuadToHulls(position2d, 0f, 20f, 20f); QuadToHulls quad = new QuadToHulls(position, angle, width, height); new MarchingSquaresCutTools(marchingGrid).DigAxisAlignedRectFromWorld(position, width, height, isSolid, sharpCorners); Destroy(this.gameObject); }
private float GetIntermediateNodePosition(int index, int anchorX, int anchorY, MarchingSquaresGrid marchingGrid) { switch (index) { case 0: { return(marchingGrid.GetNode(anchorX, anchorY)); } case 1: { return(Mathf.Abs(marchingGrid.GetVert(anchorX, anchorY))); ; } case 2: { return(marchingGrid.GetNode(anchorX, anchorY + 1)); } case 3: { return(Mathf.Abs(marchingGrid.GetHoriz(anchorX, anchorY + 1))); } case 4: { return(marchingGrid.GetNode(anchorX + 1, anchorY + 1)); } case 5: { return(Mathf.Abs(marchingGrid.GetVert(anchorX + 1, anchorY))); } case 6: { return(marchingGrid.GetNode(anchorX + 1, anchorY)); } case 7: { return(Mathf.Abs(marchingGrid.GetHoriz(anchorX, anchorY))); } } return(-1f); }
//Take a tile and an index, and return the vertext in 0,0 to 1,1 terms. private Vector3 GetTileVertPosition(int index, int anchorX, int anchorY, MarchingSquaresGrid marchingGrid) { switch (index) { case 0: { return(new Vector3(0f, 0f, 0f)); } case 1: { return(new Vector3(0f, Mathf.Abs(GetNode(index, anchorX, anchorY, marchingGrid)), 0f)); //Abs to convert to -ve values (indicating they don't cross the 0.5 mark) into postive values //(which will be midway between two points that are both above or below 0.5) } case 2: { return(new Vector3(0f, 1f, 0f)); } case 3: { return(new Vector3(Mathf.Abs(GetNode(index, anchorX, anchorY, marchingGrid)), 1f, 0f)); } case 4: { return(new Vector3(1f, 1f, 0f)); } case 5: { return(new Vector3(1f, Mathf.Abs(GetNode(index, anchorX, anchorY, marchingGrid)), 0f)); } case 6: { return(new Vector3(1f, 0f, 0f)); } case 7: { return(new Vector3(Mathf.Abs(GetNode(index, anchorX, anchorY, marchingGrid)), 0f, 0f)); } } return(new Vector3(0f, 0f, 0f)); }
public void BuildMesh(MarchingSquaresGrid marchingGrid) { //Loop through marchingGrid starting from your own coordinate for (int i = chunkCoord.X * chunkSize; i < chunkCoord.X * chunkSize + chunkSize; i++) { for (int j = chunkCoord.Y * chunkSize; j < chunkCoord.Y * chunkSize + chunkSize; j++) { BuildSquare(i, j, marchingGrid); } } while (numPanes < maxPanes) { StowPane(); } UpdateMesh(); }
//Take a tile and an index, and return the vertext in 0,0 to 1,1 terms. private Vector3 GetTileVertPosition(int index, int anchorX, int anchorY, MarchingSquaresGrid marchingGrid) { switch (index) { case 0: { return(new Vector3(0f, 0f, 0f)); } case 1: { return(new Vector3(0f, GetNode(index, anchorX, anchorY, marchingGrid), 0f)); } case 2: { return(new Vector3(0f, 1f, 0f)); } case 3: { return(new Vector3(GetNode(index, anchorX, anchorY, marchingGrid), 1f, 0f)); } case 4: { return(new Vector3(1f, 1f, 0f)); } case 5: { return(new Vector3(1f, GetNode(index, anchorX, anchorY, marchingGrid), 0f)); } case 6: { return(new Vector3(1f, 0f, 0f)); } case 7: { return(new Vector3(GetNode(index, anchorX, anchorY, marchingGrid), 0f, 0f)); } } return(new Vector3(0f, 0f, 0f)); }
public void Initialise(float vesselSize) { this.vesselRadius = vesselSize / 2f; //Ensure enough chunks to contain vessel. Could add a buffer to build above this level. numChunks = (int)Mathf.Ceil(vesselSize / chunkSize); worldSizeX = numChunks * chunkSize; worldSizeY = numChunks * chunkSize; vesselCenter = new Vector3((float)worldSizeX / 2f, (float)worldSizeY / 2f, 0f); GameObject marchingGridGO = Instantiate(marchingGridPrefab, this.transform.position, Quaternion.identity) as GameObject; marchingGrid = marchingGridGO.GetComponent <MarchingSquaresGrid> () as MarchingSquaresGrid; marchingGrid.Initialise(worldSizeX, worldSizeY, isSolid); oreGrid = new OreGrid(); oreGrid.GenerateMap(worldSizeX, worldSizeY); destructableArray = oreGrid.GetDestructableArray(); LabyrinthBuilder labyrinthBuilder = GetComponentInChildren <LabyrinthBuilder> () as LabyrinthBuilder; if (labyrinthBuilder != null) { labyrinthBuilder.GenerateLabyrinth(); } rootStampCollection = this.transform.GetComponentInChildren <StampCollection> () as StampCollection; ApplyStampCollection(rootStampCollection); renderChunkPool = new Stack <RenderChunk> (); renderChunkUpdateQueue = new Queue <RenderChunk> (); renderChunkPriorityUpdateQueue = new Queue <RenderChunk> (); renderChunkArray = new RenderChunk[numChunks, numChunks]; collisionChunkPool = new Stack <CollisionChunk> (); collisionChunkUpdateQueue = new Queue <CollisionChunk> (); collisionChunkPriorityUpdateQueue = new Queue <CollisionChunk> (); collisionChunkArray = new CollisionChunk[numChunks, numChunks]; this.faceGO = Instantiate(facePrefab, new Vector3(0f, 0f, 0f), Quaternion.identity) as GameObject; this.interiorGO = Instantiate(interiorPrefab, new Vector3(0f, 0f, 0f), Quaternion.identity) as GameObject; renderFoci = new List <GameObject> (); }
public void ApplyStamp(MarchingSquaresGrid marchingGrid, OreGrid oreGrid) { new MarchingSquaresCutTools(marchingGrid).DigPerlinTunnels(0.02f); Destroy(this.gameObject); }
public void UpdateRenderChunk(MarchingSquaresGrid marchingGrid, OreGrid oreGrid) { BuildMesh(marchingGrid, oreGrid); }
private void BuildSquare(int x, int y, MarchingSquaresGrid marchingGrid, OreGrid oreGrid) { float xOffset = (float)x; float yOffset = (float)y; Vector3 vecOffset = new Vector3(xOffset, yOffset, 0f); Color32 borderColor = new Color32(230, 230, 230, 255); Color32 mainColor = new Color32(200, 200, 200, 255); //Build an individual square by going clockwise around the nodes and interpolations in that tile space int numCornerNodes = 0; int numAllTypeNodes = 0; int i = 0; int anchorVert = numVerts; int numShapes = 0; //One shape per unique OreType. for (i = 0; i < 8; i++) { if (i == 0 || i == 2 || i == 4 || i == 6) { if (GetNode(i, x, y, marchingGrid) >= 0.5f) { numCornerNodes++; } } } if (numCornerNodes > 0) { //Parse up to 4 shapes. //Look at each corner. //If the Corner is rendered, set its bit to true. //If the the adjacent corners are different or not rendered, set the adjacent edge bits to true. byte botLeft = 0; byte topRight = 0; byte topLeft = 0; byte botRight = 0; OreTypes ore0 = (OreTypes)oreGrid.GetTile(x, y); OreTypes ore1 = (OreTypes)oreGrid.GetTile(x, y + 1); OreTypes ore2 = (OreTypes)oreGrid.GetTile(x + 1, y + 1); OreTypes ore3 = (OreTypes)oreGrid.GetTile(x + 1, y); bool unique0 = true; bool unique1 = true; bool unique2 = true; bool unique3 = true; int shape0Nodes = 0; int shape1Nodes = 0; int shape2Nodes = 0; int shape3Nodes = 0; //Identify the ore types that appear. if (ore0 == ore1) { unique1 = false; } if (ore0 == ore2) { unique2 = false; } if (ore0 == ore3) { unique3 = false; } if (ore1 == ore2) { unique2 = false; } if (ore1 == ore3) { unique3 = false; } if (ore2 == ore3) { unique3 = false; } //Render the first ore across the entire tile, to prevent gaps bool baseColorRendered = false; //For each unique ore type, loop around the perimeter, flagging raised corners of that type, and edge nodes where the ore is different or the elevation changes. //If a corner is the first instance of an ore type, parse its shape. Redundant ore type corners will be flagged in the first instance as part of this loop. if (unique0) { botLeft = ParseBaseShape(ore0, marchingGrid, oreGrid, x, y); baseColorRendered = true; // botLeft = ParseShape (ore0, marchingGrid, oreGrid, x, y); } if (unique1) { if (baseColorRendered) { topLeft = ParseShape(ore1, marchingGrid, oreGrid, x, y); } else { baseColorRendered = true; topLeft = ParseBaseShape(ore1, marchingGrid, oreGrid, x, y); } } if (unique2) { if (baseColorRendered) { topRight = ParseShape(ore2, marchingGrid, oreGrid, x, y); } else { baseColorRendered = true; topRight = ParseBaseShape(ore2, marchingGrid, oreGrid, x, y); } } if (unique3) { if (baseColorRendered) { botRight = ParseShape(ore3, marchingGrid, oreGrid, x, y); } else { botRight = ParseBaseShape(ore3, marchingGrid, oreGrid, x, y); } } //If a corner is the origin of a shape, render it. if (botLeft > 0) //if bot left needs to be rendered { mainColor = oreGrid.GetOreColor(ore0); for (i = 0; i < 8; i++) { if ((botLeft & ((byte)1 << i)) > 0) { AddFaceVert(GetTileVertPosition(i, x, y, marchingGrid) + vecOffset + new Vector3(0f, 0f, -0.1f), mainColor); shape0Nodes++; } } for (i = 1; i < shape0Nodes - 1; i++) { faceTris.Add(anchorVert); faceTris.Add(anchorVert + i); faceTris.Add(anchorVert + i + 1); numTris++; } anchorVert = numVerts; } if (topLeft > 0) { mainColor = oreGrid.GetOreColor(ore1); for (i = 0; i < 8; i++) { if ((topLeft & ((byte)1 << i)) > 0) { AddFaceVert(GetTileVertPosition(i, x, y, marchingGrid) + vecOffset + new Vector3(0f, 0f, -0.2f), mainColor); shape1Nodes++; } } for (i = 1; i < shape1Nodes - 1; i++) { faceTris.Add(anchorVert); faceTris.Add(anchorVert + i); faceTris.Add(anchorVert + i + 1); numTris++; } anchorVert = numVerts; } if (topRight > 0) { mainColor = oreGrid.GetOreColor(ore2); for (i = 0; i < 8; i++) { if ((topRight & ((byte)1 << i)) > 0) { AddFaceVert(GetTileVertPosition(i, x, y, marchingGrid) + vecOffset + new Vector3(0f, 0f, -0.3f), mainColor); shape2Nodes++; } } for (i = 1; i < shape2Nodes - 1; i++) { faceTris.Add(anchorVert); faceTris.Add(anchorVert + i); faceTris.Add(anchorVert + i + 1); numTris++; } anchorVert = numVerts; } if (botRight > 0) { mainColor = oreGrid.GetOreColor(ore3); for (i = 0; i < 8; i++) { if ((botRight & ((byte)1 << i)) > 0) { AddFaceVert(GetTileVertPosition(i, x, y, marchingGrid) + vecOffset + new Vector3(0f, 0f, -0.4f), mainColor); shape3Nodes++; } } for (i = 1; i < shape3Nodes - 1; i++) { faceTris.Add(anchorVert); faceTris.Add(anchorVert + i); faceTris.Add(anchorVert + i + 1); numTris++; } anchorVert = numVerts; } //Add a lighter colour to the edge of the tile BuildOutline(x, y, marchingGrid, borderColor); } }
private void BuildSquare(int x, int y, MarchingSquaresGrid marchingGrid) { float xOffset = ((float)x); float yOffset = ((float)y); Vector3 vecOffset = new Vector3(xOffset, yOffset, 0f); Vector3 start1 = new Vector3(0f, 0f, 0f); Vector3 end1 = new Vector3(0f, 0f, 0f); Vector3 start2 = new Vector3(0f, 0f, 0f); Vector3 end2 = new Vector3(0f, 0f, 0f); int numPanesToRender = 0; //A tile will have //0 collision panes if all corners true or no corners true //1 collision pane if 1 corner true, 1 corner false, or 2 adjacent corners true //2 collision panes corners alternate true and false //Turn the pattern of corners into a nybble ushort cornerPattern = 0x0000; for (int i = 0; i < 4; i++) { if (GetNode(i * 2, x, y, marchingGrid) >= 0.5f) { cornerPattern |= (ushort)((ushort)0x0001 << (i * 4)); } } switch (cornerPattern) { case 0x0000: //All empty { break; } case 0x1111: //All occupied { break; } case 0x0001: //Bot left occupied { start1 = GetTileVertPosition(1, x, y, marchingGrid); end1 = GetTileVertPosition(7, x, y, marchingGrid); numPanesToRender = 1; break; } case 0x0010: //Top left occupied { start1 = GetTileVertPosition(3, x, y, marchingGrid); end1 = GetTileVertPosition(1, x, y, marchingGrid); numPanesToRender = 1; break; } case 0x0100: //Top right occupied { start1 = GetTileVertPosition(5, x, y, marchingGrid); end1 = GetTileVertPosition(3, x, y, marchingGrid); numPanesToRender = 1; break; } case 0x1000: //Bot right occupied { start1 = GetTileVertPosition(7, x, y, marchingGrid); end1 = GetTileVertPosition(5, x, y, marchingGrid); numPanesToRender = 1; break; } case 0x1110: //Bot left vacant { start1 = GetTileVertPosition(7, x, y, marchingGrid); end1 = GetTileVertPosition(1, x, y, marchingGrid); numPanesToRender = 1; break; } case 0x1101: //Top left vacant { start1 = GetTileVertPosition(1, x, y, marchingGrid); end1 = GetTileVertPosition(3, x, y, marchingGrid); numPanesToRender = 1; break; } case 0x1011: //Top right vacant { start1 = GetTileVertPosition(3, x, y, marchingGrid); end1 = GetTileVertPosition(5, x, y, marchingGrid); numPanesToRender = 1; break; } case 0x0111: //Bot right vacant { start1 = GetTileVertPosition(5, x, y, marchingGrid); end1 = GetTileVertPosition(7, x, y, marchingGrid); numPanesToRender = 1; break; } case 0x0011: //Right facing wall { start1 = GetTileVertPosition(3, x, y, marchingGrid); end1 = GetTileVertPosition(7, x, y, marchingGrid); numPanesToRender = 1; break; } case 0x1100: //left facing wall { start1 = GetTileVertPosition(7, x, y, marchingGrid); end1 = GetTileVertPosition(3, x, y, marchingGrid); numPanesToRender = 1; break; } case 0x1001: //Up facing panel { start1 = GetTileVertPosition(1, x, y, marchingGrid); end1 = GetTileVertPosition(5, x, y, marchingGrid); numPanesToRender = 1; break; } case 0x0110: //Down facing panel { start1 = GetTileVertPosition(5, x, y, marchingGrid); end1 = GetTileVertPosition(1, x, y, marchingGrid); numPanesToRender = 1; break; } case 0x0101: //Solid from bot left to top right { start1 = GetTileVertPosition(1, x, y, marchingGrid); end1 = GetTileVertPosition(3, x, y, marchingGrid); start2 = GetTileVertPosition(5, x, y, marchingGrid); end2 = GetTileVertPosition(7, x, y, marchingGrid); numPanesToRender = 2; break; } case 0x1010: //Solid from top left to bot right { start1 = GetTileVertPosition(3, x, y, marchingGrid); end1 = GetTileVertPosition(5, x, y, marchingGrid); start2 = GetTileVertPosition(7, x, y, marchingGrid); end2 = GetTileVertPosition(1, x, y, marchingGrid); numPanesToRender = 2; break; } } start1 = start1 + new Vector3(xOffset, yOffset); end1 = end1 + new Vector3(xOffset, yOffset); start2 = start2 + new Vector3(xOffset, yOffset); end2 = end2 + new Vector3(xOffset, yOffset); if (numPanesToRender == 1) { BuildPane(start1.x, start1.y, end1.x, end1.y); } else if (numPanesToRender == 2) { BuildPane(start1.x, start1.y, end1.x, end1.y); BuildPane(start2.x, start2.y, end2.x, end2.y); } }
public void UpdateCollisionChunk(MarchingSquaresGrid marchingGrid) { BuildMesh(marchingGrid); }