Skip to content

Commit

Permalink
Merge branch 'v0.8' of https://github.com/sisl/AutoViz.jl into v0.8
Browse files Browse the repository at this point in the history
  • Loading branch information
MaximeBouton committed Mar 5, 2020
2 parents f3f559b + eaedfdf commit f79857a
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 60 deletions.
2 changes: 1 addition & 1 deletion notebooks/autoviz_tutorial.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
],
"source": [
"roadway = gen_stadium_roadway(2)\n",
"render([roadway], camera=FitToContentCamera(0.0))"
"render([roadway])"
]
},
{
Expand Down
1 change: 0 additions & 1 deletion src/AutoViz.jl
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ export
ZoomingCamera,
ComposedCamera,
SceneFollowCamera,
FitToContentCamera,
set_camera!,
camera_move!,
camera_move_pix!,
Expand Down
16 changes: 0 additions & 16 deletions src/cameras.jl
Original file line number Diff line number Diff line change
Expand Up @@ -187,19 +187,3 @@ function update_camera!(camera::ComposedCamera, scene::Frame{E}) where {E<:Entit
update_camera!(camera.cs, cam, scene)
end
end

"""
FitToContentCamera
Move the camera such that all rendered content fits the canvas.
The camera rotation will always be set to 0. An additional border can be added around the content using the argument `percent_border`.
# Constructor
`FitToContentCamera(percent_border::Float64)`
"""
mutable struct FitToContentCamera <: Camera
state::CameraState
percent_border::Float64
end
FitToContentCamera(percent_border::Float64;kwargs...) = FitToContentCamera(CameraState(;kwargs...), percent_border)
12 changes: 11 additions & 1 deletion src/renderable.jl
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,18 @@ Helper function for directly rendering entities, takes care of wrapping them in
function add_renderable!(
rendermodel::RenderModel,
entity::E,
color::Colorant=RGB(rand(), rand(), rand())
color::Union{Nothing, Colorant}=nothing
) where {E<:Entity}
if color === nothing
# random color based on hash code of entity.id
# see https://stackoverflow.com/questions/11120840/hash-string-into-rgb-color
idhash = hash(entity.id)
color = RGB(
.3 + .7*((idhash & 0xFF0000) >> 16)/255,
.3 + .7*((idhash & 0x00FF00) >> 8)/255,
.3 + .7*((idhash & 0x0000FF))/255,
)
end
if rendermode == :fancy
fe = (class(entity.def) == AgentClass.PEDESTRIAN ? FancyPedestrian(ped=entity, color=color) : FancyCar(car=entity, color=color))
add_renderable!(rendermodel, fe)
Expand Down
91 changes: 50 additions & 41 deletions src/rendermodels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,19 @@ You should call `update_camera!` before calling `render` to adapt the camera to
The instructions of the `rendermodel` are reset automatically at the beginning of this function.
"""
function render(renderables::AbstractVector;
camera::Camera=StaticCamera(;zoom=4.),
surface::CairoSurface = CairoSVGSurface(IOBuffer(), canvas_width(camera), canvas_height(camera))
camera::Union{Nothing, Camera} = nothing,
canvas_width::Int64 = (camera === nothing ? DEFAULT_CANVAS_WIDTH : canvas_width(camera)),
canvas_height::Int64 = (camera === nothing ? DEFAULT_CANVAS_HEIGHT : canvas_height(camera)),
surface::CairoSurface = CairoSVGSurface(IOBuffer(), canvas_width, canvas_height)
)
rendermodel = RenderModel()
reset_instructions!(rendermodel)
ctx = creategc(surface)
for renderable in renderables
add_renderable!(rendermodel, renderable)
end
if isa(camera, FitToContentCamera)
camera.state = camera_fit_to_content(rendermodel, ctx,
canvas_width(camera), canvas_height(camera),
percent_border = camera.percent_border)
if camera === nothing
camera = camera_fit_to_content(rendermodel, ctx, canvas_width, canvas_height)
end
render_to_canvas(rendermodel, camera, ctx)
return surface
Expand Down Expand Up @@ -152,7 +152,7 @@ end


"""
camera_fit_to_content(rendermodel::RenderModel, ctx::CairoContext, canvas_width::Integer = DEFAULT_CANVAS_WIDTH, canvas_height::Integer = DEFAULT_CANVAS_HEIGHT; percent_border::Real = 0.1)
camera_fit_to_content(rendermodel::RenderModel, ctx::CairoContext, canvas_width::Integer = DEFAULT_CANVAS_WIDTH, canvas_height::Integer = DEFAULT_CANVAS_HEIGHT; percent_border::Real = 0.0)
Helper function that determines camera parameters such that all rendered content fits on the canvas.
"""
function camera_fit_to_content(
Expand Down Expand Up @@ -218,42 +218,51 @@ function camera_fit_to_content(
end

if isinf(xmin) || isinf(ymin)
return
end
camera_state = CameraState(
position = VecE2(canvas_width/2, canvas_height/2), # [m]
zoom = 1., # [pix/m]
rotation = 0., # [rad]
canvas_width = canvas_width, # [px]
canvas_height = canvas_height # [px]
)
@warn "no render instructions found"
else

if xmax < xmin
xmax = xmin + 1.0
end
if ymax < ymin
ymax = ymin + 1.0
end
if xmax < xmin
xmax = xmin + 1.0
end
if ymax < ymin
ymax = ymin + 1.0
end

# compute zoom to fit
world_width = xmax - xmin
world_height = ymax - ymin
canvas_aspect = canvas_width / canvas_height
world_aspect = world_width / world_height

if world_aspect > canvas_aspect
# expand height to fit
half_diff = (world_width * canvas_aspect - world_height) / 2
world_height = world_width * canvas_aspect # [m]
ymax += half_diff
ymin -= half_diff
else
# expand width to fit
half_diff = (canvas_aspect * world_height - world_width) / 2
world_width = canvas_aspect * world_height
xmax += half_diff
xmin -= half_diff
end
# compute zoom to fit
world_width = xmax - xmin
world_height = ymax - ymin
canvas_aspect = canvas_width / canvas_height
world_aspect = world_width / world_height

if world_aspect > canvas_aspect
# expand height to fit
half_diff = (world_width * canvas_aspect - world_height) / 2
world_height = world_width * canvas_aspect # [m]
ymax += half_diff
ymin -= half_diff
else
# expand width to fit
half_diff = (canvas_aspect * world_height - world_width) / 2
world_width = canvas_aspect * world_height
xmax += half_diff
xmin -= half_diff
end

camera_state = CameraState(
position = VecE2(xmin + world_width/2, ymin + world_height/2), # [m]
zoom = (canvas_width*(1-percent_border)) / world_width, # [pix/m]
rotation = 0., # [rad]
canvas_width = canvas_width, # [px]
canvas_height = canvas_height # [px]
)
camera_state = CameraState(
position = VecE2(xmin + world_width/2, ymin + world_height/2), # [m]
zoom = (canvas_width*(1-percent_border)) / world_width, # [pix/m]
rotation = 0., # [rad]
canvas_width = canvas_width, # [px]
canvas_height = canvas_height # [px]
)

end
return camera_state
end

0 comments on commit f79857a

Please sign in to comment.