packages feed

bloxorz-0.1: Quaternion.hs

module Quaternion
where

import Graphics.Rendering.OpenGL.GL


type Quaternion = (Float, Float, Float, Float) -- w x y z

quatIdentity :: Quaternion
quatIdentity = (1.0, 0.0, 0.0, 0.0)

quatFromAngleAxis :: Float -> Float -> Float -> Float -> Quaternion
quatFromAngleAxis angle ax ay az = (w, x, y, z)
  where
    w = cos half
    x = hsin * ax
    y = hsin * ay
    z = hsin * az
    half = angle / 2.0
    hsin = sin half


quatMul :: Quaternion -> Quaternion -> Quaternion
quatMul (w1,x1,y1,z1) (w2,x2,y2,z2) = (ww,xx,yy,zz)
  where
    ww = w1*w2 - x1*x2 - y1*y2 - z1*z2
    xx = w1*x2 + x1*w2 + y1*z2 - z1*y2
    yy = w1*y2 + y1*w2 + z1*x2 - x1*z2
    zz = w1*z2 + z1*w2 + x1*y2 - y1*x2


quat2Matrix :: Quaternion -> IO (GLmatrix GLfloat)
quat2Matrix (w,x,y,z) =
  newMatrix ColumnMajor [(r00 :: GLfloat),r01,r02,r03,
                         r10,r11,r12,r13,
                         r20,r21,r22,r23,
                         r30,r31,r32,r33]
  where
    r00 = 1.0 - 2.0*y*y - 2.0*z*z
    r01 = 2.0*x*y + 2.0*w*z
    r02 = 2.0*x*z - 2.0*w*y
    r03 = 0.0

    r10 = 2.0*x*y - 2.0*w*z
    r11 = 1.0 - 2.0*x*x - 2.0*z*z
    r12 = 2.0*y*z + 2.0*w*x
    r13 = 0.0

    r20 = 2.0*x*z + 2.0*w*y
    r21 = 2.0*y*z - 2.0*w*x
    r22 = 1.0 - 2.0*x*x - 2.0*y*y
    r23 = 0.0

    r30 = 0.0
    r31 = 0.0
    r32 = 0.0
    r33 = 1.0