Beispiel #1
0
        public bool Intersects(Line2D line, out float t0, out float t1, out float t2, out float t3)
        {
            List <LineSegment2D> segs = LineSegment2D.FromBounds(this);

            t0 = t1 = t2 = t3 = 0f;


            float unused;
            // horizontal
            float h0, h1;
            bool  intersects = segs[0].line.Intersects(line, out unused, out h0);

            if (!intersects)
            {
                return(false);
            }
            intersects = segs[1].line.Intersects(line, out unused, out h1);
            if (!intersects)
            {
                return(false);
            }

            // vertical
            float v0, v1;

            intersects = segs[2].line.Intersects(line, out unused, out v0);
            if (!intersects)
            {
                return(false);
            }
            intersects = segs[3].line.Intersects(line, out unused, out v1);
            if (!intersects)
            {
                return(false);
            }

            float hh0 = Mathf.Min(h0, h1);
            float hh1 = Mathf.Max(h0, h1);
            float vv0 = Mathf.Min(v0, v1);
            float vv1 = Mathf.Max(v0, v1);

            if (MUtils.LessOrEqual(hh0, vv0))
            {
                // hit h0 first
                t0 = hh0;
                t1 = vv0;
                t2 = Mathf.Min(hh1, vv1);
                t3 = Mathf.Max(hh1, vv1);
                return(MUtils.LessOrEqual(vv0, hh1));
            }
            else
            {
                // hit v0 first
                t0 = vv0;
                t1 = hh0;
                t2 = Mathf.Min(vv1, hh1);
                t3 = Mathf.Max(vv1, hh1);
                return(MUtils.LessOrEqual(hh0, vv1));
            }
        }
            public void SetNode(Node n, float loose)
            {
                n.parent = this;
                if (children == null)
                {
                    children = new Node[4];
                }
                children[n.index] = n;
#if UNITY_EDITOR
                var b = GetSubBounds(n.index, loose);
                Debug.Assert(MUtils.Approximately(n.bounds.min, b.min));
                Debug.Assert(MUtils.Approximately(n.bounds.max, b.max));
#endif
            }
Beispiel #3
0
        public Triangle GetWinding(Vector3 normal)
        {
            var d0    = (p1.vertex - p0.vertex).normalized;
            var d1    = (p2.vertex - p0.vertex).normalized;
            var cross = Vector3.Cross(d0, d1);

            if (Vector3.Dot(normal, cross) < 0f)
            {
                var pp1 = p1;
                var pp2 = p2;
                MUtils.Swap(ref pp1, ref pp2);
                return(new Triangle(p0, pp1, pp2));
            }
            return(new Triangle(p0, p1, p2));
        }
