Esempio n. 1
0
        private void GetObstacleBounds(TileCacheObstacle ob, out Vector3 bmin, out Vector3 bmax)
        {
            bmin = new Vector3();
            bmax = new Vector3();

            if (ob.Type == ObstacleType.DT_OBSTACLE_CYLINDER)
            {
                var cl = ob.Cylinder;

                bmin.X = cl.Pos.X - cl.Radius;
                bmin.Y = cl.Pos.Y;
                bmin.Z = cl.Pos.Z - cl.Radius;
                bmax.X = cl.Pos.X + cl.Radius;
                bmax.Y = cl.Pos.Y + cl.Height;
                bmax.Z = cl.Pos.Z + cl.Radius;
            }
            else if (ob.Type == ObstacleType.DT_OBSTACLE_BOX)
            {
                bmin = ob.Box.BMin;
                bmax = ob.Box.BMax;
            }
            else if (ob.Type == ObstacleType.DT_OBSTACLE_ORIENTED_BOX)
            {
                var orientedBox = ob.OrientedBox;

                float maxr = 1.41f * Math.Max(orientedBox.HalfExtents.X, orientedBox.HalfExtents.Z);
                bmin.X = orientedBox.Center.X - maxr;
                bmax.X = orientedBox.Center.X + maxr;
                bmin.Y = orientedBox.Center.Y - orientedBox.HalfExtents.Y;
                bmax.Y = orientedBox.Center.Y + orientedBox.HalfExtents.Y;
                bmin.Z = orientedBox.Center.Z - maxr;
                bmax.Z = orientedBox.Center.Z + maxr;
            }
        }
Esempio n. 2
0
        public int GetObstacleRef(TileCacheObstacle ob)
        {
            if (ob == null)
            {
                return(0);
            }

            int idx = Array.IndexOf(m_obstacles, ob);

            return(EncodeObstacleId(ob.Salt, idx));
        }
Esempio n. 3
0
        public Status AddBoxObstacle(Vector3 center, Vector3 halfExtents, float yRadians, out int result)
        {
            result = 0;

            if (m_nreqs >= DetourTileCache.MAX_REQUESTS)
            {
                return(Status.DT_FAILURE | Status.DT_BUFFER_TOO_SMALL);
            }

            int ob = -1;

            if (m_nextFreeObstacle >= 0)
            {
                ob = m_nextFreeObstacle;
                m_nextFreeObstacle   = m_obstacles[ob].Next;
                m_obstacles[ob].Next = -1;
            }
            if (ob == -1)
            {
                return(Status.DT_FAILURE);
            }

            float coshalf = (float)Math.Cos(0.5f * yRadians);
            float sinhalf = (float)Math.Sin(-0.5f * yRadians);
            var   rotAux  = new Vector2(coshalf * sinhalf, coshalf * coshalf - 0.5f);

            int salt = m_obstacles[ob].Salt;

            m_obstacles[ob] = new TileCacheObstacle
            {
                Salt        = salt,
                State       = ObstacleState.DT_OBSTACLE_PROCESSING,
                Type        = ObstacleType.DT_OBSTACLE_ORIENTED_BOX,
                OrientedBox = new ObstacleOrientedBox
                {
                    Center      = center,
                    HalfExtents = halfExtents,
                    RotAux      = rotAux,
                }
            };

            var req = new ObstacleRequest
            {
                Action = ObstacleRequestAction.REQUEST_ADD,
                NRef   = GetObstacleRef(m_obstacles[ob])
            };

            m_reqs[m_nreqs++] = req;

            result = req.NRef;

            return(Status.DT_SUCCESS);
        }
