确实这样子可以使得 objects
的类型全部确定下来, 下面代码是我对这个方法的实现, 因为这个函数只会在一开始调用一次, 所以这个函数内的类型不稳定就不在意了.
function setupobjects(objs::Vector{Object})
objdict = Dict{DataType, Any}()
for obj ∈ objs
T = typeof(obj)
T ∉ keys(objdict) && (objdict[T] = T[])
push!(objdict[T], obj)
end
return (values(objdict)..., )
end
下面是对这个函数的测试
julia> objs isa Vector{nyasRT.Object}
true
julia> objlists = nyasRT.setupobjects(objs);
julia> typeof(objlists)
Tuple{Vector{Main.nyasRT.Object{Main.nyasRT.Sphere, Main.nyasRT.PureColor, Main.nyasRT.Phong}},
Vector{Main.nyasRT.Object{Main.nyasRT.InftyPlane, Main.nyasRT.PureColor, Main.nyasRT.Lambertian}}}
但是问题是如何对 objlists
里面的元素进行历遍呢, 下面是我设想的一种方法
function hitobjects(objs, ray)
hitsetidx = hiteleidx = 0
rec = nyasRT.HittingRecord()
for (setidx, objlists) ∈ enumerate(objs)
for (eleidx, obj) ∈ enumerate(objlists)
tmprec = nyasRT.hit(obj.surface, ray, rec.t)
if tmprec.hitted
rec = tmprec
hitsetidx = setidx
hiteleidx = eleidx
end
end
end
return (hitsetidx, hiteleidx), rec
end
但是通过 code_warntypes
查看这个函数依然是类型不稳定的
julia> @code_warntype hitobjects(objs, nyasRT.Ray(Vec3(0), Vec3(0)))
MethodInstance for hitobjects(::Tuple{Vector{Object{Sphere, PureColor, Phong}}, Vector{Object{InftyPlane, PureColor, Lambertian}}}, ::Ray)
from hitobjects(objs, ray) in Main at
Arguments
#self#::Core.Const(test3)
objs::Tuple{Vector{Object{Sphere, PureColor, Phong}}, Vector{Object{InftyPlane, PureColor, Lambertian}}}
ray::Ray
Locals
@_4::Union{Nothing, Tuple{Union{Vector{Object{InftyPlane, PureColor, Lambertian}}, Vector{Object{Sphere, PureColor, Phong}}}, Int64}}
rec::HittingRecord
@_6::Union{Nothing, Tuple{Object{InftyPlane, PureColor, Lambertian}, Int64}, Tuple{Object{Sphere, PureColor, Phong}, Int64}}
objlists::Union{Vector{Object{InftyPlane, PureColor, Lambertian}}, Vector{Object{Sphere, PureColor, Phong}}}
obj::Union{Object{InftyPlane, PureColor, Lambertian}, Object{Sphere, PureColor, Phong}}
tmprec::Tuple{Bool, Float64}
Body::HittingRecord
1 ─ %1 = HittingRecord::Core.Const(HittingRecord)
│ (rec = (%1)())
│ %3 = objs::Tuple{Vector{Object{Sphere, PureColor, Phong}}, Vector{Object{InftyPlane, PureColor, Lambertian}}}
│ (@_4 = Base.iterate(%3))
│ %5 = (@_4::Core.PartialStruct(Tuple{Vector{Object{Sphere, PureColor, Phong}}, Int64}, Any[Vector{Object{Sphere, PureColor, Phong}}, Core.Const(2)]) === nothing)::Core.Const(false)
│ %6 = Base.not_int(%5)::Core.Const(true)
└── goto #6 if not %6
2 ┄ %8 = @_4::Union{Tuple{Vector{Object{InftyPlane, PureColor, Lambertian}}, Int64}, Tuple{Vector{Object{Sphere, PureColor, Phong}}, Int64}}
│ (objlists = Core.getfield(%8, 1))
│ %10 = Core.getfield(%8, 2)::Int64
│ %11 = objlists::Union{Vector{Object{InftyPlane, PureColor, Lambertian}}, Vector{Object{Sphere, PureColor, Phong}}}
│ (@_6 = Base.iterate(%11))
│ %13 = (@_6 === nothing)::Bool
│ %14 = Base.not_int(%13)::Bool
└── goto #4 if not %14
3 ─ %16 = @_6::Union{Tuple{Object{InftyPlane, PureColor, Lambertian}, Int64}, Tuple{Object{Sphere, PureColor, Phong}, Int64}}
│ (obj = Core.getfield(%16, 1))
│ Core.getfield(%16, 2)
│ %19 = hit::Core.Const(hit)
│ %20 = Base.getproperty(obj, :surface)::Union{InftyPlane, Sphere}
│ %21 = Base.getproperty(rec::Core.Const(HittingRecord(false, Inf, [0.0, 0.0, 0.0], [0.0, 0.0, 0.0])), :t)::Core.Const(Inf)
│ (tmprec = (%19)(%20, ray, %21))
│ Base.getproperty(tmprec, :hitted)
│ Core.Const(:(Core.typeassert(%23, Core.Bool)))
│ Core.Const(:(rec = tmprec))
│ Core.Const(:(goto %27))
│ Core.Const(:(@_6 = Base.iterate(%11, %18)))
│ Core.Const(:(@_6 === nothing))
│ Core.Const(:(Base.not_int(%28)))
│ Core.Const(:(goto %32 if not %29))
└── Core.Const(:(goto %16))
4 ┄ (@_4 = Base.iterate(%3, %10))
│ %33 = (@_4 === nothing)::Bool
│ %34 = Base.not_int(%33)::Bool
└── goto #6 if not %34
5 ─ goto #2
6 ┄ return rec::Core.Const(HittingRecord(false, Inf, [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]))