Giter Club home page Giter Club logo

cglm's Introduction

๐ŸŽฅ OpenGL Mathematics (glm) for C


Build Status Documentation Status Codacy Badge Coverage Status Coverage Status

Sponsors on Open Collective Backers on Open Collective


Highly optimized 2D|3D math library, also known as OpenGL Mathematics (glm) for `C`. cglm provides lot of utils to help math operations to be fast and quick to write. It is community friendly, feel free to bring any issues, bugs you faced.


๐Ÿ“š Documentation

Almost all functions (inline versions) and parameters are documented inside the corresponding headers.
Complete documentation: http://cglm.readthedocs.io

๐Ÿ“Œ Note for previous versions:

  • _dup (duplicate) is changed to _copy. For instance glm_vec_dup -> glm_vec3_copy
  • OpenGL related functions are dropped to make this lib platform/third-party independent
  • make sure you have latest version and feel free to report bugs, troubles
  • [bugfix] euler angles was implemented in reverse order (extrinsic) it was fixed, now they are intrinsic. Make sure that you have the latest version
  • [major change] by starting v0.4.0, quaternions are stored as [x, y, z, w], it was [w, x, y, z] in v0.3.5 and earlier versions
  • [api rename] by starting v0.4.5, glm_simd functions are renamed to glmm_
  • [new option] by starting v0.4.5, you can disable alignment requirement, check options in docs.
  • [major change] by starting v0.5.0, vec3 functions use glm_vec3_ namespace, it was glm_vec_ until v0.5.0
  • [major change] by starting v0.5.1, built-in alignment is removed from vec3 and mat3 types
  • [major change] by starting v0.7.3, inline print functions are disabled in release/production mode to eliminate print costs (see options in documentation). Print output also improved. You can disable colors if you need (see documentation)
  • [major change] by starting v0.8.3, cglm supports alternative clipspace configurations e.g. Left Handed, Zero-to-One (_zo)... CGLM_FORCE_DEPTH_ZERO_TO_ONE and CGLM_FORCE_LEFT_HANDED is provided to control clipspace. You should be able to use cglm with Vulkan, DirectX and Metal now... see https://cglm.readthedocs.io/en/latest/opt.html#clipspace-option-s

๐Ÿ“Œ Note for C++ developers:

If you are not aware of the original GLM library yet, you may also want to look at: https://github.com/g-truc/glm

๐Ÿ“Œ Note for new comers (Important):

  • vec4 and mat4 variables must be aligned. (There will be unaligned versions later)
  • in and [in, out] parameters must be initialized (please). But [out] parameters not, initializing out param is also redundant
  • All functions are inline if you don't want to use pre-compiled versions with glmc_ prefix, you can ignore build process. Just include headers.
  • if your debugger takes you to cglm headers then make sure you are not trying to copy vec4 to vec3 or alig issues...
  • Welcome!

๐Ÿ“Œ Note for experienced developers:

  • Since I'm testing this library in my projects, sometimes bugs occurs; finding that bug[s] and making improvements would be more easy with multiple developer/contributor and their projects or knowledge. Consider to make some tests if you suspect something is wrong and any feedbacks, contributions and bug reports are always welcome.

๐Ÿ“Œ Allocations?

cglm doesn't alloc any memory on heap. So it doesn't provide any allocator. You should alloc memory for out parameters too if you pass pointer of memory location. Don't forget that vec4 (also quat/versor) and mat4 must be aligned (16-bytes), because cglm uses SIMD instructions to optimize most operations if available.

๐Ÿ“Œ Returning vector or matrix... ?

cglm supports both ARRAY API and STRUCT API, so you can return structs if you utilize struct api (glms_).


Like some other graphics libraries (especially OpenGL) this library use Column-Major layout to keep matrices in the memory.
ย 
In the future the library may support an option to use row-major layout, CURRENTLY if you need to row-major layout you will need to transpose it.

๐Ÿš€ Features

  • scalar and simd (sse, avx, neon...) optimizations
  • option to use different clipspaces e.g. Left Handed, Zero-to-One... (currently right handed negative-one is default)
  • array api and struct api, you can use arrays or structs.
  • general purpose matrix operations (mat4, mat3)
  • chain matrix multiplication (square only)
  • general purpose vector operations (cross, dot, rotate, proj, angle...)
  • affine transformations
  • matrix decomposition (extract rotation, scaling factor)
  • optimized affine transform matrices (mul, rigid-body inverse)
  • camera (lookat)
  • projections (ortho, perspective)
  • quaternions
  • euler angles / yaw-pitch-roll to matrix
  • extract euler angles
  • inline or pre-compiled function call
  • frustum (extract view frustum planes, corners...)
  • bounding box (AABB in Frustum (culling), crop, merge...)
  • bounding sphere
  • project, unproject
  • easing functions
  • curves
  • curve interpolation helpers (SMC, deCasteljau...)
  • helpers to convert cglm types to Apple's simd library to pass cglm types to Metal GL without packing them on both sides
  • ray intersection helpers
  • and others...

You have two options to call a function/operation: inline or library call (link) Almost all functions are marked inline (always_inline) so compiler will probably inline. To call pre-compiled versions, just use glmc_ (c stands for 'call') instead of glm_.

  #include <cglm/cglm.h>   /* for inline */
  #include <cglm/call.h>   /* for library call (this also includes cglm.h) */

  mat4 rot, trans, rt;
  /* ... */
  glm_mul(trans, rot, rt);  /* inline */
  glmc_mul(trans, rot, rt); /* call from library */

Most of math functions are optimized manually with SSE2 if available, if not? Dont worry there are non-sse versions of all operations

You can pass matrices and vectors as array to functions rather than get address.

  mat4 m = {
    1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1
  };

  glm_translate(m, (vec3){1.0f, 0.0f, 0.0f});

Library contains general purpose mat4 mul and inverse functions, and also contains some special forms (optimized) of these functions for affine transformations' matrices. If you want to multiply two affine transformation matrices you can use glm_mul instead of glm_mat4_mul and glm_inv_tr (ROT + TR) instead glm_mat4_inv

/* multiplication */
mat4 modelMat;
glm_mul(T, R, modelMat);

/* othonormal rot + tr matrix inverse (rigid-body) */
glm_inv_tr(modelMat);

Struct API

The struct API works as follows, note the s suffix on types, the glms_ prefix on functions and the GLMS_ prefix on constants:

#include <cglm/struct.h>

mat4s mat = GLMS_MAT4_IDENTITY_INIT;
mat4s inv = glms_mat4_inv(mat);

Struct functions generally take their parameters as values and return their results, rather than taking pointers and writing to out parameters. That means your parameters can usually be const, if you're into that.

