Git Product home page Git Product logo

math3d's Introduction

Math3d

A small header-only math library for vectors and matrices.

Build Status

Build Status
Ubuntu ci-linux
Windows ci-windows

Yet another math library

This library is designed to be a potential replacement to various other great libraries like Eigen and glm, but with a narrow focus on 2, 3, and 4 dimensional vectors and matrices. These appear commonly when using spatial algebra in robotics, which is the main application area this library was initially developed for.

Setup

C++ setup

Clone this package into your third_party dependencies:

# Replace "third_party" with your own dependencies-folder name
git clone https://github.com/wpumacay/math3d.git third_party/math3d

There's a CMake target called math::math. Just add the source directory in your CMake workflow, and use the given target as follows:

# Add the Math3d subdirectory
add(third_party/math3d)

# Link against the exposed math::math target
target_link_library(MY_LIBRARY PRIVATE math::math)

Python setup

Use the provided setup.py file:

python setup.py install

And import the types from the math3d package:

import math3d as m3d

Usage

C++

#include <vec3_t.h>
#include <mat3_t.h>

int main()
{
    // Create a vec3-float32 and show it on the console
    ::math::Vector3f vec = { 1.0f, 2.0f, 3.0f };
    std::cout << "vec: " << vec << std::endl;

    // Create a mat3 float32, show its entries and its inverse
    auto mat = ::math::Matrix3f( 3.0f, 9.0f, 3.0f,
                                 9.0f, 0.0f, 3.0f,
                                 2.0f, 3.0f, 8.0f );

    std::cout << "mat:" << std::endl;
    std::cout << mat << std::endl;
    std::cout << "mat.inverse():" << std::endl;
    std::cout << ::math::inverse( mat ) << std::endl;

    return 0;
}

Python

import numpy as np
from math3d import Vector3f, Matrix3f

# Create a vec3-float32 and show it on the console
vec = Vector3f(np.array([1.0, 2.0, 3.0], dtype=np.float32))
print(vec)

# Create a mat3 float32, show its entries and its inverse
mat = Matrix3f(np.array([[ 3.0, 9.0, 3.0 ],
                         [ 9.0, 0.0, 3.0 ],
                         [ 2.0, 3.0, 8.0 ]], dtype=np.float32))

print(mat)
print("inverse(): \n\r{}".format(mat.inverse()))

math3d's People

Contributors

wpumacay avatar

Watchers

James Cloos avatar  avatar

math3d's Issues

Axis-Angle Data Type (axis_angle_t)

Description

Tracks the implementation of the Axis-Angle Data Type, as another alternative for orientation|rotation representation

Rationale

This tracks the implementation of axis-angle Data Type (axis_angle_t), which is yet another alternative representation of orientation|rotation. This one will also come in handy from the user side, as is very likely that we have a given axis along which we might want to rotate a rigid body

[Bug]: Can't assign numpy array directly

Description

There's an issue when trying to assign a vector or matrix attribute as part of a struct that is exposed by using pybind11. We can access the elements of the vector-matrix in question, but can't directly assign, as we get an error similar to the one below:

TypeError: (): incompatible function arguments. The following argument types are supported:
    1. (self: renderer_bindings.WindowConfig, arg0: math3d_bindings.Vector4f) -> None

This happens for example when doing this:

import math3d as m3d
import renderer as rdr

config = rdr.WindowConfig()
config.clear_color = [0.3, 0.3, 0.3, 1.0]

Segfault when using aligned load and store version of SIMD extensions

Description

We're currently using the unaligned versions of the load (_mm_loadu_ps, _mm256_loadu_pd) and store (_mm_storeu_ps, _mm256_storeu_pd) SIMD intrinsics, as the algined version give a segfault. This is likely to be
an issue with the default alignment of std::array (e.g. std::array<float32_t, 4> ) which is used to hold the vector's data

Vector3 padding breaks usage in OpenGL related calls

Description

Currently we're using padding for vec3_t (1 extra float or double), which was required for aligning properly when we used the aligned versions of SIMD instructions. However, this padding makes this data type unusable for applications where the user requires a continuous layout of elements of a given size.

Example

In this situation we're trying to store vertex data into an std::vector of Vec3. The layout would be the following:

//  -------------------------------------------------------
//  | v.x | v.y | v.z | unused | v.x | v.y | v.z | unused |
//  -------------------------------------------------------

However, the expected attribute for vertex data used in buffer attributes should be contiguous, like the following:

//  -------------------------------------
//  | v.x | v.y | v.z | v.x | v.y | v.z |
//  -------------------------------------

Thus, we'll get weird issues when using vec3_t for vertex data in computer graphics related applications.

