예제 #1
0
파일: MoveTo.cs 프로젝트: rol2728/Dev.D3
        public static async Task <bool> MoveToPosWithNavMeshAsync(SharpDX.Vector3 vecDest, int NearDistance = 50)
        {
            if (Nav.D3.Navmesh.Current == null)
            {
                Nav.D3.Navmesh.Create(Enigma.D3.Engine.Current, new Nav.ExploreEngine.Nearest());
            }

            var localAcd = ActorCommonDataHelper.GetLocalAcd();
            var distance = vecDest.Distance(); // (Math.Pow(localAcd.x0D0_WorldPosX - vecDest.X, 2) + Math.Pow(localAcd.x0D4_WorldPosY - vecDest.Y, 2));

            var minDistanceReached = distance;
            var dtDistanceReached  = DateTime.Now;

            DateTime dtTimeout = DateTime.Now;

            while (distance > NearDistance)
            {
                if (DateTime.Now > dtTimeout.AddSeconds(30) || DateTime.Now > dtDistanceReached.AddSeconds(10))
                {
                    return(false);
                }

                SharpDX.Vector2 curVector  = localAcd.ToSharpDXVector2(); // new SharpDX.Vector2(localAcd.x0D0_WorldPosX, localAcd.x0D4_WorldPosY);
                SharpDX.Vector2 destVector = new SharpDX.Vector2(vecDest.X, vecDest.Y);

                // Update current player position.
                Nav.D3.Navmesh.Current.Navigator.CurrentPos = localAcd.ToNavVec3(); // new Nav.Vec3(localAcd.x0D0_WorldPosX, localAcd.x0D4_WorldPosY, localAcd.x0D8_WorldPosZ);

                // Update destination. You can keep setting the same value there is internal check if destination has actually changed.
                // This destination overrides any internal destinations (including exploration). When You just want to explore You do
                // not need to set any destination. It will be set automatically.
                Nav.D3.Navmesh.Current.Navigator.Destination = new Nav.Vec3(vecDest.X, vecDest.Y, vecDest.Z);

                // Get current destination.
                Nav.Vec3 goToPosition = Nav.D3.Navmesh.Current.Navigator.GoToPosition;
                while (goToPosition.IsEmpty)
                {
                    await Task.Delay(10);
                }

                SharpDX.Vector3 goToPositionVector = new SharpDX.Vector3(goToPosition.X, goToPosition.Y, goToPosition.Z);
                await MoveToPosAsync(goToPositionVector);
            }

            return(true);
        }
예제 #2
0
파일: AABB.cs 프로젝트: rol2728/Dev.D3
 public void Deserialize(BinaryReader r)
 {
     min      = new Vec3(r);
     max      = new Vec3(r);
     is_empty = r.ReadBoolean();
 }
예제 #3
0
파일: AABB.cs 프로젝트: rol2728/Dev.D3
 public void Translate(Vec3 v)
 {
     min += v;
     max += v;
 }
예제 #4
0
파일: AABB.cs 프로젝트: rol2728/Dev.D3
 public AABB(AABB aabb)
 {
     min = new Vec3(aabb.min);
     max = new Vec3(aabb.max);
 }
예제 #5
0
파일: AABB.cs 프로젝트: rol2728/Dev.D3
 public Vec3 Align(Vec3 p)
 {
     return(Vec3.Min(Vec3.Max(Min, p), Max));
 }
예제 #6
0
 public void Translate(Vec3 v)
 {
     Min += v;
     Max += v;
 }
예제 #7
0
 public GridCell(Vec3 min, Vec3 max, int id = -1, int area_id = -1)
     : base(min, max, MovementFlag.None, id)
 {
     InitGridCell(area_id);
 }
예제 #8
0
 public path_pos(Vec3 p, Cell c)
 {
     pos  = p;
     cell = c;
 }
예제 #9
0
파일: AABB.cs 프로젝트: rol2728/Dev.D3
 public bool Contains2D(Vec3 p)
 {
     return(p.X >= min.X && p.X <= max.X && p.Y >= min.Y && p.Y <= max.Y);
 }
예제 #10
0
파일: AABB.cs 프로젝트: rol2728/Dev.D3
 public bool Contains(Vec3 p, float z_tolerance = 0)
 {
     return(p.X >= min.X && p.X <= max.X && p.Y >= min.Y && p.Y <= max.Y && (p.Z + z_tolerance) >= min.Z && (p.Z - z_tolerance) <= max.Z);
 }
