Click here to Skip to main content
15,884,472 members
Articles / Programming Languages / C#
Tip/Trick

Graphics Data Structures with Dynamically Generated IL

Rate me:
Please Sign up or sign in to vote.
4.85/5 (6 votes)
9 Apr 2014CPOL4 min read 13.1K   129   10   3
Matrix, Quaternion and three Vector structures with IL generated at runtime to provide support for all number types.

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:

  1. Throw the idea out the window and just create a new version for each type you need
  2. Try the slow interface implementation that gives you the ability to do arithmetic operations on generic types
  3. 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 Singles, the other used Doubles, etc.. That's many pairs of structs 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:

Image 1

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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
AnswerMy vote of 5 Pin
Christian Amado10-Apr-14 11:02
professionalChristian Amado10-Apr-14 11:02 
Questionmy vote of 5 Pin
Southmountain10-Apr-14 7:50
Southmountain10-Apr-14 7:50 
AnswerRe: my vote of 5 Pin
Nowaki10-Apr-14 8:19
Nowaki10-Apr-14 8:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.