Пример #1
0
 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);
         }
     }
 }
Пример #2
0
        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);
        }
Пример #3
0
        /// <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);
        }
Пример #6
0
        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**********************//
        }