Esempio n. 1
0
 public TriangleOctree GetOctree()
 {
     if (oct == null)
     {
         oct = new TriangleOctree(this);
     }
     return(oct);
 }
        public bool IsInWater(float x, float y, float min_z, float max_z)
        {
            TriangleCollection tc = GetChunkAt(x, y);
            ICollection <int>  ts, tsm, tst;
            float minCliffD = 0.5f;

            ts = null;
            if (UseOctree)
            {
                TriangleOctree ot = tc.GetOctree();
                tst = ts = ot.FindTrianglesInBox(x - minCliffD, y - minCliffD, min_z, x + minCliffD, y + minCliffD, max_z);
            }

            if (UseMatrix)
            {
                TriangleMatrix tm = tc.GetTriangleMatrix();
                tsm = ts = tm.GetAllCloseTo(x, y, 1.0f);
            }

            Vector s0, s1;

            s0.x = x;
            s0.y = y;
            s0.z = min_z;
            s1.x = x;
            s1.y = y;
            s1.z = max_z;

            foreach (int t in ts)
            {
                Vector vertex0;
                Vector vertex1;
                Vector vertex2;
                Vector intersect;
                int    t_flags, sequence;

                tc.GetTriangleVertices(t,
                                       out vertex0.x, out vertex0.y, out vertex0.z,
                                       out vertex1.x, out vertex1.y, out vertex1.z,
                                       out vertex2.x, out vertex2.y, out vertex2.z, out t_flags, out sequence);

                Vector normal;
                Utils.GetTriangleNormal(vertex0, vertex1, vertex2, out normal);

                if (Utils.SegmentTriangleIntersect(s0, s1, vertex0, vertex1, vertex2, out intersect))
                {
                    if ((t_flags & TriangleFlagDeepWater) != 0)
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Esempio n. 3
0
            public Node(TriangleOctree tree,
                        Vector min,
                        Vector max)
            {
                this.tree  = tree;
                this.min   = min;
                this.max   = max;
                this.mid.x = (min.x + max.x) / 2;
                this.mid.y = (min.y + max.y) / 2;
                this.mid.z = (min.z + max.z) / 2;

                //triangles = new SimpleLinkedList();  // assume being a leaf node
            }
Esempio n. 4
0
        public bool IsSpotBlocked(float x, float y, float z,
                                  float toonHeight, float toonSize)
        {
            TriangleCollection tc = GetChunkAt(x, y);

            ICollection <int> ts, tst, tsm;

            ts = null;
            if (UseOctree)
            {
                TriangleOctree ot = tc.GetOctree();
                tst = ts = ot.FindTrianglesInBox(x - toonSize, y - toonSize, z + toonHeight - toonSize,
                                                 x + toonSize, y + toonSize, z + toonHeight + toonSize);
            }

            if (UseMatrix)
            {
                TriangleMatrix tm = tc.GetTriangleMatrix();
                tsm = ts = tm.GetAllCloseTo(x, y, toonSize);
            }

            Vector toon;

            toon.x = x;
            toon.y = y;
            toon.z = z + toonHeight;

            //            for(int t = 0 ; t<tc.GetNumberOfTriangles(); t++)
            //            {

            foreach (int t in ts)
            {
                Vector vertex0;
                Vector vertex1;
                Vector vertex2;
                int    flags;
                tc.GetTriangleVertices(t,
                                       out vertex0.x, out vertex0.y, out vertex0.z,
                                       out vertex1.x, out vertex1.y, out vertex1.z,
                                       out vertex2.x, out vertex2.y, out vertex2.z, out flags);
                float d = Utils.PointDistanceToTriangle(toon, vertex0, vertex1, vertex2);
                if (d < toonSize)
                {
                    return(true);
                }
            }

            return(false);
        }
        public bool FindStandableAt1(float x, float y, float min_z, float max_z,
                                     out float z0, out int flags, float toonHeight, float toonSize, bool IgnoreGradient, int[] allowedFlags)
        {
            TriangleCollection tc = GetChunkAt(x, y);
            ICollection <int>  ts, tsm, tst;
            float minCliffD = 0.5f;

            ts = null;
            if (UseOctree)
            {
                TriangleOctree ot = tc.GetOctree();
                tst = ts = ot.FindTrianglesInBox(x - minCliffD, y - minCliffD, min_z, x + minCliffD, y + minCliffD, max_z);
            }

            if (UseMatrix)
            {
                TriangleMatrix tm = tc.GetTriangleMatrix();
                tsm = ts = tm.GetAllCloseTo(x, y, 1.0f);
            }

            Vector s0, s1;

            s0.x = x;
            s0.y = y;
            s0.z = min_z;
            s1.x = x;
            s1.y = y;
            s1.z = max_z;

            float best_z     = -1E30f;
            int   best_flags = 0;
            bool  found      = false;

            foreach (int t in ts)
            {
                Vector vertex0;
                Vector vertex1;
                Vector vertex2;
                Vector intersect;
                int    t_flags, sequence;

                tc.GetTriangleVertices(t,
                                       out vertex0.x, out vertex0.y, out vertex0.z,
                                       out vertex1.x, out vertex1.y, out vertex1.z,
                                       out vertex2.x, out vertex2.y, out vertex2.z, out t_flags, out sequence);

                if (allowedFlags == null || allowedFlags.Contains(t_flags))
                {
                    Vector normal;
                    Utils.GetTriangleNormal(vertex0, vertex1, vertex2, out normal);
                    float angle_z = (float)Math.Sin(45.0 / 360.0 * Math.PI * 2); //
                    if (Utils.abs(normal.z) > angle_z)
                    {
                        if (Utils.SegmentTriangleIntersect(s0, s1, vertex0, vertex1, vertex2, out intersect))
                        {
                            if (intersect.z > best_z)
                            {
                                if (!IsSpotBlocked(intersect.x, intersect.y, intersect.z, toonHeight, toonSize))
                                {
                                    best_z     = intersect.z;
                                    best_flags = t_flags;
                                    found      = true;
                                }
                            }
                        }
                    }
                }
            }
            if (found)
            {
                Vector up, dn, tmp;
                up.z = best_z + 2;
                dn.z = best_z - 5;
                bool[] nearCliff = { true, true, true, true };

                bool allGood = true;
                foreach (int t in ts)
                {
                    Vector vertex0;
                    Vector vertex1;
                    Vector vertex2;

                    tc.GetTriangleVertices(t,
                                           out vertex0.x, out vertex0.y, out vertex0.z,
                                           out vertex1.x, out vertex1.y, out vertex1.z,
                                           out vertex2.x, out vertex2.y, out vertex2.z);

                    float[] dx = { minCliffD, -minCliffD, 0, 0 };
                    float[] dy = { 0, 0, minCliffD, -minCliffD };
                    // Check if it is close to a "cliff"

                    allGood = true;
                    for (int i = 0; i < 4; i++)
                    {
                        if (nearCliff[i])
                        {
                            up.x = dn.x = x + dx[i];
                            up.y = dn.y = y + dy[i];
                            if (Utils.SegmentTriangleIntersect(up, dn, vertex0, vertex1, vertex2, out tmp))
                            {
                                nearCliff[i] = false;
                            }
                        }
                        allGood &= !nearCliff[i];
                    }
                    if (allGood)
                    {
                        break;
                    }
                }

                allGood = true;
                for (int i = 0; i < 4; i++)
                {
                    allGood &= !nearCliff[i];
                }
                if (!allGood)
                {
                    z0    = best_z;
                    flags = best_flags;
                    return(false); // too close to cliff
                }
            }
            z0    = best_z;
            flags = best_flags;
            return(found);
        }
        public bool FindStandableAt2(double xx, double yy, float min_z, float max_z,
                                     out float z0, out int flags, float toonHeight, float toonSize, bool IgnoreGradient)
        {
            float x = (float)xx;
            float y = (float)yy;

            TriangleCollection tc = GetChunkAt(x, y);
            ICollection <int>  ts, tsm, tst;
            float minCliffD = 0.5f;

            ts = null;
            if (UseOctree)
            {
                TriangleOctree ot = tc.GetOctree();
                tst = ts = ot.FindTrianglesInBox(x - minCliffD, y - minCliffD, min_z, x + minCliffD, y + minCliffD, max_z);
            }

            if (UseMatrix)
            {
                TriangleMatrix tm = tc.GetTriangleMatrix();
                tsm = ts = tm.GetAllCloseTo(x, y, 2.0f);
            }

            Vector s0, s1, s2, s3, s4, s5, s6, s7, s8, s9;

            s0.x = x; s0.y = y; s0.z = min_z;
            s1.x = x; s1.y = y; s1.z = max_z;

            float gap = (float)0.2;

            s2.x = x + gap; s2.y = y; s2.z = min_z;
            s3.x = x + gap; s3.y = y; s3.z = max_z;

            s4.x = x - gap; s4.y = y; s4.z = min_z;
            s5.x = x - gap; s5.y = y; s5.z = max_z;

            s6.x = x; s6.y = y + gap; s6.z = min_z;
            s7.x = x; s7.y = y + gap; s7.z = max_z;

            s8.x = x; s8.y = y - gap; s8.z = min_z;
            s9.x = x; s9.y = y - gap; s9.z = max_z;

            float best_z     = -1E30f;
            int   best_flags = 0;
            bool  found      = false;

            //logger.WriteLine(string.Format("x: {0} y: {1} min_z: {2} max_z: {3}", x, y, min_z, max_z));
            foreach (int t in ts)
            {
                Vector vertex0;
                Vector vertex1;
                Vector vertex2;
                Vector intersect;
                int    t_flags, sequence;

                tc.GetTriangleVertices(t,
                                       out vertex0.x, out vertex0.y, out vertex0.z,
                                       out vertex1.x, out vertex1.y, out vertex1.z,
                                       out vertex2.x, out vertex2.y, out vertex2.z, out t_flags, out sequence);

                // logger.WriteLine(string.Format("x: {0},{1},{2} y: {3},{4},{5} z: {6},{7},{8}",vertex0.x,vertex1.x,vertex2.x,vertex0.y,vertex1.y,vertex2.y,vertex0.z,vertex1.z,vertex2.z));

                Vector normal;
                Utils.GetTriangleNormal(vertex0, vertex1, vertex2, out normal);
                float angle_z = (float)Math.Sin(40.0 / 360.0 * Math.PI * 2); //
                if (Utils.abs(normal.z) > angle_z || IgnoreGradient)
                {
                    bool hasIntersected = false;

                    hasIntersected = Utils.SegmentTriangleIntersect(s0, s1, vertex0, vertex1, vertex2, out intersect);
                    if (!hasIntersected)
                    {
                        hasIntersected = Utils.SegmentTriangleIntersect(s2, s3, vertex0, vertex1, vertex2, out intersect);
                    }
                    if (!hasIntersected)
                    {
                        hasIntersected = Utils.SegmentTriangleIntersect(s4, s5, vertex0, vertex1, vertex2, out intersect);
                    }
                    if (!hasIntersected)
                    {
                        hasIntersected = Utils.SegmentTriangleIntersect(s6, s7, vertex0, vertex1, vertex2, out intersect);
                    }
                    if (!hasIntersected)
                    {
                        hasIntersected = Utils.SegmentTriangleIntersect(s8, s9, vertex0, vertex1, vertex2, out intersect);
                    }

                    if (hasIntersected)
                    {
                        if (intersect.z > best_z)
                        {
                            if (!IsSpotBlocked(intersect.x, intersect.y, intersect.z, toonHeight, toonSize))
                            {
                                logger.WriteLine("new best z:" + intersect.z.ToString());
                                best_z     = intersect.z;
                                best_flags = t_flags;
                                found      = true;
                            }
                        }
                        else
                        {
                            //logger.WriteLine("not best");
                        }
                    }
                    else
                    {
                        //logger.WriteLine("Utils.SegmentTriangleIntersect false");
                    }
                }
                else
                {
                    //logger.WriteLine(string.Format("utils.abs(normal.z) {0} > angle_z {1}", Utils.abs(normal.z), angle_z));
                }
            }
            if (found)
            {
                Vector up, dn, tmp;
                up.z = best_z + 2;
                dn.z = best_z - 5;
                bool[] nearCliff = { true, true, true, true };

                bool allGood = true;
                foreach (int t in ts)
                {
                    Vector vertex0;
                    Vector vertex1;
                    Vector vertex2;

                    tc.GetTriangleVertices(t,
                                           out vertex0.x, out vertex0.y, out vertex0.z,
                                           out vertex1.x, out vertex1.y, out vertex1.z,
                                           out vertex2.x, out vertex2.y, out vertex2.z);

                    float[] dx = { minCliffD, -minCliffD, 0, 0 };
                    float[] dy = { 0, 0, minCliffD, -minCliffD };
                    // Check if it is close to a "cliff"

                    allGood = true;
                    for (int i = 0; i < 4; i++)
                    {
                        if (nearCliff[i])
                        {
                            up.x = dn.x = x + dx[i];
                            up.y = dn.y = y + dy[i];
                            if (Utils.SegmentTriangleIntersect(up, dn, vertex0, vertex1, vertex2, out tmp))
                            {
                                nearCliff[i] = false;
                            }
                        }
                        allGood &= !nearCliff[i];
                    }
                    if (allGood)
                    {
                        break;
                    }
                }

                allGood = true;
                for (int i = 0; i < 4; i++)
                {
                    allGood &= !nearCliff[i];
                }
                if (!allGood)
                {
                    z0    = best_z;
                    flags = best_flags;
                    return(false); // too close to cliff
                }
            }
            z0    = best_z;
            flags = best_flags;
            return(found);
        }
        public bool IsStepBlocked(float x0, float y0, float z0,
                                  float x1, float y1, float z1,
                                  float toonHeight, float toonSize, TriangleCollection paintI)
        {
            TriangleCollection tc = GetChunkAt(x0, y0);

            float dx         = x0 - x1;
            float dy         = y0 - y1;
            float dz         = z0 - z1;
            float stepLength = (float)Math.Sqrt(dx * dx + dy * dy + dz * dz);
            // 1: check steepness

            // TODO

            // 2: check is there is a big step

            float mid_x     = (x0 + x1) / 2.0f;
            float mid_y     = (y0 + y1) / 2.0f;
            float mid_z     = (z0 + z1) / 2.0f;
            float mid_z_hit = 0;
            float mid_dz    = Math.Abs(stepLength);
            //if (mid_dz < 1.0f) mid_dz = 1.0f;
            int mid_flags = 0;

            if (FindStandableAt(mid_x, mid_y, mid_z - mid_dz, mid_z + mid_dz, out mid_z_hit, out mid_flags, toonHeight, toonSize))
            {
                float dz0 = Math.Abs(z0 - mid_z_hit);
                float dz1 = Math.Abs(z1 - mid_z_hit);

                // Console.WriteLine("z0 " + z0 + " z1 " + z1 + " dz0 " + dz0+ " dz1 " + dz1 );
                if (dz0 > stepLength / 2.0 && dz0 > 1.0)
                {
                    return(true); // too steep
                }
                if (dz1 > stepLength / 2.0 && dz1 > 1.0)
                {
                    return(true); // too steep
                }
            }
            else
            {
                // bad!
                return(true);
            }

            ICollection <int> ts, tsm, tst;

            ts = null;
            if (UseOctree)
            {
                TriangleOctree ot = tc.GetOctree();
                tst = ts = ot.FindTrianglesInBox(Utils.min(x0, x1), Utils.min(y0, y1), Utils.min(z0, z1),
                                                 Utils.max(x0, x1), Utils.max(y0, y1), Utils.max(z0, z1));
            }
            if (UseMatrix)
            {
                TriangleMatrix tm = tc.GetTriangleMatrix();
                tsm = ts = tm.GetAllInSquare(Utils.min(x0, x1), Utils.min(y0, y1), Utils.max(x0, x1), Utils.max(y0, y1));
            }

            // 3: check collision with objects

            Vector from, from_up, from_low;
            Vector to, to_up, to_low;

            from.x = x0;
            from.y = y0;
            from.z = z0 + toonSize; //+0.5

            to.x = x1;
            to.y = y1;
            to.z = z1 + toonSize;

            from_up   = new Vector(from);
            from_up.z = z0 + toonHeight - toonSize;

            to_up   = new Vector(to);
            to_up.z = z1 + toonHeight - toonSize;

            //diagonal
            if (CheckForCollision(tc, ts, ref from, ref to_up))
            {
                return(true);
            }

            //diagonal
            if (CheckForCollision(tc, ts, ref from_up, ref to))
            {
                return(true);
            }

            //head height
            // if (CheckForCollision(tc, ts, ref from_up, ref to_up)) { return true; }

            //close to the ground
            from_low   = new Vector(from);
            from_low.z = z0 + 0.2f;
            to_low     = new Vector(to);
            to_low.z   = z1 + 0.2f;
            if (CheckForCollision(tc, ts, ref from_low, ref to_low))
            {
                return(true);
            }

            float ddx, ddy;

            GetNormal(x0, y0, x1, y1, out ddx, out ddy, 0.2f);

            from_low.x += ddy;
            from_low.y += ddx;
            to_low.x   += ddy;
            to_low.y   += ddx;
            if (CheckForCollision(tc, ts, ref from_low, ref to_low))
            {
                return(true);
            }

            from_low.x -= 2 * ddy;
            from_low.y -= 2 * ddx;
            to_low.x   -= 2 * ddy;
            to_low.y   -= 2 * ddx;
            if (CheckForCollision(tc, ts, ref from_low, ref to_low))
            {
                return(true);
            }

            return(false);
        }
Esempio n. 8
0
        public bool IsStepBlocked(float x0, float y0, float z0,
                                  float x1, float y1, float z1,
                                  float toonHeight, float toonSize, TriangleCollection paintI)
        {
            TriangleCollection tc = GetChunkAt(x0, y0);



            ICollection <int> ts, tsm, tst;

            ts = null;
            if (UseOctree)
            {
                TriangleOctree ot = tc.GetOctree();
                tst = ts = ot.FindTrianglesInBox(Utils.min(x0, x1), Utils.min(y0, y1), Utils.min(z0, z1),
                                                 Utils.max(x0, x1), Utils.max(y0, y1), Utils.max(z0, z1));
            }
            if (UseMatrix)
            {
                TriangleMatrix tm = tc.GetTriangleMatrix();
                tsm = ts = tm.GetAllInSquare(Utils.min(x0, x1), Utils.min(y0, y1), Utils.max(x0, x1), Utils.max(y0, y1));
            }


            bool   coll = false;
            Vector from, from_up;
            Vector to, to_up;

            from.x    = x0; from.y = y0; from.z = z0 + toonSize;
            from_up.x = x0; from_up.y = y0; from_up.z = z0 + toonHeight - toonSize;

            to.x    = x1; to.y = y1; to.z = z1 + toonSize;
            to_up.x = x1; to_up.y = y1; to_up.z = z1 + toonHeight - toonSize;



            foreach (int t in ts)
            //for(int t = 0 ; t<tc.GetNumberOfTriangles(); t++)
            {
                Vector vertex0;
                Vector vertex1;
                Vector vertex2;
                Vector intersect;

                tc.GetTriangleVertices(t,
                                       out vertex0.x, out vertex0.y, out vertex0.z,
                                       out vertex1.x, out vertex1.y, out vertex1.z,
                                       out vertex2.x, out vertex2.y, out vertex2.z);

                if (Utils.SegmentTriangleIntersect(from, to_up, vertex0, vertex1, vertex2, out intersect) ||
                    Utils.SegmentTriangleIntersect(from_up, to, vertex0, vertex1, vertex2, out intersect))
                {
                    if (paintI != null)
                    {
                        //paintI.AddMarker(intersect.x, intersect.y, intersect.z);
                    }
                    //Console.WriteLine("Collided at " + intersect);
                    coll = true;
                    return(true);
                    // blocked!
                }
            }


            return(coll);
        }
Esempio n. 9
0
        public bool IsStepBlocked(float x0, float y0, float z0,
                                  float x1, float y1, float z1,
                                  float toonHeight, float toonSize, TriangleCollection paintI)
        {
            TriangleCollection tc = GetChunkAt(x0, y0);

            float dx         = x0 - x1;
            float dy         = y0 - y1;
            float dz         = z0 - z1;
            var   stepLength = (float)Math.Sqrt(dx * dx + dy * dy + dz + dz);
            // 1: check steepness

            // TODO

            // 2: check is there is a big step

            float mid_x     = (x0 + x1) / 2.0f;
            float mid_y     = (y0 + y1) / 2.0f;
            float mid_z     = (z0 + z1) / 2.0f;
            float mid_z_hit = 0;
            float mid_dz    = Math.Abs(stepLength);
            //if (mid_dz < 1.0f) mid_dz = 1.0f;
            int mid_flags = 0;

            if (FindStandableAt(mid_x, mid_y, mid_z - mid_dz, mid_z + mid_dz, out mid_z_hit, out mid_flags, toonHeight,
                                toonSize))
            {
                float dz0 = Math.Abs(z0 - mid_z_hit);
                float dz1 = Math.Abs(z1 - mid_z_hit);

                // PathGraph.Log("z0 " + z0 + " z1 " + z1 + " dz0 " + dz0+ " dz1 " + dz1 );
                if (dz0 > stepLength / 2.0 && dz0 > 1.0)
                {
                    return(true); // too steep
                }
                if (dz1 > stepLength / 2.0 && dz1 > 1.0)
                {
                    return(true); // too steep
                }
            }
            else
            {
                // bad!
                return(true);
            }

            ICollection <int> ts, tsm, tst;

            ts = null;
            if (UseOctree)
            {
                TriangleOctree ot = tc.GetOctree();
                tst = ts = ot.FindTrianglesInBox(Utils.min(x0, x1), Utils.min(y0, y1), Utils.min(z0, z1),
                                                 Utils.max(x0, x1), Utils.max(y0, y1), Utils.max(z0, z1));
            }
            if (UseMatrix)
            {
                TriangleMatrix tm = tc.GetTriangleMatrix();
                tsm = ts = tm.GetAllInSquare(Utils.min(x0, x1), Utils.min(y0, y1), Utils.max(x0, x1), Utils.max(y0, y1));
            }


            // 3: check collision with objects

            bool   coll = false;
            Vector from, from_up;
            Vector to, to_up;

            from.x    = x0;
            from.y    = y0;
            from.z    = z0 + toonSize;
            from_up.x = x0;
            from_up.y = y0;
            from_up.z = z0 + toonHeight - toonSize;

            to.x    = x1;
            to.y    = y1;
            to.z    = z1 + toonSize;
            to_up.x = x1;
            to_up.y = y1;
            to_up.z = z1 + toonHeight - toonSize;


            foreach (int t in ts)
            //for(int t = 0 ; t<tc.GetNumberOfTriangles(); t++)
            {
                Vector vertex0;
                Vector vertex1;
                Vector vertex2;
                Vector intersect;

                tc.GetTriangleVertices(t,
                                       out vertex0.x, out vertex0.y, out vertex0.z,
                                       out vertex1.x, out vertex1.y, out vertex1.z,
                                       out vertex2.x, out vertex2.y, out vertex2.z);

                if (Utils.SegmentTriangleIntersect(from, to_up, vertex0, vertex1, vertex2, out intersect) ||
                    Utils.SegmentTriangleIntersect(from_up, to, vertex0, vertex1, vertex2, out intersect))
                {
                    if (paintI != null)
                    {
                        //paintI.AddMarker(intersect.x, intersect.y, intersect.z);
                    }
                    //PathGraph.Log("Collided at " + intersect);
                    coll = true;
                    return(true);
                    // blocked!
                }
            }


            return(coll);
        }