Click here to Skip to main content
Click here to Skip to main content

Graphics Data Structures with Dynamically Generated IL

, 9 Apr 2014
Rate this:
Please Sign up or sign in to vote.
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.

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:

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)

About the Author

Nowaki

United States United States
No Biography provided

Comments and Discussions

 
AnswerMy vote of 5 PinpremiumChristian Amado10-Apr-14 11:02 
Questionmy vote of 5 PinmemberSouthmountain10-Apr-14 7:50 
AnswerRe: my vote of 5 PinmemberNowaki10-Apr-14 8:19 

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

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

| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 10 Apr 2014
Article Copyright 2014 by Nowaki
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid