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 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: []