geo3d 0.0.9 → 0.1.0

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
  SHA1:
3
- metadata.gz: e792232f7a90e668e5cae09575b15574c33c0b30
4
- data.tar.gz: 18ccd86ed62ef23860e8bd4bc650958b0401836f
3
+ metadata.gz: 41c051605a8dd60b857e28eb5cd761dee1945f71
4
+ data.tar.gz: 5637c0862c56ad4f92f3491575b866c0e4719713
5
5
  SHA512:
6
- metadata.gz: 048b7fb31747320c8024580e1381b630540442a1810089a9a6b49a94060140b0e8cb56e105927de9c6b15cdacda5e4a753934e2e42578979fb6763b7714a85b1
7
- data.tar.gz: 119f28b82c0ed685bbf834e215b80501855520e848daf6a9a2f63e289c768116ead912585fec145d277e30213e0d78b0ae55d60b7e77d37f86aee47d1d981429
6
+ metadata.gz: 140091ea429a7e8385668e197194b1300b83c0eefe2a9306699f85208be9e94c81aa06b936dd8eb81db2f98e69a2af16c0cde94200b0a3acadc5a5e55c83c1f7
7
+ data.tar.gz: 57abc21c5d11b25311eca919b83d0b201bf695faf5c50465eac9fd29c63fb22d005520f200175f0dc4468ea9e8e58c6d112dbe96cfeca38a3fbaae42df51895a
data/README.md CHANGED
@@ -87,7 +87,11 @@ Linear Interpolation
87
87
  ```
88
88
  vec_a.lerp vec_b, 0.4 #returns a new vector which is the 40% linear interpolation between vec_a and vec_b
89
89
  ```
90
-
90
+ Screenspace projections
91
+ ```
92
+ vec.project viewport, projection, view, world #transform an objectspace vertex to screenspace
93
+ vec.unproject viewport, projection, view, world #transform a screenspace vertex to objectspace
94
+ ```
91
95
 
92
96
  ## Matrix
93
97
 
@@ -160,18 +164,26 @@ Rotation
160
164
  angle = 0.9
161
165
  Geo3d::Matrix.rotation axis, angle #rotate about an arbitrary axis
162
166
  ```
163
- Projection matrix constructors
167
+ Projection matrix constructors ala Direct3D (clip space has a range of 0 to 1)
164
168
  ```
165
169
  Geo3d::Matrix.perspective_fov_rh fovy, aspect, z_near, z_far #returns a right handed perspective projection matrix
166
170
  Geo3d::Matrix.perspective_fov_lh fovy, aspect, z_near, z_far #returns a left handed perspective projection matrix
167
171
  Geo3d::Matrix.ortho_off_center_rh left, right, bottom, top, z_near, z_far #returns a right handed orthographic projection matrix
168
172
  Geo3d::Matrix.ortho_off_center_lh left, right, bottom, top, z_near, z_far #returns a left handed orthographic projection matrix
169
173
  ```
174
+ Projection matrix constructors ala OpenGL (clip space has a range of -1 to 1)
175
+ ```
176
+ Geo3d::Matrix.glu_perspective_degrees fovy, aspect, zn, zf #returns an opengl style right handed projection matrix
177
+ ```
170
178
  View matrix constructors
171
179
  ```
172
180
  Geo3d::Matrix.look_at_rh eye_position, look_at_position, up_direction #returns a right handed view matrix
173
181
  Geo3d::Matrix.look_at_lh eye_position, look_at_position, up_direction #returns a left handed view matrix
174
182
  ```
183
+ Viewport matrix constructors
184
+ ```
185
+ Geo3d::Matrix.viewport x, y, width, height
186
+ ```
175
187
  Misc constructors
176
188
  ```
177
189
  Geo3d::Matrix.reflection reflection_plane #returns a reflection matrix where reflection_plane is a Geo3d::Vector that corresponds to the normal of the plane
@@ -1,3 +1,3 @@
1
1
  module Geo3d
2
- VERSION = "0.0.9"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -471,7 +471,7 @@ module Geo3d
471
471
  matrix = self.new
472
472
  matrix._11 = 2.0 * zn / (r-l)
473
473
  matrix._31 = a
474
- matrix._22 = 2.0 * zn / (t-b) #todo: the man page says multiply this by two, but I don't actually match what glFrustum does if I do
474
+ matrix._22 = zn / (t-b) #todo: the man page says multiply this by two, but I don't actually match what glFrustum does if I do
475
475
  matrix._32 = b
476
476
  matrix._33 = c
477
477
  matrix._43 = d
@@ -609,6 +609,11 @@ module Geo3d
609
609
  matrix
610
610
  end
611
611
 
612
+
613
+ def self.viewport x, y, width, height
614
+ self.scaling(width.to_f / 2.0, height.to_f / 2.0, 0.5) * self.translation(x.to_f + width.to_f / 2.0, y.to_f + height.to_f / 2.0, 0.5)
615
+ end
616
+
612
617
  def self.reflection reflection_plane
613
618
  reflection_plane = Geo3d::Vector.new *reflection_plane.to_a
614
619
  reflection_matrix = self.new
@@ -673,20 +678,20 @@ module Geo3d
673
678
 
674
679
  def self.translation x, y, z
675
680
  translation_matrix = self.new
676
- translation_matrix._11 = translation_matrix._22 = translation_matrix._33 = translation_matrix._44 = 1
681
+ translation_matrix._11 = translation_matrix._22 = translation_matrix._33 = translation_matrix._44 = 1.0
677
682
  #todo: consider simplifying with identity
678
- translation_matrix._41 = x
679
- translation_matrix._42 = y
680
- translation_matrix._43 = z
683
+ translation_matrix._41 = x.to_f
684
+ translation_matrix._42 = y.to_f
685
+ translation_matrix._43 = z.to_f
681
686
  translation_matrix
682
687
  end
683
688
 
684
689
  def self.scaling x, y, z
685
690
  scaling_matrix = self.new
686
- scaling_matrix._11 = x
687
- scaling_matrix._22 = y
688
- scaling_matrix._33 = z
689
- scaling_matrix._44 = 1
691
+ scaling_matrix._11 = x.to_f
692
+ scaling_matrix._22 = y.to_f
693
+ scaling_matrix._33 = z.to_f
694
+ scaling_matrix._44 = 1.0
690
695
  scaling_matrix
691
696
  end
692
697
 
@@ -114,6 +114,18 @@ module Geo3d
114
114
  l.w = w + (vec.w - w)*s
115
115
  l
116
116
  end
117
+
118
+ def project viewport, projection, view, world
119
+ clipspace_vector = projection * view * world * one_w
120
+ normalized_clipspace_vector = (clipspace_vector / clipspace_vector.w.to_f).one_w
121
+ viewport * normalized_clipspace_vector
122
+ end
123
+
124
+ def unproject viewport, projection, view, world
125
+ normalized_clipspace_vector = viewport.inverse * one_w
126
+ almost_objectspace_vector = (projection * view * world).inverse * normalized_clipspace_vector.one_w
127
+ (almost_objectspace_vector / almost_objectspace_vector.w).one_w
128
+ end
117
129
  end
118
130
  end
119
131
 
@@ -91,5 +91,45 @@ describe Geo3d::Matrix do
91
91
  end
92
92
  end
93
93
 
94
+ it "should project a vector the same way gluProject does" do
95
+ viewport_data = {:x => 0, :y => 0, :width => 640, :height => 480}
96
+ projection_data = {:fovy_in_degrees => 60.0, :width => 640.0, :height => 480.0, :near => 0.1, :far => 1000.0}
97
+ view_data = {:eye => [1.0, 0.0, 0.0], :focus => [200.0, -40.0, -100.0], :up => [0.0, 1.0, 0.0]}
98
+ eye = Geo3d::Vector.new *view_data[:eye]
99
+ focus = Geo3d::Vector.new *view_data[:focus]
100
+ up = Geo3d::Vector.new *view_data[:up]
101
+
102
+
103
+ viewport_matrix = Geo3d::Matrix.viewport viewport_data[:x], viewport_data[:y], viewport_data[:width], viewport_data[:height]
104
+ projection_matrix = Geo3d::Matrix.glu_perspective_degrees(projection_data[:fovy_in_degrees], projection_data[:width].to_f/projection_data[:height].to_f, projection_data[:near], projection_data[:far])
105
+ view_matrix = Geo3d::Matrix.look_at_rh(eye, focus, up)
106
+
107
+ vector = Geo3d::Vector.new 300, 100, -500
108
+
109
+ glu_vector = gluProject vector.x, vector.y, vector.z, projection_matrix.to_a, view_matrix.to_a, [viewport_data[:x], viewport_data[:y], viewport_data[:width], viewport_data[:height]]
110
+
111
+ puts "glu vect is #{glu_vector.inspect}"
112
+ Geo3d::Vector.new(*glu_vector).should == vector.project(viewport_matrix, projection_matrix, view_matrix, Geo3d::Matrix.identity).zero_w
113
+ end
114
+
115
+ it "should unproject a vector the same way gluUnproject does" do
116
+ viewport_data = {:x => 0, :y => 0, :width => 640, :height => 480}
117
+ projection_data = {:fovy_in_degrees => 60.0, :width => 640.0, :height => 480.0, :near => 0.1, :far => 1000.0}
118
+ view_data = {:eye => [1.0, 0.0, 0.0], :focus => [200.0, -40.0, -100.0], :up => [0.0, 1.0, 0.0]}
119
+ eye = Geo3d::Vector.new *view_data[:eye]
120
+ focus = Geo3d::Vector.new *view_data[:focus]
121
+ up = Geo3d::Vector.new *view_data[:up]
122
+
123
+
124
+ viewport_matrix = Geo3d::Matrix.viewport viewport_data[:x], viewport_data[:y], viewport_data[:width], viewport_data[:height]
125
+ projection_matrix = Geo3d::Matrix.glu_perspective_degrees(projection_data[:fovy_in_degrees], projection_data[:width].to_f/projection_data[:height].to_f, projection_data[:near], projection_data[:far])
126
+ view_matrix = Geo3d::Matrix.look_at_rh(eye, focus, up)
127
+
128
+ vector = Geo3d::Vector.new 574.1784279190967, 294.42147391181595, 0.8485367205965038
129
+
130
+ glu_vector = gluUnProject vector.x, vector.y, vector.z, projection_matrix.to_a, view_matrix.to_a, [viewport_data[:x], viewport_data[:y], viewport_data[:width], viewport_data[:height]]
131
+ Geo3d::Vector.new(*glu_vector).should == vector.unproject(viewport_matrix, projection_matrix, view_matrix, Geo3d::Matrix.identity).zero_w
132
+ end
133
+
94
134
 
95
135
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: geo3d
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Misha Conway
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-19 00:00:00.000000000 Z
11
+ date: 2014-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler