sonulohani / vecpp

A simple C++17 vector math library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

VecPP

A simple vector math library.

build build_win

Current State

In agressive initial development. Once Matrices are in, we'll do a full feature and interaction coverage pass and declare a first usable version.

Design Goals

  • Strict adherance to C++ standard (no UB or strict aliasing violation)
  • No multiple ways to achieve the same thing
  • No external non-stl dependencies
  • constexpr everything
  • Code is easy to follow and straightforward

Documentation

The full documentation can be found in the /docs directory (either in markdown or HTML depending on how you obtained the library).

An HTML version matching the current state of the master branch can always be found here.

Quick Start

Prerequisites

All you need is a standard compliant C++17 compiler.

Installation

include

Vecpp is a header-only library. As such, all you need to do is make the contents of the include directory avilable to your compiler.

single-include

Alternatively, you can simply copy "vecpp_single.h" into your project and use that single freestanding header. (if you are cloning the raw source, you will need to generate it using -DVECPP_BUILD_SINGLE_HEADER).

Tip: We maintain a copy of this file in sync with the master branch here. This can be used to quickly test generated code on compiler explorer. For example: like this.

CMake

Finally, while the cmake project is primarily used to manage tests and deployment, it's still set up as a proper target-exporting project. So you can use either add_subdirectory(path/to/vecpp_source) or find_package(VecPP) and use `target_link_libraries(my_target VecPP::VecPP).

Usage

Vectors

Vectors are declared using the Vec<TYPE, SIZE> template (preferably aliased).

Individual vector members are accessed through the vec[index] operator. There is no .x, .y, .z etc... members. This is because VecPP avoids redundancy in its interface as much as possible (see the design goals).

#include "vecpp/vecpp.h"
#include <iosteam>

using Vec3 = vecpp::Vec<float, 3>;
static_assert(sizeof(Vec3) == 3 * sizeof(float)); // guaranteed!

int main() {
  Vec3 ux = {1.0f, 0.0f, 0.0f};
  Vec3 uy = {0.0f, 1.0f, 0.0f};

  std::cout << "ux.x: " << ux[0] << "\n";

  std::cout << "ux x uy :" << cross(x, y) << "\n";
  std::cout << "ux . uy :" << dot(x, y) << "\n";
}

Angles

VecPP angles are strongly-typed, and correctly handle wraparounds and conversions under the hood.

#include "vecpp/vecpp.h"

using Angle = vecpp::Angle<float>;
using vecpp::pi;

int main() {
  Angle a = Angle::from_rad(pi<float>);
  Angle b = Angle::from_deg(20.0f);

  Angle c = a + b; // is now holding -160deg
  Angle d = c - Angle::from_deg(160.0f); // contains 40deg

  float sin_val = sin(c);

  std::cout << "sin(" << c << ") = " << sin(c) << "\n";
  // prints: "sin(-160°) = -0.34202"
}

** Coming soon!** :

Matrices

#include "vecpp/vecpp.h"

using Mat = vecpp::Matrix<float, 3, 3>;
using Vec = vecpp::Vec<float, 3>;


int main() {
  Vec a = {1.0f, 0.0f, 0.0f};
  Mat m = {
    1.0f, 0.0f, 0.0,
    1.0f, 1.0f, 1.0fl
    0.0f, 1.0f , 0.0f
  };
  
  Vec b = m * a;
  std::cout << b << "\n";

}

Acknowledgements

  • glm is used as a reference point for many algorithms.
  • cppreference.com is used as a reference point for the documentation format.

FAQS

Why use this over GLM?

GLM is an amazing library, and right now, probably a better fit for your needs.

That being said, glm has a few drawbacks that stem from its design goals that vecpp aims to remedy.

  • Closely following GLSL creates many layers of abstraction between the interface and implentation.
  • GLSL basically cannot be reimplemented without relying on undefined behavior.
  • Supporting C++ accross the spectrum of versions adds a lot of complexity.
  • There are many ways to compile the library which leads to an inconsistent and confusing API.
  • The type system cannot be leveraged to its full potential (scalars must be scalar values for example).

Why use this over eigen?

Eigen is another amazing library with a wide variety of uses.

In short: Eigen is a massive library that supports a very wide variety of usage patterns. If your needs are more specifically in line with what vecpp provide you will find it to be a lot more straightforward to navigate. Less is more.

Why does vecpp not provide aliases for commonly used templates?

Writing vecpp::Vec<float, 3> over and over again is annoying, verbose, and frankly makes code harder to read, but we think that the same goes for vecpp::Vec3. What we really want when writing linear algebra code, is to just use Vec3.

So, we expect that users will be aliasing their commonly used types within their project's namespace (or the global namespace, we don't judge). In that context, all vecpp::Vec3 or vecpp::Mat4 would provide is an unnecessary layer of indirection between our aliases and our underlying types.

Also, creating these aliases would force us to take positions on matters such as "should the default scalar type be float or double?", which we would rather avoid.

So a typical project making use of VecPP would likely have a header that looks a lot like this:

// vecmath.h
#include "vecpp/vecpp.h"

namespace my_ns {
  using Angle = vecpp::Angle<float>;
  using Vec3 = vecpp::Vec<float, 3>;
  using Mat4 = vecpp::Mat<float, 4, 4>;
  using Quat = vecpp::Quat<float>;
}

What's with vecpp::ct()?

Some functions need to have different implementations between runtime and compile-time evaluation (sqrt() for example), and unfortunately, there is currently no known way to achieve that implicitely in C++17.
ct() is our workaround.

The rule of thumb is: Write code as if everything magically worked.

using Vec3 = vecpp::Vec<float, 3>;
constexpr Vec3 val = {1.0f, 1.0f 1.0f};
constexpr Vec3 val_len = length(val);

And if you see an error that looks like:

call to non-constexpr function ‘float vecpp::sqrt_impl(float)’

Then you can fix it by wrapping the offending operand with ct():

constexpr Vec3 val_len = length(ct(val));

N.B. Only use ct() in constexprs! Its usage triggers the use of slower algorithms that are fine during compilation, but unsuitable for runtime.

About

A simple C++17 vector math library

License:Boost Software License 1.0


Languages

Language:C++ 98.9%Language:CMake 1.0%Language:C 0.1%