The types used are actually unions that allow access to the same data multiple ways. One of those ways involves anonymous structures, available since C11. MSVC also supports it for earlier C versions out of the box and GCC/Clang do if you enable -fms-extensions. To explicitly enable these anonymous structures, #define CGLM_USE_ANONYMOUS_STRUCT to 1, to disable them, to 0. For backward compatibility, you can also #define CGLM_NO_ANONYMOUS_STRUCT (value is irrelevant) to disable them. If you don't specify explicitly, cglm will do a best guess based on your compiler and the C version you're using.

๐Ÿ”จ Build

CMake (All platforms)

$ mkdir build
$ cd build
$ cmake .. # [Optional] -DCGLM_SHARED=ON
$ make
$ sudo make install # [Optional]
Cmake options with Defaults:
option(CGLM_SHARED "Shared build" ON)
option(CGLM_STATIC "Static build" OFF)
option(CGLM_USE_C99 "" OFF) #ย C11 
option(CGLM_USE_TEST "Enable Tests" OFF) #ย for make check - make test

Use as header-only library with your CMake project

This requires no building or installation of cglm.

  • Example:
cmake_minimum_required(VERSION 3.8.2)

project(<Your Project Name>)

add_executable(${PROJECT_NAME} src/main.c)
target_link_libraries(${LIBRARY_NAME} PRIVATE
  cglm_headers)

add_subdirectory(external/cglm/ EXCLUDE_FROM_ALL)

Use with your CMake project

  • Example:
cmake_minimum_required(VERSION 3.8.2)

project(<Your Project Name>)

add_executable(${PROJECT_NAME} src/main.c)
target_link_libraries(${LIBRARY_NAME} PRIVATE
  cglm)

add_subdirectory(external/cglm/)

# or you can use find_package to configure cglm

Use CMake to build for WebAssembly

Since math functions like sinf is used, this can not be targeted at wasm32-unknown-unknown, one of wasi-sdk or emscripten should be used.

Should note that shared build is not yet supported for WebAssembly.

For simd128 support, add -msimd128 to CMAKE_C_FLAGS, in command line -DCMAKE_C_FLAGS="-msimd128".

For tests, the cmake option CGLM_USE_TEST would still work, you'll need a wasi runtime for running tests, see our ci config file for a detailed example.

Use CMake and WASI SDK to build for WebAssembly
$ cmake .. \
  -DCMAKE_TOOLCHAIN_FILE=/path/to/wasi-sdk-19.0/share/cmake/wasi-sdk.cmake \
  -DWASI_SDK_PREFIX=/path/to/wasi-sdk-19.0

Where /path/to/wasi-sdk-19.0/ is the path to extracted wasi sdk.

In this case it would by default make a static build.

Use CMake and Emscripten SDK to build for WebAssembly
$ emcmake cmake .. \
  -DCMAKE_EXE_LINKER_FLAGS="-s STANDALONE_WASM" \
  -DCGLM_STATIC=ON

The emcmake here is the cmake wrapper for Emscripten from installed emsdk.

Meson (All platforms)

$ meson build # [Optional] --default-library=static
$ cd build
$ ninja
$ sudo ninja install # [Optional]
Meson options with Defaults:
c_std=c11
buildtype=release
default_library=shared
build_tests=true #ย to run tests: ninja test

Use with your Meson project

  • Example:
# Clone cglm or create a cglm.wrap under <source_root>/subprojects
project('name', 'c')

cglm_dep = dependency('cglm', fallback : 'cglm', 'cglm_dep')

executable('exe', 'src/main.c', dependencies : cglm_dep)

Swift (Swift Package Manager)

Currently only default build options are supported. Add cglm dependency to your project:

...
Package( 
  ...
  dependencies: [
    ...
    .package(url: "https://github.com/recp/cglm", .branch("master")),
  ]
  ...
)

Now add cgml as a dependency to your target. Product choices are:

  • cglm for inlined version of the library which can be linked only statically
  • cglmc for a compiled version of the library with no linking limitation
...
.target(
  ...
  dependencies: [
    ...
    .product(name: "cglm", package: "cglm"),
  ]
  ...
)
...

Unix (Autotools)

$ sh autogen.sh
$ ./configure
$ make
$ make check # [Optional]
$ [sudo] make install # [Optional]

This will also install pkg-config files so you can use pkg-config --cflags cglm and pkg-config --libs cglm to retrieve compiler and linker flags.

The files will be installed into the given prefix (usually /usr/local by default on Linux), but your pkg-config may not be configured to actually check there. You can figure out where it's looking by running pkg-config --variable pc_path pkg-config and change the path the files are installed to via ./configure --with-pkgconfigdir=/your/path. Alternatively, you can add the prefix path to your PKG_CONFIG_PATH environment variable.

Windows (MSBuild)

Windows related build file and project files are located in win folder, make sure you are inside cglm/win folder. Code Analysis is enabled, so it may take awhile to build.

$ cd win
$ .\build.bat

if msbuild won't work (because of multi version VS) then try to build with devenv:

$ devenv cglm.sln /Build Release

Running Tests on Windows

You can see test project in same visual studio solution file. It is enough to run that project to run tests.

Building Docs

First you need install Sphinx: http://www.sphinx-doc.org/en/master/usage/installation.html then:

$ cd docs
$ sphinx-build source build

it will compile docs into build folder, you can run index.html inside that function.

How to use

If you want to use the inline versions of functions, then include the main header

#include <cglm/cglm.h>

the header will include all headers. Then call the func you want e.g. rotate vector by axis:

glm_vec3_rotate(v1, glm_rad(45), (vec3){1.0f, 0.0f, 0.0f});

some functions are overloaded :) e.g you can normalize vector:

glm_vec3_normalize(vec);

this will normalize vec and store normalized vector into vec but if you will store normalized vector into another vector do this:

glm_vec3_normalize_to(vec, result);

like this function you may see _to postfix, this functions store results to another variables and save temp memory

to call pre-compiled versions include header with c postfix, c means call. Pre-compiled versions are just wrappers.

#include <cglm/call.h>

this header will include all headers with c postfix. You need to call functions with c posfix:

glmc_vec3_normalize(vec);

Function usage and parameters are documented inside related headers. You may see same parameter passed twice in some examples like this:

glm_mat4_mul(m1, m2, m1);

/* or */
glm_mat4_mul(m1, m1, m1);

the first two parameter are [in] and the last one is [out] parameter. After multiplying m1 and m2, the result is stored in m1. This is why we send m1 twice. You may store the result in a different matrix, this is just an example.

Example: Computing MVP matrix

Option 1

mat4 proj, view, model, mvp;

/* init proj, view and model ... */

glm_mat4_mul(proj, view, viewProj);
glm_mat4_mul(viewProj, model, mvp);

Option 2

mat4 proj, view, model, mvp;

/* init proj, view and model ... */

glm_mat4_mulN((mat4 *[]){&proj, &view, &model}, 3, mvp);

How to send matrix to OpenGL

mat4 is array of vec4 and vec4 is array of floats. glUniformMatrix4fv functions accecpts float* as value (last param), so you can cast mat4 to float* or you can pass first column of matrix as beginning of memory of matrix:

Option 1: Send first column

