 TYPED:: m4. ( a: matrix4 b: matrix4 -- c: matrix4 )
     matrix4 (struct) :> c
 
-    a rows>> first  :> a1
-    a rows>> second :> a2
-    a rows>> third  :> a3
-    a rows>> fourth :> a4
-    b rows>> first  :> b1
-    b rows>> second :> b2
-    b rows>> third  :> b3
-    b rows>> fourth :> b4
+    a rows :> a4 :> a3 :> a2 :> a1
+    b rows :> b4 :> b3 :> b2 :> b1
 
-    a1 { 0 0 0 0 } vshuffle b1 v* :> c1a
-    a2 { 0 0 0 0 } vshuffle b1 v* :> c2a
-    a3 { 0 0 0 0 } vshuffle b1 v* :> c3a
-    a4 { 0 0 0 0 } vshuffle b1 v* :> c4a
+    a1 first  b1 n*v :> c1a
+    a2 first  b1 n*v :> c2a
+    a3 first  b1 n*v :> c3a
+    a4 first  b1 n*v :> c4a
 
-    a1 { 1 1 1 1 } vshuffle b2 v* c1a v+ :> c1b 
-    a2 { 1 1 1 1 } vshuffle b2 v* c2a v+ :> c2b
-    a3 { 1 1 1 1 } vshuffle b2 v* c3a v+ :> c3b
-    a4 { 1 1 1 1 } vshuffle b2 v* c4a v+ :> c4b
+    a1 second b2 n*v c1a v+ :> c1b 
+    a2 second b2 n*v c2a v+ :> c2b
+    a3 second b2 n*v c3a v+ :> c3b
+    a4 second b2 n*v c4a v+ :> c4b
 
-    a1 { 2 2 2 2 } vshuffle b3 v* c1b v+ :> c1c 
-    a2 { 2 2 2 2 } vshuffle b3 v* c2b v+ :> c2c
-    a3 { 2 2 2 2 } vshuffle b3 v* c3b v+ :> c3c
-    a4 { 2 2 2 2 } vshuffle b3 v* c4b v+ :> c4c
+    a1 third  b3 n*v c1b v+ :> c1c 
+    a2 third  b3 n*v c2b v+ :> c2c
+    a3 third  b3 n*v c3b v+ :> c3c
+    a4 third  b3 n*v c4b v+ :> c4c
 
-    a1 { 3 3 3 3 } vshuffle b4 v* c1c v+ :> c1 
-    a2 { 3 3 3 3 } vshuffle b4 v* c2c v+ :> c2
-    a3 { 3 3 3 3 } vshuffle b4 v* c3c v+ :> c3
-    a4 { 3 3 3 3 } vshuffle b4 v* c4c v+ :> c4
+    a1 fourth b4 n*v c1c v+
+    a2 fourth b4 n*v c2c v+
+    a3 fourth b4 n*v c3c v+
+    a4 fourth b4 n*v c4c v+
 
-    c1 c rows>> set-first
-    c2 c rows>> set-second
-    c3 c rows>> set-third
-    c4 c rows>> set-fourth
-
-    c ;
+    c set-rows ;
 
 CONSTANT: identity-matrix4
     S{ matrix4 f

! (c)Joe Groff bsd license
USING: accessors classes.struct kernel locals math math.functions
math.matrices.simd math.vectors math.vectors.simd sequences
sequences.private specialized-arrays typed ;
QUALIFIED-WITH: alien.c-types c
SIMD: c:float
SPECIALIZED-ARRAY: float-4


    float-4{ 0.0 0.0 0.0 1.0 } :> c4
    { t t t f } offset c4 v? :> offset'

    offset' { 3 3 3 0 } vshuffle { t f f t } vmask
    offset' { 3 3 3 1 } vshuffle { f t f t } vmask
    offset' { 3 3 3 2 } vshuffle { f f t t } vmask
    c4

    c set-rows ;

TYPED:: rotation-matrix4 ( axis: float-4 theta: float -- matrix: matrix4 )
    !   x*x + c*(1.0 - x*x)   x*y*(1.0 - c) - s*z   x*z*(1.0 - c) + s*y   0
