1 //// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
2 //// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
3 //// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
4 //// PARTICULAR PURPOSE.
6 //// Copyright (c) Microsoft Corporation. All rights reserved
10 #define _USE_MATH_DEFINES
15 #define PI_F 3.1415927f
17 // Template Vector & Matrix Classes
19 template <class T> struct Vector2
40 T& operator[](unsigned int index)
42 return static_cast<T*>(this)[index];
45 Vector2(T _x = 0, T _y = 0) : x(_x), y(_y) { }
48 template <class T> struct Vector3
72 T& operator[](unsigned int index)
74 return static_cast<T*>(this)[index];
77 Vector3(T _x = 0, T _y = 0, T _z = 0) : x(_x), y(_y), z(_z) { }
80 template <class T> struct Vector4
100 T& operator[](unsigned int index)
102 return static_cast<T*>(this)[index];
105 Vector4(T _x = 0, T _y = 0, T _z = 0, T _w = 0) : x(_x), y(_y), z(_z), w(_w) { }
108 template <class T> struct Matrix4x4
114 T _11; T _12; T _13; T _14;
115 T _21; T _22; T _23; T _24;
116 T _31; T _32; T _33; T _34;
117 T _41; T _42; T _43; T _44;
121 T _m00; T _m01; T _m02; T _m03;
122 T _m10; T _m11; T _m12; T _m13;
123 T _m20; T _m21; T _m22; T _m23;
124 T _m30; T _m31; T _m32; T _m33;
128 Matrix4x4(T value = 0)
130 _11 = _12 = _13 = _14 = value;
131 _21 = _22 = _23 = _24 = value;
132 _31 = _32 = _33 = _34 = value;
133 _41 = _42 = _43 = _44 = value;
137 T i11, T i12, T i13, T i14,
138 T i21, T i22, T i23, T i24,
139 T i31, T i32, T i33, T i34,
140 T i41, T i42, T i43, T i44
143 _11 = i11; _12 = i12; _13 = i13; _14 = i14;
144 _21 = i21; _22 = i22; _23 = i23; _24 = i24;
145 _31 = i31; _32 = i32; _33 = i33; _34 = i34;
146 _41 = i41; _42 = i42; _43 = i43; _44 = i44;
149 T* operator[](unsigned int index)
151 return &(reinterpret_cast<T*>(this)[index*4]);
155 // Template Vector Operations
158 T dot(Vector2<T> a, Vector2<T> b)
160 return a.x * b.x + a.y * b.y;
164 T dot(Vector3<T> a, Vector3<T> b)
166 return a.x * b.x + a.y * b.y + a.z * b.z;
170 T dot(Vector4<T> a, Vector4<T> b)
172 return a.x * b.x + a.y * b.y + a.z * b.z + a.w + b.w;
176 T length(Vector2<T> a)
178 return sqrt(a.x * a.x + a.y * a.y);
182 T length(Vector3<T> a)
184 return sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
188 T length(Vector4<T> a)
190 return sqrt(a.x * a.x + a.y * a.y + a.z * a.z + a.w * a.w);
194 Vector3<T> cross(Vector3<T> a, Vector3<T> b)
196 return Vector3<T>((a.y*b.z)-(a.z*b.y), (a.z*b.x)-(a.x*b.z), (a.x*b.y)-(a.y*b.x));
200 Vector2<T> normalize(Vector2<T> a)
203 return Vector2<T>(a.x / len, a.y / len);
207 Vector3<T> normalize(Vector3<T> a)
210 return Vector3<T>(a.x / len, a.y / len, a.z / len);
214 Vector4<T> normalize(Vector4<T> a)
217 return Vector4<T>(a.x / len, a.y / len, a.z / len, a.w / len);
220 // Template Vector Operators
223 Vector2<T> operator-(Vector2<T> a, Vector2<T> b)
225 return Vector2<T>(a.x - b.x, a.y - b.y);
229 Vector2<T> operator-(Vector2<T> a)
231 return Vector2<T>( -a.x, -a.y);
235 Vector3<T> operator-(Vector3<T> a, Vector3<T> b)
237 return Vector3<T>(a.x - b.x, a.y - b.y, a.z - b.z);
241 Vector3<T> operator-(Vector3<T> a)
243 return Vector3<T>( -a.x, -a.y, -a.z);
247 Vector4<T> operator-(Vector4<T> a, Vector4<T> b)
249 return Vector4<T>(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
253 Vector4<T> operator-(Vector4<T> a)
255 return Vector4<T>( -a.x, -a.y, -a.z, -a.w);
259 Vector2<T> operator+(Vector2<T> a, Vector2<T> b)
261 return Vector2<T>(a.x + b.x, a.y + b.y);
265 Vector3<T> operator+(Vector3<T> a, Vector3<T> b)
267 return Vector3<T>(a.x + b.x, a.y + b.y, a.z + b.z);
271 Vector4<T> operator+(Vector4<T> a, Vector4<T> b)
273 return Vector4<T>(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
277 Vector2<T> operator*(Vector2<T> a, T s)
279 return Vector2<T>(a.x * s, a.y * s);
283 Vector2<T> operator*(T s, Vector2<T> a)
289 Vector2<T> operator*(Vector2<T> a, Vector2<T> b)
291 return Vector2<T>(a.x * b.x, a.y * b.y);
295 Vector2<T> operator/(Vector2<T> a, T s)
297 return Vector2<T>(a.x / s, a.y / s);
301 Vector3<T> operator*(Vector3<T> a, T s)
303 return Vector3<T>(a.x * s, a.y * s, a.z * s);
307 Vector3<T> operator*(T s, Vector3<T> a)
313 Vector3<T> operator*(Vector3<T> a, Vector3<T> b)
315 return Vector3<T>(a.x * b.x, a.y * b.y, a.z * b.z);
319 Vector3<T> operator/(Vector3<T> a, T s)
321 return Vector3<T>(a.x / s, a.y / s, a.z / s);
325 Vector4<T> operator*(Vector4<T> a, T s)
327 return Vector4<T>(a.x * s, a.y * s, a.z * s, a.w * s);
331 Vector4<T> operator*(T s, Vector4<T> a)
337 Vector4<T> operator*(Vector4<T> a, Vector4<T> b)
339 return Vector4<T>(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
343 Vector4<T> operator/(Vector4<T> a, T s)
345 return Vector4<T>(a.x / s, a.y / s, a.z / s, a.w / s);
350 // Template Matrix Operations
353 Matrix4x4<T> transpose(Matrix4x4<T> m)
356 m._11, m._21, m._31, m._41,
357 m_.12, m._22, m._32, m._42,
358 m._13, m._23, m._33, m._43,
359 m._14, m._24, m._34, m._44
364 Matrix4x4<T> mul(Matrix4x4<T> m1, Matrix4x4<T> m2)
368 for (int i = 0; i < 4; i++)
370 for (int j = 0; j < 4; j++)
372 for (int k = 0; k < 4; k++)
374 mOut[i][j] += m1[i][k] * m2[k][j];
382 // Common HLSL-compatible vector typedefs
384 typedef unsigned int uint;
386 typedef Vector2<float> float2;
387 typedef Vector3<float> float3;
388 typedef Vector4<float> float4;
390 typedef Matrix4x4<float> float4x4;
392 // Standard Matrix Intializers
394 inline float4x4 identity()
398 mOut._11 = 1.0f; mOut._12 = 0.0f; mOut._13 = 0.0f; mOut._14 = 0.0f;
399 mOut._21 = 0.0f; mOut._22 = 1.0f; mOut._23 = 0.0f; mOut._24 = 0.0f;
400 mOut._31 = 0.0f; mOut._32 = 0.0f; mOut._33 = 1.0f; mOut._34 = 0.0f;
401 mOut._41 = 0.0f; mOut._42 = 0.0f; mOut._43 = 0.0f; mOut._44 = 1.0f;
406 inline float4x4 translation(float x, float y, float z)
410 mOut._11 = 1.0f; mOut._12 = 0.0f; mOut._13 = 0.0f; mOut._14 = x;
411 mOut._21 = 0.0f; mOut._22 = 1.0f; mOut._23 = 0.0f; mOut._24 = y;
412 mOut._31 = 0.0f; mOut._32 = 0.0f; mOut._33 = 1.0f; mOut._34 = z;
413 mOut._41 = 0.0f; mOut._42 = 0.0f; mOut._43 = 0.0f; mOut._44 = 1.0f;
418 inline float4x4 scale(float x, float y, float z)
422 mOut._11 = x; mOut._12 = 0.0f; mOut._13 = 0.0f; mOut._14 = 0.0f;
423 mOut._21 = 0.0f; mOut._22 = y; mOut._23 = 0.0f; mOut._24 = 0.0f;
424 mOut._31 = 0.0f; mOut._32 = 0.0f; mOut._33 = z; mOut._34 = 0.0f;
425 mOut._41 = 0.0f; mOut._42 = 0.0f; mOut._43 = 0.0f; mOut._44 = 1.0f;
430 inline float4x4 rotationX(float degreeX)
432 float angleInRadians = degreeX * (PI_F / 180.0f);
434 float sinAngle = sinf(angleInRadians);
435 float cosAngle = cosf(angleInRadians);
439 mOut._11 = 1.0f; mOut._12 = 0.0f; mOut._13 = 0.0f; mOut._14 = 0.0f;
440 mOut._21 = 0.0f; mOut._22 = cosAngle; mOut._23 = -sinAngle; mOut._24 = 0.0f;
441 mOut._31 = 0.0f; mOut._32 = sinAngle; mOut._33 = cosAngle; mOut._34 = 0.0f;
442 mOut._41 = 0.0f; mOut._42 = 0.0f; mOut._43 = 0.0f; mOut._44 = 1.0f;
447 inline float4x4 rotationY(float degreeY)
449 float angleInRadians = degreeY * (PI_F / 180.0f);
451 float sinAngle = sinf(angleInRadians);
452 float cosAngle = cosf(angleInRadians);
456 mOut._11 = cosAngle; mOut._12 = 0.0f; mOut._13 = sinAngle; mOut._14 = 0.0f;
457 mOut._21 = 0.0f; mOut._22 = 1.0f; mOut._23 = 0.0f; mOut._24 = 0.0f;
458 mOut._31 = -sinAngle; mOut._32 = 0.0f; mOut._33 = cosAngle; mOut._34 = 0.0f;
459 mOut._41 = 0.0f; mOut._42 = 0.0f; mOut._43 = 0.0f; mOut._44 = 1.0f;
464 inline float4x4 rotationZ(float degreeZ)
466 float angleInRadians = degreeZ * (PI_F / 180.0f);
468 float sinAngle = sinf(angleInRadians);
469 float cosAngle = cosf(angleInRadians);
473 mOut._11 = cosAngle; mOut._12 = -sinAngle; mOut._13 = 0.0f; mOut._14 = 0.0f;
474 mOut._21 = sinAngle; mOut._22 = cosAngle; mOut._23 = 0.0f; mOut._24 = 0.0f;
475 mOut._31 = 0.0f; mOut._32 = 0.0f; mOut._33 = 1.0f; mOut._34 = 0.0f;
476 mOut._41 = 0.0f; mOut._42 = 0.0f; mOut._43 = 0.0f; mOut._44 = 1.0f;
481 // 3D Rotation matrix for an arbitrary axis specified by x, y and z
482 inline float4x4 rotationArbitrary(float3 axis, float degree)
484 axis = normalize(axis);
486 float angleInRadians = degree * (PI_F / 180.0f);
488 float sinAngle = sinf(angleInRadians);
489 float cosAngle = cosf(angleInRadians);
490 float oneMinusCosAngle = 1 - cosAngle;
494 mOut._11 = 1.0f + oneMinusCosAngle * (axis.x * axis.x - 1.0f);
495 mOut._12 = axis.z * sinAngle + oneMinusCosAngle * axis.x * axis.y;
496 mOut._13 = -axis.y * sinAngle + oneMinusCosAngle * axis.x * axis.z;
499 mOut._21 = -axis.z * sinAngle + oneMinusCosAngle * axis.y * axis.x;
500 mOut._22 = 1.0f + oneMinusCosAngle * (axis.y * axis.y - 1.0f);
501 mOut._23 = axis.x * sinAngle + oneMinusCosAngle * axis.y * axis.z;
504 mOut._31 = axis.y * sinAngle + oneMinusCosAngle * axis.z * axis.x;
505 mOut._32 = -axis.x * sinAngle + oneMinusCosAngle * axis.z * axis.y;
506 mOut._33 = 1.0f + oneMinusCosAngle * (axis.z * axis.z - 1.0f);