def decompose(self):
        """Decomposes the matrix into a translation, rotation and scaling part.

        Returns a tuple (translation, rotation, scaling). The 
        translation and scaling parts are given as vec3's, the rotation
        is still given as a mat4.
        """
        dummy = self.ortho()
        dummy.setRow(3,_vec4(0.0, 0.0, 0.0, 1.0))
        dummy.setColumn(3,_vec4(0.0, 0.0, 0.0, 1.0))

        x = dummy.getColumn(0)
        y = dummy.getColumn(1)
        z = dummy.getColumn(2)
        xl = x.length()
        yl = y.length()
        zl = z.length()
        scale = _vec3(xl,yl,zl)
        
        x/=xl
        y/=yl
        z/=zl
        dummy.setColumn(0,x)
        dummy.setColumn(1,y)
        dummy.setColumn(2,z)
        if dummy.determinant()<0.0:
            dummy.setColumn(0,-x)
            scale.x=-scale.x

        return (_vec3(self.mlist[3], self.mlist[7], self.mlist[11]),
                dummy,
                scale)
Exemple #2
0
    def decompose(self):
        """Decomposes the matrix into a translation, rotation and scaling part.

        Returns a tuple (translation, rotation, scaling). The 
        translation and scaling parts are given as vec3's, the rotation
        is still given as a mat4.
        """
        try:
            dummy = self.ortho()
        except ZeroDivisionError:
            return (_vec3(0), mat4(1.0), _vec3(0))

        dummy.setRow(3, _vec4(0.0, 0.0, 0.0, 1.0))
        dummy.setColumn(3, _vec4(0.0, 0.0, 0.0, 1.0))

        x = dummy.getColumn(0)
        y = dummy.getColumn(1)
        z = dummy.getColumn(2)
        xl = x.length()
        yl = y.length()
        zl = z.length()
        scale = _vec3(xl, yl, zl)

        x /= xl
        y /= yl
        z /= zl
        dummy.setColumn(0, x)
        dummy.setColumn(1, y)
        dummy.setColumn(2, z)
        if dummy.determinant() < 0.0:
            dummy.setColumn(0, -x)
            scale.x = -scale.x

        return (_vec3(self.mlist[3], self.mlist[7],
                      self.mlist[11]), dummy, scale)
Exemple #3
0
 def getColumn(self, idx):
     """Return column (as vec4)."""
     m = self.mlist
     if idx == 0: return _vec4(m[0], m[4], m[8], m[12])
     elif idx == 1: return _vec4(m[1], m[5], m[9], m[13])
     elif idx == 2: return _vec4(m[2], m[6], m[10], m[14])
     elif idx == 3: return _vec4(m[3], m[7], m[11], m[15])
     else:
         raise IndexError, "index out of range"
Exemple #4
0
 def getColumn(self, idx):
     """Return column (as vec4)."""
     m=self.mlist
     if   idx==0: return _vec4(m[0], m[4], m[8], m[12])
     elif idx==1: return _vec4(m[1], m[5], m[9], m[13])
     elif idx==2: return _vec4(m[2], m[6], m[10], m[14])
     elif idx==3: return _vec4(m[3], m[7], m[11], m[15])
     else:
         raise IndexError,"index out of range"
Exemple #5
0
 def getColumn(self, index):
     """Return column (as vec4)."""
     if type(index)==int:
         m=self.mlist
         if   index==0: return _vec4(m[0], m[4], m[8], m[12])
         elif index==1: return _vec4(m[1], m[5], m[9], m[13])
         elif index==2: return _vec4(m[2], m[6], m[10], m[14])
         elif index==3: return _vec4(m[3], m[7], m[11], m[15])
         else:
             raise IndexError("index out of range")
     else:
         raise TypeError("index must be integer or 2-tuple")
Exemple #6
0
 def getColumn(self, index):
     """Return column (as vec4)."""
     if type(index) == int:
         m = self.mlist
         if index == 0: return _vec4(m[0], m[4], m[8], m[12])
         elif index == 1: return _vec4(m[1], m[5], m[9], m[13])
         elif index == 2: return _vec4(m[2], m[6], m[10], m[14])
         elif index == 3: return _vec4(m[3], m[7], m[11], m[15])
         else:
             raise IndexError("index out of range")
     else:
         raise TypeError("index must be integer or 2-tuple")
