private bool IsVisible(int a, int b) { float ax = _nodes[a].x; float ay = _nodes[a].z; float bx = _nodes[b].x; float by = _nodes[b].z; float abx = bx - ax; float aby = by - ay; float sqrDist = SomeMath.SqrDistance(ax, ay, bx, by); isVisibleTemp.Clear(); DDARasterization.DrawLine(ax - chunkPos.x, ay - chunkPos.y, bx - chunkPos.x, by - chunkPos.y, edgeMapPiselSize, IsVisibleDelegate); foreach (var edge in isVisibleTemp) { if (edge.Contains(a, b)) { continue; } float ix, iy; if (SomeMath.RayIntersect(ax, ay, abx, aby, _nodes[edge.a].x, _nodes[edge.a].z, _nodes[edge.b].x, _nodes[edge.b].z, out ix, out iy) && SomeMath.SqrDistance(ax, ay, ix, iy) < sqrDist) { return(false); } } return(true); //Vector2 aPos = _nodes[a].positionV2; //Vector2 bPos = _nodes[b].positionV2; //Vector2 dir = bPos - aPos; //float curSqrDist = SomeMath.SqrDistance(aPos, bPos); //foreach (var edge in edges) { // if (edge.Contains(a, b)) // continue; // Vector2 intersection; // if (SomeMath.RayIntersectXZ( // aPos, dir, //from, direction // NodePosV2(edge.a), NodePosV2(edge.b), //a, b // out intersection) // && SomeMath.SqrDistance(aPos, intersection) < curSqrDist) { // //Debuger3.AddRay(new Vector3(intersection.x, 0, intersection.y), Vector3.up, Color.magenta); // //Debuger3.AddLine(ds.NodePosV3(a), new Vector3(intersection.x, 0, intersection.y), Color.magenta); // //Debuger3.AddLine(ds.NodePosV3(b), new Vector3(intersection.x, 0, intersection.y), Color.magenta); // return false; // } //} //return true; }
public void AddEdge(int a, int b, int usage, bool checkContains = true) { TriangulatorEdge edge = new TriangulatorEdge(a, b, _edges.Count); if (checkContains && _edges.Contains(edge)) { return; } _edges.Add(edge); _edgesUsage.Add(usage); curAddEdge = edge; DDARasterization.DrawLine( (nodes[a].x - chunkPos.x), (nodes[a].z - chunkPos.y), (nodes[b].x - chunkPos.x), (nodes[b].z - chunkPos.y), edgeMapPiselSize, AddEdgeDelegate); //Debuger_K.AddLine(nodes[a].positionV3, nodes[b].positionV3, Color.blue, 0.1f); }
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); }