cyberarm_engine 0.13.0 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +8 -8
  3. data/.travis.yml +5 -5
  4. data/Gemfile +6 -6
  5. data/LICENSE.txt +21 -21
  6. data/README.md +73 -43
  7. data/Rakefile +10 -10
  8. data/bin/console +14 -14
  9. data/bin/setup +8 -8
  10. data/cyberarm_engine.gemspec +36 -36
  11. data/lib/cyberarm_engine.rb +49 -47
  12. data/lib/cyberarm_engine/animator.rb +53 -53
  13. data/lib/cyberarm_engine/background.rb +175 -175
  14. data/lib/cyberarm_engine/bounding_box.rb +149 -149
  15. data/lib/cyberarm_engine/common.rb +96 -96
  16. data/lib/cyberarm_engine/config_file.rb +46 -0
  17. data/lib/cyberarm_engine/engine.rb +101 -101
  18. data/lib/cyberarm_engine/game_object.rb +256 -256
  19. data/lib/cyberarm_engine/game_state.rb +88 -88
  20. data/lib/cyberarm_engine/gosu_ext/circle.rb +8 -8
  21. data/lib/cyberarm_engine/ray.rb +55 -55
  22. data/lib/cyberarm_engine/shader.rb +398 -262
  23. data/lib/cyberarm_engine/text.rb +146 -146
  24. data/lib/cyberarm_engine/timer.rb +22 -22
  25. data/lib/cyberarm_engine/transform.rb +272 -272
  26. data/lib/cyberarm_engine/ui/border_canvas.rb +100 -100
  27. data/lib/cyberarm_engine/ui/dsl.rb +98 -98
  28. data/lib/cyberarm_engine/ui/element.rb +275 -275
  29. data/lib/cyberarm_engine/ui/elements/button.rb +66 -66
  30. data/lib/cyberarm_engine/ui/elements/check_box.rb +58 -58
  31. data/lib/cyberarm_engine/ui/elements/container.rb +176 -176
  32. data/lib/cyberarm_engine/ui/elements/edit_line.rb +171 -171
  33. data/lib/cyberarm_engine/ui/elements/flow.rb +16 -16
  34. data/lib/cyberarm_engine/ui/elements/image.rb +51 -51
  35. data/lib/cyberarm_engine/ui/elements/label.rb +49 -49
  36. data/lib/cyberarm_engine/ui/elements/progress.rb +49 -49
  37. data/lib/cyberarm_engine/ui/elements/stack.rb +12 -12
  38. data/lib/cyberarm_engine/ui/elements/toggle_button.rb +55 -55
  39. data/lib/cyberarm_engine/ui/event.rb +46 -46
  40. data/lib/cyberarm_engine/ui/gui_state.rb +134 -134
  41. data/lib/cyberarm_engine/ui/style.rb +36 -36
  42. data/lib/cyberarm_engine/ui/theme.rb +120 -120
  43. data/lib/cyberarm_engine/vector.rb +289 -202
  44. data/lib/cyberarm_engine/version.rb +4 -4
  45. metadata +3 -2
