4 // Rodrigo Kumpera (rkumpera@novell.com)
6 // (C) 2008 Novell, Inc. (http://www.novell.com)
8 // Permission is hereby granted, free of charge, to any person obtaining
9 // a copy of this software and associated documentation files (the
10 // "Software"), to deal in the Software without restriction, including
11 // without limitation the rights to use, copy, modify, merge, publish,
12 // distribute, sublicense, and/or sell copies of the Software, and to
13 // permit persons to whom the Software is furnished to do so, subject to
14 // the following conditions:
16 // The above copyright notice and this permission notice shall be
17 // included in all copies or substantial portions of the Software.
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System.Runtime.InteropServices;
\r
33 public enum ShuffleSel
\r
55 /*Expand a single element into all elements*/
56 ExpandX = XFromX | YFromX | ZFromX | WFromX,
57 ExpandY = XFromY | YFromY | ZFromY | WFromY,
58 ExpandZ = XFromZ | YFromZ | ZFromZ | WFromZ,
59 ExpandW = XFromW | YFromW | ZFromW | WFromW,
61 /*Expand a pair of elements (x,y,z,w) -> (x,x,y,y)*/
62 ExpandXY = XFromX | YFromX | ZFromY | WFromY,
63 ExpandZW = XFromZ | YFromZ | ZFromW | WFromW,
65 /*Expand interleaving elements (x,y,z,w) -> (x,y,x,y)*/
66 ExpandInterleavedXY = XFromX | YFromY | ZFromX | WFromY,
67 ExpandInterleavedZW = XFromZ | YFromW | ZFromZ | WFromW,
70 RotateRight = XFromY | YFromZ | ZFromW | WFromX,
71 RotateLeft = XFromW | YFromX | ZFromY | WFromZ,
74 Swap = XFromW | YFromZ | ZFromY | WFromX,
79 Unary - (implemented as mulps [-1,-1,-1,-1])
80 Abs (implemented as pand [7fffffff,...] )
82 Mask extraction function
85 Single float constructor (expand it to the 4 positions)
86 Replace Shuffle with less bug prone methods
89 [StructLayout(LayoutKind.Sequential, Pack = 0, Size = 16)]
\r
90 public struct Vector4f
\r
97 public float X { get { return x; } set { x = value; } }
\r
98 public float Y { get { return y; } set { y = value; } }
\r
99 public float Z { get { return z; } set { z = value; } }
\r
100 public float W { get { return w; } set { w = value; } }
\r
102 public Vector4f (float x, float y, float z, float w)
\r
110 public static unsafe Vector4f operator & (Vector4f v1, Vector4f v2)
\r
112 Vector4f res = new Vector4f ();
113 int *a = (int*)&v1;
\r
114 int *b = (int*)&v2;
\r
116 *c++ = *a++ & *b++;
\r
117 *c++ = *a++ & *b++;
\r
118 *c++ = *a++ & *b++;
\r
123 public static unsafe Vector4f operator | (Vector4f v1, Vector4f v2)
\r
125 Vector4f res = new Vector4f ();
126 int *a = (int*)&v1;
\r
127 int *b = (int*)&v2;
\r
129 *c++ = *a++ | *b++;
\r
130 *c++ = *a++ | *b++;
\r
131 *c++ = *a++ | *b++;
\r
136 public static unsafe Vector4f operator ^ (Vector4f v1, Vector4f v2)
\r
138 Vector4f res = new Vector4f ();
139 int *a = (int*)&v1;
\r
140 int *b = (int*)&v2;
\r
142 *c++ = *a++ ^ *b++;
\r
143 *c++ = *a++ ^ *b++;
\r
144 *c++ = *a++ ^ *b++;
\r
149 public static Vector4f operator + (Vector4f v1, Vector4f v2)
\r
151 return new Vector4f (v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.w + v2.w);
\r
154 public static Vector4f operator - (Vector4f v1, Vector4f v2)
\r
156 return new Vector4f (v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.w - v2.w);
\r
159 public static Vector4f operator * (Vector4f v1, Vector4f v2)
\r
161 return new Vector4f (v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.w * v2.w);
\r
164 public static Vector4f operator / (Vector4f v1, Vector4f v2)
\r
166 return new Vector4f (v1.x / v2.x, v1.y / v2.y, v1.z / v2.z, v1.w / v2.w);
\r
169 public static unsafe Vector4f AndNot (Vector4f v1, Vector4f v2)
\r
171 Vector4f res = new Vector4f ();
172 int *a = (int*)&v1;
\r
173 int *b = (int*)&v2;
\r
175 *c++ = ~*a++ & *b++;
\r
176 *c++ = ~*a++ & *b++;
\r
177 *c++ = ~*a++ & *b++;
\r
182 public static Vector4f Sqrt (Vector4f v1)
\r
184 return new Vector4f ((float)System.Math.Sqrt ((float)v1.x),
\r
185 (float)System.Math.Sqrt ((float)v1.y),
\r
186 (float)System.Math.Sqrt ((float)v1.z),
\r
187 (float)System.Math.Sqrt ((float)v1.w));
\r
190 public static Vector4f InvSqrt (Vector4f v1)
\r
192 return new Vector4f ((float)(1.0 / System.Math.Sqrt ((float)v1.x)),
\r
193 (float)(1.0 / System.Math.Sqrt ((float)v1.y)),
\r
194 (float)(1.0 / System.Math.Sqrt ((float)v1.z)),
\r
195 (float)(1.0 / System.Math.Sqrt ((float)v1.w)));
\r
198 public static Vector4f Reciprocal (Vector4f v1)
\r
200 return new Vector4f (1.0f / v1.x, 1.0f / v1.y, 1.0f / v1.z, 1.0f / v1.w);
\r
203 public static Vector4f Max (Vector4f v1, Vector4f v2)
\r
205 return new Vector4f (System.Math.Max (v1.x, v2.x),
\r
206 System.Math.Max (v1.y, v2.y),
\r
207 System.Math.Max (v1.z, v2.z),
\r
208 System.Math.Max (v1.w, v2.w));
\r
211 public static Vector4f Min (Vector4f v1, Vector4f v2)
\r
213 return new Vector4f (System.Math.Min (v1.x, v2.x),
\r
214 System.Math.Min (v1.y, v2.y),
\r
215 System.Math.Min (v1.z, v2.z),
\r
216 System.Math.Min (v1.w, v2.w));
\r
219 public static Vector4f HorizontalAdd (Vector4f v1, Vector4f v2)
\r
221 return new Vector4f (v1.x + v1.y, v1.z + v1.w, v2.x + v2.y, v2.z + v2.w);
\r
224 public static Vector4f AddSub (Vector4f v1, Vector4f v2)
\r
226 return new Vector4f (v1.x - v2.x, v1.y + v2.y, v1.z - v2.z, v1.w + v2.w);
\r
229 public static Vector4f HorizontalSub (Vector4f v1, Vector4f v2)
\r
231 return new Vector4f (v1.x - v1.y, v1.z - v1.w, v2.x - v2.y, v2.z - v2.w);
\r
234 public static Vector4f InterleaveHigh (Vector4f v1, Vector4f v2)
\r
236 return new Vector4f (v1.z, v2.z, v1.w, v2.w);
\r
239 public static Vector4f InterleaveLow (Vector4f v1, Vector4f v2)
\r
241 return new Vector4f (v1.x, v2.x, v1.y, v2.y);
\r
245 public unsafe static Vector4f CompareEquals (Vector4f v1, Vector4f v2)
247 Vector4f res = new Vector4f ();
249 *c++ = v1.x == v2.x ? -1 : 0;
\r
250 *c++ = v1.y == v2.y ? -1 : 0;
\r
251 *c++ = v1.z == v2.z ? -1 : 0;
\r
252 *c = v1.w == v2.w ? -1 : 0;
256 public unsafe static Vector4f CompareLessThan (Vector4f v1, Vector4f v2)
258 Vector4f res = new Vector4f ();
260 *c++ = v1.x < v2.x ? -1 : 0;
\r
261 *c++ = v1.y < v2.y ? -1 : 0;
\r
262 *c++ = v1.z < v2.z ? -1 : 0;
\r
263 *c = v1.w < v2.w ? -1 : 0;
268 public unsafe static Vector4f CompareLessEqual (Vector4f v1, Vector4f v2)
270 Vector4f res = new Vector4f ();
272 *c++ = v1.x <= v2.x ? -1 : 0;
\r
273 *c++ = v1.y <= v2.y ? -1 : 0;
\r
274 *c++ = v1.z <= v2.z ? -1 : 0;
\r
275 *c = v1.w <= v2.w ? -1 : 0;
278 /*Same float.IsNaN (a) || float.IsNaN (b). */
279 public unsafe static Vector4f CompareUnordered (Vector4f v1, Vector4f v2)
281 Vector4f res = new Vector4f ();
283 *c++ = float.IsNaN (v1.x) || float.IsNaN (v2.x) ? -1 : 0;
\r
284 *c++ = float.IsNaN (v1.y) || float.IsNaN (v2.y) ? -1 : 0;
\r
285 *c++ = float.IsNaN (v1.z) || float.IsNaN (v2.z) ? -1 : 0;
\r
286 *c = float.IsNaN (v1.w) || float.IsNaN (v2.w) ? -1 : 0;
290 public unsafe static Vector4f CompareNotEqual (Vector4f v1, Vector4f v2)
292 Vector4f res = new Vector4f ();
294 *c++ = v1.x != v2.x ? -1 : 0;
\r
295 *c++ = v1.y != v2.y ? -1 : 0;
\r
296 *c++ = v1.z != v2.z ? -1 : 0;
\r
297 *c = v1.w != v2.w ? -1 : 0;
301 /*Same as !(a < b). */
302 public unsafe static Vector4f CompareNotLessThan (Vector4f v1, Vector4f v2)
304 Vector4f res = new Vector4f ();
306 *c++ = v1.x < v2.x ? 0 : -1;
\r
307 *c++ = v1.y < v2.y ? 0 : -1;
\r
308 *c++ = v1.z < v2.z ? 0 : -1;
\r
309 *c = v1.w < v2.w ? 0 : -1;
313 /*Same as !(a <= b). */
314 public unsafe static Vector4f CompareNotLessEqual (Vector4f v1, Vector4f v2)
316 Vector4f res = new Vector4f ();
318 *c++ = v1.x <= v2.x ? 0 : -1;
\r
319 *c++ = v1.y <= v2.y ? 0 : -1;
\r
320 *c++ = v1.z <= v2.z ? 0 : -1;
\r
321 *c = v1.w <= v2.w ? 0 : -1;
325 /*Same !float.IsNaN (a) && !float.IsNaN (b). */
326 public unsafe static Vector4f CompareOrdered (Vector4f v1, Vector4f v2)
328 Vector4f res = new Vector4f ();
330 *c++ = !float.IsNaN (v1.x) && !float.IsNaN (v2.x) ? -1 : 0;
\r
331 *c++ = !float.IsNaN (v1.y) && !float.IsNaN (v2.y) ? -1 : 0;
\r
332 *c++ = !float.IsNaN (v1.z) && !float.IsNaN (v2.z) ? -1 : 0;
\r
333 *c = !float.IsNaN (v1.w) && !float.IsNaN (v2.w) ? -1 : 0;
336 public static Vector4f DuplicateLow (Vector4f v1)
338 return new Vector4f (v1.x, v1.x, v1.z, v1.z);
341 public static Vector4f DuplicateHigh (Vector4f v1)
343 return new Vector4f (v1.y, v1.y, v1.w, v1.w);
347 The sel argument must be a value combination of ShuffleSel flags.
349 public static unsafe Vector4f Shuffle (Vector4f v1, ShuffleSel sel)
\r
351 float *ptr = (float*)&v1;
352 int idx = (int)sel;
\r
353 return new Vector4f (*(ptr + ((idx >> 0) & 0x3)),*(ptr + ((idx >> 2) & 0x3)),*(ptr + ((idx >> 4) & 0x3)),*(ptr + ((idx >> 6) & 0x3)));
\r
356 [CLSCompliant(false)]
\r
357 public static unsafe explicit operator Vector4ui(Vector4f v)
\r
359 Vector4ui* p = (Vector4ui*)&v;
\r
363 [CLSCompliant(false)]
\r
364 public static unsafe explicit operator Vector8us(Vector4f v)
\r
366 Vector8us* p = (Vector8us*)&v;
\r
370 [CLSCompliant(false)]
\r
371 public static unsafe explicit operator Vector16b(Vector4f v)
\r
373 Vector16b* p = (Vector16b*)&v;
\r
377 public static Vector4f LoadAligned (ref Vector4f v)
\r
382 public static void StoreAligned (ref Vector4f res, Vector4f val)
\r