I tried what I thought was a simpler solution, that is creating a Vector of Materials and using the Int64 index instead of the material itself.
Otherwise there is going to be some added complextity with all the Hitables and Materials that come along in the next stages of development.
https://github.com/lawless-m/ShirleyRenderer.jl/tree/OneIndexedMaterials
This helped in that Spheres did not need a Material type but instead an Int
e.g. add!(scene, Sphere(Point3(0, 1, 0), 1.0, add!(scene, Dielectric(1.5))))
but in the end, the scatter still needed to go from Abstract → Concrete
function scatter!(scene, ray::Ray, rec::Hit)::Tuple{Bool, Color}
_scatter!(scene.materials[rec.material], ray, rec)
end
the @code_warntype see %4
MethodInstance for ShirleyRayTracer.scatter!(::Scene, ::ShirleyRayTracer.Ray, ::Hit)
from scatter!(scene, ray::ShirleyRayTracer.Ray, rec::Hit) in ShirleyRayTracer at /home/matt/GitHub/ShirleyRenderer.jl/src/Materials.jl:4
Arguments
#self#::Core.Const(ShirleyRayTracer.scatter!)
scene::Scene
ray::ShirleyRayTracer.Ray
rec::Hit
Body::Tuple{Bool, ColorTypes.RGB{Float64}}
1 ─ %1 = Core.apply_type(ShirleyRayTracer.Tuple, ShirleyRayTracer.Bool, ShirleyRayTracer.Color)::Core.Const(Tuple{Bool, ColorTypes.RGB{Float64}})
│ %2 = Base.getproperty(scene, :materials)::Vector{ShirleyRayTracer.Material}
│ %3 = Base.getproperty(rec, :material)::Int64
│ %4 = Base.getindex(%2, %3)::ShirleyRayTracer.Material
│ %5 = ShirleyRayTracer._scatter!(%4, ray, rec)::Tuple{Bool, ColorTypes.RGB{Float64}}
│ %6 = Base.convert(%1, %5)::Tuple{Bool, ColorTypes.RGB{Float64}}
│ %7 = Core.typeassert(%6, %1)::Tuple{Bool, ColorTypes.RGB{Float64}}
└── return %7
tbh I’m not expert enough in doing this - as you might tell
but hey, I’m learning