rmath3d_plain 1.2.3 → 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
2
  SHA256:
3
- metadata.gz: 4afeec14769aedc4dc064924600f42123b7db3001dd1d9b04887ea72226a6e62
4
- data.tar.gz: 65f26f341e1c5c13e2e1971131132c7d641e1ac2cc1ee1abc1cc9a92c47f2731
3
+ metadata.gz: 569f5334bd7df6cf7e0f7a857ae589bc8258b0940913807ebaa2dcae60bf711e
4
+ data.tar.gz: 5f5cf50b25ad23c0a51574f6a4d83ac45cfc820e9c5a337591d66a7574c47145
5
5
  SHA512:
6
- metadata.gz: dc52e86e9d990b0bfe033c399dbcf5da0b2eefd2309b37ce539bfaf420c58fbd8a526e4723c511d92ab5f473ea7257a696126f39b79606342dcfb91840273759
7
- data.tar.gz: a197442846a593aa7d54a63609aa9ba3eebebdd6a2fa7b984def5741f077ec3e6322770164d2e200718769635f24a1cd58b3cc1ceb5a9bf1770336e81d7a822a
6
+ metadata.gz: 13a0b47c640f875de55331962edc75ee9f48f43554e196b98073c297b7ebf6f02e47449c0280f4f9a377a281d0c2607a154a37838cdbaf2d90aa6536a7429c72
7
+ data.tar.gz: da55b4c5ed4322637162396c67ff45d2f2c870ec7242592309d9bc31dce68e9b3014449bc4f781cde6754cc02e1ce5f5aacbcb98f57cbe867d031dc37a07338d
data/ChangeLog CHANGED
@@ -1,3 +1,7 @@
1
+ 2020-07-23 vaiorabbit <http://twitter.com/vaiorabbit>
2
+
3
+ * rmath3d.c, rmath3d_plain.rb (RMtx4): Added lookAtLH, perspectiveLH, etc.
4
+
1
5
  2020-06-21 vaiorabbit <http://twitter.com/vaiorabbit>
2
6
 
3
7
  * rmath3d.c, rmath3d_plain.rb (RMtx4): Added argument 'ndc_homogeneous' for projection matrix APIs.
File without changes
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  rmath3d is a math module for 3D game programming and computer graphics.
6
6
 
7
- * Last Update: Jun 21, 2020
7
+ * Last Update: Jul 23, 2020
8
8
  * Since: Jul 20, 2008
9
9
 
10
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)
@@ -33,14 +33,8 @@ rmath3d is a math module for 3D game programming and computer graphics.
33
33
  Notice: This library provides native extension. You must setup develop environment (or DevKit) before installation.
34
34
 
35
35
  * Ruby
36
- * ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-darwin12.4.0]
37
- * ruby 2.0.0p247 (2013-06-27) [i386-mingw32] With Development Kit installed.
38
- * I used: DevKit-mingw64-32-4.7.2-20130224-1151-sfx.exe
39
- * Unpack the archive -> "> ruby dk.rb init" -> edit config.yml (just add your ruby foldier) -> "> ruby dk.rb install"
40
- * Ref.: http://blog.mattwynne.net/2010/10/12/installing-ruby-gems-with-native-extensions-on-windows/
41
- * ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin14]
42
- * Ruby 1.9.3 and prior versions are no longer supported.
43
- * Ref.: https://www.ruby-lang.org/en/news/2015/02/23/support-for-ruby-1-9-3-has-ended/
36
+ * ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x64-mingw32]
37
+ * Ruby 2.3 and prior versions are no longer supported.
44
38
 
45
39
  ## Building rmath3d.{so|bundle} ##
46
40
 
@@ -1904,7 +1904,7 @@ module RMath3D
1904
1904
  end
1905
1905
 
1906
1906
  #
1907
- # call-seq: perspectiveRH(width,height,znear,zfar,ndc_convention) -> self
1907
+ # call-seq: perspectiveLH(width,height,znear,zfar,ndc_convention) -> self
1908
1908
  #
1909
1909
  # Builds a perspective projection matrix for a right-handed coordinate system from:
1910
1910
  # * View volume width (+width+)
@@ -1913,13 +1913,12 @@ module RMath3D
1913
1913
  # * Far clip plane distance (+zfar+)
1914
1914
  # * Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (+ndc_homogeneous+)
1915
1915
  #
