This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/blenlib/BLI_math_rotation.hh

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

481 lines
18 KiB
C++
Raw Normal View History

BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
/* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
/** \file
* \ingroup bli
*/
#include "BLI_math_rotation_types.hh"
#include "BLI_math_axis_angle.hh"
#include "BLI_math_euler.hh"
#include "BLI_math_matrix.hh"
#include "BLI_math_quaternion.hh"
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
#include "BLI_math_vector.hh"
namespace blender::math {
/* -------------------------------------------------------------------- */
/** \name Rotation helpers
* \{ */
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
/**
* Rotate \a a by \a b. In other word, insert the \a b rotation before \a a.
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
*
* \note Since \a a is a #Quaternion it will cast \a b to a #Quaternion.
* This might introduce some precision loss and have performance implication.
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
*/
template<typename T, typename RotT>
[[nodiscard]] QuaternionBase<T> rotate(const QuaternionBase<T> &a, const RotT &b);
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
/**
* Rotate \a a by \a b. In other word, insert the \a b rotation before \a a.
*
* \note Since \a a is an #AxisAngle it will cast both \a a and \a b to #Quaternion.
* This might introduce some precision loss and have performance implication.
*/
template<typename T, typename RotT, typename AngleT>
[[nodiscard]] AxisAngleBase<T, AngleT> rotate(const AxisAngleBase<T, AngleT> &a, const RotT &b);
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
/**
* Rotate \a a by \a b. In other word, insert the \a b rotation before \a a.
*
* \note Since \a a is an #EulerXYZ it will cast both \a a and \a b to #MatBase<T, 3, 3>.
* This might introduce some precision loss and have performance implication.
*/
template<typename T, typename RotT>
[[nodiscard]] EulerXYZBase<T> rotate(const EulerXYZBase<T> &a, const RotT &b);
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
/**
* Rotate \a a by \a b. In other word, insert the \a b rotation before \a a.
*
* \note Since \a a is an #Euler3 it will cast both \a a and \a b to #MatBase<T, 3, 3>.
* This might introduce some precision loss and have performance implication.
*/
template<typename T, typename RotT>
[[nodiscard]] Euler3Base<T> rotate(const Euler3Base<T> &a, const RotT &b);
/**
* Return rotation from orientation \a a to orientation \a b into another quaternion.
*/
template<typename T>
[[nodiscard]] QuaternionBase<T> rotation_between(const QuaternionBase<T> &a,
const QuaternionBase<T> &b);
/**
* Create a orientation from a triangle plane and the axis formed by the segment(v1, v2).
* Takes pre-computed \a normal from the triangle.
* Used for Ngons when their normal is known.
*/
template<typename T>
[[nodiscard]] QuaternionBase<T> from_triangle(const VecBase<T, 3> &v1,
const VecBase<T, 3> &v2,
const VecBase<T, 3> &v3,
const VecBase<T, 3> &normal);
/**
* Create a orientation from a triangle plane and the axis formed by the segment(v1, v2).
*/
template<typename T>
[[nodiscard]] QuaternionBase<T> from_triangle(const VecBase<T, 3> &v1,
const VecBase<T, 3> &v2,
const VecBase<T, 3> &v3);
/**
* Create a rotation from a vector and a basis rotation.
* Used for tracking.
* \a track_flag is supposed to be #Object.trackflag
* \a up_flag is supposed to be #Object.upflag
*/
template<typename T>
[[nodiscard]] QuaternionBase<T> from_vector(const VecBase<T, 3> &vector,
const AxisSigned track_flag,
const Axis up_flag);
/**
* Returns a quaternion for converting local space to tracking space.
* This is slightly different than from_axis_conversion for legacy reasons.
*/
template<typename T>
[[nodiscard]] QuaternionBase<T> from_tracking(AxisSigned forward_axis, Axis up_axis);
/**
* Convert euler rotation to gimbal rotation matrix.
*/
template<typename T> [[nodiscard]] MatBase<T, 3, 3> to_gimbal_axis(const Euler3Base<T> &rotation);
/** \} */
/* -------------------------------------------------------------------- */
/** \name Angles
* \{ */
/**
* Extract rotation angle from a unit quaternion.
* Returned angle is in [0..2pi] range.
*
* Unlike the angle between vectors, this does *NOT* return the shortest angle.
* See `angle_of_signed` below for this.
*/
template<typename T> [[nodiscard]] AngleRadianBase<T> angle_of(const QuaternionBase<T> &q)
{
BLI_assert(is_unit_scale(q));
return T(2) * math::safe_acos(q.w);
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
}
/**
* Extract rotation angle from a unit quaternion. Always return the shortest angle.
* Returned angle is in [-pi..pi] range.
*
* `angle_of` with quaternion can exceed PI radians. Having signed versions of these functions
* allows to use 'abs(angle_of_signed(...))' to get the shortest angle between quaternions with
* higher precision than subtracting 2pi afterwards.
*/
template<typename T> [[nodiscard]] AngleRadianBase<T> angle_of_signed(const QuaternionBase<T> &q)
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
{
BLI_assert(is_unit_scale(q));
return T(2) * ((q.w >= T(0)) ? math::safe_acos(q.w) : -math::safe_acos(-q.w));
}
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
/**
* Extract angle between 2 orientations.
* For #Quaternion, the returned angle is in [0..2pi] range.
* For other types, the returned angle is in [0..pi] range.
* See `angle_of` for more detail.
*/
template<typename T>
[[nodiscard]] AngleRadianBase<T> angle_between(const QuaternionBase<T> &a,
const QuaternionBase<T> &b)
{
return angle_of(rotation_between(a, b));
}
template<typename T>
[[nodiscard]] AngleRadianBase<T> angle_between(const VecBase<T, 3> &a, const VecBase<T, 3> &b)
{
BLI_assert(is_unit_scale(a));
BLI_assert(is_unit_scale(b));
return math::safe_acos(dot(a, b));
}
template<typename T>
[[nodiscard]] AngleFraction<T> angle_between(const AxisSigned a, const AxisSigned b)
{
if (a == b) {
return AngleFraction<T>::identity();
}
if (abs(a) == abs(b)) {
return AngleFraction<T>::pi();
}
return AngleFraction<T>::pi() / 2;
}
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
/**
* Extract angle between 2 orientations.
* Returned angle is in [-pi..pi] range.
* See `angle_of_signed` for more detail.
*/
template<typename T>
[[nodiscard]] AngleRadianBase<T> angle_between_signed(const QuaternionBase<T> &a,
const QuaternionBase<T> &b)
{
return angle_of_signed(rotation_between(a, b));
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
}
/** \} */
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
/* -------------------------------------------------------------------- */
/** \name Template implementations
* \{ */
template<typename T, typename RotT>
[[nodiscard]] QuaternionBase<T> rotate(const QuaternionBase<T> &a, const RotT &b)
{
return a * QuaternionBase<T>(b);
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
}
template<typename T, typename RotT, typename AngleT>
[[nodiscard]] AxisAngleBase<T, AngleT> rotate(const AxisAngleBase<T, AngleT> &a, const RotT &b)
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
{
return AxisAngleBase<T, AngleT>(QuaternionBase<T>(a) * QuaternionBase<T>(b));
}
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
template<typename T, typename RotT>
[[nodiscard]] EulerXYZBase<T> rotate(const EulerXYZBase<T> &a, const RotT &b)
{
MatBase<T, 3, 3> tmp = from_rotation<MatBase<T, 3, 3>>(a) * from_rotation<MatBase<T, 3, 3>>(b);
return to_euler(tmp);
}
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
template<typename T, typename RotT>
[[nodiscard]] Euler3Base<T> rotate(const Euler3Base<T> &a, const RotT &b)
{
const MatBase<T, 3, 3> tmp = from_rotation<MatBase<T, 3, 3>>(a) *
from_rotation<MatBase<T, 3, 3>>(b);
return to_euler(tmp, a.order());
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
}
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
template<typename T>
[[nodiscard]] QuaternionBase<T> rotation_between(const QuaternionBase<T> &a,
const QuaternionBase<T> &b)
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
{
return invert(a) * b;
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
}
template<typename T>
[[nodiscard]] QuaternionBase<T> from_triangle(const VecBase<T, 3> &v1,
const VecBase<T, 3> &v2,
const VecBase<T, 3> &v3,
const VecBase<T, 3> &normal)
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
{
/* Force to used an unused var to avoid the same function signature as the version without
* `normal` argument. */
UNUSED_VARS(v3);
using Vec3T = VecBase<T, 3>;
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
/* Move z-axis to face-normal. */
const Vec3T z_axis = normal;
Vec3T nor = normalize(Vec3T(z_axis.y, -z_axis.x, T(0)));
if (is_zero(nor.xy())) {
nor.x = T(1);
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
}
T angle = T(-0.5) * math::safe_acos(z_axis.z);
T si = math::sin(angle);
QuaternionBase<T> q1(math::cos(angle), nor.x * si, nor.y * si, T(0));
/* Rotate back line v1-v2. */
Vec3T line = transform_point(conjugate(q1), (v2 - v1));
/* What angle has this line with x-axis? */
line = normalize(Vec3T(line.x, line.y, T(0)));
angle = T(0.5) * math::atan2(line.y, line.x);
QuaternionBase<T> q2(math::cos(angle), 0.0, 0.0, math::sin(angle));
return q1 * q2;
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
}
template<typename T>
[[nodiscard]] QuaternionBase<T> from_triangle(const VecBase<T, 3> &v1,
const VecBase<T, 3> &v2,
const VecBase<T, 3> &v3)
{
return from_triangle(v1, v2, v3, normal_tri(v1, v2, v3));
}
template<typename T>
[[nodiscard]] QuaternionBase<T> from_vector(const VecBase<T, 3> &vector,
const AxisSigned track_flag,
const Axis up_flag)
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
{
using Vec2T = VecBase<T, 2>;
using Vec3T = VecBase<T, 3>;
using Vec4T = VecBase<T, 4>;
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
const T vec_len = length(vector);
if (UNLIKELY(vec_len == 0.0f)) {
return QuaternionBase<T>::identity();
}
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
const Axis axis = track_flag.axis();
const Vec3T vec = track_flag.is_negative() ? vector : -vector;
Vec3T rotation_axis;
constexpr T eps = T(1e-4);
T axis_len;
switch (axis) {
case Axis::X:
rotation_axis = normalize_and_get_length(Vec3T(T(0), -vec.z, vec.y), axis_len);
if (axis_len < eps) {
rotation_axis = Vec3T(0, 1, 0);
}
break;
case Axis::Y:
rotation_axis = normalize_and_get_length(Vec3T(vec.z, T(0), -vec.x), axis_len);
if (axis_len < eps) {
rotation_axis = Vec3T(0, 0, 1);
}
break;
default:
case Axis::Z:
rotation_axis = normalize_and_get_length(Vec3T(-vec.y, vec.x, T(0)), axis_len);
if (axis_len < eps) {
rotation_axis = Vec3T(1, 0, 0);
}
break;
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
}
/* TODO(fclem): Can optimize here by initializing AxisAngle using the cos an sin directly.
* Avoiding the need for safe_acos and deriving sin from cos. */
const T rotation_angle = math::safe_acos(vec[axis.as_int()] / vec_len);
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
const QuaternionBase<T> q1 = to_quaternion(
AxisAngleBase<T, AngleRadianBase<T>>(rotation_axis, rotation_angle));
if (axis == up_flag) {
/* Nothing else to do. */
return q1;
}
/* Extract rotation between the up axis of the rotated space and the up axis. */
/* There might be an easier way to get this angle directly from the quaternion representation. */
const Vec3T rotated_up = transform_point(q1, Vec3T(0, 0, 1));
/* Project using axes index instead of arithmetic. It's much faster and more precise. */
const AxisSigned y_axis_signed = math::cross(AxisSigned(axis), AxisSigned(up_flag));
const Axis x_axis = up_flag;
const Axis y_axis = y_axis_signed.axis();
Vec2T projected = normalize(Vec2T(rotated_up[x_axis.as_int()], rotated_up[y_axis.as_int()]));
/* Flip sign for flipped axis. */
if (y_axis_signed.is_negative()) {
projected.y = -projected.y;
}
/* Not sure if this was a bug or not in the previous implementation.
* Carry over this weird behavior to avoid regressions. */
if (axis == Axis::Z) {
projected = -projected;
}
const AngleCartesianBase<T> angle(projected.x, projected.y);
const AngleCartesianBase<T> half_angle = angle / T(2);
const QuaternionBase<T> q2(Vec4T(half_angle.cos(), vec * (half_angle.sin() / vec_len)));
return q2 * q1;
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
}
template<typename T>
[[nodiscard]] QuaternionBase<T> from_tracking(AxisSigned forward_axis, Axis up_axis)
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
{
BLI_assert(forward_axis.axis() != up_axis);
/* Curve have Z forward, Y up, X left. */
return QuaternionBase<T>(
rotation_between(from_orthonormal_axes(AxisSigned::Z_POS, AxisSigned::Y_POS),
from_orthonormal_axes(forward_axis, AxisSigned(up_axis))));
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
}
template<typename T> [[nodiscard]] MatBase<T, 3, 3> to_gimbal_axis(const Euler3Base<T> &rotation)
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
{
using Mat3T = MatBase<T, 3, 3>;
using Vec3T = VecBase<T, 3>;
const int i_index = rotation.i_index();
const int j_index = rotation.j_index();
const int k_index = rotation.k_index();
Mat3T result;
/* First axis is local. */
result[i_index] = from_rotation<Mat3T>(rotation)[i_index];
/* Second axis is local minus first rotation. */
Euler3Base<T> tmp_rot = rotation;
tmp_rot.i() = T(0);
result[j_index] = from_rotation<Mat3T>(tmp_rot)[j_index];
/* Last axis is global. */
result[k_index] = Vec3T(0);
result[k_index][k_index] = T(1);
return result;
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Conversion from Cartesian Basis
* \{ */
/**
* Creates a quaternion from an axis triple.
* This is faster and more precise than converting from another representation.
*/
template<typename T> QuaternionBase<T> to_quaternion(const CartesianBasis &rotation)
{
/**
* There are only 6 * 4 = 24 possible valid orthonormal orientations.
* We precompute them and store them inside this switch using a key.
* Generated using `generate_axes_to_quaternion_switch_cases()`.
*/
constexpr auto map = [](AxisSigned x, AxisSigned y, AxisSigned z) {
return x.as_int() << 16 | y.as_int() << 8 | z.as_int();
};
switch (map(rotation.axes.x, rotation.axes.y, rotation.axes.z)) {
default:
return QuaternionBase<T>::identity();
case map(AxisSigned::Z_POS, AxisSigned::X_POS, AxisSigned::Y_POS):
return QuaternionBase<T>{T(0.5), T(-0.5), T(-0.5), T(-0.5)};
case map(AxisSigned::Y_NEG, AxisSigned::X_POS, AxisSigned::Z_POS):
return QuaternionBase<T>{T(M_SQRT1_2), T(0), T(0), T(-M_SQRT1_2)};
case map(AxisSigned::Z_NEG, AxisSigned::X_POS, AxisSigned::Y_NEG):
return QuaternionBase<T>{T(0.5), T(0.5), T(0.5), T(-0.5)};
case map(AxisSigned::Y_POS, AxisSigned::X_POS, AxisSigned::Z_NEG):
return QuaternionBase<T>{T(0), T(M_SQRT1_2), T(M_SQRT1_2), T(0)};
case map(AxisSigned::Z_NEG, AxisSigned::Y_POS, AxisSigned::X_POS):
return QuaternionBase<T>{T(M_SQRT1_2), T(0), T(M_SQRT1_2), T(0)};
case map(AxisSigned::Z_POS, AxisSigned::Y_POS, AxisSigned::X_NEG):
return QuaternionBase<T>{T(M_SQRT1_2), T(0), T(-M_SQRT1_2), T(0)};
case map(AxisSigned::X_NEG, AxisSigned::Y_POS, AxisSigned::Z_NEG):
return QuaternionBase<T>{T(0), T(0), T(1), T(0)};
case map(AxisSigned::Y_POS, AxisSigned::Z_POS, AxisSigned::X_POS):
return QuaternionBase<T>{T(0.5), T(0.5), T(0.5), T(0.5)};
case map(AxisSigned::X_NEG, AxisSigned::Z_POS, AxisSigned::Y_POS):
return QuaternionBase<T>{T(0), T(0), T(M_SQRT1_2), T(M_SQRT1_2)};
case map(AxisSigned::Y_NEG, AxisSigned::Z_POS, AxisSigned::X_NEG):
return QuaternionBase<T>{T(0.5), T(0.5), T(-0.5), T(-0.5)};
case map(AxisSigned::X_POS, AxisSigned::Z_POS, AxisSigned::Y_NEG):
return QuaternionBase<T>{T(M_SQRT1_2), T(M_SQRT1_2), T(0), T(0)};
case map(AxisSigned::Z_NEG, AxisSigned::X_NEG, AxisSigned::Y_POS):
return QuaternionBase<T>{T(0.5), T(-0.5), T(0.5), T(0.5)};
case map(AxisSigned::Y_POS, AxisSigned::X_NEG, AxisSigned::Z_POS):
return QuaternionBase<T>{T(M_SQRT1_2), T(0), T(0), T(M_SQRT1_2)};
case map(AxisSigned::Z_POS, AxisSigned::X_NEG, AxisSigned::Y_NEG):
return QuaternionBase<T>{T(0.5), T(0.5), T(-0.5), T(0.5)};
case map(AxisSigned::Y_NEG, AxisSigned::X_NEG, AxisSigned::Z_NEG):
return QuaternionBase<T>{T(0), T(-M_SQRT1_2), T(M_SQRT1_2), T(0)};
case map(AxisSigned::Z_POS, AxisSigned::Y_NEG, AxisSigned::X_POS):
return QuaternionBase<T>{T(0), T(M_SQRT1_2), T(0), T(M_SQRT1_2)};
case map(AxisSigned::X_NEG, AxisSigned::Y_NEG, AxisSigned::Z_POS):
return QuaternionBase<T>{T(0), T(0), T(0), T(1)};
case map(AxisSigned::Z_NEG, AxisSigned::Y_NEG, AxisSigned::X_NEG):
return QuaternionBase<T>{T(0), T(-M_SQRT1_2), T(0), T(M_SQRT1_2)};
case map(AxisSigned::X_POS, AxisSigned::Y_NEG, AxisSigned::Z_NEG):
return QuaternionBase<T>{T(0), T(1), T(0), T(0)};
case map(AxisSigned::Y_NEG, AxisSigned::Z_NEG, AxisSigned::X_POS):
return QuaternionBase<T>{T(0.5), T(-0.5), T(0.5), T(-0.5)};
case map(AxisSigned::X_POS, AxisSigned::Z_NEG, AxisSigned::Y_POS):
return QuaternionBase<T>{T(M_SQRT1_2), T(-M_SQRT1_2), T(0), T(0)};
case map(AxisSigned::Y_POS, AxisSigned::Z_NEG, AxisSigned::X_NEG):
return QuaternionBase<T>{T(0.5), T(-0.5), T(-0.5), T(0.5)};
case map(AxisSigned::X_NEG, AxisSigned::Z_NEG, AxisSigned::Y_NEG):
return QuaternionBase<T>{T(0), T(0), T(-M_SQRT1_2), T(M_SQRT1_2)};
}
}
/** \} */
} // namespace blender::math
namespace blender::math {
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
/* Using explicit template instantiations in order to reduce compilation time. */
extern template EulerXYZ to_euler(const AxisAngle &);
extern template EulerXYZ to_euler(const AxisAngleCartesian &);
extern template EulerXYZ to_euler(const Quaternion &);
extern template Euler3 to_euler(const AxisAngle &, EulerOrder);
extern template Euler3 to_euler(const AxisAngleCartesian &, EulerOrder);
extern template Euler3 to_euler(const Quaternion &, EulerOrder);
extern template Quaternion to_quaternion(const AxisAngle &);
extern template Quaternion to_quaternion(const AxisAngleCartesian &);
extern template Quaternion to_quaternion(const Euler3 &);
extern template Quaternion to_quaternion(const EulerXYZ &);
extern template AxisAngleCartesian to_axis_angle(const Euler3 &);
extern template AxisAngleCartesian to_axis_angle(const EulerXYZ &);
extern template AxisAngleCartesian to_axis_angle(const Quaternion &);
extern template AxisAngle to_axis_angle(const Euler3 &);
extern template AxisAngle to_axis_angle(const EulerXYZ &);
extern template AxisAngle to_axis_angle(const Quaternion &);
} // namespace blender::math
BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view<NumCol, NumRow, StartCol, StartRow>()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625
2023-01-06 17:02:28 +01:00
/** \} */