예제 #1
0
        public static CSGPlane InverseTransformed(CSGPlane plane, Matrix4x4 transformation)
        {
            var ttrans = transformation.transpose;
            var vector = ttrans * new Vector4(plane.a, plane.b, plane.c, -plane.d);

            return(new CSGPlane(vector.x, vector.y, vector.z, -vector.w));
        }
예제 #2
0
        //public Plane() { }

        public CSGPlane(CSGPlane inPlane)
        {
            a = inPlane.a;
            b = inPlane.b;
            c = inPlane.c;
            d = inPlane.d;
        }
예제 #3
0
 public static CSGPlane Translated(CSGPlane plane, float translateX, float translateY, float translateZ)
 {
     return(new CSGPlane(plane.a, plane.b, plane.c,
                         // translated offset = plane.Normal.Dotproduct(translation)
                         // normal = A,B,C
                         plane.d + (plane.a * translateX) +
                         (plane.b * translateY) +
                         (plane.c * translateZ)));
 }
예제 #4
0
 public static CSGPlane Translated(CSGPlane plane, Vector3 translation)
 {
     return(new CSGPlane(plane.a, plane.b, plane.c,
                         // translated offset = plane.Normal.Dotproduct(translation)
                         // normal = A,B,C
                         plane.d + (plane.a * translation.x) +
                         (plane.b * translation.y) +
                         (plane.c * translation.z)));
 }
예제 #5
0
        public static CSGPlane InverseTransform(CSGPlane srcPlane, Matrix4x4 transformation)
        {
            var ittrans  = transformation.transpose;
            var vector   = ittrans * new Vector4(srcPlane.a, srcPlane.b, srcPlane.c, -srcPlane.d);
            var dstPlane = new CSGPlane(vector.x, vector.y, vector.z, -vector.w);

            dstPlane.Normalize();
            return(dstPlane);
        }
예제 #6
0
        public static void Transform(CSGPlane[] planes, Matrix4x4 transformation)
        {
            var ittrans = transformation.inverse.transpose;

            for (int i = 0; i < planes.Length; i++)
            {
                var plane  = planes[i];
                var vector = ittrans * new Vector4(plane.a, plane.b, plane.c, -plane.d);
                planes[i] = new CSGPlane(vector.x, vector.y, vector.z, -vector.w);
            }
        }
예제 #7
0
 public static void Translate(CSGPlane[] src, Vector3 translation, out CSGPlane[] dst)
 {
     dst = new CSGPlane[src.Length];
     for (int i = 0; i < src.Length; i++)
     {
         var plane = src[i];
         dst[i] = new CSGPlane(plane.a, plane.b, plane.c,
                               plane.d + (plane.a * translation.x) +
                               (plane.b * translation.y) +
                               (plane.c * translation.z));
     }
 }
예제 #8
0
        public static void Transform(List <CSGPlane> src, Matrix4x4 transformation, out CSGPlane[] dst)
        {
            var ittrans = transformation.inverse.transpose;

            dst = new CSGPlane[src.Count];
            for (int i = 0; i < src.Count; i++)
            {
                var plane  = src[i];
                var vector = ittrans * new Vector4(plane.a, plane.b, plane.c, -plane.d);
                dst[i] = new CSGPlane(vector.x, vector.y, vector.z, -vector.w);
            }
        }
예제 #9
0
        public static void InverseTransform(List <CSGPlane> srcPlanes, Matrix4x4 transformation, out CSGPlane[] dstPlanes)
        {
            var ittrans = transformation.transpose;

            dstPlanes = new CSGPlane[srcPlanes.Count];
            for (int i = 0; i < srcPlanes.Count; i++)
            {
                var plane  = srcPlanes[i];
                var vector = ittrans * new Vector4(plane.a, plane.b, plane.c, -plane.d);
                dstPlanes[i] = new CSGPlane(vector.x, vector.y, vector.z, -vector.w);
                dstPlanes[i].Normalize();
            }
        }
