Alternate ways to deal with arrays of subtypes of abstract type

Disregard my comment: I was mistaken. Here is what I have

using StaticArrays
using LinearAlgebra
using BenchmarkTools

const Vec3 = SVector{3, Float64}

abstract type Primitive end

const Scene = Vector{T} where T <: Primitive #Type alias for scene

struct Sphere <: Primitive
    c::Vec3
    r::Float64
end
Sphere() = Sphere(Vec3(0., 0., 0.), 1.) #Default Debugging Sphere

struct Plane <: Primitive
    n::Vec3
    h::Float64
end
Plane() = Plane(Vec3(0., 1., 0.), 0.) #Default Debugging Plane

sdf(p::Vec3, sphere::Sphere)    = norm(sphere.c - p) - sphere.r
sdf(p::Vec3, plane::Plane)      = p⋅plane.n + plane.h

function sdfUnion(p::Vec3, objects::Scene)
    n = length(objects)
    n == 1 && return sdf(p, objects[1])
    d = sdf(p, objects[1])
    for i ∈ 2:n
        d = min(d, sdf(p, objects[i]))
    end
    return d
end

@btime sdfUnion(vec3, scene) setup=(vec3 = Vec3(0., 0., 0.); scene = Primitive[Sphere(), Plane()])

yielding

  13.527 ns (0 allocations: 0 bytes)

which looks pretty good to me. Only thing I seem to remember is that certain compiler optimizations stop working in such cases if the number of sub types gets larger than a small limit (could be 3 or 4?), but then manual dispatch could help. Could this be the problem? Or do we need to investigate Vec3?

1 Like