glUniformMatrix4fv(location, 1, GL_FALSE, matrix[0]);

/* array of matrices */
glUniformMatrix4fv(location, 1, GL_FALSE, matrix[0][0]);

Option 2: Cast matrix to pointer type (also valid for multiple dimensional arrays)

glUniformMatrix4fv(location, 1, GL_FALSE, (float *)matrix);

You can pass matrices the same way to other APIs e.g. Vulkan, DX...

Notes

  • This library does not support double type... yet
  • If headers are not working properly with your compiler, IDE please open an issue, because I'm using GCC and clang to test it maybe sometimes MSVC

TODO:

  • Unit tests (In Progress)
  • Unit tests for comparing cglm with glm results
  • Add version info
  • Unaligned operations (e.g. glm_umat4_mul)
  • Extra documentation
  • ARM Neon Arch

Contributors

This project exists thanks to all the people who contribute. [Contribute].

Backers

Thank you to all our backers! ๐Ÿ™ [Become a backer]

Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]

License

MIT. check the LICENSE file

cglm's People

Contributors

acoto87 avatar akaricchi avatar ayham-1 avatar beeverfeever avatar bwhmather avatar chris-f5 avatar duarm avatar easyip2023 avatar fmmazur avatar frostkiwi avatar hartenfels avatar haxpor avatar lambdara avatar legends2k avatar michael-g avatar mxi avatar myfreeer avatar podsvirov avatar raedwulf avatar randy408 avatar recep-aurora avatar recp avatar smumriak avatar superbigio avatar telephone001 avatar v1993 avatar vitassuper avatar waywardmonkeys avatar winter091 avatar zollerboy1 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cglm's Issues

TODOs and Features Queue

General

  • Unit tests (In Progress) [important]
  • ARM Neon Arch (In Progress)
  • Unit tests for comparing cglm with glm results [important]
  • Unaligned operations (e.g. glm_umat4_mul)
  • Extra documentation
  • Performance tests

Quaternion

  • Matrix to Quaternion
  • Euler to Quaternion
  • Rotate vector with quat (we already have glm_vec_rotate(vec, angle, axis))
  • Half precision float (16 bit) support
  • Unit tests

Precision

  • Half precision float (16 bit)
  • Double precision float (64 bit double)

Convenient Functions

There could be inline wrapper for some functions e.g. glm_vec_crossand glm_vec_dot like glm_cross and glm_dot. Original functions must stay where they are. This is not necessary but could help to write code fast and more readable .

One another things there could be convenient functions for operations like this ( it is just example ):

/* v = v1 * v2 + v3 * v4 + v5 * v6 */
vec3 sum;
vec3 tmp, tmp2;

glm_vec_mulv(v1, v2, sum);

glm_vec_mulv(v3, v4, tmp2);
glm_vec_add(tmp2, sum, sum);

glm_vec_mulv(v5, v6, tmp2);
glm_vec_add(tmp2, sum, sum);
/* ... */

It could be something like this:

/* v = v1 * v2 + v3 * v4 + v5 * v6 */
vec3 sum;

glm_vec_mulv(v1, v2, sum);

glm_vec_muladd(v3, v4, sum);
glm_vec_muladd(v5, v6, sum);

/* ... */

this is also not necessary, just my thoughts. In short I mean convenient functions for +=, *=, -=, /=

Also any feature request, feedback or contribution are welcome. We can use this issue collect feature requests and feedbacks

Create AUTHORS file

I didn't want to create/fill authors manually
maybe there is a tool / service which collects Pull Requests
and appends contributor to AUTHORS file if not exists.
Because Github is already knows contributors

added to my TODOs

Install via Package Managers

I created CocoaPods spec, so now Xcode users can import cglm to their project via CocoaPods.

target 'MyApp' do
  # use_frameworks!

  pod 'cglm', '~> 0.4' 

  # or latest version
  pod 'cglm' 
end

If you use use_frameworks! in Podfile, it will create cglm.framework and you will have to include headers as #include <cglm/cglm/cglm.h> or @import cglm;, @import cglm.cglm;, @import cglm.call;, @import cglm.mat4;...

Import framework header syntax:
#import <FrameworkName/Header.h>, since there is extra cglm folder you will need to use cglm twice.

Without use_frameworks! it will create libcglm.a and you can include headers as #include <cglm/cglm.h>

Cocoapods will link cglm to your project automatically.

  • cglm for Cocoapods for Xcode (macOS)
  • cglm for Homebrew (macOS)
  • cglm for Nuget for Visual Studio (Windows)
  • cglm for Linux distros (Fedora, Debian, Ubuntu..)
  • cglm for MSYS2 (Thanks for @podsvirov)
  • cglm for Debian and Ubuntu (Thanks for @lmarz)

Any help for Nuget and Linux packages would be appreciated. Especially I want to automate these in Travis CI and AppVeyor after build is completed.

Rotation Proposal

glm_rotate() applies rotation at origin. I think we could provide a helper for rotating at arbitrary point.

Candidates:

  • glm_rotate_around() - Rotation Around Point
  • glm_rotate_at() - Rotation At Point

I like the second one, I'm going to implement it asap.

After:

glm_rotate_at(model, pivot, angle, axis);

build: autogen.sh permission

Homebrew team wanted me to create an issue about permissions of autogen.sh. FWIW, Build instructions are already placed in README and docs.

autogen.sh file is not set to be executable. It is just a wrapper that calls these commands for you:

  • autoheader,
  • libtoolize,
  • aclocal,
  • autoconf
  • automake

you may need execute permission to execute it (autogen.sh). You have a few options to execute autogen.sh, two of them:

  1. set a execute permission and run it:
$ chmod +x ./autogen.sh
$ ./autogen.sh
  1. use sh to execute it:
$ sh ./autogen.sh

Can not work on Windows 10 (VS2017)

Hello,
When I try to build and use it on my computer ( OS:Windows 10 IDE: Visual Studio 2017 )
but it can not work.
Here are error info:
(I used google translate to translate from Chinese to English,because i do not have English version of Visual Studio.)