예제 #10
0
        public PlaneAlignment Alignment(CSGPlane other)
        {
            var absDeltaA = Mathf.Abs(a - other.a);
            var absDeltaB = Mathf.Abs(b - other.b);
            var absDeltaC = Mathf.Abs(c - other.c);

            if (float.IsNaN(absDeltaA) || float.IsInfinity(absDeltaA) ||
                float.IsNaN(absDeltaB) || float.IsInfinity(absDeltaB) ||
                float.IsNaN(absDeltaC) || float.IsInfinity(absDeltaC))
            {
                return(PlaneAlignment.Invalid);
            }

            if (absDeltaA > MathConstants.NormalEpsilon ||
                absDeltaB > MathConstants.NormalEpsilon ||
                absDeltaC > MathConstants.NormalEpsilon)
            {
                return(PlaneAlignment.Intersecting);
            }

            var isAligned = Vector3.Dot(normal, other.normal) >= 0;
            var distance  = Distance(other.pointOnPlane);

            if (isAligned)
            {
                // inPlane1 and inPlanr2 are both facing in the same direction
                if (distance < MathConstants.DistanceEpsilon)
                {
                    return(PlaneAlignment.DisjointAndInFront);                                                  // inPlane1 is in front of inPlane2
                }
                if (distance > MathConstants.DistanceEpsilon)
                {
                    return(PlaneAlignment.DisjointAndBehind);                                   // inPlane1 is behind inPlane2
                }
                return(PlaneAlignment.CoincidingFacingSameDirection);                           // 'this' is coinciding with 'other'
            }
            else
            {
                // inPlane1 and inPlanr2 are both facing in the opposite direction
                if (distance < MathConstants.DistanceEpsilon)
                {
                    return(PlaneAlignment.DisjointFacingOutwards);                                      // the planes are facing outwards
                }
                if (distance > MathConstants.DistanceEpsilon)
                {
                    return(PlaneAlignment.DisjointFacingInwards);                           // the planes are facing inwards
                }
                return(PlaneAlignment.CoincidingFacingOppositeDirection);                   // 'this' is coinciding with 'other'
            }
        }
예제 #11
0
 public bool Equals(CSGPlane other)
 {
     if (System.Object.ReferenceEquals(this, other))
     {
         return(true);
     }
     if (System.Object.ReferenceEquals(other, null))
     {
         return(false);
     }
     return(Mathf.Abs(this.Distance(other.pointOnPlane)) <= MathConstants.DistanceEpsilon &&
            Mathf.Abs(other.Distance(this.pointOnPlane)) <= MathConstants.DistanceEpsilon &&
            Mathf.Abs(a - other.a) <= MathConstants.NormalEpsilon &&
            Mathf.Abs(b - other.b) <= MathConstants.NormalEpsilon &&
            Mathf.Abs(c - other.c) <= MathConstants.NormalEpsilon);
 }
예제 #12
0
        static public Vector3 Intersection(CSGPlane inPlane1,
                                           CSGPlane inPlane2,
                                           CSGPlane inPlane3)
        {
            // intersection point with 3 planes
            //  {
            //      x = -( c2*b1*d3-c2*b3*d1+b3*c1*d2+c3*b2*d1-b1*c3*d2-c1*b2*d3)/
            //           (-c2*b3*a1+c3*b2*a1-b1*c3*a2-c1*b2*a3+b3*c1*a2+c2*b1*a3),
            //      y =  ( c3*a2*d1-c3*a1*d2-c2*a3*d1+d2*c1*a3-a2*c1*d3+c2*d3*a1)/
            //           (-c2*b3*a1+c3*b2*a1-b1*c3*a2-c1*b2*a3+b3*c1*a2+c2*b1*a3),
            //      z = -(-a2*b1*d3+a2*b3*d1-a3*b2*d1+d3*b2*a1-d2*b3*a1+d2*b1*a3)/
            //           (-c2*b3*a1+c3*b2*a1-b1*c3*a2-c1*b2*a3+b3*c1*a2+c2*b1*a3)
            //  }

            double bc1 = (inPlane1.b * inPlane3.c) - (inPlane3.b * inPlane1.c);
            double bc2 = (inPlane2.b * inPlane1.c) - (inPlane1.b * inPlane2.c);
            double bc3 = (inPlane3.b * inPlane2.c) - (inPlane2.b * inPlane3.c);

            double ad1 = (inPlane1.a * inPlane3.d) - (inPlane3.a * inPlane1.d);
            double ad2 = (inPlane2.a * inPlane1.d) - (inPlane1.a * inPlane2.d);
            double ad3 = (inPlane3.a * inPlane2.d) - (inPlane2.a * inPlane3.d);

            double x = -((inPlane1.d * bc3) + (inPlane2.d * bc1) + (inPlane3.d * bc2));
            double y = -((inPlane1.c * ad3) + (inPlane2.c * ad1) + (inPlane3.c * ad2));
            double z = +((inPlane1.b * ad3) + (inPlane2.b * ad1) + (inPlane3.b * ad2));
            double w = -((inPlane1.a * bc3) + (inPlane2.a * bc1) + (inPlane3.a * bc2));

            // better to have detectable invalid values than to have reaaaaaaally big values
            if (w > -MathConstants.DistanceEpsilon &&
                w < MathConstants.DistanceEpsilon)
            {
                return(new Vector3(Single.NaN,
                                   Single.NaN,
                                   Single.NaN));
            }
            else
            {
                return(new Vector3((float)(x / w),
                                   (float)(y / w),
                                   (float)(z / w)));
            }
        }
