@@ -14,8 +14,6 @@ namespace System.Numerics
14
14
[ Intrinsic ]
15
15
public struct Plane : IEquatable < Plane >
16
16
{
17
- private const float NormalizeEpsilon = 1.192092896e-07f ; // smallest such that 1.0+NormalizeEpsilon != 1.0
18
-
19
17
/// <summary>The normal vector of the plane.</summary>
20
18
public Vector3 Normal ;
21
19
@@ -74,49 +72,15 @@ public Plane(Vector4 value)
74
72
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
75
73
public static Plane CreateFromVertices ( Vector3 point1 , Vector3 point2 , Vector3 point3 )
76
74
{
77
- if ( Vector128 . IsHardwareAccelerated )
78
- {
79
- Vector3 a = point2 - point1 ;
80
- Vector3 b = point3 - point1 ;
81
-
82
- // N = Cross(a, b)
83
- Vector3 n = Vector3 . Cross ( a , b ) ;
84
- Vector3 normal = Vector3 . Normalize ( n ) ;
85
-
86
- // D = - Dot(N, point1)
87
- float d = - Vector3 . Dot ( normal , point1 ) ;
88
-
89
- return Create ( normal , d ) ;
90
- }
91
- else
92
- {
93
- float ax = point2 . X - point1 . X ;
94
- float ay = point2 . Y - point1 . Y ;
95
- float az = point2 . Z - point1 . Z ;
75
+ // This implementation is based on the DirectX Math Library XMPlaneFromPoints method
76
+ // https://github.com/microsoft/DirectXMath/blob/master/Inc/DirectXMathMisc.inl
96
77
97
- float bx = point3 . X - point1 . X ;
98
- float by = point3 . Y - point1 . Y ;
99
- float bz = point3 . Z - point1 . Z ;
78
+ Vector3 normal = Vector3 . Normalize ( Vector3 . Cross ( point2 - point1 , point3 - point1 ) ) ;
100
79
101
- // N=Cross(a,b)
102
- float nx = ay * bz - az * by ;
103
- float ny = az * bx - ax * bz ;
104
- float nz = ax * by - ay * bx ;
105
-
106
- // Normalize(N)
107
- float ls = nx * nx + ny * ny + nz * nz ;
108
- float invNorm = 1.0f / float . Sqrt ( ls ) ;
109
-
110
- Vector3 normal = Vector3 . Create (
111
- nx * invNorm ,
112
- ny * invNorm ,
113
- nz * invNorm ) ;
114
-
115
- return Create (
116
- normal ,
117
- - ( normal . X * point1 . X + normal . Y * point1 . Y + normal . Z * point1 . Z )
118
- ) ;
119
- }
80
+ return Create (
81
+ normal ,
82
+ - Vector3 . Dot ( normal , point1 )
83
+ ) ;
120
84
}
121
85
122
86
/// <summary>Calculates the dot product of a plane and a 4-dimensional vector.</summary>
@@ -131,29 +95,40 @@ public static Plane CreateFromVertices(Vector3 point1, Vector3 point2, Vector3 p
131
95
/// <param name="plane">The plane.</param>
132
96
/// <param name="value">The 3-dimensional vector.</param>
133
97
/// <returns>The dot product.</returns>
134
- public static float DotCoordinate ( Plane plane , Vector3 value ) => Vector3 . Dot ( plane . Normal , value ) + plane . D ;
98
+ public static float DotCoordinate ( Plane plane , Vector3 value )
99
+ {
100
+ // This implementation is based on the DirectX Math Library XMPlaneDotCoord method
101
+ // https://github.com/microsoft/DirectXMath/blob/master/Inc/DirectXMathMisc.inl
102
+
103
+ return Dot ( plane , Vector4 . Create ( value , 1.0f ) ) ;
104
+ }
135
105
136
106
/// <summary>Returns the dot product of a specified three-dimensional vector and the <see cref="Normal" /> vector of this plane.</summary>
137
107
/// <param name="plane">The plane.</param>
138
108
/// <param name="value">The three-dimensional vector.</param>
139
109
/// <returns>The dot product.</returns>
140
- public static float DotNormal ( Plane plane , Vector3 value ) => Vector3 . Dot ( plane . Normal , value ) ;
110
+ public static float DotNormal ( Plane plane , Vector3 value )
111
+ {
112
+ // This implementation is based on the DirectX Math Library XMPlaneDotNormal method
113
+ // https://github.com/microsoft/DirectXMath/blob/master/Inc/DirectXMathMisc.inl
114
+
115
+ return Vector3 . Dot ( plane . Normal , value ) ;
116
+ }
141
117
142
118
/// <summary>Creates a new <see cref="Plane" /> object whose normal vector is the source plane's normal vector normalized.</summary>
143
119
/// <param name="value">The source plane.</param>
144
120
/// <returns>The normalized plane.</returns>
145
- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
146
121
public static Plane Normalize ( Plane value )
147
122
{
148
- float normalLengthSquared = value . Normal . LengthSquared ( ) ;
123
+ // This implementation is based on the DirectX Math Library XMPlaneNormalize method
124
+ // https://github.com/microsoft/DirectXMath/blob/master/Inc/DirectXMathMisc.inl
149
125
150
- if ( float . Abs ( normalLengthSquared - 1.0f ) < NormalizeEpsilon )
151
- {
152
- // It already normalized, so we don't need to farther process.
153
- return value ;
154
- }
126
+ Vector128 < float > lengthSquared = Vector128 . Create ( value . Normal . LengthSquared ( ) ) ;
155
127
156
- return ( value . AsVector128 ( ) / float . Sqrt ( normalLengthSquared ) ) . AsPlane ( ) ;
128
+ return Vector128 . AndNot (
129
+ ( value . AsVector128 ( ) / Vector128 . Sqrt ( lengthSquared ) ) ,
130
+ Vector128 . Equals ( lengthSquared , Vector128 . Create ( float . PositiveInfinity ) )
131
+ ) . AsPlane ( ) ;
157
132
}
158
133
159
134
/// <summary>Transforms a normalized plane by a 4x4 matrix.</summary>
@@ -162,64 +137,15 @@ public static Plane Normalize(Plane value)
162
137
/// <returns>The transformed plane.</returns>
163
138
/// <remarks><paramref name="plane" /> must already be normalized so that its <see cref="Normal" /> vector is of unit length before this method is called.</remarks>
164
139
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
165
- public static Plane Transform ( Plane plane , Matrix4x4 matrix )
166
- {
167
- Matrix4x4 . Invert ( matrix , out Matrix4x4 m ) ;
168
-
169
- float x = plane . Normal . X , y = plane . Normal . Y , z = plane . Normal . Z , w = plane . D ;
170
-
171
- return Create (
172
- x * m . M11 + y * m . M12 + z * m . M13 + w * m . M14 ,
173
- x * m . M21 + y * m . M22 + z * m . M23 + w * m . M24 ,
174
- x * m . M31 + y * m . M32 + z * m . M33 + w * m . M34 ,
175
- x * m . M41 + y * m . M42 + z * m . M43 + w * m . M44
176
- ) ;
177
- }
140
+ public static Plane Transform ( Plane plane , Matrix4x4 matrix ) => Vector4 . Transform ( plane . AsVector4 ( ) , matrix ) . AsPlane ( ) ;
178
141
179
142
/// <summary>Transforms a normalized plane by a Quaternion rotation.</summary>
180
143
/// <param name="plane">The normalized plane to transform.</param>
181
144
/// <param name="rotation">The Quaternion rotation to apply to the plane.</param>
182
145
/// <returns>A new plane that results from applying the Quaternion rotation.</returns>
183
146
/// <remarks><paramref name="plane" /> must already be normalized so that its <see cref="Normal" /> vector is of unit length before this method is called.</remarks>
184
147
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
185
- public static Plane Transform ( Plane plane , Quaternion rotation )
186
- {
187
- // Compute rotation matrix.
188
- float x2 = rotation . X + rotation . X ;
189
- float y2 = rotation . Y + rotation . Y ;
190
- float z2 = rotation . Z + rotation . Z ;
191
-
192
- float wx2 = rotation . W * x2 ;
193
- float wy2 = rotation . W * y2 ;
194
- float wz2 = rotation . W * z2 ;
195
- float xx2 = rotation . X * x2 ;
196
- float xy2 = rotation . X * y2 ;
197
- float xz2 = rotation . X * z2 ;
198
- float yy2 = rotation . Y * y2 ;
199
- float yz2 = rotation . Y * z2 ;
200
- float zz2 = rotation . Z * z2 ;
201
-
202
- float m11 = 1.0f - yy2 - zz2 ;
203
- float m21 = xy2 - wz2 ;
204
- float m31 = xz2 + wy2 ;
205
-
206
- float m12 = xy2 + wz2 ;
207
- float m22 = 1.0f - xx2 - zz2 ;
208
- float m32 = yz2 - wx2 ;
209
-
210
- float m13 = xz2 - wy2 ;
211
- float m23 = yz2 + wx2 ;
212
- float m33 = 1.0f - xx2 - yy2 ;
213
-
214
- float x = plane . Normal . X , y = plane . Normal . Y , z = plane . Normal . Z ;
215
-
216
- return Create (
217
- x * m11 + y * m21 + z * m31 ,
218
- x * m12 + y * m22 + z * m32 ,
219
- x * m13 + y * m23 + z * m33 ,
220
- plane . D
221
- ) ;
222
- }
148
+ public static Plane Transform ( Plane plane , Quaternion rotation ) => Vector4 . Transform ( plane . AsVector4 ( ) , rotation ) . AsPlane ( ) ;
223
149
224
150
/// <summary>Returns a value that indicates whether two planes are equal.</summary>
225
151
/// <param name="value1">The first plane to compare.</param>
0 commit comments