on master help sign in
Split MJS into Math.Vector and Math.Matrix
commit9bed9119c8b4894852f5640434729a1b1f375628 authorEvan Czaplicki <info@elm-lang.org> dateMon 5 May 2014, 15:57 (13 years ago) parent3965802
4 files changed+205−172
compiler/SourceSyntax/Literal.hs+4−4 libraries/MJS.elm → libraries/Math/Matrix.elm+33−104 libraries/Math/Vector.elm+126 libraries/Native/MJS.js+42−64
compiler/SourceSyntax/Literal.hs+4−4
@@ -29,10 +29,10 @@ glTipeName glTipe =
2929 case glTipe of
3030 Int -> "Int"
3131 Float -> "Float"
32− V2 -> "MJS.V2"
33− V3 -> "MJS.V3"
34− V4 -> "MJS.V4"
35− M4 -> "MJS.M4x4"
32+ V2 -> "Math.Vector.Vec2"
33+ V3 -> "Math.Vector.Vec3"
34+ V4 -> "Math.Vector.Vec4"
35+ M4 -> "Math.Matrix.Mat4"
3636 Texture -> "Graphics.WebGL.Texture"
3737
3838data GLShaderTipe = GLShaderTipe
libraries/MJS.elm → libraries/Math/Matrix.elmrenamed+33−104
@@ -1,118 +1,47 @@
1−module MJS where
1+module Math.Matrix where
22
33{-| A high performance linear algebra library using native JS arrays. Geared
4−towards 3D graphics and use with `Graphics.WebGL`.
4+towards 3D graphics and use with `Graphics.WebGL`. All matrices are immutable.
55
6−Both vectors and matrices are immutable.
6+This library uses the convention that the prefix `make` is creating a new
7+array, whereas without the prefix, you are applying some transform to an
8+existing matrix.
79
8−# Constructing and Destructing Vectors
10+@docs mul4x4
911
10−@docs v3, toTuple3
11−
12−# Vector Math
13−
14−@docs add, sub, neg, direction, length, lengthSquared, normalize, scale
15−
16−# Vector Operations
17−
18−@docs dot, cross, mul4x4
19−
20−Matrix operations
12+# Operations
2113
2214@docs identity, inverseOrthonormal, mul, mulAffine, transpose, makeBasis
2315
24−Matrix projections
16+# Projections
2517
2618@docs makeFrustrum, makePerspective, makeOrtho, makeOrtho2D, makeLookAt
2719
28−Matrix transforms
20+# Transforms
2921
3022@docs makeRotate, rotate, makeScale3, makeScale, scaleM3, scaleM, makeTranslate3, makeTranslate, translate3, translate
3123
3224-}
3325
3426import Native.MJS
27+import Math.Vector (Vec3)
3528
36−data V2 = V2
37−data V3 = V3
38−data V4 = V4
39−
40−{-| Creates a new 3-element vector with the given values
41−-}
42−v3 : Float -> Float -> Float -> V3
43−v3 = Native.MJS.v3
44−
45−{-| Convert to a native tuple
46−-}
47−toTuple3 : V3 -> (Float,Float,Float)
48−toTuple3 = Native.MJS.toTuple3
49−
50−{-| Vector addition: a + b
51−-}
52−add : V3 -> V3 -> V3
53−add = Native.MJS.v3add
54−
55−{-| Vector subtraction: a - b
56−-}
57−sub : V3 -> V3 -> V3
58−sub = Native.MJS.v3sub
59−
60−{-| Vector negation: -a
61−-}
62−neg : V3 -> V3
63−neg = Native.MJS.v3neg
64−
65−{-| The normalized direction from a to b: (a - b) / |a - b|
66−-}
67−direction : V3 -> V3 -> V3
68−direction = Native.MJS.v3direction
69−
70−{-| The length of the given vector: |a|
71−-}
72−length : V3 -> Float
73−length = Native.MJS.v3length
74−
75−{-| The square of the length of the given vector: |a| * |a|
76−-}
77−lengthSquared : V3 -> Float
78−lengthSquared = Native.MJS.v3lengthSquared
79−
80−{-| A unit vector with the same direction as the given vector: a / |a|
81−-}
82−normalize : V3 -> V3
83−normalize = Native.MJS.v3normalize
84−
85−{-| Multiply the vector by a scalar: a * k
86−-}
87−scale : V3 -> Float -> V3
88−scale = Native.MJS.v3scale
89−
90−{-| The dot product of a and b
91−-}
92−dot : V3 -> V3 -> Float
93−dot = Native.MJS.v3dot
94−
95−{-| The cross product of a and b
96−-}
97−cross : V3 -> V3 -> V3
98−cross = Native.MJS.v3cross
99−
100−data M4x4 = M4x4
29+data Mat4 = Mat4
10130
10231{-| Multiply a vector by a 4x4 matrix: m * v
10332-}
104−mul4x4 : M4x4 -> V3 -> V3
33+mul4x4 : Mat4 -> Vec3 -> Vec3
10534mul4x4 = Native.MJS.v3mul4x4
10635
10736{-| A matrix with all 0s, except 1s on the diagonal.
10837-}
109−identity : M4x4
38+identity : Mat4
11039identity = Native.MJS.m4x4identity
11140
11241{-| Computes the inverse of the given matrix m, assuming that the matrix is
11342orthonormal.
11443-}
115−inverseOrthonormal : M4x4 -> M4x4
44+inverseOrthonormal : Mat4 -> Mat4
11645inverseOrthonormal = Native.MJS.m4x4inverseOrthonormal
11746
11847{-| Creates a matrix for a projection frustum with the given parameters.
@@ -126,7 +55,7 @@ Parameters:
12655 * znear - the near z distance of the frustum
12756 * zfar - the far z distance of the frustum
12857-}
129−makeFrustrum : Float -> Float -> Float -> Float -> Float -> Float -> Float -> M4x4
58+makeFrustrum : Float -> Float -> Float -> Float -> Float -> Float -> Float -> Mat4
13059makeFrustrum = Native.MJS.m4x4makeFrustrum
13160
13261{-| Creates a matrix for a perspective projection with the given parameters.
@@ -138,7 +67,7 @@ Parameters:
13867 * znear - the near z distance of the projection
13968 * zfar - the far z distance of the projection
14069-}
141−makePerspective : Float -> Float -> Float -> Float -> M4x4
70+makePerspective : Float -> Float -> Float -> Float -> Mat4
14271makePerspective = Native.MJS.m4x4makePerspective
14372
14473{-|
@@ -153,7 +82,7 @@ Parameters:
15382 * znear - the near z distance of the frustum
15483 * zfar - the far z distance of the frustum
15584-}
156−makeOrtho : Float -> Float -> Float -> Float -> Float -> Float -> Float -> M4x4
85+makeOrtho : Float -> Float -> Float -> Float -> Float -> Float -> Float -> Mat4
15786makeOrtho = Native.MJS.m4x4makeOrtho
15887
15988{-| Creates a matrix for a 2D orthogonal frustum projection with the given
@@ -166,75 +95,75 @@ Parameters:
16695 * bottom - the bottom coordinate of the frustum
16796 * top - the top coordinate of the frustum
16897-}
169−makeOrtho2D : Float -> Float -> Float -> Float -> M4x4
98+makeOrtho2D : Float -> Float -> Float -> Float -> Mat4
17099makeOrtho2D = Native.MJS.m4x4makeOrtho2D
171100
172101{-| Matrix multiplcation: a * b
173102-}
174−mul : M4x4 -> M4x4 -> M4x4
103+mul : Mat4 -> Mat4 -> Mat4
175104mul = Native.MJS.m4x4mul
176105
177106{-| Matrix multiplication, assuming a and b are affine: a * b
178107-}
179−mulAffine : M4x4 -> M4x4 -> M4x4
108+mulAffine : Mat4 -> Mat4 -> Mat4
180109mulAffine = Native.MJS.m4x4mulAffine
181110
182111{-| Creates a transformation matrix for rotation in radians about the
1831123-element vector axis.
184113-}
185−makeRotate : Float -> V3 -> M4x4
114+makeRotate : Float -> Vec3 -> Mat4
186115makeRotate = Native.MJS.m4x4makeRotate
187116
188117{-| Concatenates a rotation of angle radians about the axis to the given matrix.
189118-}
190−rotate : Float -> V3 -> M4x4 -> M4x4
119+rotate : Float -> Vec3 -> Mat4 -> Mat4
191120rotate = Native.MJS.m4x4rotate
192121
193122{-| Creates a transformation matrix for scaling by 3 scalar values, one for
194123each of the x, y, and z directions.
195124-}
196−makeScale3 : Float -> Float -> Float -> M4x4
125+makeScale3 : Float -> Float -> Float -> Mat4
197126makeScale3 = Native.MJS.m4x4makeScale3
198127
199128{-| Creates a transformation matrix for scaling each of the x, y, and z axes by
200129the amount given in the corresponding element of the 3-element vector.
201130-}
202−makeScale : V3 -> M4x4
131+makeScale : Vec3 -> Mat4
203132makeScale = Native.MJS.m4x4makeScale
204133
205134{-| Concatenates a scaling to the given matrix.
206135-}
207−scaleM3 : Float -> Float -> Float -> M4x4 -> M4x4
136+scaleM3 : Float -> Float -> Float -> Mat4 -> Mat4
208137scaleM3 = Native.MJS.m4x4scale3
209138
210139{-| Concatenates a scaling to the given matrix.
211140-}
212−scaleM : V3 -> M4x4 -> M4x4
141+scaleM : Vec3 -> Mat4 -> Mat4
213142scaleM = Native.MJS.m4x4scale
214143
215144{-|
216145Creates a transformation matrix for translating by 3 scalar values, one for
217146each of the x, y, and z directions.
218147-}
219−makeTranslate3 : Float -> Float -> Float -> M4x4
148+makeTranslate3 : Float -> Float -> Float -> Mat4
220149makeTranslate3 = Native.MJS.m4x4makeTranslate3
221150
222151{-| Creates a transformation matrix for translating each of the x, y, and z
223152axes by the amount given in the corresponding element of the 3-element vector.
224153-}
225−makeTranslate : V3 -> M4x4
154+makeTranslate : Vec3 -> Mat4
226155makeTranslate = Native.MJS.m4x4makeTranslate
227156
228157{-|
229158Concatenates a translation to the given matrix.
230159-}
231−translate3 : Float -> Float -> Float -> M4x4 -> M4x4
160+translate3 : Float -> Float -> Float -> Mat4 -> Mat4
232161translate3 = Native.MJS.m4x4translate3
233162
234163{-|
235164Concatenates a translation to the given matrix.
236165-}
237−translate : V3 -> M4x4 -> M4x4
166+translate : Vec3 -> Mat4 -> Mat4
238167translate = Native.MJS.m4x4translate
239168
240169{-|
@@ -246,16 +175,16 @@ Parameters:
246175 * center - The location of the focused object
247176 * up - The "up" direction according to the camera
248177-}
249−makeLookAt : V3 -> V3 -> V3 -> M4x4
178+makeLookAt : Vec3 -> Vec3 -> Vec3 -> Mat4
250179makeLookAt = Native.MJS.m4x4makeLookAt
251180
252181{-| "Flip" the matrix across the diagonal by swapping row index and column
253182index.
254183-}
255−transpose : M4x4 -> M4x4
184+transpose : Mat4 -> Mat4
256185transpose = Native.MJS.m4x4transpose
257186
258187{-| Creates a transform from a basis consisting of 3 linearly independent vectors.
259188-}
260−makeBasis : V3 -> V3 -> V3 -> M4x4
189+makeBasis : Vec3 -> Vec3 -> Vec3 -> Mat4
261190makeBasis = Native.MJS.m4x4makeBasis
libraries/Math/Vector.elmnew file+126
@@ -0,0 +1,126 @@
1+module Math.Vector where
2+
3+{-| A high performance linear algebra library using native JS arrays. Geared
4+towards 3D graphics and use with `Graphics.WebGL`.
5+
6+All vectors are immutable.
7+
8+# Create
9+@docs v3, i, j, k
10+
11+# Get and Set
12+The set functions create a new copy of the vector, updating a single field.
13+
14+@docs getX, getY, getZ, setX, setY, setZ, toTuple, toRecord
15+
16+# Operations
17+@docs add, sub, neg, direction, length, lengthSquared, normalize, scale, dot, cross
18+
19+-}
20+
21+import Native.MJS
22+
23+data Vec2 = Vec2
24+data Vec3 = Vec3
25+data Vec4 = Vec4
26+
27+{-| Creates a new 3-element vector with the given values.
28+-}
29+v3 : Float -> Float -> Float -> Vec3
30+v3 = Native.MJS.v3
31+
32+{-| The unit vector &icirc; which points in the x direction: `v3 1 0 0` -}
33+i : Vec3
34+i = Native.MJS.v3 1 0 0
35+
36+{-| The unit vector &jcirc; which points in the y direction: `v3 0 1 0` -}
37+j : Vec3
38+j = Native.MJS.v3 0 1 0
39+
40+{-| The unit vector &kcirc; which points in the z direction: `v3 0 0 1` -}
41+k : Vec3
42+k = Native.MJS.v3 0 0 1
43+
44+{-| Extract the x component of a vector. -}
45+getX : Vec3 -> Float
46+getX = Native.MJS.getX
47+
48+{-| Extract the y component of a vector. -}
49+getY : Vec3 -> Float
50+getY = Native.MJS.getY
51+
52+{-| Extract the z component of a vector. -}
53+getZ : Vec3 -> Float
54+getZ = Native.MJS.getZ
55+
56+{-| Update the x component of a vector. -}
57+setX : Vec3 -> Float
58+setX = Native.MJS.setX
59+
60+{-| Update the y component of a vector. -}
61+setY : Vec3 -> Float
62+setY = Native.MJS.setY
63+
64+{-| Update the z component of a vector. -}
65+setZ : Vec3 -> Float
66+setZ = Native.MJS.setZ
67+
68+{-| Convert a vector to a tuple.
69+-}
70+toTuple : Vec3 -> (Float,Float,Float)
71+toTuple = Native.MJS.toTuple3
72+
73+{-| Convert a vector to a record.
74+-}
75+toRecord : Vec3 -> { x:Float, y:Float, z:Float }
76+toRecord = Native.MJS.toRecord3
77+
78+{-| Vector addition: a + b
79+-}
80+add : Vec3 -> Vec3 -> Vec3
81+add = Native.MJS.v3add
82+
83+{-| Vector subtraction: a - b
84+-}
85+sub : Vec3 -> Vec3 -> Vec3
86+sub = Native.MJS.v3sub
87+
88+{-| Vector negation: -a
89+-}
90+neg : Vec3 -> Vec3
91+neg = Native.MJS.v3neg
92+
93+{-| The normalized direction from a to b: (a - b) / |a - b|
94+-}
95+direction : Vec3 -> Vec3 -> Vec3
96+direction = Native.MJS.v3direction
97+
98+{-| The length of the given vector: |a|
99+-}
100+length : Vec3 -> Float
101+length = Native.MJS.v3length
102+
103+{-| The square of the length of the given vector: |a| * |a|
104+-}
105+lengthSquared : Vec3 -> Float
106+lengthSquared = Native.MJS.v3lengthSquared
107+
108+{-| A unit vector with the same direction as the given vector: a / |a|
109+-}
110+normalize : Vec3 -> Vec3
111+normalize = Native.MJS.v3normalize
112+
113+{-| Multiply the vector by a scalar: a * k
114+-}
115+scale : Vec3 -> Float -> Vec3
116+scale = Native.MJS.v3scale
117+
118+{-| The dot product of a and b
119+-}
120+dot : Vec3 -> Vec3 -> Float
121+dot = Native.MJS.v3dot
122+
123+{-| The cross product of a and b
124+-}
125+cross : Vec3 -> Vec3 -> Vec3
126+cross = Native.MJS.v3cross
libraries/Native/MJS.js+42−64
@@ -30,7 +30,7 @@
3030 * File: mjs
3131 *
3232 * Vector and Matrix math utilities for JavaScript, optimized for WebGL.
33− * Edited to work with Elm Programming Language
33+ * Edited to work with the Elm Programming Language
3434 */
3535
3636Elm.Native.MJS = {};
@@ -56,7 +56,7 @@ Elm.Native.MJS.make = function(elm) {
5656 * For potentially more performance, the assert methods can be
5757 * commented out in each place where they are called.
5858 */
59− //var MJS_DO_ASSERT = true;
59+ var MJS_DO_ASSERT = false;
6060
6161 /*
6262 * Constant: MJS_FLOAT_ARRAY_TYPE
@@ -73,14 +73,15 @@ Elm.Native.MJS.make = function(elm) {
7373 //MJS_FLOAT_ARRAY_TYPE = Float64Array;
7474 //MJS_FLOAT_ARRAY_TYPE = Array;
7575
76− //if (MJS_DO_ASSERT) {
77− //function MathUtils_assert(cond, msg) {
78− //if (!cond)
79− //throw "Assertion failed: " + msg;
80− //}
81− //} else {
82− function MathUtils_assert() { }
83− //}
76+ if (MJS_DO_ASSERT) {
77+ function MathUtils_assert(cond, msg) {
78+ if (!cond) {
79+ throw "Assertion failed: " + msg;
80+ }
81+ }
82+ } else {
83+ function MathUtils_assert() { }
84+ }
8485
8586 /*
8687 * Class: V3
@@ -104,11 +105,6 @@ Elm.Native.MJS.make = function(elm) {
104105 V3.$ = function V3_$(x, y, z) {
105106 return [x, y, z];
106107 };
107−
108− V3.clone = function V3_clone(a) {
109− //MathUtils_assert(a.length == 3, "a.length == 3");
110− return [a[0], a[1], a[2]];
111− };
112108 } else {
113109 V3.x = new MJS_FLOAT_ARRAY_TYPE([1.0, 0.0, 0.0]);
114110 V3.y = new MJS_FLOAT_ARRAY_TYPE([0.0, 1.0, 0.0]);
@@ -131,34 +127,21 @@ Elm.Native.MJS.make = function(elm) {
131127 V3.$ = function V3_$(x, y, z) {
132128 return new MJS_FLOAT_ARRAY_TYPE([x, y, z]);
133129 };
134−
135− /*
136− * Function: V3.clone
137− *
138− * Clone the given 3-element vector.
139− *
140− * Parameters:
141− *
142− * a - the 3-element vector to clone
143− *
144− * Returns:
145− *
146− * A new vector with the same values as the passed-in one.
147− */
148−
149− V3.clone = function V3_clone(a) {
150− //MathUtils_assert(a.length == 3, "a.length == 3");
151− return new MJS_FLOAT_ARRAY_TYPE(a);
152− };
153130 }
154131
155132 V3.u = V3.x;
156133 V3.v = V3.y;
157134
158− /* Function: V3.toTuple3
159− *
160− * Turn into an Elm Tuple
161− */
135+ V3.getX = function V3_getX(a) {
136+ return a[0];
137+ }
138+ V3.getY = function V3_getY(a) {
139+ return a[1];
140+ }
141+ V3.getZ = function V3_getZ(a) {
142+ return a[2];
143+ }
144+
162145 V3.toTuple3 = function V3_toTuple3(a) {
163146 return {
164147 ctor:"_Tuple3",
@@ -167,6 +150,21 @@ Elm.Native.MJS.make = function(elm) {
167150 _2:a[2]
168151 };
169152 };
153+ V3.fromTuple3 = function V3_fromTuple3(t) {
154+ return new MJS_FLOAT_ARRAY_TYPE([t._0, t._1, t._2]);
155+ };
156+
157+ V3.toRecord3 = function V3_toRecord3(a) {
158+ return {
159+ _:{},
160+ x:a[0],
161+ y:a[1],
162+ z:a[2]
163+ };
164+ };
165+ V3.fromRecord3 = function V3_fromRecord3(r) {
166+ return new MJS_FLOAT_ARRAY_TYPE([r.x, r.y, r.z]);
167+ };
170168
171169 /*
172170 * Function: V3.add
@@ -506,14 +504,6 @@ Elm.Native.MJS.make = function(elm) {
506504 m08, m09, m10, m11,
507505 m12, m13, m14, m15];
508506 };
509−
510− M4x4.clone = function M4x4_clone(m) {
511− //MathUtils_assert(m.length == 16, "m.length == 16");
512− return new [m[0], m[1], m[2], m[3],
513− m[4], m[5], m[6], m[7],
514− m[8], m[9], m[10], m[11],
515− m[12], m[13], m[14], m[15]];
516− };
517507 } else {
518508 M4x4.I = new MJS_FLOAT_ARRAY_TYPE([1.0, 0.0, 0.0, 0.0,
519509 0.0, 1.0, 0.0, 0.0,
@@ -543,24 +533,6 @@ Elm.Native.MJS.make = function(elm) {
543533 m08, m09, m10, m11,
544534 m12, m13, m14, m15]);
545535 };
546−
547− /*
548− * Function: M4x4.clone
549− *
550− * Clone the given 4x4 matrix.
551− *
552− * Parameters:
553− *
554− * m - the 4x4 matrix to clone
555− *
556− * Returns:
557− *
558− * A new matrix with the same values as the passed-in one.
559− */
560− M4x4.clone = function M4x4_clone(m) {
561− //MathUtils_assert(m.length == 16, "m.length == 16");
562− return new MJS_FLOAT_ARRAY_TYPE(m);
563− };
564536 }
565537
566538 M4x4.identity = M4x4.I;
@@ -1740,7 +1712,13 @@ Elm.Native.MJS.make = function(elm) {
17401712 return {
17411713 V3: V3,
17421714 v3: F3(V3.$),
1715+ getX: V3.getX,
1716+ getY: V3.getY,
1717+ getZ: V3.getZ,
17431718 toTuple3: V3.toTuple3,
1719+ toRecord3: V3.toRecord3,
1720+ fromTuple3: V3.fromTuple3,
1721+ fromRecord3: V3.fromRecord3,
17441722 v3add: F2(V3.add),
17451723 v3sub: F2(V3.sub),
17461724 v3neg: V3.neg,