Class: Bestguigui::Render3D::Mat4
- Inherits:
-
Object
- Object
- Bestguigui::Render3D::Mat4
- Defined in:
- lib/bestguigui/render_3d/mat4.rb
Overview
Matrice 4x4, colonne-major (convention OpenGL) — le strict nécessaire pour remplacer la pile de matrices figée (glMatrixMode/glRotatef/ gluPerspective/gluLookAt) par des matrices calculées à la main et envoyées aux shaders comme uniforms.
Instance Attribute Summary collapse
-
#data ⇒ Object
readonly
16 floats, colonne-major.
Class Method Summary collapse
- .identity ⇒ Object
- .identity_data ⇒ Object
-
.look_at(eye, target, up) ⇒ Object
Équivalent de gluLookAt.
-
.perspective(fovy_degrees, aspect, near, far) ⇒ Object
Équivalent de gluPerspective.
- .rotation_x(degrees) ⇒ Object
- .rotation_y(degrees) ⇒ Object
- .scaling(x, y, z) ⇒ Object
- .translation(x, y, z) ⇒ Object
Instance Method Summary collapse
- #*(other) ⇒ Object
-
#initialize(data = Mat4.identity_data) ⇒ Mat4
constructor
A new instance of Mat4.
- #to_a ⇒ Object
Constructor Details
#initialize(data = Mat4.identity_data) ⇒ Mat4
Returns a new instance of Mat4.
10 11 12 |
# File 'lib/bestguigui/render_3d/mat4.rb', line 10 def initialize(data = Mat4.identity_data) @data = data end |
Instance Attribute Details
#data ⇒ Object (readonly)
16 floats, colonne-major
8 9 10 |
# File 'lib/bestguigui/render_3d/mat4.rb', line 8 def data @data end |
Class Method Details
.identity ⇒ Object
18 19 20 |
# File 'lib/bestguigui/render_3d/mat4.rb', line 18 def self.identity new end |
.identity_data ⇒ Object
14 15 16 |
# File 'lib/bestguigui/render_3d/mat4.rb', line 14 def self.identity_data [1.0, 0, 0, 0, 0, 1.0, 0, 0, 0, 0, 1.0, 0, 0, 0, 0, 1.0] end |
.look_at(eye, target, up) ⇒ Object
Équivalent de gluLookAt. eye/target/up : tableaux [x, y, z].
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/bestguigui/render_3d/mat4.rb', line 80 def self.look_at(eye, target, up) ex, ey, ez = eye tx, ty, tz = target ux, uy, uz = up fx, fy, fz = tx - ex, ty - ey, tz - ez flen = Math.sqrt((fx * fx) + (fy * fy) + (fz * fz)) fx /= flen fy /= flen fz /= flen sx = (fy * uz) - (fz * uy) sy = (fz * ux) - (fx * uz) sz = (fx * uy) - (fy * ux) slen = Math.sqrt((sx * sx) + (sy * sy) + (sz * sz)) sx /= slen sy /= slen sz /= slen rux = (sy * fz) - (sz * fy) ruy = (sz * fx) - (sx * fz) ruz = (sx * fy) - (sy * fx) new([ sx, rux, -fx, 0, sy, ruy, -fy, 0, sz, ruz, -fz, 0, -((sx * ex) + (sy * ey) + (sz * ez)), -((rux * ex) + (ruy * ey) + (ruz * ez)), (fx * ex) + (fy * ey) + (fz * ez), 1.0 ]) end |
.perspective(fovy_degrees, aspect, near, far) ⇒ Object
Équivalent de gluPerspective. near/far forcés en Float : si on les laisse en Integer (ex: near: 1, far: 1000, les valeurs par défaut de Camera), (far + near) / (near - far) fait de la division entière en Ruby et explose la matrice (ex: 1001/-999 devient -2 au lieu de -1.002) — tout sort du frustum, écran vide sans erreur GL.
67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/bestguigui/render_3d/mat4.rb', line 67 def self.perspective(fovy_degrees, aspect, near, far) near = near.to_f far = far.to_f f = 1.0 / Math.tan((fovy_degrees * Math::PI / 180.0) / 2.0) new([ f / aspect, 0, 0, 0, 0, f, 0, 0, 0, 0, (far + near) / (near - far), -1.0, 0, 0, (2.0 * far * near) / (near - far), 0 ]) end |
.rotation_x(degrees) ⇒ Object
40 41 42 43 44 45 46 47 48 49 |
# File 'lib/bestguigui/render_3d/mat4.rb', line 40 def self.rotation_x(degrees) r = degrees * Math::PI / 180.0 c, s = Math.cos(r), Math.sin(r) new([ 1.0, 0, 0, 0, 0, c, s, 0, 0, -s, c, 0, 0, 0, 0, 1.0 ]) end |
.rotation_y(degrees) ⇒ Object
51 52 53 54 55 56 57 58 59 60 |
# File 'lib/bestguigui/render_3d/mat4.rb', line 51 def self.rotation_y(degrees) r = degrees * Math::PI / 180.0 c, s = Math.cos(r), Math.sin(r) new([ c, 0, -s, 0, 0, 1.0, 0, 0, s, 0, c, 0, 0, 0, 0, 1.0 ]) end |
.scaling(x, y, z) ⇒ Object
31 32 33 34 35 36 37 38 |
# File 'lib/bestguigui/render_3d/mat4.rb', line 31 def self.scaling(x, y, z) new([ x.to_f, 0, 0, 0, 0, y.to_f, 0, 0, 0, 0, z.to_f, 0, 0, 0, 0, 1.0 ]) end |
.translation(x, y, z) ⇒ Object
22 23 24 25 26 27 28 29 |
# File 'lib/bestguigui/render_3d/mat4.rb', line 22 def self.translation(x, y, z) new([ 1.0, 0, 0, 0, 0, 1.0, 0, 0, 0, 0, 1.0, 0, x.to_f, y.to_f, z.to_f, 1.0 ]) end |
Instance Method Details
#*(other) ⇒ Object
114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/bestguigui/render_3d/mat4.rb', line 114 def *(other) a = @data b = other.data result = Array.new(16, 0.0) 4.times do |col| 4.times do |row| sum = 0.0 4.times { |k| sum += a[(k * 4) + row] * b[(col * 4) + k] } result[(col * 4) + row] = sum end end Mat4.new(result) end |
#to_a ⇒ Object
128 129 130 |
# File 'lib/bestguigui/render_3d/mat4.rb', line 128 def to_a @data end |