rray 0.1.0 → 0.2.0

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
2
  SHA256:
3
- metadata.gz: 8524e60bb5c72619ed588acd7778faf1c4164b93928094d9c75379e3315a1897
4
- data.tar.gz: ad9f79b082e057ff74b555672bbc7a11082fda5339353506efa1e004003642a3
3
+ metadata.gz: c1f6b0d451c5f0098de3d1aaf967766038c58b622dab31a26b3d4400a28c72bd
4
+ data.tar.gz: 97a44a8efa2be4a28e81b6dcf10de54646bb034787326787e3d6925fe79afab8
5
5
  SHA512:
6
- metadata.gz: f64cf7f310538afd73185ebc926ad928ee727752160012d6d506149a9e1433d1486579ffb8b51ab8fd6385aafc4d5a8b656d41dadcb59cf95babe97789eccdbd
7
- data.tar.gz: 9379ec81d4072e789115fd3534570733d0cd1d29fa5636e4a67e4f0e6f377e5414fa62fe66dc2cbc4872165cc6c78b85c50c2cb611d7f1a6098998b4f48e8b8b
6
+ metadata.gz: 50d401573d8e62609cd940451580269fe0f153d086217153f9a3ca9ec571e1ddb0c28a456adb0ae9c55661b67c5733dab4e4b81817290b950618ca475c4d9ed9
7
+ data.tar.gz: 0d46651fc158a7cef699a2b4371a0a5892df107c1f0f5c8a93778b7f03fd76a63706a175d4775a6ebc28b55ad428ae601463802a1519b33e42ef9392f190d508
data/lib/rray/aabb.rb ADDED
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './interval'
4
+
5
+ module Rray
6
+ class AABB
7
+ attr_accessor :x, :y, :z
8
+
9
+ # The default AABB is empty, since intervals are empty by default.
10
+ def initialize(x = Interval.new, y = Interval.new, z = Interval.new)
11
+ @x = x
12
+ @y = y
13
+ @z = z
14
+ end
15
+
16
+ # Treat the two points a and b as extrema for the bounding box, so we don't require a
17
+ # particular minimum/maximum coordinate order.
18
+ def self.from_points(a, b)
19
+ new(
20
+ a.x < b.x ? Interval.new(a.x, b.x) : Interval.new(b.x, a.x),
21
+ a.y < b.y ? Interval.new(a.y, b.y) : Interval.new(b.y, a.y),
22
+ a.z < b.z ? Interval.new(a.z, b.z) : Interval.new(b.z, a.z)
23
+ )
24
+ end
25
+
26
+ def self.from_aabbs(box0, box1)
27
+ new(
28
+ Interval.from_intervals(box0.x, box1.x),
29
+ Interval.from_intervals(box0.y, box1.y),
30
+ Interval.from_intervals(box0.z, box1.z)
31
+ )
32
+ end
33
+
34
+ def [](n)
35
+ case n
36
+ when 0 then x
37
+ when 1 then y
38
+ when 2 then z
39
+ end
40
+ end
41
+
42
+ def hit(r, ray_t)
43
+ t = Interval.from_range(ray_t)
44
+
45
+ (0...3).each do |axis|
46
+ ax = self[axis]
47
+ adinv = 1.0 / r.direction[axis]
48
+
49
+ t0 = (ax.min - r.origin[axis]) * adinv
50
+ t1 = (ax.max - r.origin[axis]) * adinv
51
+
52
+ if t0 < t1
53
+ t.min = t0 if t0 > t.min
54
+ t.max = t1 if t1 < t.max
55
+ else
56
+ t.min = t1 if t1 > t.min
57
+ t.max = t0 if t0 < t.max
58
+ end
59
+
60
+ return false if t.max <= t.min
61
+ end
62
+
63
+ true
64
+ end
65
+
66
+ # Returns the index of the longest axis of the bounding box.
67
+ def longest_axis
68
+ if x.size > y.size
69
+ x.size > z.size ? 0 : 2
70
+ else
71
+ y.size > z.size ? 1 : 2
72
+ end
73
+ end
74
+
75
+ EMPTY = new(Interval::EMPTY, Interval::EMPTY, Interval::EMPTY)
76
+ UNIVERSE = new(Interval::UNIVERSE, Interval::UNIVERSE, Interval::UNIVERSE)
77
+ end
78
+ end
data/lib/rray/camera.rb CHANGED
@@ -66,15 +66,27 @@ module Rray
66
66
  # Construct a camera ray originating from the defocus disk and directed at a randomly
