Class: RubyGL::Mat4

Inherits:
Object
  • Object
show all
Defined in:
lib/rubygl/math.rb

Overview

Stored In Column Order For Interoperability With OpenGL. Subscript Operator Will Return A Vector That Represents A Column Within The Matrix. This Matrix Class Only Supports Matrices Where The Number Of Rows Equals The Number Of Columns; Operations Are Constrained As Such.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(diagonal = 1.0) ⇒ Mat4

Returns a new instance of Mat4.



180
181
182
183
184
185
186
187
# File 'lib/rubygl/math.rb', line 180

def initialize(diagonal = 1.0)
    @data = Array.new(4) { |index|
        column = Vec4.new()
        column[index] = diagonal
        
        column
    }
end

Class Method Details

.orthogonal(left, right, bottom, top, z_near = -1.0,, z_far = 1.0) ⇒ Object



251
252
253
254
255
256
257
258
259
260
261
262
# File 'lib/rubygl/math.rb', line 251

def self.orthogonal(left, right, bottom, top, z_near = -1.0, z_far = 1.0)
    mat = Mat4.new(1.0)
    mat[0][0] = 2.0 / (right - left)
    mat[1][1] = 2.0 / (top - bottom)
    mat[2][2] = 2.0 / (z_near - z_far)
    mat[3][3] = 1.0
    mat[3][0] = -(right + left) / (right - left)
    mat[3][1] = -(top + bottom) / (top - bottom)
    mat[3][2] = -(z_far + z_near) / (z_far - z_near)
    
    mat
end

.perspective(fov, aspect, z_near, z_far) ⇒ Object



237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/rubygl/math.rb', line 237

def self.perspective(fov, aspect, z_near, z_far)
    top = Math::tan(Conversion::deg_to_rad(fov) / 2) * z_near
    right = top * aspect
    
    mat = Mat4.new(1.0)
    mat[0][0] = z_near / right
    mat[1][1] = z_near / top
    mat[2][2] = -(z_far + z_near) / (z_far - z_near)
    mat[3][2] = -2.0 * z_far * z_near / (z_far - z_near)
    mat[2][3] = -1.0
    
    mat
end

.rotation(x_axis, y_axis, z_axis, theta) ⇒ Object

The axis value should be 0 if that axis should not be rotated around; any other value indicates its priority (higher priority axis is rotated around before the lower priority axis).



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/rubygl/math.rb', line 202

def self.rotation(x_axis, y_axis, z_axis, theta)
    rad_angle = Conversion::deg_to_rad(theta)
    sin_angle = Math::sin(rad_angle)
    cos_angle = Math::cos(rad_angle)
    
    # Multiply Lower -> Higher To Get Ordering Correct
    axis_priority = [[:x, x_axis], [:y, y_axis], [:z, z_axis]]
    axis_priority.delete_if { |(_, val)| 
        val == 0 
    }.sort!.reverse!
    
    rot_matrix = Mat4.new(1.0)
    axis_priority.each { |(axis, _)|
        mat = Mat4.new(1.0)
    
        if axis == :x then
            mat[1][1] = mat[2][2] = cos_angle
            mat[1][2] = sin_angle
            mat[2][1] = -sin_angle
        elsif axis == :y then
            mat[0][0] = mat[2][2] = cos_angle
            mat[0][2] = -sin_angle
            mat[2][0] = sin_angle
        else
            mat[0][0] = mat[1][1] = cos_angle
            mat[0][1] = sin_angle
            mat[1][0] = -sin_angle
        end
        
        rot_matrix *= mat
    }
    
    rot_matrix
end

.translation(x, y, z) ⇒ Object



189
190
191
192
193
194
195
196
197
# File 'lib/rubygl/math.rb', line 189

def self.translation(x, y, z)
    matrix = Mat4.new(1.0)
    
    matrix[3][0] = x
    matrix[3][1] = y
    matrix[3][2] = z
    
    matrix
end

Instance Method Details

#*(other_matrix) ⇒ Object



264
265
266
267
268
269
270
271
272
273
274
275
276
# File 'lib/rubygl/math.rb', line 264

def *(other_matrix)
    new_matrix = Mat4.new(0)
    
    for i in 0...self.dim
        for j in 0...self.dim
            for k in 0...self.dim
                new_matrix[j][i] += self[k][i] * other_matrix[j][k]
            end
        end
    end
    
    new_matrix
end

#[](index) ⇒ Object



282
283
284
# File 'lib/rubygl/math.rb', line 282

def [](index)
    @data[index]
end

#[]=(index, value) ⇒ Object



286
287
288
# File 'lib/rubygl/math.rb', line 286

def []=(index, value)
    @data[index] = value
end

#dimObject



278
279
280
# File 'lib/rubygl/math.rb', line 278

def dim()
    @data.size()
end

#to_aObject



296
297
298
# File 'lib/rubygl/math.rb', line 296

def to_a()
    self.to_ary
end

#to_aryObject



290
291
292
293
294
# File 'lib/rubygl/math.rb', line 290

def to_ary()
    @data.collect { |vec|
        vec.to_ary
    }.flatten!
end