Exemple #7
0
 def __rmul__(self, other):
     T = type(other)
     # scalar*mat4
     if T == types.FloatType or T == types.IntType or T == types.LongType:
         return mat4(map(lambda x, other=other: other * x, self.mlist))
     # vec4*mat4
     if isinstance(other, _vec4):
         m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44 = self.mlist
         return _vec4(
             other.x * m11 + other.y * m21 + other.z * m31 + other.w * m41,
             other.x * m12 + other.y * m22 + other.z * m32 + other.w * m42,
             other.x * m13 + other.y * m23 + other.z * m33 + other.w * m43,
             other.x * m14 + other.y * m24 + other.z * m34 + other.w * m44)
     # vec3*mat4
     if isinstance(other, _vec3):
         m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44 = self.mlist
         w = float(other.x * m14 + other.y * m24 + other.z * m34 + m44)
         return _vec3(
             other.x * m11 + other.y * m21 + other.z * m31 + m41,
             other.x * m12 + other.y * m22 + other.z * m32 + m42,
             other.x * m13 + other.y * m23 + other.z * m33 + m43) / w
     # mat4*mat4
     if isinstance(other, mat4):
         return self.__mul__(other)
     # unsupported
     else:
         raise TypeError, "unsupported operand type for *"
Exemple #8
0
 def __getitem__(self, key):
     if type(key)==types.IntType:
         if key<0 or key>3:
             raise IndexError("index out of range")
         m=self.mlist
         if   key==0: return _vec4(m[0],m[4],m[8],m[12])
         elif key==1: return _vec4(m[1],m[5],m[9],m[13])
         elif key==2: return _vec4(m[2],m[6],m[10],m[14])
         elif key==3: return _vec4(m[3],m[7],m[11],m[15])
     elif type(key)==types.TupleType:
         i,j=key
         if i<0 or i>3 or j<0 or j>3:
             raise IndexError("index out of range")
         return self.mlist[i*4+j]
     else:
         raise TypeError("index must be integer or 2-tuple")
Exemple #9
0
 def __rmul__(self, other):
     T = type(other)
     # scalar*mat4
     if T==types.FloatType or T==types.IntType or T==types.LongType:
         return mat4(map(lambda x,other=other: other*x, self.mlist))
     # vec4*mat4
     if isinstance(other, _vec4):
         m11,m12,m13,m14,m21,m22,m23,m24,m31,m32,m33,m34,m41,m42,m43,m44 = self.mlist
         return _vec4(other.x*m11 + other.y*m21 + other.z*m31 + other.w*m41, 
                      other.x*m12 + other.y*m22 + other.z*m32 + other.w*m42,
                      other.x*m13 + other.y*m23 + other.z*m33 + other.w*m43,
                      other.x*m14 + other.y*m24 + other.z*m34 + other.w*m44)
     # vec3*mat4
     if isinstance(other, _vec3):
         m11,m12,m13,m14,m21,m22,m23,m24,m31,m32,m33,m34,m41,m42,m43,m44 = self.mlist
         w = float(other.x*m14 + other.y*m24 + other.z*m34 + m44)
         return _vec3(other.x*m11 + other.y*m21 + other.z*m31 + m41, 
                      other.x*m12 + other.y*m22 + other.z*m32 + m42,
                      other.x*m13 + other.y*m23 + other.z*m33 + m43)/w
     # mat4*mat4
     if isinstance(other, mat4):
         return self.__mul__(other)
     # unsupported
     else:
         raise TypeError("unsupported operand type for *")
Exemple #10
0
 def __getitem__(self, key):
     if type(key) == types.IntType:
         if key < 0 or key > 3:
             raise IndexError("index out of range")
         m = self.mlist
         if key == 0: return _vec4(m[0], m[4], m[8], m[12])
         elif key == 1: return _vec4(m[1], m[5], m[9], m[13])
         elif key == 2: return _vec4(m[2], m[6], m[10], m[14])
         elif key == 3: return _vec4(m[3], m[7], m[11], m[15])
     elif type(key) == types.TupleType:
         i, j = key
         if i < 0 or i > 3 or j < 0 or j > 3:
             raise IndexError("index out of range")
         return self.mlist[i * 4 + j]
     else:
         raise TypeError("index must be integer or 2-tuple")
Exemple #11
0
    def rotateVec(self, v):
        """Return the rotated vector v.

        The quaternion must be a unit quaternion.
        This operation is equivalent to turning v into a quat, computing
        self*v*self.conjugate() and turning the result back into a vec3.
        """

        u = _vec3(v[:3])
        ww = self.w * self.w
        xx = self.x * self.x
        yy = self.y * self.y
        zz = self.z * self.z
        wx = self.w * self.x
        wy = self.w * self.y
        wz = self.w * self.z
        xy = self.x * self.y
        xz = self.x * self.z
        yz = self.y * self.z

        u = (ww * u.x + xx * u.x - yy * u.x - zz * u.x + 2 *
             ((xy - wz) * u.y + (xz + wy) * u.z), ww * u.y - xx * u.y +
             yy * u.y - zz * u.y + 2 * ((xy + wz) * u.x + (yz - wx) * u.z),
             ww * u.z - xx * u.z - yy * u.z + zz * u.z + 2 * ((xz - wy) * u.x +
                                                              (yz + wx) * u.y))
        if isinstance(v, _vec4):
            return _vec4(u)
        return _vec3(u)
