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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5b2a5f2fa521f8b303ef746634b8574967b7b703
4
- data.tar.gz: ecfe68cac549e516052ea77ddd885051fd36fc81
2
+ SHA256:
3
+ metadata.gz: 569f5334bd7df6cf7e0f7a857ae589bc8258b0940913807ebaa2dcae60bf711e
4
+ data.tar.gz: 5f5cf50b25ad23c0a51574f6a4d83ac45cfc820e9c5a337591d66a7574c47145
5
5
  SHA512:
6
- metadata.gz: 1bda4cabbc91bc183b5881f5c51c0716c3fb8b0f1b3562eb8843e47c3bd3f774c69de6111c4f7412103e81b2258b3476cd7f1b974c6aaa9abbc8b05c3d447750
7
- data.tar.gz: a58f95113e0d9e3bef1488fdf26d79c2069f3fb0654eeeaec0bd6741ceb43941ec2af3e8cd7c016d3524d5adcda99933da38e1c4496cfb7f1c1335aea23ef245
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.
@@ -1,5 +1,5 @@
1
1
  rmath3d : Ruby math module for 3D Applications
2
- Copyright (c) 2008-2015 vaiorabbit <http://twitter.com/vaiorabbit>
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: Apr 12, 2015
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.0.0p247 (2013-06-27 revision 41674) [x86_64-darwin12.4.0]
34
- * ruby 2.0.0p247 (2013-06-27) [i386-mingw32] With Development Kit installed.
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 Fixnum, Float
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 Fixnum, Float
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 Fixnum, Float, Bignum
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 Fixnum, Float, Bignum
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 ( other.class != RMtx2 )
444
- raise TypeError, "RMtx2#==(other) : Unknown type #{other.class} given as RMtx2."
445
- return nil
446
- end
447
-
448
- for row in 0...2 do
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 Fixnum, Float, Bignum
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 Fixnum, Float
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 Fixnum, Float
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 Fixnum, Float, Bignum
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 Fixnum, Float, Bignum
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 ( other.class != RMtx3 )
1133
- raise TypeError, "RMtx3#==(other) : Unknown type #{other.class} given as RMtx3."
1134
- return nil
1135
- end
1136
-
1137
- for row in 0...3 do
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 Fixnum, Float, Bignum
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 Fixnum, Float
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 Fixnum, Float
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 Fixnum, Float, Bignum
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: perspectiveRH(width,height,znear,zfar) -> self
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 perspectiveRH( width, height, znear, zfar )
1885
- perspectiveOffCenterRH(-width/2.0, width/2.0, -height/2.0, height/2.0, znear, zfar )
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: perspectiveFovRH(fovy,aspect,znear,zfar) -> self
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 perspectiveFovRH( fovy_radian, aspect, znear, zfar )
1899
- f = Math::tan( fovy_radian / 2.0 )
1900
- f = 1.0 / f
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
- setElement( 0, 0, f / aspect )
1904
- setElement( 1, 1, f )
1905
- setElement( 2, 2, (zfar+znear)/(znear-zfar) )
1906
- setElement( 2, 3, 2*zfar*znear/(znear-zfar) )
1907
- setElement( 3, 2, -1.0 )
1908
- setElement( 3, 3, 0.0 )
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
- setIdentity()
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 Fixnum, Float, Bignum
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 ( other.class != RMtx4 )
2085
- raise TypeError, "RMtx4#==(other) : Unknown type #{other.class} given as RMtx4."
2086
- return nil
2087
- end
2088
-
2089
- for row in 0...4 do
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 Fixnum, Float, Bignum
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 Fixnum, Float
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 Fixnum, Float
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]} )\n"
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 Fixnum, Float, Bignum
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 Fixnum, Float
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 != RQuat
2634
- raise TypeError, "RQuat#== : Unknown type #{other.class}."
2635
- return nil
2636
- end
2637
-
2638
- if (x-other.x).abs<=Float::EPSILON &&
2639
- (y-other.y).abs<=Float::EPSILON &&
2640
- (z-other.z).abs<=Float::EPSILON &&
2641
- (w-other.w).abs<=Float::EPSILON
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 Fixnum, Float
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 Fixnum, Float
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 Fixnum, Float
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]} )\n"
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 Fixnum, Float, Bignum
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 Fixnum, Float
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 != RVec2
3085
- raise TypeError, "RVec2#== : Unknown type #{other.class}."
3086
- return nil
3087
- end
3088
-
3089
- if (x-other.x).abs<=Float::EPSILON &&
3090
- (y-other.y).abs<=Float::EPSILON
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 != Fixnum && arg.class != Float
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 Fixnum, Float
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 Fixnum, Float
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]} )\n"
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 Fixnum, Float, Bignum
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 Fixnum, Float
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 != RVec3
3639
- raise TypeError, "RVec3#== : Unknown type #{other.class}."
3640
- return nil
3641
- end
3642
-
3643
- if (x-other.x).abs<=Float::EPSILON &&
3644
- (y-other.y).abs<=Float::EPSILON &&
3645
- (z-other.z).abs<=Float::EPSILON
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 != Fixnum && arg.class != Float
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 Fixnum, Float
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 Fixnum, Float
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]} )\n"
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 Fixnum, Float, Bignum
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 Fixnum, Float
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 != RVec4
4086
- raise TypeError, "RVec4#== : Unknown type #{other.class}."
4087
- return nil
4088
- end
4089
-
4090
- if (x-other.x).abs<=Float::EPSILON &&
4091
- (y-other.y).abs<=Float::EPSILON &&
4092
- (z-other.z).abs<=Float::EPSILON &&
4093
- (w-other.w).abs<=Float::EPSILON
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 != Fixnum && other.class != Float
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]
@@ -1,4 +1,4 @@
1
- begin
1
+ begin
2
2
  require 'rmath3d/rmath3d'
3
3
  rescue LoadError
4
4
  require 'rmath3d/rmath3d_plain'
@@ -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, 0.0,
544
- 0.0, f, 0.0, 0.0,
545
- 0.0, 0.0, (z_f+z_n)/(z_n-z_f), 2*z_f*z_n/(z_n-z_f),
546
- 0.0, 0.0, -1.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), m2.getElement(r,c), @tolerance )
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.1.0
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: 2015-04-12 00:00:00.000000000 Z
11
+ date: 2020-07-23 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: |
14
- Provides vector2/3/4, matrix2x2/3x3/4x4 and quaternion in plain Ruby form.
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
- - zlib/libpng
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: '0'
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
- rubyforge_project:
56
- rubygems_version: 2.4.6
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: []