1> ------ Startup Generated: Project: Project1, Configuration: Debug Win32 ------
1> cglmtest.cpp
1> c: \ users \ mr.guo \ desktop \ cglm \ cglm \ include \ cglm \ cam.h (323): error C2059: Syntax error: "="
1> c: \ users \ mr.guo \ desktop \ cglm \ cglm \ include \ cglm \ cam.h (324): error C2059: Syntax error: "="
1> c: \ users \ mr.guo \ desktop \ cglm \ cglm \ include \ cglm \ cam.h (325): error C2100: Illegal Indirect Addressing
1> c: \ users \ mr.guo \ desktop \ cglm \ cglm \ include \ cglm \ cam.h (326): error C2100: Illegal Indirect Addressing
1> c: \ users \ mr.guo \ desktop \ cglm \ cglm \ include \ cglm \ cam.h (327): error C2100: Illegal Indirect Addressing
1> c: \ users \ mr.guo \ desktop \ cglm \ cglm \ include \ cglm \ cam.h (328): error C2100: Illegal Indirect Addressing
1> c: \ users \ mr.guo \ desktop \ cglm \ cglm \ include \ cglm \ cam.h (358): warning C4091: "": ignoring the left side of "float"
1> c: \ users \ mr.guo \ desktop \ cglm \ cglm \ include \ cglm \ cam.h (360): error C2059: Syntax error: "="
1> c: \ users \ mr.guo \ desktop \ cglm \ cglm \ include \ cglm \ cam.h (361): error C2100: Illegal Indirect Addressing
1> c: \ users \ mr.guo \ desktop \ cglm \ cglm \ include \ cglm \ cam.h (362): error C2100: Illegal Indirect Addressing
1> c: \ users \ mr.guo \ desktop \ cglm \ cglm \ include \ cglm \ cam.h (378): warning C4091: "": ignoring the left side of "float"
1> c: \ users \ mr.guo \ desktop \ cglm \ cglm \ include \ cglm \ cam.h (380): error C2059: Syntax error: "="
1> c: \ users \ mr.guo \ desktop \ cglm \ cglm \ include \ cglm \ cam.h (381): error C2100: Illegal Indirect Addressing
1> c: \ users \ mr.guo \ desktop \ cglm \ cglm \ include \ cglm \ cam.h (382): error C2100: Illegal Indirect Addressing
1> c: \ users \ mr.guo \ desktop \ cglm \ cglm \ include \ cglm \ cam.h (398): error C2059: Syntax error: "="
1> c: \ users \ mr.guo \ desktop \ cglm \ cglm \ include \ cglm \ cam.h (399): error C2059: Syntax error: "="
1> c: \ users \ mr.guo \ desktop \ cglm \ cglm \ include \ cglm \ cam.h (411): error C2059: Syntax error: "="
1> c: \ users \ mr.guo \ desktop \ cglm \ cglm \ include \ cglm \ cam.h (423): error C2059: Syntax error: "="
1> The operation of generating the project "Project1.vcxproj" completed - failed.
========== Generate: 0 success, 1 failure, 0 latest, 0 skip ==========

This is main function code:

/*cglmtest.cpp*/
#include <stdio.h>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include "shader_c.h"
#include "stb_image.h"
#include <cglm\cglm.h>
#define STB_IMAGE_IMPLEMENTATION

int main(void)
{

	return 0;
}

Please help me and please do not mind my poor English.
Thanks!

Bug in vec2 implementation

I detected bugs in the implementations of some vec2 functions.
At the moment, there is at least glm_normalize, glm_vec_normalize and glm_vec_norm

It seems that there are no specialized vec2 functions, so the vec3 ones are utilized. Therefore, these functions uses unpredictable third coordinates instead of a z coordinate set to zero.

Trouble Installing

I am trying to install on a different machine now (mac). When I run sh autogen.sh, I get the following:

autogen.sh: line 20: autoheader: command not found
autogen.sh: line 21: libtoolize: command not found
autogen.sh: line 22: aclocal: command not found
autogen.sh: line 23: autoconf: command not found
autogen.sh: line 24: automake: command not found

How can use the function in your cglm library to make mat4 to Glfloat?

Today,i still learn the OpenGL from https://learnopengl.com/#!Getting-started/Transformations
(the Chinese version: https://learnopengl-cn.github.io/01%20Getting%20started/07%20Transformations/ )

the guide book is using c++ (the glm library) and i try to use your cglm library instead of it.

When i try to define variables mat4 a,use your function like glm_rotate to calc,the guide book tell me that i need to make mat4 to Glfloat to use the OpenGL function.But i can not find a way to make mat4 to Glfloat?I use search tool to search your guide book,but i do not find anything...

The OpenGL guide book code is:

glm::mat4 trans;
trans = glm::rotate(trans, glm::radians(90.0f), glm::vec3(0.0, 0.0, 1.0));
trans = glm::scale(trans, glm::vec3(0.5, 0.5, 0.5)); 
unsigned int transformLoc = glGetUniformLocation(ourShader.ID, "transform");
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));

My code is

mat4 trans;
vec3 a = { 0.0, 0.0, 1.0 };
glm_rotate(trans, glm_rad(90.0f), a);
vec3 b = { 0.5, 0.5, 0.5 };
glm_scale(trans,b);
unsigned int transformLoc = glGetUniformLocation(ID, "transform");
//because i do not know how to make mat4 to Glfloat,so i comment it.
//glUniformMatrix4fv(transformLoc, 1, GL_FALSE, trans);

So can you help me and give me some idea to solve it when you have free time?Thanks!!!
Please do not mind my poor English and my poor code.

Support for unaligned memory

Currently all mat4 and vec4 operations need memory to aligned 16 because of SSE/AVX instructions, this library may support unaligned memory operations, this would beuseful when using library on non-library type e.g. float[4][4]:

for instance:
needs aligned:

glm_mat4_mul(  )

no aligment required:

glm_mat4u_mul(  )

matrix inverse must be transposed

current implementation of matrix inverse must be transposed (plain & simd),

