- blend_m3_m3m3 and blend_m4_m4m4 now support matrices with negative scales.
authorCampbell Barton <ideasman42@gmail.com>
Mon, 22 Nov 2010 10:39:28 +0000 (10:39 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 22 Nov 2010 10:39:28 +0000 (10:39 +0000)
- python/mathutils api matrix.lerp(other, factor)
- new function mat3_to_rot_size(), like mat4_to_loc_rot_size but with no location.

source/blender/blenlib/BLI_math_matrix.h
source/blender/blenlib/intern/math_matrix.c
source/blender/python/generic/mathutils_matrix.c
source/blender/python/generic/mathutils_matrix.h
source/blender/python/generic/mathutils_vector.c

index 2144107a6cdf06ff7b35caaf6b38294473da17bc..7b21c5f6df7a45727b8814818fc91c477f4309c6 100644 (file)
@@ -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 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],
 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 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]);
 
 int is_negative_m3(float mat[3][3]);
 int is_negative_m4(float mat[4][4]);
index d2bd7a0a2b191ed855858bffc80b544188cb5510..154eb746e5cf798566cd1e907ad4ab88c0de7f97 100644 (file)
@@ -976,17 +976,15 @@ float mat4_to_scale(float mat[][4])
        return mat3_to_scale(tmat);
 }
 
        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. */
 
        /* 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);
        /* 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];
 }
 
        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;
 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];
        
        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);
        /* 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);
 }
 
        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 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);
        /* do blending */
        interp_v3_v3v3(floc, dloc, sloc, srcweight);
        interp_qt_qtqt(fquat, dquat, squat, srcweight);
index 232d24714c5c17e9438af9bb4272b1bb63a7f7b7..fc717b0013bcd0b8835df62829137e846c76e067 100644 (file)
@@ -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"
 /*---------------------------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},
        {"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},
        {"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},
index 21538f8168e241be2f9cd41fd8da63d83170c774..f1cce3a45a8289ec63a1704c857136afcc736eed 100644 (file)
@@ -38,10 +38,9 @@ extern PyTypeObject matrix_Type;
 
 typedef struct {
        BASE_MATH_MEMBERS(contigPtr)
 
 typedef struct {
        BASE_MATH_MEMBERS(contigPtr)
-
-       unsigned char rowSize;
-       unsigned int colSize;
        float *matrix[MATRIX_MAX_DIM];          /* ptr to the contigPtr (accessor) */
        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
 } MatrixObject;
 
 /*struct data contains a pointer to the actual data that the
index e4027d7a80e5ce2c58e6126215793e29871c43ec..4dd2e2508048f4823b552810929b21df74aad27a 100644 (file)
@@ -670,7 +670,7 @@ static PyObject *Vector_Lerp(VectorObject *self, PyObject *args)
                return NULL;
 
        if(self->size != vec2->size) {
                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;
        }
 
                return NULL;
        }