rmath3d_plain 1.1.0 → 1.2.4
Sign up to get free protection for your applications and to get access to all the features.
- 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) [![Gem Version](https://badge.fury.io/rb/rmath3d.svg)](https://badge.fury.io/rb/rmath3d) [![Gem](https://img.shields.io/gem/dt/rmath3d.svg)](https://rubygems.org/gems/rmath3d)
|
11
|
+
* rmath3d_plain (Pure Ruby Implementation) [![Gem Version](https://badge.fury.io/rb/rmath3d_plain.svg)](https://badge.fury.io/rb/rmath3d_plain) [![Gem](https://img.shields.io/gem/dt/rmath3d_plain.svg)](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: []
|