예제 #11
0
        private bool InternalRayTest(Vec3 ray_origin, Vec3 ray_dir, ref Vec3 result, int num_dim)
        {
            // implementation based upon https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-box-intersection
            // + added custom support for rays tangent to sides of AABB
            Vec3 ray_dir_inv = 1 / ray_dir;

            int[] sign = new int[] { ray_dir_inv.X < 0 ? 1 : 0, ray_dir_inv.Y < 0 ? 1 : 0, ray_dir_inv.Z < 0 ? 1 : 0 };

            float tmin, tmax, tymin, tymax, tzmin, tzmax;

            tmin  = (Bounds(sign[0]).X - ray_origin.X) * ray_dir_inv.X;
            tmax  = (Bounds(1 - sign[0]).X - ray_origin.X) * ray_dir_inv.X;
            tymin = (Bounds(sign[1]).Y - ray_origin.Y) * ray_dir_inv.Y;
            tymax = (Bounds(1 - sign[1]).Y - ray_origin.Y) * ray_dir_inv.Y;

            if ((tmin > tymax) || (tymin > tmax))
            {
                return(false);
            }

            bool tangent_x = float.IsNaN(tmin) || float.IsNaN(tmax);
            bool tangent_y = float.IsNaN(tymin) || float.IsNaN(tymax);

            if (tymin > tmin || tangent_x)
            {
                tmin = tymin;
            }
            if (tymax < tmax && !tangent_y)
            {
                tmax = tymax;
            }

            bool tangent_z = false;

            if (num_dim > 2)
            {
                tzmin = (Bounds(sign[2]).Z - ray_origin.Z) * ray_dir_inv.Z;
                tzmax = (Bounds(1 - sign[2]).Z - ray_origin.Z) * ray_dir_inv.Z;

                tangent_z = float.IsNaN(tzmin) || float.IsNaN(tzmax);

                if ((tmin > tzmax) || (tzmin > tmax))
                {
                    return(false);
                }

                if (tzmin > tmin || float.IsNaN(tmin))
                {
                    tmin = tzmin;
                }
                if (tzmax < tmax && !float.IsNaN(tmax))
                {
                    tmax = tzmax;
                }
            }

            if (tmax >= 0)
            {
                if (tmin < 0 && (tangent_x || tangent_y || tangent_z))
                {
                    result = ray_origin;
                }
                else
                {
                    result = ray_origin + ray_dir * (tmin < 0 ? tmax : tmin);
                }
                return(true);
            }

            return(false);
        }
예제 #12
0
 public bool RayTest(Vec3 ray_origin, Vec3 ray_dir, ref Vec3 result)
 {
     return(InternalRayTest(ray_origin, ray_dir, ref result, 3));
 }
예제 #13
0
 public void Deserialize(BinaryReader r)
 {
     Min = new Vec3(r);
     Max = new Vec3(r);
 }
예제 #14
0
 public AABB(AABB aabb)
 {
     Min = new Vec3(aabb.Min);
     Max = new Vec3(aabb.Max);
 }
예제 #15
0
파일: AABB.cs 프로젝트: rol2728/Dev.D3
 public bool RayTest2D(Vec3 ray_origin, Vec3 ray_dir, out Vec3 result)
 {
     return(InternalRayTest(ray_origin, ray_dir, out result, 2));
 }
예제 #16
0
파일: AABB.cs 프로젝트: rol2728/Dev.D3
        private bool InternalRayTest(Vec3 ray_origin, Vec3 ray_dir, out Vec3 result, int num_dim)
        {
            // implementation is brutal port from http://tog.acm.org/resources/GraphicsGems/gems/RayBox.c
            result = Vec3.Empty;

            const int RIGHT  = 0;
            const int LEFT   = 1;
            const int MIDDLE = 2;

            bool inside = true;

            float[] origin = new float[3] {
                ray_origin.X, ray_origin.Y, ray_origin.Z
            };
            float[] minB = new float[3] {
                min.X, min.Y, min.Z
            };
            float[] maxB = new float[3] {
                max.X, max.Y, max.Z
            };
            float[] dir = new float[3] {
                ray_dir.X, ray_dir.Y, ray_dir.Z
            };
            float[] coord = new float[3] {
                0, 0, 0
            };

            int[] quadrant = new int[3] {
                0, 0, 0
            };
            float[] candidatePlane = new float[3];

            /* Find candidate planes; this loop can be avoided if
             * rays cast all from the eye(assume perpsective view) */
            for (int i = 0; i < num_dim; ++i)
            {
                if (origin[i] < minB[i])
                {
                    quadrant[i]       = LEFT;
                    candidatePlane[i] = minB[i];
                    inside            = false;
                }
                else if (origin[i] > maxB[i])
                {
                    quadrant[i]       = RIGHT;
                    candidatePlane[i] = maxB[i];
                    inside            = false;
                }
                else
                {
                    quadrant[i] = MIDDLE;
                }
            }

            /* Ray origin inside bounding box */
            if (inside)
            {
                result = new Vec3(ray_origin);
                return(true);
            }

            float[] maxT = new float[3];

            /* Calculate T distances to candidate planes */
            for (int i = 0; i < num_dim; ++i)
            {
                if (quadrant[i] != MIDDLE && dir[i] != 0)
                {
                    maxT[i] = (candidatePlane[i] - origin[i]) / dir[i];
                }
                else
                {
                    maxT[i] = -1;
                }
            }

            /* Get largest of the maxT's for final choice of intersection */
            int whichPlane = 0;

            for (int i = 1; i < num_dim; ++i)
            {
                if (maxT[whichPlane] < maxT[i])
                {
                    whichPlane = i;
                }
            }

            /* Check final candidate actually inside box */
            if (maxT[whichPlane] < 0)
            {
                return(false);
            }

            for (int i = 0; i < num_dim; ++i)
            {
                if (whichPlane != i)
                {
                    coord[i] = origin[i] + maxT[whichPlane] * dir[i];

                    if (coord[i] < minB[i] || coord[i] > maxB[i])
                    {
                        return(false);
                    }
                }
                else
                {
                    coord[i] = candidatePlane[i];
                }
            }

            result = new Vec3(coord[0], coord[1], num_dim == 3 ? coord[2] : 0);

            return(true);                               /* ray hits box */
        }
