Ejemplo n.º 1
0
 private static float[] PositionToArray(TundraVector3 vec)
 {
     float[] arr = new float[3];
     arr[0] = vec.X;
     arr[1] = vec.Y + YOffset;
     arr[2] = vec.Z;
     return(arr);
 }
Ejemplo n.º 2
0
 public void Deserialize(DeserializeEvent e)
 {
     ID       = e.Reader.ReadUInt32();
     TargetID = e.Reader.ReadUInt32();
     Name     = e.Reader.ReadString(Encoding.Unicode);
     State    = (EntityState)e.Reader.ReadByte();
     Position = e.Reader.ReadSerializable <TundraVector3>();
     Health   = e.Reader.ReadInt32();
 }
Ejemplo n.º 3
0
        private void HandleNavigateTo(Message message)
        {
            var data = message.Deserialize <NavigateToPacket>();

            if (data != null)
            {
                navComponent.SetDestination(TundraVector3.Create(data.Destination.X, data.Destination.Y, data.Destination.Z));
            }
        }
Ejemplo n.º 4
0
 public void LoadLevel(string levelName)
 {
     NavMeshQuery = NavMeshSerializer.CreateMeshQuery(NavMeshSerializer.Deserialize("Levels/" + levelName + ".nav"));
     //The YOffset requires the world to have a valid NavMesh-Position at (0,0,0)
     Pathfinder.YOffset = Pathfinder.GetClosestPointOnNavMesh(NavMeshQuery, TundraVector3.Create(0f, 0f, 0f)).Y;
     AddEntity(new Monster {
         Name = "Monster", Position = TundraVector3.Zero
     });
 }
Ejemplo n.º 5
0
 public void SetDestination(TundraVector3 destination)
 {
     CurrentPath = Pathfinder.ComputeSmoothPath(NavMeshQuery, Position, destination);
     if (CurrentPath.Points.Count > 0)
     {
         _currentPathIndex   = 0;
         _currentDestination = CurrentPath.Points[0];
         Destination         = CurrentPath.Points[CurrentPath.PointsCount - 1];
     }
     else
     {
         CurrentPath = null;
     }
 }
Ejemplo n.º 6
0
        public static TundraVector3 GetClosestPointOnNavMesh(NavMeshQuery navQuery, TundraVector3 pos)
        {
            float[] extents = new float[3];
            for (int i = 0; i < 3; ++i)
            {
                extents[i] = 10.0f;
            }

            Detour.dtQueryFilter filter   = new Detour.dtQueryFilter();
            dtPolyRef            startRef = 0;

            float[] res = new float[3];

            navQuery.findNearestPoly(PositionToArray(pos), extents, filter, ref startRef, ref res);
            return(ArrayToPosition(res));
        }
Ejemplo n.º 7
0
        public void Integrate(float deltaTime)
        {
            var maxDistance = Speed * deltaTime;

            if (TundraVector3.Distance(Position, _currentDestination) <= StoppingDistance)
            {
                if (_currentPathIndex < CurrentPath.PointsCount - 1)
                {
                    _currentDestination = CurrentPath.Points[++_currentPathIndex];
                    Position            = TundraVector3.MoveTowards(Position, _currentDestination, maxDistance);
                }
                else
                {
                    CurrentPath = null;
                }
            }
            else
            {
                Position = TundraVector3.MoveTowards(Position, _currentDestination, maxDistance);
            }
        }