Exemple #12
0
    def rotateVec(self, v):
        """Return the rotated vector v.

        The quaternion must be a unit quaternion.
        This operation is equivalent to turning v into a quat, computing
        self*v*self.conjugate() and turning the result back into a vec3.
        """

        u = _vec3(v[:3])
        ww = self.w*self.w
        xx = self.x*self.x
        yy = self.y*self.y
        zz = self.z*self.z
        wx = self.w*self.x
        wy = self.w*self.y
        wz = self.w*self.z
        xy = self.x*self.y
        xz = self.x*self.z
        yz = self.y*self.z

        u = (ww*u.x + xx*u.x - yy*u.x - zz*u.x + 2*((xy-wz)*u.y + (xz+wy)*u.z),
             ww*u.y - xx*u.y + yy*u.y - zz*u.y + 2*((xy+wz)*u.x + (yz-wx)*u.z),
             ww*u.z - xx*u.z - yy*u.z + zz*u.z + 2*((xz-wy)*u.x + (yz+wx)*u.y))
        if isinstance(v, _vec4):
            return _vec4(u)
        return _vec3(u)
Exemple #13
0
    def __mul__(self, other):
        """Multiplication.

        >>> M=mat4(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
        >>> print M*2.0
        [   2.0000,    4.0000,    6.0000,    8.0000]
        [  10.0000,   12.0000,   14.0000,   16.0000]
        [  18.0000,   20.0000,   22.0000,   24.0000]
        [  26.0000,   28.0000,   30.0000,   32.0000]
        >>> print 2.0*M
        [   2.0000,    4.0000,    6.0000,    8.0000]
        [  10.0000,   12.0000,   14.0000,   16.0000]
        [  18.0000,   20.0000,   22.0000,   24.0000]
        [  26.0000,   28.0000,   30.0000,   32.0000]
        >>> print M*M
        [  90.0000,  100.0000,  110.0000,  120.0000]
        [ 202.0000,  228.0000,  254.0000,  280.0000]
        [ 314.0000,  356.0000,  398.0000,  440.0000]
        [ 426.0000,  484.0000,  542.0000,  600.0000]
        >>> print M*_vec3(1,2,3)
        (0.1765, 0.4510, 0.7255)
        >>> print _vec3(1,2,3)*M
        (0.7083, 0.8056, 0.9028)
        """
        T = type(other)
        # mat4*scalar
        if T == types.FloatType or T == types.IntType or T == types.LongType:
            return mat4(map(lambda x, other=other: x * other, self.mlist))
        # mat4*vec3
        if isinstance(other, _vec3):
            m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44 = self.mlist
            w = float(m41 * other.x + m42 * other.y + m43 * other.z + m44)
            return _vec3(
                m11 * other.x + m12 * other.y + m13 * other.z + m14,
                m21 * other.x + m22 * other.y + m23 * other.z + m24,
                m31 * other.x + m32 * other.y + m33 * other.z + m34) / w
        # mat4*vec4
        if isinstance(other, _vec4):
            m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44 = self.mlist
            return _vec4(
                m11 * other.x + m12 * other.y + m13 * other.z + m14 * other.w,
                m21 * other.x + m22 * other.y + m23 * other.z + m24 * other.w,
                m31 * other.x + m32 * other.y + m33 * other.z + m34 * other.w,
                m41 * other.x + m42 * other.y + m43 * other.z + m44 * other.w)
        # mat4*mat4
        if isinstance(other, mat4):
            m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44 = self.mlist
            n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 = other.mlist
            return mat4(m11 * n11 + m12 * n21 + m13 * n31 + m14 * n41,
                        m11 * n12 + m12 * n22 + m13 * n32 + m14 * n42,
                        m11 * n13 + m12 * n23 + m13 * n33 + m14 * n43,
                        m11 * n14 + m12 * n24 + m13 * n34 + m14 * n44,
                        m21 * n11 + m22 * n21 + m23 * n31 + m24 * n41,
                        m21 * n12 + m22 * n22 + m23 * n32 + m24 * n42,
                        m21 * n13 + m22 * n23 + m23 * n33 + m24 * n43,
                        m21 * n14 + m22 * n24 + m23 * n34 + m24 * n44,
                        m31 * n11 + m32 * n21 + m33 * n31 + m34 * n41,
                        m31 * n12 + m32 * n22 + m33 * n32 + m34 * n42,
                        m31 * n13 + m32 * n23 + m33 * n33 + m34 * n43,
                        m31 * n14 + m32 * n24 + m33 * n34 + m34 * n44,
                        m41 * n11 + m42 * n21 + m43 * n31 + m44 * n41,
                        m41 * n12 + m42 * n22 + m43 * n32 + m44 * n42,
                        m41 * n13 + m42 * n23 + m43 * n33 + m44 * n43,
                        m41 * n14 + m42 * n24 + m43 * n34 + m44 * n44)
        # unsupported
        else:
            raise TypeError, "unsupported operand type for *"
