Scope of OpenTK.Math
Continuing the discussion from the "Math module?" topic which has started growing too long.
Inertia said: This brings up an interesting question: What's the real scope of the mathlib?
I haven't really given this much thought, but the general idea was to build a set of functions useful for 3d graphics. Not physics or anything of that sort, but I can imagine it containing noise functions, geometric primitives (useful for bounding volumes, projections etc) or even a tri-strip generator. I don't have a concrete plan though, and this is not high priority stuff at this point.
What do you think the math toolkit should contain? Should it stay simple and focused (vectors, matrices, quaternions and that's it), or should it grow as needed by projects that use it?




Comments
Nov 24
17:08:41To bump some concerns
posted by InertiaTo bump some concerns mentioned in the other thread:
From my perspective the mathlib's dimension is great the way it is, except for the few ref/out overloads and helpers mentioned in the other topic. Noise functions sound good too, especially a better random number generator than the .NET one would be a nice addition. What is the primary use for noise you have in mind? Heightfields for terrain?
I wouldn't turn down more complex primitives than my current plane/sphere/AABB testing, but be aware that it's alot of work.
The thing is, it's rather pointless to include geometric primitives without the ability to compare/test them for intersection. The permutations can become quite numberous if you go for more than just comparing them vs. planes (Frustum). This gets even more work if a simple boolean result is not enough and you're approaching collision detection.
[tri-strips]
To keep it a short Offtopic: If you are using VBO, triangle strips are nowadays less efficient than indexed triangle lists. With tri-strips it's not possible to fully utilize the graphic card's vertex cache without inserting alot of degenerate triangles into the mesh. tri-lists on the other hand do not care about topology of the mesh and allow the mesh to be further optimized for self-occlusion (e.g. draw torso first so that extremities - occluded by the torso - fail Z-test) all without inserting degenerate triangles.
Nov 24
18:51:17[tri-strips] It is my
posted by the Fiddler.[tri-strips]
It is my understanding that tri-strips are faster exactly because a) discarding degenerate triangles is trivial and b) even with degenerate triangles there is a net reduction in the number of indices (thus more data will fit in the vertex cache). I'm quite sure this still holds for newer cards but I don't have the tools to test right now. Will have do that at some point (XNA does have a test, and I think the Ati and Nvidia SDK's have some tools, too).
[primitives]
True it's a lot of work and there are more important parts to implement, but they would be nice to add some point (ray, plane, AABB, sphere). Some of these are already implemented in Mono.Xna so it is possible to lift some parts from there.
[noise]
I've had to implement noise functions countless times over the years, so having some enhanced perlin at hand would be nice for heightmaps/clouds. I don't actually need this right now, but at some point I (or someone) probably will so sooner or later it will be implemented.
[Instance Methods]
This, along with the missing interfaces (IEquatable, IComparable) are the most important missing parts right now. The bad part is that I have my hands full at the moment (a large documentation release is coming). The good part is that these are quite easy to implement, so I'll probably do at some point soon.
Nov 24
20:48:38from the other
posted by nythrixfrom the other thread:
Should it become a full replacement for Math.Net or Collision/Physics SDKs?
Collision, physics and primitive handling, you say? I smell game/graphics engine here. Is OpenTK going that way? I mean, sure all this stuff is useful but will you actually use it in your own code? Or will you replace it with something that suits you better? We all need low level OpenGL. But not everyone needs (standard) collision detection or primitive handling.
[double]
This is not a hot issue so I think we can wait for now.
[dual quaternions]
Rotation & translation is all I need. In fact, I'm removing scaling support from my engine. I get slightly faster execution, happier normals and cleaner teeth :D
I say stay simple.
Nov 25
13:39:30[tri-strips] a) You are
posted by Inertia[tri-strips]
a) You are still assembling a primitive just to cull it and with the added degenerate triangles the Indicies count is higher than n+2 for n Triangles. It's also problematic with unculled transparent geometry, since you will see the lines. This could maybe be worked around with a geometry shader.
b) I wish there was some good documentation about the vertex caches to quote from, but AFAIK the data stored in GL_ELEMENT_ARRAY_BUFFER is never cached anywhere. The GL_ARRAY_BUFFER itself would be identical for a tri-strip and tri-list. There's the Pre-T&L-Cache (around 64k entries on GF6, preferably 32 Bytes aligned) whos only purpose is to keep a copy of the memory block - where the requested vertex was located in - in fast memory, because more accesses to it's neighbours are expected (like the CPU's L2 cache). The Post-T&L-Cache (24 entries for GF3) is the more interesting one, since it will skip the whole vertex processing in case of a cache hit.
Long story short: This is a rather vivid area of research and what's awesome today is outdated in a month or 2. I wouldn't really recommend including this into OpenTK. nVidia provides a nvtristrip tool and Ati provides Tootle for this task.
[primitives]
Don't forget the 2D versions, which would be in demand too. I'm not certain if it should be OpenTK's responsibility to provide this.
...full replacement for Math.Net or Collision/Physics SDKs?
That was a bit exaggerated to show some extremes, not a demand. You're using OpenGL for realtime 3D and not performing any broad Frustum culling? I see that not every app needs collision detection, but most apps need some sort of visibility culling.
[dual quaternions]
Rotating a vector3 by a quaternion is slower than rotating it by a matrix. It sure is more compact in memory, but considering the amount of matrices sent to the graphics card per frame the bandwidth used is imho neglectible.
Nov 25
21:37:52You're using OpenGL for
posted by nythrixYou're using OpenGL for realtime 3D and not performing any broad Frustum culling?
It's large-scale terrain culling in my case. Should OpenTK provide the means for it?
[dual quaternions]
You have a point here. However a) matrices need heavy reorthogonalization from time to time and b) interpolating dual quaternions should be faster. Disadvantage is, I have to convert them to matrices anyway and feed the graphic card. I have to do some testing to prove all this though.
Nov 26
14:56:37Should OpenTK provide the
posted by InertiaShould OpenTK provide the means for it?
Never the hierarchy itself, the only thing I would consider are simple AABB/Plane types as building blocks for your custom (tree) hierarchy. I'm very unsure if this is desireable to include into the mathlib tho, the implementation itself is trivial but the kinds of primitives required will vary from app to app and can quickly become numberous. It will be quite some enterprise trying to satisfy everyone's needs.
[dual quaternions]
Misunderstood you there, I was assuming you're sending the Quaternions as uniforms to a shader instead of a matrix.
Nov 27
03:17:20* Immutable types * Double
posted by JTalton* Immutable types
* Double precision floating point
I currently have an implementation of an immutable double precision class which I am using. I would rather use something that is built in nicely with OpenTK. (i.e. you can current pass a OpenTK.Math.Vector to GL.Vector3) While most people are not going to be using double precision, I am making a model editor that needs it. If no one else if planning on working on it I would be interested in doing both of those.
* Collision Detection
I would like to see basic collision detection algorithms. I have a few already written in C#. Basic line to plane intersection and such.
* Noise
I have some C++ implementations of perlin noise, both repeating and non-repeating. I was planning on porting those to C# and contributing them.
Nov 28
22:53:41I think this is a really
posted by objarniI think this is a really interesting and important discussion.
What is the scope of OpenTK?
I have two words to say in this discussion: avoid bloat. It is the killer of libraries..
For me, OpenTK should be a thin, idiomatic (enums and such) wrapper around OpenGL+OpenAL+windowing/os-events. Nothing more. While I view linear algebra types handy for communicating with GL (and AL in the future I guess), I can't see what perlin noise, AABBs or any mid-to-high-level algorithms and structures has any place in OpenTK.
Keep it simple, please. If I wanted a feature-rich library, I'd go for Irrlicht, Ogre or Torque. But I want the basics, the rest I'll code myself.
One way to do this is by separating such things into, say, OpenTKU (utilities).
my two cents,
Nov 28
00:27:40I feel that code which
posted by the Fiddler.I feel that code which interacts directly with OpenGL functions belongs in the core library (this includes for example double precision vectors, but excludes collision detection). Splitting into core + utilities libraries is , I think, a good idea. What belongs were might be a little debatable but something like the following could work:
The reason for splitting the windowing toolkits out is that a) they bring additional dependencies and b) you are unlikely to use more than one at the same time. On the other hand, it would be nice to have a single integrated dll that is useable on its own (which should include at least one way to create an OpenGL window).
The thing is, OpenTK aims to be more than a simple wrapper but short of a 3d engine. That is, it should include commonly used functionality (like fonts!) but be low-level enough that it doesn't get in the way of building a higher level system. It's a fine line to tread, hopefully it will work out in the end.
@JTalton: do contribute the code you have!
Nov 29
11:46:00Thumbs up. Making
posted by objarniThumbs up. Making dependencies explicit is a good thing.
Of course, the price to pay is the lost dream of "one single dll to suit them all". Maybe it's worth it? I don't know. Maybe both worlds can coexist via build script: giving rise to OpenTKBundle.dll? I don't know how much work this is either.
Nov 29
16:07:13The thing is, OpenTK aims to
posted by InertiaThe thing is, OpenTK aims to be more than a simple wrapper but short of a 3d engine. That is, it should include commonly used functionality (like fonts!) but be low-level enough that it doesn't get in the way of building a higher level system.
This is how I understood it aswell, a Foundation to build your custom Structures upon. Providing an elegant interface to OpenGL/AL in the Core and commonly used functionality like loading/saving Images/Sounds from File, Fonts, Noise, etc. in the Utilities.
Most higher level demands like Texture Managers, Collision Testing or Model loading might be best off in wiki/tutorial example codes, since the requirements to such components vary wildly.
Nov 29
03:15:04Removed double post.
posted by JTaltonRemoved double post.
Nov 29
03:13:20I'll put together my math
posted by JTaltonI'll put together my math stuff. I need some suggestions though.
* Structures vs Classes
It is recommended that structures are 12 to 16 bytes or less.
Vector2f == 8 bytes
Vector3f == 12 bytes
Vector4f == 16 bytes
Vector2d == 16 bytes
Vector3d == 24 bytes
Vector4d == 32 bytes
Matrix3f == 36 bytes
Matrix4f == 64 bytes
Matrix3d == 72 bytes
Matrix4d == 128 bytes
Quaternionf == 16 bytes
Quaterniond == 32 bytes
Structures can be put on the stack while classes are on the heap.
Structures are copied while classes are reference counted.
There are benefits to both and I think the 16 byte limit refers to where you start losing performance when passing variables. I would not want to make some structs and some classes, because they would behave differently.
My code is currently classes, while the current OpenTK.Math is vectors. I am leaning toward classes unless anyone has objections.
* Class names
Do the class names above look good? Or should the floating point be Vector3 while the double precision be Vector3d?
* Interfaces
My classes currently implement IEquatable<>, IComparer<>, and IComparable<>.
Any others?
Nov 30
12:08:54* Names Let's keep the
posted by the Fiddler.* Names
Let's keep the single precision version clean and the add a 'd' in the double version. Looks better and an 'f' provides no real benefit.
* classes vs structs:
This was discussed that at length and decided to implement eveything in structs, but provide overloads with 'ref' and 'out' parameters to avoid copying memory around. I.e.
void Add(ref Vector2d, ref Vector2d, out Vector2d) { } // Fast version
Since we don't use inheritance, and we benefit from the improved locality of reference structs provide, there is little reason to use classes. Tests showed that struct references are a little faster than classes, too.
* Interfaces
Can't think of anything else.
I'll add the necessary overloads in GL/Glu once these are complete.
Jul 15
14:09:43Re: Scope of OpenTK.Math
posted by MantherenIn converting my camera class from DirectX to an OpenTK version I could not find a Plane class (which I use for the frustum) in the Math lib.
It was not entirely clear to me, but is there a plan for a Plane class to be added?
Or should I not wait for this and just go about finding an alternate solution?
Thanks,
Mantheren
Jul 15
15:49:35Re: Scope of OpenTK.Math
posted by the FiddlerThe math lib is mostly built on contributed code (Vectors, Matrices, Beziers). The idea is that whenever someone implements (are has implemented) a new structure (e.g. Planes, Splines etc), he can donate it to help other people who might need the same thing.
It happens that noone needed a Plane class until now. There's a good chance you can find something useful in the Axiom Engine, Math.NET or even the SlimDX source code. If nothing works as you'd like it to and you happen to roll your own class, you are welcome to donate the code (of course you are not expected to do so if you don't wish to).
Jul 15
23:46:58Re: Scope of OpenTK.Math
posted by KamujinHere is my plane class. I think I poached it from Axiom. Hopefully, this help.
{
public Vector3 Normal;
public float D;
private static readonly Plane nullPlane = new Plane(Vector3.Zero, 0);
public Plane(Plane plane)
{
this.Normal = plane.Normal;
this.D = plane.D;
}
public Plane( Vector3 normal, float constant )
{
this.Normal = normal;
this.D = -constant;
}
public Plane( Vector3 normal, Vector3 point )
{
this.Normal = normal;
this.D = -Vector3.Dot(normal, point);
}
public Plane( Vector3 point0, Vector3 point1, Vector3 point2 )
{
Vector3 edge1 = point1 - point0;
Vector3 edge2 = point2 - point0;
Normal = Vector3.Cross(edge1, edge2);
Normal.Normalize();
D = -Vector3.Dot(Normal, point0);
}
public float GetDistance( Vector3 point )
{
return Vector3.Dot(Normal, point) + D;
}
}
Jul 16
09:55:35Re: Scope of OpenTK.Math
posted by objarniAre classes such as Plane put into TK or TKU?
Jul 16
10:46:40Re: Scope of OpenTK.Math
posted by MantherenThanks for the info,
In that case I think I will have a go at trying to create a relatively complete Plane struct.
@Kamujin: I never needed GetDistance yet, but it seems handy so I'll add that as well if you don't mind, thanks. :)
Of course I will gladly donate it back, so what is the preferred way to post it? I see I can't add attachments to posts right?
-- Edit --
Oh wait I see now, I can only attach to new topics, and not in replies to topics, so never mind...
-- End Edit --