Unravel Engine C++ Reference
Loading...
Searching...
No Matches
thumbnail_manager.cpp
Go to the documentation of this file.
1#include "thumbnail_manager.h"
2
8#include <engine/engine.h>
9#include <engine/events.h>
14
16
21#include <graphics/texture.h>
22
24#include <filesystem/watcher.h>
25
26namespace unravel
27{
28
29namespace
30{
31
32template<typename T>
33auto make_thumbnail(thumbnail_manager::generator& gen, const asset_handle<T>& asset, int frames = 1, delta_t dt = delta_t(0.016667f)) -> gfx::texture::ptr
34{
35 auto& thumbnail = gen.thumbnails[asset.uid()];
36 auto current_fbo = thumbnail.get();
37
38 if(gen.remaining > 0 && thumbnail.needs_regeneration)
39 {
40 try
41 {
42 auto& scn = gen.get_scene();
43 scn.unload();
44 auto& ctx = engine::context();
45 bool focus_camera = frames == 1;
46 auto result = defaults::create_default_3d_scene_for_asset_preview(ctx, scn, asset, {256, 256}, focus_camera);
47
48 auto& rpath = ctx.get_cached<rendering_system>();
49 for(int i = 0; i < frames; i++)
50 {
51 rpath.on_frame_update(scn, dt);
52 rpath.on_frame_before_render(scn, dt);
53 }
54
55 if(result.object && !focus_camera)
56 {
57 std::array<entt::handle, 1> entities = {result.object};
58 defaults::focus_camera_on_entities(result.camera, entities);
59 }
60
61
62 auto new_fbo = rpath.render_scene(scn, dt);
63 thumbnail.set(new_fbo);
64 }
65 catch(const std::exception& e)
66 {
67 APPLOG_ERROR("{}", e.what());
68 }
69 }
70
71 return current_fbo;
72}
73
74template<typename T>
75auto get_thumbnail_impl(thumbnail_manager::generator& gen,
76 const asset_handle<T>& asset,
77 const asset_handle<gfx::texture>& transparent,
78 const asset_handle<gfx::texture>& loading,
79 int frames = 1, delta_t dt = delta_t(0.016667f)) -> gfx::texture::ptr
80{
81 if(!asset.is_valid())
82 {
83 return transparent.get();
84 }
85
86 if(!asset.is_ready())
87 {
88 return loading.get();
89 }
90
91 return make_thumbnail(gen, asset, frames, dt);
92}
93
94} // namespace
95
96
97template<>
99{
100 auto thumbnail = get_thumbnail_impl(gen_, asset, thumbnails_.transparent, thumbnails_.loading);
101
102 if(thumbnail)
103 {
104 return thumbnail;
105 }
106
107 return thumbnails_.mesh.get();
108}
109
110template<>
112{
113 auto thumbnail = get_thumbnail_impl(gen_, asset, thumbnails_.transparent, thumbnails_.loading);
114
115 if(thumbnail)
116 {
117 return thumbnail;
118 }
119
120 return thumbnails_.material.get();
121}
122
123
124template<>
126{
127 if(!asset.is_valid())
128 {
129 return thumbnails_.transparent.get();
130 }
131 return !asset.is_ready() ? thumbnails_.loading.get() : thumbnails_.ui_tree.get();
132}
133
134template<>
136{
137 if(!asset.is_valid())
138 {
139 return thumbnails_.transparent.get();
140 }
141 return !asset.is_ready() ? thumbnails_.loading.get() : thumbnails_.style_sheet.get();
142}
143
144template<>
146{
147 if(!asset.is_valid())
148 {
149 return thumbnails_.transparent.get();
150 }
151 return !asset.is_ready() ? thumbnails_.loading.get() : thumbnails_.script.get();
152}
153
154template<>
157{
158 if(!asset.is_valid())
159 {
160 return thumbnails_.transparent.get();
161 }
162 return !asset.is_ready() ? thumbnails_.loading.get() : thumbnails_.physics_material.get();
163}
164
165template<>
167{
168 if(!asset.is_valid())
169 {
170 return thumbnails_.transparent.get();
171 }
172 return !asset.is_ready() ? thumbnails_.loading.get() : thumbnails_.audio_clip.get();
173}
174
175template<>
177{
178 if(!asset.is_valid())
179 {
180 return thumbnails_.transparent.get();
181 }
182 return !asset.is_ready() ? thumbnails_.loading.get() : thumbnails_.font.get();
183}
184
185template<>
187{
188 if(!asset.is_valid())
189 {
190 return thumbnails_.transparent.get();
191 }
192 return !asset.is_ready() ? thumbnails_.loading.get() : thumbnails_.animation.get();
193}
194
195template<>
196auto thumbnail_manager::get_thumbnail<gfx::texture>(const asset_handle<gfx::texture>& asset) -> gfx::texture::ptr
197{
198 if(!asset.is_valid())
199 {
200 return thumbnails_.transparent.get();
201 }
202
203 return !asset.is_ready() ? thumbnails_.loading.get() : asset.get();
204}
205
206template<>
207auto thumbnail_manager::get_thumbnail<gfx::shader>(const asset_handle<gfx::shader>& asset) -> gfx::texture::ptr
208{
209 if(!asset.is_valid())
210 {
211 return thumbnails_.transparent.get();
212 }
213 return !asset.is_ready() ? thumbnails_.loading.get() : thumbnails_.shader.get();
214}
215
216template<>
218{
219 delta_t dt(0.016667f * 5.0f);
220 int frames = 2;
221 auto thumbnail = get_thumbnail_impl(gen_, asset, thumbnails_.transparent, thumbnails_.loading, frames, dt);
222
223 if(thumbnail)
224 {
225 return thumbnail;
226 }
227
228 return thumbnails_.prefab.get();
229}
230
231template<>
233{
234 if(!asset.is_valid())
235 {
236 return thumbnails_.transparent.get();
237 }
238 return !asset.is_ready() ? thumbnails_.loading.get() : thumbnails_.scene_prefab.get();
239}
240
242{
243 fs::error_code ec;
244 if(fs::is_directory(path, ec))
245 {
246 return thumbnails_.folder.get();
247 }
248
249 return thumbnails_.file.get();
250}
251
253{
254 gen_.thumbnails[uid].needs_regeneration = true;
255}
256void thumbnail_manager::remove_thumbnail(const hpp::uuid& uid)
257{
258 gen_.thumbnails.erase(uid);
259}
260
262{
263 gen_.thumbnails.clear();
264}
265
267{
269
270 if(e.all_of<camera_component>())
271 {
272 icon = gimzmo_icons_.camera;
273 }
274
275 if(e.all_of<light_component>())
276 {
277 const auto& light_comp = e.get<light_component>();
278 const auto& light = light_comp.get_light();
279
280 auto type = [&]() -> asset_handle<gfx::texture>
281 {
282 switch(light.type)
283 {
285 {
286 if(e.all_of<skylight_component>())
287 return gimzmo_icons_.sky_light;
288
289 return gimzmo_icons_.directional_light;
290 }
292 return gimzmo_icons_.point_light;
293 case light_type::spot:
294 return gimzmo_icons_.spot_light;
295 default:
296 return gimzmo_icons_.sky_light;
297 }
298 }();
299
300 icon = type;
301 }
302
303 if(e.all_of<reflection_probe_component>())
304 {
305 icon = gimzmo_icons_.reflection_probe;
306 }
307
308 if(e.all_of<audio_source_component>())
309 {
310 icon = gimzmo_icons_.audio_source;
311 }
312
313 if(e.all_of<particle_emitter_component>())
314 {
315 icon = gimzmo_icons_.particle_emitter;
316 }
317
318 return icon.get();
319}
320
321
323{
324 APPLOG_TRACE("{}::{}", hpp::type_name_str(*this), __func__);
325
326 auto& ev = ctx.get_cached<events>();
327 ev.on_frame_update.connect(sentinel_, this, &thumbnail_manager::on_frame_update);
328
329 auto& am = ctx.get_cached<asset_manager>();
330 thumbnails_.transparent = am.get_asset<gfx::texture>("engine:/data/textures/transparent.png");
331
332 thumbnails_.file = am.get_asset<gfx::texture>("editor:/data/icons/file.png");
333 thumbnails_.folder = am.get_asset<gfx::texture>("editor:/data/icons/folder.png");
334 thumbnails_.folder_empty = am.get_asset<gfx::texture>("editor:/data/icons/folder_empty.png");
335 thumbnails_.loading = am.get_asset<gfx::texture>("editor:/data/icons/loading.png");
336 thumbnails_.font = am.get_asset<gfx::texture>("editor:/data/icons/font.png");
337 thumbnails_.shader = am.get_asset<gfx::texture>("editor:/data/icons/shader.png");
338 thumbnails_.material = am.get_asset<gfx::texture>("editor:/data/icons/material.png");
339 thumbnails_.physics_material = am.get_asset<gfx::texture>("editor:/data/icons/material.png");
340 thumbnails_.mesh = am.get_asset<gfx::texture>("editor:/data/icons/mesh.png");
341 thumbnails_.animation = am.get_asset<gfx::texture>("editor:/data/icons/animation.png");
342 thumbnails_.prefab = am.get_asset<gfx::texture>("editor:/data/icons/prefab.png");
343 thumbnails_.scene_prefab = am.get_asset<gfx::texture>("editor:/data/icons/scene.png");
344 thumbnails_.audio_clip = am.get_asset<gfx::texture>("editor:/data/icons/sound.png");
345 thumbnails_.script = am.get_asset<gfx::texture>("editor:/data/icons/script.png");
346 thumbnails_.ui_tree = am.get_asset<gfx::texture>("editor:/data/icons/rhtml.png");
347 thumbnails_.style_sheet = am.get_asset<gfx::texture>("editor:/data/icons/rcss.png");
348
349 gimzmo_icons_.camera = am.get_asset<gfx::texture>("editor:/data/icons/camera.png");
350 gimzmo_icons_.sky_light = am.get_asset<gfx::texture>("editor:/data/icons/sky_light.png");
351 gimzmo_icons_.directional_light = am.get_asset<gfx::texture>("editor:/data/icons/directional_light.png");
352 gimzmo_icons_.point_light = am.get_asset<gfx::texture>("editor:/data/icons/point_light.png");
353 gimzmo_icons_.spot_light = am.get_asset<gfx::texture>("editor:/data/icons/spot_light.png");
354 gimzmo_icons_.audio_source = am.get_asset<gfx::texture>("editor:/data/icons/audio_source.png");
355 gimzmo_icons_.reflection_probe = am.get_asset<gfx::texture>("editor:/data/icons/reflection_probe.png");
356 gimzmo_icons_.particle_emitter = am.get_asset<gfx::texture>("editor:/data/icons/particle_emitter.png");
357 return true;
358}
359
361{
362 APPLOG_TRACE("{}::{}", hpp::type_name_str(*this), __func__);
363
364 return true;
365}
366
371
373{
374 if(!thumbnail)
375 {
376 return nullptr;
377 }
378
379 return thumbnail->get_texture();
380}
381
387
389{
390 reset_wait();
391 remaining--;
392 return scenes[remaining];
393}
394
396{
397 if(wait_frames-- <= 0)
398 {
399 for(auto& scn : scenes)
400 {
401 scn.unload();
402 }
403 remaining = scenes.size();
404
405 reset_wait();
406 }
407}
408
410{
411 wait_frames = 1;
412}
413
414} // namespace unravel
manifold_type type
Manages assets, including loading, unloading, and storage.
auto get_asset(const std::string &key, load_flags flags=load_flags::standard) -> 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 particle system emitter functionality.
Class that contains core reflection probe data, used for rendering and other purposes.
Class that contains sky light data.
std::chrono::duration< float > delta_t
const char * icon
#define APPLOG_ERROR(...)
Definition logging.h:20
#define APPLOG_TRACE(...)
Definition logging.h:17
Represents a handle to an asset, providing access and management functions.
auto is_valid() const -> bool
Checks if the handle is valid.
auto uid() const -> const hpp::uuid &
Gets the unique identifier of the asset.
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.
static void focus_camera_on_entities(entt::handle camera, hpp::span< const entt::handle > entities)
Focuses a camera on a specified entity.
Definition defaults.cpp:822
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 &
Definition engine.cpp:116
hpp::event< void(rtti::context &, delta_t)> on_frame_update
Definition events.h:16
Struct representing a light.
Definition light.h:87
light_type type
The type of the light.
Definition light.h:89
Represents a scene in the ACE framework, managing entities and their relationships.
Definition scene.h:21
std::map< hpp::uuid, generated_thumbnail > thumbnails
auto init(rtti::context &ctx) -> bool
auto get_thumbnail(const asset_handle< T > &asset) -> gfx::texture::ptr
auto deinit(rtti::context &ctx) -> bool
auto get_gizmo_icon(entt::handle e) -> gfx::texture::ptr
void on_frame_update(rtti::context &ctx, delta_t)
void remove_thumbnail(const hpp::uuid &uid)
void regenerate_thumbnail(const hpp::uuid &uid)