private int SortCellDataMapValue(CellDataMapValue x, CellDataMapValue y) { //Less than 0 x is less than y. //0 x equals y. //Greater than 0 x is greater than y if (x.connection != null) { if (y.connection != null) { return(0); } else { return(-1); } } else { if (y.connection == null) { return(0); } else { return(+1); } } }
private void AddEdgeToMap(Cell origin, Cell connection, CellContentData data) { //Debuger_K.AddLine(origin.centerV3, SomeMath.MidPoint(data.leftV3, data.centerV3), Color.blue); //Debuger_K.AddLine(origin.centerV3, SomeMath.MidPoint(data.rightV3, data.centerV3), Color.red); tempCellDataMapValue = new CellDataMapValue(origin, connection, data); DDARasterization.DrawLine(data.a.x - chunk.realX, data.a.z - chunk.realZ, data.b.x - chunk.realX, data.b.z - chunk.realZ, PathFinder.CELL_GRID_SIZE / PathFinder.gridSize, AddEdgeToMapDelegate); }
/// <summary> /// IMPORTANT: /// Sort so empty edges are at begining /// </summary> private void AddEdgeToMapDelegate(int x, int z) { x = SomeMath.Clamp(0, PathFinder.CELL_GRID_SIZE - 1, x); z = SomeMath.Clamp(0, PathFinder.CELL_GRID_SIZE - 1, z); CellDataMapValue[] arr = dataMap[x][z]; if (arr == null) { arr = new CellDataMapValue[0]; } CellDataMapValue[] newArr = new CellDataMapValue[arr.Length + 1]; for (int i = 0; i < arr.Length; i++) { newArr[i] = arr[i]; } newArr[arr.Length] = tempCellDataMapValue; Array.Sort(newArr, SortCellDataMapValue); dataMap[x][z] = newArr; //if(dataMap[x][z] == null) // dataMap[x][z] = new List<CellDataMapValue>(); //dataMap[x][z].Add(tempCellDataMapValue); //dataMap[x][z].Sort(SortCellDataMapValue);//place connections with null at the end and with connection at begining }
public static void Raycast2Body2(float posX, float posY, float posZ, float rayDirX, float rayDirY, Cell cell, float maxLength, bool checkArea, bool checkPass, Area expArea, Passability expPass, RaycastAllocatedData rad, out RaycastHitNavMesh2 hit) { if (SomeMath.SqrMagnitude(rayDirX, rayDirY) == 0f) { hit = new RaycastHitNavMesh2(posX, posY, posZ, NavmeshRaycastResultType2.ReachMaxDistance, cell); return; } rad.chunkPixelSize = PathFinder.gridSize / PathFinder.CELL_GRID_SIZE; //trick to fix case when raycast start on "near" edge //currently can't be on chunk edge so we dont care if chunk changed rad.currentChunkData = cell.graph.chunk; int curGridX = (int)((posX - rad.currentChunkData.realX) / rad.chunkPixelSize); int curGridY = (int)((posZ - rad.currentChunkData.realZ) / rad.chunkPixelSize); //if (curGridX < 0) curGridX = 0; else if (curGridX > 9) curGridX = 9; //if (curGridY < 0) curGridY = 0; else if (curGridY > 9) curGridY = 9; rad.startIntX = (rad.currentChunkData.x * 10) + curGridX; rad.startIntY = (rad.currentChunkData.z * 10) + curGridY; var tempVal = maxLength / rad.chunkPixelSize; if (tempVal > 10000) //too big number anyway { rad.gridDistanceTreshold = SomeMath.Sqr(10000); } else { rad.gridDistanceTreshold = (int)SomeMath.Sqr(maxLength / rad.chunkPixelSize) + 1; } rad.dataArray = cell.graph.dataMap[curGridX][curGridY]; if (rad.dataArray != null) { for (int i = 0; i < rad.dataArray.Length; i++) { CellDataMapValue mapData = rad.dataArray[i]; if (mapData.from != cell) { continue; } if (mapData.data.RotateRightAndReturnDot(rayDirX, rayDirY) < 0) { continue; } float sqrDist = SomeMath.SqrDistance(mapData.data.NearestPointXZ(posX, posZ), new Vector2(posX, posZ)); if (sqrDist < 0.0001f) { Vector2 dirToCellCenter = (cell.centerVector2 - new Vector2(posX, posZ)).normalized * 0.001f; posX += dirToCellCenter.x; posZ += dirToCellCenter.y; //if (dot < 0.001f) {//oh wow. start point exactly on edge and ray alond side //} break; } } } //if (DEBUG) { // Debuger_K.AddRay(new Vector3(posX, posY + 0.1f, posZ), new Vector3(rayDirX, 0, rayDirY), Color.gray); //} rad.posX = posX; rad.posY = posY; rad.posZ = posZ; rad.rayDirX = rayDirX; rad.rayDirY = rayDirY; rad.checkPass = checkPass; rad.checkArea = checkArea; rad.expPass = expPass; rad.expArea = expArea; rad.raycastType = NavmeshRaycastResultType2.Nothing; rad.maxSqrLength = SomeMath.Sqr(maxLength); rad.curCell = cell; rad.prevCell = null; rad.raycastDone = false; float chunkX, chunkZ, curHullX, curHullZ, lastHullX = posX, lastHullZ = posZ; for (int i = 0; i < 4; i++) { rad.raycastSamples[i] = raycastSamplesTemplate[i].RotateRightAndReturnDot(rayDirX, rayDirY) < 0; } int chunkIteration = 0; while (rad.raycastDone == false) { chunkIteration++; if (chunkIteration > 50) { string s = string.Format("chunkIteration too large. x {0}, y {1}, z {2}, dx {3}, dy {4}, max {5}", posX, posY, posZ, rayDirX, rayDirY, maxLength); //HandleTextFile.WriteString(s); //Debuger_K.AddRay(new Vector3(posX, posY, posZ), Vector3.down, Color.cyan); //Debuger_K.AddRay(new Vector3(posX, posY, posZ), new Vector3(rayDirX, 0, rayDirY), Color.yellow, 50); //Debuger_K.UserfulPublicFlag = true; Debug.LogError(s); break; } rad.currentChunkData = rad.curCell.graph.chunk; rad.curChunkIntX = rad.currentChunkData.x * 10; rad.curChunkIntY = rad.currentChunkData.z * 10; rad.dataMap = rad.curCell.graph.dataMap; chunkX = rad.currentChunkData.realX; chunkZ = rad.currentChunkData.realZ; #region border points curHullX = posX; curHullZ = posZ; for (int i = 0; i < 4; i++) { if (rad.raycastSamples[i]) { CellContentData curSide = raycastSamplesTemplate[i]; float rX, rZ; if (SomeMath.RayIntersectSegment(posX, posZ, rayDirX, rayDirY, curSide.xLeft + chunkX, curSide.zLeft + chunkZ, curSide.xRight + chunkX, curSide.zRight + chunkZ, out rX, out rZ)) { curHullX = rX; curHullZ = rZ; } //if (DEBUG) // Debuger_K.AddLine(curSide.a, curSide.b, Color.red, chunkIteration); } } #region debug //if (DEBUG) { // Debuger_K.AddLine(new Vector3(curHullX, 0, curHullZ), new Vector3(lastHullX, 0, lastHullZ), Color.yellow, chunkIteration); // for (int x = 0; x < PathFinder.CELL_GRID_SIZE + 1; x++) { // Debuger_K.AddLine( // currentChunkData.realPositionV3 + new Vector3(x * chunkPixelSize, 0, 0), // currentChunkData.realPositionV3 + new Vector3(x * chunkPixelSize, 0, PathFinder.gridSize), // Color.red); // } // for (int z = 0; z < PathFinder.CELL_GRID_SIZE + 1; z++) { // Debuger_K.AddLine( // currentChunkData.realPositionV3 + new Vector3(0, 0, z * chunkPixelSize), // currentChunkData.realPositionV3 + new Vector3(PathFinder.gridSize, 0, z * chunkPixelSize), // Color.red); // } //} #endregion #endregion DDARasterization.DrawLine( lastHullX - chunkX, lastHullZ - chunkZ, curHullX - chunkX, curHullZ - chunkZ, rad.chunkPixelSize, rad, RaycastDelegate); lastHullX = curHullX; lastHullZ = curHullZ; } hit = new RaycastHitNavMesh2(rad.raycastResultX, rad.raycastResultY, rad.raycastResultZ, rad.raycastType, rad.curCell); }
private static bool RaycastDelegate(int x, int y, RaycastAllocatedData rad) { if (rad.raycastDone) { return(true); } if (x < 0) { x = 0; } else if (x > 9) { x = 9; //x = SomeMath.Clamp(0, CELL_GRID_SIZE - 1, x); } if (y < 0) { y = 0; } else if (y > 9) { y = 9; //y = SomeMath.Clamp(0, CELL_GRID_SIZE - 1, y); } if (SomeMath.SqrDistance(rad.startIntX, rad.startIntY, rad.curChunkIntX + x, rad.curChunkIntY + y) > rad.gridDistanceTreshold) { rad.raycastType = NavmeshRaycastResultType2.ReachMaxDistance; rad.raycastDone = true; } //IMPORTANT: edges in this list are sorted. "connection != null" at the begining and "connection == null" at the end. //some logic here based on this order rad.dataArray = rad.dataMap[x][y]; if (rad.dataArray == null) { return(false); } int dataArrayLength = rad.dataArray.Length; #region debug //if (DEBUG) { // Vector3 p = currentChunkData.realPositionV3 + new Vector3((x * chunkPixelSize) + (chunkPixelSize * 0.5f), 0, (y * chunkPixelSize) + (chunkPixelSize * 0.5f)); // Debuger_K.AddDot(curCell.centerV3, Color.cyan); // Debuger_K.AddDot(p, Color.red, 0.05f); // //list.ForEach(item => Debuger_K.AddLine(item.data.NearestPoint(p), p, Color.blue)); //} #endregion int cellLoop = 0; bool doCellLoop = true; while (doCellLoop) { cellLoop++; if (cellLoop > 50) { Debug.LogErrorFormat("cellLoop too large. x {0}, y {1}, z {2}, dx {3}, dy {4}, max {5}", rad.posX, rad.posY, rad.posZ, rad.rayDirX, rad.rayDirY, Mathf.Sqrt(rad.maxSqrLength)); break; } doCellLoop = false; for (int i = 0; i < dataArrayLength; i++) { CellDataMapValue mapData = rad.dataArray[i]; if (mapData.from != rad.curCell) { continue; } CellContentData ccd = mapData.data; if ((-(ccd.zRight - ccd.zLeft) * rad.rayDirX) + ((ccd.xRight - ccd.xLeft) * rad.rayDirY) < 0) { continue; } float ix, iy, iz; if (SomeMath.RayIntersectXZ(rad.posX, rad.posZ, rad.rayDirX, rad.rayDirY, ccd.xLeft, ccd.yLeft, ccd.zLeft, ccd.xRight, ccd.yRight, ccd.zRight, out ix, out iy, out iz) == false) { continue; } rad.raycastResultX = ix; rad.raycastResultY = iy; rad.raycastResultZ = iz; rad.prevCell = rad.curCell; if (SomeMath.SqrDistance(rad.posX, rad.posY, rad.posZ, ix, iy, iz) >= rad.maxSqrLength) { rad.raycastType = NavmeshRaycastResultType2.ReachMaxDistance; rad.raycastDone = true; return(true); } if (mapData.connection != null) { #region debug //if (DEBUG) { // Vector3 p = currentChunkData.realPositionV3 + new Vector3((x * chunkPixelSize) + (chunkPixelSize * 0.5f), 0, (y * chunkPixelSize) + (chunkPixelSize * 0.5f)); // //Debuger_K.AddLine(ToV3(curHullIntersection), resultVector); // if (prevCell != null) { // Vector3 p1p = SomeMath.MidPoint(curCell.centerV3, prevCell.centerV3); // //Vector3 p2p = SomeMath.MidPoint(p1p, p); // Debuger_K.AddLine(curCell.centerV3, prevCell.centerV3, Color.green); // Debuger_K.AddLine(p1p, p, Color.cyan); // } //} #endregion doCellLoop = true; rad.curCell = mapData.connection; if (rad.checkPass && rad.curCell.passability != rad.expPass) { rad.raycastType = NavmeshRaycastResultType2.PassabilityChange; rad.raycastDone = true; return(true); } else if (rad.checkArea && rad.curCell.area != rad.expArea) { rad.raycastType = NavmeshRaycastResultType2.AreaChange; rad.raycastDone = true; return(true); } } else { rad.curCell = null; rad.raycastType = NavmeshRaycastResultType2.NavmeshBorderHit; rad.raycastDone = true; return(true); } break; } } return(rad.raycastDone); }
public void SetBunchOfData(List <Cell> passedCells, List <Cell>[][] map, Dictionary <CellContentData, Cell> contourLib) { _cells.AddRange(passedCells); _mapCell = map; _contourLib = contourLib; //**********************TEMP**********************// for (int i = 0; i < passedCells.Count; i++) { passedCells[i].debugID = i; } //dataMap = new List<CellDataMapValue>[PathFinder.CELL_GRID_SIZE][]; //for (int x = 0; x < PathFinder.CELL_GRID_SIZE; x++) { // dataMap[x] = new List<CellDataMapValue>[PathFinder.CELL_GRID_SIZE]; //} dataMap = new CellDataMapValue[PathFinder.CELL_GRID_SIZE][][]; for (int x = 0; x < PathFinder.CELL_GRID_SIZE; x++) { dataMap[x] = new CellDataMapValue[PathFinder.CELL_GRID_SIZE][]; } Vector2 chunkPos = chunk.realPositionV2; foreach (var cell in passedCells) { foreach (var pair in cell.dataContentPairs) { if (pair.Value != null) { if (pair.Value is CellContentGenericConnection)//skip jump connections since they dont participate in raycasting right now { AddEdgeToMap(cell, pair.Value.connection, pair.Key); } } else { AddEdgeToMap(cell, null, pair.Key); } } } //debug //float edgeMapPiselSize = PathFinder.CELL_GRID_SIZE / PathFinder.gridSize; //Vector3 realNotOffsetedPosition = chunk.realPositionV3; //for (int x = 0; x < PathFinder.CELL_GRID_SIZE + 1; x++) { // Vector3 A = realNotOffsetedPosition + new Vector3(x * edgeMapPiselSize, 0, 0); // Vector3 B = realNotOffsetedPosition + new Vector3(x * edgeMapPiselSize, 0, PathFinder.gridSize); // Debuger_K.AddLine(A, B, Color.red); //} //for (int z = 0; z < PathFinder.CELL_GRID_SIZE + 1; z++) { // Vector3 A = realNotOffsetedPosition + new Vector3(0, 0, z * edgeMapPiselSize); // Vector3 B = realNotOffsetedPosition + new Vector3(PathFinder.gridSize, 0, z * edgeMapPiselSize); // Debuger_K.AddLine(A, B, Color.red); //} //Vector3 chunkPosition = chunk.realPositionV3; //float chunkPixelSize = PathFinder.gridSize / PathFinder.CELL_GRID_SIZE; //for (int x = 0; x < PathFinder.CELL_GRID_SIZE; x++) { // for (int z = 0; z < PathFinder.CELL_GRID_SIZE; z++) { // Vector3 p = chunkPosition + new Vector3((x * chunkPixelSize) + (chunkPixelSize * 0.5f), 0, (z * chunkPixelSize) + (chunkPixelSize * 0.5f)); // if (dataMap[x][z] != null) { // string s = "|"; // for (int i = 0; i < dataMap[x][z].Length; i++) { // s += dataMap[x][z][i].connection == null ? "-" : "+"; // } // Debuger_K.AddLabel(p, s); // } // else { // Debuger_K.AddLabel(p, "null"); // } // Debuger_K.AddDot(p); // } //} //**********************TEMP**********************// }