If you decide to use this, please, post me a comment telling me your opinion. Feedback is important.
Introduction
This is a set of 5 structures that are essential for any 2D/3D graphics programming.
The structures contained within the .zip are:
Matrix4
Quaternion4
Vector2
Vector3
Vector4
MathHelper
// A bonus
What's So Special About These?
As you may know, C# doesn't support the generic constraint for numbers. It would be a great addition, but, alas, it wasn't yet implemented.
And thus, you've got 3 options when it comes to solving this problem:
- Throw the idea out the window and just create a new version for each type you need
- Try the slow interface implementation that gives you the ability to do arithmetic operations on generic types
- Run-time generate IL
I actually went with the first one at the beginning, but it wasn't sufficient. I had several versions of each struct
. One used Single
s, the other used Double
s, etc.. That's many pairs of struct
s to keep up to date. It wasn't worth it, so I gave it up.
The second approach is so slow that it just isn't viable for something like this, so out it went.
The third approach is the most painful one, but has the potential to have the same performance as compiled code and gives you the ultimate power.
If you want to add two variables, you can. Does it matter that they might not be something that supports addition? Not a bit, it'll just spit out some cryptic error. But should you be able to guarantee that those variables are always numbers, then you could do all the arithmetic you want without worrying.
Another problem arises, though, it's IL. No static typing, no comprehensible errors, no IntelliSense, nothing. And you know what? It sounded awesome, so I decided to go with it.
How it looks like:
I offer you this:
Matrix4
:
Array
Backward
Column0
Column1
Column2
Column3
Down
Forward
Identity
Left
Right
Row0
Row1
Row2
Row3
Translation
Up
Add (+1 overload)
CreateBillboard (+1 overload)
CreateConstrainedBillboard (+2 overloads)
CreateFromAxisAngle (+1 overload)
CreateLookAt (+1 overload)
CreateOrthographic
CreateOrthographicOffCenter
CreatePerspective
CreatePerspectiveFieldOfView
CreatePerspectiveOffCenter
CreateRotationX
CreateRotationY
CreateRotationZ
CreateScale (+3 overloads)
CreateTranslation (+2 overloads)
CreateWorld (+1 overload)
Decompose
Divide (+2 overloads)
Equals (+1 overload)
explicit operator Matrix4<T>
explicit operator T[]
Invert (+1 overload)
Lerp (+1 overload)
Matrix4 (+3 overloads)
Multiply (+2 overloads)
Negate (+1 overload)
operator- (+1 overload)
operator!=
operator* (+2 overloads)
operator/
operator+
operator==
Subtract (+1 overload)
Transpose (+1 overload)
Quaternion4
:
Array
Identity
Length
LengthSquared
Add (+1 overload)
Concatenate (+1 overload)
Conjugate (+1 overload)
CreateFromAxisAngle (+1 overload)
CreateFromRotationMatrix (+1 overload)
CreateFromYawPitchRoll
Divide (+1 overload)
Dot (+1 overload)
explicit oprator Vector4<T>
Invert (+1 overload)
Lerp (+1 overload)
Multiply (+2 overloads)
Negate (+1 overload)
Normalize (+1 overload)
operator- (+1 overload)
operator!=
operator* (+1 overload)
operator/
operator+
operator==
Quaterion4 (+3 overloads)
Slerp (+1 overload)
Subtract (+1 overload)
Vector2
:
Array
Down
Left
Length
LengthFast
LengthSquared
One
Right
UnitX
UnitY
Up
Zero
Add (+3 overloads)
Barycentric (+1 overload)
CalculateAngle (+1 overload)
CatmullRom (+1 overload)
Clamp (+1 overload)
ComponentMax (+1 overload)
ComponentMin (+1 overload)
Cross (+1 overload)
Distance (+1 overload)
DistanceSquared (+1 overload)
Divide (+3 overloads)
Dot (+1 overload)
explicit operator Vector3<T>
explicit operator Vector4<T>
Hermite (+1 overload)
Lerp (+1 overload)
Max (+1 overload)
Min (+1 overload)
Multiply (+3 overloads)
Negate (+1 overload)
Normalize (+1 overload)
NormalizeFast (+1 overload)
operator- (+3 overloads)
operator!=
operator* (+2 overloads)
operator/ (+2 overloads)
operator+ (+2 overloads)
operator==
Reflect (+1 overload)
SmoothStep (+1 overload)
Subtract (+2 overloads)
Transform (+1 overload)
Vector2 (+5 overloads)
Vector3
:
Array
Backward
Down
Forward
Left
Length
LengthFast
LengthSquared
One
Right
UnitX
UnitY
UnitZ
Up
Zero
Add (+3 overloads)
Barycentric (+1 overload)
CalculateAngle (+1 overload)
CatmullRom (+1 overload)
Clamp (+1 overload)
ComponentMax (+1 overload)
ComponentMin (+1 overload)
Cross (+1 overload)
Distance (+1 overload)
DistanceSquared (+1 overload)
Divide (+3 overloads)
Dot (+1 overload)
explicit operator Vector3<T>
explicit operator Vector4<T>
Hermite (+1 overload)
Lerp (+1 overload)
Max (+1 overload)
Min (+1 overload)
Multiply (+3 overloads)
Negate (+1 overload)
Normalize (+1 overload)
NormalizeFast (+1 overload)
operator- (+3 overloads)
operator!=
operator* (+2 overloads)
operator/ (+2 overloads)
operator+ (+2 overloads)
operator==
Reflect (+1 overload)
SmoothStep (+1 overload)
Subtract (+2 overloads)
Transform (+3 overload)
Vector3 (+5 overloads)
Vector4
:
Array
Backward
Down
Forward
Left
Length
LengthFast
LengthSquared
One
Right
UnitW
UnitX
UnitY
UnitZ
Up
Zero
Add (+3 overloads)
Barycentric (+1 overload)
CalculateAngle (+1 overload)
CatmullRom (+1 overload)
Clamp (+1 overload)
ComponentMax (+1 overload)
ComponentMin (+1 overload)
Distance (+1 overload)
DistanceSquared (+1 overload)
Divide (+3 overloads)
Dot (+1 overload)
explicit operator Quaternion4<T>
explicit operator Vector3<T>
explicit operator Vector4<T>
Hermite (+1 overload)
Lerp (+1 overload)
Max (+1 overload)
Min (+1 overload)
Multiply (+3 overloads)
Negate (+1 overload)
Normalize (+1 overload)
NormalizeFast (+1 overload)
operator- (+3 overloads)
operator!=
operator* (+2 overloads)
operator/ (+2 overloads)
operator+ (+2 overloads)
operator==
Reflect (+1 overload)
SmoothStep (+1 overload)
Subtract (+2 overloads)
Transform (+5 overload)
Vector4 (+6 overloads)
Some methods like Equals
, ToString
, etc., were omitted from this list, but they are fully defined.
All of this is implemented in hand-written IL. It spans 20,000 lines of pure code and 80,000 lines total, including comments. Every single line of IL is commented with contents of the stack (for the purposes of debugging and better maintainability).
The methods are unit-tested and the performance (from the few tests I ran) should be very close to compiled code. It would be great if someone were to post a benchmark.
Final Words
I really hope this helps someone in some way. It has taken tremendous effort to create and to manage.
I have given it my best, so tell me what you think of it. I look forward to it.