// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. // // ----------------------------------------------------------------------------- // Original code from SlimMath project. http://code.google.com/p/slimmath/ // Greetings to SlimDX Group. Original code published with the following license: // ----------------------------------------------------------------------------- /* * Copyright (c) 2007-2011 SlimDX Group * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ using System; using System.Globalization; using System.Runtime.InteropServices; using System.Runtime.Serialization; namespace math { /// /// Represents a plane in three dimensional space. /// [DataContract] [StructLayout( LayoutKind.Sequential, Pack = 4 )] public struct Plane : IEquatable, IFormattable { /// /// The normal vector of the plane. /// public Vec3 Normal; /// /// The distance of the plane along its normal from the origin. /// public float D; /// /// Initializes a new instance of the struct. /// /// The value that will be assigned to all components. public Plane( float value ) { Normal.X = Normal.Y = Normal.Z = D = value; } /// /// Initializes a new instance of the struct. /// /// The X component of the normal. /// The Y component of the normal. /// The Z component of the normal. /// The distance of the plane along its normal from the origin. public Plane( float a, float b, float c, float d ) { Normal.X = a; Normal.Y = b; Normal.Z = c; D = d; } /// /// Initializes a new instance of the struct. /// /// Any point that lies along the plane. /// The normal vector to the plane. public Plane( Vec3 point, Vec3 normal ) { this.Normal = normal; this.D = Vec3.Dot( normal, point ); } /// /// Initializes a new instance of the struct. /// /// The normal of the plane. /// The distance of the plane along its normal from the origin public Plane( Vec3 value, float d ) { Normal = value; D = d; } /// /// Initializes a new instance of the struct. /// /// First point of a triangle defining the plane. /// Second point of a triangle defining the plane. /// Third point of a triangle defining the plane. public Plane( Vec3 point1, Vec3 point2, Vec3 point3 ) { float x1 = point2.X - point1.X; float y1 = point2.Y - point1.Y; float z1 = point2.Z - point1.Z; float x2 = point3.X - point1.X; float y2 = point3.Y - point1.Y; float z2 = point3.Z - point1.Z; float yz = ( y1 * z2 ) - ( z1 * y2 ); float xz = ( z1 * x2 ) - ( x1 * z2 ); float xy = ( x1 * y2 ) - ( y1 * x2 ); float invPyth = 1.0f / (float)( Math.Sqrt( ( yz * yz ) + ( xz * xz ) + ( xy * xy ) ) ); Normal.X = yz * invPyth; Normal.Y = xz * invPyth; Normal.Z = xy * invPyth; D = -( ( Normal.X * point1.X ) + ( Normal.Y * point1.Y ) + ( Normal.Z * point1.Z ) ); } /// /// Initializes a new instance of the struct. /// /// The values to assign to the A, B, C, and D components of the plane. This must be an array with four elements. /// Thrown when is null. /// Thrown when contains more or less than four elements. public Plane( float[] values ) { if( values == null ) throw new ArgumentNullException( "values" ); if( values.Length != 4 ) throw new ArgumentOutOfRangeException( "values", "There must be four and only four input values for Plane." ); Normal.X = values[0]; Normal.Y = values[1]; Normal.Z = values[2]; D = values[3]; } /// /// Gets or sets the component at the specified index. /// /// The value of the A, B, C, or D component, depending on the index. /// The index of the component to access. Use 0 for the A component, 1 for the B component, 2 for the C component, and 3 for the D component. /// The value of the component at the specified index. /// Thrown when the is out of the range [0, 3]. public float this[int index] { get { switch( index ) { case 0: return Normal.X; case 1: return Normal.Y; case 2: return Normal.Z; case 3: return D; } throw new ArgumentOutOfRangeException( "index", "Indices for Plane run from 0 to 3, inclusive." ); } set { switch( index ) { case 0: Normal.X = value; break; case 1: Normal.Y = value; break; case 2: Normal.Z = value; break; case 3: D = value; break; default: throw new ArgumentOutOfRangeException( "index", "Indices for Plane run from 0 to 3, inclusive." ); } } } /// /// Negates a plane by negating all its coefficients, which result in a plane in opposite direction. /// public void Negate() { Normal.X = -Normal.X; Normal.Y = -Normal.Y; Normal.Z = -Normal.Z; D = -D; } /// /// Changes the coefficients of the normal vector of the plane to make it of unit length. /// public void Normalize() { float magnitude = 1.0f / (float)( Math.Sqrt( ( Normal.X * Normal.X ) + ( Normal.Y * Normal.Y ) + ( Normal.Z * Normal.Z ) ) ); Normal.X *= magnitude; Normal.Y *= magnitude; Normal.Z *= magnitude; D *= magnitude; } /// /// Creates an array containing the elements of the plane. /// /// A four-element array containing the components of the plane. public float[] ToArray() { return new float[] { Normal.X, Normal.Y, Normal.Z, D }; } /// /// Determines if there is an intersection between the current object and a point. /// /// The point to test. /// Whether the two objects intersected. public PlaneIntersectionType Intersects( ref Vec3 point ) { return CollisionHelper.PlaneIntersectsPoint( ref this, ref point ); } /// /// Determines if there is an intersection between the current object and a . /// /// The ray to test. /// Whether the two objects intersected. public bool Intersects( ref Ray ray ) { float distance; return CollisionHelper.RayIntersectsPlane( ref ray, ref this, out distance ); } /// /// Determines if there is an intersection between the current object and a . /// /// The ray to test. /// When the method completes, contains the distance of the intersection, /// or 0 if there was no intersection. /// Whether the two objects intersected. public bool Intersects( ref Ray ray, out float distance ) { return CollisionHelper.RayIntersectsPlane( ref ray, ref this, out distance ); } /// /// Determines if there is an intersection between the current object and a . /// /// The ray to test. /// When the method completes, contains the point of intersection, /// or if there was no intersection. /// Whether the two objects intersected. public bool Intersects( ref Ray ray, out Vec3 point ) { return CollisionHelper.RayIntersectsPlane( ref ray, ref this, out point ); } /// /// Determines if there is an intersection between the current object and a . /// /// The plane to test. /// Whether the two objects intersected. public bool Intersects( ref Plane plane ) { return CollisionHelper.PlaneIntersectsPlane( ref this, ref plane ); } /// /// Determines if there is an intersection between the current object and a . /// /// The plane to test. /// When the method completes, contains the line of intersection /// as a , or a zero ray if there was no intersection. /// Whether the two objects intersected. public bool Intersects( ref Plane plane, out Ray line ) { return CollisionHelper.PlaneIntersectsPlane( ref this, ref plane, out line ); } /// /// Determines if there is an intersection between the current object and a triangle. /// /// The first vertex of the triangle to test. /// The second vertex of the triagnle to test. /// The third vertex of the triangle to test. /// Whether the two objects intersected. public PlaneIntersectionType Intersects( ref Vec3 vertex1, ref Vec3 vertex2, ref Vec3 vertex3 ) { return CollisionHelper.PlaneIntersectsTriangle( ref this, ref vertex1, ref vertex2, ref vertex3 ); } /// /// Determines if there is an intersection between the current object and a . /// /// The box to test. /// Whether the two objects intersected. public PlaneIntersectionType Intersects( ref BoundingBox box ) { return CollisionHelper.PlaneIntersectsBox( ref this, ref box ); } /// /// Determines if there is an intersection between the current object and a . /// /// The sphere to test. /// Whether the two objects intersected. public PlaneIntersectionType Intersects( ref BoundingSphere sphere ) { return CollisionHelper.PlaneIntersectsSphere( ref this, ref sphere ); } /// /// Scales the plane by the given scaling factor. /// /// The plane to scale. /// The amount by which to scale the plane. /// When the method completes, contains the scaled plane. public static void Multiply( ref Plane value, float scale, out Plane result ) { result.Normal.X = value.Normal.X * scale; result.Normal.Y = value.Normal.Y * scale; result.Normal.Z = value.Normal.Z * scale; result.D = value.D * scale; } /// /// Scales the plane by the given scaling factor. /// /// The plane to scale. /// The amount by which to scale the plane. /// The scaled plane. public static Plane Multiply( Plane value, float scale ) { return new Plane( value.Normal.X * scale, value.Normal.Y * scale, value.Normal.Z * scale, value.D * scale ); } /// /// Calculates the dot product of the specified vector and plane. /// /// The source plane. /// The source vector. /// When the method completes, contains the dot product of the specified plane and vector. public static void Dot( ref Plane left, ref Vec4 right, out float result ) { result = ( left.Normal.X * right.X ) + ( left.Normal.Y * right.Y ) + ( left.Normal.Z * right.Z ) + ( left.D * right.W ); } /// /// Calculates the dot product of the specified vector and plane. /// /// The source plane. /// The source vector. /// The dot product of the specified plane and vector. public static float Dot( Plane left, Vec4 right ) { return ( left.Normal.X * right.X ) + ( left.Normal.Y * right.Y ) + ( left.Normal.Z * right.Z ) + ( left.D * right.W ); } /// /// Calculates the dot product of a specified vector and the normal of the plane plus the distance value of the plane. /// /// The source plane. /// The source vector. /// When the method completes, contains the dot product of a specified vector and the normal of the Plane plus the distance value of the plane. public static void DotCoordinate( ref Plane left, ref Vec3 right, out float result ) { result = ( left.Normal.X * right.X ) + ( left.Normal.Y * right.Y ) + ( left.Normal.Z * right.Z ) + left.D; } /// /// Calculates the dot product of a specified vector and the normal of the plane plus the distance value of the plane. /// /// The source plane. /// The source vector. /// The dot product of a specified vector and the normal of the Plane plus the distance value of the plane. public static float DotCoordinate( Plane left, Vec3 right ) { return ( left.Normal.X * right.X ) + ( left.Normal.Y * right.Y ) + ( left.Normal.Z * right.Z ) + left.D; } /// /// Calculates the dot product of the specified vector and the normal of the plane. /// /// The source plane. /// The source vector. /// When the method completes, contains the dot product of the specified vector and the normal of the plane. public static void DotNormal( ref Plane left, ref Vec3 right, out float result ) { result = ( left.Normal.X * right.X ) + ( left.Normal.Y * right.Y ) + ( left.Normal.Z * right.Z ); } /// /// Calculates the dot product of the specified vector and the normal of the plane. /// /// The source plane. /// The source vector. /// The dot product of the specified vector and the normal of the plane. public static float DotNormal( Plane left, Vec3 right ) { return ( left.Normal.X * right.X ) + ( left.Normal.Y * right.Y ) + ( left.Normal.Z * right.Z ); } /// /// Projects a point onto a plane. /// /// The plane to project the point to. /// The point to project. /// The projected point. public static void Project( ref Plane plane, ref Vec3 point, out Vec3 result ) { float distance; DotCoordinate( ref plane, ref point, out distance ); // compute: point - distance * plane.Normal Vec3.Multiply( ref plane.Normal, distance, out result ); Vec3.Subtract( ref point, ref result, out result ); } /// /// Projects a point onto a plane. /// /// The plane to project the point to. /// The point to project. /// The projected point. public static Vec3 Project( Plane plane, Vec3 point ) { Vec3 result; Project( ref plane, ref point, out result ); return result; } /// /// Changes the coefficients of the normal vector of the plane to make it of unit length. /// /// The source plane. /// When the method completes, contains the normalized plane. public static void Normalize( ref Plane plane, out Plane result ) { float magnitude = 1.0f / (float)( Math.Sqrt( ( plane.Normal.X * plane.Normal.X ) + ( plane.Normal.Y * plane.Normal.Y ) + ( plane.Normal.Z * plane.Normal.Z ) ) ); result.Normal.X = plane.Normal.X * magnitude; result.Normal.Y = plane.Normal.Y * magnitude; result.Normal.Z = plane.Normal.Z * magnitude; result.D = plane.D * magnitude; } /// /// Changes the coefficients of the normal vector of the plane to make it of unit length. /// /// The source plane. /// The normalized plane. public static Plane Normalize( Plane plane ) { float magnitude = 1.0f / (float)( Math.Sqrt( ( plane.Normal.X * plane.Normal.X ) + ( plane.Normal.Y * plane.Normal.Y ) + ( plane.Normal.Z * plane.Normal.Z ) ) ); return new Plane( plane.Normal.X * magnitude, plane.Normal.Y * magnitude, plane.Normal.Z * magnitude, plane.D * magnitude ); } /// /// Negates a plane by negating all its coefficients, which result in a plane in opposite direction. /// /// The source plane. /// When the method completes, contains the flipped plane. public static void Negate( ref Plane plane, out Plane result ) { result.Normal.X = -plane.Normal.X; result.Normal.Y = -plane.Normal.Y; result.Normal.Z = -plane.Normal.Z; result.D = -plane.D; } /// /// Negates a plane by negating all its coefficients, which result in a plane in opposite direction. /// /// The source plane. /// The flipped plane. public static Plane Negate( Plane plane ) { float magnitude = 1.0f / (float)( Math.Sqrt( ( plane.Normal.X * plane.Normal.X ) + ( plane.Normal.Y * plane.Normal.Y ) + ( plane.Normal.Z * plane.Normal.Z ) ) ); return new Plane( plane.Normal.X * magnitude, plane.Normal.Y * magnitude, plane.Normal.Z * magnitude, plane.D * magnitude ); } /// /// Transforms a normalized plane by a quaternion rotation. /// /// The normalized source plane. /// The quaternion rotation. /// When the method completes, contains the transformed plane. public static void Transform( ref Plane plane, ref Quaternion rotation, out Plane result ) { float x2 = rotation.X + rotation.X; float y2 = rotation.Y + rotation.Y; float z2 = rotation.Z + rotation.Z; float wx = rotation.W * x2; float wy = rotation.W * y2; float wz = rotation.W * z2; float xx = rotation.X * x2; float xy = rotation.X * y2; float xz = rotation.X * z2; float yy = rotation.Y * y2; float yz = rotation.Y * z2; float zz = rotation.Z * z2; float x = plane.Normal.X; float y = plane.Normal.Y; float z = plane.Normal.Z; result.Normal.X = ( ( x * ( ( 1.0f - yy ) - zz ) ) + ( y * ( xy - wz ) ) ) + ( z * ( xz + wy ) ); result.Normal.Y = ( ( x * ( xy + wz ) ) + ( y * ( ( 1.0f - xx ) - zz ) ) ) + ( z * ( yz - wx ) ); result.Normal.Z = ( ( x * ( xz - wy ) ) + ( y * ( yz + wx ) ) ) + ( z * ( ( 1.0f - xx ) - yy ) ); result.D = plane.D; } /// /// Transforms a normalized plane by a quaternion rotation. /// /// The normalized source plane. /// The quaternion rotation. /// The transformed plane. public static Plane Transform( Plane plane, Quaternion rotation ) { Plane result; float x2 = rotation.X + rotation.X; float y2 = rotation.Y + rotation.Y; float z2 = rotation.Z + rotation.Z; float wx = rotation.W * x2; float wy = rotation.W * y2; float wz = rotation.W * z2; float xx = rotation.X * x2; float xy = rotation.X * y2; float xz = rotation.X * z2; float yy = rotation.Y * y2; float yz = rotation.Y * z2; float zz = rotation.Z * z2; float x = plane.Normal.X; float y = plane.Normal.Y; float z = plane.Normal.Z; result.Normal.X = ( ( x * ( ( 1.0f - yy ) - zz ) ) + ( y * ( xy - wz ) ) ) + ( z * ( xz + wy ) ); result.Normal.Y = ( ( x * ( xy + wz ) ) + ( y * ( ( 1.0f - xx ) - zz ) ) ) + ( z * ( yz - wx ) ); result.Normal.Z = ( ( x * ( xz - wy ) ) + ( y * ( yz + wx ) ) ) + ( z * ( ( 1.0f - xx ) - yy ) ); result.D = plane.D; return result; } /// /// Transforms an array of normalized planes by a quaternion rotation. /// /// The array of normalized planes to transform. /// The quaternion rotation. /// Thrown when is null. public static void Transform( Plane[] planes, ref Quaternion rotation ) { if( planes == null ) throw new ArgumentNullException( "planes" ); float x2 = rotation.X + rotation.X; float y2 = rotation.Y + rotation.Y; float z2 = rotation.Z + rotation.Z; float wx = rotation.W * x2; float wy = rotation.W * y2; float wz = rotation.W * z2; float xx = rotation.X * x2; float xy = rotation.X * y2; float xz = rotation.X * z2; float yy = rotation.Y * y2; float yz = rotation.Y * z2; float zz = rotation.Z * z2; for( int i = 0; i < planes.Length; ++i ) { float x = planes[i].Normal.X; float y = planes[i].Normal.Y; float z = planes[i].Normal.Z; /* * Note: * Factor common arithmetic out of loop. */ planes[i].Normal.X = ( ( x * ( ( 1.0f - yy ) - zz ) ) + ( y * ( xy - wz ) ) ) + ( z * ( xz + wy ) ); planes[i].Normal.Y = ( ( x * ( xy + wz ) ) + ( y * ( ( 1.0f - xx ) - zz ) ) ) + ( z * ( yz - wx ) ); planes[i].Normal.Z = ( ( x * ( xz - wy ) ) + ( y * ( yz + wx ) ) ) + ( z * ( ( 1.0f - xx ) - yy ) ); } } /// /// Transforms a normalized plane by a matrix. /// /// The normalized source plane. /// The transformation matrix. /// When the method completes, contains the transformed plane. public static void Transform( ref Plane plane, ref Matrix transformation, out Plane result ) { float x = plane.Normal.X; float y = plane.Normal.Y; float z = plane.Normal.Z; float d = plane.D; Matrix inverse; Matrix.Invert( ref transformation, out inverse ); result.Normal.X = ( ( ( x * inverse.M11 ) + ( y * inverse.M12 ) ) + ( z * inverse.M13 ) ) + ( d * inverse.M14 ); result.Normal.Y = ( ( ( x * inverse.M21 ) + ( y * inverse.M22 ) ) + ( z * inverse.M23 ) ) + ( d * inverse.M24 ); result.Normal.Z = ( ( ( x * inverse.M31 ) + ( y * inverse.M32 ) ) + ( z * inverse.M33 ) ) + ( d * inverse.M34 ); result.D = ( ( ( x * inverse.M41 ) + ( y * inverse.M42 ) ) + ( z * inverse.M43 ) ) + ( d * inverse.M44 ); } /// /// Transforms a normalized plane by a matrix. /// /// The normalized source plane. /// The transformation matrix. /// When the method completes, contains the transformed plane. public static Plane Transform( Plane plane, Matrix transformation ) { Plane result; float x = plane.Normal.X; float y = plane.Normal.Y; float z = plane.Normal.Z; float d = plane.D; transformation.Invert(); result.Normal.X = ( ( ( x * transformation.M11 ) + ( y * transformation.M12 ) ) + ( z * transformation.M13 ) ) + ( d * transformation.M14 ); result.Normal.Y = ( ( ( x * transformation.M21 ) + ( y * transformation.M22 ) ) + ( z * transformation.M23 ) ) + ( d * transformation.M24 ); result.Normal.Z = ( ( ( x * transformation.M31 ) + ( y * transformation.M32 ) ) + ( z * transformation.M33 ) ) + ( d * transformation.M34 ); result.D = ( ( ( x * transformation.M41 ) + ( y * transformation.M42 ) ) + ( z * transformation.M43 ) ) + ( d * transformation.M44 ); return result; } /// /// Transforms an array of normalized planes by a matrix. /// /// The array of normalized planes to transform. /// The transformation matrix. /// Thrown when is null. public static void Transform( Plane[] planes, ref Matrix transformation ) { if( planes == null ) throw new ArgumentNullException( "planes" ); Matrix inverse; Matrix.Invert( ref transformation, out inverse ); for( int i = 0; i < planes.Length; ++i ) { Transform( ref planes[i], ref transformation, out planes[i] ); } } /// /// Scales a plane by the given value. /// /// The amount by which to scale the plane. /// The plane to scale. /// The scaled plane. public static Plane operator *( float scale, Plane plane ) { return new Plane( plane.Normal.X * scale, plane.Normal.Y * scale, plane.Normal.Z * scale, plane.D * scale ); } /// /// Scales a plane by the given value. /// /// The plane to scale. /// The amount by which to scale the plane. /// The scaled plane. public static Plane operator *( Plane plane, float scale ) { return new Plane( plane.Normal.X * scale, plane.Normal.Y * scale, plane.Normal.Z * scale, plane.D * scale ); } /// /// Negates a plane by negating all its coefficients, which result in a plane in opposite direction. /// /// The negated plane. public static Plane operator -( Plane plane ) { return new Plane( -plane.Normal.X, -plane.Normal.Y, -plane.Normal.Z, -plane.D ); } /// /// Tests for equality between two objects. /// /// The first value to compare. /// The second value to compare. /// true if has the same value as ; otherwise, false. public static bool operator ==( Plane left, Plane right ) { return left.Equals( right ); } /// /// Tests for inequality between two objects. /// /// The first value to compare. /// The second value to compare. /// true if has a different value than ; otherwise, false. public static bool operator !=( Plane left, Plane right ) { return !left.Equals( right ); } /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString() { return string.Format( CultureInfo.CurrentCulture, "A:{0} B:{1} C:{2} D:{3}", Normal.X, Normal.Y, Normal.Z, D ); } /// /// Returns a that represents this instance. /// /// The format. /// /// A that represents this instance. /// public string ToString( string format ) { return string.Format( CultureInfo.CurrentCulture, "A:{0} B:{1} C:{2} D:{3}", Normal.X.ToString( format, CultureInfo.CurrentCulture ), Normal.Y.ToString( format, CultureInfo.CurrentCulture ), Normal.Z.ToString( format, CultureInfo.CurrentCulture ), D.ToString( format, CultureInfo.CurrentCulture ) ); } /// /// Returns a that represents this instance. /// /// The format provider. /// /// A that represents this instance. /// public string ToString( IFormatProvider formatProvider ) { return string.Format( formatProvider, "A:{0} B:{1} C:{2} D:{3}", Normal.X, Normal.Y, Normal.Z, D ); } /// /// Returns a that represents this instance. /// /// The format. /// The format provider. /// /// A that represents this instance. /// public string ToString( string format, IFormatProvider formatProvider ) { return string.Format( formatProvider, "A:{0} B:{1} C:{2} D:{3}", Normal.X.ToString( format, formatProvider ), Normal.Y.ToString( format, formatProvider ), Normal.Z.ToString( format, formatProvider ), D.ToString( format, formatProvider ) ); } /// /// Returns a hash code for this instance. /// /// /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// public override int GetHashCode() { return Normal.GetHashCode() + D.GetHashCode(); } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// public bool Equals( Plane value ) { return Normal == value.Normal && D == value.D; } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// public override bool Equals( object value ) { if( value == null ) return false; if( value.GetType() != GetType() ) return false; return Equals( (Plane)value ); } #if SlimDX1xInterop /// /// Performs an implicit conversion from to . /// /// The value. /// The result of the conversion. public static implicit operator SlimDX.Plane(Plane value) { return new SlimDX.Plane(value.Normal, value.D); } /// /// Performs an implicit conversion from to . /// /// The value. /// The result of the conversion. public static implicit operator Plane(SlimDX.Plane value) { return new Plane(value.Normal, value.D); } #endif #if XnaInterop /// /// Performs an implicit conversion from to . /// /// The value. /// The result of the conversion. public static implicit operator Microsoft.Xna.Framework.Plane(Plane value) { return new Microsoft.Xna.Framework.Plane(value.Normal, value.D); } /// /// Performs an implicit conversion from to . /// /// The value. /// The result of the conversion. public static implicit operator Plane(Microsoft.Xna.Framework.Plane value) { return new Plane(value.Normal, value.D); } #endif } }