67
67
  # sampled point around the pixel location x, y.
68
68
  def ray(x, y)
69
- offset = Util.sample_square
69
+ offset = Vec3.sample_square
70
70
  pixel_sample = pixel00_loc +
71
71
  (pixel_delta_u * (x + offset.x)) +
72
72
  (pixel_delta_v * (y + offset.y))
73
73
 
74
74
  ray_origin = defocus_angle <= 0 ? center : defocus_disk_sample
75
75
  ray_direction = pixel_sample - ray_origin
76
+ ray_time = rand
76
77
 
77
- Ray.new(ray_origin, ray_direction)
78
+ Ray.new(ray_origin, ray_direction, ray_time)
79
+ end
80
+
81
+ def export
82
+ {
83
+ vfov: vfov,
84
+ lookfrom: lookfrom.to_a,
85
+ lookat: lookat.to_a,
86
+ vup: vup.to_a,
87
+ defocus_angle: defocus_angle,
88
+ focus_dist: focus_dist
89
+ }
78
90
  end
79
91
 
80
92
  private
data/lib/rray/hit.rb CHANGED
@@ -2,14 +2,14 @@
2
2
 
3
3
  module Rray
4
4
  class Hit
5
- attr_accessor :point, :normal, :t, :mat, :front_face
5
+ attr_accessor :point, :normal, :t, :material, :front_face
6
6
 
7
- def initialize(point, r, outward_normal, t, mat)
7
+ def initialize(point, r, outward_normal, t, material)
8
8
  @point = point
9
9
  @t = t
10
- @mat = mat
10
+ @material = material
11
11
 
12
- # Sets the hit record normal vector.
12
+ # Sets the hit's normal vector.
13
13
  # NOTE: the parameter `outward_normal` is assumed to have unit length.
14
14
 
15
15
  @front_face = r.direction.dot(outward_normal) < 0
data/lib/rray/interval.rb CHANGED
@@ -4,11 +4,24 @@ module Rray
4
4
  class Interval
5
5
  attr_accessor :min, :max
6
6
 
7
- def initialize(min, max)
7
+ # Default interval is empty
8
+ def initialize(min = Float::INFINITY, max = -Float::INFINITY)
8
9
  @min = min
9
10
  @max = max
10
11
  end
11
12
 
13
+ def self.from_range(r)
14
+ new(r.min, r.max)
15
+ end
16
+
17
+ # Create the interval tightly enclosing the two input intervals.
18
+ def self.from_intervals(a, b)
19
+ new(
20
+ a.min <= b.min ? a.min : b.min,
21
+ a.max >= b.max ? a.max : b.max
22
+ )
23
+ end
24
+
12
25
  def size = max - min
13
26
  def include?(x) = min <= x && x <= max
14
27
  def surround?(x) = min < x && x < max
@@ -19,6 +32,15 @@ module Rray
19
32
  x
20
33
  end
21
34
 
35
+ def expand(delta)
36
+ padding = delta / 2.0
37
+ Interval.new(min - padding, max + padding)
38
+ end
39
+
40
+ def dup
41
+ Interval.new(min, max)
42
+ end
43
+
22
44
  EMPTY = new(Float::INFINITY, -Float::INFINITY)
23
45
  UNIVERSE = new(-Float::INFINITY, Float::INFINITY)
24
46
  end
@@ -3,9 +3,21 @@
3
3
  module Rray
4
4
  module Material
5
5
  class Base
6
+ def id
7
+ "#{type.downcase}-#{object_id.to_s(16)}"
8
+ end
9
+
10
+ def type
11
+ self.class.name.split('::').last
12
+ end
13
+
6
14
  def scatter(r_in, rec)
7
15
  raise NotImplementedError, "Implement #{self.class}#scatter"
8
16
  end
17
+
18
+ def export
19
+ raise NotImplementedError, "Implement #{self.class.name}#export"
20
+ end
9
21
  end
10
22
  end
11
23
  end
@@ -26,17 +26,24 @@ module Rray
26
26
  unit_direction.refract(rec.normal, ri)
27
27
  end
28
28
 
29
- scattered = Ray.new(rec.point, direction)
29
+ scattered = Ray.new(rec.point, direction, r_in.time)
30
30
 
31
31
  Scatter.new(scattered, attenuation)
32
32
  end
33
33
 
34
+ def export
35
+ {
36
+ type: "Dielectric",
37
+ refraction_index: refraction_index
38
+ }
39
+ end
40
+
34
41
  private