Beispiel #4
0
        // this -> P + D*t
        // other -> line.P + line.D*s
        public bool Intersects(Line2D line, out float t, out float s)
        {
            // P0 + D0t = P1 + D1s => D0t - D1s = P1 - P0
            // P1 - P0 -> K
            // Kross D0 at both side -> -Kross(D0, D1)s = Kross(D0, K) => s = Kross(D0, K)/Kross(D1, D0)
            // Kross D1 at both side -> -Kross(D0, D1)t = Kross(D1, K) => t = Kross(D1, K)/Kross(D1, D0)
            // condition -> Kross(D1, D0) != 0

            float kross = Kross(line.D, D);

            if (!MUtils.Approximately(kross, 0f))
            {
                Vector2 K = line.P - P;
                s = Kross(D, K) / kross;
                t = Kross(line.D, K) / kross;
                return(true);
            }
            s = t = 0;
            return(false);
        }
        void GetProjParams(Camera c, out Vector3 wCamMinOnPlane, out Vector3 wCamMaxOnPlane)
        {
            if (c.orthographic)
            {
                var camPos = c.transform.position;
                var size   = (c.transform.up + c.transform.right * c.aspect) * c.orthographicSize;

                var   camMin = camPos - size;
                var   camMax = camPos + size;
                var   plane  = new Plane(transform.up, transform.position);
                float enter;
                var   r = new Ray(camMin, c.transform.forward);
                plane.Raycast(r, out enter);
                camMin = r.GetPoint(enter);
                r      = new Ray(camMax, c.transform.forward);
                plane.Raycast(r, out enter);
                camMax = r.GetPoint(enter);


                wCamMinOnPlane = new Vector3(
                    Mathf.Min(camMin.x, camMax.x),
                    Mathf.Min(camMin.y, camMax.y),
                    Mathf.Min(camMin.z, camMax.z));
                wCamMaxOnPlane = new Vector3(
                    Mathf.Max(camMin.x, camMax.x),
                    Mathf.Max(camMin.y, camMax.y),
                    Mathf.Max(camMin.z, camMax.z));
            }
            else
            {
                var   corners = c.ProjectFrustumOnXZPlane();
                float minX, maxX, minY, maxY, minZ, maxZ;
                MUtils.MinMax(out minX, out maxX, corners[0].x, corners[1].x, corners[2].x, corners[3].x);
                MUtils.MinMax(out minY, out maxY, corners[0].y, corners[1].y, corners[2].y, corners[3].y);
                MUtils.MinMax(out minZ, out maxZ, corners[0].z, corners[1].z, corners[2].z, corners[3].z);
                wCamMinOnPlane = new Vector3(minX, minY, minZ);
                wCamMaxOnPlane = new Vector3(maxX, maxY, maxZ);
            }
        }
        public static Vector3[] ProjectFrustumOnXZPlane(this Camera camera)
        {
            Plane plane = new Plane(Vector3.up, Vector3.zero);

            Plane[] planes = GeometryUtility.CalculateFrustumPlanes(camera);
            Line    L0;

            MUtils.Intersects(planes[0], plane, out L0);
            Line L1;

            MUtils.Intersects(planes[1], plane, out L1);
            Line L2;

            MUtils.Intersects(planes[2], plane, out L2);
            Line L3;

            MUtils.Intersects(planes[3], plane, out L3);

            Line2D l2d0 = MappingAxis.Map(L0);
            Line2D l2d1 = MappingAxis.Map(L1);
            Line2D l2d2 = MappingAxis.Map(L2);
            Line2D l2d3 = MappingAxis.Map(L3);

            float s, t;

            l2d0.Intersects(l2d2, out t, out s);
            Vector3 rightTop = MappingAxis.Map(l2d0.GetPoint(t));

            l2d0.Intersects(l2d3, out t, out s);
            Vector3 rightBottom = MappingAxis.Map(l2d0.GetPoint(t));

            l2d1.Intersects(l2d2, out t, out s);
            Vector3 leftTop = MappingAxis.Map(l2d1.GetPoint(t));

            l2d1.Intersects(l2d3, out t, out s);
            Vector3 leftBottom = MappingAxis.Map(l2d1.GetPoint(t));

            return(new Vector3[] { leftTop, rightTop, rightBottom, leftBottom });
        }
 public bool PointOnSegment(float t)
 {
     return(MUtils.LessOrEqual(d0, t) && MUtils.LessOrEqual(t, d1));
 }
 /*
  * +---+---+
  * | 3 | 2 |
  * +---+---+
  * | 0 | 1 |
  * +---+---+
  */
 public bool BoundsInSub(int s, Bounds b, float loose)
 {
     return(MUtils.QuadTree_IsBoundsInSub(bounds, s, b, loose));
 }
 public Bounds GetSubBounds(int s, float loose)
 {
     return(MUtils.QuadTree_GetSubBounds(bounds, s, loose));
 }
