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)); }
//public Plane() { } public CSGPlane(CSGPlane inPlane) { a = inPlane.a; b = inPlane.b; c = inPlane.c; d = inPlane.d; }
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))); }
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))); }
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); }
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); } }
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)); } }
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); } }
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(); } }
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' } }
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); }
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))); } }
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; } }
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); } }
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); } //*/ }