Ejemplo n.º 8
0
        public static SmoothPath ComputeSmoothPath(NavMeshQuery navQuery, TundraVector3 start, TundraVector3 end)
        {
            var        startWorldPos = PositionToArray(start);
            var        endWorldPos   = PositionToArray(end);
            SmoothPath smoothPath    = new SmoothPath();

            if (navQuery == null)
            {
                return(smoothPath);
            }

            float[] extents = new float[3];
            for (int i = 0; i < 3; ++i)
            {
                extents[i] = 10.0f;
            }

            uint startRef = 0;
            uint endRef   = 0;

            float[] startPt = new float[3];
            float[] endPt   = new float[3];

            Detour.dtQueryFilter filter = new Detour.dtQueryFilter();

            navQuery.findNearestPoly(startWorldPos, extents, filter, ref startRef, ref startPt);
            navQuery.findNearestPoly(endWorldPos, extents, filter, ref endRef, ref endPt);

            const int maxPath = SmoothPath.MAX_POLYS;

            uint[] path = new uint[maxPath];

            int pathCount = -1;

            navQuery.findPath(startRef, endRef, startPt, endPt, filter, path, ref pathCount, maxPath);

            smoothPath.PointsCount = 0;

            if (pathCount > 0)
            {
                // Iterate over the path to find smooth path on the detail mesh surface.
                uint[] polys = new uint[SmoothPath.MAX_POLYS];
                for (int i = 0; i < pathCount; ++i)
                {
                    polys[i] = path[i];
                }
                int npolys = pathCount;

                float[] iterPos           = new float[3];
                float[] targetPos         = new float[3];
                bool    posOverPoly_dummy = false;
                navQuery.closestPointOnPoly(startRef, startPt, iterPos, ref posOverPoly_dummy);
                navQuery.closestPointOnPoly(polys[npolys - 1], endPt, targetPos, ref posOverPoly_dummy);

                const float STEP_SIZE = 0.5f;
                const float SLOP      = 0.01f;

                smoothPath.PointsCount = 0;

                smoothPath.Points.Add(ArrayToPosition(iterPos));
                //Detour.dtVcopy(smoothPath.Points, smoothPath.PointsCount * 3, iterPos, 0);
                smoothPath.PointsCount++;

                // Move towards target a small advancement at a time until target reached or
                // when ran out of memory to store the path.
                while (npolys != 0 && smoothPath.PointsCount < SmoothPath.MAX_SMOOTH)
                {
                    // Find location to steer towards.
                    float[] steerPos     = new float[3];
                    byte    steerPosFlag = 0;
                    uint    steerPosRef  = 0;

                    if (!getSteerTarget(navQuery, iterPos, targetPos, SLOP,
                                        polys, npolys, steerPos, ref steerPosFlag, ref steerPosRef))
                    {
                        break;
                    }

                    bool endOfPath         = (steerPosFlag & (byte)Detour.dtStraightPathFlags.DT_STRAIGHTPATH_END) != 0 ? true : false;
                    bool offMeshConnection = (steerPosFlag & (byte)Detour.dtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION) != 0 ? true : false;

                    // Find movement delta.
                    float[] delta = new float[3];//, len;
                    float   len   = .0f;
                    Detour.dtVsub(delta, steerPos, iterPos);
                    len = MathF.Sqrt(Detour.dtVdot(delta, delta));
                    // If the steer target is end of path or off-mesh link, do not move past the location.
                    if ((endOfPath || offMeshConnection) && len < STEP_SIZE)
                    {
                        len = 1;
                    }
                    else
                    {
                        len = STEP_SIZE / len;
                    }
                    float[] moveTgt = new float[3];
                    Detour.dtVmad(moveTgt, iterPos, delta, len);

                    // Move
                    float[] result   = new float[3];
                    uint[]  visited  = new uint[16];
                    int     nvisited = 0;
                    navQuery.moveAlongSurface(polys[0], iterPos, moveTgt, filter,
                                              result, visited, ref nvisited, 16);

                    npolys = fixupCorridor(polys, npolys, SmoothPath.MAX_POLYS, visited, nvisited);
                    npolys = fixupShortcuts(polys, npolys, navQuery);

                    float h = 0;
                    var   getHeightStatus = navQuery.getPolyHeight(polys[0], result, ref h);
                    result[1] = h;

                    if ((getHeightStatus & Detour.DT_FAILURE) != 0)
                    {
                        Debug.WriteLine("Failed to getPolyHeight " + polys[0] + " pos " + result[0] + " " + result[1] + " " + result[2] + " h " + h);
                    }

                    Detour.dtVcopy(iterPos, result);

                    // Handle end of path and off-mesh links when close enough.
                    if (endOfPath && inRange(iterPos, 0, steerPos, 0, SLOP, 1.0f))
                    {
                        // Reached end of path.
                        Detour.dtVcopy(iterPos, targetPos);
                        if (smoothPath.PointsCount < SmoothPath.MAX_SMOOTH)
                        {
                            smoothPath.Points.Add(ArrayToPosition(iterPos));
                            //Detour.dtVcopy(smoothPath.Points, smoothPath.PointsCount * 3, iterPos, 0);
                            smoothPath.PointsCount++;
                        }
                        break;
                    }
                    else if (offMeshConnection && inRange(iterPos, 0, steerPos, 0, SLOP, 1.0f))
                    {
                        // Reached off-mesh connection.
                        float[] startPos = new float[3];//, endPos[3];
                        float[] endPos   = new float[3];

                        // Advance the path up to and over the off-mesh connection.
                        uint prevRef = 0, polyRef = polys[0];
                        int  npos = 0;
                        while (npos < npolys && polyRef != steerPosRef)
                        {
                            prevRef = polyRef;
                            polyRef = polys[npos];
                            npos++;
                        }
                        for (int i = npos; i < npolys; ++i)
                        {
                            polys[i - npos] = polys[i];
                        }

                        npolys -= npos;

                        // Handle the connection.

                        var status = navQuery.getAttachedNavMesh().getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos);
                        if (Detour.dtStatusSucceed(status))
                        {
                            if (smoothPath.PointsCount < SmoothPath.MAX_SMOOTH)
                            {
                                smoothPath.Points.Add(ArrayToPosition(startPos));
                                //Detour.dtVcopy(smoothPath.Points, smoothPath.PointsCount * 3, startPos, 0);
                                smoothPath.PointsCount++;
                                // Hack to make the dotted path not visible during off-mesh connection.
                                if ((smoothPath.PointsCount & 1) != 0)
                                {
                                    smoothPath.Points.Add(ArrayToPosition(startPos));
                                    //Detour.dtVcopy(smoothPath.Points, smoothPath.PointsCount * 3, startPos, 0);
                                    smoothPath.PointsCount++;
                                }
                            }
                            // Move position at the other side of the off-mesh link.
                            Detour.dtVcopy(iterPos, endPos);
                            float eh = 0.0f;
                            navQuery.getPolyHeight(polys[0], iterPos, ref eh);
                            iterPos[1] = eh;
                        }
                    }

                    // Store results.
                    if (smoothPath.PointsCount < SmoothPath.MAX_SMOOTH)
                    {
                        smoothPath.Points.Add(ArrayToPosition(iterPos));
                        //Detour.dtVcopy(smoothPath.Points, smoothPath.PointsCount * 3, iterPos, 0);
                        smoothPath.PointsCount++;
                    }
                }
            }
            return(smoothPath);
        }
Ejemplo n.º 9
0
 private static TundraVector3 ArrayToPosition(float[] pos, int start = 0)
 {
     return(TundraVector3.Create(pos[start], pos[start + 1] - YOffset, pos[start + 2]));
 }
Ejemplo n.º 10
0
 public void Deserialize(DeserializeEvent e)
 {
     Destination = e.Reader.ReadSerializable <TundraVector3>();
 }