lib/cyberarm_engine/transform.rb in cyberarm_engine-0.14.0 vs lib/cyberarm_engine/transform.rb in cyberarm_engine-0.15.0
- old
+ new
@@ -1,14 +1,15 @@
module CyberarmEngine
# Basic 4x4 matrix operations
class Transform
attr_reader :elements
+
def initialize(matrix)
@elements = matrix
raise "Transform is wrong size! Got #{@elements.size}, expected 16" if 16 != @elements.size
- raise "Invalid value for matrix, must all be numeric!" if @elements.any? { |e| e.nil? || !e.is_a?(Numeric)}
+ raise "Invalid value for matrix, must all be numeric!" if @elements.any? { |e| e.nil? || !e.is_a?(Numeric) }
end
def self.identity
Transform.new(
[
@@ -25,14 +26,14 @@
# 2d rotate operation, replicates Gosu's Gosu.rotate function
def self.rotate(angle, rotate_around = nil)
double c = Math.cos(angle).degrees_to_radians
double s = Math.sin(angle).degrees_to_radians
matrix = [
- +c, +s, 0, 0,
- -s, +c, 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1,
+ +c, +s, 0, 0,
+ -s, +c, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1
]
rotate_matrix = Transform.new(matrix, rows: 4, columns: 4)
if rotate_around && (rotate_around.x != 0.0 || rotate_around.y != 0.0)
@@ -42,21 +43,21 @@
concat(translate(negative_rotate_around), rotate_matrix),
translate(rotate_around)
)
end
- return rotate_matrix
+ rotate_matrix
end
# 2d translate operation, replicates Gosu's Gosu.translate function
def self.translate(vector)
x, y, z = vector.to_a[0..2]
matrix = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
- x, y, z, 1,
+ x, y, z, 1
]
Transform.new(matrix)
end
@@ -65,11 +66,11 @@
scale_x, scale_y, scale_z = vector.to_a[0..2]
matrix = [
scale_x, 0, 0, 0,
0, scale_y, 0, 0,
0, 0, scale_z, 0,
- 0, 0, 0, 1,
+ 0, 0, 0, 1
]
scale_matrix = Transform.new(matrix)
if center_around && (center_around.x != 0.0 || center_around.y != 0.0)
@@ -79,11 +80,11 @@
concat(translate(negative_center_around), scale_matrix),
translate(center_around)
)
end
- return scale_matrix
+ scale_matrix
end
def self.concat(left, right)
matrix = Array.new(left.elements.size)
rows = 4
@@ -105,17 +106,17 @@
x, y, z = vector.to_a[0..2]
matrix = [
1, 0, 0, x,
0, 1, 0, y,
0, 0, 1, z,
- 0, 0, 0, 1,
+ 0, 0, 0, 1
]
Transform.new(matrix)
end
- def self.rotate_3d(vector, order = "zyx")
+ def self.rotate_3d(vector, _order = "zyx")
x, y, z = vector.to_a[0..2].map { |axis| axis * Math::PI / 180.0 }
rotation_x = Transform.new(
[
1, 0, 0, 0,
@@ -161,11 +162,11 @@
Transform.new(
[
x * x * n + c, x * y * n - z * s, x * z * n + y * s, 0,
y * x * n + z * s, y * y * n + c, y * z * n - x * s, 0,
x * z * n - y * s, y * z * n + x * s, z * z * n + c, 0,
- 0, 0, 0, 1.0
+ 0, 0, 0, 1.0
]
)
end
def self.scale_3d(vector)
@@ -188,16 +189,39 @@
Transform.new(
[
f / aspect_ratio, 0.0, 0.0, 0.0,
0.0, f, 0.0, 0.0,
- 0.0, 0.0, zn, zf,
+ 0.0, 0.0, zn, zf,
0.0, 0.0, -1.0, 0.0
]
)
end
+ def self.orthographic(left, right, bottom, top, near, far)
+ s = Vector.new(
+ 2 / (right - left.to_f),
+ 2 / (top - bottom.to_f),
+ -2 / (far - near.to_f)
+ )
+
+ t = Vector.new(
+ (right + left.to_f) / (right - left.to_f),
+ (top + bottom.to_f) / (top - bottom.to_f),
+ (far + near.to_f) / (far - near.to_f)
+ )
+
+ Transform.new(
+ [
+ s.x, 0.0, 0.0, t.x,
+ 0.0, s.y, 0.0, t.y,
+ 0.0, 0.0, s.z, t.z,
+ 0.0, 0.0, 0.0, 1.0
+ ]
+ )
+ end
+
def self.view(eye, orientation)
# https://www.3dgep.com/understanding-the-view-matrix/#The_View_Matrix
cosPitch = Math.cos(orientation.z * Math::PI / 180.0)
sinPitch = Math.sin(orientation.z * Math::PI / 180.0)
cosYaw = Math.cos(orientation.y * Math::PI / 180.0)
@@ -207,20 +231,19 @@
y_axis = Vector.new(sinYaw * sinPitch, cosPitch, cosYaw * sinPitch)
z_axis = Vector.new(sinYaw * cosPitch, -sinPitch, cosPitch * cosYaw)
Transform.new(
[
- x_axis.x, y_axis.y, z_axis.z, 0,
- x_axis.x, y_axis.y, z_axis.z, 0,
- x_axis.x, y_axis.y, z_axis.z, 0,
+ x_axis.x, y_axis.y, z_axis.z, 0,
+ x_axis.x, y_axis.y, z_axis.z, 0,
+ x_axis.x, y_axis.y, z_axis.z, 0,
-x_axis.dot(eye), -y_axis.dot(eye), -z_axis.dot(eye), 1
]
)
end
def *(other)
-
case other
when CyberarmEngine::Vector
matrix = @elements.clone
list = other.to_a
@@ -229,11 +252,11 @@
end
Transform.new(matrix)
when CyberarmEngine::Transform
- return multiply_matrices(other)
+ multiply_matrices(other)
else
p other.class
raise TypeError, "Expected CyberarmEngine::Vector or CyberarmEngine::Transform got #{other.class}"
end
end
@@ -254,11 +277,11 @@
matrix[4 * y + x] += get(x, k) * other.get(k, y)
end
end
end
- return Transform.new(matrix)
+ Transform.new(matrix)
end
# arranges Matrix in column major form
def to_gl
e = @elements
@@ -268,6 +291,6 @@
e[2], e[6], e[10], e[14],
e[3], e[7], e[11], e[15]
]
end
end
-end
\ No newline at end of file
+end