know realized that I was implemented col-major matrix inverse as row-major inverse :(

  • column major matrix inverse (plain)
  • column major matrix inverse (simd)

name change for glm_euler_sq

Hi,

This is a minor suggestion. I find glm_euler_sq a little misleading as a name since the accepted convention in c (and other languages) is for "sq" as an abbreviation to usually mean square or squared (e.g. sqrt()). Why don't you change the name to glm_euler_seq? It is only a character longer but it conveys the meaning much more clearly. Alternatively, since I suspect this enum won't be used very often you could also go with glm_euler_sequence without the need of shortening the name.

squared distance

Hi,
I am ready with a PR for a glm_vec4_distance_squared() function with support for SIMD, call and struct. I propose renaming the function distance_squared as opposed to distance2 like it currently is. Obviously I have #defines that allow calls to distance2 to be compiled successfully, but I think the distance2() name should be deprecated in favor of distance_squared(). If it is ok for you, I will send you a PR.

Building with emscripten.

Looks like there is an issue with the order and spaghetti of the headers.

This fixed the issue for me.

diff --git a/include/cglm/cglm.h b/include/cglm/cglm.h
index 52c7e97..d3fdce6 100644
--- a/include/cglm/cglm.h
+++ b/include/cglm/cglm.h
@@ -11,12 +11,12 @@
 #include "common.h"
 #include "vec3.h"
 #include "vec4.h"
+#include "quat.h"
 #include "mat4.h"
 #include "mat3.h"
 #include "affine.h"
 #include "cam.h"
 #include "frustum.h"
-#include "quat.h"
 #include "euler.h"
 #include "plane.h"
 #include "box.h"
cheako@debian:~/src/github/cglm$ sh autogen.sh 
libtoolize: putting auxiliary files in '.'.
libtoolize: linking file './ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'.
libtoolize: linking file 'm4/libtool.m4'
libtoolize: linking file 'm4/ltoptions.m4'
libtoolize: linking file 'm4/ltsugar.m4'
libtoolize: linking file 'm4/ltversion.m4'
libtoolize: linking file 'm4/lt~obsolete.m4'
libtoolize: Consider adding '-I m4' to ACLOCAL_AMFLAGS in Makefile.am.
configure.ac:22: installing './ar-lib'
configure.ac:18: installing './compile'
configure.ac:27: installing './config.guess'
configure.ac:27: installing './config.sub'
configure.ac:11: installing './install-sh'
configure.ac:11: installing './missing'
makefile.am: installing './depcomp'
parallel-tests: installing './test-driver'
cheako@debian:~/src/github/cglm$ CC=emcc ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for gcc... emcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether emcc accepts -g... yes
checking for emcc option to accept ISO C89... none needed
checking whether emcc understands -c and -o together... yes
checking for style of include used by make... GNU
checking dependency style of emcc... gcc3
checking for ar... ar
checking the archiver (ar) interface... ar
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking how to print strings... printf
checking for a sed that does not truncate output... /bin/sed
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for fgrep... /bin/grep -F
checking for ld used by emcc... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 1572864
checking how to convert x86_64-pc-linux-gnu file names to x86_64-pc-linux-gnu format... func_convert_file_noop
checking how to convert x86_64-pc-linux-gnu file names to toolchain format... func_convert_file_noop
checking for /usr/bin/ld option to reload object files... -r
checking for objdump... objdump
checking how to recognize dependent libraries... pass_all
checking for dlltool... no
checking how to associate runtime and link libraries... printf %s\n
checking for archiver @FILE support... @
checking for strip... strip
checking for ranlib... ranlib
checking command to parse /usr/bin/nm -B output from emcc object... failed
checking for sysroot... no
checking for a working dd... /bin/dd
checking how to truncate binary pipes... /bin/dd bs=4096 count=1
checking for mt... mt
checking if mt is a manifest tool... no
checking how to run the C preprocessor... emcc -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for dlfcn.h... yes
checking for objdir... .libs
checking if emcc supports -fno-rtti -fno-exceptions... yes
checking for emcc option to produce PIC... -fPIC -DPIC
checking if emcc PIC flag -fPIC -DPIC works... yes
checking if emcc static flag -static works... yes
checking if emcc supports -c -o file.o... yes
checking if emcc supports -c -o file.o... (cached) yes
checking whether the emcc linker (/usr/bin/ld) supports shared libraries... yes
checking whether -lc should be explicitly linked in... yes
checking dynamic linker characteristics... ERROR:root:no input files
note that input files without a known suffix are ignored, make sure your input files end with one of: ('.c', '.C', '.i', '.cpp', '.cxx', '.cc', '.c++', '.CPP', '.CXX', '.CC', '.C++', '.ii', '.m', '.mi', '.mm', '.mii', '/dev/null', '.bc', '.o', '.obj', '.lo', '.dylib', '.so', '.a', '.ll', '.h', '.hxx', '.hpp', '.hh', '.H', '.HXX', '.HPP', '.HH')
GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... yes
checking for floor in -lm... yes
checking for special C compiler options needed for large files... no
checking for _FILE_OFFSET_BITS value needed for large files... unknown
checking for _LARGE_FILES value needed for large files... unknown
checking limits.h usability... yes
checking limits.h presence... yes
checking for limits.h... yes
checking stddef.h usability... yes
checking stddef.h presence... yes
checking for stddef.h... yes
checking for stdint.h... (cached) yes
checking for stdlib.h... (cached) yes
checking for string.h... (cached) yes
checking for stdbool.h that conforms to C99... yes
checking for _Bool... yes
checking for inline... inline
checking for int32_t... yes
checking for int64_t... yes
checking for size_t... yes
checking for uint16_t... yes
checking for uint32_t... yes
checking for uint64_t... yes
checking for uint8_t... yes
checking for error_at_line... no
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating makefile
config.status: creating config.h
config.status: executing depfiles commands
config.status: executing libtool commands
cheako@debian:~/src/github/cglm$ make
(CDPATH="${ZSH_VERSION+.}:" && cd . && /bin/bash /home/cheako/src/github/cglm/missing autoheader)
rm -f stamp-h1
touch config.h.in
cd . && /bin/bash ./config.status config.h
config.status: creating config.h
make  all-am
make[1]: Entering directory '/home/cheako/src/github/cglm'
depbase=`echo src/euler.lo | sed 's|[^/]*$|.deps/&|;s|\.lo$||'`;\
/bin/bash ./libtool  --tag=CC   --mode=compile emcc -DHAVE_CONFIG_H -I.    -Wall -std=gnu99 -O3 -Wstrict-aliasing=2 -fstrict-aliasing -pedantic -g -O2 -MT src/euler.lo -MD -MP -MF $depbase.Tpo -c -o src/euler.lo src/euler.c &&\
mv -f $depbase.Tpo $depbase.Plo
libtool: compile:  emcc -DHAVE_CONFIG_H -I. -Wall -std=gnu99 -O3 -Wstrict-aliasing=2 -fstrict-aliasing -pedantic -g -O2 -MT src/euler.lo -MD -MP -MF src/.deps/euler.Tpo -c src/euler.c  -fPIC -DPIC -o src/.libs/euler.o
In file included from src/euler.c:8:
In file included from src/../include/cglm/cglm.h:14:
In file included from src/../include/cglm/mat4.h:48:
In file included from src/../include/cglm/quat.h:59:
src/../include/cglm/affine-mat.h:157:3: error: implicit declaration of function
      'glm_mat4_pick3t' is invalid in C99
      [-Werror,-Wimplicit-function-declaration]
  glm_mat4_pick3t(mat, r);
  ^
src/../include/cglm/affine-mat.h:158:3: error: implicit declaration of function
      'glm_mat4_ins3' is invalid in C99
      [-Werror,-Wimplicit-function-declaration]
  glm_mat4_ins3(r, mat);
  ^
src/../include/cglm/affine-mat.h:158:3: note: did you mean 'glm_mat3_inv'?
src/../include/cglm/mat3.h:281:1: note: 'glm_mat3_inv' declared here
glm_mat3_inv(mat3 mat, mat3 dest) {
^
In file included from src/euler.c:8:
In file included from src/../include/cglm/cglm.h:14:
src/../include/cglm/mat4.h:179:1: error: static declaration of 'glm_mat4_pick3t'
      follows non-static declaration
glm_mat4_pick3t(mat4 mat, mat3 dest) {
^
src/../include/cglm/affine-mat.h:157:3: note: previous implicit declaration is
      here
  glm_mat4_pick3t(mat, r);
  ^
In file included from src/euler.c:8:
In file included from src/../include/cglm/cglm.h:14:
src/../include/cglm/mat4.h:201:1: error: static declaration of 'glm_mat4_ins3'
      follows non-static declaration
glm_mat4_ins3(mat3 mat, mat4 dest) {
^
src/../include/cglm/affine-mat.h:158:3: note: previous implicit declaration is
      here
  glm_mat4_ins3(r, mat);
  ^
4 errors generated.
ERROR:root:compiler frontend failed to generate LLVM bitcode, halting
makefile:876: recipe for target 'src/euler.lo' failed
make[1]: *** [src/euler.lo] Error 1
make[1]: Leaving directory '/home/cheako/src/github/cglm'
makefile:668: recipe for target 'all' failed
make: *** [all] Error 2
cheako@debian:~/src/github/cglm$ 

Type Safe Implementation

What is the stance on a type-safe wrapper that utilizes structs or unions instead of arrays?

Is there any interest in a wrapper (kind of like the call "wrapper") that adds type safety?

glm_vec4_copy segfaults with unaligned memory

I want to notify that glm_vec4_copy crashes if SSE2 is enabled and operates on a vector saved in misaligned memory!

It seems the instruction _mm_store_ps segfaults if it operates on non-aligned memory.

I had a struct the size of 20 bytes before an array of vectors and it crashed.
After padding the struct to 24 bytes everything worked perfectly.

I think CGLM should check if memory is aligned or just add it in the documentation as a big warning!

SIMD shuffle optimization

It seems using pshufd instead of shufps can save some move instructions. But pshufd is in integer domain and shufps is in float. It seems we get correct results with pshufd too. But there are some discussions about bypass delay (I'm still investigating). I tested on my machine results seem identical. Since the results are identical why don't we save some instructions to save binary size?

Matrix multiplication with shufps = 68 instruction
Matrix multiplication with pshufd = 56 instruction

Quaternion-to-matrix identity rotated

I'm seeing the following behavior for quaternion to matrix conversion.

versor rotation = GLM_QUAT_IDENTITY_INIT;
fprintf(stderr, "-- Quaternion --\n%.4f %.4f %.4f %.4f\n\n", rotation[0], rotation[1], rotation[2], rotation[3]);

mat4 rotMatrix = GLM_MAT4_IDENTITY_INIT;
glm_quat_mat4(rotation, rotMatrix);
fprintf(stderr, "-- Matrix --\n%.4f %.4f %.4f %.4f\n%.4f %.4f %.4f %.4f\n%.4f %.4f %.4f %.4f\n%.4f %.4f %.4f %.4f\n", rotMatrix[0][0], rotMatrix[0][1], rotMatrix[0][2], rotMatrix[0][3], rotMatrix[1][0], rotMatrix[1][1], rotMatrix[1][2], rotMatrix[1][3], rotMatrix[2][0], rotMatrix[2][1], rotMatrix[2][2], rotMatrix[2][3], rotMatrix[3][0], rotMatrix[3][1], rotMatrix[3][2], rotMatrix[3][3]);

outputs

-- Quaternion --
0.0000 0.0000 0.0000 1.0000

-- Matrix --
-1.0000 0.0000 0.0000 0.0000
0.0000 -1.0000 0.0000 0.0000
0.0000 0.0000 1.0000 0.0000
0.0000 0.0000 0.0000 1.0000

The identity quaternion is what I expect, but the matrix seems to be flipped 180 degrees on X and Y. I noticed this because everything I render is flipped upside down. Shouldn't rotMatrix[0][0] and rotMatrix[1][1] equal positive 1 instead of negative 1 when using an identity quaternion? Or maybe I don't understand quaternions fully.

Platform:
Linux 64-bit
gcc v7.2.1
cglm v0.3.1

transform vec3 with mat4

A few helpers available for transforming vec3 with mat4

  • glm_mat4_mulv3
  • glm_vec_rotate_m4

but both use rotation part. The second one already applies rotation (ignores scaling) and the first one could apply translation too. I'm going to change glm_mat4_mulv3 behavior to apply translation like

result = vec3(mat4 * vec4(inputVector, 1.0))

Current signature of func :

glm_mat4_mulv3(mat4 m, vec3 v, vec3 dest)

it could be:

glm_mat4_mulv3(mat4 m, vec3 v, float last, vec3 dest)

so if user don't want to translation part then passing last parameter as 0.0 (zero) will do that job. Passing last as 1.0 will include translation too. I think this will make things flexible

Can't install on my system.

Hello,

I have a Mac. I'm having trouble installing this on my system, although I have run sh build-deps.sh multiple times (although I removed the directory and re-cloned from git each time I tried).

I know I haven't provided much information, but I really don't know what info to provide.

One thing I thought was rather strange is that build-deps.sh was outputting this:

-- Looking for io.h
-- Looking for io.h - not found
-- Looking for malloc.h
-- Looking for malloc.h - not found

Sorry for minimal info provided, but if anyone can tell me what info I should provide, to troubleshoot this, that would be fantastic. Thanks for reading.

The argument order of glmm_store3() and glmm_store() is not consistent.

glm_store3() arguments are swapped compared to glm_store().
Luckily glm_store3() doesn't seem to be used anywhere in the codebase.
Making it consistent with glm_store() would be trivial and it would not break anything.

I propose changing the argument order of glm_store3() so that the float pointer/array (destination) comes 1st and the 128-bit SSE vector argument (source) comes 2nd.

Notice that both SSE and Neon intrinsics follow the same convention.
(float pointer/array 1st, SIMD vector 2nd)

TODO: Pre-Compiled Library

This library could provide a pre-compiled version of all funcs,

some functions are too long and they may cause increase code side
significantly

[Question] Why only vec3 in this particular line use CGLM_ALIGN(16) instead of CGLM_ALIGN(8)

I'm curious why this only line using CGLM_ALIGN(16) instead of CGLM_ALIGN(8) as the latter is used all across the board for all other vec3 declaration.

I probably miss and didn't have intuition about something here. But would love to understand this as now my wires to the following according to some studying at the cglm source code.

vec3 -> CGLM_ALIGN(8)
vec4 -> CGLM_ALIGN(16)
mat3 -> CGLM_ALIGN_MAT (depends on whether AVX is supported, 32 if support, 16 if not)
mat4 -> CGLM_ALIGN_MAT (depends on whether AVX is supported, 32 if support, 16 if not)
versor -> CGLM_ALIGN(16)

Thanks!

Feedbacks for vec3 update

  • Do we want to change glm_vec_ namespace to glm_vec3_?
  • I want to rename glm_vec_flipsign() to glm_vec_negate() and deprecate glm_vec_flipsign() in favor of negate
  • glm_vec_inv() inverts sign of components (same as negate) but probably it should invert vector components like glMatrix.js (https://github.com/toji/gl-matrix/blob/master/src/vec3.js#L321)? :
CGLM_INLINE
void
glm_vec_inv_to(vec3 v, vec3 dest) {
  dest[0] = 1.0f / dest[0];
  dest[1] = 1.0f / dest[1];
  dest[2] = 1.0f / dest[2];
}
  • it seems cglm should support vec2 functions too ( #66 )

Any other feedback, bug or feature request? Or what do you think about these changes?

Strange behavior glm_lookat

I am adding a map editing mode, so the camera will look down on the world

These two versions work perfectly:

glm_lookat((vec3){100,30,100},(vec3){100,0,100.1},WORLD_VECTOR_UP,camera_view_matrix);
glm_lookat((vec3){100,30,100},(vec3){100,0,99.9},WORLD_VECTOR_UP,camera_view_matrix);

The output of 100.1 is:

Matrix (float4x4):
|-1.0000 0.0000 0.0000 100.0000|
|0.0000 0.0033 1.0000 -100.0994|
|-0.0000 1.0000 -0.0033 -29.6665|
|0.0000 0.0000 0.0000 1.0000|

But when I try to look exactly down from an altitude of 30:
glm_lookat((vec3){100,30,100},(vec3){100,0,100},WORLD_VECTOR_UP,camera_view_matrix);

The output is:

Matrix (float4x4):
|0.0000 0.0000 0.0000 -0.0000|
|0.0000 0.0000 -0.0000 -0.0000|
|-0.0000 1.0000 -0.0000 -30.0000|
|0.0000 0.0000 0.0000 1.0000|

And it obviously doesn't render anymore.
Is it expected behavior and I am missing something or is it a bug?

Functions don't use const when possible

Due to functions not taking arguments as const when possible (ie. when a variable is never written to), it's very tough to integrate CGLM with code that passes vector/matrix types as const. Since constant variables cannot be cast to non-const, this means any code that calls CGLM can't use constant variables.

Since it's possible to cast to const, but not from, would it be possible to mark read-only function arguments as const?

wrong euler angles order

It seems euler angles implemented in reverse order of intrinsic rotation which makes it extrinsic rotation. But cglm docs says that these rotations are intrinsic

If the euler order is wrong then it must be fixed asap. All we need to do is change functions names. Check also g-truc/glm#744

glm_mat4_inv precision

Currently glm_mat4_inv uses _mm_rcp_ps instruction (as default) to divide matrix by determinant. It is faster than division but there is a cost, we lost precision.

There is also glm_mat4_inv_precise version which is not using _mm_rcp_ps instruction, instead it uses division so it is more accurate but how many users are aware of this? Probably they will use the default behavior and lost precision and they will not have any idea what's going on

Maybe the accurate / precise version should be default and we could rename fast / inaccurate version as glm_mat4_inv_fast?

This seems good idea

Binary Constants in AVX implementations

While playing with various compiler flags on my machine with AVX support, I noticed that you are using binary constants in the mm256_permute functions, which are GCC extensions. This could lead to some problems when trying to compile on MSVC, but it is also not supported when using ISO C99.

The question is now if we should just change these to hex constants or do something like this to make it more readable:

#if _GNUC_
  s1 = 0b00000011;
#else
  s1 = 0x3;
#endif
y4 = _mm256_permute2f128_ps(y2, y2, s1);

Compatibility with original glm

Hello,

  1. How feature-complete cglm is compared to glm?
  2. Does cglm behave identically to glm (in the sense that the corresponding functions do the same thing as in glm)?

Thx

Why are matrices 2-d arrays instead of 1-d?

Hi, this is not an issue so much as just a question I have. Why are matrices represented as an array[m][n] instead of a flat array[m*n]? It seems like doing it the second way would be better for performance since it takes up less memory and doesn't require as many dereferences to access, and you can still trivially get individual vectors out of flat-array-represented matrices.

Compiling on the Raspberry PI

Hi there,

I was trying to compile cglm on my Raspberry PI, and after installing autotools and libtool I proceed to make.

When I make the project it throw at first the following error:

src/../include/cglm/mat4.h:173:48: error: unknown type name โ€˜size_tโ€™
 glm_mat4_identity_array(mat4 * __restrict mat, size_t count) {
                                                ^~~~~~

I failed to find where do the compiler was trying to grab the header file with that definition (size_t is defined in multiple standard headers) and since I see that common.h is only including:

#include <stdint.h>
#include <math.h>
#include <float.h>

in neither of those files has the declaration for size_t in this platform. So, another header where that type is declared is in stddef.h so I include it, and the error is gone. Specifically, this file was included: /usr/lib/gcc/arm-linux-gnueabihf/6/include/stddef.h.

So, have you think about this issue, that maybe in other platforms other headers need to be included to compile the project?

After that when I do make I got the following warnings (there are similar others):

In file included from src/../include/cglm/cglm.h:19:0,
                 from src/quat.c:8:
src/quat.c: In function โ€˜glmc_quat_rotatevโ€™:
src/../include/cglm/quat.h:749:3: warning: โ€˜*((void *)&p+12)โ€™ may be used uninitialized in this function [-Wmaybe-uninitialized]
   glm_vec3_scale(v2, 2.0f * s, v2);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/../include/cglm/quat.h:736:25: note: โ€˜*((void *)&p+12)โ€™ was declared here
   CGLM_ALIGN(16) versor p;
                         ^

the *((void *)&p+12) comes from the s = glm_quat_real(p); line in the glm_quat_rotatev function that was inlined by the compiler. So, have you see these kind of warnings?

I'm missing something and need to do something else to compile without warnings/errors?

My compiler version:

gcc (Raspbian 6.3.0-18+rpi1+deb9u1) 6.3.0 20170516
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Let me know if you need me to make more tests.

Reflect, code.

/*!
 * @brief reflect vector across a plain identified by it's normal 
 *        and store result in dest
 *
 * @param[in]  I    input
 * @param[in]  N    normalized normal
 * @param[out] dest reflected vector
 */
CGLM_INLINE
void
glm_vec4_reflect(vec4 I, vec4 N, vec4 dest) {
	      vec4 mul1;
#ifdef CGLM_BE_MY_MOM
	      glm_vec4_normalize(N);
#endif
	      glm_vec4_scale(N, glm_vec4_dot(N, I) * 2.0f, mul1);
	      glm_vec4_sub(I, mul1, dest);
}

Euler angles proposal

Ken Shoemake's algorithm seems most common one, it also handles 24 different permutations of rotation order. Maybe instead of providing separate functions for euler angles we could adopt that algorithm / codes.

Related implementation (Graphics Gems IV): https://github.com/erich666/GraphicsGems/tree/master/gemsiv/euler_angle
https://github.com/erich666/GraphicsGems/blob/master/gemsiv/euler_angle/EulerAngles.c

It also provides euler to quaternion which is in our TODO list. I hope there is no any LICENSE conflict

make install fails due to duplicate line in Makefile.am

On Ubuntu 19.10, make install fails at this point :

/usr/bin/install -c -m 644 include/cglm/version.h include/cglm/common.h include/cglm/types.h include/cglm/types-struct.h include/cglm/cglm.h include/cglm/call.h include/cglm/struct.h include/cglm/cam.h include/cglm/io.h include/cglm/mat4.h include/cglm/mat3.h include/cglm/affine.h include/cglm/vec3.h include/cglm/vec3-ext.h include/cglm/vec4.h include/cglm/vec4-ext.h include/cglm/euler.h include/cglm/util.h include/cglm/quat.h include/cglm/affine-mat.h include/cglm/plane.h include/cglm/frustum.h include/cglm/box.h include/cglm/color.h include/cglm/project.h include/cglm/sphere.h include/cglm/ease.h include/cglm/curve.h include/cglm/bezier.h include/cglm/bezier.h include/cglm/applesimd.h '/usr/local/include/cglm'
/usr/bin/install: will not overwrite just-created '/usr/local/include/cglm/bezier.h' with 'include/cglm/bezier.h'
make[1]: *** [Makefile:1033: install-cglmHEADERS] Error 1

This is caused by the duplicate entry for include/cglm/bezier.h in the cglm_HEADERS in Makefile.am

SIMD #1

_mm_rcp_ps vs _mm_div_ps ?

there may be an option between reciprocal approximations or division like (or just preprocessor):

void glm_mat4_inv(mat4 mat, mat4 dest)
void glm_mat4_inv_rcp(mat4 mat, mat4 dest)

or 

#ifdef CGLM_NO_RCP
  x0 = _mm_div_ps(_mm_set1_ps(1.0f), x0);
#else
  x0 = _mm_rcp_ps(x0);
#endif

_mm_rcp_ps:

Performance
Architecture    Latency Throughput
Haswell          5       1
Ivy Bridge       5       1
Sandy Bridge     5       1
Westmere         3       2
Nehalem          3       2

_mm_div_ps:

Performance
Architecture    Latency Throughput
Haswell          13      5
Ivy Bridge       13      6
Sandy Bridge     14      14
Westmere         14      12
Nehalem          14      12

plus _mm_set1_ps(1.0f) cost

this improves rcp_ps' precision:

  x1 = _mm_rcp_ps(x0);

  x0 = _mm_sub_ps(_mm_add_ps(x1, x1),
                   _mm_mul_ps(x0, _mm_mul_ps(x1, x1)));

but with extra cost: 3 + 3 + 5 + 5 = 13 Latency + 5 rcp = 18 Latency

warning: "__SSE2__" redefined

It would be nice to not define __SSE2__ if it's already defined, otherwise the log would fill of warnings:
"warning: "__SSE2__" redefined" for every include of cglm.h.
Mingw-w64 x86_64-7.2.0-posix-seh-rt_v5-rev1 already defines it.
Thanks.

error: undefined reference to 'vaddvq_f32'

I try to build cglm on two abis which are armeabi-v7a and arm64-v8a onto android device that is aarch64. I faced the problem shown with the error same as the title of this issue. Thus only armeabi-v7a cannot be built, the another is fine.

After initial digging it, I found this line defined in vector4.h. It uses NEON function namely vaddvq_f32 which is available only on armv8 (aarch64). I believe that this is not intention as for another place in which there is safety guard implemented in arm.h of these lines.

Please correct me if I'm wrong, or might miss-understand. Anyway, if that's the opposite, I'm willing to do a PR on this (possibly add preprocessor guard + use NEON functions supported by armeabi-v7a instead) but please kindly guide me which NEON functions I should be using instead.

glm_vec_broadcast() ---> glm_vec_fill()

I think all versions of glm_vec_broadcast() should be renamed to glm_vec_fill() which is shorter and more self-explanatory. If you agree I will create a PR.

Crash Exception on VisualStudio2017

Hi my friend, I always encounter a issure like below. when I call something like
glm_translate(model->transforms[0], model->position);

glm_translate(mat4 m, vec3 v) { #if defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(m[3],

My compiler told me exception when access some address.

Can't build release v0.5.3

Below is the output of make:

pi@raspberrypi:~/Development Libraries/cglm $ make
(CDPATH="${ZSH_VERSION+.}:" && cd . && /bin/bash "/home/pi/Development Libraries/cglm/missing" autoheader)
rm -f stamp-h1
touch config.h.in
cd . && /bin/bash ./config.status config.h
config.status: creating config.h
make  all-am
make[1]: Entering directory '/home/pi/Development Libraries/cglm'
  CC       src/euler.lo
In file included from src/../include/cglm/cglm.h:14:0,
                 from src/euler.c:8:
src/../include/cglm/mat4.h:173:48: error: unknown type name โ€˜size_tโ€™
 glm_mat4_identity_array(mat4 * __restrict mat, size_t count) {
                                                ^~~~~~
In file included from src/../include/cglm/cglm.h:15:0,
                 from src/euler.c:8:
src/../include/cglm/mat3.h:113:48: error: unknown type name โ€˜size_tโ€™
 glm_mat3_identity_array(mat3 * __restrict mat, size_t count) {
                                                ^~~~~~
In file included from src/../include/cglm/cglm.h:19:0,
                 from src/euler.c:8:
src/../include/cglm/quat.h:116:48: error: unknown type name โ€˜size_tโ€™
 glm_quat_identity_array(versor * __restrict q, size_t count) {
                                                ^~~~~~
makefile:905: recipe for target 'src/euler.lo' failed
make[1]: *** [src/euler.lo] Error 1
make[1]: Leaving directory '/home/pi/Development Libraries/cglm'
makefile:686: recipe for target 'all' failed
make: *** [all] Error 2

I resolved this issue by adding this into include/cglm/mat4.h:

#include <stdlib.h>

However it still ends with another error I'm not so sure about:

ar: `u' modifier ignored since `D' is the default (see `U')
sh ./post-build.sh
ln: target '.libs/libcmocka.so.0' is not a directory
makefile:1773: recipe for target 'all-local' failed
make[1]: *** [all-local] Error 1
make[1]: Leaving directory '/home/pi/Development Libraries/cglm'
makefile:686: recipe for target 'all' failed
make: *** [all] Error 2

glm_mat4_scale Incorrect

I've encountered an issue with glm_mat4_scale. I'm using it to scale a model and I'm using it like so:
mat4 m = GLM_MAT4_IDENTITY_INIT;
glm_mat4_scale(m, 0.5f);

The 'm' matrix becomes:
0.5 0.0 0.0 0.0
0.0 0.5 0.0 0.0
0.0 0.0 0.5 0.0
0.0 0.0 0.0 0.5

This, however, does not scale the model. I believe that w is supposed to be unchanged. If I add the following after 'glm_mat4_scale', the model scales properly:
m[3][3] = 1.0f;

I'm not that skilled with linear algebra and vector math; so, I apologize if this behaviour is intended and I've just missed something!

Tests

Currently cglm uses cmocka for tests, recently I thought that maybe we can use assert() and make our own test runner. Because the only build dependency is cmocka which is for tests, writing our own runner will make cglm zero-dependency library


After we made tests more stable then all Pull Requests or features must come with test cases (if the changes are related to coding)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.