crocodile-0.1: app/src/Matrix.hs
-- 4D Matrix Library
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash #-}
module Matrix where
import Vector
data Matrix = Matrix ![Double] deriving (Show, Read, Eq)
-- Just pass back the identity matrix
identity :: Matrix
identity = Matrix [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
-- This multiplies one element of the matrix against
mulElement :: Matrix -> Matrix -> Int -> Int -> Double
mulElement (Matrix mat1) (Matrix mat2) i j = sum [(mat1 !! (i * 4 + k)) * (mat2 !! (k * 4 + j)) | k <- [0..3]]
-- Multiply together two matrices
-- TODO - Turn mulElement into a lambda function?
mul :: Matrix -> Matrix -> Matrix
mul a b = Matrix [mulElement a b i j | j <- [0..3], i <- [0..3]]
-- Need matrix inversion code
-- Vector * Matrix
transformVector :: Matrix -> Vector -> Vector
transformVector (Matrix mat) (Vector !x !y !z !w) = Vector x' y' z' w'
where
!vec = [x, y, z, w]
!xvector = take 4 mat
!yvector = take 4 (drop 4 mat)
!zvector = take 4 (drop 8 mat)
!wvector = take 4 (drop 12 mat)
!x' = sum $ zipWith (*) vec xvector
!y' = sum $ zipWith (*) vec yvector
!z' = sum $ zipWith (*) vec zvector
!w' = sum $ zipWith (*) vec wvector
-- Build a matrix from 4 vectors
buildMatrix :: Vector -> Vector -> Vector -> Vector -> Matrix
buildMatrix (Vector xx xy xz _) (Vector yx yy yz _) (Vector zx zy zz _) (Vector px py pz _) = Matrix ([xx, xy, xz] ++ [px] ++
[yx, yy, yz] ++ [py] ++
[zx, zy, zz] ++ [pz] ++
[0, 0, 0, 1])
getTranslation :: Matrix -> Vector
{-# SPECIALIZE INLINE getTranslation :: Matrix -> Vector #-}
getTranslation (Matrix a) = Vector x y z 1
where
[!x, !y, !z, _] = drop 12 a
translationMatrix :: Double -> Double -> Double -> Matrix
translationMatrix !x !y !z = Matrix [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1]
translationMatrix' :: Vector -> Matrix
translationMatrix' (Vector !x !y !z _) = Matrix [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1]