Esempio n. 4
0
        public void Init(TileCacheParams tcparams, TileCacheMeshProcess tmproc)
        {
            m_params = tcparams;
            m_tmproc = tmproc;

            // Alloc space for obstacles.
            m_obstacles        = new TileCacheObstacle[tcparams.MaxObstacles];
            m_nextFreeObstacle = -1;
            for (int i = tcparams.MaxObstacles - 1; i >= 0; i--)
            {
                m_obstacles[i] = new TileCacheObstacle
                {
                    Salt = 1,
                    Next = m_nextFreeObstacle
                };
                m_nextFreeObstacle = i;
            }

            // Init tiles
            var m_tileLutSize = Helper.NextPowerOfTwo(tcparams.MaxTiles / 4);

            if (m_tileLutSize == 0)
            {
                m_tileLutSize = 1;
            }
            m_tileLutMask = m_tileLutSize - 1;

            m_tiles     = new CompressedTile[tcparams.MaxTiles];
            m_posLookup = new CompressedTile[m_tileLutSize];

            for (int i = tcparams.MaxTiles - 1; i >= 0; i--)
            {
                m_tiles[i] = new CompressedTile
                {
                    Salt = 1,
                    Next = m_nextFreeTile
                };
                m_nextFreeTile = m_tiles[i];
            }

            // Init ID generator values.
            m_tileBits = (int)Math.Log(Helper.NextPowerOfTwo(tcparams.MaxTiles), 2);

            // Only allow 31 salt bits, since the salt mask is calculated using 32bit uint and it will overflow.
            m_saltBits = Math.Min(31, 32 - m_tileBits);
            if (m_saltBits < 10)
            {
                throw new EngineException("NavMesh DT_INVALID_PARAM");
            }
        }
Esempio n. 5
0
        public Status AddObstacle(Vector3 pos, float radius, float height, out int result)
        {
            result = 0;

            if (m_nreqs >= DetourTileCache.MAX_REQUESTS)
            {
                return(Status.DT_FAILURE | Status.DT_BUFFER_TOO_SMALL);
            }

            int ob = -1;

            if (m_nextFreeObstacle >= 0)
            {
                ob = m_nextFreeObstacle;
                m_nextFreeObstacle   = m_obstacles[ob].Next;
                m_obstacles[ob].Next = -1;
            }
            if (ob == -1)
            {
                return(Status.DT_FAILURE);
            }

            int salt = m_obstacles[ob].Salt;

            m_obstacles[ob] = new TileCacheObstacle
            {
                Salt     = salt,
                State    = ObstacleState.DT_OBSTACLE_PROCESSING,
                Type     = ObstacleType.DT_OBSTACLE_CYLINDER,
                Cylinder = new ObstacleCylinder
                {
                    Pos    = pos,
                    Radius = radius,
                    Height = height
                }
            };

            var req = new ObstacleRequest
            {
                Action = ObstacleRequestAction.REQUEST_ADD,
                NRef   = GetObstacleRef(m_obstacles[ob]),
            };

            m_reqs[m_nreqs++] = req;

            result = req.NRef;

            return(Status.DT_SUCCESS);
        }
Esempio n. 6
0
        public Status AddBoxObstacle(Vector3 bmin, Vector3 bmax, out int result)
        {
            result = 0;

            if (m_nreqs >= DetourTileCache.MAX_REQUESTS)
            {
                return(Status.DT_FAILURE | Status.DT_BUFFER_TOO_SMALL);
            }

            int ob = -1;

            if (m_nextFreeObstacle >= 0)
            {
                ob = m_nextFreeObstacle;
                m_nextFreeObstacle   = m_obstacles[ob].Next;
                m_obstacles[ob].Next = -1;
            }
            if (ob == -1)
            {
                return(Status.DT_FAILURE);
            }

            int salt = m_obstacles[ob].Salt;

            m_obstacles[ob] = new TileCacheObstacle
            {
                Salt  = salt,
                State = ObstacleState.DT_OBSTACLE_PROCESSING,
                Type  = ObstacleType.DT_OBSTACLE_BOX,
                Box   = new ObstacleBox
                {
                    BMin = bmin,
                    BMax = bmax
                }
            };

            var req = new ObstacleRequest
            {
                Action = ObstacleRequestAction.REQUEST_ADD,
                NRef   = GetObstacleRef(m_obstacles[ob])
            };

            m_reqs[m_nreqs++] = req;

            result = req.NRef;

            return(Status.DT_SUCCESS);
        }