diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index 2144107a6cd..7b21c5f6df7 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -144,6 +144,8 @@ void mat4_to_size(float r[3], float M[4][4]); void translate_m4(float mat[4][4], float tx, float ty, float tz); void rotate_m4(float mat[4][4], const char axis, const float angle); + +void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[][3]); void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[][4]); void loc_eul_size_to_mat4(float R[4][4], @@ -155,8 +157,8 @@ void loc_quat_size_to_mat4(float R[4][4], void loc_axisangle_size_to_mat4(float R[4][4], const float loc[3], const float axis[4], const float angle, const float size[3]); -void blend_m3_m3m3(float R[3][3], float A[3][3], float B[3][3], float t); -void blend_m4_m4m4(float R[4][4], float A[4][4], float B[4][4], float t); +void blend_m3_m3m3(float R[3][3], float A[3][3], float B[3][3], const float t); +void blend_m4_m4m4(float R[4][4], float A[4][4], float B[4][4], const float t); int is_negative_m3(float mat[3][3]); int is_negative_m4(float mat[4][4]); diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index d2bd7a0a2b1..154eb746e5c 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -976,17 +976,15 @@ float mat4_to_scale(float mat[][4]) return mat3_to_scale(tmat); } -void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[][4]) + +void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]) { - float mat3[3][3]; /* wmat -> 3x3 */ - float mat3_n[3][3]; /* wmat -> normalized, 3x3 */ - float imat3_n[3][3]; /* wmat -> normalized & inverted, 3x3 */ - /* location */ - copy_v3_v3(loc, wmat[3]); + float mat3_n[3][3]; /* mat3 -> normalized, 3x3 */ + float imat3_n[3][3]; /* mat3 -> normalized & inverted, 3x3 */ /* rotation & scale are linked, we need to create the mat's * for these together since they are related. */ - copy_m3_m4(mat3, wmat); + /* so scale doesnt interfear with rotation [#24291] */ /* note: this is a workaround for negative matrix not working for rotation conversion, FIXME */ normalize_m3_m3(mat3_n, mat3); @@ -1010,6 +1008,17 @@ void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wm size[2]= mat3[2][2]; } +void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[][4]) +{ + float mat3[3][3]; /* wmat -> 3x3 */ + + copy_m3_m4(mat3, wmat); + mat3_to_rot_size(rot, size, mat3); + + /* location */ + copy_v3_v3(loc, wmat[3]); +} + void scale_m3_fl(float m[][3], float scale) { m[0][0]= m[1][1]= m[2][2]= scale; @@ -1075,18 +1084,19 @@ void rotate_m4(float mat[][4], const char axis, const float angle) } } -void blend_m3_m3m3(float out[][3], float dst[][3], float src[][3], float srcweight) +void blend_m3_m3m3(float out[][3], float dst[][3], float src[][3], const float srcweight) { + float srot[3][3], drot[3][3]; float squat[4], dquat[4], fquat[4]; float ssize[3], dsize[3], fsize[3]; float rmat[3][3], smat[3][3]; - mat3_to_quat(dquat,dst); - mat3_to_size(dsize,dst); + mat3_to_rot_size(drot, dsize, dst); + mat3_to_rot_size(srot, ssize, src); + + mat3_to_quat(dquat, drot); + mat3_to_quat(squat, srot); - mat3_to_quat(squat,src); - mat3_to_size(ssize,src); - /* do blending */ interp_qt_qtqt(fquat, dquat, squat, srcweight); interp_v3_v3v3(fsize, dsize, ssize, srcweight); @@ -1097,20 +1107,19 @@ void blend_m3_m3m3(float out[][3], float dst[][3], float src[][3], float srcweig mul_m3_m3m3(out, rmat, smat); } -void blend_m4_m4m4(float out[][4], float dst[][4], float src[][4], float srcweight) +void blend_m4_m4m4(float out[][4], float dst[][4], float src[][4], const float srcweight) { + float sloc[3], dloc[3], floc[3]; + float srot[3][3], drot[3][3]; float squat[4], dquat[4], fquat[4]; float ssize[3], dsize[3], fsize[3]; - float sloc[3], dloc[3], floc[3]; - - mat4_to_quat(dquat,dst); - mat4_to_size(dsize,dst); - copy_v3_v3(dloc, dst[3]); - mat4_to_quat(squat,src); - mat4_to_size(ssize,src); - copy_v3_v3(sloc, src[3]); - + mat4_to_loc_rot_size(dloc, drot, dsize, dst); + mat4_to_loc_rot_size(sloc, srot, ssize, src); + + mat3_to_quat(dquat, drot); + mat3_to_quat(squat, srot); + /* do blending */ interp_v3_v3v3(floc, dloc, sloc, srcweight); interp_qt_qtqt(fquat, dquat, squat, srcweight); diff --git a/source/blender/python/generic/mathutils_matrix.c b/source/blender/python/generic/mathutils_matrix.c index 232d24714c5..fc717b0013b 100644 --- a/source/blender/python/generic/mathutils_matrix.c +++ b/source/blender/python/generic/mathutils_matrix.c @@ -1043,6 +1043,50 @@ static PyObject *Matrix_decompose(MatrixObject * self) } + +static char Matrix_Lerp_doc[] = +".. function:: lerp(other, factor)\n" +"\n" +" Returns the interpolation of two matricies.\n" +"\n" +" :arg other: value to interpolate with.\n" +" :type other: :class:`Matrix`\n" +" :arg factor: The interpolation value in [0.0, 1.0].\n" +" :type factor: float\n" +" :return: The interpolated rotation.\n" +" :rtype: :class:`Matrix`\n"; + +static PyObject *Matrix_Lerp(MatrixObject *self, PyObject *args) +{ + MatrixObject *mat2 = NULL; + float fac, mat[MATRIX_MAX_DIM*MATRIX_MAX_DIM]; + + if(!PyArg_ParseTuple(args, "O!f:lerp", &matrix_Type, &mat2, &fac)) + return NULL; + + if(self->rowSize != mat2->rowSize || self->colSize != mat2->colSize) { + PyErr_SetString(PyExc_AttributeError, "matrix.lerp(): expects both matrix objects of the same dimensions"); + return NULL; + } + + if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(mat2)) + return NULL; + + /* TODO, different sized matrix */ + if(self->rowSize==4 && self->colSize==4) { + blend_m4_m4m4((float (*)[4])mat, (float (*)[4])self->contigPtr, (float (*)[4])mat2->contigPtr, fac); + } + else if (self->rowSize==3 && self->colSize==3) { + blend_m3_m3m3((float (*)[3])mat, (float (*)[3])self->contigPtr, (float (*)[3])mat2->contigPtr, fac); + } + else { + PyErr_SetString(PyExc_AttributeError, "matrix.lerp(): only 3x3 and 4x4 matrices supported"); + return NULL; + } + + return (PyObject*)newMatrixObject(mat, self->rowSize, self->colSize, Py_NEW, Py_TYPE(self)); +} + /*---------------------------Matrix.determinant() ----------------*/ static char Matrix_Determinant_doc[] = ".. method:: determinant()\n" @@ -1791,6 +1835,7 @@ static struct PyMethodDef Matrix_methods[] = { {"zero", (PyCFunction) Matrix_Zero, METH_NOARGS, Matrix_Zero_doc}, {"identity", (PyCFunction) Matrix_Identity, METH_NOARGS, Matrix_Identity_doc}, {"transpose", (PyCFunction) Matrix_Transpose, METH_NOARGS, Matrix_Transpose_doc}, + {"lerp", (PyCFunction) Matrix_Lerp, METH_VARARGS, Matrix_Lerp_doc}, {"determinant", (PyCFunction) Matrix_Determinant, METH_NOARGS, Matrix_Determinant_doc}, {"invert", (PyCFunction) Matrix_Invert, METH_NOARGS, Matrix_Invert_doc}, {"translation_part", (PyCFunction) Matrix_TranslationPart, METH_NOARGS, Matrix_TranslationPart_doc}, diff --git a/source/blender/python/generic/mathutils_matrix.h b/source/blender/python/generic/mathutils_matrix.h index 21538f8168e..f1cce3a45a8 100644 --- a/source/blender/python/generic/mathutils_matrix.h +++ b/source/blender/python/generic/mathutils_matrix.h @@ -38,10 +38,9 @@ extern PyTypeObject matrix_Type; typedef struct { BASE_MATH_MEMBERS(contigPtr) - - unsigned char rowSize; - unsigned int colSize; float *matrix[MATRIX_MAX_DIM]; /* ptr to the contigPtr (accessor) */ + unsigned short rowSize; + unsigned short colSize; } MatrixObject; /*struct data contains a pointer to the actual data that the diff --git a/source/blender/python/generic/mathutils_vector.c b/source/blender/python/generic/mathutils_vector.c index e4027d7a80e..4dd2e250804 100644 --- a/source/blender/python/generic/mathutils_vector.c +++ b/source/blender/python/generic/mathutils_vector.c @@ -670,7 +670,7 @@ static PyObject *Vector_Lerp(VectorObject *self, PyObject *args) return NULL; if(self->size != vec2->size) { - PyErr_SetString(PyExc_AttributeError, "vector.lerp(): expects (2) vector objects of the same size"); + PyErr_SetString(PyExc_AttributeError, "vector.lerp(): expects both vector objects to have the same size"); return NULL; }