stainless at August 29th, 2013 09:49 — #1
Anyone know any good game maths libraries?
I looked a CML. I really like the code it produces when compiled, but it's missing a couple of key things for me.
1) You cannot access member variables by name, no Vector.X instead Vector[value based on configuration]
2) No Vector = Quaternion * Vector operator
When I brought this up in their forums, I was ridiculed and insulted, then they deleted the thread.
So that one is out.
I've looked at GLM, but had some issues with it and our compiler.
Are there any out there that actually work and have everything a games programmer needs?
My own classes were optomised for compilers I don't use anymore, I was hoping not to have to rewrite them all and go through the whole compile, inspect, optomise, loop yet again.
vilem_otte at August 29th, 2013 19:50 — #2
Huh I will do something heroic and brave, ending in epic suicide (and now, flame me please). I'll post an example of my math library, float4 class. If you're interested I might add mat4 and quat classes that I use. I don't use float3/2/... nor mat3/2/3x4/4x3/....... as they're replaced or packed into float4 or mat4.
Here it goes (with epic license): http://pastebin.com/NFFVEg8w
It's not well commented and misses some part of code (aligned allocation/free), and macro - if needed I can post definitions here, but I bet you can add them in like 10 seconds (or maybe you use some of your allocators so you might want to add these functions yourself). It's compatible for any platform for which C++ can compile, or SSE/SSE2/SSE3/SSE4 versions for x86/x86_64 CPUs that support this functionality, switched through macros. Formerly it was C library (so any platform for which C could compile was okay).
Will this help you? I could run the project on GIT and keep versions up to date if wanted.
reedbeta at August 29th, 2013 21:06 — #3
Slightly off-topic, but is SIMD (SSE, AVX, etc.) really needed for most of the vector math operations in a game engine?
On some platforms (*coughPS3cough*) there are enough penalties associated with getting data in and out of SIMD registers that it practically negates all the benefits of SIMD unless you are doing a serious amount of math. But for doing just a small thing with a few operations it wasn't worth it.
Besides, SIMD-izing individual vectors (so that x, y, z, w go into four SIMD lanes) isn't the most efficient way to use SIMD. You can't use more than 4 lanes this way, and if you only use 2 or 3 components of the vector then you waste a bunch of the hardware. To use SIMD effectively you want SoA layout, so you can have a register of 4 or 8 different x values, another of 4 or 8 different y values, etc. and process 4 or 8 vectors in parallel. That's how shaders work on GPUs, although with 32 or 64 lanes instead of 4 or 8.
I've started thinking maybe the best way to do a math library is to forget about SIMD for your general vector/matrix/etc. operations, and just implement those with regular old floats. It makes the math library portable and much cleaner, and probably no slower for most cases. Then for the few places where it really matters you can code the SIMD stuff, using SoA layout and calling intrinsics directly, or maybe a very thin wrapper class for portability.
thenut at August 29th, 2013 23:18 — #4
\\^ this (although template your type so you can swap to doubles for improved precision). Compilers are more than just translators. They do all the dirty optimization work. I've been using the same math library I wrote ages ago, and ported to almost any platform you can think of. I never once had any performance impact for not getting dirty with low level instructions. In this day and age, you have to focus on the larger problems.
As for Stainless, I dunno. I think you should just refactor your code into a form like Reed mentioned. Just blow away a day or two doing it and you'll never have to look back. It's far better than putting up with some rift-raft library out there that will find excuses not to be portable, or have constraining licenses, or blow up your exe sizes, etc.
stainless at August 30th, 2013 04:31 — #5
Thanks Vilem, but I have to code for platform independence at a binary level, ie. no compile time flags.
SIMD is a not an option, and as Reed has already noticed, it's counter productive on a hell of a lot of platforms.
My stuff used to be very efficient, but I have noticed that some of the methods are invalidating the cache now when they didn't used to, and they seem to have got bigger as well.
I really don't have the time to investigate why and fix it. usual problem, too much work, not enough time.
Now I am doing more OpenGLES 2 stuff, and efficient maths library is much more important than it used to be.
Before I could just use glTranslatef, glRotatef, glPushMatrix, et al.
Now I have to code all of those myself, not a complex task at all, in fact I just took my old code from my software rasteriser and dropped it in.
TheNut, I think you are right. I'm just going to have to find some time aren't I? :wacko:
vilem_otte at September 1st, 2013 21:54 — #6
#Reedbeta - actually the math library I use is a bit more complicated (it has float4x4 - SoA float, etc.); but it gets brain heavy and messy. Also my math libraries are primarily targeted for multi-core x86_64 Linux machines (with OpenCL device inside). So I don't need to develop for "ugly" platforms.
As for SIMD in game engine. I just miss the fact that all rendering on GPU is actually done in SIMD (vectorized) nature - but apart from rendering it depends on what you gonna do. Do you need some insane ray casting into scene determining visibility (several MRays/s) - it helps, a lot. For physics - again it depends a lot on what you do (and if you aim for high precision, you should stay away from floats as far as possible - but anyways using integer registers here help too -> fixed point vectorized computations are viable for high precision physics). So all in all it depends on what your game/app should do.
Also my math library didn't aim for creating clean library - it aim for creating library that could be used (and is used) for real time CPU ray tracing. Performance was more important goal than clean code. But I think it still is in some borders and not as huge mess as some previous ones (I got even ancient one written directly in x86 assembly - now thats what I call ugly code).
This also mostly answers TheNut's note - it is low level for a purpose. Also I'd like to note that it is portable, but needs re-compilation with different flags. I found this way the best so far (running some parametrized shell scripts does the job in an instant) ... of course it hurts once you work in IDE (but I'm one of those guys lovin' his terminal and simple text editor )
stainless at September 3rd, 2013 04:20 — #7
We have all done nasty code for speed, hell I used to have two pieces of tape on all my TV's and monitors.
You change the border colour before and after a routine and use the tape to measure execution time
The trouble with it is that 99% of the time the changes you make are platform dependent. I used self modding code in the render loop on the Atari st, I created a 3D array of pre-muliplied values for the view matrix on the Z80, threw away the operating system and went into supervisor mode on the 68000, used the flat memory model on the n86, ... the list is endless.
I can no longer do any platform dependencies. My code runs on so many devices I have to use a bare minimum of requirements.
I never use textures > 1024 pixels , always use POT textures, design input schema's that don't require any specific input devices.
It can be difficult at times.
I really wanted an efficient maths library, but none of the ones I have looked at can work in my environment.