mathutils module methods only contained matrix constructors, move these to matrix...
authorCampbell Barton <ideasman42@gmail.com>
Wed, 11 Aug 2010 16:40:36 +0000 (16:40 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 11 Aug 2010 16:40:36 +0000 (16:40 +0000)
 mathutils.RotationMatrix -> mathutils.Matrix.Rotation
 mathutils.ScaleMatrix -> mathutils.Matrix.Scale
 mathutils.ShearMatrix -> mathutils.Matrix.Shear
 mathutils.TranslationMatrix -> mathutils.Matrix.Translation
 mathutils.OrthoProjectionMatrix -> mathutils.Matrix.OrthoProjection

12 files changed:
release/scripts/io/export_fbx.py
release/scripts/io/export_obj.py
release/scripts/io/export_x3d.py
release/scripts/io/import_anim_bvh.py
release/scripts/io/import_scene_3ds.py
release/scripts/modules/add_object_utils.py
release/scripts/modules/rigify/spine_pivot_flex.py
release/scripts/modules/rigify/tail_control.py
release/scripts/op/uvcalc_smart_project.py
release/scripts/templates/gamelogic.py
source/blender/python/generic/mathutils.c
source/blender/python/generic/mathutils_matrix.c

index 5c2e0cb5f95f4ccfcf9fd8fa80b0aac6e2280497..c040861941a7e7d9b29af4bffa76fe23e2da980a 100644 (file)
@@ -55,7 +55,7 @@ import math # math.pi
 import shutil # for file copying
 
 import bpy
-from mathutils import Vector, Euler, Matrix, RotationMatrix
+from mathutils import Vector, Euler, Matrix
 
 def copy_file(source, dest):
     # XXX - remove, can use shutil
@@ -107,19 +107,19 @@ def eulerRadToDeg(eul):
 mtx4_identity = Matrix()
 
 # testing
-mtx_x90                = RotationMatrix( math.pi/2, 3, 'X') # used
-#mtx_x90n      = RotationMatrix(-90, 3, 'x')
-#mtx_y90       = RotationMatrix( 90, 3, 'y')
-#mtx_y90n      = RotationMatrix(-90, 3, 'y')
-#mtx_z90       = RotationMatrix( 90, 3, 'z')
-#mtx_z90n      = RotationMatrix(-90, 3, 'z')
-
-#mtx4_x90      = RotationMatrix( 90, 4, 'x')
-mtx4_x90n      = RotationMatrix(-math.pi/2, 4, 'X') # used
-#mtx4_y90      = RotationMatrix( 90, 4, 'y')
-mtx4_y90n      = RotationMatrix(-math.pi/2, 4, 'Y') # used
-mtx4_z90       = RotationMatrix( math.pi/2, 4, 'Z') # used
-mtx4_z90n      = RotationMatrix(-math.pi/2, 4, 'Z') # used
+mtx_x90                = Matrix.Rotation( math.pi/2, 3, 'X') # used
+#mtx_x90n      = Matrix.Rotation(-90, 3, 'x')
+#mtx_y90       = Matrix.Rotation( 90, 3, 'y')
+#mtx_y90n      = Matrix.Rotation(-90, 3, 'y')
+#mtx_z90       = Matrix.Rotation( 90, 3, 'z')
+#mtx_z90n      = Matrix.Rotation(-90, 3, 'z')
+
+#mtx4_x90      = Matrix.Rotation( 90, 4, 'x')
+mtx4_x90n      = Matrix.Rotation(-math.pi/2, 4, 'X') # used
+#mtx4_y90      = Matrix.Rotation( 90, 4, 'y')
+mtx4_y90n      = Matrix.Rotation(-math.pi/2, 4, 'Y') # used
+mtx4_z90       = Matrix.Rotation( math.pi/2, 4, 'Z') # used
+mtx4_z90n      = Matrix.Rotation(-math.pi/2, 4, 'Z') # used
 
 # def strip_path(p):
 #      return p.split('\\')[-1].split('/')[-1]
@@ -562,7 +562,7 @@ def write(filename, batch_objects = None, \
             elif type =='CAMERA':
 #                      elif ob and type =='Camera':
                 y = matrix_rot * Vector((0.0, 1.0, 0.0))
-                matrix_rot = RotationMatrix(math.pi/2, 3, y) * matrix_rot
+                matrix_rot = Matrix.Rotation(math.pi/2, 3, y) * matrix_rot
 
             return matrix_rot
 
@@ -664,7 +664,7 @@ def write(filename, batch_objects = None, \
                     rot = tuple(matrix_rot.to_euler())
                 elif ob and ob.type =='Camera':
                     y = matrix_rot * Vector((0.0, 1.0, 0.0))
-                    matrix_rot = RotationMatrix(math.pi/2, 3, y) * matrix_rot
+                    matrix_rot = Matrix.Rotation(math.pi/2, 3, y) * matrix_rot
                     rot = tuple(matrix_rot.to_euler())
                 else:
                     rot = tuple(matrix_rot.to_euler())
index 5603f52d1a4e9a5216a2ecaa3bee59a53f4f600a..5e951f064065c4a9cf91c74a7d7fab34d4ae47f1 100644 (file)
@@ -363,7 +363,7 @@ def write_file(filepath, objects, scene,
         file.write('mtllib %s\n' % ( mtlfilepath.split('\\')[-1].split('/')[-1] ))
 
     if EXPORT_ROTX90:
-        mat_xrot90= mathutils.RotationMatrix(-math.pi/2, 4, 'X')
+        mat_xrot90= mathutils.Matrix.Rotation(-math.pi/2, 4, 'X')
 
     # Initialize totals, these are updated each object
     totverts = totuvco = totno = 1
index 5fe48a2550a45373ddadeb8908cefc43d3f5677b..607f38be6f7db97ca84277fe8298c8bd41429c18 100644 (file)
@@ -81,7 +81,7 @@ from export_3ds import create_derived_objects, free_derived_objects
 
 #
 DEG2RAD=0.017453292519943295
-MATWORLD= mathutils.RotationMatrix(-90, 4, 'X')
+MATWORLD= mathutils.Matrix.Rotation(-90, 4, 'X')
 
 ####################################
 # Global Variables
index ba9b8a1f91d79b159bff2c4d7471158ad47afc19..3a80768070016652e961122e40004b84e31f0106 100644 (file)
@@ -23,7 +23,7 @@ from math import radians
 
 import bpy
 import mathutils
-from mathutils import Vector, Euler, Matrix, RotationMatrix, TranslationMatrix
+from mathutils import Vector, Euler, Matrix
 
 
 class bvh_node_class(object):
@@ -78,7 +78,7 @@ MATRIX_IDENTITY_4x4 = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0,
 
 def eulerRotate(x, y, z, rot_order):
     # Clamp all values between 0 and 360, values outside this raise an error.
-    mats = [RotationMatrix(x, 3, 'X'), RotationMatrix(y, 3, 'Y'), RotationMatrix(z, 3, 'Z')]
+    mats = [Matrix.Rotation(x, 3, 'X'), Matrix.Rotation(y, 3, 'Y'), Matrix.Rotation(z, 3, 'Z')]
     return (MATRIX_IDENTITY_3x3 * mats[rot_order[0]] * (mats[rot_order[1]] * (mats[rot_order[2]]))).to_euler()
 
     # Should work but doesnt!
@@ -529,7 +529,7 @@ def bvh_node_dict2armature(context, bvh_nodes, ROT_MODE='XYZ', IMPORT_START_FRAM
                     prev_euler[i] = euler
 
             if bvh_node.has_loc:
-                pose_bone.location = (bone_rest_matrix_inv * TranslationMatrix(Vector((lx, ly, lz)) - bvh_node.rest_head_local)).translation_part()
+                pose_bone.location = (bone_rest_matrix_inv * Matrix.Translation(Vector((lx, ly, lz)) - bvh_node.rest_head_local)).translation_part()
 
             if bvh_node.has_loc:
                 pose_bone.keyframe_insert("location")
index fe242ca1f292a9c4583f0c0e5b56e3ecbe76219e..12c99c0ff46ae0c7d1cc5799d31a66aef5380fa7 100644 (file)
@@ -771,7 +771,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
             #print contextMatrix_rot
             contextMatrix_rot.invert()
             #print contextMatrix_rot
-            #contextMatrix_tx = Blender.mathutils.TranslationMatrix(0.5 * Blender.mathutils.Vector(data[9:]))
+            #contextMatrix_tx = mathutils.Matrix.Translation(0.5 * Blender.mathutils.Vector(data[9:]))
             #contextMatrix_tx.invert()
 
             #tx.invert()
index 9031121060ac76a6ca6960f32d493c78c3cb20ad..41c05ce9d8a503912c421f45e87b6c9cd3615ba5 100644 (file)
@@ -25,11 +25,11 @@ import mathutils
 def add_object_align_init(context, operator):
 
     if operator and operator.properties.is_property_set("location") and operator.properties.is_property_set("rotation"):
-        location = mathutils.TranslationMatrix(mathutils.Vector(operator.properties.location))
+        location = mathutils.Matrix.Translation(mathutils.Vector(operator.properties.location))
         rotation = mathutils.Euler(operator.properties.rotation).to_matrix().resize4x4()
     else:
         # TODO, local view cursor!
-        location = mathutils.TranslationMatrix(context.scene.cursor_location)
+        location = mathutils.Matrix.Translation(context.scene.cursor_location)
 
         if context.user_preferences.edit.object_align == 'VIEW' and context.space_data.type == 'VIEW_3D':
             rotation = context.space_data.region_3d.view_matrix.rotation_part().invert().resize4x4()
index 86f2399f7ff1600fdda99ef3aa95745fc6b90a33..c4c9886e2e2e8488f4a83d6869d4b0acc99ce5f4 100644 (file)
@@ -147,7 +147,7 @@ def deform(obj, definitions, base_names, options):
 
 
 def main(obj, bone_definition, base_names, options):
-    from mathutils import Vector, RotationMatrix
+    from mathutils import Vector, Matrix
     from math import radians, pi
 
     arm = obj.data
@@ -264,7 +264,7 @@ def main(obj, bone_definition, base_names, options):
 
     # Rotate the rev chain 180 about the by the first bones center point
     pivot = (rv_chain.spine_01_e.head + rv_chain.spine_01_e.tail) * 0.5
-    matrix = RotationMatrix(radians(180), 3, 'X')
+    matrix = Matrix.Rotation(radians(180), 3, 'X')
     for i, attr in enumerate(rv_chain.attr_names): # similar to neck
         spine_e = getattr(rv_chain, attr + "_e")
         # use the first bone as the pivot
index f34bde92dee486881a1b8caa46249f751a288050..a629487c0c83c86a3ec5141cdcd616390c8e0acc 100644 (file)
@@ -22,7 +22,7 @@ import bpy
 from rigify import RigifyError
 from rigify_utils import bone_class_instance, copy_bone_simple
 from rna_prop_ui import rna_idprop_ui_prop_get
-from mathutils import Vector, RotationMatrix
+from mathutils import Vector, Matrix
 from math import radians, pi
 
 # not used, defined for completeness
index fbda1955013f89350a9eccc0ff400a46f009e310..bbd0102fc6108faf2e1eab3854b55f4c50646821 100644 (file)
@@ -22,7 +22,7 @@
 
 # <pep8 compliant>
 
-from mathutils import Matrix, Vector, RotationMatrix
+from mathutils import Matrix, Vector
 import time
 import geometry
 import bpy
@@ -275,15 +275,15 @@ def testNewVecLs2DRotIsBetter(vecs, mat=-1, bestAreaSoFar = -1):
 
 # Takes a list of faces that make up a UV island and rotate
 # until they optimally fit inside a square.
-ROTMAT_2D_POS_90D = RotationMatrix( radians(90.0), 2)
-ROTMAT_2D_POS_45D = RotationMatrix( radians(45.0), 2)
+ROTMAT_2D_POS_90D = Matrix.Rotation( radians(90.0), 2)
+ROTMAT_2D_POS_45D = Matrix.Rotation( radians(45.0), 2)
 
 RotMatStepRotation = []
 rot_angle = 22.5 #45.0/2
 while rot_angle > 0.1:
     RotMatStepRotation.append([\
-     RotationMatrix( radians(rot_angle), 2),\
-     RotationMatrix( radians(-rot_angle), 2)])
+     Matrix.Rotation( radians(rot_angle), 2),\
+     Matrix.Rotation( radians(-rot_angle), 2)])
 
     rot_angle = rot_angle/2.0
 
index b31d5d95987f2996b73fc3d63d507c0ceb72a4ac..21a901c091b7018ff45cf302135deeec5408f26a 100644 (file)
@@ -6,7 +6,7 @@
 # for keyboard event comparison
 # import GameKeys
 
-# support for Vector(), Matrix() types and advanced functions like ScaleMatrix(...) and RotationMatrix(...)
+# support for Vector(), Matrix() types and advanced functions like Matrix.Scale(...) and Matrix.Rotation(...)
 # import mathutils
 
 # for functions like getWindowWidth(), getWindowHeight()
index 2bfd9a6d0c67452f6bfbdb6aab89c9a0150a6402..ada5bac8c2a194de78e540a0b2f3d59fac407761 100644 (file)
  * - Vector.toTrackQuat --> Vector.to_track_quat
  * - Quaternion * Quaternion --> cross product (not dot product)
  *
+ * moved into class functions.
+ * - Mathutils.RotationMatrix -> mathutils.Matrix.Rotation
+ * - Mathutils.ScaleMatrix -> mathutils.Matrix.Scale
+ * - Mathutils.ShearMatrix -> mathutils.Matrix.Shear
+ * - Mathutils.TranslationMatrix -> mathutils.Matrix.Translation
+ * - Mathutils.OrthoProjectionMatrix -> mathutils.Matrix.OrthoProjection
+ *
  * Moved to Geometry module: Intersect, TriangleArea, TriangleNormal, QuadNormal, LineIntersect
  */
 
@@ -94,434 +101,7 @@ int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *
 }
 
 //----------------------------------MATRIX FUNCTIONS--------------------
-//----------------------------------mathutils.RotationMatrix() ----------
-//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
-static char M_Mathutils_RotationMatrix_doc[] =
-".. function:: RotationMatrix(angle, size, axis)\n"
-"\n"
-"   Create a matrix representing a rotation.\n"
-"\n"
-"   :arg angle: The angle of rotation desired, in radians.\n"
-"   :type angle: float\n"
-"   :arg size: The size of the rotation matrix to construct [2, 4].\n"
-"   :type size: int\n"
-"   :arg axis: a string in ['X', 'Y', 'Z'] or a 3D Vector Object (optional when size is 2).\n"
-"   :type axis: string or :class:`Vector`\n"
-"   :return: A new rotation matrix.\n"
-"   :rtype: :class:`Matrix`\n";
-
-static PyObject *M_Mathutils_RotationMatrix(PyObject * self, PyObject * args)
-{
-       VectorObject *vec= NULL;
-       char *axis= NULL;
-       int matSize;
-       float angle = 0.0f;
-       float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-               0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
-
-       if(!PyArg_ParseTuple(args, "fi|O", &angle, &matSize, &vec)) {
-               PyErr_SetString(PyExc_TypeError, "mathutils.RotationMatrix(angle, size, axis): expected float int and a string or vector\n");
-               return NULL;
-       }
-
-       if(vec && !VectorObject_Check(vec)) {
-               axis= _PyUnicode_AsString((PyObject *)vec);
-               if(axis==NULL || axis[0]=='\0' || axis[1]!='\0' || axis[0] < 'X' || axis[0] > 'Z') {
-                       PyErr_SetString(PyExc_TypeError, "mathutils.RotationMatrix(): 3rd argument axis value must be a 3D vector or a string in 'X', 'Y', 'Z'\n");
-                       return NULL;
-               }
-               else {
-                       /* use the string */
-                       vec= NULL;
-               }
-       }
-
-       while (angle<-(Py_PI*2))
-               angle+=(Py_PI*2);
-       while (angle>(Py_PI*2))
-               angle-=(Py_PI*2);
-       
-       if(matSize != 2 && matSize != 3 && matSize != 4) {
-               PyErr_SetString(PyExc_AttributeError, "mathutils.RotationMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n");
-               return NULL;
-       }
-       if(matSize == 2 && (vec != NULL)) {
-               PyErr_SetString(PyExc_AttributeError, "mathutils.RotationMatrix(): cannot create a 2x2 rotation matrix around arbitrary axis\n");
-               return NULL;
-       }
-       if((matSize == 3 || matSize == 4) && (axis == NULL) && (vec == NULL)) {
-               PyErr_SetString(PyExc_AttributeError, "mathutils.RotationMatrix(): please choose an axis of rotation for 3d and 4d matrices\n");
-               return NULL;
-       }
-       if(vec) {
-               if(vec->size != 3) {
-                       PyErr_SetString(PyExc_AttributeError, "mathutils.RotationMatrix(): the vector axis must be a 3D vector\n");
-                       return NULL;
-               }
-               
-               if(!BaseMath_ReadCallback(vec))
-                       return NULL;
-               
-       }
 
-       /* check for valid vector/axis above */
-       if(vec) {
-               axis_angle_to_mat3( (float (*)[3])mat,vec->vec, angle);
-       }
-       else if(matSize == 2) {
-               //2D rotation matrix
-               mat[0] = (float) cos (angle);
-               mat[1] = (float) sin (angle);
-               mat[2] = -((float) sin(angle));
-               mat[3] = (float) cos(angle);
-       } else if(strcmp(axis, "X") == 0) {
-               //rotation around X
-               mat[0] = 1.0f;
-               mat[4] = (float) cos(angle);
-               mat[5] = (float) sin(angle);
-               mat[7] = -((float) sin(angle));
-               mat[8] = (float) cos(angle);
-       } else if(strcmp(axis, "Y") == 0) {
-               //rotation around Y
-               mat[0] = (float) cos(angle);
-               mat[2] = -((float) sin(angle));
-               mat[4] = 1.0f;
-               mat[6] = (float) sin(angle);
-               mat[8] = (float) cos(angle);
-       } else if(strcmp(axis, "Z") == 0) {
-               //rotation around Z
-               mat[0] = (float) cos(angle);
-               mat[1] = (float) sin(angle);
-               mat[3] = -((float) sin(angle));
-               mat[4] = (float) cos(angle);
-               mat[8] = 1.0f;
-       }
-       else {
-               /* should never get here */
-               PyErr_SetString(PyExc_AttributeError, "mathutils.RotationMatrix(): unknown error\n");
-               return NULL;
-       }
-
-       if(matSize == 4) {
-               //resize matrix
-               mat[10] = mat[8];
-               mat[9] = mat[7];
-               mat[8] = mat[6];
-               mat[7] = 0.0f;
-               mat[6] = mat[5];
-               mat[5] = mat[4];
-               mat[4] = mat[3];
-               mat[3] = 0.0f;
-       }
-       //pass to matrix creation
-       return newMatrixObject(mat, matSize, matSize, Py_NEW, NULL);
-}
-
-static char M_Mathutils_TranslationMatrix_doc[] =
-".. function:: TranslationMatrix(vector)\n"
-"\n"
-"   Create a matrix representing a translation.\n"
-"\n"
-"   :arg vector: The translation vector.\n"
-"   :type vector: :class:`Vector`\n"
-"   :return: An identity matrix with a translation.\n"
-"   :rtype: :class:`Matrix`\n";
-
-static PyObject *M_Mathutils_TranslationMatrix(PyObject * self, VectorObject * vec)
-{
-       float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-               0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
-       
-       if(!VectorObject_Check(vec)) {
-               PyErr_SetString(PyExc_TypeError, "mathutils.TranslationMatrix(): expected vector\n");
-               return NULL;
-       }
-       if(vec->size != 3 && vec->size != 4) {
-               PyErr_SetString(PyExc_TypeError, "mathutils.TranslationMatrix(): vector must be 3D or 4D\n");
-               return NULL;
-       }
-       
-       if(!BaseMath_ReadCallback(vec))
-               return NULL;
-       
-       //create a identity matrix and add translation
-       unit_m4((float(*)[4]) mat);
-       mat[12] = vec->vec[0];
-       mat[13] = vec->vec[1];
-       mat[14] = vec->vec[2];
-
-       return newMatrixObject(mat, 4, 4, Py_NEW, NULL);
-}
-//----------------------------------mathutils.ScaleMatrix() -------------
-//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
-static char M_Mathutils_ScaleMatrix_doc[] =
-".. function:: ScaleMatrix(factor, size, axis)\n"
-"\n"
-"   Create a matrix representing a scaling.\n"
-"\n"
-"   :arg factor: The factor of scaling to apply.\n"
-"   :type factor: float\n"
-"   :arg size: The size of the scale matrix to construct [2, 4].\n"
-"   :type size: int\n"
-"   :arg axis: Direction to influence scale. (optional).\n"
-"   :type axis: :class:`Vector`\n"
-"   :return: A new scale matrix.\n"
-"   :rtype: :class:`Matrix`\n";
-
-static PyObject *M_Mathutils_ScaleMatrix(PyObject * self, PyObject * args)
-{
-       VectorObject *vec = NULL;
-       float norm = 0.0f, factor;
-       int matSize, x;
-       float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-               0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
-
-       if(!PyArg_ParseTuple(args, "fi|O!", &factor, &matSize, &vector_Type, &vec)) {
-               PyErr_SetString(PyExc_TypeError, "mathutils.ScaleMatrix(): expected float int and optional vector\n");
-               return NULL;
-       }
-       if(matSize != 2 && matSize != 3 && matSize != 4) {
-               PyErr_SetString(PyExc_AttributeError, "mathutils.ScaleMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n");
-               return NULL;
-       }
-       if(vec) {
-               if(vec->size > 2 && matSize == 2) {
-                       PyErr_SetString(PyExc_AttributeError, "mathutils.ScaleMatrix(): please use 2D vectors when scaling in 2D\n");
-                       return NULL;
-               }
-               
-               if(!BaseMath_ReadCallback(vec))
-                       return NULL;
-               
-       }
-       if(vec == NULL) {       //scaling along axis
-               if(matSize == 2) {
-                       mat[0] = factor;
-                       mat[3] = factor;
-               } else {
-                       mat[0] = factor;
-                       mat[4] = factor;
-                       mat[8] = factor;
-               }
-       } else { //scaling in arbitrary direction
-               //normalize arbitrary axis
-               for(x = 0; x < vec->size; x++) {
-                       norm += vec->vec[x] * vec->vec[x];
-               }
-               norm = (float) sqrt(norm);
-               for(x = 0; x < vec->size; x++) {
-                       vec->vec[x] /= norm;
-               }
-               if(matSize == 2) {
-                       mat[0] = 1 +((factor - 1) *(vec->vec[0] * vec->vec[0]));
-                       mat[1] =((factor - 1) *(vec->vec[0] * vec->vec[1]));
-                       mat[2] =((factor - 1) *(vec->vec[0] * vec->vec[1]));
-                       mat[3] = 1 + ((factor - 1) *(vec->vec[1] * vec->vec[1]));
-               } else {
-                       mat[0] = 1 + ((factor - 1) *(vec->vec[0] * vec->vec[0]));
-                       mat[1] =((factor - 1) *(vec->vec[0] * vec->vec[1]));
-                       mat[2] =((factor - 1) *(vec->vec[0] * vec->vec[2]));
-                       mat[3] =((factor - 1) *(vec->vec[0] * vec->vec[1]));
-                       mat[4] = 1 + ((factor - 1) *(vec->vec[1] * vec->vec[1]));
-                       mat[5] =((factor - 1) *(vec->vec[1] * vec->vec[2]));
-                       mat[6] =((factor - 1) *(vec->vec[0] * vec->vec[2]));
-                       mat[7] =((factor - 1) *(vec->vec[1] * vec->vec[2]));
-                       mat[8] = 1 + ((factor - 1) *(vec->vec[2] * vec->vec[2]));
-               }
-       }
-       if(matSize == 4) {
-               //resize matrix
-               mat[10] = mat[8];
-               mat[9] = mat[7];
-               mat[8] = mat[6];
-               mat[7] = 0.0f;
-               mat[6] = mat[5];
-               mat[5] = mat[4];
-               mat[4] = mat[3];
-               mat[3] = 0.0f;
-       }
-       //pass to matrix creation
-       return newMatrixObject(mat, matSize, matSize, Py_NEW, NULL);
-}
-//----------------------------------mathutils.OrthoProjectionMatrix() ---
-//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
-static char M_Mathutils_OrthoProjectionMatrix_doc[] =
-".. function:: OrthoProjectionMatrix(plane, size, axis)\n"
-"\n"
-"   Create a matrix to represent an orthographic projection.\n"
-"\n"
-"   :arg plane: Can be any of the following: ['X', 'Y', 'XY', 'XZ', 'YZ', 'R'], where a single axis is for a 2D matrix and 'R' requires axis is given.\n"
-"   :type plane: string\n"
-"   :arg size: The size of the projection matrix to construct [2, 4].\n"
-"   :type size: int\n"
-"   :arg axis: Arbitrary perpendicular plane vector (optional).\n"
-"   :type axis: :class:`Vector`\n"
-"   :return: A new projection matrix.\n"
-"   :rtype: :class:`Matrix`\n";
-static PyObject *M_Mathutils_OrthoProjectionMatrix(PyObject * self, PyObject * args)
-{
-       VectorObject *vec = NULL;
-       char *plane;
-       int matSize, x;
-       float norm = 0.0f;
-       float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-               0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
-       
-       if(!PyArg_ParseTuple(args, "si|O!", &plane, &matSize, &vector_Type, &vec)) {
-               PyErr_SetString(PyExc_TypeError, "mathutils.OrthoProjectionMatrix(): expected string and int and optional vector\n");
-               return NULL;
-       }
-       if(matSize != 2 && matSize != 3 && matSize != 4) {
-               PyErr_SetString(PyExc_AttributeError,"mathutils.OrthoProjectionMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n");
-               return NULL;
-       }
-       if(vec) {
-               if(vec->size > 2 && matSize == 2) {
-                       PyErr_SetString(PyExc_AttributeError, "mathutils.OrthoProjectionMatrix(): please use 2D vectors when scaling in 2D\n");
-                       return NULL;
-               }
-               
-               if(!BaseMath_ReadCallback(vec))
-                       return NULL;
-               
-       }
-       if(vec == NULL) {       //ortho projection onto cardinal plane
-               if((strcmp(plane, "X") == 0) && matSize == 2) {
-                       mat[0] = 1.0f;
-               } else if((strcmp(plane, "Y") == 0) && matSize == 2) {
-                       mat[3] = 1.0f;
-               } else if((strcmp(plane, "XY") == 0) && matSize > 2) {
-                       mat[0] = 1.0f;
-                       mat[4] = 1.0f;
-               } else if((strcmp(plane, "XZ") == 0) && matSize > 2) {
-                       mat[0] = 1.0f;
-                       mat[8] = 1.0f;
-               } else if((strcmp(plane, "YZ") == 0) && matSize > 2) {
-                       mat[4] = 1.0f;
-                       mat[8] = 1.0f;
-               } else {
-                       PyErr_SetString(PyExc_AttributeError, "mathutils.OrthoProjectionMatrix(): unknown plane - expected: X, Y, XY, XZ, YZ\n");
-                       return NULL;
-               }
-       } else { //arbitrary plane
-               //normalize arbitrary axis
-               for(x = 0; x < vec->size; x++) {
-                       norm += vec->vec[x] * vec->vec[x];
-               }
-               norm = (float) sqrt(norm);
-               for(x = 0; x < vec->size; x++) {
-                       vec->vec[x] /= norm;
-               }
-               if((strcmp(plane, "R") == 0) && matSize == 2) {
-                       mat[0] = 1 - (vec->vec[0] * vec->vec[0]);
-                       mat[1] = -(vec->vec[0] * vec->vec[1]);
-                       mat[2] = -(vec->vec[0] * vec->vec[1]);
-                       mat[3] = 1 - (vec->vec[1] * vec->vec[1]);
-               } else if((strcmp(plane, "R") == 0) && matSize > 2) {
-                       mat[0] = 1 - (vec->vec[0] * vec->vec[0]);
-                       mat[1] = -(vec->vec[0] * vec->vec[1]);
-                       mat[2] = -(vec->vec[0] * vec->vec[2]);
-                       mat[3] = -(vec->vec[0] * vec->vec[1]);
-                       mat[4] = 1 - (vec->vec[1] * vec->vec[1]);
-                       mat[5] = -(vec->vec[1] * vec->vec[2]);
-                       mat[6] = -(vec->vec[0] * vec->vec[2]);
-                       mat[7] = -(vec->vec[1] * vec->vec[2]);
-                       mat[8] = 1 - (vec->vec[2] * vec->vec[2]);
-               } else {
-                       PyErr_SetString(PyExc_AttributeError, "mathutils.OrthoProjectionMatrix(): unknown plane - expected: 'r' expected for axis designation\n");
-                       return NULL;
-               }
-       }
-       if(matSize == 4) {
-               //resize matrix
-               mat[10] = mat[8];
-               mat[9] = mat[7];
-               mat[8] = mat[6];
-               mat[7] = 0.0f;
-               mat[6] = mat[5];
-               mat[5] = mat[4];
-               mat[4] = mat[3];
-               mat[3] = 0.0f;
-       }
-       //pass to matrix creation
-       return newMatrixObject(mat, matSize, matSize, Py_NEW, NULL);
-}
-
-static char M_Mathutils_ShearMatrix_doc[] =
-".. function:: ShearMatrix(plane, factor, size)\n"
-"\n"
-"   Create a matrix to represent an shear transformation.\n"
-"\n"
-"   :arg plane: Can be any of the following: ['X', 'Y', 'XY', 'XZ', 'YZ'], where a single axis is for a 2D matrix.\n"
-"   :type plane: string\n"
-"   :arg factor: The factor of shear to apply.\n"
-"   :type factor: float\n"
-"   :arg size: The size of the shear matrix to construct [2, 4].\n"
-"   :type size: int\n"
-"   :return: A new shear matrix.\n"
-"   :rtype: :class:`Matrix`\n";
-
-static PyObject *M_Mathutils_ShearMatrix(PyObject * self, PyObject * args)
-{
-       int matSize;
-       char *plane;
-       float factor;
-       float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-               0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
-
-       if(!PyArg_ParseTuple(args, "sfi", &plane, &factor, &matSize)) {
-               PyErr_SetString(PyExc_TypeError,"mathutils.ShearMatrix(): expected string float and int\n");
-               return NULL;
-       }
-       if(matSize != 2 && matSize != 3 && matSize != 4) {
-               PyErr_SetString(PyExc_AttributeError,"mathutils.ShearMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n");
-               return NULL;
-       }
-
-       if((strcmp(plane, "X") == 0)
-               && matSize == 2) {
-               mat[0] = 1.0f;
-               mat[2] = factor;
-               mat[3] = 1.0f;
-       } else if((strcmp(plane, "Y") == 0) && matSize == 2) {
-               mat[0] = 1.0f;
-               mat[1] = factor;
-               mat[3] = 1.0f;
-       } else if((strcmp(plane, "XY") == 0) && matSize > 2) {
-               mat[0] = 1.0f;
-               mat[4] = 1.0f;
-               mat[6] = factor;
-               mat[7] = factor;
-       } else if((strcmp(plane, "XZ") == 0) && matSize > 2) {
-               mat[0] = 1.0f;
-               mat[3] = factor;
-               mat[4] = 1.0f;
-               mat[5] = factor;
-               mat[8] = 1.0f;
-       } else if((strcmp(plane, "YZ") == 0) && matSize > 2) {
-               mat[0] = 1.0f;
-               mat[1] = factor;
-               mat[2] = factor;
-               mat[4] = 1.0f;
-               mat[8] = 1.0f;
-       } else {
-               PyErr_SetString(PyExc_AttributeError, "mathutils.ShearMatrix(): expected: x, y, xy, xz, yz or wrong matrix size for shearing plane\n");
-               return NULL;
-       }
-       if(matSize == 4) {
-               //resize matrix
-               mat[10] = mat[8];
-               mat[9] = mat[7];
-               mat[8] = mat[6];
-               mat[7] = 0.0f;
-               mat[6] = mat[5];
-               mat[5] = mat[4];
-               mat[4] = mat[3];
-               mat[3] = 0.0f;
-       }
-       //pass to matrix creation
-       return newMatrixObject(mat, matSize, matSize, Py_NEW, NULL);
-}
 
 /* Utility functions */
 
@@ -647,11 +227,6 @@ void BaseMathObject_dealloc(BaseMathObject * self)
 
 /*----------------------------MODULE INIT-------------------------*/
 struct PyMethodDef M_Mathutils_methods[] = {
-       {"RotationMatrix", (PyCFunction) M_Mathutils_RotationMatrix, METH_VARARGS, M_Mathutils_RotationMatrix_doc},
-       {"ScaleMatrix", (PyCFunction) M_Mathutils_ScaleMatrix, METH_VARARGS, M_Mathutils_ScaleMatrix_doc},
-       {"ShearMatrix", (PyCFunction) M_Mathutils_ShearMatrix, METH_VARARGS, M_Mathutils_ShearMatrix_doc},
-       {"TranslationMatrix", (PyCFunction) M_Mathutils_TranslationMatrix, METH_O, M_Mathutils_TranslationMatrix_doc},
-       {"OrthoProjectionMatrix", (PyCFunction) M_Mathutils_OrthoProjectionMatrix,  METH_VARARGS, M_Mathutils_OrthoProjectionMatrix_doc},
        {NULL, NULL, 0, NULL}
 };
 
index 9be50fe6349b8dc67277366008d8dcc0e0082ed8..1ef834b7a3eb80a66090ce75ffa9d5146de04a86 100644 (file)
@@ -181,6 +181,438 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        return newMatrixObject(matrix, argSize, seqSize, Py_NEW, NULL);
 }
 
+/*-----------------------CLASS-METHODS----------------------------*/
+
+//----------------------------------mathutils.RotationMatrix() ----------
+//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
+static char C_Matrix_Rotation_doc[] =
+".. classmethod:: Rotation(angle, size, axis)\n"
+"\n"
+"   Create a matrix representing a rotation.\n"
+"\n"
+"   :arg angle: The angle of rotation desired, in radians.\n"
+"   :type angle: float\n"
+"   :arg size: The size of the rotation matrix to construct [2, 4].\n"
+"   :type size: int\n"
+"   :arg axis: a string in ['X', 'Y', 'Z'] or a 3D Vector Object (optional when size is 2).\n"
+"   :type axis: string or :class:`Vector`\n"
+"   :return: A new rotation matrix.\n"
+"   :rtype: :class:`Matrix`\n";
+
+static PyObject *C_Matrix_Rotation(PyObject *cls, PyObject *args)
+{
+       VectorObject *vec= NULL;
+       char *axis= NULL;
+       int matSize;
+       float angle = 0.0f;
+       float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+               0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
+
+       if(!PyArg_ParseTuple(args, "fi|O", &angle, &matSize, &vec)) {
+               PyErr_SetString(PyExc_TypeError, "mathutils.RotationMatrix(angle, size, axis): expected float int and a string or vector\n");
+               return NULL;
+       }
+
+       if(vec && !VectorObject_Check(vec)) {
+               axis= _PyUnicode_AsString((PyObject *)vec);
+               if(axis==NULL || axis[0]=='\0' || axis[1]!='\0' || axis[0] < 'X' || axis[0] > 'Z') {
+                       PyErr_SetString(PyExc_TypeError, "mathutils.RotationMatrix(): 3rd argument axis value must be a 3D vector or a string in 'X', 'Y', 'Z'\n");
+                       return NULL;
+               }
+               else {
+                       /* use the string */
+                       vec= NULL;
+               }
+       }
+
+       while (angle<-(Py_PI*2))
+               angle+=(Py_PI*2);
+       while (angle>(Py_PI*2))
+               angle-=(Py_PI*2);
+       
+       if(matSize != 2 && matSize != 3 && matSize != 4) {
+               PyErr_SetString(PyExc_AttributeError, "mathutils.RotationMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n");
+               return NULL;
+       }
+       if(matSize == 2 && (vec != NULL)) {
+               PyErr_SetString(PyExc_AttributeError, "mathutils.RotationMatrix(): cannot create a 2x2 rotation matrix around arbitrary axis\n");
+               return NULL;
+       }
+       if((matSize == 3 || matSize == 4) && (axis == NULL) && (vec == NULL)) {
+               PyErr_SetString(PyExc_AttributeError, "mathutils.RotationMatrix(): please choose an axis of rotation for 3d and 4d matrices\n");
+               return NULL;
+       }
+       if(vec) {
+               if(vec->size != 3) {
+                       PyErr_SetString(PyExc_AttributeError, "mathutils.RotationMatrix(): the vector axis must be a 3D vector\n");
+                       return NULL;
+               }
+               
+               if(!BaseMath_ReadCallback(vec))
+                       return NULL;
+               
+       }
+
+       /* check for valid vector/axis above */
+       if(vec) {
+               axis_angle_to_mat3( (float (*)[3])mat,vec->vec, angle);
+       }
+       else if(matSize == 2) {
+               //2D rotation matrix
+               mat[0] = (float) cos (angle);
+               mat[1] = (float) sin (angle);
+               mat[2] = -((float) sin(angle));
+               mat[3] = (float) cos(angle);
+       } else if(strcmp(axis, "X") == 0) {
+               //rotation around X
+               mat[0] = 1.0f;
+               mat[4] = (float) cos(angle);
+               mat[5] = (float) sin(angle);
+               mat[7] = -((float) sin(angle));
+               mat[8] = (float) cos(angle);
+       } else if(strcmp(axis, "Y") == 0) {
+               //rotation around Y
+               mat[0] = (float) cos(angle);
+               mat[2] = -((float) sin(angle));
+               mat[4] = 1.0f;
+               mat[6] = (float) sin(angle);
+               mat[8] = (float) cos(angle);
+       } else if(strcmp(axis, "Z") == 0) {
+               //rotation around Z
+               mat[0] = (float) cos(angle);
+               mat[1] = (float) sin(angle);
+               mat[3] = -((float) sin(angle));
+               mat[4] = (float) cos(angle);
+               mat[8] = 1.0f;
+       }
+       else {
+               /* should never get here */
+               PyErr_SetString(PyExc_AttributeError, "mathutils.RotationMatrix(): unknown error\n");
+               return NULL;
+       }
+
+       if(matSize == 4) {
+               //resize matrix
+               mat[10] = mat[8];
+               mat[9] = mat[7];
+               mat[8] = mat[6];
+               mat[7] = 0.0f;
+               mat[6] = mat[5];
+               mat[5] = mat[4];
+               mat[4] = mat[3];
+               mat[3] = 0.0f;
+       }
+       //pass to matrix creation
+       return newMatrixObject(mat, matSize, matSize, Py_NEW, (PyTypeObject *)cls);
+}
+
+
+static char C_Matrix_Translation_doc[] =
+".. classmethod:: Translation(vector)\n"
+"\n"
+"   Create a matrix representing a translation.\n"
+"\n"
+"   :arg vector: The translation vector.\n"
+"   :type vector: :class:`Vector`\n"
+"   :return: An identity matrix with a translation.\n"
+"   :rtype: :class:`Matrix`\n";
+
+static PyObject *C_Matrix_Translation(PyObject *cls, VectorObject * vec)
+{
+       float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+               0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
+       
+       if(!VectorObject_Check(vec)) {
+               PyErr_SetString(PyExc_TypeError, "mathutils.TranslationMatrix(): expected vector\n");
+               return NULL;
+       }
+       if(vec->size != 3 && vec->size != 4) {
+               PyErr_SetString(PyExc_TypeError, "mathutils.TranslationMatrix(): vector must be 3D or 4D\n");
+               return NULL;
+       }
+       
+       if(!BaseMath_ReadCallback(vec))
+               return NULL;
+       
+       //create a identity matrix and add translation
+       unit_m4((float(*)[4]) mat);
+       mat[12] = vec->vec[0];
+       mat[13] = vec->vec[1];
+       mat[14] = vec->vec[2];
+
+       return newMatrixObject(mat, 4, 4, Py_NEW, (PyTypeObject *)cls);
+}
+//----------------------------------mathutils.ScaleMatrix() -------------
+//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
+static char C_Matrix_Scale_doc[] =
+".. classmethod:: Scale(factor, size, axis)\n"
+"\n"
+"   Create a matrix representing a scaling.\n"
+"\n"
+"   :arg factor: The factor of scaling to apply.\n"
+"   :type factor: float\n"
+"   :arg size: The size of the scale matrix to construct [2, 4].\n"
+"   :type size: int\n"
+"   :arg axis: Direction to influence scale. (optional).\n"
+"   :type axis: :class:`Vector`\n"
+"   :return: A new scale matrix.\n"
+"   :rtype: :class:`Matrix`\n";
+
+static PyObject *C_Matrix_Scale(PyObject *cls, PyObject *args)
+{
+       VectorObject *vec = NULL;
+       float norm = 0.0f, factor;
+       int matSize, x;
+       float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+               0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
+
+       if(!PyArg_ParseTuple(args, "fi|O!", &factor, &matSize, &vector_Type, &vec)) {
+               PyErr_SetString(PyExc_TypeError, "mathutils.ScaleMatrix(): expected float int and optional vector\n");
+               return NULL;
+       }
+       if(matSize != 2 && matSize != 3 && matSize != 4) {
+               PyErr_SetString(PyExc_AttributeError, "mathutils.ScaleMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n");
+               return NULL;
+       }
+       if(vec) {
+               if(vec->size > 2 && matSize == 2) {
+                       PyErr_SetString(PyExc_AttributeError, "mathutils.ScaleMatrix(): please use 2D vectors when scaling in 2D\n");
+                       return NULL;
+               }
+               
+               if(!BaseMath_ReadCallback(vec))
+                       return NULL;
+               
+       }
+       if(vec == NULL) {       //scaling along axis
+               if(matSize == 2) {
+                       mat[0] = factor;
+                       mat[3] = factor;
+               } else {
+                       mat[0] = factor;
+                       mat[4] = factor;
+                       mat[8] = factor;
+               }
+       } else { //scaling in arbitrary direction
+               //normalize arbitrary axis
+               for(x = 0; x < vec->size; x++) {
+                       norm += vec->vec[x] * vec->vec[x];
+               }
+               norm = (float) sqrt(norm);
+               for(x = 0; x < vec->size; x++) {
+                       vec->vec[x] /= norm;
+               }
+               if(matSize == 2) {
+                       mat[0] = 1 +((factor - 1) *(vec->vec[0] * vec->vec[0]));
+                       mat[1] =((factor - 1) *(vec->vec[0] * vec->vec[1]));
+                       mat[2] =((factor - 1) *(vec->vec[0] * vec->vec[1]));
+                       mat[3] = 1 + ((factor - 1) *(vec->vec[1] * vec->vec[1]));
+               } else {
+                       mat[0] = 1 + ((factor - 1) *(vec->vec[0] * vec->vec[0]));
+                       mat[1] =((factor - 1) *(vec->vec[0] * vec->vec[1]));
+                       mat[2] =((factor - 1) *(vec->vec[0] * vec->vec[2]));
+                       mat[3] =((factor - 1) *(vec->vec[0] * vec->vec[1]));
+                       mat[4] = 1 + ((factor - 1) *(vec->vec[1] * vec->vec[1]));
+                       mat[5] =((factor - 1) *(vec->vec[1] * vec->vec[2]));
+                       mat[6] =((factor - 1) *(vec->vec[0] * vec->vec[2]));
+                       mat[7] =((factor - 1) *(vec->vec[1] * vec->vec[2]));
+                       mat[8] = 1 + ((factor - 1) *(vec->vec[2] * vec->vec[2]));
+               }
+       }
+       if(matSize == 4) {
+               //resize matrix
+               mat[10] = mat[8];
+               mat[9] = mat[7];
+               mat[8] = mat[6];
+               mat[7] = 0.0f;
+               mat[6] = mat[5];
+               mat[5] = mat[4];
+               mat[4] = mat[3];
+               mat[3] = 0.0f;
+       }
+       //pass to matrix creation
+       return newMatrixObject(mat, matSize, matSize, Py_NEW, (PyTypeObject *)cls);
+}
+//----------------------------------mathutils.OrthoProjectionMatrix() ---
+//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
+static char C_Matrix_OrthoProjection_doc[] =
+".. classmethod:: OrthoProjection(plane, size, axis)\n"
+"\n"
+"   Create a matrix to represent an orthographic projection.\n"
+"\n"
+"   :arg plane: Can be any of the following: ['X', 'Y', 'XY', 'XZ', 'YZ', 'R'], where a single axis is for a 2D matrix and 'R' requires axis is given.\n"
+"   :type plane: string\n"
+"   :arg size: The size of the projection matrix to construct [2, 4].\n"
+"   :type size: int\n"
+"   :arg axis: Arbitrary perpendicular plane vector (optional).\n"
+"   :type axis: :class:`Vector`\n"
+"   :return: A new projection matrix.\n"
+"   :rtype: :class:`Matrix`\n";
+static PyObject *C_Matrix_OrthoProjection(PyObject *cls, PyObject *args)
+{
+       VectorObject *vec = NULL;
+       char *plane;
+       int matSize, x;
+       float norm = 0.0f;
+       float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+               0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
+       
+       if(!PyArg_ParseTuple(args, "si|O!", &plane, &matSize, &vector_Type, &vec)) {
+               PyErr_SetString(PyExc_TypeError, "mathutils.OrthoProjectionMatrix(): expected string and int and optional vector\n");
+               return NULL;
+       }
+       if(matSize != 2 && matSize != 3 && matSize != 4) {
+               PyErr_SetString(PyExc_AttributeError,"mathutils.OrthoProjectionMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n");
+               return NULL;
+       }
+       if(vec) {
+               if(vec->size > 2 && matSize == 2) {
+                       PyErr_SetString(PyExc_AttributeError, "mathutils.OrthoProjectionMatrix(): please use 2D vectors when scaling in 2D\n");
+                       return NULL;
+               }
+               
+               if(!BaseMath_ReadCallback(vec))
+                       return NULL;
+               
+       }
+       if(vec == NULL) {       //ortho projection onto cardinal plane
+               if((strcmp(plane, "X") == 0) && matSize == 2) {
+                       mat[0] = 1.0f;
+               } else if((strcmp(plane, "Y") == 0) && matSize == 2) {
+                       mat[3] = 1.0f;
+               } else if((strcmp(plane, "XY") == 0) && matSize > 2) {
+                       mat[0] = 1.0f;
+                       mat[4] = 1.0f;
+               } else if((strcmp(plane, "XZ") == 0) && matSize > 2) {
+                       mat[0] = 1.0f;
+                       mat[8] = 1.0f;
+               } else if((strcmp(plane, "YZ") == 0) && matSize > 2) {
+                       mat[4] = 1.0f;
+                       mat[8] = 1.0f;
+               } else {
+                       PyErr_SetString(PyExc_AttributeError, "mathutils.OrthoProjectionMatrix(): unknown plane - expected: X, Y, XY, XZ, YZ\n");
+                       return NULL;
+               }
+       } else { //arbitrary plane
+               //normalize arbitrary axis
+               for(x = 0; x < vec->size; x++) {
+                       norm += vec->vec[x] * vec->vec[x];
+               }
+               norm = (float) sqrt(norm);
+               for(x = 0; x < vec->size; x++) {
+                       vec->vec[x] /= norm;
+               }
+               if((strcmp(plane, "R") == 0) && matSize == 2) {
+                       mat[0] = 1 - (vec->vec[0] * vec->vec[0]);
+                       mat[1] = -(vec->vec[0] * vec->vec[1]);
+                       mat[2] = -(vec->vec[0] * vec->vec[1]);
+                       mat[3] = 1 - (vec->vec[1] * vec->vec[1]);
+               } else if((strcmp(plane, "R") == 0) && matSize > 2) {
+                       mat[0] = 1 - (vec->vec[0] * vec->vec[0]);
+                       mat[1] = -(vec->vec[0] * vec->vec[1]);
+                       mat[2] = -(vec->vec[0] * vec->vec[2]);
+                       mat[3] = -(vec->vec[0] * vec->vec[1]);
+                       mat[4] = 1 - (vec->vec[1] * vec->vec[1]);
+                       mat[5] = -(vec->vec[1] * vec->vec[2]);
+                       mat[6] = -(vec->vec[0] * vec->vec[2]);
+                       mat[7] = -(vec->vec[1] * vec->vec[2]);
+                       mat[8] = 1 - (vec->vec[2] * vec->vec[2]);
+               } else {
+                       PyErr_SetString(PyExc_AttributeError, "mathutils.OrthoProjectionMatrix(): unknown plane - expected: 'r' expected for axis designation\n");
+                       return NULL;
+               }
+       }
+       if(matSize == 4) {
+               //resize matrix
+               mat[10] = mat[8];
+               mat[9] = mat[7];
+               mat[8] = mat[6];
+               mat[7] = 0.0f;
+               mat[6] = mat[5];
+               mat[5] = mat[4];
+               mat[4] = mat[3];
+               mat[3] = 0.0f;
+       }
+       //pass to matrix creation
+       return newMatrixObject(mat, matSize, matSize, Py_NEW, (PyTypeObject *)cls);
+}
+
+static char C_Matrix_Shear_doc[] =
+".. classmethod:: Shear(plane, factor, size)\n"
+"\n"
+"   Create a matrix to represent an shear transformation.\n"
+"\n"
+"   :arg plane: Can be any of the following: ['X', 'Y', 'XY', 'XZ', 'YZ'], where a single axis is for a 2D matrix.\n"
+"   :type plane: string\n"
+"   :arg factor: The factor of shear to apply.\n"
+"   :type factor: float\n"
+"   :arg size: The size of the shear matrix to construct [2, 4].\n"
+"   :type size: int\n"
+"   :return: A new shear matrix.\n"
+"   :rtype: :class:`Matrix`\n";
+
+static PyObject *C_Matrix_Shear(PyObject *cls, PyObject *args)
+{
+       int matSize;
+       char *plane;
+       float factor;
+       float mat[16] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+               0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
+
+       if(!PyArg_ParseTuple(args, "sfi", &plane, &factor, &matSize)) {
+               PyErr_SetString(PyExc_TypeError,"mathutils.ShearMatrix(): expected string float and int\n");
+               return NULL;
+       }
+       if(matSize != 2 && matSize != 3 && matSize != 4) {
+               PyErr_SetString(PyExc_AttributeError,"mathutils.ShearMatrix(): can only return a 2x2 3x3 or 4x4 matrix\n");
+               return NULL;
+       }
+
+       if((strcmp(plane, "X") == 0)
+               && matSize == 2) {
+               mat[0] = 1.0f;
+               mat[2] = factor;
+               mat[3] = 1.0f;
+       } else if((strcmp(plane, "Y") == 0) && matSize == 2) {
+               mat[0] = 1.0f;
+               mat[1] = factor;
+               mat[3] = 1.0f;
+       } else if((strcmp(plane, "XY") == 0) && matSize > 2) {
+               mat[0] = 1.0f;
+               mat[4] = 1.0f;
+               mat[6] = factor;
+               mat[7] = factor;
+       } else if((strcmp(plane, "XZ") == 0) && matSize > 2) {
+               mat[0] = 1.0f;
+               mat[3] = factor;
+               mat[4] = 1.0f;
+               mat[5] = factor;
+               mat[8] = 1.0f;
+       } else if((strcmp(plane, "YZ") == 0) && matSize > 2) {
+               mat[0] = 1.0f;
+               mat[1] = factor;
+               mat[2] = factor;
+               mat[4] = 1.0f;
+               mat[8] = 1.0f;
+       } else {
+               PyErr_SetString(PyExc_AttributeError, "mathutils.ShearMatrix(): expected: x, y, xy, xz, yz or wrong matrix size for shearing plane\n");
+               return NULL;
+       }
+       if(matSize == 4) {
+               //resize matrix
+               mat[10] = mat[8];
+               mat[9] = mat[7];
+               mat[8] = mat[6];
+               mat[7] = 0.0f;
+               mat[6] = mat[5];
+               mat[5] = mat[4];
+               mat[4] = mat[3];
+               mat[3] = 0.0f;
+       }
+       //pass to matrix creation
+       return newMatrixObject(mat, matSize, matSize, Py_NEW, (PyTypeObject *)cls);
+}
+
 /* assumes rowsize == colsize is checked and the read callback has run */
 static float matrix_determinant(MatrixObject * self)
 {
@@ -1326,6 +1758,13 @@ static struct PyMethodDef Matrix_methods[] = {
        {"to_quat", (PyCFunction) Matrix_toQuat, METH_NOARGS, Matrix_toQuat_doc},
        {"copy", (PyCFunction) Matrix_copy, METH_NOARGS, Matrix_copy_doc},
        {"__copy__", (PyCFunction) Matrix_copy, METH_NOARGS, Matrix_copy_doc},
+       
+       /* class methods */
+       {"Rotation", (PyCFunction) C_Matrix_Rotation, METH_VARARGS | METH_CLASS, C_Matrix_Rotation_doc},
+       {"Scale", (PyCFunction) C_Matrix_Scale, METH_VARARGS | METH_CLASS, C_Matrix_Scale_doc},
+       {"Shear", (PyCFunction) C_Matrix_Shear, METH_VARARGS | METH_CLASS, C_Matrix_Shear_doc},
+       {"Translation", (PyCFunction) C_Matrix_Translation, METH_O | METH_CLASS, C_Matrix_Translation_doc},
+       {"OrthoProjection", (PyCFunction) C_Matrix_OrthoProjection,  METH_VARARGS | METH_CLASS, C_Matrix_OrthoProjection_doc},
        {NULL, NULL, 0, NULL}
 };