If you decide to use this, please, post me a comment telling me your opinion. Feedback is important.

`<a href="/KB/cs/757443/Files_v2.zip">Download source - 106.5 KB</a> `

## 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.