Skip to content

Instantly share code, notes, and snippets.

@briochemc
Forked from jkrumbiegel/dancing_cubes.jl
Last active June 27, 2020 08:41
Show Gist options
  • Save briochemc/269311886848a356071e1b76a1d56126 to your computer and use it in GitHub Desktop.
Save briochemc/269311886848a356071e1b76a1d56126 to your computer and use it in GitHub Desktop.
Dancing cubes
using AbstractPlotting
using MakieLayout
using GLMakie; GLMakie.activate!()
GLMakie.GLFW.WindowHint(GLMakie.GLFW.FLOATING, 1)
using LinearAlgebra
##
scene = Scene(center = false, raw = true, resolution = (800, 800))
#scene = Scene(center = false, raw = false, resolution = (800, 800))
azimuth = Node(0.0)
elevation = Node(0.0)
target = 10
targetlimits = Node(FRect3D((-target, -target, -target), (target, target, target)))
limits = lift(identity, targetlimits)
view = lift(azimuth, elevation, limits) do a, e, lims
center = lims.origin .+ 0.5 .* widths(lims)
dist = maximum(widths(lims)) # should be enough to be outside?
eyepos = center .+ dist .* LinearAlgebra.normalize(Vec3f0(sin(e) * cos(a), sin(e) * sin(a), cos(e)))
eyeright = LinearAlgebra.cross(Vec(0.0, 0, 1), LinearAlgebra.normalize(eyepos .- center))
# TODO: fix eyeup so there is no flip at the elevation zero point
eyeup = LinearAlgebra.cross(eyeright, LinearAlgebra.normalize(eyepos .- center))
AbstractPlotting.lookat(eyepos, center, -eyeup)
end
projection = lift(view) do v
lims = limits[]
ox, oy, oz = lims.origin
wx, wy, wz = lims.widths
corners = [
ox oy oz 0
ox oy oz + wz 0
ox oy + wy oz 0
ox oy + wy oz + wz 0
ox + wx oy oz 0
ox + wx oy oz + wz 0
ox + wx oy + wy oz 0
ox + wx oy + wy oz + wz 0
]
viewed_corners = (v * corners')'
boxmin = minimum(viewed_corners, dims = 1)
boxmax = maximum(viewed_corners, dims = 1)
dist = boxmax .- boxmin
minis = boxmin .+ 0.5 .* dist
maxis = boxmax .- 0.5 .* dist
boxmin
boxmax
AbstractPlotting.orthographicprojection(
boxmin[1], boxmax[1],
boxmin[2], boxmax[2],
boxmin[3] - 10000, boxmax[3] + 10000) # * flipmatrix
end
projectionview = lift(projection, view) do p, v
p * v
end
disconnect!(scene.camera)
on(projectionview) do pv
camera(scene).view[] = view[]
camera(scene).projection[] = projection[]
camera(scene).projectionview[] = pv
end
#########################################################
ncubes = (4,3,2)
N = *(ncubes...)
wet3D = trues(ncubes)
wet3D[1:2,1:2,end] .= false
wet3D[3,1,end] = false
wet3D[1,1,end-1] = false
l = 1
ws = Point3f0(l, l, l)
LI = LinearIndices(ncubes)
iwet = findall(vec(wet3D))
CI = CartesianIndices(ncubes)
cubes_orig = map(CI) do I
ori = Point3f0(l * I.I[1] + l, l * I.I[2] - 3l, -l * I.I[3])
cube = Node(FRect3D(ori, ws))
end
cubes_final = map(CI) do I
ori = Point3f0(l * I.I[1] + l, l * I.I[2] - 3l, -l * I.I[3])
cube = Node(FRect3D(ori, ws))
end
for (i, j) in enumerate(iwet)
ori = Point3f0(-3l, +3l, 15l-l*i)
cubes_final[j][] = FRect3D(ori, ws)
end
cubes = copy(cubes_orig)
for I in eachindex(cubes)
mesh!(cubes[I], color = wet3D[I] ? :lightblue2 : :coral, shading = false)
wireframe!(cubes[I], color = :black)
end
elevation[] = deg2rad(45)
azimuth[] = deg2rad(45)
record(scene, "cubes3.gif", -0.1:1/200:2.1) do t
for (i,I) in enumerate(iwet)
t2 = min(max(t - sqrt(i/N), 0), 1) # delay each cube a bit
t3 = 0.5(1 - cos(π * t2)) # smooth transition
#cubes[i][] = FRect3D((0, 3sin(i + 4t), 11i), (10, 10, 10))
#cubes[I][] = cubes_orig[I][].origin * (1-t) + cubes_final[I][].origin * t
cubes[I][] = FRect3D(cubes_orig[I][].origin * (1-t3) + cubes_final[I][].origin * t3, ws)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment