public bool IsInRect(S2DPoint point) { return(point.m_iX >= m_sPLT.m_iX && point.m_iX <= m_sPRB.m_iX && point.m_iY >= m_sPLT.m_iY && point.m_iY <= m_sPRB.m_iY); }
void OnDrawGizmosSelected() { if (null != m_pPathData) { switch (m_eGizmo) { case EPathGizmoShow.EPGS_StrictAStar: DrawStrictAStarPath(); break; case EPathGizmoShow.EPGS_HeightWalkableNormal: DrawGizmoHeightWalkNormal(); break; case EPathGizmoShow.EPGS_CommonOptimize: DrawCommonOptimize(); break; case EPathGizmoShow.EPGS_OpenList: DrawOpenList(); break; case EPathGizmoShow.EPGS_Swamp: DrawSwamp(); break; case EPathGizmoShow.EPGS_JPS: DrawJPS(); break; case EPathGizmoShow.EPGS_BlockAStar: DrawBlockAStar(); break; } } if (null != m_pPathData && GridX >= 0 && GridX < SceneConstant.m_iSceneSize && GridY >= 0 && GridY < SceneConstant.m_iSceneSize) { for (int i = GridX - 2; i <= GridX + 2; ++i) { for (int j = GridY - 2; j <= GridY + 2; ++j) { S2DPoint pt = new S2DPoint(i, j); if (pt.m_bValid) { Gizmos.color = (GridMath.m_byWalkable == m_pPathData.m_byGridStateData[pt]) ? Color.blue : Color.red; Gizmos.DrawCube(new Vector3(pt.ToV2().x, 2.0f, pt.ToV2().y), Vector3.one * (1.0f / (1.0f + Mathf.Max(Mathf.Abs(i - GridX), Mathf.Abs(j - GridY))))); } } } } }
public bool IsInRect(S2DPoint a, S2DPoint b) { return(a.m_iX >= m_sPLT.m_iX && a.m_iX <= m_sPRB.m_iX && a.m_iY >= m_sPLT.m_iY && a.m_iY <= m_sPRB.m_iY && b.m_iX >= m_sPLT.m_iX && b.m_iX <= m_sPRB.m_iX && b.m_iY >= m_sPLT.m_iY && b.m_iY <= m_sPRB.m_iY); }
public static S2DPoint GetRadiusPoint(S2DPoint center, int radius, int index) { if (index < 4) { switch (index) { case 0: return(new S2DPoint(center.m_iX, center.m_iY - radius)); case 1: return(new S2DPoint(center.m_iX, center.m_iY + radius)); case 2: return(new S2DPoint(center.m_iX - radius, center.m_iY)); case 3: return(new S2DPoint(center.m_iX + radius, center.m_iY)); } } int iRealIndex = ((index - 4) / 8) + 1; switch ((index - 4) % 8) { case 0: return(new S2DPoint(center.m_iX + iRealIndex, center.m_iY - radius)); case 1: return(new S2DPoint(center.m_iX - iRealIndex, center.m_iY + radius)); case 2: return(new S2DPoint(center.m_iX - iRealIndex, center.m_iY - radius)); case 3: return(new S2DPoint(center.m_iX + iRealIndex, center.m_iY + radius)); case 4: return(new S2DPoint(center.m_iX - radius, center.m_iY + iRealIndex)); case 5: return(new S2DPoint(center.m_iX + radius, center.m_iY - iRealIndex)); case 6: return(new S2DPoint(center.m_iX - radius, center.m_iY - iRealIndex)); case 7: return(new S2DPoint(center.m_iX + radius, center.m_iY + iRealIndex)); } return(invalid); }
private void DrawOpenList() { #if DebugJPSOpenlist if (null != m_pPathData && null != m_pPathData._debugJpsOpenList && SceneConstant.m_iSceneSizeSq == m_pPathData._debugJpsOpenList.Length && null != m_pPathData._debugJpsDeadList && SceneConstant.m_iSceneSizeSq == m_pPathData._debugJpsDeadList.Length) { for (int i = 0; i < SceneConstant.m_iSceneSize; ++i) { for (int j = 0; j < SceneConstant.m_iSceneSize; ++j) { S2DPoint pt = new S2DPoint(i, j); if (m_pPathData._debugJpsOpenList[pt] >= 0 && m_pPathData._debugJpsOpenList[pt] != pt) { S2DPoint parent = m_pPathData._debugJpsOpenList[pt]; if (parent.m_bValid) { Gizmos.color = Color.green; Gizmos.DrawLine( new Vector3(pt.ToV2().x, 5.0f, pt.ToV2().y), new Vector3(parent.ToV2().x, 5.0f, parent.ToV2().y)); } } if (m_pPathData._debugJpsDeadList[pt] >= 0 && m_pPathData._debugJpsDeadList[pt] != pt) { S2DPoint parent = m_pPathData._debugJpsDeadList[pt]; if (parent.m_bValid) { Gizmos.color = Color.red; Gizmos.DrawLine( new Vector3(pt.ToV2().x, 4.5f, pt.ToV2().y), new Vector3(parent.ToV2().x, 4.5f, parent.ToV2().y)); } } } } } #endif }
/// <summary> /// Using the input gridsState to find a path, not using any H-functions. Should only use in Editor. /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <param name="gridsState"></param> /// <param name="length">length of the path, -1 if path not exist</param> /// <returns>path</returns> static public S2DPoint[] StrictAStar(S2DPoint start, S2DPoint end, byte[] gridsState, out float length) { if (start == end) { length = 0.0f; return(new[] { start }); } if (m_byWalkable != gridsState[start]) { length = -1.0f; //CRuntimeLogger.LogWarning("Start is not a walkable"); return(null); } ++m_iAStarIndex; _tmpOpList[start] = m_iAStarIndex; _tmpParentList[start] = 0; _tmpFVList[start] = 0.0f; _tmpDistToParentList[start] = 0.0f; m_opList.Clear(); m_opList.Add(start); int iOpenListStart = 0; int iProtect = m_iAstarProtect; while (m_opList.Count > iOpenListStart && iProtect > 0) { --iProtect; if (iProtect < 0) { CRuntimeLogger.LogError("No Way!"); length = -1.0f; return(null); } //find lowest f in open list //lowest f is always the first one S2DPoint pLowestF = m_opList[iOpenListStart]; //If in close list, skip it if (m_iAStarIndex == _tmpClsList[pLowestF]) { ++iOpenListStart; continue; } if (m_byWalkable != gridsState[pLowestF]) { CRuntimeLogger.LogError("No Way!"); length = -1.0f; return(null); } //Add to close list _tmpClsList[pLowestF] = m_iAStarIndex; if (pLowestF == end) { break; } //Open List is sorted, just add one index for next loop ++iOpenListStart; m_tmpNewAddNode.Clear(); #region Connect Points //check connected points for (short i = -1; i < 2; ++i) { for (short j = -1; j < 2; ++j) { if (i != 0 || j != 0) { S2DPoint connect = (i + pLowestF.m_iX) * SceneConstant.m_iSceneSize + (j + pLowestF.m_iY); if (connect.m_bValid && m_byWalkable == gridsState[connect] && _tmpClsList[connect] != m_iAStarIndex) { if (_tmpOpList[connect] != m_iAStarIndex) { _tmpParentList[connect] = pLowestF + 1; _tmpOpList[connect] = m_iAStarIndex; float fDist = (connect.m_iX == pLowestF.m_iX || connect.m_iY == pLowestF.m_iY) ? m_fStraightDist : m_fDiagDist; _tmpDistToParentList[connect] = fDist; _tmpFVList[connect] = _tmpFVList[pLowestF] + fDist; m_tmpNewAddNode.Add(connect); } else { float fNewDist = (connect.m_iX == pLowestF.m_iX || connect.m_iY == pLowestF.m_iY) ? m_fStraightDist : m_fDiagDist; float newF = _tmpFVList[pLowestF] + fNewDist; //Check F Value if (newF < _tmpFVList[connect]) { _tmpFVList[connect] = newF; _tmpDistToParentList[connect] = fNewDist; _tmpParentList[connect] = pLowestF + 1; m_tmpNewAddNode.Add(connect); } } } } } } #endregion #region New Lowest F, Resort Order for (int i = 0; i < m_tmpNewAddNode.Count; ++i) { int iInsertPos = -1; for (int j = iOpenListStart; j < m_opList.Count; ++j) { if (_tmpFVList[m_tmpNewAddNode[i]] < _tmpFVList[m_opList[j]]) { iInsertPos = j; break; } } // the connect point may be add into an open list twice (or even more) // however it dose not harm, because the first place is the lowestF // after lowest F, it is in close list, and will be skipped anywhere if (-1 == iInsertPos) { m_opList.Add(m_tmpNewAddNode[i]); } else { m_opList.Insert(iInsertPos, m_tmpNewAddNode[i]); } } #endregion } if (_tmpParentList[end] > 0) { m_res.Clear(); m_res.Add(end); length = 0.0f; S2DPoint pLastParent = end; int iProtected2 = m_iAstarProtect; while (_tmpParentList[pLastParent] > 0 && iProtected2 > 0) { --iProtected2; if (iProtected2 < 0) { length = -1.0f; CRuntimeLogger.LogError("what?"); return(null); } S2DPoint parent = _tmpParentList[pLastParent] - 1; m_res.Insert(0, parent); length += _tmpDistToParentList[pLastParent];; pLastParent = parent; } return(m_res.ToArray()); } length = -1.0f; //CRuntimeLogger.LogWarning(string.Format("End does not have a parent. protect: {0}, oplist: {1}, opstart: {2}", iProtect, m_opList.Count, iOpenListStart)); return(null); }
public bool Equals(S2DPoint other) { return(m_iIndex == other.m_iIndex); }
public static S2DPoint Step(S2DPoint pt, short step) { return(new S2DPoint(pt.m_iX * step, pt.m_iY * step)); }
void Update() { #region Editor test if (TestPath) { TestPath = false; if (null != m_pStart && null != m_pEnd) { switch (m_eGizmo) { case EPathGizmoShow.EPGS_StrictAStar: { m_bHasStrictAStarPath = true; float flength = 0.0f; S2DPoint[] res = GridMath.StrictAStar( new Vector2(m_pStart.transform.position.x, m_pStart.transform.position.z), new Vector2(m_pEnd.transform.position.x, m_pEnd.transform.position.z), m_pPathData.m_byGridStateData, out flength ); m_v2PathStrictAStar = new Vector2[res.Length]; for (int i = 0; i < res.Length; ++i) { m_v2PathStrictAStar[i] = res[i].ToV2(); } CRuntimeLogger.Log(flength); } break; /* * case EPathGizmoShow.EPGS_Swamp: * { * m_pPathData.ResetGrids(); * EPathRes eres = EPathRes.EPR_NoPath; * m_v2PathSwamp = m_pPathData.FindPathAStar( * new Vector2(m_pStart.transform.position.x, m_pStart.transform.position.z), * new Vector2(m_pEnd.transform.position.x, m_pEnd.transform.position.z), * -1, * out eres * ); * m_bSwampPath = true; * } * break; */ case EPathGizmoShow.EPGS_JPS: { m_pPathData.BakePruningRule(); m_pPathData.InitialBlockbasedGrid(); m_pPathData.ResetGrids(); EPathRes eres = EPathRes.EPR_NoPath; m_v2PathJPS = m_pPathData.FindPathJPS( new Vector2(m_pStart.transform.position.x, m_pStart.transform.position.z), new Vector2(m_pEnd.transform.position.x, m_pEnd.transform.position.z), 30, out eres ); m_bJPSPath = true; } break; /* * case EPathGizmoShow.EPGS_BlockAStar: * { * m_pPathData.ResetBlockAStarBlocks(); * * EPathRes eres = EPathRes.EPR_NoPath; * m_v2PathBlockAStar = m_pPathData.FindPathBlockAStar( * new Vector2(m_pStart.transform.position.x, m_pStart.transform.position.z), * new Vector2(m_pEnd.transform.position.x, m_pEnd.transform.position.z), * -1, * out eres * ); * m_bBlockAStarPath = true; * } * break; */ } } } #endregion #region Running Test if (StartPerformanceTest) { for (int i = 0; i < 200; ++i) { S2DPoint p1 = S2DPoint.random; S2DPoint p2 = S2DPoint.random; EPathRes eres = EPathRes.EPR_NoPath; //m_pPathData.FindPathAStarOld(p1.ToV2(), p2.ToV2(), -1, out eres); //m_pPathData.FindPathAStar(p1.ToV2(), p2.ToV2(), -1, out eres); //m_pPathData.FindPathBlockAStar(p1.ToV2(), p2.ToV2(), -1, out eres); //m_pPathData.FindPathJPSOld(p1.ToV2(), p2.ToV2(), -1, out eres); //m_pPathData.FindPathJPS(p1.ToV2(), p2.ToV2(), -1, out eres); //m_pPathData.FindPathJPSMJ(p1.ToV2(), p2.ToV2(), -1, out eres); //blocked jps without multi-jump is the best, it expand more open-list at same time!(so it should be slower..but, not...) //for a partial path, or non-reachable, expand more open-list is even better! m_pPathData.FindPathJPS(p1.ToV2(), p2.ToV2(), 30, out eres); m_pPathData.FindPathJPSMJ(p1.ToV2(), p2.ToV2(), 7, out eres); } } #endregion }
private void DrawCommonOptimize() { //==================================== //Line Rect if (null != m_pPathData.m_ushGridRectangleData && SceneConstant.m_iSceneSizeSq == m_pPathData.m_ushGridRectangleData.Length) { for (int i = 0; i < SceneConstant.m_iSceneSize; ++i) { for (int j = 0; j < SceneConstant.m_iSceneSize; ++j) { if (0 != (m_pPathData.m_ushGridRectangleData[i * SceneConstant.m_iSceneSize + j] & (1 << m_iRectIndex))) { Gizmos.color = new Color((16 - m_iRectIndex) / 15.0f, m_iRectIndex / 15.0f, m_iRectIndex / 15.0f); Vector3 vPos1 = new Vector3( i - SceneConstant.m_iSceneSize / 2 + 0.5f, 3.0f, j - SceneConstant.m_iSceneSize / 2 + 0.5f); Gizmos.DrawWireCube(vPos1, Vector3.one * 0.4f); } } } } //==================================== //Island if (null != m_pPathData.m_byIslandData && SceneConstant.m_iSceneSizeSq == m_pPathData.m_byIslandData.Length) { for (int i = 0; i < SceneConstant.m_iSceneSize; ++i) { for (int j = 0; j < SceneConstant.m_iSceneSize; ++j) { if (m_pPathData.m_byIslandData[i * SceneConstant.m_iSceneSize + j] > 0 && m_iIslandIndex == m_pPathData.m_byIslandData[i * SceneConstant.m_iSceneSize + j]) { Gizmos.color = new Color((16 - m_iIslandIndex) / 15.0f, m_iIslandIndex / 15.0f, m_iIslandIndex / 15.0f); Vector3 vPos1 = new Vector3( i - SceneConstant.m_iSceneSize / 2 + 0.5f, 5.0f, j - SceneConstant.m_iSceneSize / 2 + 0.5f); Gizmos.DrawWireCube(vPos1, Vector3.one * 0.2f); } } } } //===================================================== //near grid if (null != m_pPathData.m_shNearGridData && SceneConstant.m_iSceneSizeSq * (m_pPathData.m_byIslandNumber + 1) == m_pPathData.m_shNearGridData.Length && m_iNearIndex <= m_pPathData.m_byIslandNumber) { for (int i = 0; i < SceneConstant.m_iSceneSize; ++i) { for (int j = 0; j < SceneConstant.m_iSceneSize; ++j) { S2DPoint pt = m_pPathData.m_shNearGridData[m_iNearIndex * SceneConstant.m_iSceneSizeSq + i * SceneConstant.m_iSceneSize + j]; if (pt != new S2DPoint(i, j)) { Gizmos.color = Color.blue; Vector3 vPos1 = new Vector3( i - SceneConstant.m_iSceneSize / 2 + 0.5f, 2.0f, j - SceneConstant.m_iSceneSize / 2 + 0.5f); Vector3 vPos2 = new Vector3( pt.m_iX - SceneConstant.m_iSceneSize / 2 + 0.5f, 2.0f, pt.m_iY - SceneConstant.m_iSceneSize / 2 + 0.5f); Gizmos.DrawLine(vPos2, vPos1); } } } } }