Skip to content

dangmoody/HLML

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HLML

(High Level Maths Library).

CI

HLML is a maths library for C and C++ focused on games/graphics programming which is loosely styled on HLSL syntax where all vector/matrix types are generated by a tool. This means that there are zero templates in the generated code, which gives the following advantages:

  • Shorter compile times.
  • Easier to read and debug.
  • Ability to forward declare types.

As well as the above, HLML also offers the following:

  • SIMD maths functions (functionality is experimental and still potentially subject to change).
  • Non-uniform matrix types.
  • Boolean vectors/matrices to aid equality checking of vector types.

Currently HLML is written to produce optimised assembly for Clang. If you use another compiler then YMMV.

HLML does not override any maths functions that are a part of C99.

See the "Licenses" section below for details about what licenses HLML uses.

Installation

  1. Go to the releases page and download the latest version.
  2. Unzip the header files into your project (you can use either the C or C++ files, NOT both).

Usage

Include hlml.h.

For more detailed documentation on how to use HLML's experimental SSE functionality, please refer to the SSE document.

Code Examples

C:

Adding 2 vectors:

float3 a = { 1.0f, 2.0f, 3.0f };
float3 b = { 4.0f, 5.0f, 6.0f };

// the "c" part means "component-wise"
// the "v" part means vector
// there are also component-wise arithmetic functions for scalar ("s"), and matrix ("m" - for matrix types only)
float3 c = float3_caddv( &a, &b );

printf( "c is: (%f, %f, %f)", c.x, c.y, c.z );

Creating a Model-View-Projection matrix:

float4x4 model = float4x4_translate( &player_transform, &position );

float4x4 view = float4x4_lookat_lh_zo( &eye, &forward, &world_up );

float4x4 projection = float4x4_perspective_lh_zo( fov, aspect, znear, zfar );

// "float4_mulm" will do matrix multiplication
// "float4_cmulm" will do component-wise multiplication
float4x4 view_projection = float4x4_mulm( &view, &projection );
float4x4 mvp = float4x4_mulm( &model, &view_projection );

C++:

Adding 2 vectors:

float3 a = { 1.0f, 2.0f, 3.0f }; // in C++ you can initialise math types like this
float3 b = float3( 4.0f, 5.0f, 6.0f ); // or like this

float3 c = a + b;

printf( "c is: (%f, %f, %f)", c.x, c.y, c.z );

Creating a Model-View-Projection matrix:

float4x4 model = translate( player_transform, position );

// lh = left handed, zo = zero-to-one depth
// there also exists rh (right-handed) and no (negative-one-to-one) combinations
float4x4 view = lookat_lh_zo( eye, forward, world_up );

float4x4 projection = perspective_lh_zo( fov, aspect, znear, zfar );

// in C++ the multiply operator performs matrix multiplication
// not per-component multiplication
float4x4 view_projection = mul( view, projection );
float4x4 mvp = mul( model, view_projection );

Vector Swizzling (C++ only):

// use as you would in HLSL
// all possible combinations are automatically generated and available
float4 a = { 1.0f, 2.0f, 3.0f, 4.0f };
float4 b = a.xxyy;

Common Pitfalls

READ THIS BEFORE USING HLML:

  • Matrix types are row-major, so a float3x4 is a matrix that holds 3 float4s (or, in other words: a float4 array of size 3).
  • In C++ vector types are a union of struct/fixed-size array.
  • To avoid conflicts with Windows min/max macros, you can #define NOMINMAX before including HLML.

Contributing

If this is a project you'd like to contribute to then see the contribution document.

Alternatively you can just buy me a Diet Coke instead:

ko-fi

Credits

I'd like to dedicate HLML to my Grandad, who helped raise me and taught me to "always keep an open mind", which I always strive my best to do every single day. Grandad was someone who helped me overcome my initial fear of maths as a child, and helped make me the man I am today. He is missed dearly, and always will be.

I'd like to extend my sincerest thank yous to the following people for coming up with cool ideas to help HLML better, finding bugs, and/or contributing code:

  • Antony Bowler
  • David Smith @Flave229
  • Filip Strugar
  • Mike Young
  • Tom Whitcombe
  • @xwize

Your help is very much appreciated. HLML would not be what it is today without your contributions. Thank you. =)

I'd also like to extend credit to the following:

  • GLM - I use some of their solutions for a couple of functions, therefore I take no credit for those.
  • Unity.Mathematics - The idea of using a generator comes from this.

Motivation

I've always primarily used GLM as my maths library of choice, but there were a few things that always bugged me about it:

  • Sometimes had trouble reading past all of the templates.
  • Often have trouble debugging the templates.
  • Typing the namespace all the time got annoying.
  • Often found it frustrating to navigate the API files as everything is split into lots of little separate headers that weren't obviously named (IMO).

(This isn't an attack on GLM, just some of my personal gripes with it).

One day I stumbled upon the Unity.Mathematics library where I saw that all the maths types were being generated via a tool. I decided to try the same but for C and C++: Write a tool that generated maths types for me to see if there were any benefits of doing it that way, and I found that there were:

  • Compile times were shorter due to lack of templates.
  • Being able to just read plain, vanilla C/C++ code. No templates to read past, just very simple, minimal, and straightforward code.
  • Maintaining changes across multiple (if not all) types was a lot easier than imagined. Write the changes into the generator and watch it reflect the change across all the desired generated types automatically.

Licenses

HLML is dual licensed.

All code that is part of the generator is licensed under GNU GPL v3.

All of the generated code (found in the releases) are licensed under MIT license. Please see the respective license files (found in the root of this project) for details.

HLML's generator also makes use of the following libraries, which are under their own respective licenses: