larb 0.1.0 → 1.0.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +14 -1
- data/ext/larb/color.c +446 -0
- data/ext/larb/color.h +35 -0
- data/ext/larb/extconf.rb +11 -0
- data/ext/larb/larb.c +27 -0
- data/ext/larb/larb.h +8 -0
- data/ext/larb/mat2.c +300 -0
- data/ext/larb/mat2.h +30 -0
- data/ext/larb/mat2d.c +380 -0
- data/ext/larb/mat2d.h +35 -0
- data/ext/larb/mat3.c +469 -0
- data/ext/larb/mat3.h +33 -0
- data/ext/larb/mat4.c +671 -0
- data/ext/larb/mat4.h +31 -0
- data/ext/larb/quat.c +523 -0
- data/ext/larb/quat.h +39 -0
- data/ext/larb/quat2.c +473 -0
- data/ext/larb/quat2.h +39 -0
- data/ext/larb/vec2.c +342 -0
- data/ext/larb/vec2.h +43 -0
- data/ext/larb/vec3.c +503 -0
- data/ext/larb/vec3.h +52 -0
- data/ext/larb/vec4.c +340 -0
- data/ext/larb/vec4.h +38 -0
- data/lib/larb/version.rb +5 -0
- data/lib/larb.rb +2 -14
- data/test/larb/color_test.rb +278 -0
- data/test/larb/mat2_test.rb +144 -0
- data/test/larb/mat2d_test.rb +172 -0
- data/test/larb/mat3_test.rb +147 -0
- data/test/larb/mat4_test.rb +270 -0
- data/test/larb/quat2_test.rb +161 -0
- data/test/larb/quat_test.rb +224 -0
- data/test/larb/vec2_test.rb +251 -0
- data/test/larb/vec3_test.rb +310 -0
- data/test/larb/vec4_test.rb +189 -0
- data/test/test_helper.rb +4 -0
- metadata +53 -14
- data/Rakefile +0 -11
- data/lib/larb/color.rb +0 -148
- data/lib/larb/mat2.rb +0 -119
- data/lib/larb/mat2d.rb +0 -180
- data/lib/larb/mat3.rb +0 -238
- data/lib/larb/mat4.rb +0 -329
- data/lib/larb/quat.rb +0 -238
- data/lib/larb/quat2.rb +0 -193
- data/lib/larb/vec2.rb +0 -150
- data/lib/larb/vec3.rb +0 -218
- data/lib/larb/vec4.rb +0 -125
data/lib/larb/quat2.rb
DELETED
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Larb
|
|
4
|
-
# Dual Quaternion for rigid body transformations
|
|
5
|
-
# Represented as 8 values: [real quaternion (4), dual quaternion (4)]
|
|
6
|
-
# real: rotation, dual: translation encoded
|
|
7
|
-
class Quat2
|
|
8
|
-
attr_reader :data
|
|
9
|
-
|
|
10
|
-
def initialize(data = nil)
|
|
11
|
-
@data = data || [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0]
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def self.identity
|
|
15
|
-
new
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def self.from_rotation_translation(rotation, translation)
|
|
19
|
-
rx, ry, rz, rw = rotation.x, rotation.y, rotation.z, rotation.w
|
|
20
|
-
tx, ty, tz = translation.x, translation.y, translation.z
|
|
21
|
-
|
|
22
|
-
new([
|
|
23
|
-
rx, ry, rz, rw,
|
|
24
|
-
(tx * rw + ty * rz - tz * ry) * 0.5,
|
|
25
|
-
(ty * rw + tz * rx - tx * rz) * 0.5,
|
|
26
|
-
(tz * rw + tx * ry - ty * rx) * 0.5,
|
|
27
|
-
(-tx * rx - ty * ry - tz * rz) * 0.5
|
|
28
|
-
])
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def self.from_translation(translation)
|
|
32
|
-
from_rotation_translation(Quat.identity, translation)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def self.from_rotation(rotation)
|
|
36
|
-
new([rotation.x, rotation.y, rotation.z, rotation.w, 0, 0, 0, 0])
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def self.from_mat4(m)
|
|
40
|
-
rotation = m.extract_rotation
|
|
41
|
-
translation = m.extract_translation
|
|
42
|
-
from_rotation_translation(rotation, translation)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def real
|
|
46
|
-
Quat.new(@data[0], @data[1], @data[2], @data[3])
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def dual
|
|
50
|
-
Quat.new(@data[4], @data[5], @data[6], @data[7])
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def [](i)
|
|
54
|
-
@data[i]
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def []=(i, v)
|
|
58
|
-
@data[i] = v.to_f
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def *(other)
|
|
62
|
-
case other
|
|
63
|
-
when Quat2
|
|
64
|
-
ax0, ay0, az0, aw0 = @data[0], @data[1], @data[2], @data[3]
|
|
65
|
-
bx1, by1, bz1, bw1 = @data[4], @data[5], @data[6], @data[7]
|
|
66
|
-
ax1, ay1, az1, aw1 = other.data[0], other.data[1], other.data[2], other.data[3]
|
|
67
|
-
bx0, by0, bz0, bw0 = other.data[4], other.data[5], other.data[6], other.data[7]
|
|
68
|
-
|
|
69
|
-
Quat2.new([
|
|
70
|
-
ax0 * aw1 + aw0 * ax1 + ay0 * az1 - az0 * ay1,
|
|
71
|
-
ay0 * aw1 + aw0 * ay1 + az0 * ax1 - ax0 * az1,
|
|
72
|
-
az0 * aw1 + aw0 * az1 + ax0 * ay1 - ay0 * ax1,
|
|
73
|
-
aw0 * aw1 - ax0 * ax1 - ay0 * ay1 - az0 * az1,
|
|
74
|
-
ax0 * bw0 + aw0 * bx0 + ay0 * bz0 - az0 * by0 +
|
|
75
|
-
bx1 * aw1 + bw1 * ax1 + by1 * az1 - bz1 * ay1,
|
|
76
|
-
ay0 * bw0 + aw0 * by0 + az0 * bx0 - ax0 * bz0 +
|
|
77
|
-
by1 * aw1 + bw1 * ay1 + bz1 * ax1 - bx1 * az1,
|
|
78
|
-
az0 * bw0 + aw0 * bz0 + ax0 * by0 - ay0 * bx0 +
|
|
79
|
-
bz1 * aw1 + bw1 * az1 + bx1 * ay1 - by1 * ax1,
|
|
80
|
-
aw0 * bw0 - ax0 * bx0 - ay0 * by0 - az0 * bz0 +
|
|
81
|
-
bw1 * aw1 - bx1 * ax1 - by1 * ay1 - bz1 * az1
|
|
82
|
-
])
|
|
83
|
-
when Vec3
|
|
84
|
-
transform_point(other)
|
|
85
|
-
when Numeric
|
|
86
|
-
Quat2.new(@data.map { |v| v * other })
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def +(other)
|
|
91
|
-
Quat2.new(@data.zip(other.data).map { |a, b| a + b })
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def -(other)
|
|
95
|
-
Quat2.new(@data.zip(other.data).map { |a, b| a - b })
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def dot(other)
|
|
99
|
-
@data[0] * other.data[0] + @data[1] * other.data[1] +
|
|
100
|
-
@data[2] * other.data[2] + @data[3] * other.data[3]
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def length
|
|
104
|
-
Math.sqrt(length_squared)
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def length_squared
|
|
108
|
-
@data[0..3].sum { |v| v * v }
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
def normalize
|
|
112
|
-
len = length
|
|
113
|
-
return Quat2.new(@data.dup) if len < 1e-10
|
|
114
|
-
|
|
115
|
-
inv_len = 1.0 / len
|
|
116
|
-
Quat2.new(@data.map { |v| v * inv_len })
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
def normalize!
|
|
120
|
-
len = length
|
|
121
|
-
return self if len < 1e-10
|
|
122
|
-
|
|
123
|
-
inv_len = 1.0 / len
|
|
124
|
-
@data.map! { |v| v * inv_len }
|
|
125
|
-
self
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
def conjugate
|
|
129
|
-
Quat2.new([
|
|
130
|
-
-@data[0], -@data[1], -@data[2], @data[3],
|
|
131
|
-
-@data[4], -@data[5], -@data[6], @data[7]
|
|
132
|
-
])
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
def inverse
|
|
136
|
-
len_sq = length_squared
|
|
137
|
-
return conjugate if len_sq < 1e-10
|
|
138
|
-
|
|
139
|
-
inv_len_sq = 1.0 / len_sq
|
|
140
|
-
conj = conjugate
|
|
141
|
-
Quat2.new(conj.data.map { |v| v * inv_len_sq })
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
def translation
|
|
145
|
-
ax, ay, az, aw = @data[0], @data[1], @data[2], @data[3]
|
|
146
|
-
bx, by, bz, bw = @data[4], @data[5], @data[6], @data[7]
|
|
147
|
-
# t = 2 * dual * conjugate(real)
|
|
148
|
-
Vec3.new(
|
|
149
|
-
2 * (-bw * ax + bx * aw - by * az + bz * ay),
|
|
150
|
-
2 * (-bw * ay + by * aw - bz * ax + bx * az),
|
|
151
|
-
2 * (-bw * az + bz * aw - bx * ay + by * ax)
|
|
152
|
-
)
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
def rotation
|
|
156
|
-
real.normalize
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
def transform_point(point)
|
|
160
|
-
rotation * point + translation
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
def lerp(other, t)
|
|
164
|
-
Quat2.new(@data.zip(other.data).map { |a, b| a + (b - a) * t }).normalize
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
def to_mat4
|
|
168
|
-
rot = rotation
|
|
169
|
-
trans = translation
|
|
170
|
-
Mat4.from_quaternion(rot) * Mat4.translation(trans.x, trans.y, trans.z)
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
def to_a
|
|
174
|
-
@data.dup
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
def ==(other)
|
|
178
|
-
return false unless other.is_a?(Quat2)
|
|
179
|
-
|
|
180
|
-
@data == other.data
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
def near?(other, epsilon = 1e-6)
|
|
184
|
-
@data.zip(other.data).all? { |a, b| (a - b).abs < epsilon }
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
def inspect
|
|
188
|
-
"Quat2[real: #{real.inspect}, dual: #{dual.inspect}]"
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
alias to_s inspect
|
|
192
|
-
end
|
|
193
|
-
end
|
data/lib/larb/vec2.rb
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Larb
|
|
4
|
-
class Vec2
|
|
5
|
-
attr_accessor :x, :y
|
|
6
|
-
|
|
7
|
-
def initialize(x = 0.0, y = 0.0)
|
|
8
|
-
@x = x.to_f
|
|
9
|
-
@y = y.to_f
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def self.[](x, y)
|
|
13
|
-
new(x, y)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def self.zero
|
|
17
|
-
new(0, 0)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def self.one
|
|
21
|
-
new(1, 1)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def +(other)
|
|
25
|
-
Vec2.new(@x + other.x, @y + other.y)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def -(other)
|
|
29
|
-
Vec2.new(@x - other.x, @y - other.y)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def *(scalar)
|
|
33
|
-
Vec2.new(@x * scalar, @y * scalar)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def /(scalar)
|
|
37
|
-
Vec2.new(@x / scalar, @y / scalar)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def -@
|
|
41
|
-
Vec2.new(-@x, -@y)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def dot(other)
|
|
45
|
-
@x * other.x + @y * other.y
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def length
|
|
49
|
-
Math.sqrt(@x * @x + @y * @y)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def length_squared
|
|
53
|
-
@x * @x + @y * @y
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def normalize
|
|
57
|
-
self / length
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def normalize!
|
|
61
|
-
l = length
|
|
62
|
-
@x /= l
|
|
63
|
-
@y /= l
|
|
64
|
-
self
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def lerp(other, t)
|
|
68
|
-
self + (other - self) * t
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def to_a
|
|
72
|
-
[@x, @y]
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def [](i)
|
|
76
|
-
to_a[i]
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def []=(i, v)
|
|
80
|
-
if i == 0
|
|
81
|
-
@x = v
|
|
82
|
-
else
|
|
83
|
-
@y = v
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def ==(other)
|
|
88
|
-
return false unless other.is_a?(Vec2)
|
|
89
|
-
|
|
90
|
-
@x == other.x && @y == other.y
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def near?(other, epsilon = 1e-6)
|
|
94
|
-
(@x - other.x).abs < epsilon && (@y - other.y).abs < epsilon
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def angle
|
|
98
|
-
Math.atan2(@y, @x)
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
def angle_to(other)
|
|
102
|
-
Math.atan2(other.y - @y, other.x - @x)
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def rotate(radians)
|
|
106
|
-
c = Math.cos(radians)
|
|
107
|
-
s = Math.sin(radians)
|
|
108
|
-
Vec2.new(@x * c - @y * s, @x * s + @y * c)
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
def distance(other)
|
|
112
|
-
Math.sqrt(distance_squared(other))
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
def distance_squared(other)
|
|
116
|
-
dx = @x - other.x
|
|
117
|
-
dy = @y - other.y
|
|
118
|
-
dx * dx + dy * dy
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
def cross(other)
|
|
122
|
-
@x * other.y - @y * other.x
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
def perpendicular
|
|
126
|
-
Vec2.new(-@y, @x)
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
def reflect(normal)
|
|
130
|
-
self - normal * (2 * dot(normal))
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
def clamp_length(max_length)
|
|
134
|
-
len_sq = length_squared
|
|
135
|
-
return self if len_sq <= max_length * max_length
|
|
136
|
-
|
|
137
|
-
self * (max_length / Math.sqrt(len_sq))
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
def to_vec3(z = 0.0)
|
|
141
|
-
Vec3.new(@x, @y, z)
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
def inspect
|
|
145
|
-
"Vec2[#{@x}, #{@y}]"
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
alias to_s inspect
|
|
149
|
-
end
|
|
150
|
-
end
|
data/lib/larb/vec3.rb
DELETED
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Larb
|
|
4
|
-
class Vec3
|
|
5
|
-
attr_accessor :x, :y, :z
|
|
6
|
-
|
|
7
|
-
def initialize(x = 0.0, y = 0.0, z = 0.0)
|
|
8
|
-
@x = x.to_f
|
|
9
|
-
@y = y.to_f
|
|
10
|
-
@z = z.to_f
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def self.[](x, y, z)
|
|
14
|
-
new(x, y, z)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def self.zero
|
|
18
|
-
new(0, 0, 0)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def self.one
|
|
22
|
-
new(1, 1, 1)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def self.up
|
|
26
|
-
new(0, 1, 0)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def self.down
|
|
30
|
-
new(0, -1, 0)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def self.forward
|
|
34
|
-
new(0, 0, -1)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def self.back
|
|
38
|
-
new(0, 0, 1)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def self.right
|
|
42
|
-
new(1, 0, 0)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def self.left
|
|
46
|
-
new(-1, 0, 0)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def +(other)
|
|
50
|
-
Vec3.new(@x + other.x, @y + other.y, @z + other.z)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def -(other)
|
|
54
|
-
Vec3.new(@x - other.x, @y - other.y, @z - other.z)
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def *(scalar)
|
|
58
|
-
case scalar
|
|
59
|
-
when Numeric
|
|
60
|
-
Vec3.new(@x * scalar, @y * scalar, @z * scalar)
|
|
61
|
-
when Vec3
|
|
62
|
-
Vec3.new(@x * scalar.x, @y * scalar.y, @z * scalar.z)
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def /(scalar)
|
|
67
|
-
Vec3.new(@x / scalar, @y / scalar, @z / scalar)
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def -@
|
|
71
|
-
Vec3.new(-@x, -@y, -@z)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def dot(other)
|
|
75
|
-
@x * other.x + @y * other.y + @z * other.z
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def cross(other)
|
|
79
|
-
Vec3.new(
|
|
80
|
-
@y * other.z - @z * other.y,
|
|
81
|
-
@z * other.x - @x * other.z,
|
|
82
|
-
@x * other.y - @y * other.x
|
|
83
|
-
)
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def length
|
|
87
|
-
Math.sqrt(@x * @x + @y * @y + @z * @z)
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def length_squared
|
|
91
|
-
@x * @x + @y * @y + @z * @z
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def normalize
|
|
95
|
-
self / length
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def reflect(normal)
|
|
99
|
-
self - normal * (2 * dot(normal))
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def xy
|
|
103
|
-
Vec2.new(@x, @y)
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def xz
|
|
107
|
-
Vec2.new(@x, @z)
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
def yz
|
|
111
|
-
Vec2.new(@y, @z)
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def lerp(other, t)
|
|
115
|
-
self + (other - self) * t
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def to_a
|
|
119
|
-
[@x, @y, @z]
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def to_vec4(w = 1.0)
|
|
123
|
-
Vec4.new(@x, @y, @z, w)
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
def [](i)
|
|
127
|
-
to_a[i]
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def ==(other)
|
|
131
|
-
return false unless other.is_a?(Vec3)
|
|
132
|
-
|
|
133
|
-
@x == other.x && @y == other.y && @z == other.z
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
def near?(other, epsilon = 1e-6)
|
|
137
|
-
(@x - other.x).abs < epsilon &&
|
|
138
|
-
(@y - other.y).abs < epsilon &&
|
|
139
|
-
(@z - other.z).abs < epsilon
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
def distance(other)
|
|
143
|
-
Math.sqrt(distance_squared(other))
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
def distance_squared(other)
|
|
147
|
-
dx = @x - other.x
|
|
148
|
-
dy = @y - other.y
|
|
149
|
-
dz = @z - other.z
|
|
150
|
-
dx * dx + dy * dy + dz * dz
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
def angle_between(other)
|
|
154
|
-
d = dot(other) / (length * other.length)
|
|
155
|
-
Math.acos(d.clamp(-1.0, 1.0))
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
def project(onto)
|
|
159
|
-
onto * (dot(onto) / onto.length_squared)
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
def reject(from)
|
|
163
|
-
self - project(from)
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
def slerp(other, t)
|
|
167
|
-
dot_val = normalize.dot(other.normalize).clamp(-1.0, 1.0)
|
|
168
|
-
theta = Math.acos(dot_val) * t
|
|
169
|
-
relative = (other - self * dot_val).normalize
|
|
170
|
-
self * Math.cos(theta) + relative * Math.sin(theta)
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
def clamp_length(max_length)
|
|
174
|
-
len_sq = length_squared
|
|
175
|
-
return self if len_sq <= max_length * max_length
|
|
176
|
-
|
|
177
|
-
self * (max_length / Math.sqrt(len_sq))
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
def normalize!
|
|
181
|
-
l = length
|
|
182
|
-
@x /= l
|
|
183
|
-
@y /= l
|
|
184
|
-
@z /= l
|
|
185
|
-
self
|
|
186
|
-
end
|
|
187
|
-
|
|
188
|
-
def min(other)
|
|
189
|
-
Vec3.new([@x, other.x].min, [@y, other.y].min, [@z, other.z].min)
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
def max(other)
|
|
193
|
-
Vec3.new([@x, other.x].max, [@y, other.y].max, [@z, other.z].max)
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
def abs
|
|
197
|
-
Vec3.new(@x.abs, @y.abs, @z.abs)
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
def floor
|
|
201
|
-
Vec3.new(@x.floor, @y.floor, @z.floor)
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
def ceil
|
|
205
|
-
Vec3.new(@x.ceil, @y.ceil, @z.ceil)
|
|
206
|
-
end
|
|
207
|
-
|
|
208
|
-
def round
|
|
209
|
-
Vec3.new(@x.round, @y.round, @z.round)
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
def inspect
|
|
213
|
-
"Vec3[#{@x}, #{@y}, #{@z}]"
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
alias to_s inspect
|
|
217
|
-
end
|
|
218
|
-
end
|
data/lib/larb/vec4.rb
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Larb
|
|
4
|
-
class Vec4
|
|
5
|
-
attr_accessor :x, :y, :z, :w
|
|
6
|
-
|
|
7
|
-
def initialize(x = 0.0, y = 0.0, z = 0.0, w = 1.0)
|
|
8
|
-
@x = x.to_f
|
|
9
|
-
@y = y.to_f
|
|
10
|
-
@z = z.to_f
|
|
11
|
-
@w = w.to_f
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def self.[](x, y, z, w = 1.0)
|
|
15
|
-
new(x, y, z, w)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def self.zero
|
|
19
|
-
new(0, 0, 0, 0)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def self.one
|
|
23
|
-
new(1, 1, 1, 1)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def +(other)
|
|
27
|
-
Vec4.new(@x + other.x, @y + other.y, @z + other.z, @w + other.w)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def -(other)
|
|
31
|
-
Vec4.new(@x - other.x, @y - other.y, @z - other.z, @w - other.w)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def *(scalar)
|
|
35
|
-
Vec4.new(@x * scalar, @y * scalar, @z * scalar, @w * scalar)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def /(scalar)
|
|
39
|
-
Vec4.new(@x / scalar, @y / scalar, @z / scalar, @w / scalar)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def -@
|
|
43
|
-
Vec4.new(-@x, -@y, -@z, -@w)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def dot(other)
|
|
47
|
-
@x * other.x + @y * other.y + @z * other.z + @w * other.w
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def length
|
|
51
|
-
Math.sqrt(length_squared)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def length_squared
|
|
55
|
-
@x * @x + @y * @y + @z * @z + @w * @w
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def normalize
|
|
59
|
-
self / length
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def normalize!
|
|
63
|
-
l = length
|
|
64
|
-
@x /= l
|
|
65
|
-
@y /= l
|
|
66
|
-
@z /= l
|
|
67
|
-
@w /= l
|
|
68
|
-
self
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def perspective_divide
|
|
72
|
-
return Vec3.new(@x, @y, @z) if @w == 0 || @w == 1
|
|
73
|
-
|
|
74
|
-
Vec3.new(@x / @w, @y / @w, @z / @w)
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def xyz
|
|
78
|
-
Vec3.new(@x, @y, @z)
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def xy
|
|
82
|
-
Vec2.new(@x, @y)
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def rgb
|
|
86
|
-
Vec3.new(@x, @y, @z)
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def to_a
|
|
90
|
-
[@x, @y, @z, @w]
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def [](i)
|
|
94
|
-
to_a[i]
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def ==(other)
|
|
98
|
-
return false unless other.is_a?(Vec4)
|
|
99
|
-
|
|
100
|
-
@x == other.x && @y == other.y && @z == other.z && @w == other.w
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def near?(other, epsilon = 1e-6)
|
|
104
|
-
(@x - other.x).abs < epsilon &&
|
|
105
|
-
(@y - other.y).abs < epsilon &&
|
|
106
|
-
(@z - other.z).abs < epsilon &&
|
|
107
|
-
(@w - other.w).abs < epsilon
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
def lerp(other, t)
|
|
111
|
-
Vec4.new(
|
|
112
|
-
@x + (other.x - @x) * t,
|
|
113
|
-
@y + (other.y - @y) * t,
|
|
114
|
-
@z + (other.z - @z) * t,
|
|
115
|
-
@w + (other.w - @w) * t
|
|
116
|
-
)
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
def inspect
|
|
120
|
-
"Vec4[#{@x}, #{@y}, #{@z}, #{@w}]"
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
alias to_s inspect
|
|
124
|
-
end
|
|
125
|
-
end
|