} // public bool setNaviPortal_forShortestWay(int iSeqCell) // Collect all blocks requestcell to goal. And then buildup shortest way start to goal. // 요청셀 부터 골까지의 길 셀만을 모은다(가장 짧은 길을 택한다) public void collectWayToGoalLinear(int iCellStart, ref List <CNAVICELL> listSequenceCell_) { if (m_arrNavicells.Length <= iCellStart || 0 > iCellStart) { return; } bool bCollectComplete = false; CNAVICELL cellWay = m_arrNavicells[iCellStart]; bCollectComplete = false; listSequenceCell_.Add(cellWay); // collect start cell first. //@ first collect all blocks start -> goal. while (false == bCollectComplete) { int iIdxCellBestWay = cellWay.getIdxCell_nextWay(); if (CNAVICELL.NULL_CELL == iIdxCellBestWay) { return; } cellWay = m_arrNavicells[iIdxCellBestWay]; listSequenceCell_.Add(cellWay); // Last unit must be goalcell. if (true == cellWay.IsGoalCell()) { bCollectComplete = true; } } // while (false == bCollectComplete) } // public void collectWayToGoalLinear
public void setLinkAllAdjs(ref CNAVICELL[] arrnavicellall, ref List <int> listCellAdjCollected) { bool bComputeOK = false; int iLevelFromGoalParent = m_iLevelToGoal; int iLevelBlockroad = m_iLevelBlockroadToGoal; CNAVICELL.E_CELL_SIDEEDGE eEdgeAdj; for (int iEdge = 0; iEdge < 3; ++iEdge) { eEdgeAdj = (CNAVICELL.E_CELL_SIDEEDGE)iEdge; int iSeqCellAdj = m_arriAdjCells[iEdge]; if (CNAVICELL.NULL_CELL == iSeqCellAdj) { continue; } if (eEdgeAdj == m_eEdge_bestway) { continue; } CNAVICELL naviCellAdj = arrnavicellall[iSeqCellAdj]; bComputeOK = naviCellAdj.setLinkcomputeCell(iLevelFromGoalParent + 1, m_iSeqCell, m_arrfcosttoGoal_edge[iEdge], iLevelBlockroad); if (true == bComputeOK) { listCellAdjCollected.Add(iSeqCellAdj); } } // for( int iEdge=0; iEdge<3; ++iEdge) }
// 함수:Mapping Navigation() // Build up cost of the way from the goal iterating all cells. // 1. Calculate cost of the way from the goal which iterating all cells. // -return:Updated Cells protected void mappingNavigation_(List <int> listCellsGoal, List <int> listCellsBlock, List <int> listCellsBlockroad, ref CNAVICELL[] arrNavicells) { bool bMappingComplete = false; int iLevelFromGoalRefer = 0, iLevelFromGoalIterator = 0; List <int> listCellAdjCollected = new List <int>(); List <int> listCellsIterator_ = new List <int>(); //@ Set all block cell for (int iSeqCell = 0; iSeqCell < listCellsBlock.Count; ++iSeqCell) { CNAVICELL naviCellCurr = m_arrNavicells[listCellsBlock[iSeqCell]]; naviCellCurr.SetBlockCell(); } //@ Set all blockroad cell for (int iSeqCell = 0; iSeqCell < listCellsBlockroad.Count; ++iSeqCell) { CNAVICELL naviCellCurr = m_arrNavicells[listCellsBlockroad[iSeqCell]]; naviCellCurr.SetBlockRoadCell(); } //@ construct top(GOAL) to leap for (int iSeqCellGoal = 0; iSeqCellGoal < listCellsGoal.Count; ++iSeqCellGoal) { int iSeqCell = listCellsGoal[iSeqCellGoal]; CNAVICELL naviCellCurr = arrNavicells[iSeqCell]; naviCellCurr.setLinkcomputeNaviCell_GOAL(0, (int)(CNAVICELL.E_CELL_STATUS.CELL_STATUS_GOAL), 0.0f); listCellsIterator_.Add(iSeqCell); } //@ Simulate validation or not. do // while( false==bMappingComplete ) { foreach (int iSeqCellParent_ in listCellsIterator_) { CNAVICELL naviCellParent = arrNavicells[iSeqCellParent_]; naviCellParent.setLinkAllAdjs(ref m_arrNavicells, ref listCellAdjCollected); } if (listCellAdjCollected.Count < 1) { bMappingComplete = true; break; } iLevelFromGoalRefer = ++iLevelFromGoalIterator; listCellsIterator_.Clear(); listCellAdjCollected.Sort(); foreach (int iSeqCellADJ in listCellAdjCollected) { listCellsIterator_.Add(iSeqCellADJ); } listCellAdjCollected.Clear(); } while (false == bMappingComplete); m_iDepthLevel_Navi = iLevelFromGoalRefer; } // protected void mappingNavigation_(List<int> listCellsGoal, List<int> listCellsBlock, ref CNAVICELL[] arrNavicells)
protected int simulateMappingNavigation_(List <int> listCellsGoal, List <int> listCellsBlock, ref CNAVICELL[] arrNavicells) { int iLevelFromGoalRefer = -1, iIteratorLevel = 0; List <int> listCellsCurrentLevel = new List <int>(); for (int iSeqCell = 0; iSeqCell < listCellsBlock.Count; ++iSeqCell) { CNAVICELL naviCellCurr = arrNavicells[listCellsBlock[iSeqCell]]; naviCellCurr.SetBlockCell(); } //@ Set all Goal, block cell for (int iSeqCellGoal = 0; iSeqCellGoal < listCellsGoal.Count; ++iSeqCellGoal) { int iSeqCell = listCellsGoal[iSeqCellGoal]; CNAVICELL naviCellCurr = arrNavicells[iSeqCell]; naviCellCurr.setLinkcomputeSimulate(0, (int)(CNAVICELL.E_CELL_STATUS.CELL_STATUS_GOAL)); listCellsCurrentLevel.Add(iSeqCell); } listCellsCurrentLevel.Sort(); List <int> listCellsNextLevel = new List <int>(); bool bMappingComplete = false; while (false == bMappingComplete) { foreach (int iSeqCell in listCellsCurrentLevel) { CNAVICELL naviCellParent = arrNavicells[iSeqCell]; naviCellParent.setLinkAllAdjs_simulate(iSeqCell, iLevelFromGoalRefer, ref m_arrNavicells, ref listCellsCurrentLevel, ref listCellsNextLevel); } if (listCellsNextLevel.Count > 0) { iLevelFromGoalRefer = iIteratorLevel++; listCellsNextLevel.Sort(); listCellsCurrentLevel.Clear(); foreach (int iSeqCellAdjacentNextlevel in listCellsNextLevel) { listCellsCurrentLevel.Add(iSeqCellAdjacentNextlevel); } listCellsNextLevel.Clear(); } else { bMappingComplete = true; break; } } // while (false == bMappingComplete) return(iLevelFromGoalRefer); } // protected bool mappingNavigation_Simulate_(List<int> listCellsGoal, List<int> listCellsBlock, ref CNAVICELL[] arrNavicells)
} // public bool getPosWayToGoal(int iSeqCell_current, ref CCellWayto pntNavi_out) //@ -Return:pre-calculated shortest cost middle edge position (way to goal) (when mappingnavigation). // Every navicell have just only one shortest way to GOAL. public CNAVICELL.E_CELL_STATUS getPosNextWayTo(int iSeqCell_current, ref CCellWayto pntNavi_out) { if (iSeqCell_current > (int)m_arrNavicells.Length || iSeqCell_current < 0) { Debug.Log("!!!ERROR iSeqCell_current>(int)m_arrNavicells.size()||iSeqCell_current<0"); return(CNAVICELL.E_CELL_STATUS.CELL_STATUS_NULL); } CNAVICELL naviCellcurr = m_arrNavicells[iSeqCell_current]; Vector3 v3PosDest = new Vector3(); Vector3 v3PosStart = new Vector3(); naviCellcurr.getPos_nextWay(ref v3PosStart); int iIdxCellCurrent = naviCellcurr.seqCell; int iIdxCellNextTo = naviCellcurr.getIdxCell_nextWay(); if (CNAVICELL.NULL_CELL == iIdxCellNextTo) { return(CNAVICELL.E_CELL_STATUS.CELL_STATUS_NULL); } CNAVICELL naviCellNext = m_arrNavicells[iIdxCellNextTo]; if (naviCellNext.IsGoalCell()) { return(CNAVICELL.E_CELL_STATUS.CELL_STATUS_GOAL); } bool bGetPos_nextWay = naviCellNext.getPos_nextWay(ref v3PosDest); if (false == bGetPos_nextWay) { return(CNAVICELL.E_CELL_STATUS.CELL_STATUS_NULL); } Vector3 posEdgeTo0 = new Vector3(), posEdgeTo1 = new Vector3(), posEdgeFrom0 = new Vector3(), posEdgeFrom1 = new Vector3(); naviCellcurr.getPntsOfEdgeBestway(ref posEdgeFrom0, ref posEdgeFrom1); naviCellNext.getPntsOfEdgeBestway(ref posEdgeTo0, ref posEdgeTo1); Vector3 v3dirEntryToNextway = naviCellNext.getDirEntryToGoal(iIdxCellCurrent); pntNavi_out.setPntnavi(iIdxCellNextTo, naviCellcurr.leveltogoal, v3PosStart, v3PosDest, posEdgeFrom0, posEdgeFrom1, posEdgeTo0, posEdgeTo1, naviCellNext.getPos_cellCenter(), v3dirEntryToNextway); return(CNAVICELL.E_CELL_STATUS.CELL_STATUS_ROAD); } // public bool getPosWayToGoal(int iSeqCell_current, ref CCellWayto pntNavi_out)
public bool getCell(uint iIdxCell, ref CNAVICELL naviCell) { if (iIdxCell > m_arrNavicells.Length) { return(false); } naviCell = m_arrNavicells[iIdxCell]; return(true); }
} // public void DestructNavi() //@ Private //@ Build all Cells relationship with adjacent Cells. (N^2) CELL * CELL protected void buildupAdjacentAll(ref CNAVICELL[] arrNavicells) { for (int iSeqCell = 0; iSeqCell < arrNavicells.Length; ++iSeqCell) { CNAVICELL naviCell = (arrNavicells[iSeqCell]); BuildAdjacentATri(ref naviCell, ref arrNavicells); } //FORTEST //validateAllAdjcntCells(arrNavicells); }
public void setLinkAllAdjs_simulate(int iSeqCell, int iLevelFromGoal, ref CNAVICELL[] arrnavicellall, ref List <int> listCellsCurrentLevel, ref List <int> listCellsNextLevel) { if (true == IsBlockCell()) { return; } CNAVICELL.E_CELL_SIDEEDGE eEdgeAdj; bool bOverlappedWith = false, bComputeOK = false; for (int iEdge = 0; iEdge < 3; ++iEdge) { eEdgeAdj = (CNAVICELL.E_CELL_SIDEEDGE)iEdge; int iSeqCellAdj = m_arriAdjCells[iEdge]; if (CNAVICELL.NULL_CELL == iSeqCellAdj) { continue; } CNAVICELL naviCellAdj = arrnavicellall[iSeqCellAdj]; if (naviCellAdj.IsBlockCell() || naviCellAdj.IsGoalCell()) { continue; } if (eEdgeAdj == m_eEdge_bestway) { continue; } if (CNAVICELL.NULL_LEVELFROMGOAL == naviCellAdj.m_iLevelToGoal) { bOverlappedWith = (-1 < listCellsCurrentLevel.BinarySearch(iSeqCellAdj)); if (false == bOverlappedWith) { bComputeOK = naviCellAdj.setLinkcomputeSimulate(iLevelFromGoal, iSeqCell); if (true == bComputeOK) { listCellsNextLevel.Add(iSeqCellAdj); } } } // if (CNAVICELL.NULL_LEVELFROMGOAL == naviCellAdj.m_iLevelToGoal) } // for (int iEdge = 0; iEdge < 3; ++iEdge) } // public void setLinkAllAdjs_simulate
// Every navicell have just only one shortest way to GOAL. public bool getPosWayToGoal(int iSeqCell_current, ref Vector3 v3PosDest) { if (iSeqCell_current > (int)m_arrNavicells.Length || iSeqCell_current < 0) { Debug.Log("iSeqCell_current>(int)m_arrNavicells.size()||iSeqCell_current<0"); return(false); } CNAVICELL naviCell = m_arrNavicells[iSeqCell_current]; if (naviCell.IsBlockCell()) { return(false); } return(naviCell.getPos_nextWay(ref v3PosDest)); }
} // public bool getPosWayTo_Portal( int iSeqCell_current, ref Vector3 v3PosDest ) //@ Get adjacent Index Triangles validated. public void getAdjacentTris(int iSeqCell, ref List <int> listTrisAdj) { if (iSeqCell > m_arrNavicells.Length) { return; } CNAVICELL naviCellCurr = m_arrNavicells[iSeqCell]; for (int iAdj = 0; iAdj < naviCellCurr.m_arriAdjCells.Length; ++iAdj) { int iAdjTri = naviCellCurr.m_arriAdjCells[iAdj]; if (iAdjTri != CNAVICELL.NULL_CELL) { listTrisAdj.Add(iAdjTri); } } }
//@ -Return: public bool getPosWayTo_Portal(int iSeqCell_current, Vector2[] arrv2PntObjBoundary, ref Vector3 v3PosDest) { if (iSeqCell_current > (int)m_arrNavicells.Length || iSeqCell_current < 0) { Debug.Log("iSeqCell_current>(int)m_arrNavicells.size()||iSeqCell_current<0"); return(false); } CNAVICELL naviCellCurr = m_arrNavicells[iSeqCell_current]; if (naviCellCurr.IsBlockCell()) { return(false); } //@ 가시성을 고려한 최단 거리의 위치값 설정. setNaviPortal_forShortestWay(arrv2PntObjBoundary, ref naviCellCurr); return(naviCellCurr.getPos_nextWay(ref v3PosDest)); } // public bool getPosWayTo_Portal( int iSeqCell_current, ref Vector3 v3PosDest )
} // protected bool BuildAdjacentATri // 함수:ConstructTrisToCells // 네비게이션을 위한 모든 셀들과 인접 셀들을 생성한다 //@ Construct all adjacent Cells for navigation. protected void ConstructTrisToCells(List <CTRI> listTris_) { int iCntTris = listTris_.Count; m_arrNavicells = new CNAVICELL[iCntTris]; // Tri카운트 만큼 네비셀 생성 for (int iTri = 0; iTri < iCntTris; iTri++) { CTRI triCurr = listTris_[iTri]; CNAVICELL naviCell = new CNAVICELL(); naviCell.InitializeNaviCell(); // 각 셀들의 초기화 //@ Compute each middle edge to Center naviCell.SetComponentCell(iTri, triCurr); // Tri 기본 정보를 네비셀에 전달 그리고 각각의 미들 엣지,센터를 계산 m_arrNavicells[iTri] = naviCell; } buildupAdjacentAll(ref m_arrNavicells); // 인접 셀 빌드업 }
} // protected float differChangeRateBetweenVec3(Vector3 v3Way0, Vector3 v3Way1, Vector3 v3Way2) //@ search intersected point // faster then 3.x~4.x times average, prepare RayIntersect. public int intersectRay_inAdjs(int iSeqCell, Vector3 v3RayOrigin, Vector3 v3RayDir, ref Vector3 posIntersected_out) { if (CNAVICELL.NULL_CELL == iSeqCell) { return(CNAVICELL.NULL_CELL); } CNAVICELL navicell = m_arrNavicells[iSeqCell]; int iIdxIntersectedCell = CNAVICELL.NULL_CELL; bool bIntersectedCell = false; bIntersectedCell = CMATH.IntersectRayTri_GetPos( v3RayOrigin, v3RayDir, navicell.m_arrv3PT, ref posIntersected_out); if (true == bIntersectedCell) { iIdxIntersectedCell = iSeqCell; } else { foreach (int iIterCell in navicell.m_arriAdjCells) { if (CNAVICELL.NULL_CELL != iIterCell) { bIntersectedCell = m_arrNavicells[iIterCell].trilinkcell.IntersectRayTri(v3RayOrigin, v3RayDir, ref posIntersected_out); if (true == bIntersectedCell) { iIdxIntersectedCell = iIterCell; break; } } // if (CNAVICELL.NULL_CELL != iSeqCell) } // foreach(int iSeqCellNavi in navicell.m_arriAdjCells) } // if (true == bIntersectedCell) return(iIdxIntersectedCell); } // public bool intersectRay_inAdjs(int iSeqCell, Vector3 v3RayOrigin, Vector3 v3RayDir, ref Vector3 posIntersected_out)
protected bool extractNavicellToAdj( List <CTRI> listTris, CNAVICELL[] arrNavicells, ref CNAVICELL.CADJ_TRI[] arrAdjs) { int iCntNaviCell = arrNavicells.Length; if (iCntNaviCell < 1) { Debug.Log("if(iCntNaviCell < 1)"); return(false); } arrAdjs = new CNAVICELL.CADJ_TRI[iCntNaviCell]; for (int iSeqTri = 0; iSeqTri < iCntNaviCell; ++iSeqTri) { CNAVICELL naviCellCurr = arrNavicells[iSeqTri]; arrAdjs[iSeqTri] = naviCellCurr.getAdj(); arrAdjs[iSeqTri].tri = listTris[iSeqTri]; } return(true); }
//@ For DEBUG, check all adjacent cells. protected void validateAllAdjcntCells(CNAVICELL[] arrNavicells) { string szOutputDebug; uint uiCnt = 0; szOutputDebug = "Validate All Adjacent Cell\n"; szOutputDebug += "============================================================================"; Debug.Log(szOutputDebug); szOutputDebug = ""; int iCntCells = arrNavicells.Length; for (int iSeqCell = 0; iSeqCell < iCntCells; ++iCntCells, ++uiCnt) { CNAVICELL cellRight = arrNavicells[iSeqCell]; //szOutputDebug = "\n " + uiCnt + ". TriSeq(" + cellRight.m_iSeq + ")"; // szOutputDebug += "AdjacentTri :"; for (int iAdj = 0; iAdj < CNAVICELL.countSideEdge; ++iAdj) { int iAdjcntTri = cellRight.m_arriAdjCells[iAdj]; szOutputDebug += "/i=" + iAdjcntTri; } szOutputDebug += "\n " + uiCnt + ". TriSeq(" + cellRight.seqCell + ")//"; } Debug.Log(szOutputDebug); //validateAdjcnt_Iteration( 0, arrNavicells ); szOutputDebug += "Check Call by NeiborTri"; szOutputDebug += "============================================================================"; Debug.Log(szOutputDebug); szOutputDebug = ""; }
//@ -Return:pre-calculated shortest cost middle edge position (way to goal) (when mappingnavigation). // Every navicell have just only one shortest way to GOAL. public CNAVICELL.E_CELL_STATUS getPosCurrentWayToGoal(int iSeqCell_current, ref CCellWayto pntNavi_out) { if (iSeqCell_current > (int)m_arrNavicells.Length || iSeqCell_current < 0) { Debug.Log("!!!ERROR iSeqCell_current>(int)m_arrNavicells.size()||iSeqCell_current<0"); return(CNAVICELL.E_CELL_STATUS.CELL_STATUS_NULL); } CNAVICELL naviCell = m_arrNavicells[iSeqCell_current]; Vector3 v3PosDest = Vector3.zero; bool bGetPos_nextWay = naviCell.getPos_nextWay(ref v3PosDest); if (false == bGetPos_nextWay || Vector3.zero == v3PosDest) { return(CNAVICELL.E_CELL_STATUS.CELL_STATUS_NULL); } Vector3 posEdge0 = new Vector3(), posEdge1 = new Vector3(); naviCell.getPntsOfEdgeBestway(ref posEdge0, ref posEdge1); pntNavi_out.setPntnavi(naviCell.seqCell, naviCell.leveltogoal, Vector3.zero, v3PosDest, posEdge0, posEdge1, posEdge0, posEdge1, naviCell.getPos_cellCenter(), naviCell.dirCenterToGoal); return(CNAVICELL.E_CELL_STATUS.CELL_STATUS_ROAD); } // public bool getPosWayToGoal(int iSeqCell_current, ref CCellWayto pntNavi_out)
} // public bool getPosWayToGoal(int iSeqCell_current, ref CCellWayto pntNavi_out) //@ -Return: public bool getPosWayTo_Portal(int iSeqCell_current, Vector2[] arrv2PntObjBoundary, ref CCellWayto pntNavi_out) { if (iSeqCell_current > (int)m_arrNavicells.Length || iSeqCell_current < 0) { Debug.Log("iSeqCell_current>(int)m_arrNavicells.size()||iSeqCell_current<0"); return(false); } CNAVICELL naviCellCurr = m_arrNavicells[iSeqCell_current]; //@ 가시성을 고려한 최단 거리의 위치값 설정. Vector3 v3PosDest = new Vector3(); bool bGetPos_nextWay = setNaviPortal_forShortestWay(arrv2PntObjBoundary, ref naviCellCurr); if (false == bGetPos_nextWay) { return(false); } pntNavi_out._idxnavicell = naviCellCurr.seqCell; pntNavi_out._postoDest = v3PosDest; return(true); }
// Collect all blocks start to goal. And then buildup shortest way start to goal. // 처음 스타트 부터 골까지의 모든 네비 블럭을 모은다(가장 짧은 길을 택한다) static public void collectWayToGoalLinear(CNAVICELL[] arrNavicells_, CNAVICELL cellStart_, ref List <CNAVICELL> listSequenceCell_, ref CComputeEdgeBlock processorEdge_) { bool bOrganizedComplete = false; Vector3 v3PntEdge0 = new Vector3(); Vector3 v3PntEdge1 = new Vector3(); CNAVICELL cellWay = cellStart_; bOrganizedComplete = false; listSequenceCell_.Add(cellWay); //First unit is startcell. //@ first collect all blocks start -> goal. while (false == bOrganizedComplete) { CTRI triWaytoGoal = cellWay.trilinkcell; //@ if Adjacent cell is NULL, add new EDGE list. //이웃셀이 없다면 추가한다 for (int iSeqAdj = 0; iSeqAdj < cellWay.m_arriAdjCells.Length; ++iSeqAdj) { int iIdxAdj = cellWay.m_arriAdjCells[iSeqAdj]; CTRI.E_TRI_EDGE eEdge = (CTRI.E_TRI_EDGE)iSeqAdj; //@ Checkup adjacent Edge Tri // if (CNAVICELL.NULL_CELL == iIdxAdj) { triWaytoGoal.GetEdgePoint(eEdge, ref v3PntEdge0, ref v3PntEdge1); processorEdge_.AddToBlockEdge(v3PntEdge0, v3PntEdge1); //-> Add Edge to Block List } else { CNAVICELL cellAdj = arrNavicells_[iIdxAdj]; //@ Adj cell is block cell, then into list. if (cellAdj.IsBlockCell()) { processorEdge_.AddToBlockEdge_Tri(cellAdj.trilinkcell, iIdxAdj); //-> Add Edge to Block List } } } // for (int iAdj = 0; iAdj < naviCellNextWay.m_arriAdjCells.Length; ++iAdj) int iIdxCellBestWay = cellWay.getIdxCell_nextWay(); if (CNAVICELL.NULL_CELL == iIdxCellBestWay) { return; } cellWay = arrNavicells_[iIdxCellBestWay]; listSequenceCell_.Add(cellWay); // Last unit must be goalcell. if (true == cellWay.IsGoalCell()) { bOrganizedComplete = true; } } // while (false == bOrganizedComplete) } // protected void collectWayToGoalLinear()
//@ Actually build up relationship with adjacent Cells and calculate cost of the way to GOAL. //@ Not acceptable 1 or more NULL CELL which status is CNAVICELL.NULL_CELL protected bool BuildAdjacentATri(ref CNAVICELL cellLeft, ref CNAVICELL[] arrNavicells) { if (true == cellLeft.DidSetAllAdjacent()) { return(false); } int[] aruiIVleft = cellLeft.trilinkcell._arriIV; int[] aruiIVRight; bool bFoundShared = false; int iFoundShared = 0; int[] ariPointsShared_left = new int[3]; int[] ariPointsShared_right = new int[3]; int iCntCells = arrNavicells.Length; for (int iSeqcell = 0; iSeqcell < iCntCells; ++iSeqcell) { CNAVICELL cellRight = arrNavicells[iSeqcell]; CTRI triRight_ = cellRight.trilinkcell; if (cellRight.seqCell == cellLeft.seqCell) { continue; } for (int i = 0; i < 3; ++i) { ariPointsShared_left[i] = ariPointsShared_right[i] = CNAVICELL.NULL_CELL; } aruiIVRight = triRight_._arriIV; iFoundShared = 0; int iSharedIV_left = 0, iSharedIV_right = 0; for (int iL = 0; iL < 3; ++iL) { for (int iR = 0; iR < 3; ++iR) { if (aruiIVleft[iL] == aruiIVRight[iR]) { ariPointsShared_left[iL] = aruiIVleft[iL]; ariPointsShared_right[iR] = aruiIVRight[iR]; iSharedIV_left = iSharedIV_left + iL; iSharedIV_right = iSharedIV_right + iR; ++iFoundShared; } } // for( int iR=0; iR<3; ++iR ) } // for( int iL=0; iL<3; ++iL ) bFoundShared = (iFoundShared > 1); if (true == bFoundShared) { if (iFoundShared > 2) { break; } cellLeft.SetAdjacentCell(CNAVICELL.getTypeEdge(iSharedIV_left), cellRight.seqCell); cellRight.SetAdjacentCell(CNAVICELL.getTypeEdge(iSharedIV_right), cellLeft.seqCell); if (cellLeft.DidSetAllAdjacent() == true) { break; } } // if( iFoundShared>1 ) } // for( it_=iterBegin; it_!=iterEnd; ++it_ ) return(true); } // protected bool BuildAdjacentATri
} // public bool intersectRay_inAdjs(int iSeqCell, Vector3 v3RayOrigin, Vector3 v3RayDir, ref Vector3 posIntersected_out) //@ Organize shortest way block edges only Current cell public bool setNaviPortal_forShortestWay(Vector2[] arrv2PntObjBoundary, ref CNAVICELL cellWayStart) { if (true == cellWayStart.useWaytoPortal) { return(true); } List <CNAVICELL> listSequenceCell = new List <CNAVICELL>(); collectWayToGoalLinear(m_arrNavicells, cellWayStart, ref listSequenceCell, ref m_computeEdgeBlock); if (listSequenceCell.Count < 2) { return(true); } Vector3 v3PntPrev = new Vector3(); Vector3 v3PntCurr = new Vector3(); Vector3 v3PntNext = new Vector3(); int iLenSeq = listSequenceCell.Count; int iSeqIteration = 0; CNAVICELL cellGOAL = listSequenceCell[iLenSeq - 1]; CNAVICELL cellNext, cellPrev; bool bCrosswithBlock = false; bool bSetNewPortalPosition = false; Vector3[] arrv3Pnt_Cell_start = new Vector3[cellWayStart.m_arrv3PT.Length]; Array.Copy(cellWayStart.m_arrv3PT, arrv3Pnt_Cell_start, cellWayStart.m_arrv3PT.Length); CMATH.rescaleVertices(ref arrv3Pnt_Cell_start, DFLT_ADJUST_SCALE_FOR_VISIBLECHECK); foreach (CNAVICELL cellCurr in listSequenceCell) { int iSeqCurr = iSeqIteration++; if (0 == iSeqCurr) { continue; } if (cellGOAL == cellCurr) { cellWayStart.SetPortalPosition(cellGOAL.seqCell, cellGOAL.getPos_cellCenter()); bSetNewPortalPosition = true; break; } cellPrev = listSequenceCell[iSeqCurr - 1]; cellNext = listSequenceCell[iSeqCurr + 1]; cellCurr.getPos_BestWay_onEdge(ref v3PntCurr); cellNext.getPos_BestWay_onEdge(ref v3PntNext); cellPrev.getPos_BestWay_onEdge(ref v3PntPrev); bCrosswithBlock = false; foreach (Vector3 v3PntCell in arrv3Pnt_Cell_start) { if (m_computeEdgeBlock.crossBlockIteration(v3PntCell, v3PntNext)) { bCrosswithBlock = true; break; } } //@ Set Portal if (true == bCrosswithBlock) { cellWayStart.SetPortalPosition(cellCurr.seqCell, v3PntCurr); bSetNewPortalPosition = true; break; } Vector2 v2PntNext = CMATH.ConvertToV2_Y(v3PntNext); foreach (Vector2 v2PntObj in arrv2PntObjBoundary) { //@ Cross At least 1 mo if (true == m_computeEdgeBlock.crossBlockIteration(v2PntObj, v2PntNext)) { bCrosswithBlock = true; break; } } //@ Set Portal -2 if (true == bCrosswithBlock) { cellWayStart.SetPortalPosition(cellCurr.seqCell, v3PntCurr); bSetNewPortalPosition = true; break; } } // foreach (CNAVICELL cellCurr in listSequenceCell) listSequenceCell.Clear(); listSequenceCell = null; return(bSetNewPortalPosition); } // public bool setNaviPortal_forShortestWay(int iSeqCell)
} // public void collectWayToGoalLinear //@ Organize shortest way block edges startcell to goalcell. public bool collectWay_allStartsToGoal(CTriCollector tricollector, ref CNAVICELL[] arrSequenceCellforPortal) { if (tricollector.m_listTris_naviStart.Count < 1) { return(false); } if (tricollector.m_listTris_naviGoal.Count < 1) { return(false); } arrSequenceCellforPortal = null; Vector3 v3PntStart_ = new Vector3(); Vector3 v3PntEnd_ = new Vector3(); Vector3 v3PntPortal = new Vector3(); List <CNAVICELL> listSequenceCell = new List <CNAVICELL>(); //@ each start cell foreach (int iSeqTriStart in tricollector.m_listTris_naviStart) { CNAVICELL cellWayStart = m_arrNavicells[iSeqTriStart]; //@ First Collect all blocks start to goal. And then buildup shortest way start to goal. collectWayToGoalLinear(m_arrNavicells, cellWayStart, ref listSequenceCell, ref m_computeEdgeBlock); //@ Organize Start -> Goal if (listSequenceCell.Count > 2) { int iLenSeq = listSequenceCell.Count; int iSeqIteration = 0, iSeqPortalSpot = 0; v3PntStart_ = listSequenceCell[0].poscenterofcell; CNAVICELL cellGOAL = listSequenceCell[iLenSeq - 1]; bool bCrosswithBlock = false; foreach (CNAVICELL cellCurr in listSequenceCell) { int iSeqCurr = iSeqIteration++; if (cellCurr == cellGOAL) { break; } cellCurr.getPos_nextWay(ref v3PntEnd_); bCrosswithBlock = m_computeEdgeBlock.crossBlockIteration(v3PntStart_, v3PntEnd_); if (true == bCrosswithBlock) { iSeqPortalSpot = iSeqCurr - 1; if (listSequenceCell.Count <= iSeqPortalSpot || iSeqPortalSpot < 0) { continue; } listSequenceCell[iSeqPortalSpot].getPos_nextWay(ref v3PntPortal); ////@ Some problem this, have to solve. //for (int iCellSeq = iSeqPortalSpot__ + 1; iCellSeq < iSeqPortalSpot; ++iCellSeq) //{ // listSequenceCell[iCellSeq].SetPortalPosition(iSeqPortalSpot__, v3PntPortal); //} //for (int iCellSeq = iSeqPortalSpot; iCellSeq < iSeqCurr - 1; ++iCellSeq) v3PntStart_ = v3PntPortal; } // if (true == bCrosswithBlock) } // foreach (CNAVICELL cellCurr in listSequenceCell) int iSeqCopyTo = 0; if (null == arrSequenceCellforPortal) { arrSequenceCellforPortal = new CNAVICELL[listSequenceCell.Count]; } else { iSeqCopyTo = arrSequenceCellforPortal.Length; Array.Resize(ref arrSequenceCellforPortal, arrSequenceCellforPortal.Length + listSequenceCell.Count); } // if (null == arrSequenceCellforPortal) listSequenceCell.CopyTo(arrSequenceCellforPortal, iSeqCopyTo); listSequenceCell.Clear(); } // if(listSequenceCell.Count > 2) } // foreach(int iSeqTriStart in m_listCellsIdxStart) listSequenceCell.Clear(); listSequenceCell = null; return(true); } // protected bool collectWay_allStartsToGoal()