@@ -1,37 +1,37 @@
1
- module Gosu
2
- class Color
3
- def _dump(level)
4
- [
5
- "%02X" % self.alpha,
6
- "%02X" % self.red,
7
- "%02X" % self.green,
8
- "%02X" % self.blue
9
- ].join
10
- end
11
-
12
- def self._load(hex)
13
- argb(hex.to_i(16))
14
- end
15
- end
16
- end
17
-
18
- module CyberarmEngine
19
- class Style
20
- def initialize(hash = {})
21
- @hash = Marshal.load(Marshal.dump(hash))
22
- end
23
-
24
- def method_missing(method, *args, &block)
25
- if method.to_s.end_with?("=")
26
- raise "Did not expect more than 1 argument" if args.size > 1
27
- return @hash[method.to_s.sub("=", "").to_sym] = args.first
28
-
29
- elsif args.size == 0
30
- return @hash[method]
31
-
32
- else
33
- raise ArgumentError, "Did not expect arguments"
34
- end
35
- end
36
- end
1
+ module Gosu
2
+ class Color
3
+ def _dump(level)
4
+ [
5
+ "%02X" % self.alpha,
6
+ "%02X" % self.red,
7
+ "%02X" % self.green,
8
+ "%02X" % self.blue
9
+ ].join
10
+ end
11
+
12
+ def self._load(hex)
13
+ argb(hex.to_i(16))
14
+ end
15
+ end
16
+ end
17
+
18
+ module CyberarmEngine
19
+ class Style
20
+ def initialize(hash = {})
21
+ @hash = Marshal.load(Marshal.dump(hash))
22
+ end
23
+
24
+ def method_missing(method, *args, &block)
25
+ if method.to_s.end_with?("=")
26
+ raise "Did not expect more than 1 argument" if args.size > 1
27
+ return @hash[method.to_s.sub("=", "").to_sym] = args.first
28
+
29
+ elsif args.size == 0
30
+ return @hash[method]
31
+
32
+ else
33
+ raise ArgumentError, "Did not expect arguments"
34
+ end
35
+ end
36
+ end
37
37
  end
