Now that B-Bone shape data is kept in bPoseChannel_Runtime, the armature level cache only holds one quaternion value per bone. It can also be moved to runtime, and the structure removed. This has an additional effect that, as far as I can tell, now the Armature modifier can run as soon as all of the bones it actually needs are done, thus making T59848 a purely depsgraph level problem.
248 lines
10 KiB
C++
248 lines
10 KiB
C++
/*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
* All rights reserved.
|
|
*
|
|
* The Original Code is: some of this file.
|
|
*
|
|
* */
|
|
|
|
#ifndef __BLI_MATH_ROTATION_H__
|
|
#define __BLI_MATH_ROTATION_H__
|
|
|
|
/** \file
|
|
* \ingroup bli
|
|
*/
|
|
|
|
#include "DNA_vec_types.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define RAD2DEG(_rad) ((_rad) * (180.0 / M_PI))
|
|
#define DEG2RAD(_deg) ((_deg) * (M_PI / 180.0))
|
|
|
|
#define RAD2DEGF(_rad) ((_rad) * (float)(180.0 / M_PI))
|
|
#define DEG2RADF(_deg) ((_deg) * (float)(M_PI / 180.0))
|
|
|
|
/******************************** Quaternions ********************************/
|
|
/* stored in (w, x, y, z) order */
|
|
|
|
/* init */
|
|
void unit_axis_angle(float axis[3], float *angle);
|
|
void unit_qt(float q[4]);
|
|
void copy_qt_qt(float q[4], const float a[4]);
|
|
|
|
/* arithmetic */
|
|
void mul_qt_qtqt(float q[4], const float a[4], const float b[4]);
|
|
void mul_qt_v3(const float q[4], float r[3]);
|
|
void mul_qt_fl(float q[4], const float f);
|
|
|
|
void pow_qt_fl_normalized(float q[4], const float f);
|
|
|
|
void sub_qt_qtqt(float q[4], const float a[4], const float b[4]);
|
|
|
|
void invert_qt(float q[4]);
|
|
void invert_qt_qt(float q1[4], const float q2[4]);
|
|
void invert_qt_normalized(float q[4]);
|
|
void invert_qt_qt_normalized(float q1[4], const float q2[4]);
|
|
void conjugate_qt(float q[4]);
|
|
void conjugate_qt_qt(float q1[4], const float q2[4]);
|
|
float dot_qtqt(const float a[4], const float b[4]);
|
|
float normalize_qt(float q[4]);
|
|
float normalize_qt_qt(float q1[4], const float q2[4]);
|
|
|
|
/* comparison */
|
|
bool is_zero_qt(const float q[4]);
|
|
|
|
/* interpolation */
|
|
void interp_dot_slerp(const float t, const float cosom, float w[2]);
|
|
void interp_qt_qtqt(float q[4], const float a[4], const float b[4], const float t);
|
|
void add_qt_qtqt(float q[4], const float a[4], const float b[4], const float t);
|
|
|
|
/* conversion */
|
|
void quat_to_mat3(float mat[3][3], const float q[4]);
|
|
void quat_to_mat4(float mat[4][4], const float q[4]);
|
|
|
|
void quat_to_compatible_quat(float q[4], const float a[4], const float old[4]);
|
|
|
|
void mat3_normalized_to_quat(float q[4], const float mat[3][3]);
|
|
void mat4_normalized_to_quat(float q[4], const float mat[4][4]);
|
|
void mat3_to_quat(float q[4], const float mat[3][3]);
|
|
void mat4_to_quat(float q[4], const float mat[4][4]);
|
|
void tri_to_quat_ex(float quat[4],
|
|
const float v1[3],
|
|
const float v2[3],
|
|
const float v3[3],
|
|
const float no_orig[3]);
|
|
float tri_to_quat(float q[4], const float a[3], const float b[3], const float c[3]);
|
|
void vec_to_quat(float q[4], const float vec[3], short axis, const short upflag);
|
|
/* note: v1 and v2 must be normalized */
|
|
void rotation_between_vecs_to_mat3(float m[3][3], const float v1[3], const float v2[3]);
|
|
void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3]);
|
|
void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q2[4]);
|
|
|
|
float angle_normalized_qt(const float q[4]);
|
|
float angle_normalized_qtqt(const float q1[4], const float q2[4]);
|
|
float angle_qt(const float q[4]);
|
|
float angle_qtqt(const float q1[4], const float q2[4]);
|
|
|
|
float angle_signed_normalized_qt(const float q[4]);
|
|
float angle_signed_normalized_qtqt(const float q1[4], const float q2[4]);
|
|
float angle_signed_qt(const float q[4]);
|
|
float angle_signed_qtqt(const float q1[4], const float q2[4]);
|
|
|
|
/* TODO: don't what this is, but it's not the same as mat3_to_quat */
|
|
void mat3_to_quat_is_ok(float q[4], const float mat[3][3]);
|
|
|
|
/* other */
|
|
void print_qt(const char *str, const float q[4]);
|
|
|
|
#define print_qt_id(q) print_qt(STRINGIFY(q), q)
|
|
|
|
/******************************** Axis Angle *********************************/
|
|
|
|
/* conversion */
|
|
void axis_angle_normalized_to_quat(float r[4], const float axis[3], const float angle);
|
|
void axis_angle_to_quat(float r[4], const float axis[3], const float angle);
|
|
void axis_angle_to_mat3(float R[3][3], const float axis[3], const float angle);
|
|
void axis_angle_normalized_to_mat3_ex(float mat[3][3],
|
|
const float axis[3],
|
|
const float angle_sin,
|
|
const float angle_cos);
|
|
void axis_angle_normalized_to_mat3(float R[3][3], const float axis[3], const float angle);
|
|
void axis_angle_to_mat4(float R[4][4], const float axis[3], const float angle);
|
|
|
|
void mat3_normalized_to_axis_angle(float axis[3], float *angle, const float M[3][3]);
|
|
void mat4_normalized_to_axis_angle(float axis[3], float *angle, const float M[4][4]);
|
|
void mat3_to_axis_angle(float axis[3], float *angle, const float M[3][3]);
|
|
void mat4_to_axis_angle(float axis[3], float *angle, const float M[4][4]);
|
|
void quat_to_axis_angle(float axis[3], float *angle, const float q[4]);
|
|
|
|
void angle_to_mat2(float R[2][2], const float angle);
|
|
void axis_angle_to_mat3_single(float R[3][3], const char axis, const float angle);
|
|
void axis_angle_to_mat4_single(float R[4][4], const char axis, const float angle);
|
|
|
|
void axis_angle_to_quat_single(float q[4], const char axis, const float angle);
|
|
|
|
/****************************** Exponential Map ******************************/
|
|
void quat_to_expmap(float expmap[3], const float q[4]);
|
|
void quat_normalized_to_expmap(float expmap[3], const float q[4]);
|
|
void expmap_to_quat(float r[4], const float expmap[3]);
|
|
|
|
/******************************** XYZ Eulers *********************************/
|
|
|
|
void eul_to_quat(float quat[4], const float eul[3]);
|
|
void eul_to_mat3(float mat[3][3], const float eul[3]);
|
|
void eul_to_mat4(float mat[4][4], const float eul[3]);
|
|
|
|
void mat3_normalized_to_eul(float eul[3], const float mat[3][3]);
|
|
void mat4_normalized_to_eul(float eul[3], const float mat[4][4]);
|
|
void mat3_to_eul(float eul[3], const float mat[3][3]);
|
|
void mat4_to_eul(float eul[3], const float mat[4][4]);
|
|
void quat_to_eul(float eul[3], const float quat[4]);
|
|
|
|
void mat3_normalized_to_compatible_eul(float eul[3], const float old[3], float mat[3][3]);
|
|
void mat3_to_compatible_eul(float eul[3], const float old[3], float mat[3][3]);
|
|
void quat_to_compatible_eul(float eul[3], const float oldrot[3], const float quat[4]);
|
|
void compatible_eul(float eul[3], const float old[3]);
|
|
|
|
void rotate_eul(float eul[3], const char axis, const float angle);
|
|
|
|
/************************** Arbitrary Order Eulers ***************************/
|
|
|
|
/* warning: must match the eRotationModes in DNA_action_types.h
|
|
* order matters - types are saved to file. */
|
|
|
|
typedef enum eEulerRotationOrders {
|
|
EULER_ORDER_DEFAULT = 1, /* blender classic = XYZ */
|
|
EULER_ORDER_XYZ = 1,
|
|
EULER_ORDER_XZY,
|
|
EULER_ORDER_YXZ,
|
|
EULER_ORDER_YZX,
|
|
EULER_ORDER_ZXY,
|
|
EULER_ORDER_ZYX,
|
|
/* there are 6 more entries with dulpicate entries included */
|
|
} eEulerRotationOrders;
|
|
|
|
void eulO_to_quat(float quat[4], const float eul[3], const short order);
|
|
void eulO_to_mat3(float mat[3][3], const float eul[3], const short order);
|
|
void eulO_to_mat4(float mat[4][4], const float eul[3], const short order);
|
|
void eulO_to_axis_angle(float axis[3], float *angle, const float eul[3], const short order);
|
|
void eulO_to_gimbal_axis(float gmat[3][3], const float eul[3], const short order);
|
|
|
|
void mat3_normalized_to_eulO(float eul[3], const short order, const float mat[3][3]);
|
|
void mat4_normalized_to_eulO(float eul[3], const short order, const float mat[4][4]);
|
|
void mat3_to_eulO(float eul[3], const short order, const float mat[3][3]);
|
|
void mat4_to_eulO(float eul[3], const short order, const float mat[4][4]);
|
|
void quat_to_eulO(float eul[3], const short order, const float quat[4]);
|
|
void axis_angle_to_eulO(float eul[3], const short order, const float axis[3], const float angle);
|
|
|
|
void mat3_normalized_to_compatible_eulO(float eul[3],
|
|
const float old[3],
|
|
const short order,
|
|
const float mat[3][3]);
|
|
void mat4_normalized_to_compatible_eulO(float eul[3],
|
|
const float old[3],
|
|
const short order,
|
|
const float mat[4][4]);
|
|
void mat3_to_compatible_eulO(float eul[3],
|
|
const float old[3],
|
|
const short order,
|
|
const float mat[3][3]);
|
|
void mat4_to_compatible_eulO(float eul[3],
|
|
const float old[3],
|
|
const short order,
|
|
const float mat[4][4]);
|
|
void quat_to_compatible_eulO(float eul[3],
|
|
const float old[3],
|
|
const short order,
|
|
const float quat[4]);
|
|
|
|
void rotate_eulO(float eul[3], const short order, char axis, float angle);
|
|
|
|
/******************************* Dual Quaternions ****************************/
|
|
|
|
void copy_dq_dq(DualQuat *r, const DualQuat *dq);
|
|
void normalize_dq(DualQuat *dq, float totw);
|
|
void add_weighted_dq_dq(DualQuat *r, const DualQuat *dq, float weight);
|
|
void mul_v3m3_dq(float r[3], float R[3][3], DualQuat *dq);
|
|
|
|
void mat4_to_dquat(DualQuat *r, const float base[4][4], const float M[4][4]);
|
|
void dquat_to_mat4(float R[4][4], const DualQuat *dq);
|
|
|
|
void quat_apply_track(float quat[4], short axis, short upflag);
|
|
void vec_apply_track(float vec[3], short axis);
|
|
|
|
float focallength_to_fov(float focal_length, float sensor);
|
|
float fov_to_focallength(float fov, float sensor);
|
|
|
|
float angle_wrap_rad(float angle);
|
|
float angle_wrap_deg(float angle);
|
|
|
|
float angle_compat_rad(float angle, float angle_compat);
|
|
|
|
bool mat3_from_axis_conversion(
|
|
int src_forward, int src_up, int dst_forward, int dst_up, float r_mat[3][3]);
|
|
bool mat3_from_axis_conversion_single(int src_axis, int dst_axis, float r_mat[3][3]);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* __BLI_MATH_ROTATION_H__ */
|