35
42
 
36
43
  def reflectance(cosine, ri)
37
44
  # Use Schlick's approximation for reflectance.
38
45
  r0 = ((1.0 - ri) / (1.0 + ri))**2
39
- r0 + (1-r0)*(1.0-cosine)**5
46
+ r0 + (1.0-r0)*(1.0-cosine)**5
40
47
  end
41
48
  end
42
49
  end
@@ -11,13 +11,20 @@ module Rray
11
11
 
12
12
  def scatter(r_in, rec)
13
13
  scatter_direction = rec.normal + Vec3.random_unit_vector
14
- scattered = Ray.new(rec.point, scatter_direction)
14
+ scattered = Ray.new(rec.point, scatter_direction, r_in.time)
15
15
 
16
16
  # Catch degenerate scatter direction
17
17
  scatter_direction = rec.normal if scatter_direction.zero?
18
18
 
19
19
  Scatter.new(scattered, albedo)
20
20
  end
21
+
22
+ def export
23
+ {
24
+ type: "Lambertian",
25
+ albedo: albedo.to_a
26
+ }
27
+ end
21
28
  end
22
29
  end
23
30
  end
@@ -13,11 +13,19 @@ module Rray
13
13
  def scatter(r_in, rec)
14
14
  reflected = r_in.direction.reflect(rec.normal)
15
15
  reflected = reflected.normalize.add(Vec3.random_unit_vector.mul(fuzz))
16
- scattered = Ray.new(rec.point, reflected)
16
+ scattered = Ray.new(rec.point, reflected, r_in.time)
17
17
  return nil if scattered.direction.dot(rec.normal) <= 0
18
18
 
19
19
  Scatter.new(scattered, albedo)
20
20
  end
21
+
22
+ def export
23
+ {
24
+ type: "Metal",
25
+ albedo: albedo.to_a,
26
+ fuzz: fuzz
27
+ }
28
+ end
21
29
  end
22
30
  end
23
31
  end
@@ -3,9 +3,25 @@
3
3
  module Rray
4
4
  module Object
5
5
  class Base
6
+ def id
7
+ "#{type.downcase}-#{object_id.to_s(16)}"
8
+ end
9
+
10
+ def type
11
+ self.class.name.split('::').last
12
+ end
13
+
6
14
  def hit(r, ray_t)
7
15
  raise NotImplementedError, "Implement #{self.class.name}#hit"
8
16
  end
17
+
18
+ def export
19
+ raise NotImplementedError, "Implement #{self.class.name}#export"
20
+ end
21
+
22
+ def bounding_box
23
+ raise NotImplementedError, "Implement #{self.class.name}#bounding_box"
24
+ end
9
25
  end
10
26
  end
11
27
  end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rray
4
+ module Object
5
+ class BVH < Base
6
+ attr_reader :bounding_box
7
+
8
+ def initialize(objects)
9
+ @bounding_box = AABB::EMPTY
10
+ objects.each do |object|
11
+ @bounding_box = AABB.from_aabbs(@bounding_box, object.bounding_box)
12
+ end
13
+
14
+ axis = @bounding_box.longest_axis
15
+
16
+ case objects.length
17
+ when 1
18
+ @left = @right = objects[0]
19
+ when 2
20
+ @left = objects[0]
21
+ @right = objects[1]
22
+ else
23
+ objects.sort_by! { _1.bounding_box[axis].min }
24
+ mid = objects.length / 2
25
+ @left = BVH.new(objects[0...mid])
26
+ @right = BVH.new(objects[mid..])
27
+ end
28
+ end
29
+
30
+ def hit(r, ray_t)
31
+ return nil unless bounding_box.hit(r, ray_t)
32
+
33
+ hit_left = @left.hit(r, ray_t)
34
+ hit_right = @right.hit(r, ray_t.min..(hit_left&.t || ray_t.max))
35
+
36
+ hit_right || hit_left
37
+ end
38
+
39
+ def export
40
+ raise NotImplementedError, "Cannot export BVH, perhaps you meant to use a group?"
41
+ end
42
+
43
+ def to_s(depth=0)
44
+ indent = " "*depth
45
+ "#{indent}BVH {\n" +
46
+ "#{indent} left=\n"+
47
+ "#{@left.to_s(depth+2)}\n"+
48
+ "#{indent} right=\n"+
49
+ "#{@right.to_s(depth+2)}\n"+
50
+ "#{indent}}"
51
+ end
52
+ end
53
+ end
54
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative './bvh'
4
+
3
5
  module Rray
