Skip to content

Commit

Permalink
Vector view (#6)
Browse files Browse the repository at this point in the history
* feat: vector_view utility class

* feat: memory vector view utility
zmij authored Jan 17, 2019
1 parent 22040f4 commit 4df5506
Showing 9 changed files with 802 additions and 46 deletions.
72 changes: 53 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -15,22 +15,22 @@ Library provides easy syntax for declaring, assigning vectors and matrices and m
// Vector
#include <pushkin/math/vector.hpp>

using vector3d = ::psst::math::vector<float, 3>;
using vector3d = psst::math::vector<float, 3>;

vector3d p1{1, 2, 1.5}, p2{2, 3, 5.4};

// Matrix
#include <pushkin/math/matrix.hpp>

using matrix3x3 = ::psst::math::matrix<float, 3, 3>;
using matrix3x3 = psst::math::matrix<float, 3, 3>;

matrix3x3 m1 {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 }
};

using affine_matrix = ::psst::math::matrix<float, 4, 4>;
using affine_matrix = psst::math::matrix<float, 4, 4>;

affine_matrix
rotate_x( float a )
@@ -55,7 +55,7 @@ rotate_x( float a )
```C++
using vector4 = ::psst::math::vector<float, 4>;
using vector4 = psst::math::vector<float, 4>;
vector4 v1{1, 2, 3, 4};
auto x = v1[0];
@@ -133,8 +133,8 @@ m3 /= 3;
auto i = matrix3x3::identity(); // identity matrix

// Rectangular matrices
using matrix4x3 = ::psst::math::matrix<float, 4, 3>;
using matrix3x4 = ::psst::math::matrix<float, 3, 4>;
using matrix4x3 = psst::math::matrix<float, 4, 3>;
using matrix3x4 = psst::math::matrix<float, 3, 4>;

matrix4x3 r1 {
{ 1, 2, 3 },
@@ -161,7 +161,7 @@ vector3d v5 = as_row_matrix(v1) * m1; // vector by matrix multiplication
#include <pushkin/math/vector_io.hpp>
#include <pushkin/math/matrix_io.hpp>
namespace io = ::psst::math::io;
namespace io = psst::math::io;
std::cout << v1 << "\n";
// output {1,2,1.5}
@@ -176,14 +176,48 @@ std::cout << io::pretty << m1 << io::ugly << "\n";
// }
```

#### Memory buffers as vectors

A memory buffer can be accessed as a container of vectors with certain properties (size, axes). A constant buffer can be used to read data in a structured manner, a non-costant buffer can be used to modify data in the buffer via `vector_view` and `memory_vector_view` utility classes. A `vector_view` is for reading a single element, `memory_vector_view` is for using a buffer as a 'container' of vectors.

```C++
#include <pushkin/math/vector_view.hpp>

using namespace psst::math;

// Size of the vector is 16 bytes
using vec4f = vector<float, 4>;

char const* const_buffer = "..."; // Get this buffer somewhere
std::size_t buffer_size = 256; // this is 16 vectors

auto const_mem_view = make_memory_view<vec4f>(const_buffer, buffer_size);

for (auto mv : const_mem_view) {
// do something with the vectors, no modification is available
}


char const* mutable_buffer = "..."; // Get this buffer somewhere

auto mem_view = make_memory_view<vec4f>(mutable_buffer, buffer_size);

for (auto mv : mem_view) {
// do something with the vectors, modification is available
mv *= 2;
}

```
### Quaternions
The libbrary provides quaternions and operations with them, such as sum, substraction, multiplication and division by scalar, quaternion multiplication, magnitude, normalize, conjugate and inverse functions. Components of a quaternion are accessible via `w()`, `x()`, `y()` and `z()` accessors, where `w()` is the real part and `x()`, `y()` and `z()` are coefficients for i, j and k respectively. Also, the scalar part is accessible via `scalar_part()` member function, and the vector part is accessible via `vector_part()`.
```C++
#include <pushkin/math/quaternion.hpp>
using quat = ::psst::math::quaternion<double>;
using quat = psst::math::quaternion<double>;
quat q1{1, 2, 3, 4}, q2{5, 6, 7, 8};
// quaternion sum and difference
@@ -206,8 +240,8 @@ auto i = inverse(q2);
```C++
#include <pushkin/math/quaternion.hpp>

