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; } }
public int GetObstacleRef(TileCacheObstacle ob) { if (ob == null) { return(0); } int idx = Array.IndexOf(m_obstacles, ob); return(EncodeObstacleId(ob.Salt, idx)); }
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); }
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"); } }
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); }
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); }