Module: Collada::Transforms

Defined in:
lib/collada/transforms.rb

Constant Summary collapse

R2D =
(180.0 / Math::PI)
D2R =
(Math::PI / 180.0)

Class Method Summary collapse

Class Method Details

.extract_axis(matrix) ⇒ Object



111
112
113
114
# File 'lib/collada/transforms.rb', line 111

def self.extract_axis(matrix)
  # Transform [x, y, z], Rotation [x, y, z, w]
  [matrix[0, 3], matrix[1, 3], matrix[2, 3], *rotation_matrix_to_quaternion(matrix)]
end

.for(transforms) ⇒ Object



101
102
103
104
105
106
107
108
109
# File 'lib/collada/transforms.rb', line 101

def self.for(transforms)
  product = Matrix.identity(4)
  
  transforms.each do |(name, arguments)|
    product = product * self.send(name, *arguments)
  end
  
  return product
end

.matrix(*arguments) ⇒ Object



97
98
99
# File 'lib/collada/transforms.rb', line 97

def self.matrix(*arguments)
  Matrix[*(arguments.each_slice(4).to_a)]
end

.rotate(x, y, z, angle) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
# File 'lib/collada/transforms.rb', line 76

def self.rotate(x, y, z, angle)
  c = Math::cos(angle*D2R)
  s = Math::sin(angle*D2R)
  
  Matrix[
    [x*x*(1-c) + c, x*y*(1-c) - z*s, x*z*(1-c) + y*s, 0],
    [x*y*(1-c) + z*s, y*y*(1-c) + c, y*z*(1-c) - x*s, 0],
    [x*z*(1-c) - y*s, y*z*(1-c) + x*s, z*z*(1-c) + c, 0],
    [0, 0, 0, 1],
  ]
end

.rotation_matrix_to_quaternion(a) ⇒ Object

In x, y, z, w format.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/collada/transforms.rb', line 29

def self.rotation_matrix_to_quaternion(a)
  t = a[0, 0] + a[1, 1] + a[2, 2]
  
  if (t > 0)
    s = Math::sqrt(t + 1.0) * 2.0
    Vector[
      (a[2, 1] - a[1, 2]) / s,
      (a[0, 2] - a[2, 0]) / s,
      (a[1, 0] - a[0, 1]) / s,
      0.25 * s,
    ]
  elsif a[0, 0] > a[1, 1] and a[0, 0] > a[2, 2]
    s = 2.0 * Math::sqrt(1.0 + a[0, 0] - a[1, 1] - a[2, 2])
    Vector[
      0.25 * s,
      (a[0, 1] + a[1, 0]) / s,
      (a[0, 2] + a[2, 0]) / s,
      (a[2, 1] - a[1, 2] ) / s,
    ]
  elsif a[1, 1] > a[2, 2]
    s = 2.0 * Math::sqrt(1.0 + a[1, 1] - a[0, 0] - a[2, 2])
    Vector[
      (a[0, 1] + a[1, 0]) / s,
      0.25 * s,
      (a[1, 2] + a[2, 1]) / s,
      (a[0, 2] - a[2, 0]) / s,
    ]
  else
    s = 2.0 * Math::sqrt(1.0 + a[2, 2] - a[0, 0] - a[1, 1])
    Vector[
      (a[0, 2] + a[2, 0]) / s,
      (a[1, 2] + a[2, 1]) / s,
      0.25 * s,
      (a[1, 0] - a[0, 1]) / s,
    ]
  end
end

.scale(x, y, z) ⇒ Object



67
68
69
70
71
72
73
74
# File 'lib/collada/transforms.rb', line 67

def self.scale(x, y, z)
  Matrix[
    [x, 0, 0, 0],
    [0, y, 0, 0],
    [0, 0, z, 0],
    [0, 0, 0, 1],
  ]
end

.translate(x, y, z) ⇒ Object



88
89
90
91
92
93
94
95
# File 'lib/collada/transforms.rb', line 88

def self.translate(x, y, z)
  Matrix[
    [1, 0, 0, x],
    [0, 1, 0, y],
    [0, 0, 1, z],
    [0, 0, 0, 1],
  ]
end