Possible fixes

  • The easiest fix is to make vec3_t not use padding. This however bring some issues, like not being able to use SIMD instructions due to not being able to guarantee that an xmm or ymm register will touch only elements of the vector (will read or write data that doesn't belong to the vec3). There are no mask-read or mask-store, so we'd have to disable all SIMD related kernels for both Vec3 and Mat3 types.

Transforms|Pose3D (transform_t) operations

Description

Tracks the implementation of various operations required for handling transform_t data types (see list below):

  • inverse
  • transform-transform operations
  • transform-vector operations
  • transform-matrix operations
  • transform-quaternion operations

Missing support for Python Bindings

Description

There's currently some legacy code that implemented python bindings for our legacy types. We have to refactor/remake this feature based on what we've learned on how other repos handle bindings using pybind11 in their projects (we still have a header-only library, so the resulting code might be quite similar to our legacy implementation)

Documentation for Pose3d

Description

Should add examples of usage and API reference for the pose3d_t type. Use Sphinx for the generation of API ref.

Tasks

  • Add examples of usage for pose3d_t
  • Add auto-generated API reference for pose3d_t

Change Pybind11 dependency to the one from the main repo

Description

We currently use the PyBind11 version from this fork. We chose this fork because it supported using std::unique_ptr in binding code (transfer ownership). We'll move towards using the main repo and use std::shared_ptr instead, as it seems that in most cases in both the renderer and the locomotion framework, we'll have to let the user keep ownership of references.

Tasks

  • Updated Dependencies.cmake to use the version of pybind11 from the principal repository.

Make source distribution for PyPi deployment

Description

The current installation method we provide is by cloning the repo and installing using setuptools via the provided setup.py file. We should add support for installation from PyPI using as first approach source distributions (i.e. providing all the source code to be later compiled when installing from PyPI). We have supported a similar method in the past, so just check the legacy repo and bring back that functionality ๐Ÿ˜„ .

Tasks

  • Create a MANIFEST.in file that includes all source files to be included in the distribution.
  • Upload to PyPI. (Or TestPyPI)
  • Test source distribution locally.
  • Test source distribution on Google Colab.

Add `CI-rules` to compile/test with `SEE` and `AVX`

Description

The current ci-rules (github-actions) only consider the case for scalar functions. Although the builds are made locally to tests against SSE and AVX, we should also add these options to the current rules (github VMs should have support for this instruction sets)

Refactor unittests using custom generators

Description

The current unit tests for various vector and matrix types are using catch2 generators that generate single scalars, and then we're combining them into the appropriate types we need. We should replace this with the custom generators we're using for the unit tests for pose3d_t.

// Generate 3 scalars using catch generators
auto x = GENERATE(take(num_samples, random(range_min, range_max)));
auto y = GENERATE(take(num_samples, random(range_min, range_max)));
auto z = GENERATE(take(num_samples, random(range_min, range_max)));

Vector3 v3_test(x, y, z);

// We should replace the code above with the following
auto v3_test = GENERATE(take(num_samples, ::math::random_vec3(range_min, range_max)));

Tasks

  • Tests for vec2_t
  • Tests for vec3_t
  • Tests for vec4_t
  • Tests for mat2_t
  • Tests for mat3_t
  • Tests for mat4_t
  • Tests for quat_t
  • Tests for euler_t
  • Tests for pose3d_t

Documentation for Rotation types

Description

Should add .rst files for the docs for all rotation types (e.g. Euler angles, quaternions, etc.). Use Sphinx as well to combine with the manually generated docs.

Tasks

  • Add docs for euler_t (Euler angles)
  • Add docs for quat_t (Quaternions)
  • Add docs for mat3_t (Rotation matrices)

Make binary distribution using manylinux

Description

Add support for built distribution for Linux platforms using manylinux. Once this is completed, we should have faster installs from PyPI using just pip as usual.

Tasks

  • Check resources in here, here, and here ๐Ÿ˜„
  • Make built distribution and test locally
  • Test built distribution on Google Colab.

Documentation for Matrix types

Description

Should add .rst files for the docs for all matrix types. Use sphinx as well to combine with the manually generated docs.

Tasks

  • Add docs for mat2_t
  • Add docs for mat3_t
  • Add docs for mat4_t

Transform|Pose3D Data Type (transform_t)

Description

Tracks the implementation of the transform Data Type, which we'll require to handle transformations from and to reference frames.

Rationale

This tracks the implementation of the transform Data Type (transform_t), which we use for quite various purposes, like:

  • Hopping from one reference frame to another
  • Reference frame chaining
  • Represent special kind of matrices (e.g. model, view, projection matrices in computer graphics
  • etc.

Its implementation is based in most references projects that also use transforms (i.e. position+ scale+quaternion), instead of having a full 4x4 transformation matrix, which can have reduced precision when chaining various transforms.

Notice that we have two use cases that can potentially derive into two separate data types: transforms include a scale, as in most computer graphics applications (e.g. model-matrix); however, we commonly use poses (e.g. in ROS and Rigid Body Simulations), which only require a position vector and a quaternion to fully represent a pose|reference frame.

Euler-Angle Data Type (euler_t)

Description

Tracks the implementation of Euler Angles

Rationale

This tracks the implementation of the euler Data type (euler_t), which we'll use as an alternative form of orientation|rotation representation; this is likely to be used by the user (as it's easier to handle UI that sets euler angles than quaternions or a full blown rotation matrix ๐Ÿ˜… ). Note that internally we'll avoid using these for orientation|rotation representation (thanks to Gimbal Lock โ˜น๏ธ)

clang-tidy issues finding dependencies

Description

We're currently having issues finding the includes of the math library. The generated compile_commands.json seems fine, but clang-tidy keeps complaining for the following paths (throws File not found errors):

#include <loco/math/vec2_t_impl.hpp

Perhaps the issue could be related to all framework-related dependencies (loco-utils, loco-math, loco-renderer) having the same nested folder structure, which could be messing up the include directories.

Missing unittests for exposed python types

Description

There are missing unit tests for some math types. Also, we should add missing typings (should move the typings to separate files).

Tasks

  • 2x2 Matrix
  • 3x3 Matrix
  • 4x4 Matrix
  • Euler Angles

Add checks for SIMD support in the host system

Description

There's currently no support to check if the host system has SSE or AVX support (neither its version number); we just have some hardcoded cmake options ๐Ÿ˜ž .
We could use something like using check_cxx_sources from cmake as they do in some repos (check that code with some specific instrinsics compile), but a perhaps better way would be to ask the processor directly. This might be platform dependent, but have seen the cpuinfo function thingy implemented somewhere already ๐Ÿค”

Quaternion Data Type (quat_t)

Description

Tracks the implementation of quaternions

Rationale

This tracks the implementation of the quaternion Data Type (quat_t), which will be used in the codebase to represent orientations and implement rotations in an efficient way. Note we'll also have other Data Types to represent orientations|rotations (i.e. Euler Angles, and Rotation Matrices), but quat_t should be used internally for poses (i.e. pose3d_t)

Tasks

  • Base API (quat_t)
  • Operations dispatching (quat_t_impl)
  • Operations Scalar implementation
  • [ ] Operations SSE implementation
  • [ ] Operations AVX implementation
  • Examples of its usage
  • Python bindings

Port remaining types from legacy renderer

Description

We should keep porting various types and functions that are located in the legacy renderer repository. Should also move the Perlin noise generation functions from the utils repo to this repo.

Tasks

  • Add remaining math types from the legacy renderer.

Quaternion (quat_t) operations

Description

Tracks the implementation of various operations used with the quat_t type

Rationale

This keeps track of the implementation of the operations listed below, which involve quaternions and other data types (e.g. vectors, matrices, etc.).

List of Operations

  • Normalization
  • Conjugate
  • Inverse
  • quaternion addition
  • quaternion substraction
  • quaternion multiplication
  • quaternion-vector operations
  • quaternion-matrix operations

Kernels not being properly inlined (perhaps use `-flto`?)

Description

The kernels that implement various operations in either scalar, SSE, and AVX, are not being inlined properly into the function that calls it; this is likely caused by having the kernels in different translation units, so the compiler can't actually get to inline these properly.

Note that the generated assembly instructions are the expected ones (as in SSE and AVX versions), so just this inline thingy is missing as a required optimization.

Matrix (mat3_t) operations

Description

Tracks the implementation of various operations required for handling mat3_t data types (see list below):

  • inverse
  • transpose
  • matrix-matrix addition
  • matrix-matrix substraction
  • matrix-matrix product
  • matrix-matrix element-wise product
  • scalar-matrix product
  • vector-matrix product
  • matrix-matrix comparison
  • matrix norms

Rotation Matrices (3x3) Data Type (mat3_t)

Description

Tracks the implementation of 3x3 matrices, which we can use as alternative representation for rotation|orientation when required

Rationale

This tracks the implementation of the 3x3 matrix Data Type (mat3_t), which is another alternative representation for orientations|rotations. Unlike quat_t types, this one is bigger in memory (it even allocates a 3x4 array to allow easier SIMD usage). However, it'll be potentially used by users when creating rotations along some canonical axes (e.g. rotx, roty, rotz). Notice that still we won't use these internally for handling rotation|orientation (quaternions will handle this), as we lose precision during matrix multiplies when applying|chaining rotations ๐Ÿ˜ž .

Implement Euler angles conversions from 'Graphics Gems 4' book

Description

We currently have a partial implementation of Euler angles conversions to other rotation types (e.g. Quaternions). This implementation was adapted from ThreeJS. We should replace it with the suggested conversions from the book Graphics Gems 4, which includes cases for extrinsic convention.

Tasks

  • Implement Euler angles conversions from this book
  • Add unit tests for this new conversions (we previously only checked conversions between supported orderings and conventions)

Documentation for Vector types

Description

Should add .rst files for the docs for all vector types. Use sphinx as well to combine with the manually generated docs.

Tasks

  • Add docs for vec2_t
  • Add docs for vec3_t
  • Add docs for vec4_t

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.