rmath3d_plain 1.1.0 → 1.2.4
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 +5 -5
- data/ChangeLog +26 -0
- data/LICENSE.txt +1 -1
- data/README.md +6 -6
- data/lib/rmath3d/rmath3d_plain.rb +270 -139
- data/sample/opengl-bindings/load_matrix.rb +2 -2
- data/sample/opengl2/load_matrix.rb +2 -2
- data/test/test.rb +1 -1
- data/test/test_RMtx4.rb +143 -16
- metadata +12 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 569f5334bd7df6cf7e0f7a857ae589bc8258b0940913807ebaa2dcae60bf711e
|
4
|
+
data.tar.gz: 5f5cf50b25ad23c0a51574f6a4d83ac45cfc820e9c5a337591d66a7574c47145
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 13a0b47c640f875de55331962edc75ee9f48f43554e196b98073c297b7ebf6f02e47449c0280f4f9a377a281d0c2607a154a37838cdbaf2d90aa6536a7429c72
|
7
|
+
data.tar.gz: da55b4c5ed4322637162396c67ff45d2f2c870ec7242592309d9bc31dce68e9b3014449bc4f781cde6754cc02e1ce5f5aacbcb98f57cbe867d031dc37a07338d
|
data/ChangeLog
CHANGED
@@ -1,3 +1,29 @@
|
|
1
|
+
2020-07-23 vaiorabbit <http://twitter.com/vaiorabbit>
|
2
|
+
|
3
|
+
* rmath3d.c, rmath3d_plain.rb (RMtx4): Added lookAtLH, perspectiveLH, etc.
|
4
|
+
|
5
|
+
2020-06-21 vaiorabbit <http://twitter.com/vaiorabbit>
|
6
|
+
|
7
|
+
* rmath3d.c, rmath3d_plain.rb (RMtx4): Added argument 'ndc_homogeneous' for projection matrix APIs.
|
8
|
+
Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal)
|
9
|
+
https://www.slideshare.net/Mark_Kilgard/opengl-32-and-more/26-Direct3D_vs_OpenGL_Coordinate_System
|
10
|
+
https://metashapes.com/blog/opengl-metal-projection-matrix-problem/
|
11
|
+
* rmath3d_plain.rb: Removed Fixnum and Bignum symbols (deprecated and unified into Integer class since Ruby 2.4)
|
12
|
+
|
13
|
+
2017-07-22 vaiorabbit <http://twitter.com/vaiorabbit>
|
14
|
+
|
15
|
+
* Added 'Integer' type for argument type branching (constant ::Fixnum is deprecated since ruby 2.4).
|
16
|
+
|
17
|
+
2015-08-23 vaiorabbit <http://twitter.com/vaiorabbit>
|
18
|
+
|
19
|
+
* rmath3d.c (def ==): Removed control path returning Qnil.
|
20
|
+
* rmath3d_plain.rb (def ==): Removed control path returning Qnil.
|
21
|
+
|
22
|
+
2015-05-02 vaiorabbit <http://twitter.com/vaiorabbit>
|
23
|
+
|
24
|
+
* Ruby 1.9.3 and prior versions are no longer supported. Ref.: https://www.ruby-lang.org/en/news/2015/02/23/support-for-ruby-1-9-3-has-ended/
|
25
|
+
* rmath3d.c: Data_Get_Struct -> TypedData_Get_Struct, etc.
|
26
|
+
|
1
27
|
2015-04-12 vaiorabbit <http://twitter.com/vaiorabbit>
|
2
28
|
|
3
29
|
* RVec2.c|h, RMtx2.c|h: Added.
|
data/LICENSE.txt
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
rmath3d : Ruby math module for 3D Applications
|
2
|
-
Copyright (c) 2008-
|
2
|
+
Copyright (c) 2008-2020 vaiorabbit <http://twitter.com/vaiorabbit>
|
3
3
|
|
4
4
|
This software is provided 'as-is', without any express or implied
|
5
5
|
warranty. In no event will the authors be held liable for any damages
|
data/README.md
CHANGED
@@ -4,9 +4,12 @@
|
|
4
4
|
|
5
5
|
rmath3d is a math module for 3D game programming and computer graphics.
|
6
6
|
|
7
|
-
* Last Update:
|
7
|
+
* Last Update: Jul 23, 2020
|
8
8
|
* Since: Jul 20, 2008
|
9
9
|
|
10
|
+
* rmath3d (C Extension Library Implementation) [](https://badge.fury.io/rb/rmath3d) [](https://rubygems.org/gems/rmath3d)
|
11
|
+
* rmath3d_plain (Pure Ruby Implementation) [](https://badge.fury.io/rb/rmath3d_plain) [](https://rubygems.org/gems/rmath3d_plain)
|
12
|
+
|
10
13
|
## Features ##
|
11
14
|
|
12
15
|
### Supports frequently-used vector and matrix classes ###
|
@@ -30,11 +33,8 @@ rmath3d is a math module for 3D game programming and computer graphics.
|
|
30
33
|
Notice: This library provides native extension. You must setup develop environment (or DevKit) before installation.
|
31
34
|
|
32
35
|
* Ruby
|
33
|
-
* ruby 2.
|
34
|
-
*
|
35
|
-
* I used: DevKit-mingw64-32-4.7.2-20130224-1151-sfx.exe
|
36
|
-
* Unpack the archive -> "> ruby dk.rb init" -> edit config.yml (just add your ruby foldier) -> "> ruby dk.rb install"
|
37
|
-
* Ref.: http://blog.mattwynne.net/2010/10/12/installing-ruby-gems-with-native-extensions-on-windows/
|
36
|
+
* ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x64-mingw32]
|
37
|
+
* Ruby 2.3 and prior versions are no longer supported.
|
38
38
|
|
39
39
|
## Building rmath3d.{so|bundle} ##
|
40
40
|
|
@@ -29,7 +29,7 @@ module RMath3D
|
|
29
29
|
0.0, 0.0 ]
|
30
30
|
when 1
|
31
31
|
case a[0]
|
32
|
-
when
|
32
|
+
when Float, Integer
|
33
33
|
@e = [ a[0], a[0],
|
34
34
|
a[0], a[0] ]
|
35
35
|
when RMtx2
|
@@ -46,7 +46,7 @@ module RMath3D
|
|
46
46
|
for col in 0...2 do
|
47
47
|
index = 2*row + col
|
48
48
|
case a[index]
|
49
|
-
when
|
49
|
+
when Float, Integer
|
50
50
|
setElement( row, col, a[index] )
|
51
51
|
else
|
52
52
|
raise TypeError, "RMtx2#initialize : Unknown type #{a[0].class}."
|
@@ -88,7 +88,7 @@ module RMath3D
|
|
88
88
|
#
|
89
89
|
def coerce
|
90
90
|
case arg
|
91
|
-
when
|
91
|
+
when Float, Integer
|
92
92
|
return [ self, arg ]
|
93
93
|
else
|
94
94
|
raise TypeError, "RMtx2#coerce : #{arg.self} can't be coerced into #{self.class}."
|
@@ -411,7 +411,7 @@ module RMath3D
|
|
411
411
|
#
|
412
412
|
def *( arg )
|
413
413
|
case arg
|
414
|
-
when
|
414
|
+
when Float, Integer
|
415
415
|
return RMtx2.new( arg*self.e00, arg*self.e01,
|
416
416
|
arg*self.e10, arg*self.e11 )
|
417
417
|
|
@@ -440,19 +440,18 @@ module RMath3D
|
|
440
440
|
# mtx1 == mtx2 : evaluates equality.
|
441
441
|
#
|
442
442
|
def ==( other )
|
443
|
-
if
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
for col in 0...2 do
|
450
|
-
if ( (getElement(row,col) - other.getElement(row,col)).abs > TOLERANCE )
|
451
|
-
return false
|
443
|
+
if other.class == RMtx2
|
444
|
+
for row in 0...2 do
|
445
|
+
for col in 0...2 do
|
446
|
+
if ( (getElement(row,col) - other.getElement(row,col)).abs > TOLERANCE )
|
447
|
+
return false
|
448
|
+
end
|
452
449
|
end
|
453
450
|
end
|
451
|
+
return true
|
452
|
+
else
|
453
|
+
return false
|
454
454
|
end
|
455
|
-
return true
|
456
455
|
end
|
457
456
|
|
458
457
|
#
|
@@ -504,7 +503,7 @@ module RMath3D
|
|
504
503
|
#
|
505
504
|
def mul!( other )
|
506
505
|
case other
|
507
|
-
when
|
506
|
+
when Float, Integer
|
508
507
|
self.e00 = other*self.e00
|
509
508
|
self.e01 = other*self.e01
|
510
509
|
self.e10 = other*self.e10
|
@@ -561,7 +560,7 @@ module RMath3D
|
|
561
560
|
0.0, 0.0, 0.0 ]
|
562
561
|
when 1
|
563
562
|
case a[0]
|
564
|
-
when
|
563
|
+
when Float, Integer
|
565
564
|
@e = [ a[0], a[0], a[0],
|
566
565
|
a[0], a[0], a[0],
|
567
566
|
a[0], a[0], a[0] ]
|
@@ -580,7 +579,7 @@ module RMath3D
|
|
580
579
|
for col in 0...3 do
|
581
580
|
index = 3*row + col
|
582
581
|
case a[index]
|
583
|
-
when
|
582
|
+
when Float, Integer
|
584
583
|
setElement( row, col, a[index] )
|
585
584
|
else
|
586
585
|
raise TypeError, "RMtx3#initialize : Unknown type #{a[0].class}."
|
@@ -623,7 +622,7 @@ module RMath3D
|
|
623
622
|
#
|
624
623
|
def coerce
|
625
624
|
case arg
|
626
|
-
when
|
625
|
+
when Float, Integer
|
627
626
|
return [ self, arg ]
|
628
627
|
else
|
629
628
|
raise TypeError, "RMtx3#coerce : #{arg.self} can't be coerced into #{self.class}."
|
@@ -1099,7 +1098,7 @@ module RMath3D
|
|
1099
1098
|
#
|
1100
1099
|
def *( arg )
|
1101
1100
|
case arg
|
1102
|
-
when
|
1101
|
+
when Float, Integer
|
1103
1102
|
return RMtx3.new( arg*self.e00, arg*self.e01, arg*self.e02,
|
1104
1103
|
arg*self.e10, arg*self.e11, arg*self.e12,
|
1105
1104
|
arg*self.e20, arg*self.e21, arg*self.e22 )
|
@@ -1129,19 +1128,18 @@ module RMath3D
|
|
1129
1128
|
# mtx1 == mtx2 : evaluates equality.
|
1130
1129
|
#
|
1131
1130
|
def ==( other )
|
1132
|
-
if
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1138
|
-
for col in 0...3 do
|
1139
|
-
if ( (getElement(row,col) - other.getElement(row,col)).abs > TOLERANCE )
|
1140
|
-
return false
|
1131
|
+
if other.class == RMtx3
|
1132
|
+
for row in 0...3 do
|
1133
|
+
for col in 0...3 do
|
1134
|
+
if ( (getElement(row,col) - other.getElement(row,col)).abs > TOLERANCE )
|
1135
|
+
return false
|
1136
|
+
end
|
1141
1137
|
end
|
1142
1138
|
end
|
1139
|
+
return true
|
1140
|
+
else
|
1141
|
+
return false
|
1143
1142
|
end
|
1144
|
-
return true
|
1145
1143
|
end
|
1146
1144
|
|
1147
1145
|
#
|
@@ -1193,7 +1191,7 @@ module RMath3D
|
|
1193
1191
|
#
|
1194
1192
|
def mul!( other )
|
1195
1193
|
case other
|
1196
|
-
when
|
1194
|
+
when Float, Integer
|
1197
1195
|
self.e00 = other*self.e00
|
1198
1196
|
self.e01 = other*self.e01
|
1199
1197
|
self.e02 = other*self.e02
|
@@ -1261,7 +1259,7 @@ module RMath3D
|
|
1261
1259
|
0.0, 0.0, 0.0, 0.0 ]
|
1262
1260
|
when 1
|
1263
1261
|
case a[0]
|
1264
|
-
when
|
1262
|
+
when Float, Integer
|
1265
1263
|
@e = [ a[0], a[0], a[0], a[0],
|
1266
1264
|
a[0], a[0], a[0], a[0],
|
1267
1265
|
a[0], a[0], a[0], a[0],
|
@@ -1282,7 +1280,7 @@ module RMath3D
|
|
1282
1280
|
for col in 0...4 do
|
1283
1281
|
index = 4*row + col
|
1284
1282
|
case a[index]
|
1285
|
-
when
|
1283
|
+
when Float, Integer
|
1286
1284
|
setElement( row, col, a[index] )
|
1287
1285
|
else
|
1288
1286
|
raise TypeError, "RMtx4#initialize : Unknown type #{a[0].class}."
|
@@ -1326,7 +1324,7 @@ module RMath3D
|
|
1326
1324
|
#
|
1327
1325
|
def coerce
|
1328
1326
|
case arg
|
1329
|
-
when
|
1327
|
+
when Float, Integer
|
1330
1328
|
return [ self, arg ]
|
1331
1329
|
else
|
1332
1330
|
raise TypeError, "RMtx4#coerce : #{arg.self} can't be coerced into #{self.class}."
|
@@ -1839,6 +1837,39 @@ module RMath3D
|
|
1839
1837
|
return self
|
1840
1838
|
end
|
1841
1839
|
|
1840
|
+
#
|
1841
|
+
# call-seq: lookAtLH(eye,at,up) -> self
|
1842
|
+
#
|
1843
|
+
# Builds a viewing matrix for a left-handed coordinate system from:
|
1844
|
+
# * eye position (+eye+: RVec3)
|
1845
|
+
# * a point looking at (+at+: RVec3)
|
1846
|
+
# * up vector (+up+: RVec3)
|
1847
|
+
#
|
1848
|
+
def lookAtLH( eye, at, up )
|
1849
|
+
setIdentity()
|
1850
|
+
|
1851
|
+
axis_z = (at - eye).normalize!
|
1852
|
+
axis_x = RVec3.cross( up, axis_z ).normalize!
|
1853
|
+
axis_y = RVec3.cross( axis_z, axis_x )
|
1854
|
+
|
1855
|
+
self.e00 = axis_x[0]
|
1856
|
+
self.e01 = axis_x[1]
|
1857
|
+
self.e02 = axis_x[2]
|
1858
|
+
self.e03 = -RVec3.dot( axis_x, eye )
|
1859
|
+
|
1860
|
+
self.e10 = axis_y[0]
|
1861
|
+
self.e11 = axis_y[1]
|
1862
|
+
self.e12 = axis_y[2]
|
1863
|
+
self.e13 = -RVec3.dot( axis_y, eye )
|
1864
|
+
|
1865
|
+
self.e20 = axis_z[0]
|
1866
|
+
self.e21 = axis_z[1]
|
1867
|
+
self.e22 = axis_z[2]
|
1868
|
+
self.e23 = -RVec3.dot( axis_z, eye )
|
1869
|
+
|
1870
|
+
return self
|
1871
|
+
end
|
1872
|
+
|
1842
1873
|
#
|
1843
1874
|
# call-seq: lookAtRH(eye,at,up) -> self
|
1844
1875
|
#
|
@@ -1873,43 +1904,146 @@ module RMath3D
|
|
1873
1904
|
end
|
1874
1905
|
|
1875
1906
|
#
|
1876
|
-
# call-seq:
|
1907
|
+
# call-seq: perspectiveLH(width,height,znear,zfar,ndc_convention) -> self
|
1877
1908
|
#
|
1878
1909
|
# Builds a perspective projection matrix for a right-handed coordinate system from:
|
1879
1910
|
# * View volume width (+width+)
|
1880
1911
|
# * View volume height (+height+)
|
1881
1912
|
# * Near clip plane distance (+znear+)
|
1882
1913
|
# * Far clip plane distance (+zfar+)
|
1914
|
+
# * Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (+ndc_homogeneous+)
|
1883
1915
|
#
|
1884
|
-
def
|
1885
|
-
|
1886
|
-
return self
|
1916
|
+
def perspectiveLH( width, height, znear, zfar, ndc_homogeneous = true)
|
1917
|
+
return perspectiveOffCenterLH(-width/2.0, width/2.0, -height/2.0, height/2.0, znear, zfar, ndc_homogeneous )
|
1887
1918
|
end
|
1888
1919
|
|
1889
1920
|
#
|
1890
|
-
# call-seq:
|
1921
|
+
# call-seq: perspectiveFovLH(fovy,aspect,znear,zfar,ndc_homogeneous) -> self
|
1891
1922
|
#
|
1892
1923
|
# Builds a perspective projection matrix for a right-handed coordinate system from:
|
1893
1924
|
# * Field of view in y direction (+fovy+ radian)
|
1894
1925
|
# * Aspect ratio (+aspect+)
|
1895
1926
|
# * Near clip plane distance (+znear+)
|
1896
1927
|
# * Far clip plane distance (+zfar+)
|
1928
|
+
# * Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (+ndc_homogeneous+)
|
1929
|
+
#
|
1930
|
+
def perspectiveFovLH( fovy_radian, aspect, znear, zfar, ndc_homogeneous = true)
|
1931
|
+
# Ref.: https://www.scratchapixel.com/lessons/3d-basic-rendering/perspective-and-orthographic-projection-matrix/opengl-perspective-projection-matrix
|
1932
|
+
top = Math::tan(fovy_radian / 2.0) * znear
|
1933
|
+
bottom = -top
|
1934
|
+
right = top * aspect
|
1935
|
+
left = -right
|
1936
|
+
return perspectiveOffCenterLH(left, right, bottom, top, znear, zfar, ndc_homogeneous)
|
1937
|
+
end
|
1938
|
+
|
1939
|
+
#
|
1940
|
+
# call-seq: perspectiveOffCenterLH(left,right,bottom,top,znear,zfar) -> self
|
1941
|
+
#
|
1942
|
+
# Builds a perspective projection matrix for a right-handed coordinate system from:
|
1943
|
+
# * Minimum value of the view volume width (+left+)
|
1944
|
+
# * Maximum value of the view volume width (+right+)
|
1945
|
+
# * Minimum value of the view volume height (+bottom+)
|
1946
|
+
# * Maximum value of the view volume height (+top+)
|
1947
|
+
# * Near clip plane distance (+znear+)
|
1948
|
+
# * Far clip plane distance (+zfar+)
|
1949
|
+
# * Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (+ndc_homogeneous+)
|
1950
|
+
#
|
1951
|
+
def perspectiveOffCenterLH( left, right, bottom, top, znear, zfar, ndc_homogeneous = true)
|
1952
|
+
a = (right+left) / (right-left)
|
1953
|
+
b = (top+bottom) / (top-bottom)
|
1954
|
+
c = ndc_homogeneous ? -(zfar+znear) / (zfar-znear) : -zfar / (zfar-znear)
|
1955
|
+
d = ndc_homogeneous ? -(2*znear*zfar) / (zfar-znear) : -(znear*zfar) / (zfar-znear)
|
1956
|
+
|
1957
|
+
setZero()
|
1958
|
+
|
1959
|
+
setElement( 0, 0, 2*znear/(right-left) )
|
1960
|
+
setElement( 0, 2, -a )
|
1961
|
+
setElement( 1, 1, 2*znear/(top-bottom) )
|
1962
|
+
setElement( 1, 2, -b )
|
1963
|
+
setElement( 2, 2, -c )
|
1964
|
+
setElement( 2, 3, d )
|
1965
|
+
setElement( 3, 2, 1.0 )
|
1966
|
+
|
1967
|
+
return self
|
1968
|
+
end
|
1969
|
+
|
1970
|
+
#
|
1971
|
+
# call-seq: orthoLH(width,height,znear,zfar) -> self
|
1972
|
+
#
|
1973
|
+
# Builds a orthogonal projection matrix for a right-handed coordinate system from:
|
1974
|
+
# * View volume width (+width+)
|
1975
|
+
# * View volume height (+height+)
|
1976
|
+
# * Near clip plane distance (+znear+)
|
1977
|
+
# * Far clip plane distance (+zfar+)
|
1978
|
+
# * Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (+ndc_homogeneous+)
|
1897
1979
|
#
|
1898
|
-
def
|
1899
|
-
|
1900
|
-
|
1980
|
+
def orthoLH( width, height, znear, zfar, ndc_homogeneous = true)
|
1981
|
+
orthoOffCenterLH( -width/2.0, width/2.0, -height/2.0, height/2.0, znear, zfar, ndc_homogeneous )
|
1982
|
+
return self
|
1983
|
+
end
|
1984
|
+
|
1985
|
+
#
|
1986
|
+
# call-seq: orthoOffCenterLH(left,right,bottom,top,znear,zfar) -> self
|
1987
|
+
#
|
1988
|
+
# Builds a orthogonal projection matrix for a right-handed coordinate system from:
|
1989
|
+
# * Minimum value of the view volume width (+left+)
|
1990
|
+
# * Maximum value of the view volume width (+right+)
|
1991
|
+
# * Minimum value of the view volume height (+bottom+)
|
1992
|
+
# * Maximum value of the view volume height (+top+)
|
1993
|
+
# * Near clip plane distance (+znear+)
|
1994
|
+
# * Far clip plane distance (+zfar+)
|
1995
|
+
# * Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (+ndc_homogeneous+)
|
1996
|
+
#
|
1997
|
+
def orthoOffCenterLH( left, right, bottom, top, znear, zfar, ndc_homogeneous = true)
|
1998
|
+
tx = -(right+left) / (right-left)
|
1999
|
+
ty = -(top+bottom) / (top-bottom)
|
2000
|
+
tz = ndc_homogeneous ? -(zfar+znear) / (zfar-znear) : -znear / (zfar-znear)
|
1901
2001
|
|
1902
2002
|
setIdentity()
|
1903
|
-
|
1904
|
-
setElement(
|
1905
|
-
setElement(
|
1906
|
-
setElement(
|
1907
|
-
setElement(
|
1908
|
-
setElement(
|
2003
|
+
|
2004
|
+
setElement( 0, 0, 2.0/(right-left) )
|
2005
|
+
setElement( 0, 3, tx )
|
2006
|
+
setElement( 1, 1, 2.0/(top-bottom) )
|
2007
|
+
setElement( 1, 3, ty )
|
2008
|
+
setElement( 2, 2, (ndc_homogeneous ? 2.0 : 1.0)/(zfar-znear) )
|
2009
|
+
setElement( 2, 3, tz )
|
1909
2010
|
|
1910
2011
|
return self
|
1911
2012
|
end
|
1912
2013
|
|
2014
|
+
#
|
2015
|
+
# call-seq: perspectiveRH(width,height,znear,zfar,ndc_convention) -> self
|
2016
|
+
#
|
2017
|
+
# Builds a perspective projection matrix for a right-handed coordinate system from:
|
2018
|
+
# * View volume width (+width+)
|
2019
|
+
# * View volume height (+height+)
|
2020
|
+
# * Near clip plane distance (+znear+)
|
2021
|
+
# * Far clip plane distance (+zfar+)
|
2022
|
+
# * Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (+ndc_homogeneous+)
|
2023
|
+
#
|
2024
|
+
def perspectiveRH( width, height, znear, zfar, ndc_homogeneous = true)
|
2025
|
+
return perspectiveOffCenterRH(-width/2.0, width/2.0, -height/2.0, height/2.0, znear, zfar, ndc_homogeneous )
|
2026
|
+
end
|
2027
|
+
|
2028
|
+
#
|
2029
|
+
# call-seq: perspectiveFovRH(fovy,aspect,znear,zfar,ndc_homogeneous) -> self
|
2030
|
+
#
|
2031
|
+
# Builds a perspective projection matrix for a right-handed coordinate system from:
|
2032
|
+
# * Field of view in y direction (+fovy+ radian)
|
2033
|
+
# * Aspect ratio (+aspect+)
|
2034
|
+
# * Near clip plane distance (+znear+)
|
2035
|
+
# * Far clip plane distance (+zfar+)
|
2036
|
+
# * Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (+ndc_homogeneous+)
|
2037
|
+
#
|
2038
|
+
def perspectiveFovRH( fovy_radian, aspect, znear, zfar, ndc_homogeneous = true)
|
2039
|
+
# Ref.: https://www.scratchapixel.com/lessons/3d-basic-rendering/perspective-and-orthographic-projection-matrix/opengl-perspective-projection-matrix
|
2040
|
+
top = Math::tan(fovy_radian / 2.0) * znear
|
2041
|
+
bottom = -top
|
2042
|
+
right = top * aspect
|
2043
|
+
left = -right
|
2044
|
+
return perspectiveOffCenterRH(left, right, bottom, top, znear, zfar, ndc_homogeneous)
|
2045
|
+
end
|
2046
|
+
|
1913
2047
|
#
|
1914
2048
|
# call-seq: perspectiveOffCenterRH(left,right,bottom,top,znear,zfar) -> self
|
1915
2049
|
#
|
@@ -1920,14 +2054,15 @@ module RMath3D
|
|
1920
2054
|
# * Maximum value of the view volume height (+top+)
|
1921
2055
|
# * Near clip plane distance (+znear+)
|
1922
2056
|
# * Far clip plane distance (+zfar+)
|
2057
|
+
# * Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (+ndc_homogeneous+)
|
1923
2058
|
#
|
1924
|
-
def perspectiveOffCenterRH( left, right, bottom, top, znear, zfar )
|
2059
|
+
def perspectiveOffCenterRH( left, right, bottom, top, znear, zfar, ndc_homogeneous = true)
|
1925
2060
|
a = (right+left) / (right-left)
|
1926
2061
|
b = (top+bottom) / (top-bottom)
|
1927
|
-
c = -(zfar+znear) / (zfar-znear)
|
1928
|
-
d = -(2*znear*zfar) / (zfar-znear)
|
2062
|
+
c = ndc_homogeneous ? -(zfar+znear) / (zfar-znear) : -zfar / (zfar-znear)
|
2063
|
+
d = ndc_homogeneous ? -(2*znear*zfar) / (zfar-znear) : -(znear*zfar) / (zfar-znear)
|
1929
2064
|
|
1930
|
-
|
2065
|
+
setZero()
|
1931
2066
|
|
1932
2067
|
setElement( 0, 0, 2*znear/(right-left) )
|
1933
2068
|
setElement( 0, 2, a )
|
@@ -1936,7 +2071,6 @@ module RMath3D
|
|
1936
2071
|
setElement( 2, 2, c )
|
1937
2072
|
setElement( 2, 3, d )
|
1938
2073
|
setElement( 3, 2, -1.0 )
|
1939
|
-
setElement( 3, 3, 0.0 )
|
1940
2074
|
|
1941
2075
|
return self
|
1942
2076
|
end
|
@@ -1949,9 +2083,10 @@ module RMath3D
|
|
1949
2083
|
# * View volume height (+height+)
|
1950
2084
|
# * Near clip plane distance (+znear+)
|
1951
2085
|
# * Far clip plane distance (+zfar+)
|
2086
|
+
# * Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (+ndc_homogeneous+)
|
1952
2087
|
#
|
1953
|
-
def orthoRH( width, height, znear, zfar )
|
1954
|
-
orthoOffCenterRH( -width/2.0, width/2.0, -height/2.0, height/2.0, znear, zfar )
|
2088
|
+
def orthoRH( width, height, znear, zfar, ndc_homogeneous = true)
|
2089
|
+
orthoOffCenterRH( -width/2.0, width/2.0, -height/2.0, height/2.0, znear, zfar, ndc_homogeneous )
|
1955
2090
|
return self
|
1956
2091
|
end
|
1957
2092
|
|
@@ -1965,11 +2100,12 @@ module RMath3D
|
|
1965
2100
|
# * Maximum value of the view volume height (+top+)
|
1966
2101
|
# * Near clip plane distance (+znear+)
|
1967
2102
|
# * Far clip plane distance (+zfar+)
|
2103
|
+
# * Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (+ndc_homogeneous+)
|
1968
2104
|
#
|
1969
|
-
def orthoOffCenterRH( left, right, bottom, top, znear, zfar )
|
1970
|
-
tx = (right+left) / (right-left)
|
1971
|
-
ty = (top+bottom) / (top-bottom)
|
1972
|
-
tz = (zfar+znear) / (zfar-znear)
|
2105
|
+
def orthoOffCenterRH( left, right, bottom, top, znear, zfar, ndc_homogeneous = true)
|
2106
|
+
tx = -(right+left) / (right-left)
|
2107
|
+
ty = -(top+bottom) / (top-bottom)
|
2108
|
+
tz = ndc_homogeneous ? -(zfar+znear) / (zfar-znear) : -znear / (zfar-znear)
|
1973
2109
|
|
1974
2110
|
setIdentity()
|
1975
2111
|
|
@@ -1977,7 +2113,7 @@ module RMath3D
|
|
1977
2113
|
setElement( 0, 3, tx )
|
1978
2114
|
setElement( 1, 1, 2.0/(top-bottom) )
|
1979
2115
|
setElement( 1, 3, ty )
|
1980
|
-
setElement( 2, 2, -2.0/(zfar-znear) )
|
2116
|
+
setElement( 2, 2, -(ndc_homogeneous ? 2.0 : 1.0)/(zfar-znear) )
|
1981
2117
|
setElement( 2, 3, tz )
|
1982
2118
|
|
1983
2119
|
return self
|
@@ -2050,7 +2186,7 @@ module RMath3D
|
|
2050
2186
|
#
|
2051
2187
|
def *( arg )
|
2052
2188
|
case arg
|
2053
|
-
when
|
2189
|
+
when Float, Integer
|
2054
2190
|
return RMtx4.new( arg*self.e00, arg*self.e01, arg*self.e02, arg*self.e03,
|
2055
2191
|
arg*self.e10, arg*self.e11, arg*self.e12, arg*self.e13,
|
2056
2192
|
arg*self.e20, arg*self.e21, arg*self.e22, arg*self.e23,
|
@@ -2081,19 +2217,18 @@ module RMath3D
|
|
2081
2217
|
# mtx1 == mtx2 : evaluates equality.
|
2082
2218
|
#
|
2083
2219
|
def ==( other )
|
2084
|
-
if
|
2085
|
-
|
2086
|
-
|
2087
|
-
|
2088
|
-
|
2089
|
-
|
2090
|
-
for col in 0...4 do
|
2091
|
-
if ( (getElement(row,col) - other.getElement(row,col)).abs > TOLERANCE )
|
2092
|
-
return false
|
2220
|
+
if other.class == RMtx4
|
2221
|
+
for row in 0...4 do
|
2222
|
+
for col in 0...4 do
|
2223
|
+
if ( (getElement(row,col) - other.getElement(row,col)).abs > TOLERANCE )
|
2224
|
+
return false
|
2225
|
+
end
|
2093
2226
|
end
|
2094
2227
|
end
|
2228
|
+
return true
|
2229
|
+
else
|
2230
|
+
return false
|
2095
2231
|
end
|
2096
|
-
return true
|
2097
2232
|
end
|
2098
2233
|
|
2099
2234
|
#
|
@@ -2145,7 +2280,7 @@ module RMath3D
|
|
2145
2280
|
#
|
2146
2281
|
def mul!( other )
|
2147
2282
|
case other
|
2148
|
-
when
|
2283
|
+
when Float, Integer
|
2149
2284
|
self.e00 = other*self.e00
|
2150
2285
|
self.e01 = other*self.e01
|
2151
2286
|
self.e02 = other*self.e02
|
@@ -2227,7 +2362,7 @@ module RMath3D
|
|
2227
2362
|
@e = [0.0, 0.0, 0.0, 0.0]
|
2228
2363
|
when 1
|
2229
2364
|
case a[0]
|
2230
|
-
when
|
2365
|
+
when Float, Integer
|
2231
2366
|
@e = [ a[0], a[0], a[0], a[0] ]
|
2232
2367
|
when RQuat
|
2233
2368
|
@e = [ a[0].x, a[0].y, a[0].z, a[0].w ]
|
@@ -2238,7 +2373,7 @@ module RMath3D
|
|
2238
2373
|
when 4
|
2239
2374
|
a.each_with_index do |elem, index|
|
2240
2375
|
case elem
|
2241
|
-
when
|
2376
|
+
when Float, Integer
|
2242
2377
|
@e[index] = elem
|
2243
2378
|
else
|
2244
2379
|
raise TypeError, "RQuat#initialize : Unknown type #{elem.class}."
|
@@ -2258,7 +2393,7 @@ module RMath3D
|
|
2258
2393
|
# Returns human-readable string.
|
2259
2394
|
#
|
2260
2395
|
def to_s
|
2261
|
-
return "( #{@e[0]}, #{@e[1]}, #{@e[2]}, #{@e[3]} )
|
2396
|
+
return "( #{@e[0]}, #{@e[1]}, #{@e[2]}, #{@e[3]} )"
|
2262
2397
|
end
|
2263
2398
|
|
2264
2399
|
#
|
@@ -2277,7 +2412,7 @@ module RMath3D
|
|
2277
2412
|
#
|
2278
2413
|
def coerce( arg )
|
2279
2414
|
case arg
|
2280
|
-
when
|
2415
|
+
when Float, Integer
|
2281
2416
|
return [ self, arg ]
|
2282
2417
|
else
|
2283
2418
|
raise TypeError, "RQuat#coerce : #{arg.self} can't be coerced into #{self.class}."
|
@@ -2616,7 +2751,7 @@ module RMath3D
|
|
2616
2751
|
z = q1w*q2z + q1x*q2y - q1y*q2x + q1z*q2w
|
2617
2752
|
w = q1w*q2w - q1x*q2x - q1y*q2y - q1z*q2z
|
2618
2753
|
return RQuat.new( x, y, z, w )
|
2619
|
-
when
|
2754
|
+
when Float, Integer
|
2620
2755
|
return RQuat.new( @e[0]*arg, @e[1]*arg, @e[2]*arg, @e[3]*arg )
|
2621
2756
|
else
|
2622
2757
|
raise TypeError, "RQuat#* : Unknown type #{arg}."
|
@@ -2630,16 +2765,15 @@ module RMath3D
|
|
2630
2765
|
# quat1 == quat2 : evaluates equality.
|
2631
2766
|
#
|
2632
2767
|
def ==( other )
|
2633
|
-
if other.class
|
2634
|
-
|
2635
|
-
|
2636
|
-
|
2637
|
-
|
2638
|
-
|
2639
|
-
|
2640
|
-
|
2641
|
-
|
2642
|
-
return true
|
2768
|
+
if other.class == RQuat
|
2769
|
+
if (x-other.x).abs<=Float::EPSILON &&
|
2770
|
+
(y-other.y).abs<=Float::EPSILON &&
|
2771
|
+
(z-other.z).abs<=Float::EPSILON &&
|
2772
|
+
(w-other.w).abs<=Float::EPSILON
|
2773
|
+
return true
|
2774
|
+
else
|
2775
|
+
return false
|
2776
|
+
end
|
2643
2777
|
else
|
2644
2778
|
return false
|
2645
2779
|
end
|
@@ -2712,7 +2846,7 @@ module RMath3D
|
|
2712
2846
|
|
2713
2847
|
return self
|
2714
2848
|
|
2715
|
-
when
|
2849
|
+
when Float, Integer
|
2716
2850
|
self.x *= other
|
2717
2851
|
self.y *= other
|
2718
2852
|
self.z *= other
|
@@ -2828,7 +2962,7 @@ module RMath3D
|
|
2828
2962
|
@e = [0.0, 0.0]
|
2829
2963
|
when 1
|
2830
2964
|
case a[0]
|
2831
|
-
when
|
2965
|
+
when Float, Integer
|
2832
2966
|
@e = [ a[0], a[0] ]
|
2833
2967
|
when RVec2
|
2834
2968
|
@e = [ a[0].x, a[0].y ]
|
@@ -2839,7 +2973,7 @@ module RMath3D
|
|
2839
2973
|
when 2
|
2840
2974
|
a.each_with_index do |elem, index|
|
2841
2975
|
case elem
|
2842
|
-
when
|
2976
|
+
when Float, Integer
|
2843
2977
|
@e[index] = elem
|
2844
2978
|
else
|
2845
2979
|
raise TypeError, "RVec2#initialize : Unknown type #{elem.class}."
|
@@ -2859,7 +2993,7 @@ module RMath3D
|
|
2859
2993
|
# Returns human-readable string.
|
2860
2994
|
#
|
2861
2995
|
def to_s
|
2862
|
-
return "( #{@e[0]}, #{@e[1]} )
|
2996
|
+
return "( #{@e[0]}, #{@e[1]} )"
|
2863
2997
|
end
|
2864
2998
|
|
2865
2999
|
#
|
@@ -2878,7 +3012,7 @@ module RMath3D
|
|
2878
3012
|
#
|
2879
3013
|
def coerce( arg )
|
2880
3014
|
case arg
|
2881
|
-
when
|
3015
|
+
when Float, Integer
|
2882
3016
|
return [ self, arg ]
|
2883
3017
|
else
|
2884
3018
|
raise TypeError, "RVec2#coerce : #{arg.self} can't be coerced into #{self.class}."
|
@@ -3067,7 +3201,7 @@ module RMath3D
|
|
3067
3201
|
#
|
3068
3202
|
def *( arg )
|
3069
3203
|
case arg
|
3070
|
-
when
|
3204
|
+
when Float, Integer
|
3071
3205
|
return RVec2.new( @e[0]*arg, @e[1]*arg )
|
3072
3206
|
else
|
3073
3207
|
raise TypeError, "RVec2#* : Unknown type #{arg}."
|
@@ -3081,14 +3215,13 @@ module RMath3D
|
|
3081
3215
|
# vec1 == vec2 : evaluates equality.
|
3082
3216
|
#
|
3083
3217
|
def ==( other )
|
3084
|
-
if other.class
|
3085
|
-
|
3086
|
-
|
3087
|
-
|
3088
|
-
|
3089
|
-
|
3090
|
-
|
3091
|
-
return true
|
3218
|
+
if other.class == RVec2
|
3219
|
+
if (x-other.x).abs<=Float::EPSILON &&
|
3220
|
+
(y-other.y).abs<=Float::EPSILON
|
3221
|
+
return true
|
3222
|
+
else
|
3223
|
+
return false
|
3224
|
+
end
|
3092
3225
|
else
|
3093
3226
|
return false
|
3094
3227
|
end
|
@@ -3134,7 +3267,7 @@ module RMath3D
|
|
3134
3267
|
# vec1 *= vec2
|
3135
3268
|
#
|
3136
3269
|
def mul!( arg )
|
3137
|
-
if arg.class
|
3270
|
+
if !(arg.class == Float || arg.class == Integer)
|
3138
3271
|
raise TypeError, "RVec2#mul! : Unknown type #{arg.class}."
|
3139
3272
|
return nil
|
3140
3273
|
end
|
@@ -3168,7 +3301,7 @@ module RMath3D
|
|
3168
3301
|
@e = [0.0, 0.0, 0.0]
|
3169
3302
|
when 1
|
3170
3303
|
case a[0]
|
3171
|
-
when
|
3304
|
+
when Float, Integer
|
3172
3305
|
@e = [ a[0], a[0], a[0] ]
|
3173
3306
|
when RVec3
|
3174
3307
|
@e = [ a[0].x, a[0].y, a[0].z ]
|
@@ -3179,7 +3312,7 @@ module RMath3D
|
|
3179
3312
|
when 3
|
3180
3313
|
a.each_with_index do |elem, index|
|
3181
3314
|
case elem
|
3182
|
-
when
|
3315
|
+
when Float, Integer
|
3183
3316
|
@e[index] = elem
|
3184
3317
|
else
|
3185
3318
|
raise TypeError, "RVec3#initialize : Unknown type #{elem.class}."
|
@@ -3199,7 +3332,7 @@ module RMath3D
|
|
3199
3332
|
# Returns human-readable string.
|
3200
3333
|
#
|
3201
3334
|
def to_s
|
3202
|
-
return "( #{@e[0]}, #{@e[1]}, #{@e[2]} )
|
3335
|
+
return "( #{@e[0]}, #{@e[1]}, #{@e[2]} )"
|
3203
3336
|
end
|
3204
3337
|
|
3205
3338
|
#
|
@@ -3218,7 +3351,7 @@ module RMath3D
|
|
3218
3351
|
#
|
3219
3352
|
def coerce( arg )
|
3220
3353
|
case arg
|
3221
|
-
when
|
3354
|
+
when Float, Integer
|
3222
3355
|
return [ self, arg ]
|
3223
3356
|
else
|
3224
3357
|
raise TypeError, "RVec3#coerce : #{arg.self} can't be coerced into #{self.class}."
|
@@ -3522,9 +3655,9 @@ module RMath3D
|
|
3522
3655
|
t_z = q.w*self[2] + q.x*self[1] - q.y*self[0]
|
3523
3656
|
t_w = - q.x*self[0] - q.y*self[1] - q.z*self[2]
|
3524
3657
|
|
3525
|
-
result.x = -t_w*q.x + t_x*q.w - t_y*q.z + t_z*q.y
|
3526
|
-
result.y = -t_w*q.y + t_x*q.z + t_y*q.w - t_z*q.x
|
3527
|
-
result.z = -t_w*q.z - t_x*q.y + t_y*q.x + t_z*q.w
|
3658
|
+
result.x = -t_w*q.x + t_x*q.w - t_y*q.z + t_z*q.y
|
3659
|
+
result.y = -t_w*q.y + t_x*q.z + t_y*q.w - t_z*q.x
|
3660
|
+
result.z = -t_w*q.z - t_x*q.y + t_y*q.x + t_z*q.w
|
3528
3661
|
|
3529
3662
|
return result
|
3530
3663
|
end
|
@@ -3538,9 +3671,9 @@ module RMath3D
|
|
3538
3671
|
t_z = q.w*self[2] + q.x*self[1] - q.y*self[0]
|
3539
3672
|
t_w = - q.x*self[0] - q.y*self[1] - q.z*self[2]
|
3540
3673
|
|
3541
|
-
self.x = -t_w*q.x + t_x*q.w - t_y*q.z + t_z*q.y
|
3542
|
-
self.y = -t_w*q.y + t_x*q.z + t_y*q.w - t_z*q.x
|
3543
|
-
self.z = -t_w*q.z - t_x*q.y + t_y*q.x + t_z*q.w
|
3674
|
+
self.x = -t_w*q.x + t_x*q.w - t_y*q.z + t_z*q.y
|
3675
|
+
self.y = -t_w*q.y + t_x*q.z + t_y*q.w - t_z*q.x
|
3676
|
+
self.z = -t_w*q.z - t_x*q.y + t_y*q.x + t_z*q.w
|
3544
3677
|
|
3545
3678
|
return self
|
3546
3679
|
end
|
@@ -3621,7 +3754,7 @@ module RMath3D
|
|
3621
3754
|
#
|
3622
3755
|
def *( arg )
|
3623
3756
|
case arg
|
3624
|
-
when
|
3757
|
+
when Float, Integer
|
3625
3758
|
return RVec3.new( @e[0]*arg, @e[1]*arg, @e[2]*arg )
|
3626
3759
|
else
|
3627
3760
|
raise TypeError, "RVec3#* : Unknown type #{arg}."
|
@@ -3635,15 +3768,14 @@ module RMath3D
|
|
3635
3768
|
# vec1 == vec2 : evaluates equality.
|
3636
3769
|
#
|
3637
3770
|
def ==( other )
|
3638
|
-
if other.class
|
3639
|
-
|
3640
|
-
|
3641
|
-
|
3642
|
-
|
3643
|
-
|
3644
|
-
|
3645
|
-
|
3646
|
-
return true
|
3771
|
+
if other.class == RVec3
|
3772
|
+
if (x-other.x).abs<=Float::EPSILON &&
|
3773
|
+
(y-other.y).abs<=Float::EPSILON &&
|
3774
|
+
(z-other.z).abs<=Float::EPSILON
|
3775
|
+
return true
|
3776
|
+
else
|
3777
|
+
return false
|
3778
|
+
end
|
3647
3779
|
else
|
3648
3780
|
return false
|
3649
3781
|
end
|
@@ -3691,7 +3823,7 @@ module RMath3D
|
|
3691
3823
|
# vec1 *= vec2
|
3692
3824
|
#
|
3693
3825
|
def mul!( arg )
|
3694
|
-
if arg.class
|
3826
|
+
if !(arg.class == Float || arg.class == Integer)
|
3695
3827
|
raise TypeError, "RVec3#mul! : Unknown type #{arg.class}."
|
3696
3828
|
return nil
|
3697
3829
|
end
|
@@ -3726,7 +3858,7 @@ module RMath3D
|
|
3726
3858
|
@e = [0.0, 0.0, 0.0, 0.0]
|
3727
3859
|
when 1
|
3728
3860
|
case a[0]
|
3729
|
-
when
|
3861
|
+
when Float, Integer
|
3730
3862
|
@e = [ a[0], a[0], a[0], a[0] ]
|
3731
3863
|
when RVec3
|
3732
3864
|
@e = [ a[0].x, a[0].y, a[0].z, 0.0 ]
|
@@ -3739,7 +3871,7 @@ module RMath3D
|
|
3739
3871
|
when 4
|
3740
3872
|
a.each_with_index do |elem, index|
|
3741
3873
|
case elem
|
3742
|
-
when
|
3874
|
+
when Float, Integer
|
3743
3875
|
@e[index] = elem
|
3744
3876
|
else
|
3745
3877
|
raise TypeError, "RVec4#initialize : Unknown type #{elem.class}."
|
@@ -3759,7 +3891,7 @@ module RMath3D
|
|
3759
3891
|
# Returns human-readable string.
|
3760
3892
|
#
|
3761
3893
|
def to_s
|
3762
|
-
return "( #{@e[0]}, #{@e[1]}, #{@e[2]}, #{@e[3]} )
|
3894
|
+
return "( #{@e[0]}, #{@e[1]}, #{@e[2]}, #{@e[3]} )"
|
3763
3895
|
end
|
3764
3896
|
|
3765
3897
|
#
|
@@ -3778,7 +3910,7 @@ module RMath3D
|
|
3778
3910
|
#
|
3779
3911
|
def coerce( arg )
|
3780
3912
|
case arg
|
3781
|
-
when
|
3913
|
+
when Float, Integer
|
3782
3914
|
return [ self, arg ]
|
3783
3915
|
else
|
3784
3916
|
raise TypeError, "RVec4#coerce : #{arg.self} can't be coerced into #{self.class}."
|
@@ -4068,7 +4200,7 @@ module RMath3D
|
|
4068
4200
|
#
|
4069
4201
|
def *( arg )
|
4070
4202
|
case arg
|
4071
|
-
when
|
4203
|
+
when Float, Integer
|
4072
4204
|
return RVec4.new( @e[0]*arg, @e[1]*arg, @e[2]*arg, @e[3]*arg )
|
4073
4205
|
else
|
4074
4206
|
raise TypeError, "RVec4#* : Unknown type #{arg}."
|
@@ -4082,16 +4214,15 @@ module RMath3D
|
|
4082
4214
|
# vec1 == vec2 : evaluates equality.
|
4083
4215
|
#
|
4084
4216
|
def ==( other )
|
4085
|
-
if other.class
|
4086
|
-
|
4087
|
-
|
4088
|
-
|
4089
|
-
|
4090
|
-
|
4091
|
-
|
4092
|
-
|
4093
|
-
|
4094
|
-
return true
|
4217
|
+
if other.class == RVec4
|
4218
|
+
if (x-other.x).abs<=Float::EPSILON &&
|
4219
|
+
(y-other.y).abs<=Float::EPSILON &&
|
4220
|
+
(z-other.z).abs<=Float::EPSILON &&
|
4221
|
+
(w-other.w).abs<=Float::EPSILON
|
4222
|
+
return true
|
4223
|
+
else
|
4224
|
+
return false
|
4225
|
+
end
|
4095
4226
|
else
|
4096
4227
|
return false
|
4097
4228
|
end
|
@@ -4141,7 +4272,7 @@ module RMath3D
|
|
4141
4272
|
# vec1 *= vec2
|
4142
4273
|
#
|
4143
4274
|
def mul!( other )
|
4144
|
-
if other.class
|
4275
|
+
if !(other.class == Float || other.class == Integer)
|
4145
4276
|
raise TypeError, "RVec4#mul! : Unknown type #{other.class}."
|
4146
4277
|
return nil
|
4147
4278
|
end
|
@@ -4159,7 +4290,7 @@ end
|
|
4159
4290
|
|
4160
4291
|
=begin
|
4161
4292
|
RMath : Ruby math module for 3D Applications
|
4162
|
-
Copyright (c) 2008- vaiorabbit <http://twitter.com/vaiorabbit>
|
4293
|
+
Copyright (c) 2008-2020 vaiorabbit <http://twitter.com/vaiorabbit>
|
4163
4294
|
|
4164
4295
|
This software is provided 'as-is', without any express or implied
|
4165
4296
|
warranty. In no event will the authors be held liable for any damages
|
@@ -104,7 +104,7 @@ class App
|
|
104
104
|
def size_callback( window_handle, w, h )
|
105
105
|
glViewport( 0, 0, w, h )
|
106
106
|
glMatrixMode( GL_PROJECTION )
|
107
|
-
@mtxProj.perspectiveFovRH( 30.0*Math::PI/180.0, w.to_f/h.to_f, 0.1, 1000.0 )
|
107
|
+
@mtxProj.perspectiveFovRH( 30.0*Math::PI/180.0, w.to_f/h.to_f, 0.1, 1000.0, true )
|
108
108
|
glLoadMatrixf( @mtxProj.to_a.pack('F16') )
|
109
109
|
|
110
110
|
@window_width = w
|
@@ -119,7 +119,7 @@ class App
|
|
119
119
|
@at = RVec3.new(0.0, 0.0, 0.0)
|
120
120
|
@up = RVec3.new(0.0, 1.0, 0.0)
|
121
121
|
@mtxLookAt = RMtx4.new.lookAtRH( @eye, @at, @up )
|
122
|
-
@mtxProj = RMtx4.new.perspectiveFovRH( 30.0*Math::PI/180.0, @window_width.to_f/@window_height.to_f, 0.1, 1000.0 )
|
122
|
+
@mtxProj = RMtx4.new.perspectiveFovRH( 30.0*Math::PI/180.0, @window_width.to_f/@window_height.to_f, 0.1, 1000.0, true )
|
123
123
|
|
124
124
|
@light_pos = [2.5,0,5,1]
|
125
125
|
@light_diffuse = [1,1,1,1]
|
@@ -42,7 +42,7 @@ class App
|
|
42
42
|
def reshape( width, height )
|
43
43
|
glViewport( 0, 0, width, height )
|
44
44
|
glMatrixMode( GL_PROJECTION )
|
45
|
-
@mtxProj.perspectiveFovRH( 30.0*Math::PI/180.0, width.to_f/height.to_f, 0.1, 1000.0 )
|
45
|
+
@mtxProj.perspectiveFovRH( 30.0*Math::PI/180.0, width.to_f/height.to_f, 0.1, 1000.0, true )
|
46
46
|
glLoadMatrix( @mtxProj )
|
47
47
|
|
48
48
|
@window_width = width
|
@@ -74,7 +74,7 @@ class App
|
|
74
74
|
@at = RVec3.new(0.0, 0.0, 0.0)
|
75
75
|
@up = RVec3.new(0.0, 1.0, 0.0)
|
76
76
|
@mtxLookAt = RMtx4.new.lookAtRH( @eye, @at, @up )
|
77
|
-
@mtxProj = RMtx4.new.perspectiveFovRH( 30.0*Math::PI/180.0, @window_width.to_f/@window_height.to_f, 0.1, 1000.0 )
|
77
|
+
@mtxProj = RMtx4.new.perspectiveFovRH( 30.0*Math::PI/180.0, @window_width.to_f/@window_height.to_f, 0.1, 1000.0, true )
|
78
78
|
|
79
79
|
@light_pos = [2.5,0,5,1]
|
80
80
|
@light_diffuse = [1,1,1,1]
|
data/test/test.rb
CHANGED
data/test/test_RMtx4.rb
CHANGED
@@ -485,6 +485,29 @@ class TC_RMtx4 < Minitest::Test
|
|
485
485
|
end
|
486
486
|
end
|
487
487
|
|
488
|
+
def test_lookAtLH
|
489
|
+
pEye = RVec3.new( 10, 10, 10 )
|
490
|
+
vDir = ( RVec3.new(0,0,0) - pEye ).normalize! # staring at (0,0,0)
|
491
|
+
vUp = RVec3.new( 0, 1, 0 )
|
492
|
+
vRight = RVec3.cross( vUp, vDir ).normalize!
|
493
|
+
vUp = RVec3.cross( vDir, vRight ).normalize!
|
494
|
+
|
495
|
+
m0 = RMtx4.new( vRight.x, vRight.y, vRight.z, -RVec3.dot(pEye,vRight),
|
496
|
+
vUp.x, vUp.y, vUp.z, -RVec3.dot(pEye,vUp),
|
497
|
+
vDir.x, vDir.y, vDir.z, -RVec3.dot(pEye,vDir),
|
498
|
+
0.0, 0.0, 0.0, 1.0 )
|
499
|
+
|
500
|
+
m1 = RMtx4.new.lookAtLH( RVec3.new(10,10,10), # posistion
|
501
|
+
RVec3.new(0,0,0), # at
|
502
|
+
RVec3.new(0,1,0) ) # up
|
503
|
+
|
504
|
+
for r in 0...4 do
|
505
|
+
for c in 0...4 do
|
506
|
+
assert_in_delta( m0.getElement(r,c), m1.getElement(r,c), @tolerance )
|
507
|
+
end
|
508
|
+
end
|
509
|
+
end
|
510
|
+
|
488
511
|
def test_lookAtRH
|
489
512
|
pEye = RVec3.new( 10, 10, 10 )
|
490
513
|
vDir = ( pEye - RVec3.new(0,0,0) ).normalize! # staring at (0,0,0)
|
@@ -526,7 +549,7 @@ class TC_RMtx4 < Minitest::Test
|
|
526
549
|
0.0, 2*z_n/height, 0.0, 0.0,
|
527
550
|
0.0, 0.0, -(z_f+z_n)/(z_f-z_n), -2.0*z_f*z_n / (z_f-z_n),
|
528
551
|
0.0, 0.0, -1.0, 0.0 )
|
529
|
-
m1 = RMtx4.new.perspectiveRH( width, height, z_n, z_f )
|
552
|
+
m1 = RMtx4.new.perspectiveRH( width, height, z_n, z_f, true )
|
530
553
|
|
531
554
|
for r in 0...4 do
|
532
555
|
for c in 0...4 do
|
@@ -540,15 +563,15 @@ class TC_RMtx4 < Minitest::Test
|
|
540
563
|
fovy = 2.0 * Math::atan( (height/2.0) / z_n )
|
541
564
|
f = 1.0/Math::tan( fovy/2.0 )
|
542
565
|
|
543
|
-
m2 = RMtx4.new( f/aspect, 0.0, 0.0,
|
544
|
-
0.0, f, 0.0,
|
545
|
-
0.0, 0.0, (z_f+z_n)/(z_n
|
546
|
-
0.0, 0.0,
|
547
|
-
m3 = RMtx4.new.perspectiveFovRH( fovy, aspect, z_n, z_f );
|
566
|
+
m2 = RMtx4.new( f/aspect, 0.0, 0.0, 0.0,
|
567
|
+
0.0, f, 0.0, 0.0,
|
568
|
+
0.0, 0.0, -(z_f+z_n)/(z_f-z_n), -2*z_f*z_n/(z_f-z_n),
|
569
|
+
0.0, 0.0, -1.0, 0.0 )
|
570
|
+
m3 = RMtx4.new.perspectiveFovRH( fovy, aspect, z_n, z_f, true );
|
548
571
|
|
549
572
|
for r in 0...4 do
|
550
573
|
for c in 0...4 do
|
551
|
-
assert_in_delta( m2.getElement(r,c),
|
574
|
+
assert_in_delta( m2.getElement(r,c), m3.getElement(r,c), @tolerance )
|
552
575
|
end
|
553
576
|
end
|
554
577
|
|
@@ -563,7 +586,68 @@ class TC_RMtx4 < Minitest::Test
|
|
563
586
|
0.0, 0.0, c, d,
|
564
587
|
0.0, 0.0, -1.0, 0.0 )
|
565
588
|
|
566
|
-
m5 = RMtx4.new.perspectiveOffCenterRH( left, right, bottom, top, z_n, z_f )
|
589
|
+
m5 = RMtx4.new.perspectiveOffCenterRH( left, right, bottom, top, z_n, z_f, true )
|
590
|
+
|
591
|
+
for r in 0...4 do
|
592
|
+
for c in 0...4 do
|
593
|
+
assert_in_delta( m4.getElement(r,c), m5.getElement(r,c), @tolerance )
|
594
|
+
end
|
595
|
+
end
|
596
|
+
end
|
597
|
+
|
598
|
+
def test_perspectiveLH
|
599
|
+
left = -640.0
|
600
|
+
right = 640.0
|
601
|
+
bottom = -360.0
|
602
|
+
top = 360.0
|
603
|
+
z_n = 1.0
|
604
|
+
z_f = 1000.0
|
605
|
+
width = right - left
|
606
|
+
height = top - bottom
|
607
|
+
aspect = width/height
|
608
|
+
|
609
|
+
# RMtx4#perspectiveLH
|
610
|
+
m0 = RMtx4.new( 2*z_n/width, 0.0, 0.0, 0.0,
|
611
|
+
0.0, 2*z_n/height, 0.0, 0.0,
|
612
|
+
0.0, 0.0, (z_f+z_n)/(z_f-z_n), -2.0*z_f*z_n / (z_f-z_n),
|
613
|
+
0.0, 0.0, 1.0, 0.0 )
|
614
|
+
m1 = RMtx4.new.perspectiveLH( width, height, z_n, z_f, true )
|
615
|
+
|
616
|
+
for r in 0...4 do
|
617
|
+
for c in 0...4 do
|
618
|
+
assert_in_delta( m0.getElement(r,c), m1.getElement(r,c), @tolerance )
|
619
|
+
end
|
620
|
+
end
|
621
|
+
|
622
|
+
# RMtx4#perspectiveFovLH
|
623
|
+
|
624
|
+
# [NOTE] tan(fovy/2) == (height/2)/z_n
|
625
|
+
fovy = 2.0 * Math::atan( (height/2.0) / z_n )
|
626
|
+
f = 1.0/Math::tan( fovy/2.0 )
|
627
|
+
|
628
|
+
m2 = RMtx4.new( f/aspect, 0.0, 0.0, 0.0,
|
629
|
+
0.0, f, 0.0, 0.0,
|
630
|
+
0.0, 0.0, (z_f+z_n)/(z_f-z_n), -2.0*z_f*z_n/(z_f-z_n),
|
631
|
+
0.0, 0.0, 1.0, 0.0 )
|
632
|
+
m3 = RMtx4.new.perspectiveFovLH( fovy, aspect, z_n, z_f, true );
|
633
|
+
for r in 0...4 do
|
634
|
+
for c in 0...4 do
|
635
|
+
assert_in_delta( m2.getElement(r,c), m3.getElement(r,c), @tolerance )
|
636
|
+
end
|
637
|
+
end
|
638
|
+
|
639
|
+
# RMtx4#perspectiveOffCenterLH
|
640
|
+
|
641
|
+
a = (right+left)/(right-left)
|
642
|
+
b = (top+bottom)/(top-bottom)
|
643
|
+
c = -(z_f+z_n)/(z_f-z_n)
|
644
|
+
d = -2.0*z_f*z_n/(z_f-z_n)
|
645
|
+
m4 = RMtx4.new( 2*z_n/(right-left), 0.0, -a, 0.0,
|
646
|
+
0.0, 2*z_n/(top-bottom), -b, 0.0,
|
647
|
+
0.0, 0.0, -c, d,
|
648
|
+
0.0, 0.0, 1.0, 0.0 )
|
649
|
+
|
650
|
+
m5 = RMtx4.new.perspectiveOffCenterLH( left, right, bottom, top, z_n, z_f, true )
|
567
651
|
|
568
652
|
for r in 0...4 do
|
569
653
|
for c in 0...4 do
|
@@ -584,14 +668,14 @@ class TC_RMtx4 < Minitest::Test
|
|
584
668
|
height = top - bottom
|
585
669
|
|
586
670
|
# RMtx4#orthoRH
|
587
|
-
tx = (right+left)/width
|
588
|
-
ty = (top+bottom)/height
|
589
|
-
tz = (z_f+z_n)/(z_f-z_n)
|
671
|
+
tx = -(right+left)/width
|
672
|
+
ty = -(top+bottom)/height
|
673
|
+
tz = -(z_f+z_n)/(z_f-z_n)
|
590
674
|
m0 = RMtx4.new( 2.0/width, 0.0, 0.0, tx,
|
591
675
|
0.0, 2.0/height, 0.0, ty,
|
592
676
|
0.0, 0.0, -2.0/(z_f-z_n), tz,
|
593
677
|
0.0, 0.0, 0.0, 1.0 )
|
594
|
-
m1 = RMtx4.new.orthoRH( width, height, z_n, z_f )
|
678
|
+
m1 = RMtx4.new.orthoRH( width, height, z_n, z_f, true )
|
595
679
|
|
596
680
|
for r in 0...4 do
|
597
681
|
for c in 0...4 do
|
@@ -600,14 +684,57 @@ class TC_RMtx4 < Minitest::Test
|
|
600
684
|
end
|
601
685
|
|
602
686
|
# RMtx4#orthoOffCenterRH
|
603
|
-
tx = (right+left)/(right-left)
|
604
|
-
ty = (top+bottom)/(top-bottom)
|
605
|
-
tz = (z_f+z_n)/(z_f-z_n)
|
687
|
+
tx = -(right+left)/(right-left)
|
688
|
+
ty = -(top+bottom)/(top-bottom)
|
689
|
+
tz = -(z_f+z_n)/(z_f-z_n)
|
606
690
|
m2 = RMtx4.new( 2.0/(right-left), 0.0, 0.0, tx,
|
607
691
|
0.0, 2.0/(top-bottom), 0.0, ty,
|
608
692
|
0.0, 0.0, -2.0/(z_f-z_n), tz,
|
609
693
|
0.0, 0.0, 0.0, 1.0 )
|
610
|
-
m3 = RMtx4.new.orthoOffCenterRH( left, right, bottom, top, z_n, z_f )
|
694
|
+
m3 = RMtx4.new.orthoOffCenterRH( left, right, bottom, top, z_n, z_f, true )
|
695
|
+
|
696
|
+
for r in 0...4 do
|
697
|
+
for c in 0...4 do
|
698
|
+
assert_in_delta( m2.getElement(r,c), m3.getElement(r,c), @tolerance )
|
699
|
+
end
|
700
|
+
end
|
701
|
+
end
|
702
|
+
|
703
|
+
def test_orthoLH
|
704
|
+
left = -640.0
|
705
|
+
right = 640.0
|
706
|
+
bottom = -360.0
|
707
|
+
top = 360.0
|
708
|
+
z_n = 1.0
|
709
|
+
z_f = 1000.0
|
710
|
+
width = right - left
|
711
|
+
height = top - bottom
|
712
|
+
|
713
|
+
# RMtx4#orthoLH
|
714
|
+
tx = -(right+left)/width
|
715
|
+
ty = -(top+bottom)/height
|
716
|
+
tz = -(z_f+z_n)/(z_f-z_n)
|
717
|
+
m0 = RMtx4.new( 2.0/width, 0.0, 0.0, tx,
|
718
|
+
0.0, 2.0/height, 0.0, ty,
|
719
|
+
0.0, 0.0, 2.0/(z_f-z_n), tz,
|
720
|
+
0.0, 0.0, 0.0, 1.0 )
|
721
|
+
m1 = RMtx4.new.orthoLH( width, height, z_n, z_f, true )
|
722
|
+
|
723
|
+
for r in 0...4 do
|
724
|
+
for c in 0...4 do
|
725
|
+
assert_in_delta( m0.getElement(r,c), m1.getElement(r,c), @tolerance )
|
726
|
+
end
|
727
|
+
end
|
728
|
+
|
729
|
+
# RMtx4#orthoOffCenterLH
|
730
|
+
tx = -(right+left)/(right-left)
|
731
|
+
ty = -(top+bottom)/(top-bottom)
|
732
|
+
tz = -(z_f+z_n)/(z_f-z_n)
|
733
|
+
m2 = RMtx4.new( 2.0/(right-left), 0.0, 0.0, tx,
|
734
|
+
0.0, 2.0/(top-bottom), 0.0, ty,
|
735
|
+
0.0, 0.0, 2.0/(z_f-z_n), tz,
|
736
|
+
0.0, 0.0, 0.0, 1.0 )
|
737
|
+
m3 = RMtx4.new.orthoOffCenterLH( left, right, bottom, top, z_n, z_f, true )
|
611
738
|
|
612
739
|
for r in 0...4 do
|
613
740
|
for c in 0...4 do
|
metadata
CHANGED
@@ -1,17 +1,19 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rmath3d_plain
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- vaiorabbit
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-07-23 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description:
|
14
|
-
|
13
|
+
description: 'Provides vector2/3/4, matrix2x2/3x3/4x4 and quaternion in plain Ruby
|
14
|
+
form.
|
15
|
+
|
16
|
+
'
|
15
17
|
email:
|
16
18
|
- vaiorabbit@gmail.com
|
17
19
|
executables: []
|
@@ -35,9 +37,9 @@ files:
|
|
35
37
|
- test/test_RVec4.rb
|
36
38
|
homepage: https://github.com/vaiorabbit/rmath3d
|
37
39
|
licenses:
|
38
|
-
-
|
40
|
+
- Zlib
|
39
41
|
metadata: {}
|
40
|
-
post_install_message:
|
42
|
+
post_install_message:
|
41
43
|
rdoc_options: []
|
42
44
|
require_paths:
|
43
45
|
- lib
|
@@ -45,16 +47,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
45
47
|
requirements:
|
46
48
|
- - ">="
|
47
49
|
- !ruby/object:Gem::Version
|
48
|
-
version:
|
50
|
+
version: 2.4.0
|
49
51
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
52
|
requirements:
|
51
53
|
- - ">="
|
52
54
|
- !ruby/object:Gem::Version
|
53
55
|
version: '0'
|
54
56
|
requirements: []
|
55
|
-
|
56
|
-
|
57
|
-
signing_key:
|
57
|
+
rubygems_version: 3.1.2
|
58
|
+
signing_key:
|
58
59
|
specification_version: 4
|
59
60
|
summary: Ruby Math Module for 3D Applications
|
60
61
|
test_files: []
|