예제 #17
0
파일: AABB.cs 프로젝트: rol2728/Dev.D3
 public AABB(float min_x, float min_y, float min_z, float max_x, float max_y, float max_z)
 {
     min = new Vec3(min_x, min_y, min_z);
     max = new Vec3(max_x, max_y, max_z);
 }
예제 #18
0
        public static bool FindPath <T>(T start, ref T end, Vec3 from, Vec3 to, MovementFlag flags, ref List <path_pos> path, float random_coeff = 0, bool allow_disconnected = false) where T : Cell
        {
            if (path != null)
            {
                path.Clear();
            }

            //based on http://en.wikipedia.org/wiki/A*_search_algorithm

            List <NodeInfo> open   = new List <NodeInfo>();
            List <NodeInfo> closed = new List <NodeInfo>();

            Random rng = new Random();

            if (start == null || end == null)
            {
                return(false);
            }

            NodeInfo s = new NodeInfo(start, from, null, 0, from.Distance(to));

            open.Add(s);

            while (open.Count > 0)
            {
                //sort by cost
                float    min_total_cost = open.Min(x => x.TotalCost);
                NodeInfo best           = open.Find(x => x.TotalCost.Equals(min_total_cost));

                open.Remove(best);

                //take node with lower cost from open list
                NodeInfo info = best;

                if (info.cell == end)
                {
                    BuildPath(start, end, from, to, info, ref path);
                    return(true);
                }

                closed.Insert(0, info);

                foreach (Cell.Neighbour neighbour in info.cell.Neighbours)
                {
                    Cell cell_neighbour = neighbour.cell;

                    if (cell_neighbour.Disabled || (neighbour.connection_flags & flags) != flags)
                    {
                        continue;
                    }

                    Vec3 leading_point = neighbour.border_point != null ? neighbour.border_point : cell_neighbour.Center;

                    NodeInfo info_neighbour = GetNodeInfoFromList(cell_neighbour, leading_point, closed);

                    // if already processed then skip this neighbour
                    if (info_neighbour != null)
                    {
                        continue;
                    }

                    float random_dist_mod = -random_coeff + (2 * random_coeff) * (float)rng.NextDouble();

                    float new_g     = info.g + (info.leading_point.IsEmpty ? info.cell.Distance(leading_point) : info.leading_point.Distance(leading_point)) * (1 + random_dist_mod) * info.cell.MovementCostMult;
                    bool  is_better = false;

                    info_neighbour = GetNodeInfoFromList(cell_neighbour, leading_point, open);

                    // if not in open list
                    if (info_neighbour == null)
                    {
                        info_neighbour = new NodeInfo(cell_neighbour, leading_point, null, 0, leading_point.Distance(to) * (1 + random_dist_mod) * info.cell.MovementCostMult);
                        is_better      = true;

                        open.Insert(0, info_neighbour);
                    }
                    else if (new_g < info_neighbour.g)
                    {
                        is_better = true;
                    }

                    if (is_better)
                    {
                        info_neighbour.parent = info;
                        info_neighbour.g      = new_g;
                    }
                }
            }

            if (allow_disconnected && closed.Count > 0)
            {
                float    min_total_cost = closed.Min(x => x.h);
                NodeInfo best           = closed.Find(x => x.h.Equals(min_total_cost));
                end = (T)best.cell;

                BuildPath(start, end, from, to, best, ref path);
                return(true);
            }

            return(false);
        }
예제 #19
0
파일: AABB.cs 프로젝트: rol2728/Dev.D3
 public AABB(Vec3 min, Vec3 max)
 {
     this.min = new Vec3(min);
     this.max = new Vec3(max);
 }
예제 #20
0
파일: AABB.cs 프로젝트: rol2728/Dev.D3
 public static AABB Mininum(AABB aabb1, AABB aabb2)
 {
     return(new AABB(Vec3.Max(aabb1.min, aabb2.min), Vec3.Min(aabb1.max, aabb2.max)));
 }
예제 #21
0
 public AABB(Vec3 min, Vec3 max)
 {
     Min = new Vec3(min);
     Max = new Vec3(max);
 }