예제 #13
0
        public static void InverseTransform(CSGPlane[] srcPlanes, Vector3[] srcTangents, Matrix4x4 transformation, out CSGPlane[] dstPlanes, out Vector3[] dstTangents)
        {
            var ittrans = transformation.transpose;

            dstPlanes = new CSGPlane[srcPlanes.Length];
            for (int i = 0; i < srcPlanes.Length; i++)
            {
                var plane  = srcPlanes[i];
                var vector = ittrans * new Vector4(plane.a, plane.b, plane.c, -plane.d);
                dstPlanes[i] = new CSGPlane(vector.x, vector.y, vector.z, -vector.w);
            }

            dstTangents = new Vector3[srcTangents.Length];
            for (int i = 0; i < srcTangents.Length; i++)
            {
                var tangent = srcTangents[i];
                var vector  = ittrans * new Vector4(tangent.x, tangent.y, tangent.z, 1);
                dstTangents[i] = (new Vector3(vector.x / vector.w, vector.y / vector.w, vector.z / vector.w)).normalized;
            }
        }
예제 #14
0
        public static PlaneAlignment TryIntersection(CSGPlane inPlane1, CSGPlane inPlane2, out Ray intersectionRay)
        {
            var lineDirection = Vector3.Cross(inPlane1.normal, inPlane2.normal);
            var ax            = Mathf.Abs(lineDirection.x);
            var ay            = Mathf.Abs(lineDirection.y);
            var az            = Mathf.Abs(lineDirection.z);
            var aProduct      = ax + ay + az;

            if (float.IsNaN(aProduct) || float.IsInfinity(aProduct))
            {
                intersectionRay = MathConstants.emptyRay;
                return(PlaneAlignment.Invalid);
            }

            if (aProduct < MathConstants.NormalEpsilon)
            {
                intersectionRay = MathConstants.emptyRay;

                var isAligned = Mathf.Sign(Vector3.Dot(lineDirection, inPlane1.normal)) == Mathf.Sign(Vector3.Dot(lineDirection, inPlane2.normal));
                var distance  = inPlane1.Distance(inPlane2.pointOnPlane);
                if (isAligned)
                {
                    // inPlane1 and inPlane2 are both facing in the same direction
                    if (distance > MathConstants.DistanceEpsilon)
                    {
                        return(PlaneAlignment.DisjointAndInFront);                                      // inPlane1 is in front of inPlane2
                    }
                    if (distance < MathConstants.DistanceEpsilon)
                    {
                        return(PlaneAlignment.DisjointAndBehind);                                   // inPlane1 is behind inPlane2
                    }
                    return(PlaneAlignment.CoincidingFacingSameDirection);                           // 'this' is coinciding with 'other'
                }
                else
                {
                    // inPlane1 and inPlane2 are both facing in the opposite direction
                    if (distance > MathConstants.DistanceEpsilon)
                    {
                        return(PlaneAlignment.DisjointFacingOutwards);                                  // the planes are facing outwards
                    }
                    if (distance < MathConstants.DistanceEpsilon)
                    {
                        return(PlaneAlignment.DisjointFacingInwards);                               // the planes are facing inwards
                    }
                    return(PlaneAlignment.CoincidingFacingOppositeDirection);                       // 'this' is coinciding with 'other'
                }
            }

            var point = MathConstants.zeroVector3;

            if (ax > ay)
            {
                if (ax > az)                 // x = 0
                {
                    point.y         = (-inPlane2.d * inPlane1.c + inPlane1.d * inPlane2.c) / lineDirection.x;
                    point.z         = (-inPlane1.d * inPlane2.b + inPlane2.d * inPlane1.b) / lineDirection.x;
                    intersectionRay = new Ray(point, lineDirection);
                    return(PlaneAlignment.Intersecting);
                }
            }
            else
            {
                if (ay > az)                 // y = 0
                {
                    point.x         = (-inPlane1.d * inPlane2.c + inPlane2.d * inPlane1.c) / lineDirection.y;
                    point.z         = (-inPlane2.d * inPlane1.a + inPlane1.d * inPlane2.a) / lineDirection.y;
                    intersectionRay = new Ray(point, lineDirection);
                    return(PlaneAlignment.Intersecting);
                }
            }

            // z = 0
            {
                point.x         = (-inPlane2.d * inPlane1.b + inPlane1.d * inPlane2.b) / lineDirection.z;
                point.y         = (-inPlane1.d * inPlane2.a + inPlane2.d * inPlane1.a) / lineDirection.z;
                intersectionRay = new Ray(point, lineDirection);
                return(PlaneAlignment.Intersecting);
            }
        }
