1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 # Services on `Matrix` to transform and project 3D coordinates
22 # Create an orthogonal projection matrix
24 # `left, right, bottom, top, near, far` defines the world clip planes.
25 new orthogonal
(left
, right
, bottom
, top
, near
, far
: Float)
31 assert dx
!= 0.0 and dy
!= 0.0 and dz
!= 0.0
33 var mat
= new Matrix.identity
(4)
35 mat
[3, 0] = -(right
+ left
) / dx
37 mat
[3, 1] = -(top
+ bottom
) / dy
39 mat
[3, 2] = -(near
+ far
) / dz
43 # Create a perspective transformation matrix
45 # Using the given vertical `field_of_view_y` in radians, the `aspect_ratio`
46 # and the `near`/`far` world distances.
47 new perspective
(field_of_view_y
, aspect_ratio
, near
, far
: Float)
49 var frustum_height
= (field_of_view_y
/2.0).tan
* near
50 var frustum_width
= frustum_height
* aspect_ratio
52 return new Matrix.frustum
(-frustum_width
, frustum_width
,
53 -frustum_height
, frustum_height
,
57 # Create a frustum transformation matrix
59 # `left, right, bottom, top, near, far` defines the world clip planes.
60 new frustum
(left
, right
, bottom
, top
, near
, far
: Float)
72 var mat
= new Matrix(4, 4)
74 mat
[0, 0] = 2.0 * near
/ dx
80 mat
[1, 1] = 2.0 * near
/ dy
84 mat
[2, 0] = (right
+ left
) / dx
85 mat
[2, 1] = (top
+ bottom
) / dy
86 mat
[2, 2] = -(near
+ far
) / dz
91 mat
[3, 2] = -2.0 * near
* far
/ dz
97 # Apply a translation by `x, y, z` to this matrix
98 fun translate
(x
, y
, z
: Float)
101 self[3, i
] = self[3,i
] + self[0, i
] * x
+ self[1, i
] * y
+ self[2, i
] * z
105 # Apply scaling on `x, y, z` to this matrix
106 fun scale
(x
, y
, z
: Float)
109 self[0, i
] = self[0, i
] * x
110 self[1, i
] = self[1, i
] * y
111 self[2, i
] = self[2, i
] * z
115 # Create a rotation matrix by `angle` around the vector defined by `x, y, z`
116 new rotation
(angle
, x
, y
, z
: Float)
118 var mat
= new Matrix.identity
(4)
120 var mag
= (x
*x
+ y
*y
+ z
*z
).sqrt
129 var inv_cos
= 1.0 - cos
131 mat
[0, 0] = inv_cos
*x
*x
+ cos
132 mat
[0, 1] = inv_cos
*x
*y
- z
*sin
133 mat
[0, 2] = inv_cos
*z
*x
+ y
*sin
135 mat
[1, 0] = inv_cos
*x
*y
+ z
*sin
136 mat
[1, 1] = inv_cos
*y
*y
+ cos
137 mat
[1, 2] = inv_cos
*y
*z
- x
*sin
139 mat
[2, 0] = inv_cos
*z
*x
- y
*sin
140 mat
[2, 1] = inv_cos
*y
*z
+ x
*sin
141 mat
[2, 2] = inv_cos
*z
*z
+ cos
146 # Apply a rotation of `angle` radians around the vector `x, y, z`
147 fun rotate
(angle
, x
, y
, z
: Float)
149 var rotation
= new Matrix.rotation
(angle
, x
, y
, z
)
150 var rotated
= self * rotation
151 self.items
= rotated
.items