@@ -1,120 +1,120 @@
1
- module CyberarmEngine
2
- module Theme
3
- def default(*args)
4
- value = @options
5
- args.each do |arg|
6
- value = value.dig(arg)
7
- end
8
-
9
- value
10
- end
11
-
12
- def theme_defaults(options)
13
- raise "Error" unless self.class.ancestors.include?(CyberarmEngine::Element)
14
- _theme = THEME
15
- _theme = _theme.merge(options[:theme]) if options[:theme]
16
- _theme.delete(:theme) if options[:theme]
17
-
18
- hash = {}
19
- class_names = self.class.ancestors
20
- class_names = class_names[0..class_names.index(CyberarmEngine::Element)].map! {|c| c.to_s.split("::").last.to_sym}.reverse!
21
-
22
- class_names.each do |klass|
23
- next unless data = _theme.dig(klass)
24
- data.each do |key, value|
25
- hash.merge!(data)
26
- end
27
- end
28
-
29
- deep_merge(hash, options)
30
- end
31
-
32
- # Derived from Rails Hash#deep_merge!
33
- # Enables passing partial themes through Element options without issue
34
- def deep_merge(original, intergrate, &block)
35
- hash = original.merge(intergrate) do |key, this_val, other_val|
36
- if this_val.is_a?(Hash) && other_val.is_a?(Hash)
37
- deep_merge(this_val, other_val, &block)
38
- elsif block_given?
39
- block.call(key, this_val, other_val)
40
- else
41
- other_val
42
- end
43
- end
44
-
45
- return hash
46
- end
47
-
48
- THEME = {
49
- Element: {
50
- x: 0,
51
- y: 0,
52
- z: 30,
53
-
54
- width: nil,
55
- height: nil,
56
- color: Gosu::Color::WHITE,
57
- background: Gosu::Color::NONE,
58
- margin: 0,
59
- padding: 0,
60
- border_thickness: 0,
61
- border_color: Gosu::Color::NONE,
62
- border_radius: 0,
63
- },
64
-
65
- Button: { # < Label
66
- margin: 1,
67
- padding: 4,
68
- border_thickness: 1,
69
- border_color: ["ffd59674".hex, "ffff8746".hex],
70
- border_radius: 0,
71
- background: ["ffc75e61".to_i(16), "ffe26623".to_i(16)],
72
-
73
- hover: {
74
- color: Gosu::Color.rgb(200,200,200),
75
- background: ["ffB23E41".to_i(16), "ffFF7C00".to_i(16)],
76
- },
77
-
78
- active: {
79
- color: Gosu::Color::BLACK,
80
- background: ["ffB23E41".to_i(16)]
81
- }
82
- },
83
-
84
- EditLine: { # < Button
85
- type: :text,
86
- width: 200,
87
- password_character: "•",
88
- caret_width: 2,
89
- caret_color: Gosu::Color::WHITE,
90
- caret_interval: 500,
91
- selection_color: Gosu::Color::GREEN,
92
- },
93
-
94
- Image: { # < Element
95
- retro: false
96
- },
97
-
98
- Label: { # < Element
99
- text_size: 28,
100
- text_shadow: false,
101
- font: "Arial",
102
- margin: 0,
103
- padding: 2
104
- },
105
-
106
- ToggleButton: { # < Button
107
- checkmark: "√"
108
- },
109
-
110
- Progress: { # < Element
111
- width: 250,
112
- height: 36,
113
- background: 0xff111111,
114
- fraction_background: [0xffc75e61, 0xffe26623],
115
- border_thickness: 1,
116
- border_color: [0xffd59674, 0xffff8746]
117
- }
118
- }.freeze
119
- end
120
- end
1
+ module CyberarmEngine
2
+ module Theme
3
+ def default(*args)
4
+ value = @options
5
+ args.each do |arg|
6
+ value = value.dig(arg)
7
+ end
8
+
9
+ value
10
+ end
11
+
12
+ def theme_defaults(options)
13
+ raise "Error" unless self.class.ancestors.include?(CyberarmEngine::Element)
14
+ _theme = THEME
15
+ _theme = _theme.merge(options[:theme]) if options[:theme]
16
+ _theme.delete(:theme) if options[:theme]
17
+
18
+ hash = {}
19
+ class_names = self.class.ancestors
20
+ class_names = class_names[0..class_names.index(CyberarmEngine::Element)].map! {|c| c.to_s.split("::").last.to_sym}.reverse!
21
+
22
+ class_names.each do |klass|
23
+ next unless data = _theme.dig(klass)
24
+ data.each do |key, value|
25
+ hash.merge!(data)
26
+ end
27
+ end
28
+
29
+ deep_merge(hash, options)
30
+ end
31
+
32
+ # Derived from Rails Hash#deep_merge!
33
+ # Enables passing partial themes through Element options without issue
34
+ def deep_merge(original, intergrate, &block)
35
+ hash = original.merge(intergrate) do |key, this_val, other_val|
36
+ if this_val.is_a?(Hash) && other_val.is_a?(Hash)
37
+ deep_merge(this_val, other_val, &block)
38
+ elsif block_given?
39
+ block.call(key, this_val, other_val)
40
+ else
41
+ other_val
42
+ end
43
+ end
44
+
45
+ return hash
46
+ end
47
+
48
+ THEME = {
49
+ Element: {
50
+ x: 0,
51
+ y: 0,
52
+ z: 30,
53
+
54
+ width: nil,
55
+ height: nil,
56
+ color: Gosu::Color::WHITE,
57
+ background: Gosu::Color::NONE,
58
+ margin: 0,
59
+ padding: 0,
60
+ border_thickness: 0,
61
+ border_color: Gosu::Color::NONE,
62
+ border_radius: 0,
63
+ },
64
+
65
+ Button: { # < Label
66
+ margin: 1,
67
+ padding: 4,
68
+ border_thickness: 1,
69
+ border_color: ["ffd59674".hex, "ffff8746".hex],
70
+ border_radius: 0,
71
+ background: ["ffc75e61".to_i(16), "ffe26623".to_i(16)],
72
+
73
+ hover: {
74
+ color: Gosu::Color.rgb(200,200,200),
75
+ background: ["ffB23E41".to_i(16), "ffFF7C00".to_i(16)],
76
+ },
77
+
78
+ active: {
79
+ color: Gosu::Color::BLACK,
80
+ background: ["ffB23E41".to_i(16)]
81
+ }
82
+ },
83
+
84
+ EditLine: { # < Button
85
+ type: :text,
86
+ width: 200,
87
+ password_character: "•",
88
+ caret_width: 2,
89
+ caret_color: Gosu::Color::WHITE,
90
+ caret_interval: 500,
91
+ selection_color: Gosu::Color::GREEN,
92
+ },
93
+
94
+ Image: { # < Element
95
+ retro: false
96
+ },
97
+
98
+ Label: { # < Element
99
+ text_size: 28,
100
+ text_shadow: false,
101
+ font: "Arial",
102
+ margin: 0,
103
+ padding: 2
104
+ },
105
+
106
+ ToggleButton: { # < Button
107
+ checkmark: "√"
108
+ },
109
+
110
+ Progress: { # < Element
111
+ width: 250,
112
+ height: 36,
113
+ background: 0xff111111,
114
+ fraction_background: [0xffc75e61, 0xffe26623],
115
+ border_thickness: 1,
116
+ border_color: [0xffd59674, 0xffff8746]
117
+ }
118
+ }.freeze
119
+ end
120
+ end
@@ -1,203 +1,290 @@
1
- module CyberarmEngine
2
- class Vector
3
- def self.up
4
- Vector.new(0, 1, 0)
5
- end
6
-
7
- def self.down
8
- Vector.new(0, -1, 0)
9
- end
10
-
11
- def self.left
12
- Vector.new(-1, 0, 0)
13
- end
14
-
15
- def self.right
16
- Vector.new(1, 0, 0)
17
- end
18
-
19
- def self.forward
20
- Vector.new(0, 0, 1)
21
- end
22
-
23
- def self.backward
24
- Vector.new(0, 0, -1)
25
- end
26
-
27
- def initialize(x = 0, y = 0, z = 0, weight = 0)
28
- @x, @y, @z, @weight = x, y, z, weight
29
- end
30
-
31
- def x; @x; end
32
- def x=(n); @x = n; end
33
-
34
- def y; @y; end
35
- def y=(n); @y = n; end
36
-
37
- def z; @z; end
38
- def z=(n); @z = n; end
39
-
40
- def weight; @weight; end
41
- def weight=(n); @weight = n; end
42
-
43
- alias w weight
44
- alias w= weight=
45
-
46
- def ==(other)
47
- if other.is_a?(Numeric)
48
- @x == other &&
49
- @y == other &&
50
- @z == other &&
51
- @weight == other
52
- else
53
- @x == other.x &&
54
- @y == other.y &&
55
- @z == other.z &&
56
- @weight == other.weight
57
- end
58
- end
59
-
60
- def xy
61
- Vector.new(@x, @y)
62
- end
63
-
64
- # Performs math operation, excluding @weight
65
- private def operator(function, other)
66
- if other.is_a?(Numeric)
67
- Vector.new(
68
- @x.send(:"#{function}", other),
69
- @y.send(:"#{function}", other),
70
- @z.send(:"#{function}", other)
71
- )
72
- else
73
- Vector.new(
74
- @x.send(:"#{function}", other.x),
75
- @y.send(:"#{function}", other.y),
76
- @z.send(:"#{function}", other.z)
77
- )
78
- end
79
- end
80
-
81
- # Adds Vector and Numberic or Vector and Vector, excluding @weight
82
- def +(other)
83
- operator("+", other)
84
- end
85
-
86
- # Subtracts Vector and Numberic or Vector and Vector, excluding @weight
87
- def -(other)
88
- operator("-", other)
89
- end
90
-
91
- # Multiplies Vector and Numberic or Vector and Vector, excluding @weight
92
- def *(other)
93
- operator("*", other)
94
- end
95
-
96
- # Divides Vector and Numberic or Vector and Vector, excluding @weight
97
- def /(other)
98
- # Duplicated to protect from DivideByZero
99
- if other.is_a?(Numeric)
100
- Vector.new(
101
- (@x == 0 ? 0 : @x / other),
102
- (@y == 0 ? 0 : @y / other),
103
- (@z == 0 ? 0 : @z / other)
104
- )
105
- else
106
- Vector.new(
107
- (@x == 0 ? 0 : @x / other.x),
108
- (@y == 0 ? 0 : @y / other.y),
109
- (@z == 0 ? 0 : @z / other.z)
110
- )
111
- end
112
- end
113
-
114
- def dot(other)
115
- product = 0
116
-
117
- a = self.to_a
118
- b = other.to_a
119
-
120
- 3.times do |i|
121
- product = product + (a[i] * b[i])
122
- end
123
-
124
- return product
125
- end
126
-
127
- def cross(other)
128
- a = self.to_a
129
- b = other.to_a
130
-
131
- Vector.new(
132
- b[2] * a[1] - b[1] * a[2],
133
- b[0] * a[2] - b[2] * a[0],
134
- b[1] * a[0] - b[0] * a[1]
135
- )
136
- end
137
-
138
- # returns degrees
139
- def angle(other)
140
- Math.acos( self.normalized.dot(other.normalized) ) * 180 / Math::PI
141
- end
142
-
143
- # returns magnitude of Vector, ignoring #weight
144
- def magnitude
145
- Math.sqrt((@x * @x) + (@y * @y) + (@z * @z))
146
- end
147
-
148
- def normalized
149
- mag = magnitude
150
- self / Vector.new(mag, mag, mag)
151
- end
152
-
153
- def direction
154
- # z is pitch
155
- # y is yaw
156
- # x is roll
157
- _x = -Math.sin(@y.degrees_to_radians) * Math.cos(@z.degrees_to_radians)
158
- _y = Math.sin(@z.degrees_to_radians)
159
- _z = Math.cos(@y.degrees_to_radians) * Math.cos(@z.degrees_to_radians)
160
-
161
- Vector.new(_x, _y, _z)
162
- end
163
-
164
- def inverse
165
- Vector.new(1.0 / @x, 1.0 / @y, 1.0 / @z)
166
- end
167
-
168
- def sum
169
- @x + @y + @z
170
- end
171
-
172
- def lerp(other, factor)
173
- (self - other) * factor.clamp(0.0, 1.0)
174
- end
175
-
176
- # 2D distance using X and Y
177
- def distance(other)
178
- Math.sqrt((@x-other.x)**2 + (@y-other.y)**2)
179
- end
180
-
181
- # 2D distance using X and Z
182
- def gl_distance2d(other)
183
- Math.sqrt((@x-other.x)**2 + (@z-other.z)**2)
184
- end
185
-
186
- # 3D distance using X, Y, and Z
187
- def distance3d(other)
188
- Math.sqrt((@x-other.x)**2 + (@y-other.y)**2 + (@z-other.z)**2)
189
- end
190
-
191
- def to_a
192
- [@x, @y, @z, @weight]
193
- end
194
-
195
- def to_s
196
- "X: #{@x}, Y: #{@y}, Z: #{@z}, Weight: #{@weight}"
197
- end
198
-
199
- def to_h
200
- {x: @x, y: @y, z: @z, weight: @weight}
201
- end
202
- end
1
+ module CyberarmEngine
2
+ class Vector
3
+ ##
4
+ # Creates a up vector
5
+ #
6
+ # Vector.new(0, 1, 0)
7
+ #
8
+ # @return [CyberarmEngine::Vector]
9
+ def self.up
10
+ Vector.new(0, 1, 0)
11
+ end
12
+
13
+ ##
14
+ # Creates a down vector
15
+ #
16
+ # Vector.new(0, -1, 0)
17
+ #
18
+ # @return [CyberarmEngine::Vector]
19
+ def self.down
20
+ Vector.new(0, -1, 0)
21
+ end
22
+
23
+ ##
24
+ # Creates a left vector
25
+ #
26
+ # Vector.new(-1, 0, 0)
27
+ #
28
+ # @return [CyberarmEngine::Vector]
29
+ def self.left
30
+ Vector.new(-1, 0, 0)
31
+ end
32
+
33
+ ##
34
+ # Creates a right vector
35
+ #
36
+ # Vector.new(1, 0, 0)
37
+ #
38
+ # @return [CyberarmEngine::Vector]
39
+ def self.right
40
+ Vector.new(1, 0, 0)
41
+ end
42
+
43
+ ##
44
+ # Creates a forward vector
45
+ #
46
+ # Vector.new(0, 0, 1)
47
+ #
48
+ # @return [CyberarmEngine::Vector]
49
+ def self.forward
50
+ Vector.new(0, 0, 1)
51
+ end
52
+
53
+ ##
54
+ # Creates a backward vector
55
+ #
56
+ # Vector.new(0, 0, -1)
57
+ #
58
+ # @return [CyberarmEngine::Vector]
59
+ def self.backward
60
+ Vector.new(0, 0, -1)
61
+ end
62
+
63
+ def initialize(x = 0, y = 0, z = 0, weight = 0)
64
+ @x, @y, @z, @weight = x, y, z, weight
65
+ end
66
+
67
+ def x; @x; end
68
+ def x=(n); @x = n; end
69
+
70
+ def y; @y; end
71
+ def y=(n); @y = n; end
72
+
73
+ def z; @z; end
74
+ def z=(n); @z = n; end
75
+
76
+ def weight; @weight; end
77
+ def weight=(n); @weight = n; end
78
+
79
+ alias w weight
80
+ alias w= weight=
81
+
82
+ # @return [Boolean]
83
+ def ==(other)
84
+ if other.is_a?(Numeric)
85
+ @x == other &&
86
+ @y == other &&
87
+ @z == other &&
88
+ @weight == other
89
+ elsif other.is_a?(Vector)
90
+ @x == other.x &&
91
+ @y == other.y &&
92
+ @z == other.z &&
93
+ @weight == other.weight
94
+ else
95
+ other == self
96
+ end
97
+ end
98
+
99
+ # Create a new vector using {x} and {y} values
100
+ # @return [CyberarmEngine::Vector]
101
+ def xy
102
+ Vector.new(@x, @y)
103
+ end
104
+
105
+ # Performs math operation, excluding {weight}
106
+ private def operator(function, other)
107
+ if other.is_a?(Numeric)
108
+ Vector.new(
109
+ @x.send(:"#{function}", other),
110
+ @y.send(:"#{function}", other),
111
+ @z.send(:"#{function}", other)
112
+ )
113
+ else
114
+ Vector.new(
115
+ @x.send(:"#{function}", other.x),
116
+ @y.send(:"#{function}", other.y),
117
+ @z.send(:"#{function}", other.z)
118
+ )
119
+ end
120
+ end
121
+
122
+ # Adds Vector and Numeric or Vector and Vector, excluding {weight}
123
+ # @return [CyberarmEngine::Vector]
124
+ def +(other)
125
+ operator("+", other)
126
+ end
127
+
128
+ # Subtracts Vector and Numeric or Vector and Vector, excluding {weight}
129
+ # @return [CyberarmEngine::Vector]
130
+ def -(other)
131
+ operator("-", other)
132
+ end
133
+
134
+ # Multiplies Vector and Numeric or Vector and Vector, excluding {weight}
135
+ # @return [CyberarmEngine::Vector]
136
+ def *(other)
137
+ operator("*", other)
138
+ end
139
+
140
+ # Divides Vector and Numeric or Vector and Vector, excluding {weight}
141
+ # @return [CyberarmEngine::Vector]
142
+ def /(other)
143
+ # Duplicated to protect from DivideByZero
144
+ if other.is_a?(Numeric)
145
+ Vector.new(
146
+ (@x == 0 ? 0 : @x / other),
147
+ (@y == 0 ? 0 : @y / other),
148
+ (@z == 0 ? 0 : @z / other)
149
+ )
150
+ else
151
+ Vector.new(
152
+ (@x == 0 ? 0 : @x / other.x),
153
+ (@y == 0 ? 0 : @y / other.y),
154
+ (@z == 0 ? 0 : @z / other.z)
155
+ )
156
+ end
157
+ end
158
+
159
+ # dot product of {Vector}
160
+ # @return [Integer|Float]
161
+ def dot(other)
162
+ product = 0
163
+
164
+ a = self.to_a
165
+ b = other.to_a
166
+
167
+ 3.times do |i|
168
+ product = product + (a[i] * b[i])
169
+ end
170
+
171
+ return product
172
+ end
173
+
174
+ # cross product of {Vector}
175
+ # @return [CyberarmEngine::Vector]
176
+ def cross(other)
177
+ a = self.to_a
178
+ b = other.to_a
179
+
180
+ Vector.new(
181
+ b[2] * a[1] - b[1] * a[2],
182
+ b[0] * a[2] - b[2] * a[0],
183
+ b[1] * a[0] - b[0] * a[1]
184
+ )
185
+ end
186
+
187
+ # returns degrees
188
+ # @return [Float]
189
+ def angle(other)
190
+ Math.acos( self.normalized.dot(other.normalized) ) * 180 / Math::PI
191
+ end
192
+
193
+ # returns magnitude of Vector, ignoring #weight
194
+ # @return [Float]
195
+ def magnitude
196
+ Math.sqrt((@x * @x) + (@y * @y) + (@z * @z))
197
+ end
198
+
199
+ ##
200
+ # returns normalized {Vector}
201
+ #
202
+ # @example
203
+ # CyberarmEngine::Vector.new(50, 21.2, 45).normalized
204
+ # # => <CyberarmEngine::Vector:0x001 @x=0.7089... @y=0.3005... @z=0.6380... @weight=0>
205
+ #
206
+ # @return [CyberarmEngine::Vector]
207
+ def normalized
208
+ mag = magnitude
209
+ self / Vector.new(mag, mag, mag)
210
+ end
211
+
212
+
213
+ # returns a direction {Vector}
214
+ #
215
+ # z is pitch
216
+ #
217
+ # y is yaw
218
+ #
219
+ # x is roll
220
+ # @return [CyberarmEngine::Vector]
221
+ def direction
222
+ _x = -Math.sin(@y.degrees_to_radians) * Math.cos(@z.degrees_to_radians)
223
+ _y = Math.sin(@z.degrees_to_radians)
224
+ _z = Math.cos(@y.degrees_to_radians) * Math.cos(@z.degrees_to_radians)
225
+
226
+ Vector.new(_x, _y, _z)
227
+ end
228
+
229
+ # returns an inverse {Vector}
230
+ # @return [CyberarmEngine::Vector]
231
+ def inverse
232
+ Vector.new(1.0 / @x, 1.0 / @y, 1.0 / @z)
233
+ end
234
+
235
+ # Adds up values of {x}, {y}, and {z}
236
+ # @return [Integer|Float]
237
+ def sum
238
+ @x + @y + @z
239
+ end
240
+
241
+ ##
242
+ # Linear interpolation: smoothly transition between two {Vector}
243
+ #
244
+ # CyberarmEngine::Vector.new(100, 100, 100).lerp( CyberarmEngine::Vector.new(0, 0, 0), 0.75 )
245
+ # # => <CyberarmEngine::Vector:0x0001 @x=75.0, @y=75.0, @z=75.0, @weight=0>
246
+ #
247
+ # @param other [CyberarmEngine::Vector | Integer | Float] value to subtract from
248
+ # @param factor [Float] how complete transition to _other_ is, in range [0.0..1.0]
249
+ # @return [CyberarmEngine::Vector]
250
+ def lerp(other, factor)
251
+ (self - other) * factor.clamp(0.0, 1.0)
252
+ end
253
+
254
+ # 2D distance using X and Y
255
+ # @return [Float]
256
+ def distance(other)
257
+ Math.sqrt((@x-other.x)**2 + (@y-other.y)**2)
258
+ end
259
+
260
+ # 2D distance using X and Z
261
+ # @return [Float]
262
+ def gl_distance2d(other)
263
+ Math.sqrt((@x-other.x)**2 + (@z-other.z)**2)
264
+ end
265
+
266
+ # 3D distance using X, Y, and Z
267
+ # @return [Float]
268
+ def distance3d(other)
269
+ Math.sqrt((@x-other.x)**2 + (@y-other.y)**2 + (@z-other.z)**2)
270
+ end
271
+
272
+ # Converts {Vector} to Array
273
+ # @return [Array]
274
+ def to_a
275
+ [@x, @y, @z, @weight]
276
+ end
277
+
278
+ # Converts {Vector} to String
279
+ # @return [String]
280
+ def to_s
281
+ "X: #{@x}, Y: #{@y}, Z: #{@z}, Weight: #{@weight}"
282
+ end
283
+
284
+ # Converts {Vector} to Hash
285
+ # @return [Hash]
286
+ def to_h
287
+ {x: @x, y: @y, z: @z, weight: @weight}
288
+ end
289
+ end
203
290
  end