예제 #15
0
        static public Vector3 Intersection(CSGPlane inPlane1,
                                           CSGPlane inPlane2,
                                           CSGPlane inPlane3)
        {
            /*
             * var lineDirection = Vector3.Cross(inPlane1.normal, inPlane2.normal);
             *
             * if (float.IsNaN(lineDirection.x) || float.IsInfinity(lineDirection.x) ||
             *      float.IsNaN(lineDirection.y) || float.IsInfinity(lineDirection.y) ||
             *      float.IsNaN(lineDirection.z) || float.IsInfinity(lineDirection.z))
             *      return MathConstants.NaNVector3;
             *
             * float ax = Mathf.Abs(lineDirection.x);
             * float ay = Mathf.Abs(lineDirection.y);
             * float az = Mathf.Abs(lineDirection.z);
             * int maxc = 3;
             * if (ax > ay)
             * {
             *      if (ax > az) maxc = 1;
             * } else
             * {
             *      if (ay > az) maxc = 2;
             * }
             *
             * Vector3 linePosition;
             * switch (maxc)
             * {             // select max coordinate
             *      default:
             *      case 1:                     // intersect with x=0
             *              linePosition.x = 0;
             *              linePosition.y = (-inPlane2.d * inPlane1.normal.z + inPlane1.d * inPlane2.normal.z) / lineDirection.x;
             *              linePosition.z = (-inPlane1.d * inPlane2.normal.y + inPlane2.d * inPlane1.normal.y) / lineDirection.x;
             *              break;
             *      case 2:                     // intersect with y=0
             *              linePosition.x = (-inPlane1.d * inPlane2.normal.z + inPlane2.d * inPlane1.normal.z) / lineDirection.y;
             *              linePosition.y = 0;
             *              linePosition.z = (-inPlane2.d * inPlane1.normal.x + inPlane1.d * inPlane2.normal.x) / lineDirection.y;
             *              break;
             *      case 3:                     // intersect with z=0
             *              linePosition.x = (-inPlane2.d * inPlane1.normal.y + inPlane1.d * inPlane2.normal.y) / lineDirection.z;
             *              linePosition.y = (-inPlane1.d * inPlane2.normal.x + inPlane2.d * inPlane1.normal.x) / lineDirection.z;
             *              linePosition.z = 0;
             *              break;
             * }
             *
             * if (float.IsNaN(linePosition.x) || float.IsInfinity(linePosition.x) ||
             *      float.IsNaN(linePosition.y) || float.IsInfinity(linePosition.y) ||
             *      float.IsNaN(linePosition.z) || float.IsInfinity(linePosition.z))
             *      return MathConstants.NaNVector3;
             *
             * float denom = Vector3.Dot(inPlane3.normal, lineDirection);
             *
             * Vector3 p0l0 = inPlane3.pointOnPlane - linePosition;
             * var t = Vector3.Dot(p0l0, inPlane3.normal) / denom;
             *
             * if (float.IsNaN(t) || float.IsInfinity(t))
             *      return MathConstants.NaNVector3;
             *
             * return (t * lineDirection) + linePosition;
             * //*/

            /*
             * // intersection point with 3 planes
             * //  {
             * //      x = -( c2*b1*d3-c2*b3*d1+b3*c1*d2+c3*b2*d1-b1*c3*d2-c1*b2*d3)/
             * //           (-c2*b3*a1+c3*b2*a1-b1*c3*a2-c1*b2*a3+b3*c1*a2+c2*b1*a3),
             * //      y =  ( c3*a2*d1-c3*a1*d2-c2*a3*d1+d2*c1*a3-a2*c1*d3+c2*d3*a1)/
             * //           (-c2*b3*a1+c3*b2*a1-b1*c3*a2-c1*b2*a3+b3*c1*a2+c2*b1*a3),
             * //      z = -(-a2*b1*d3+a2*b3*d1-a3*b2*d1+d3*b2*a1-d2*b3*a1+d2*b1*a3)/
             * //           (-c2*b3*a1+c3*b2*a1-b1*c3*a2-c1*b2*a3+b3*c1*a2+c2*b1*a3)
             * //  }
             *
             * var plane1a = (double)inPlane1.a;
             * var plane1b = (double)inPlane1.b;
             * var plane1c = (double)inPlane1.c;
             * var plane1d = (double)inPlane1.d;
             *
             * var plane2a = (double)inPlane2.a;
             * var plane2b = (double)inPlane2.b;
             * var plane2c = (double)inPlane2.c;
             * var plane2d = (double)inPlane2.d;
             *
             * var plane3a = (double)inPlane3.a;
             * var plane3b = (double)inPlane3.b;
             * var plane3c = (double)inPlane3.c;
             * var plane3d = (double)inPlane3.d;
             *
             *
             * var bc1 = (plane1b * plane3c) - (plane3b * plane1c);
             * var bc2 = (plane2b * plane1c) - (plane1b * plane2c);
             * var bc3 = (plane3b * plane2c) - (plane2b * plane3c);
             *
             * var w = -((plane1a * bc3) + (plane2a * bc1) + (plane3a * bc2));
             *
             * // better to have detectable invalid values than to have reaaaaaaally big values
             * if (double.IsNaN(w) || double.IsInfinity(w) ||
             *      (w > -MathConstants.DistanceEpsilon &&
             *       w <  MathConstants.DistanceEpsilon))
             * {
             *      return MathConstants.NaNVector3;
             * }
             *
             * var ad1 = (plane1a * plane3d) - (plane3a * plane1d);
             * var ad2 = (plane2a * plane1d) - (plane1a * plane2d);
             * var ad3 = (plane3a * plane2d) - (plane2a * plane3d);
             *
             * var x = -((plane1d * bc3) + (plane2d * bc1) + (plane3d * bc2));
             * var y = -((plane1c * ad3) + (plane2c * ad1) + (plane3c * ad2));
             * var z = +((plane1b * ad3) + (plane2b * ad1) + (plane3b * ad2));
             *
             * x /= w;
             * y /= w;
             * z /= w;
             *
             * var result = new Vector3((float)x, (float)y, (float)z);
             * if (float.IsNaN(result.x) || float.IsInfinity(result.x) ||
             *      float.IsNaN(result.y) || float.IsInfinity(result.y) ||
             *      float.IsNaN(result.z) || float.IsInfinity(result.z))
             * {
             *      return MathConstants.NaNVector3;
             * }
             *
             * return result;
             *
             * //*/

            //*
            try
            {
                var plane1a = (decimal)inPlane1.a;
                var plane1b = (decimal)inPlane1.b;
                var plane1c = (decimal)inPlane1.c;
                var plane1d = (decimal)inPlane1.d;

                var plane2a = (decimal)inPlane2.a;
                var plane2b = (decimal)inPlane2.b;
                var plane2c = (decimal)inPlane2.c;
                var plane2d = (decimal)inPlane2.d;

                var plane3a = (decimal)inPlane3.a;
                var plane3b = (decimal)inPlane3.b;
                var plane3c = (decimal)inPlane3.c;
                var plane3d = (decimal)inPlane3.d;


                var bc1 = (plane1b * plane3c) - (plane3b * plane1c);
                var bc2 = (plane2b * plane1c) - (plane1b * plane2c);
                var bc3 = (plane3b * plane2c) - (plane2b * plane3c);

                var w = -((plane1a * bc3) + (plane2a * bc1) + (plane3a * bc2));

                var ad1 = (plane1a * plane3d) - (plane3a * plane1d);
                var ad2 = (plane2a * plane1d) - (plane1a * plane2d);
                var ad3 = (plane3a * plane2d) - (plane2a * plane3d);

                var x = -((plane1d * bc3) + (plane2d * bc1) + (plane3d * bc2));
                var y = -((plane1c * ad3) + (plane2c * ad1) + (plane3c * ad2));
                var z = +((plane1b * ad3) + (plane2b * ad1) + (plane3b * ad2));

                x /= w;
                y /= w;
                z /= w;

                var result = new Vector3((float)x, (float)y, (float)z);
                if (float.IsNaN(result.x) || float.IsInfinity(result.x) ||
                    float.IsNaN(result.y) || float.IsInfinity(result.y) ||
                    float.IsNaN(result.z) || float.IsInfinity(result.z))
                {
                    return(MathConstants.NaNVector3);
                }

                return(result);
            }
            catch
            {
                return(MathConstants.NaNVector3);
            }
            //*/
        }