35#include <NDEVR/Vertex.h>
36#include <NDEVR/LineSegment.h>
37#include <NDEVR/Bounds.h>
38#include <NDEVR/Triangle.h>
39#include <NDEVR/Polyline.h>
48 template<
class t_type,
class t_vector, u
int01 t_dims, u
int01 t_row_dims, u
int01 t_col_dims>
51 return matrix * vertex;
60 template<
class t_type,
class t_vector, u
int01 t_row_dims, u
int01 t_col_dims>
64 trans = matrix * trans;
74 template<
class t_type,
class t_vector, u
int01 t_row_dims, u
int01 t_col_dims>
77 t_type bottom = right[0] * matrix[0][3] + right[1] * matrix[1][3] + matrix[2][3] + matrix[3][3];
79 (right[0] * matrix[0][0] + right[1] * matrix[1][0] + matrix[2][0] + matrix[3][0]) / bottom
80 , (right[0] * matrix[0][1] + right[1] * matrix[1][1] + matrix[2][1] + matrix[3][1]) / bottom);
89 template<
class t_type,
class t_vector>
92 const t_type x = v[0], y = v[1], z = v[2];
100 const t_type inv_bottom = t_type(1) / bottom;
103 (x * m.inlineGet(0) + y * m.inlineGet(4) + z * m.inlineGet(8) + m.inlineGet(12)) * inv_bottom,
104 (x * m.inlineGet(1) + y * m.inlineGet(5) + z * m.inlineGet(9) + m.inlineGet(13)) * inv_bottom,
105 (x * m.inlineGet(2) + y * m.inlineGet(6) + z * m.inlineGet(10) + m.inlineGet(14)) * inv_bottom
115 template<
class t_type,
class t_vector>
119 (right[0] * matrix[0][0] + right[1] * matrix[1][0] + right[2] * matrix[2][0])
120 , (right[0] * matrix[0][1] + right[1] * matrix[1][1] + right[2] * matrix[2][1])
121 , (right[0] * matrix[0][2] + right[1] * matrix[1][2] + right[2] * matrix[2][2]));
130 template<
class t_type,
class t_vector>
133 const t_type x = v[0], y = v[1], z = v[2], w = v[3];
135 x * m.inlineGet(0) + y * m.inlineGet(4) + z * m.inlineGet(8) + w * m.inlineGet(12),
136 x * m.inlineGet(1) + y * m.inlineGet(5) + z * m.inlineGet(9) + w * m.inlineGet(13),
137 x * m.inlineGet(2) + y * m.inlineGet(6) + z * m.inlineGet(10) + w * m.inlineGet(14),
138 x * m.inlineGet(3) + y * m.inlineGet(7) + z * m.inlineGet(11) + w * m.inlineGet(15)
148 template<
class t_type,
class t_vector, u
int01 t_dims, u
int01 t_row_dims, u
int01 t_col_dims>
151 return matrix * vertex;
160 template<
class t_type,
class t_vector, u
int01 t_row_dims, u
int01 t_col_dims>
163 return Ray<1, t_type, t_vector>(right[0] * matrix[0][0]);
172 template<
class t_type,
class t_vector, u
int01 t_row_dims, u
int01 t_col_dims>
175 return Ray<2, t_type, t_vector>(
176 (right[0] * matrix[0][0] + right[1] * matrix[1][0] + matrix[2][0])
177 , (right[0] * matrix[0][1] + right[1] * matrix[1][1] + matrix[2][1]));
186 template<
class t_type,
class t_vector>
189 return Ray<3, t_type, t_vector>(
190 (right[0] * matrix[0][0] + right[1] * matrix[1][0] + right[2] * matrix[2][0])
191 , (right[0] * matrix[0][1] + right[1] * matrix[1][1] + right[2] * matrix[2][1])
192 , (right[0] * matrix[0][2] + right[1] * matrix[1][2] + right[2] * matrix[2][2]));
201 template<
class t_type,
class t_vector>
204 return Ray<3, t_type, t_vector>(
205 (right[0] * matrix[0][0] + right[1] * matrix[1][0] + right[2] * matrix[2][0])
206 , (right[0] * matrix[0][1] + right[1] * matrix[1][1] + right[2] * matrix[2][1])
207 , (right[0] * matrix[0][2] + right[1] * matrix[1][2] + right[2] * matrix[2][2]));
216 template<
class t_type,
class t_vector>
219 return Ray<4, t_type, t_vector>(
220 right[0] * matrix[0][0] + right[1] * matrix[1][0] + right[2] * matrix[2][0] + right[3] * matrix[3][0]
221 , right[0] * matrix[0][1] + right[1] * matrix[1][1] + right[2] * matrix[2][1] + right[3] * matrix[3][1]
222 , right[0] * matrix[0][2] + right[1] * matrix[1][2] + right[2] * matrix[2][2] + right[3] * matrix[3][2]
223 , right[0] * matrix[0][3] + right[1] * matrix[1][3] + right[2] * matrix[2][3] + right[3] * matrix[3][3]);
232 template<
class t_type, u
int01 t_dims,
class t_vertex, u
int01 t_row_dims, u
int01 t_col_dims>
244 template<
class t_type, u
int01 t_dims,
class t_vertex, u
int01 t_row_dims, u
int01 t_col_dims>
256 template<
class t_type,
class t_vertex, u
int01 t_dims, u
int01 t_row_dims, u
int01 t_col_dims>
273 template<
class t_type,
class t_vertex, u
int01 t_row_dims, u
int01 t_col_dims>
278 for (
uint01 max_min = 0; max_min < 2; max_min++)
280 for (
uint01 n = 0; n < 3; n++)
281 upper_1[n] = matrix[0][n] * bounds[max_min][X] + matrix[3][n];
282 t_type lower_1 = matrix[0][3] * bounds[max_min][X] + matrix[3][3];
294 template<
class t_type,
class t_vertex, u
int01 t_row_dims, u
int01 t_col_dims>
299 for (
uint01 i = MIN; i <= MAX; i++)
301 for (
uint01 n = 0; n < 3; n++)
302 upper_1[n] = matrix[0][n] * bounds[i][X] + matrix[3][n];
303 t_type lower_1 = matrix[0][3] * bounds[i][X] + matrix[3][3];
305 for (
uint01 j = MIN; j <= MAX; j++)
307 for (
uint01 n = 0; n < 3; n++)
308 upper_2[n] = upper_1[n] + matrix[1][n] * bounds[j][Y];
309 t_type lower_2 = lower_1 + matrix[1][3] * bounds[j][Y];
322 template<
class t_type,
class t_vertex, u
int01 t_row_dims, u
int01 t_col_dims>
333 for (
uint01 max_min = MIN; max_min <= MAX; max_min++)
335 for (
uint01 n = 0; n < 3; n++)
336 upper_1[n] = matrix[0][n] * bounds[max_min][X] + matrix[3][n];
337 t_type lower_1 = matrix[0][3] * bounds[max_min][X] + matrix[3][3];
339 for (
uint01 max_min_2 = MIN; max_min_2 <= MAX; max_min_2++)
341 for (
uint01 n = 0; n < 3; n++)
342 upper_2[n] = upper_1[n] + matrix[1][n] * bounds[max_min_2][Y];
343 t_type lower_2 = lower_1 + matrix[1][3] * bounds[max_min_2][Y];
345 for (
uint01 max_min_3 = MIN; max_min_3 <= MAX; max_min_3++)
347 for (
uint01 n = 0; n < 3; n++)
348 upper_3[n] = upper_2[n] + matrix[2][n] * bounds[max_min_3][Z];
349 t_type lower_3 = lower_2 + matrix[2][3] * bounds[max_min_3][Z];
375 template<
class t_type,
class t_vertex>
379 const t_type x[2] = { bounds[MIN][X], bounds[MAX][X] };
380 const t_type y[2] = { bounds[MIN][Y], bounds[MAX][Y] };
381 const t_type z[2] = { bounds[MIN][Z], bounds[MAX][Z] };
383 const auto& m = matrix;
384 const t_type m00 = m[0][0], m01 = m[0][1], m02 = m[0][2], m03 = m[0][3];
385 const t_type m10 = m[1][0], m11 = m[1][1], m12 = m[1][2], m13 = m[1][3];
386 const t_type m20 = m[2][0], m21 = m[2][1], m22 = m[2][2], m23 = m[2][3];
387 const t_type m30 = m[3][0], m31 = m[3][1], m32 = m[3][2], m33 = m[3][3];
389 for (
uint08 i = 0; i < 8; ++i)
391 t_type xi = x[(i >> 0) & 1];
392 t_type yi = y[(i >> 1) & 1];
393 t_type zi = z[(i >> 2) & 1];
394 t_type w = xi * m03 + yi * m13 + zi * m23 + m33;
395 t_type rx = (xi * m00 + yi * m10 + zi * m20 + m30) / w;
396 t_type ry = (xi * m01 + yi * m11 + zi * m21 + m31) / w;
397 t_type rz = (xi * m02 + yi * m12 + zi * m22 + m32) / w;
413 template<
class t_type,
class t_vertex>
417 { bounds[MIN][X], bounds[MIN][Y], bounds[MIN][Z] },
418 { bounds[MIN][X], bounds[MIN][Y], bounds[MAX][Z] },
419 { bounds[MIN][X], bounds[MAX][Y], bounds[MIN][Z] },
420 { bounds[MIN][X], bounds[MAX][Y], bounds[MAX][Z] },
421 { bounds[MAX][X], bounds[MIN][Y], bounds[MIN][Z] },
422 { bounds[MAX][X], bounds[MIN][Y], bounds[MAX][Z] },
423 { bounds[MAX][X], bounds[MAX][Y], bounds[MIN][Z] },
424 { bounds[MAX][X], bounds[MAX][Y], bounds[MAX][Z] }
428 for (
uint08 i = 0; i < 8; ++i)
431 const uint01 edge_pairs[12][2] = {
432 {0, 1}, {0, 2}, {0, 4},
442 bool added[8] = {
false,
false,
false,
false,
false,
false,
false,
false};
444 for (
uint08 e = 0; e < 12; ++e)
446 const uint01 i0 = edge_pairs[e][0];
447 const uint01 i1 = edge_pairs[e][1];
450 const t_type wa = a[W], wb = b[W];
452 const bool a_in = wa > t_type(0);
453 const bool b_in = wb > t_type(0);
458 result.
addToBounds(a.template as<3, t_type>() / wa);
462 result.
addToBounds(b.template as<3, t_type>() / wb);
466 else if (a_in || b_in)
468 const t_type t = (t_type(1e-5) - wa) / (wb - wa);
471 if (a_in && !added[i0]) {
472 result.
addToBounds(a.template as<3, t_type>() / wa);
475 else if (b_in && !added[i1]) {
476 result.
addToBounds(b.template as<3, t_type>() / wb);
492 template<
class t_type, u
int01 t_row_dims, u
int01 t_col_dims>
495 for (
uint01 i = 0; i < t_row_dims; i++)
496 if (!
equals(a[i], b[i], epsilon))
507 template<
class t_type, u
int01 t_row_dims, u
int01 t_col_dims>
511 for (
uint01 i = 0; i < t_row_dims; i++)
512 multiplied_matrix[i] = mult * matrix[i];
513 return multiplied_matrix;
529 bool solve_offset_xy =
true;;
A specification of upper and lower bounds in N-dimensions.
constexpr void addToBounds(const t_vertex &vector)
The equivelent of std::vector but with a bit more control.
constexpr const t_vertex & vertex(uint01 index) const
Provides static utility functions for solving best-fit and affine matrix transformations.
static Matrix< fltp08 > SolveBestFitTransform(const TransformSolveOptions &options)
Computes the best-fit rigid or similarity transform between two point sets.
static Matrix< fltp08 > SolveLeastSquaredAffine(const Buffer< Vertex< 3, fltp08 > > &a, const Buffer< Vertex< 3, fltp08 > > &b)
Solves for the least-squared affine transformation between two 3D point sets.
static Matrix< fltp08 > Solve2DAffine(const Buffer< Vertex< 2, fltp08 > > &a, const Buffer< Vertex< 2, fltp08 > > &b)
Solves for a 2D affine transformation between two sets of 2D points.
Templated logic for doing matrix multiplication.
A sequence of connected line segments defined by ordered vertices along a path.
uint04 vertexCount() const
const t_vertex & vertex(uint04 index) const
void add(const t_vertex &vertex)
A three-vertex polygon representing a triangle in N-dimensional space.
constexpr t_vertex & vertex(TriangleLocation triangle_node)
Vertices the given triangle node.
A point in N-dimensional space, used primarily for spatial location information.
The primary namespace for the NDEVR SDK.
Bounds< 3, t_type > TransformBoundsAndClipNearPlane(const Bounds< 3, t_type, t_vertex > &bounds, const Matrix< t_type, 4, 4 > &m)
Transforms 3D bounds by a 4x4 matrix and clips edges against the near plane (w=0).
uint64_t uint08
-Defines an alias representing an 8 byte, unsigned integer
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...
static constexpr Angle< t_type > operator*(const Angle< t_type > &angle_a, const Angle< t_type > &angle_b)
Multiplication operator.
uint8_t uint01
-Defines an alias representing a 1 byte, unsigned integer -Can represent exact integer values 0 throu...
static constexpr bool IsInvalid(const Angle< t_type > &value)
Checks whether the given Angle holds an invalid value.
constexpr bool equals(const LineSegment< t_dims, t_type, t_vertex > &left, const LineSegment< t_dims, t_type, t_vertex > &right, const t_type &epsilon=cast< t_type >(0))
Tests if objects are considered equal.
constexpr t_type clip(const t_type &value, const t_type &lower_bound, const t_type &upper_bound)
Clips the value given so that that the returned value falls between upper and lower bound.
constexpr t_to cast(const Angle< t_from > &value)
Casts an Angle from one backing type to another.
Defines for a given type (such as sint04, fltp08, UUID, etc) a maximum, minimum, and reserved 'invali...