Exemple #14
0
 def getDiag(self):
     """Return the diagonal."""
     return _vec4(self.mlist[0], self.mlist[5], self.mlist[10], self.mlist[15])
Exemple #15
0
    def __mul__(self, other):
        """Multiplication.

        >>> M=mat4(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
        >>> print M*2.0
        [   2.0000,    4.0000,    6.0000,    8.0000]
        [  10.0000,   12.0000,   14.0000,   16.0000]
        [  18.0000,   20.0000,   22.0000,   24.0000]
        [  26.0000,   28.0000,   30.0000,   32.0000]
        >>> print 2.0*M
        [   2.0000,    4.0000,    6.0000,    8.0000]
        [  10.0000,   12.0000,   14.0000,   16.0000]
        [  18.0000,   20.0000,   22.0000,   24.0000]
        [  26.0000,   28.0000,   30.0000,   32.0000]
        >>> print M*M
        [  90.0000,  100.0000,  110.0000,  120.0000]
        [ 202.0000,  228.0000,  254.0000,  280.0000]
        [ 314.0000,  356.0000,  398.0000,  440.0000]
        [ 426.0000,  484.0000,  542.0000,  600.0000]
        >>> print M*_vec3(1,2,3)
        (0.1765, 0.4510, 0.7255)
        >>> print _vec3(1,2,3)*M
        (0.7083, 0.8056, 0.9028)
        """
        T = type(other)
        # mat4*scalar
        if T==types.FloatType or T==types.IntType or T==types.LongType:
            return mat4(map(lambda x,other=other: x*other, self.mlist))
        # mat4*vec3
        if isinstance(other, _vec3):
            m11,m12,m13,m14,m21,m22,m23,m24,m31,m32,m33,m34,m41,m42,m43,m44 = self.mlist
            w = float(m41*other.x + m42*other.y + m43*other.z + m44)
            return _vec3(m11*other.x + m12*other.y + m13*other.z + m14, 
                         m21*other.x + m22*other.y + m23*other.z + m24, 
                         m31*other.x + m32*other.y + m33*other.z + m34)/w
        # mat4*vec4
        if isinstance(other, _vec4):
            m11,m12,m13,m14,m21,m22,m23,m24,m31,m32,m33,m34,m41,m42,m43,m44 = self.mlist
            return _vec4(m11*other.x + m12*other.y + m13*other.z + m14*other.w, 
                         m21*other.x + m22*other.y + m23*other.z + m24*other.w, 
                         m31*other.x + m32*other.y + m33*other.z + m34*other.w,
                         m41*other.x + m42*other.y + m43*other.z + m44*other.w)
        # mat4*mat4
        if isinstance(other, mat4):
            m11,m12,m13,m14,m21,m22,m23,m24,m31,m32,m33,m34,m41,m42,m43,m44 = self.mlist
            n11,n12,n13,n14,n21,n22,n23,n24,n31,n32,n33,n34,n41,n42,n43,n44 = other.mlist
            return mat4( m11*n11+m12*n21+m13*n31+m14*n41,
                         m11*n12+m12*n22+m13*n32+m14*n42,
                         m11*n13+m12*n23+m13*n33+m14*n43,
                         m11*n14+m12*n24+m13*n34+m14*n44,

                         m21*n11+m22*n21+m23*n31+m24*n41,
                         m21*n12+m22*n22+m23*n32+m24*n42,
                         m21*n13+m22*n23+m23*n33+m24*n43,
                         m21*n14+m22*n24+m23*n34+m24*n44,

                         m31*n11+m32*n21+m33*n31+m34*n41,
                         m31*n12+m32*n22+m33*n32+m34*n42,
                         m31*n13+m32*n23+m33*n33+m34*n43,
                         m31*n14+m32*n24+m33*n34+m34*n44,

                         m41*n11+m42*n21+m43*n31+m44*n41,
                         m41*n12+m42*n22+m43*n32+m44*n42,
                         m41*n13+m42*n23+m43*n33+m44*n43,
                         m41*n14+m42*n24+m43*n34+m44*n44)
        # unsupported
        else:
            raise TypeError("unsupported operand type for *")
Exemple #16
0
 def getDiag(self):
     """Return the diagonal."""
     return _vec4(self.mlist[0], self.mlist[5], self.mlist[10],
                  self.mlist[15])