1916
- def perspectiveRH( width, height, znear, zfar, ndc_homogeneous = true)
1917
- perspectiveOffCenterRH(-width/2.0, width/2.0, -height/2.0, height/2.0, znear, zfar, ndc_homogeneous )
1918
- 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 )
1919
1918
  end
1920
1919
 
1921
1920
  #
1922
- # call-seq: perspectiveFovRH(fovy,aspect,znear,zfar,ndc_homogeneous) -> self
1921
+ # call-seq: perspectiveFovLH(fovy,aspect,znear,zfar,ndc_homogeneous) -> self
1923
1922
  #
1924
1923
  # Builds a perspective projection matrix for a right-handed coordinate system from:
1925
1924
  # * Field of view in y direction (+fovy+ radian)
@@ -1928,24 +1927,123 @@ module RMath3D
1928
1927
  # * Far clip plane distance (+zfar+)
1929
1928
  # * Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (+ndc_homogeneous+)
1930
1929
  #
1931
- def perspectiveFovRH( fovy_radian, aspect, znear, zfar, ndc_homogeneous = true)
1932
- f = Math::tan( fovy_radian / 2.0 )
1933
- f = 1.0 / f
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
1934
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)
1935
1954
  c = ndc_homogeneous ? -(zfar+znear) / (zfar-znear) : -zfar / (zfar-znear)
1936
1955
  d = ndc_homogeneous ? -(2*znear*zfar) / (zfar-znear) : -(znear*zfar) / (zfar-znear)
1937
1956
 
1938
- setIdentity()
1939
- setElement( 0, 0, f / aspect )
1940
- setElement( 1, 1, f )
1941
- setElement( 2, 2, c )
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 )
1942
1964
  setElement( 2, 3, d )
1943
- setElement( 3, 2, -1.0 )
1944
- setElement( 3, 3, 0.0 )
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+)
1979
+ #
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)
2001
+
2002
+ setIdentity()
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 )
1945
2010
 
1946
2011
  return self
1947
2012
  end
1948
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
+
1949
2047
  #
1950
2048
  # call-seq: perspectiveOffCenterRH(left,right,bottom,top,znear,zfar) -> self
1951
2049
  #
@@ -1964,7 +2062,7 @@ module RMath3D
1964
2062
  c = ndc_homogeneous ? -(zfar+znear) / (zfar-znear) : -zfar / (zfar-znear)
1965
2063
  d = ndc_homogeneous ? -(2*znear*zfar) / (zfar-znear) : -(znear*zfar) / (zfar-znear)
1966
2064
 
1967
- setIdentity()
2065
+ setZero()
1968
2066
 
1969
2067
  setElement( 0, 0, 2*znear/(right-left) )
1970
2068
  setElement( 0, 2, a )
@@ -1973,7 +2071,6 @@ module RMath3D
1973
2071
  setElement( 2, 2, c )
1974
2072
  setElement( 2, 3, d )
1975
2073
  setElement( 3, 2, -1.0 )
1976
- setElement( 3, 3, 0.0 )
1977
2074
 
1978
2075
  return self
1979
2076
  end
@@ -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)
@@ -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 )
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 )
547
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
 
@@ -572,6 +595,67 @@ class TC_RMtx4 < Minitest::Test
572
595
  end
573
596
  end
574
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 )
651
+
652
+ for r in 0...4 do
653
+ for c in 0...4 do
654
+ assert_in_delta( m4.getElement(r,c), m5.getElement(r,c), @tolerance )
655
+ end
656
+ end
657
+ end
658
+
575
659
  # http://pyopengl.sourceforge.net/documentation/manual/glOrtho.3G.xml
576
660
  def test_orthoRH
577
661
  left = -640.0
@@ -616,6 +700,49 @@ class TC_RMtx4 < Minitest::Test
616
700
  end
617
701
  end
618
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 )
738
+
739
+ for r in 0...4 do
740
+ for c in 0...4 do
741
+ assert_in_delta( m2.getElement(r,c), m3.getElement(r,c), @tolerance )
742
+ end
743
+ end
744
+ end
745
+
619
746
  def test_unary_operators
620
747
  # RMtx4#+@
621
748
  m0 = RMtx4.new( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 )
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rmath3d_plain
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 1.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - vaiorabbit
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-21 00:00:00.000000000 Z
11
+ date: 2020-07-23 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: 'Provides vector2/3/4, matrix2x2/3x3/4x4 and quaternion in plain Ruby
14
14
  form.