Skip to content

Instantly share code, notes, and snippets.

@asinghvi17
Created June 21, 2024 19:11
Show Gist options
  • Save asinghvi17/742a8b0cbaa38cc42a6008a24f364e49 to your computer and use it in GitHub Desktop.
Save asinghvi17/742a8b0cbaa38cc42a6008a24f364e49 to your computer and use it in GitHub Desktop.
using GLMakie
using Meshing, GeometryBasics
isoval = 100
algo = MarchingCubes(iso=isoval, insidepositive=false)
struct CameraRotationMove{T} <: FlyThroughPaths.PathChange{T}
duration::T
axis::Vec3{Float64}
angle::Float64
action
end
CameraRotationMove(duration::T, axis::Vec3, angle, action = nothing) where {T} = CameraRotationMove{T}(duration, axis, angle, action)
function (move::CameraRotationMove)(view::ViewState, t)
FlyThroughPaths.checkt(t, move)
(; axis, angle, action) = move
tf = t/FlyThroughPaths.duration(move)
qrotation = Makie.qrotation(axis, angle * tf)
viewing_direction = view.lookat - view.eyeposition
rotation_matrix = Makie.rotationmatrix4(qrotation)[1:3, 1:3] # we don't need the fourth dimension
new_view = ViewState(
lookat = view.eyeposition + rotation_matrix * viewing_direction,
eyeposition = view.eyeposition, upvector = view.upvector, fov = view.fov
)
new_view
end
function FlyThroughPaths.target(oldtarget::ViewState{T}, move::CameraRotationMove{T}) where {T}
return move(oldtarget, FlyThroughPaths.duration(move))
end
## Decocube
Xm = 2.5
ξ = -Xm:.025:Xm;
b = 1
c = 2.2
t = 1.2
deco(x,y,z) = ((x^2 + y^2 - c^2)^2 + (z - 1)^2*(z + 1)^2)*((y^2 + z^2 - c^2)^2 +
(x - 1)^2*(x + 1)^2)*((z^2 + x^2 - c^2)^2 + (y - 1)^2*(y + 1)^2) -
t*(1 + b*(x^2 + y^2 + z^2))
show_isosurface(f[2,2],deco,ξ);
s = [deco(x,y,z) for x in ξ, y in ξ, z in ξ] .+ 100
mc = GeometryBasics.Mesh(s, algo)
coords = GeometryBasics.coordinates(mc)
const _CENTROID_MC = mean(coords)
_uv_func(point) = Vec2f(0, (sqrt(sum((point - _CENTROID_MC - Point3f(.5, .5, .5)) .^ 2)) ./ 2 ))
uvmc = GeometryBasics.normal_mesh(
GeometryBasics.Mesh(
GeometryBasics.meta(coords; uv = _uv_func.(coords)),
GeometryBasics.faces(mc)
)
)
plottable_mc = GeometryBasics.Mesh(
GeometryBasics.meta(coords; uv = uvmc.uv, normals = uvmc.normals .* -1),
GeometryBasics.faces(uvmc)
)
cmap = Makie.to_colormap(cgrad(:turbo; alpha = 0.7))
f, a, p = with_theme(theme_black()) do
mesh(
uvmc;
color = reshape(cmap, length(cmap), 1), # a matrix is interpreted as a texture, but a vector is per-vertex color.
axis = (; type = LScene, show_axis = false)
)
end
save("test.png", Makie.current_figure(); update = false, px_per_unit = 2)
using FlyThroughPaths
using ProgressMeter
state = ViewState(eyeposition=Point3f(0.5, 3.3, 2.0), lookat=Vec3f(0, 0, 0), upvector = Vec3f(-0.076228954, -0.50599855, 0.8591594), fov = 45.0)
path = Path(state)
path *= ConstrainedMove(3.0, ViewState(eyeposition = Vec3f(0.1, 0.6, 0), lookat = Vec3f(0.1, 0, -0.4)), :rotation, :constant)
path *= ConstrainedMove(1.0, ViewState(fov = 60))
path *= CameraRotationMove(6f0, Vec3(0., 1., 0.), 2π)
path *= ConstrainedMove(3f0, ViewState(eyeposition=Point3f(0.22013578, -0.7960979, -0.66677684) * 3))
record(f, "test2.mp4"; framerate = 30) do io
@showprogress for t in range(-0.1, FlyThroughPaths.duration(path) + 0.2, step = 1/30)
set_view!(a, path(t))
recordframe!(io)
end
end
# Texture experiments
@eval GLMakie begin
function mesh_inner(screen::Screen, mesh, transfunc, gl_attributes, plot, space=:data)
# signals not supported for shading yet
shading = to_value(gl_attributes[:shading])::Makie.MakieCore.ShadingAlgorithm
matcap_active = !isnothing(to_value(get(gl_attributes, :matcap, nothing)))
color = pop!(gl_attributes, :color)
interp = to_value(pop!(gl_attributes, :interpolate, true))
interp = interp ? :linear : :nearest
if to_value(color) isa Colorant
gl_attributes[:vertex_color] = color
delete!(gl_attributes, :color_map)
delete!(gl_attributes, :color_norm)
elseif to_value(color) isa Makie.AbstractPattern
img = lift(x -> el32convert(Makie.to_image(x)), plot, color)
gl_attributes[:image] = ShaderAbstractions.Sampler(img, x_repeat=:repeat, minfilter=:nearest)
get!(gl_attributes, :fetch_pixel, true)
elseif to_value(color) isa Texture
gl_attributes[:image] = color
delete!(gl_attributes, :color_map)
delete!(gl_attributes, :color_norm)
delete!(gl_attributes, :color)
elseif to_value(color) isa AbstractMatrix{<:Colorant}
gl_attributes[:image] = Texture(lift(el32convert, plot, color), minfilter = interp)
delete!(gl_attributes, :color_map)
delete!(gl_attributes, :color_norm)
elseif to_value(color) isa AbstractMatrix{<: Number}
gl_attributes[:image] = Texture(lift(el32convert, plot, color), minfilter = interp)
gl_attributes[:color] = nothing
elseif to_value(color) isa AbstractVector{<: Union{Number, Colorant}}
gl_attributes[:vertex_color] = lift(el32convert, plot, color)
else
# error("Unsupported color type: $(typeof(to_value(color)))")
end
if haskey(gl_attributes, :intensity)
intensity = pop!(gl_attributes, :intensity)
if intensity[] isa Matrix
gl_attributes[:image] = Texture(intensity, minfilter = interp)
else
gl_attributes[:vertex_color] = intensity
end
gl_attributes[:color] = nothing
end
# TODO: avoid intermediate observable
positions = map(m -> metafree(coordinates(m)), mesh)
gl_attributes[:vertices] = apply_transform_and_f32_conversion(Makie.parent_scene(plot), plot, positions)
gl_attributes[:faces] = lift(x-> decompose(GLTriangleFace, x), mesh)
if hasproperty(to_value(mesh), :uv)
gl_attributes[:texturecoordinates] = lift(decompose_uv, mesh)
end
if hasproperty(to_value(mesh), :normals) && (shading !== NoShading || matcap_active)
gl_attributes[:normals] = lift(decompose_normals, mesh)
end
return draw_mesh(screen, gl_attributes)
end
end
Makie.assemble_colors(::GLMakie.Texture, color::Observable, plot) = color
Makie.convert_attribute(color::GLMakie.Texture, ::key"color") = color
tex = GLMakie.Texture(rand(RGBf, 10, 10); x_repeat = :mirrored_repeat, y_repeat = :mirrored_repeat, z_repeat = :mirrored_repeat);
mesh(uvmc; color = tex)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment