Method: Mittsu::Ray#intersect_box

Defined in:
lib/mittsu/math/ray.rb

#intersect_box(box, target = Mittsu::Vector3.new) ⇒ Object



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/mittsu/math/ray.rb', line 192

def intersect_box(box, target = Mittsu::Vector3.new)
  # http:#www.scratchapixel.com/lessons/3d-basic-lessons/lesson-7-intersecting-simple-shapes/ray-box-intersection/
  invdirx = 1.0 / @direction.x
  invdiry = 1.0 / @direction.y
  invdirz = 1.0 / @direction.z
  origin = @origin
  if invdirx >= 0
    tmin = (box.min.x - origin.x) * invdirx
    tmax = (box.max.x - origin.x) * invdirx
  else
    tmin = (box.max.x - origin.x) * invdirx
    tmax = (box.min.x - origin.x) * invdirx
  end
  if invdiry >= 0
    tymin = (box.min.y - origin.y) * invdiry
    tymax = (box.max.y - origin.y) * invdiry
  else
    tymin = (box.max.y - origin.y) * invdiry
    tymax = (box.min.y - origin.y) * invdiry
  end
  return nil if tmin > tymax || tymin > tmax
  # These lines also handle the case where tmin or tmax is NaN
  # (result of 0 * Infinity). x != x returns true if x is NaN
  tmin = tymin if tymin > tmin || tmin != tmin
  tmax = tymax if tymax < tmax || tmax != tmax
  if invdirz >= 0
    tzmin = (box.min.z - origin.z) * invdirz
    tzmax = (box.max.z - origin.z) * invdirz
  else
    tzmin = (box.max.z - origin.z) * invdirz
    tzmax = (box.min.z - origin.z) * invdirz
  end
  return nil if tmin > tzmax || tzmin > tmax
  tmin = tzmin if tzmin > tmin || tmin != tmin
  tmax = tzmax if tzmax < tmax || tmax != tmax
  #return point closest to the ray (positive side)
  return nil if tmax < 0
  self.at(tmin >= 0 ? tmin : tmax, target)
end