4
6
  module Object
5
7
  class Group < Base
@@ -7,25 +9,35 @@ module Rray
7
9
 
8
10
  def initialize(objects = [])
9
11
  @objects = objects
12
+ @bvh = BVH.new(objects)
10
13
  end
11
14
 
12
15
  def <<(object)
13
16
  objects << object
17
+ @bvh = BVH.new(objects)
18
+ object
14
19
  end
15
20
 
16
21
  def hit(r, ray_t)
17
- rec = nil
18
- closest_so_far = ray_t.end
22
+ @bvh.hit(r, ray_t)
23
+ end
19
24
 
20
- objects.each do |object|
21
- temp_rec = object.hit(r, ray_t.begin..closest_so_far)
22
- next unless temp_rec
25
+ def bounding_box
26
+ @bvh.bounding_box
27
+ end
23
28
 
24
- rec = temp_rec
25
- closest_so_far = rec.t
26
- end
29
+ def export
30
+ {
31
+ type: "Group",
32
+ objects: objects.map(&:export)
33
+ }
34
+ end
27
35
 
28
- rec
36
+ def to_s(depth=0)
37
+ indent = " "*depth
38
+ "#{indent}Group {\n" +
39
+ objects.map { "#{indent} #{_1.to_s(depth+1)}\n" } +
40
+ "#{indent}}"
29
41
  end
30
42
  end
31
43
  end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rray
4
+ module Object
5
+ class MovingSphere < Sphere
6
+ attr_accessor :center_vec
7
+
8
+ def initialize(center1, center2, radius, material)
9
+ super(center1, radius, material)
10
+ @center_vec = center2 - center1
11
+ rvec = Vec3.new(radius, radius, radius)
12
+ box1 = AABB.from_points(center1 - rvec, center1 + rvec)
13
+ box2 = AABB.from_points(center2 - rvec, center2 + rvec)
14
+ @bounding_box = AABB.from_aabbs(box1, box2)
15
+ end
16
+
17
+ # Linearly interpolate from center1 to center2 according to time, where t=0 yields
18
+ # center1, and t=1 yields center2.
19
+ def center_at(time = 0.0)
20
+ center + center_vec * time
21
+ end
22
+
23
+ def hit(r, ray_t)
24
+ super(r, ray_t, center_at(r.time))
25
+ end
26
+
27
+ def export
28
+ {
29
+ type: "MovingSphere",
30
+ center1: center.to_a,
31
+ center2: center_at(1.0).to_a,
32
+ radius: radius,
33
+ material: material.id
34
+ }
35
+ end
36
+
37
+ def to_s(depth=0)
38
+ indent = " "*depth
39
+ "#{indent}MovingSphere { radius=#{radius}, center=#{center}, vec=#{center_vec} }"
40
+ end
41
+ end
42
+ end
43
+ end
@@ -3,15 +3,19 @@
3
3
  module Rray
4
4
  module Object
5
5
  class Sphere < Base
6
- attr_accessor :center, :radius, :mat
6
+ attr_accessor :center, :radius, :material
7
7
 
8
- def initialize(center, radius, mat)
8
+ attr_reader :bounding_box
9
+
10
+ def initialize(center, radius, material)
9
11
  @center = center
10
12
  @radius = radius
11
- @mat = mat
13
+ @material = material
14
+ rvec = Vec3.new(radius, radius, radius)
15
+ @bounding_box = AABB.from_points(center - rvec, center + rvec)
12
16
  end
13
17
 
14
- def hit(r, ray_t)
18
+ def hit(r, ray_t, center = @center)
15
19
  oc = center - r.origin
16
20
  a = r.direction.length_squared
17
21
  h = r.direction.dot(oc)
@@ -36,9 +40,23 @@ module Rray
36
40
  r,
37
41
  (point - center).div(radius),
38
42
  root,
39
- mat
43
+ material
40
44
  )
41
45
  end
46
+
47
+ def export
48
+ {
49
+ type: "Sphere",
50
+ center: center.to_a,
51
+ radius: radius,
52
+ material: material.id
53
+ }
54
+ end
55
+
56
+ def to_s(depth=0)
57
+ indent = " "*depth
58
+ "#{indent}Sphere { radius=#{radius}, center=#{center} }"
59
+ end
42
60
  end
43
61
  end
44
62
  end
data/lib/rray/ray.rb CHANGED
@@ -2,15 +2,16 @@
2
2
 
3
3
  module Rray
4
4
  class Ray