using quat = ::psst::math::quaternion<double>;
using vec3 = ::psst::math::std::vector<double, 3>;
using quat = psst::math::quaternion<double>;
using vec3 = psst::math::std::vector<double, 3>;

vec3
rotate(vec3 v, vec3 axis, double angle)
@@ -252,12 +286,12 @@ Conversion is defined for:
#include <pushkin/math/spherical_coord.hpp>
#include <pushkin/math/cylindrical_coord.hpp>
using polar_c = ::psst::math::polar_coord<double>;
using spherical_c = ::psst::math::spherical_coord<double>
using cylindrical_c = ::psst::math::cylindrical_coord<double>;
using vec3 = ::psst::math::vector<double, 3>;
using polar_c = psst::math::polar_coord<double>;
using spherical_c = psst::math::spherical_coord<double>
using cylindrical_c = psst::math::cylindrical_coord<double>;
using vec3 = psst::math::vector<double, 3>;
using ::psst::math::operator "" _deg;
using psst::math::operator "" _deg;
polar_c p{10, 180_deg};
spherical_c s = convert<spherical_c>(p);
@@ -298,11 +332,11 @@ Conversions are defined for:
```C++
#include <pushkin/math/colors.hpp>

using rgba = ::psst::math::colors::rgba<float>;
using hsla = ::psst::math::colors::hsla<float>;
using hsva = ::psst::math::colors::hsva<float>;
using rgba = psst::math::colors::rgba<float>;
using hsla = psst::math::colors::hsla<float>;
using hsva = psst::math::colors::hsva<float>;

using ::psst::math::operator "" _rgba;
using psst::math::operator "" _rgba;

rgba col1 = convert<rgba>( 0xff0000ff_rgba ); // red
hsla hl1 = convert<hsla>(col1);
3 changes: 3 additions & 0 deletions include/pushkin/math/detail/axis_access.hpp
Original file line number Diff line number Diff line change
@@ -33,6 +33,9 @@ struct basic_axis_access {
template <std::size_t N>
using value_policy = typename value_policies::template value_policy<N>;

template <std::size_t N>
using accessor_type = typename value_policy<N>::accessor_type;

protected:
expression_type&
rebind()
22 changes: 10 additions & 12 deletions include/pushkin/math/detail/permute_macros.hpp
Original file line number Diff line number Diff line change
@@ -8,18 +8,16 @@
#ifndef INCLUDE_PUSHKIN_MATH_DETAIL_PERMUTE_MACROS_HPP_
#define INCLUDE_PUSHKIN_MATH_DETAIL_PERMUTE_MACROS_HPP_

#define PSST_MATH_COORD_ACCESS(name) \
template <typename _T = typename base_type::expression_type, \
typename = enable_if_vector_or_matrix<_T>> \
constexpr \
typename base_type::template value_policy<base_type::coord_names::name>::accessor_type \
name() \
{ \
return base_type::rebind().template at<base_type::coord_names::name>(); \
} \
constexpr auto name() const \
{ \
return base_type::rebind().template at<base_type::coord_names::name>(); \
#define PSST_MATH_COORD_ACCESS(name) \
template <typename _T = typename base_type::expression_type, \
typename = enable_if_mutable_vector<_T>> \
constexpr decltype(auto) name() \
{ \
return base_type::rebind().template at<base_type::coord_names::name>(); \
} \
constexpr auto name() const \
{ \
return base_type::rebind().template at<base_type::coord_names::name>(); \
}

#define PSST_MATH_COORD_VEC2(names, a, b) \
25 changes: 25 additions & 0 deletions include/pushkin/math/detail/value_traits.hpp
Original file line number Diff line number Diff line change
@@ -259,6 +259,8 @@ template <typename T>
struct is_vector : std::false_type {};
template <typename T, std::size_t S, typename Axes>
struct is_vector<vector<T, S, Axes>> : std::true_type {};
template <typename T, std::size_t S, typename Axes>
struct is_vector<vector_view<T, S, Axes>> : std::true_type {};
template <typename T>
using is_vector_t = typename is_vector<std::decay_t<T>>::type;
template <typename T>
@@ -269,6 +271,29 @@ template <typename T>
using enable_if_vector = std::enable_if_t<is_vector_v<T>>;
//@}

//@{
/** @name is_mutable_vector */
template <typename T>
struct is_mutable_vector : std::false_type {};
template <typename T>
using is_mutable_vector_t = typename is_mutable_vector<T>::type;
template <typename T>
constexpr bool is_mutable_vector_v = is_mutable_vector_t<T>::value;

template <typename T, std::size_t S, typename Axes>
struct is_mutable_vector<vector<T, S, Axes>> : std::true_type {};
template <typename T, std::size_t S, typename Axes>
struct is_mutable_vector<vector_view<T*, S, Axes>> : std::true_type {};
template <typename T, std::size_t S, typename Axes>
struct is_mutable_vector<vector_view<T const*, S, Axes>> : std::false_type {};

template <typename T>
struct is_mutable_vector<T&> : is_mutable_vector<T> {};

template <typename T>
using enable_if_mutable_vector = std::enable_if_t<is_mutable_vector_v<T>>;
//@}

//@{
/** @name is_matrix trait */
template <typename T>
29 changes: 15 additions & 14 deletions include/pushkin/math/vector.hpp
Original file line number Diff line number Diff line change
@@ -86,15 +86,15 @@ struct vector : expr::vector_expression<vector<T, Size, Axes>>, detail::vector_o
typename value_policy<N>::accessor_type
at()
{
static_assert(N < size, "Invalid value index in vector");
static_assert(N < size, "Invalid component index in vector");
return value_policy<N>::accessor(std::get<N>(data_));
}

template <std::size_t N>
constexpr const_reference
at() const
{
static_assert(N < size, "Invalid value index in vector");
static_assert(N < size, "Invalid component index in vector");
return std::get<N>(data_);
}

@@ -132,6 +132,7 @@ struct vector : expr::vector_expression<vector<T, Size, Axes>>, detail::vector_o
return data_.end();
}

// FIXME Apply accessors
lvalue_reference operator[](std::size_t idx)
{
assert(idx < size);
@@ -243,21 +244,21 @@ project(vector<T, Size, Axes> const& n, vector<T, Size, Axes> const& v)
# include <pushkin/math/spherical_coord.hpp>
using namespace psst::math;

using vec_3f = vector<float, 3>;
using vec_3d = vector<double, 3>;
using vec_3fn = vector<float, 3, axes::none>;
using vec3f = vector<float, 3>;
using vec3d = vector<double, 3>;
using vec3fn = vector<float, 3, axes::none>;

using vec_4f = vector<float, 4>;
using vec_4d = vector<double, 4>;
using vec_4fn = vector<float, 4, axes::none>;
using vec4f = vector<float, 4>;
using vec4d = vector<double, 4>;
using vec4fn = vector<float, 4, axes::none>;

vec_3f v3f_1, v3f_2;
vec_4f v4f_1, v4f_2;
vec_3fn v3f_n;
vec_4fn v4f_n;
vec3f v3f_1, v3f_2;
vec4f v4f_1, v4f_2;
vec3fn v3f_n;
vec4fn v4f_n;

vec_3d v3d_1, v3d_2;
vec_4d v4d_1, v4d_2;
vec3d v3d_1, v3d_2;
vec4d v4d_1, v4d_2;

using polar_f = polar_coord<float>;
using spherical_f = spherical_coord<float>;
12 changes: 11 additions & 1 deletion include/pushkin/math/vector_fwd.hpp
Original file line number Diff line number Diff line change
@@ -13,10 +13,20 @@
namespace psst {
namespace math {

// TODO Parameter for calculus
template <typename T, std::size_t Size, typename Axes = axes::default_axes_t<Size>>
struct vector;

/**
* The primary template for a vector_view.
*
* vector_view is an utility to read memory regions as vectors, use them in expressions, etc.
*
* For a const pointer the vector_view is read-only, for a non-const pointer the vector view can be
* used to modify the underlying data.
*/
template <typename T, std::size_t Size, typename Axes = axes::default_axes_t<Size>>
struct vector_view;

} /* namespace math */
} /* namespace psst */

Loading
Oops, something went wrong.

0 comments on commit 4df5506

Please sign in to comment.