Class: CyberarmEngine::Transform

Inherits:
Object
  • Object
show all
Defined in:
lib/cyberarm_engine/transform.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(matrix) ⇒ Transform

Returns a new instance of Transform.



4
5
6
7
8
# File 'lib/cyberarm_engine/transform.rb', line 4

def initialize(matrix)
  @elements = matrix

  raise "Transform is wrong size! Got #{@elements.size}, expected 16" if 16 != @elements.size
end

Instance Attribute Details

#elementsObject (readonly)

Returns the value of attribute elements.



3
4
5
# File 'lib/cyberarm_engine/transform.rb', line 3

def elements
  @elements
end

Class Method Details

.concat(left, right) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/cyberarm_engine/transform.rb', line 69

def self.concat(left, right)
  matrix = Array.new(left.elements.size)
  rows = 4

  matrix.size.times do |i|
    matrix[i] = 0

    rows.times do |j|
      matrix[i] += left.elements[i / rows * rows + j] * right.elements[i % rows + j * rows]
    end
  end

  Transform.new(matrix)
end

.rotate(angle, rotate_around = nil) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/cyberarm_engine/transform.rb', line 10

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,
  ]

  rotate_matrix = Transform.new(matrix, rows: 4, columns: 4)

  if rotate_around && (rotate_around.x != 0.0 || rotate_around.y != 0.0)
    negative_rotate_around = Vector.new(-rotate_around.x, -rotate_around.y, -rotate_around.z)

    rotate_matrix = concat(
      concat(translate(negative_rotate_around), rotate_matrix),
      translate(rotate_around)
    )
  end

  return rotate_matrix
end

.scale(vector, center_around = nil) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/cyberarm_engine/transform.rb', line 46

def self.scale(vector, center_around = nil)
  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,
  ]

  scale_matrix = Transform.new(matrix)

  if center_around && (center_around.x != 0.0 || center_around.y != 0.0)
    negative_center_around = Vector.new(-center_around.x, -center_around.y, -center_around.z)

    scale_matrix = concat(
      concat(translate(negative_center_around), scale_matrix),
      translate(center_around)
    )
  end

  return scale_matrix
end

.translate(vector) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
# File 'lib/cyberarm_engine/transform.rb', line 34

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,
  ]

  Transform.new(matrix)
end