5
- attr_accessor :origin, :direction
5
+ attr_accessor :origin, :direction, :time
6
6
 
7
- def initialize(origin, direction)
7
+ def initialize(origin, direction, time = 0.0)
8
8
  @origin = origin
9
9
  @direction = direction
10
+ @time = time
10
11
  end
11
12
 
12
13
  def at(t) = (direction*t).add(origin)
13
14
 
14
- def dup = self.class.new(origin, direction)
15
+ def dup = self.class.new(origin, direction, time)
15
16
  end
16
17
  end
data/lib/rray/scene.rb CHANGED
@@ -17,6 +17,31 @@ module Rray
17
17
  Parser.new(json).parse
18
18
  end
19
19
 
20
+ def export
21
+ {
22
+ world: world.export,
23
+ camera: camera.export,
24
+ materials: export_materials
25
+ }
26
+ end
27
+
28
+ private
29
+
30
+ def export_materials
31
+ materials = {}
32
+ traverse do |object|
33
+ materials[object.material.id] ||= object.material.export
34
+ end
35
+ materials
36
+ end
37
+
38
+ def traverse(object = world, &block)
39
+ case object
40
+ when Object::Group then object.objects.each(&block)
41
+ else yield object
42
+ end
43
+ end
44
+
20
45
  class Parser
21
46
  class Error < Rray::Error; end
22
47
 
@@ -38,21 +63,34 @@ module Rray
38
63
  case mat["type"]
39
64
  when "Lambertian" then Material::Lambertian.new(Color.new(*mat["albedo"]))
40
65
  when "Metal" then Material::Metal.new(Color.new(*mat["albedo"]), mat["fuzz"])
41
- when "Dielectric" then Material::Dielectric.new(mat["refractive_index"])
42
- else raise ParserError, "unknown material type #{mat["type"]}"
66
+ when "Dielectric" then Material::Dielectric.new(mat["refraction_index"])
67
+ else raise Error, "unknown material type #{mat["type"]}"
43
68
  end
44
69
  end
45
70
 
46
71
  def parse_object(obj)
47
72
  case obj["type"]
48
- when "Group" then Object::Group.new(obj["objects"].map { parse_object(_1) })
49
- when "Sphere" then Object::Sphere.new(Point3.new(*obj["center"]), obj["radius"], material(obj["material"]))
50
- else raise ParserError, "unknown object type #{obj["type"]}"
73
+ when "Group" then parse_group(obj)
74
+ when "Sphere" then parse_sphere(obj)
75
+ when "MovingSphere" then parse_moving_sphere(obj)
76
+ else raise Error, "unknown object type #{obj["type"]}"
51
77
  end
52
78
  end
53
79
 
80
+ def parse_group(obj)
81
+ Object::Group.new(obj["objects"].map { parse_object(_1) })
82
+ end
83
+
84
+ def parse_sphere(obj)
85
+ Object::Sphere.new(Point3.new(*obj["center"]), obj["radius"], material(obj["material"]))
86
+ end
87
+
88
+ def parse_moving_sphere(obj)
89
+ Object::MovingSphere.new(Point3.new(*obj["center1"]), Point3.new(*obj["center2"]), obj["radius"], material(obj["material"]))
90
+ end
91
+
54
92
  def material(name)
55
- raise ParserError, "unknown material #{name}" unless @materials.key?(name)
93
+ raise Error, "unknown material #{name}" unless @materials.key?(name)
56
94
 
57
95
  @materials[name]
58
96
  end
data/lib/rray/tracer.rb CHANGED
@@ -29,7 +29,7 @@ module Rray
29
29
 
30
30
  rec = scene.world.hit(r, 0.001..Float::INFINITY)
31
31
  if rec
32
- scattered = rec.mat.scatter(r, rec)
32
+ scattered = rec.material.scatter(r, rec)
33
33
  return Color.new(0.0, 0.0, 0.0) unless scattered
34
34
 
35
35
  return ray_color(scattered.ray, depth-1).multiply(scattered.attenuation)
data/lib/rray/util.rb CHANGED
@@ -6,7 +6,6 @@ module Rray
6
6
 
7
7
  # Returns a random real in [min,max).
8
8
  def self.random(min, max) = min + (max-min)*rand
9
- def self.sample_square = Vec3.new(rand - 0.5, rand - 0.5, 0.0)
10
9
 
11
10
  def self.linear_to_gamma(linear_component)
12
11
  return 0 unless linear_component > 0
data/lib/rray/vec3.rb CHANGED
@@ -6,6 +6,10 @@ module Rray
6
6
  @e = [x, y, z]
7
7
  end
8
8
 
9
+ def to_a
10
+ @e.dup
11
+ end
12
+
9
13
  def x = @e[0]
10
14
  def y = @e[1]
11
15
  def z = @e[2]
@@ -22,10 +26,15 @@ module Rray
22
26
  @e[2] = v
23
27
  end
24
28
 
25
- def -@ = self.class.new(-x, -y, -z)
26
- def [](i) = @e[i]
29
+ def -@
30
+ self.class.new(-x, -y, -z)
31
+ end
32
+
33
+ def [](i)
34
+ @e[i]
35
+ end
27
36
 
28
- def []=(i, v)
37
+ def []=(i, v)
29
38
  @e[i] = v
30
39
  end
31
40
 
@@ -104,13 +113,17 @@ module Rray
104
113
  r_out_perp.add(r_out_parallel)
105
114
  end
106
115
 
116
+ def to_s
117
+ "(#{x},#{y},#{z})"
118
+ end
119
+
107
120
  def self.random(min = 0.0, max = 1.0)
108
- Vec3.new(Util.random(min, max), Util.random(min, max), Util.random(min, max))
121
+ new(Util.random(min, max), Util.random(min, max), Util.random(min, max))
109
122
  end
110
123
 
111
124
  def self.random_in_unit_sphere
112
125
  loop do
113
- v = Vec3.random(-1.0, 1.0)
126
+ v = random(-1.0, 1.0)
114
127
  return v if v.length_squared < 1
115
128
  end
116
129
  end
@@ -128,9 +141,11 @@ module Rray
128
141
 
129
142
  def self.random_in_unit_disk
130
143
  loop do
131
- v = Vec3.new(Util.random(-1.0, 1.0), Util.random(-1.0, 1.0), 0.0)
144
+ v = new(Util.random(-1.0, 1.0), Util.random(-1.0, 1.0), 0.0)
132
145
  return v if v.length_squared < 1
133
146
  end
134
147
  end
148
+
149
+ def self.sample_square = new(rand - 0.5, rand - 0.5, 0.0)
135
150
  end
136
151
  end
data/lib/rray/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rray
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/rray.rb CHANGED
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ module Rray
4
+ class Error < StandardError; end
5
+ end
6
+
3
7
  require_relative "rray/version"
4
8
  require_relative "rray/util"
5
9
  require_relative "rray/vec3"
@@ -7,11 +11,14 @@ require_relative "rray/point3"
7
11
  require_relative "rray/color"
8
12
  require_relative "rray/ray"
9
13
  require_relative "rray/interval"
14
+ require_relative "rray/aabb"
10
15
  require_relative "rray/hit"
11
16
  require_relative "rray/scatter"
12
17
  require_relative "rray/object/base"
13
18
  require_relative "rray/object/sphere"
19
+ require_relative "rray/object/moving_sphere"
14
20
  require_relative "rray/object/group"
21
+ require_relative "rray/object/bvh"
15
22
  require_relative "rray/material/base"
16
23
  require_relative "rray/material/lambertian"
17
24
  require_relative "rray/material/metal"
@@ -19,7 +26,3 @@ require_relative "rray/material/dielectric"
19
26
  require_relative "rray/camera"
20
27
  require_relative "rray/scene"
21
28
  require_relative "rray/tracer"
22
-
23
- module Rray
24
- class Error < StandardError; end
25
- end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rray
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danielle Smith
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-15 00:00:00.000000000 Z
11
+ date: 2024-05-01 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Simple raytracer written in ruby. Can be used a CLI tool or library.
14
14
  email:
@@ -21,6 +21,7 @@ files:
21
21
  - README.md
22
22
  - Rakefile
23
23
  - lib/rray.rb
24
+ - lib/rray/aabb.rb
24
25
  - lib/rray/camera.rb
25
26
  - lib/rray/color.rb
26
27
  - lib/rray/hit.rb
@@ -30,7 +31,9 @@ files:
30
31
  - lib/rray/material/lambertian.rb
31
32
  - lib/rray/material/metal.rb
32
33
  - lib/rray/object/base.rb
34
+ - lib/rray/object/bvh.rb
33
35
  - lib/rray/object/group.rb
36
+ - lib/rray/object/moving_sphere.rb
34
37
  - lib/rray/object/sphere.rb
35
38
  - lib/rray/point3.rb
36
39
  - lib/rray/ray.rb