Beispiel #10
0
        public        Triangle[] ClipBy(Plane inPlane)
        {
            Vector3 ptOnPlane = -inPlane.normal * inPlane.distance;
            float   dot0      = Vector3.Dot(p0.vertex - ptOnPlane, inPlane.normal);
            float   dot1      = Vector3.Dot(p1.vertex - ptOnPlane, inPlane.normal);
            float   dot2      = Vector3.Dot(p2.vertex - ptOnPlane, inPlane.normal);

            int dr0 = MUtils.Approximately(dot0, 0f) ? 0 : (dot0 < 0f ? -1 : 1);
            int dr1 = MUtils.Approximately(dot1, 0f) ? 0 : (dot1 < 0f ? -1 : 1);
            int dr2 = MUtils.Approximately(dot2, 0f) ? 0 : (dot2 < 0f ? -1 : 1);

            if (dr0 > 0 && dr1 > 0 && dr2 > 0)
            {
                return(null);
            }
            if (dr0 < 0 && dr1 < 0 && dr2 < 0)
            {
                return new Triangle[] { this }
            }
            ;


            // one edge lay on the plane
            System.Func <int, int, int, bool> check = delegate(int kr0, int kr1, int kr2)
            {
                if (kr0 == 0 && kr1 == 0)
                {
                    return(kr2 <= 0);
                }
                return(false);
            };

            if (check(dr0, dr1, dr2) || check(dr0, dr2, dr1) ||
                check(dr1, dr0, dr2) || check(dr1, dr2, dr0) ||
                check(dr2, dr0, dr1) || check(dr2, dr1, dr0))
            {
                return(new Triangle[] { this });
            }

            List <Triangle> tris = new List <Triangle>();

            Func <int, int, int, Vertex, Vertex, Vertex, bool> clip = delegate(int kr0, int kr1, int kr2, Vertex pt0, Vertex pt1, Vertex pt2)
            {
                if (kr0 > 0)                 // p0 at positive side
                {
                    float enter;
                    if (kr1 < 0 && kr2 < 0)                     // other two on nagetive plane
                    {
                        var r = new Ray(pt0.vertex, pt1.vertex - pt0.vertex);
                        inPlane.Raycast(r, out enter);
                        var t0 = r.GetPoint(enter);

                        Vertex tt0 = new Vertex();
                        tt0.vertex = t0;
                        tt0.uv     = pt0.uv + (pt1.uv - pt0.uv) * enter;
                        tt0.uv2    = pt0.uv2 + (pt1.uv2 - pt0.uv2) * enter;
                        tt0.uv3    = pt0.uv3 + (pt1.uv3 - pt0.uv3) * enter;
                        tt0.uv4    = pt0.uv4 + (pt1.uv4 - pt0.uv4) * enter;

                        r = new Ray(pt0.vertex, pt2.vertex - pt0.vertex);
                        inPlane.Raycast(r, out enter);
                        var    t1  = r.GetPoint(enter);
                        Vertex tt1 = new Vertex();
                        tt1.vertex = t1;
                        tt1.uv     = pt0.uv + (pt2.uv - pt0.uv) * enter;
                        tt1.uv2    = pt0.uv2 + (pt2.uv2 - pt0.uv2) * enter;
                        tt1.uv3    = pt0.uv3 + (pt2.uv3 - pt0.uv3) * enter;
                        tt1.uv4    = pt0.uv4 + (pt2.uv4 - pt0.uv4) * enter;

                        tris.Add(new Triangle(tt0, pt1, pt2));
                        tris.Add(new Triangle(tt0, pt2, tt1));
                    }
                    else if (kr1 > 0 && kr2 < 0)                     // p1 at positive side. p2 at nagetive side
                    {
                        var r = new Ray(pt0.vertex, pt2.vertex - pt0.vertex);
                        inPlane.Raycast(r, out enter);
                        var    t0  = r.GetPoint(enter);
                        Vertex tt0 = new Vertex();
                        tt0.vertex = t0;
                        tt0.uv     = pt0.uv + (pt2.uv - pt0.uv) * enter;
                        tt0.uv2    = pt0.uv2 + (pt2.uv2 - pt0.uv2) * enter;
                        tt0.uv3    = pt0.uv3 + (pt2.uv3 - pt0.uv3) * enter;
                        tt0.uv4    = pt0.uv4 + (pt2.uv4 - pt0.uv4) * enter;

                        r = new Ray(pt1.vertex, pt2.vertex - pt1.vertex);
                        inPlane.Raycast(r, out enter);
                        var    t1  = r.GetPoint(enter);
                        Vertex tt1 = new Vertex();
                        tt1.vertex = t1;
                        tt1.uv     = pt1.uv + (pt2.uv - pt1.uv) * enter;
                        tt1.uv2    = pt1.uv2 + (pt2.uv2 - pt1.uv2) * enter;
                        tt1.uv3    = pt1.uv3 + (pt2.uv3 - pt1.uv3) * enter;
                        tt1.uv4    = pt1.uv4 + (pt2.uv4 - pt1.uv4) * enter;

                        tris.Add(new Triangle(tt0, pt2, tt1));
                    }
                    else if (kr1 < 0 && kr2 > 0)                     // p2 at positive side, p1 at nagetive side,
                    {
                        var r = new Ray(pt0.vertex, pt1.vertex - pt0.vertex);
                        inPlane.Raycast(r, out enter);
                        var    t0  = r.GetPoint(enter);
                        Vertex tt0 = new Vertex();
                        tt0.vertex = t0;
                        tt0.uv     = pt0.uv + (pt1.uv - pt0.uv) * enter;
                        tt0.uv2    = pt0.uv2 + (pt1.uv2 - pt0.uv2) * enter;
                        tt0.uv3    = pt0.uv3 + (pt1.uv3 - pt0.uv3) * enter;
                        tt0.uv4    = pt0.uv4 + (pt1.uv4 - pt0.uv4) * enter;

                        r = new Ray(pt2.vertex, pt1.vertex - pt2.vertex);
                        inPlane.Raycast(r, out enter);
                        var    t1  = r.GetPoint(enter);
                        Vertex tt1 = new Vertex();
                        tt1.vertex = t1;
                        tt1.uv     = pt2.uv + (pt2.uv - pt1.uv) * enter;
                        tt1.uv2    = pt2.uv2 + (pt2.uv2 - pt1.uv2) * enter;
                        tt1.uv3    = pt2.uv3 + (pt2.uv3 - pt1.uv3) * enter;
                        tt1.uv4    = pt2.uv4 + (pt2.uv4 - pt1.uv4) * enter;

                        tris.Add(new Triangle(tt0, pt1, tt1));
                    }
                    return(true);
                }
                return(false);
            };
            bool clipped = clip(dr0, dr1, dr2, p0, p1, p2);

            clipped = clipped || clip(dr1, dr2, dr0, p1, p2, p0);
            clipped = clipped || clip(dr2, dr0, dr1, p2, p0, p1);
            return(tris.ToArray());
        }
    }