11 #ifndef __UT_TRANSFORMUTIL_H_INCLUDED__
12 #define __UT_TRANSFORMUTIL_H_INCLUDED__
62 template<
typename PREC>
72 bool* pLS_init_ptr=
nullptr
92 bool* pLS_init_ptr =
nullptr);
95 template<
typename PREC>
104 template<
typename PREC>
118 bool HAS_EFFECTIVE_LOCAL =
false
177 template <
typename PREC>
216 template <
typename PREC>
230 const UT_Vector3T<PREC> &reflection_hint
231 = UT_Vector3T<PREC>(1., 1., 1.));
250 bool NORMALIZE_WEIGHTS =
true,
266 const PREC input_weight);
271 bool NORMALIZE_WEIGHTS =
true
277 template<
typename PREC>
328 bool tmp_pLS_init =
true;
332 bool &pLS_init = HAS_PLS ? *pLS_init_ptr : tmp_pLS_init;
334 if (effective_local && effective_local != &L)
335 *effective_local = L;
368 constexpr UT_Vector3T<PREC> _t0{ 0.0, 0.0, 0.0 };
372 UT_Vector3T<PREC> _t;
383 constexpr UT_Vector3T<PREC> _t0{ 0.0, 0.0, 0.0 };
387 UT_Vector3T<PREC> _t;
421 template<
typename PREC>
433 #define UT_TRANSFORM_COMBINE(M, A) \
434 return UTtransformCombineLocalT<PREC, M, A>( \
435 L, pW, pL, effective_local, pLS_ptr, pLS_inv_ptr, pLS_init_ptr); \
437 #define IF_UT_TRANSFORM_COMBINE(M, A) \
439 UT_TRANSFORM_COMBINE(M, A) \
442 if (pLS_init_ptr && pLS_ptr && pLS_inv_ptr)
454 pLS_inv_ptr =
nullptr;
455 pLS_init_ptr =
nullptr;
467 template<
typename PREC>
496 *effective_local = L;
501 UT_Vector3T<PREC> T_vec;
520 *effective_local = L;
525 UT_Vector3T<PREC> T_vec;
543 *effective_local = L;
567 *effective_local = L;
583 *effective_local = L;
590 *effective_local = L;
597 template<
typename PREC, UT_ScaleInheritanceMode MODE,
bool HAS_EFFECTIVE_LOCAL>
624 if (HAS_EFFECTIVE_LOCAL && effective_local)
625 *effective_local = L;
630 UT_Vector3T<PREC> T_vec;
648 if (HAS_EFFECTIVE_LOCAL && effective_local)
649 *effective_local = L;
654 UT_Vector3T<PREC> T_vec;
671 if (HAS_EFFECTIVE_LOCAL && effective_local)
672 *effective_local = L;
695 if (HAS_EFFECTIVE_LOCAL && effective_local)
696 *effective_local = L;
711 if (HAS_EFFECTIVE_LOCAL && effective_local)
712 *effective_local = L;
718 if (HAS_EFFECTIVE_LOCAL && effective_local)
719 *effective_local = L;
726 template<
typename PREC>
745 bool NORMALIZE_WEIGHTS,
753 const int n = xforms.size();
761 const PREC *weights = input_weights.
data();
763 const int kSmallArrayElements = 16;
765 if (NORMALIZE_WEIGHTS)
767 PREC total_weights = 0;
768 for (PREC
w : input_weights)
771 if (total_weights > 0)
774 for (
int i = 0; i <
n; ++i)
775 new_weights[i] = input_weights[i] / total_weights;
776 weights = new_weights.
data();
788 xforms[0].getTranslates(translate);
789 translate *= weights[0];
793 stretch *= weights[0];
800 for (
int i = 1; i <
n; ++i)
802 const PREC
w = weights[i];
805 xforms[i].getTranslates(t);
811 stretch += w * stretch_tmp;
833 rots.setSizeNoInit(n);
834 for (
int i = 0; i <
n; ++i)
836 const PREC
w = weights[i];
839 xforms[i].getTranslates(t);
845 stretch += w * stretch_tmp;
847 rots[i].updateFromRotationMatrix(rotate_tmp);
851 quat.
interpolate(rots.data(), weights, rots.size());
859 result.setTranslates(translate);
870 const PREC input_weight)
872 const PREC weight0 = ((PREC)1.0) - input_weight;
873 const PREC weight1 = input_weight;
884 translate *= weight0;
896 const PREC
w = weight1;
904 rotate_tmp.makeRotationMatrix(&stretch_tmp);
905 stretch += w * stretch_tmp;
928 const PREC
w = weight0;
936 rotate_tmp.makeRotationMatrix(&stretch_tmp);
937 stretch += w * stretch_tmp;
943 const PREC
w = weight1;
951 rotate_tmp.makeRotationMatrix(&stretch_tmp);
952 stretch += w * stretch_tmp;
966 result.setTranslates(translate);
979 const PREC weight0 = ((PREC)1.0) - input_weight;
980 const PREC weight1 = input_weight;
987 auto cachedMakeRot = [&makerotcache](
993 if (makerotcache->
rot==in_xfo)
995 io_quat = makerotcache->
quat;
996 io_stretch = makerotcache->
stretch;
1003 in_rot.makeRotationMatrix(&io_stretch);
1004 io_quat.updateFromRotationMatrix(in_rot);
1007 makerotcache->
rot = in_xfo;
1008 makerotcache->
quat = io_quat;
1009 makerotcache->
stretch = io_stretch;
1020 translate *= weight0;
1023 cachedMakeRot(xform0,stretch,quat);
1030 const PREC
w = weight1;
1032 UT_Vector3T<PREC>
t;
1038 cachedMakeRot(xform1,stretch_tmp,q);
1039 stretch += w * stretch_tmp;
1041 if (
dot(ref, q) < 0)
1059 const PREC
w = weight0;
1061 UT_Vector3T<PREC>
t;
1066 cachedMakeRot(xform0,stretch_tmp,rot0);
1067 stretch += w * stretch_tmp;
1072 const PREC
w = weight1;
1074 UT_Vector3T<PREC>
t;
1079 cachedMakeRot(xform1,stretch_tmp,rot1);
1080 stretch += w * stretch_tmp;
1092 result.setTranslates(translate);
1098 template <
typename T,
bool NORMALIZE_WEIGHTS>
1101 template <
typename T>
1114 template <
typename T>
1121 const T *
w = weights.
data();
1125 const int n = weights.
size();
1126 for (
int i = 0; i <
n; ++i)
1131 for (
int i = 0; i <
n; ++i)
1132 tmp_weights[i] = w[i] / total;
1133 w = tmp_weights.
data();
1143 template <
typename PREC,
bool NORMALIZE_WEIGHTS>
1152 template<
typename PREC>
1156 const UT_Vector3T<PREC> &parent_local_s,
1158 const UT_Vector3T<PREC> &parm_t,
1159 const UT_Vector3T<PREC> &parm_r,
1160 const UT_Vector3T<PREC> &parm_s,
1161 const UT_Vector3T<PREC> &parm_p,
1162 const UT_Vector3T<PREC> &parm_pr,
1171 pivotspace.myTranslate = parm_p;
1172 pivotspace.myRotate = parm_pr;
1175 adjust.
xform(adjust_ord,
1176 parm_t[0], parm_t[1], parm_t[2],
1177 parm_r[0], parm_r[1], parm_r[2],
1178 parm_s[0], parm_s[1], parm_s[2],
1189 UT_Vector3T<PREC> local_t;
1190 UT_Vector3T<PREC> local_r;
1191 UT_Vector3T<PREC> local_s;
1192 local.
explode(order, local_r, local_s, local_t,
nullptr);
1194 UT_Vector3T<PREC>
t;
1195 UT_Vector3T<PREC>
r;
1196 UT_Vector3T<PREC>
s;
1198 order, r, s, t,
nullptr );
1202 if( scales_local_t )
1217 t *= 1.0 / (parent_local_s);
1234 q = parm_q * local_q;
1236 q = local_q * parm_q;
1252 t.x(), t.y(), t.z(),
1253 r.
x(), r.
y(), r.
z(),
1254 s.x(), s.y(), s.z() );
1257 template <
typename PREC>
1265 const UT_Vector3T<PREC> &parent_local_s,
1266 UT_Vector3T<PREC> &parm_t,
1267 UT_Vector3T<PREC> &parm_r,
1268 UT_Vector3T<PREC> &parm_s
1276 local.
explode(parmorder, parm_r, parm_s, parm_t,
nullptr);
1283 UT_Vector3T<PREC> local_t;
1284 UT_Vector3T<PREC> local_r;
1285 UT_Vector3T<PREC> local_s;
1286 local.
explode(order, local_r, local_s, local_t,
nullptr);
1288 UT_Vector3T<PREC> input_t;
1289 UT_Vector3T<PREC> input_r;
1290 UT_Vector3T<PREC> input_s;
1291 inputlocal.
explode(order, input_r, input_s, input_t,
nullptr);
1293 adjust.explode(order, parm_r, parm_s, parm_t,
nullptr);
1296 parm_t = local_t - input_t;
1297 parm_s = local_s / input_s;
1304 parm_t *= (parent_local_s);
1331 q = local_q * input_q;
1336 q = input_q * local_q;
1342 mq.
crack(parm_r,order);
1347 result.
xform(order, parm_t[0], parm_t[1], parm_t[2],
1348 parm_r[0], parm_r[1], parm_r[2],
1349 parm_s[0], parm_s[1], parm_s[2]);
1350 result.
explode(parmorder, parm_r, parm_s, parm_t,
nullptr);
1357 template <
typename PREC>
1361 const UT_Vector3T<PREC> &reflect_hint,
1362 UT_Vector3T<PREC> &xform_r,
1363 UT_Vector3T<PREC> &xform_s,
1364 UT_Vector3T<PREC> &xform_t,
1366 UT_Vector3T<PREC> *xform_sh)
1372 xform.
explode(order, xform_r, xform_s, xform_t, pivot_space, xform_sh);
1383 xform3.
rotate(xform_r, order);
1387 if ((xform_s[0] < 0) != (reflect_hint[0] < 0))
1393 if ((xform_s[1] < 0) != (reflect_hint[1] < 0))
1399 if ((xform_s[2] < 0) != (reflect_hint[2] < 0))
1406 xform3.
crack(xform_r, order);
1411 template <
typename PREC>
1416 UT_Vector3T<PREC> parm_t,
1417 UT_Vector3T<PREC> parm_r,
1418 UT_Vector3T<PREC> parm_s,
1419 UT_Vector3T<PREC> parm_sh,
1424 using Vector3 = UT_Vector3T<PREC>;
1431 parm.xform(parm_ord,
1432 parm_t(0), parm_t(1), parm_t(2),
1433 parm_r(0), parm_r(1), parm_r(2),
1434 parm_s(0), parm_s(1), parm_s(2),
1435 parm_sh(0), parm_sh(1), parm_sh(2),
1447 if (parm_ord !=
order)
1450 parm.xform(parm_ord,
1451 parm_t(0), parm_t(1), parm_t(2),
1452 parm_r(0), parm_r(1), parm_r(2),
1453 parm_s(0), parm_s(1), parm_s(2),
1454 parm_sh(0), parm_sh(1), parm_sh(2),
1457 parm.explode(
order, parm_r, parm_s, parm_t, pivot_space, &parm_sh);
1464 Vector3 local_t, local_r, local_s, local_sh;
1465 local.
explode(
order, local_r, local_s, local_t, pivot_space, &local_sh);
1468 Vector3 combined_s = parm_s * local_s;
1469 Vector3 combined_sh = parm_sh + local_sh;
1472 Vector3 combined_t, combined_r;
1480 if (
SYSsignum(local_s(0) * local_s(1) * local_s(2) < 0))
1488 combined_q = local_q * parm_q;
1489 combined_t = local_q.rotate(parm_t) + local_t;
1493 combined_q = parm_q * local_q;
1494 combined_t = parm_t + local_t;
1498 UT_ASSERT(!
"Unknown UT_ParameterTransformMode.");
1502 combined_r = combined_q.computeRotations(
order);
1503 combined_r.radToDeg();
1506 combined_local.xform(
order,
1507 combined_t(0), combined_t(1), combined_t(2),
1508 combined_r(0), combined_r(1), combined_r(2),
1509 combined_s(0), combined_s(1), combined_s(2),
1510 combined_sh(0), combined_sh(1), combined_sh(2),
1513 return combined_local;
1516 template <
typename PREC>
1528 const UT_Vector3T<PREC> &reflect_hint)
1531 using Vector3 = UT_Vector3T<PREC>;
1534 Vector3 parm_t, parm_r, parm_s, parm_sh;
1537 local.
explode(parm_ord, parm_r, parm_s, parm_t, pivot_space, &parm_sh);
1539 return {parm_t, parm_r, parm_s, parm_sh};
1553 Vector3 local_t, local_r, local_s, local_sh;
1555 local, reflect_hint, local_r, local_s, local_t, pivot_space,
1559 Vector3 rel_t, rel_r, rel_s, rel_sh;
1560 relative_local.
explode(
order, rel_r, rel_s, rel_t, pivot_space, &rel_sh);
1563 parm_s = local_s / rel_s;
1564 parm_sh = local_sh - rel_sh;
1574 parm_q = rel_inv_q * local_q;
1575 parm_t = rel_inv_q.rotate(local_t - rel_t);
1578 if (
SYSsignum(rel_s[0] * rel_s[1] * rel_s[2]) < 0)
1588 parm_q = local_q * rel_inv_q;
1589 parm_t = local_t - rel_t;
1593 UT_ASSERT(!
"Unknown UT_ParameterTransformMode.");
1597 parm_r = parm_q.computeRotations(
order);
1602 if (parm_ord !=
order)
1606 parm_t(0), parm_t(1), parm_t(2),
1607 parm_r(0), parm_r(1), parm_r(2),
1608 parm_s(0), parm_s(1), parm_s(2),
1609 parm_sh(0), parm_sh(1), parm_sh(2),
1612 parm.explode(parm_ord, parm_r, parm_s, parm_t, pivot_space, &parm_sh);
1616 return {parm_t, parm_r, parm_s, parm_sh};
1619 #endif // __UT_TRANSFORMUTIL_H_INCLUDED__
UT_Matrix3T< PREC > stretch
void setSizeNoInit(exint newsize)
void radToDeg()
conversion between degrees and radians
constexpr SYS_FORCE_INLINE T & z() noexcept
void prescale(T sx, T sy, T sz)
**But if you need a result
void getRotationMatrix(UT_Matrix3 &mat) const
GLdouble GLdouble GLdouble q
UT_QuaternionT< PREC > quat
void degToRad()
conversion between degrees and radians
void identity()
Set the matrix to identity.
constexpr SYS_FORCE_INLINE void negate() noexcept
static const UT_Matrix4T< T > & getIdentityMatrix()
fpreal64 dot(const CE_VectorT< T > &a, const CE_VectorT< T > &b)
int explode(const UT_XformOrder &order, UT_Vector3F &r, UT_Vector3F &s, UT_Vector3F &t, UT_Vector3F *shears=0) const
SYS_FORCE_INLINE void UTexplodeWithReflectionHint(const UT_Matrix4T< PREC > &xform, const UT_Vector3T< PREC > &reflect_hint, UT_Vector3T< PREC > &xform_r, UT_Vector3T< PREC > &xform_s, UT_Vector3T< PREC > &xform_t, const typename UT_Matrix4T< PREC >::PivotSpace &pivot_space, UT_Vector3T< PREC > *xform_sh)
constexpr int SYSsignum(const F a) noexcept
UT_Matrix4T< Float > Matrix4
GLdouble GLdouble GLint GLint order
void identity()
Set the matrix to identity.
ImageBuf OIIO_API rotate(const ImageBuf &src, float angle, string_view filtername=string_view(), float filterwidth=0.0f, bool recompute_roi=false, ROI roi={}, int nthreads=0)
void xform(const UT_XformOrder &order, T tx=0, T ty=0, T tz=0, T rx=0, T ry=0, T rz=0, T sx=1, T sy=1, T sz=1, T px=0, T py=0, T pz=0, int reverse=0)
void setTranslates(const UT_Vector3T< S > &translates)
UT_QuaternionT< T > operator()(const UT_Array< UT_QuaternionT< T >> &quats, const UT_Array< T > &weights)
SYS_NO_DISCARD_RESULT UT_QuaternionT< T > interpolate(const UT_QuaternionT< T > &target, T t, T b=0.0f) const
Interpolates between this quat (t==0) and the target (t==1)
bool polarDecompose(UT_Matrix3T< T > *stretch=nullptr, bool reverse=true, const int max_iter=64, const T rel_tol=FLT_EPSILON)
GLubyte GLubyte GLubyte GLubyte w
void leftMult(const UT_Matrix4T< T > &m)
void rotate(UT_Vector3T< S > &axis, T theta, int norm=1)
PUGI__FN char_t * translate(char_t *buffer, const char_t *from, const char_t *to, size_t to_length)
constexpr SYS_FORCE_INLINE T & y() noexcept
UT_QuaternionT< T > operator()(const UT_Array< UT_QuaternionT< T >> &quats, const UT_Array< T > &weights)
bool polarDecompose(UT_Matrix3T< T > *stretch=nullptr, bool reverse=true, const int max_iter=64, const T rel_tol=FLT_EPSILON)
int crack(UT_Vector3T< S > &rvec, const UT_XformOrder &order) const
bool makeRotationMatrix(UT_Matrix3T< T > *stretch=nullptr, bool reverse=true, const int max_iter=64, const T rel_tol=FLT_EPSILON)
void getTranslates(UT_Vector3T< S > &translates) const
void updateFromRotationMatrix(const UT_Matrix3 &)
void preMultiply(const UT_Matrix4T< T > &m)
constexpr SYS_FORCE_INLINE T & x() noexcept