37const usize32_t k_thumbnail_size{256, 256};
46 const auto& src_tex = source->get_texture(0);
47 if(!src_tex || !src_tex->is_valid())
52 const auto src_size = source->get_size();
53 const auto blit_width =
static_cast<uint16_t
>(std::min(src_size.width, k_thumbnail_size.width));
54 const auto blit_height =
static_cast<uint16_t
>(std::min(src_size.height, k_thumbnail_size.height));
55 if(blit_width == 0 || blit_height == 0)
60 auto snapshot = std::make_shared<gfx::texture>(k_thumbnail_size.width,
61 k_thumbnail_size.height,
64 gfx::texture_format::RGBA8,
65 BGFX_TEXTURE_BLIT_DST | BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP);
67 if(!snapshot->is_valid())
74 snapshot->native_handle(),
77 src_tex->native_handle(),
88 scn.registry->view<camera_component>().each(
89 [&](
auto e,
auto&& camera_comp)
91 auto handle = scn.create_handle(e);
94 rpath.on_frame_before_render(scn, dt);
95 auto new_fbo = rpath.render_scene(
handle, camera_comp, scn, dt,
false);
98 captured = std::move(new_fbo);
108 auto& thumbnail = gen.thumbnails[asset.
uid()];
109 auto current_fbo = thumbnail.get();
111 if(gen.remaining > 0 && thumbnail.needs_regeneration && asset.
is_ready())
116 auto& rpath = ctx.get_cached<rendering_system>();
118 auto& scn = gen.get_scene();
119 rpath.release_pipeline_resources(scn);
125 rpath.on_frame_update(scn, dt);
126 rpath.on_frame_before_render(scn, dt);
131 if(
auto captured = render_thumbnail_preview_scene(rpath, scn, dt, frames))
133 if(
auto snapshot = capture_thumbnail_snapshot(captured))
135 thumbnail.pending_snapshot = std::move(snapshot);
141 catch(
const std::exception& e)
151auto get_thumbnail_impl(thumbnail_manager::generator& gen,
159 return transparent.
get();
166 return loading.
get();
169 return make_thumbnail(gen, asset, frames, dt);
178 auto thumbnail = get_thumbnail_impl(gen_, asset, thumbnails_.transparent, thumbnails_.loading);
185 return thumbnails_.mesh.get();
191 auto thumbnail = get_thumbnail_impl(gen_, asset, thumbnails_.transparent, thumbnails_.loading);
198 return thumbnails_.material.get();
207 return thumbnails_.transparent.get();
212 return !asset.
is_ready() ? thumbnails_.loading.get() : thumbnails_.ui_tree.get();
220 return thumbnails_.transparent.get();
225 return !asset.
is_ready() ? thumbnails_.loading.get() : thumbnails_.style_sheet.get();
233 return thumbnails_.transparent.get();
238 return !asset.
is_ready() ? thumbnails_.loading.get() : thumbnails_.script.get();
247 return thumbnails_.transparent.get();
252 return !asset.
is_ready() ? thumbnails_.loading.get() : thumbnails_.physics_material.get();
260 return thumbnails_.transparent.get();
265 return !asset.
is_ready() ? thumbnails_.loading.get() : thumbnails_.audio_clip.get();
273 return thumbnails_.transparent.get();
278 return !asset.
is_ready() ? thumbnails_.loading.get() : thumbnails_.font.get();
286 return thumbnails_.transparent.get();
291 return !asset.
is_ready() ? thumbnails_.loading.get() : thumbnails_.animation.get();
299 return thumbnails_.transparent.get();
304 return !asset.
is_ready() ? thumbnails_.loading.get() : asset.
get();
312 return thumbnails_.transparent.get();
317 return !asset.
is_ready() ? thumbnails_.loading.get() : thumbnails_.shader.get();
325 auto thumbnail = get_thumbnail_impl(gen_, asset, thumbnails_.transparent, thumbnails_.loading, frames, dt);
332 return thumbnails_.prefab.get();
340 return thumbnails_.transparent.get();
345 return !asset.
is_ready() ? thumbnails_.loading.get() : thumbnails_.scene_prefab.get();
351 if(fs::is_directory(path, ec))
353 return thumbnails_.folder.get();
356 return thumbnails_.file.get();
362 entry.needs_regeneration =
true;
363 entry.snapshot =
nullptr;
364 entry.pending_snapshot =
nullptr;
378 for(
auto& scn : gen_.
scenes)
380 rpath.release_pipeline_resources(scn);
387 last_eviction_scan_ = clock::now();
392 cache_directory_ = cache_dir;
394 fs::create_directories(cache_directory_, ec);
399 if(cache_directory_.empty())
403 return cache_directory_ / (hpp::to_string(uid) +
".thumb");
426 fs::remove(path, ec);
436 icon = gimzmo_icons_.camera;
442 const auto&
light = light_comp.get_light();
451 return gimzmo_icons_.sky_light;
453 return gimzmo_icons_.directional_light;
456 return gimzmo_icons_.point_light;
458 return gimzmo_icons_.spot_light;
460 return gimzmo_icons_.sky_light;
469 icon = gimzmo_icons_.reflection_probe;
474 icon = gimzmo_icons_.audio_source;
479 icon = gimzmo_icons_.particle_emitter;
488 APPLOG_TRACE(
"{}::{}", hpp::type_name_str(*
this), __func__);
490 auto& ev = ctx.get_cached<
events>();
497 thumbnails_.file = am.get_asset<
gfx::texture>(
"editor:/data/icons/file.png");
498 thumbnails_.folder = am.get_asset<
gfx::texture>(
"editor:/data/icons/folder.png");
499 thumbnails_.folder_empty = am.get_asset<
gfx::texture>(
"editor:/data/icons/folder_empty.png");
500 thumbnails_.loading = am.get_asset<
gfx::texture>(
"editor:/data/icons/loading.png");
501 thumbnails_.font = am.get_asset<
gfx::texture>(
"editor:/data/icons/font.png");
502 thumbnails_.shader = am.get_asset<
gfx::texture>(
"editor:/data/icons/shader.png");
503 thumbnails_.material = am.get_asset<
gfx::texture>(
"editor:/data/icons/material.png");
504 thumbnails_.physics_material = am.get_asset<
gfx::texture>(
"editor:/data/icons/material.png");
505 thumbnails_.mesh = am.get_asset<
gfx::texture>(
"editor:/data/icons/mesh.png");
506 thumbnails_.animation = am.get_asset<
gfx::texture>(
"editor:/data/icons/animation.png");
507 thumbnails_.prefab = am.get_asset<
gfx::texture>(
"editor:/data/icons/prefab.png");
508 thumbnails_.scene_prefab = am.get_asset<
gfx::texture>(
"editor:/data/icons/scene.png");
509 thumbnails_.audio_clip = am.get_asset<
gfx::texture>(
"editor:/data/icons/sound.png");
510 thumbnails_.script = am.get_asset<
gfx::texture>(
"editor:/data/icons/script.png");
511 thumbnails_.ui_tree = am.get_asset<
gfx::texture>(
"editor:/data/icons/rhtml.png");
512 thumbnails_.style_sheet = am.get_asset<
gfx::texture>(
"editor:/data/icons/rcss.png");
514 gimzmo_icons_.camera = am.get_asset<
gfx::texture>(
"editor:/data/icons/camera.png");
515 gimzmo_icons_.sky_light = am.get_asset<
gfx::texture>(
"editor:/data/icons/sky_light.png");
516 gimzmo_icons_.directional_light = am.get_asset<
gfx::texture>(
"editor:/data/icons/directional_light.png");
517 gimzmo_icons_.point_light = am.get_asset<
gfx::texture>(
"editor:/data/icons/point_light.png");
518 gimzmo_icons_.spot_light = am.get_asset<
gfx::texture>(
"editor:/data/icons/spot_light.png");
519 gimzmo_icons_.audio_source = am.get_asset<
gfx::texture>(
"editor:/data/icons/audio_source.png");
520 gimzmo_icons_.reflection_probe = am.get_asset<
gfx::texture>(
"editor:/data/icons/reflection_probe.png");
521 gimzmo_icons_.particle_emitter = am.get_asset<
gfx::texture>(
"editor:/data/icons/particle_emitter.png");
523 gen_.remaining =
static_cast<int>(gen_.scenes.size());
530 APPLOG_TRACE(
"{}::{}", hpp::type_name_str(*
this), __func__);
539 evict_unused_thumbnails(std::chrono::seconds(30), std::chrono::seconds(60));
544 commit_pending_snapshots();
547void thumbnail_manager::commit_pending_snapshots()
552 if(!
entry.pending_snapshot)
561void thumbnail_manager::evict_unused_thumbnails(std::chrono::seconds scan_interval, std::chrono::seconds idle_timeout)
564 auto now = clock::now();
565 if((now - last_eviction_scan_) < scan_interval)
569 last_eviction_scan_ = now;
572 for(
auto it = thumbnails.begin(); it != thumbnails.end();)
574 auto&
entry = it->second;
575 bool is_idle = (now -
entry.last_access_time) > idle_timeout;
576 if(is_idle && !
entry.needs_regeneration)
578 it = thumbnails.erase(it);
589 if(!snapshot || !snapshot->is_valid())
594 needs_regeneration =
true;
599 last_access_time = clock::now();
605 if(!tex || !tex->is_valid())
623 if(wait_frames-- <= 0)
625 for(
auto& scn : scenes)
630 remaining =
static_cast<int>(scenes.size());
std::shared_ptr< frame_buffer > ptr
Manages assets, including loading, unloading, and storage.
auto get_asset(const std::string &key, load_flags flags=load_flags::standard, load_mode mode=load_mode::immediate) -> asset_handle< T >
Gets an asset by its key.
Class that contains core data for audio sources.
Class that contains core camera data, used for rendering and other purposes.
Class that contains core light data, used for rendering and other purposes.
Component that wraps the soa particle system emitter.
Class that contains core reflection probe data, used for rendering and other purposes.
Base class for different rendering paths in the ACE framework.
auto release_pipeline_resources(scene &scn) -> bool
Class that contains sky light data.
std::chrono::duration< float > delta_t
#define APPLOG_ERROR(...)
#define APPLOG_TRACE(...)
void frames(int _count, int32_t _flags)
void blit(view_id _id, texture_handle _dst, uint16_t _dstX, uint16_t _dstY, texture_handle _src, uint16_t _srcX, uint16_t _srcY, uint16_t _width, uint16_t _height)
void stop_all(const std::string &scope)
Stops all actions within the specified scope.
Thread-safe handle to an asset.
auto is_valid() const -> bool
Checks if the handle references a task.
auto get(bool wait=true) const -> std::shared_ptr< T >
Gets the shared pointer to the asset.
auto is_ready() const -> bool
Checks if the task is ready.
auto uid() const -> hpp::uuid
Gets the unique identifier of the asset.
static void focus_camera_on_3d_scene_for_asset_preview(rtti::context &ctx, const asset_preview_result &result)
static auto create_default_3d_scene_for_asset_preview(rtti::context &ctx, scene &scn, const asset_handle< T > &asset, const usize32_t &size, bool focus_camera=true) -> asset_preview_result
static auto context() -> rtti::context &
hpp::event< void(rtti::context &, delta_t)> on_frame_update
Struct representing a light.
light_type type
The type of the light.
Represents a scene in the ACE framework, managing entities and their relationships.
clock::time_point last_access_time
gfx::texture::ptr snapshot
Owned snapshot copied from the preview OBUFFER (not a live render target).
auto get() -> gfx::texture::ptr
void set(gfx::texture::ptr tex)
std::map< hpp::uuid, generated_thumbnail > thumbnails
std::array< scene, 3 > scenes
auto get_scene() -> scene &
void reset(rendering_system &rpath)
void invalidate_cache_entry(const hpp::uuid &uid)
Invalidates a cached thumbnail on disk.
auto load_cached_thumbnail(const hpp::uuid &uid) -> gfx::texture::ptr
Loads a cached thumbnail from disk (stub – returns nullptr for now).
auto init(rtti::context &ctx) -> bool
auto get_thumbnail(const asset_handle< T > &asset) -> gfx::texture::ptr
auto deinit(rtti::context &ctx) -> bool
void set_cache_directory(const fs::path &cache_dir)
Sets the directory for persistent thumbnail caching.
void save_thumbnail_to_cache(const hpp::uuid &uid, gfx::texture::ptr tex)
Saves a generated thumbnail to disk (stub – no-op for now).
auto get_gizmo_icon(entt::handle e) -> gfx::texture::ptr
void on_frame_update(rtti::context &ctx, delta_t)
void on_frame_end(rtti::context &ctx, delta_t)
void remove_thumbnail(const hpp::uuid &uid)
void regenerate_thumbnail(const hpp::uuid &uid)
auto get_cache_path(const hpp::uuid &uid) const -> fs::path
Gets the disk cache path for a given asset uid.