34void focus_camera_on_bounds(entt::handle camera,
const math::bsphere& bounds)
36 auto& trans_comp = camera.get<transform_component>();
37 auto& camera_comp = camera.get<camera_component>();
38 const auto& cam = camera_comp.get_camera();
42 float aspect = cam.get_aspect_ratio();
43 float fov = cam.get_fov();
45 float radius = bounds.
radius;
48 float hfov = math::degrees(2.0f * math::atan(math::tan(math::radians(fov) / 2.0f) * aspect));
50 float mfov = math::min(fov, hfov);
51 float dist = radius / (math::sin(math::radians(mfov) / 2.0f));
53 trans_comp.look_at(cen);
54 trans_comp.set_position_global(cen - dist * trans_comp.get_z_axis_global());
55 camera_comp.set_ortho_size(radius);
56 camera_comp.update(trans_comp.get_transform_global());
59void focus_camera_on_bounds(entt::handle camera,
const math::bbox& bounds)
61 auto& trans_comp = camera.get<transform_component>();
62 auto& camera_comp = camera.get<camera_component>();
63 const auto& cam = camera_comp.get_camera();
68 float aspect = cam.get_aspect_ratio();
69 float fov = cam.get_fov();
71 float radius = math::length(
size) / 2.0f;
74 float horizontal_fov = math::degrees(2.0f * math::atan(math::tan(math::radians(fov) / 2.0f) * aspect));
76 float mfov = math::min(fov, horizontal_fov);
77 float dist = radius / (math::sin(math::radians(mfov) / 2.0f));
79 trans_comp.look_at(cen);
80 trans_comp.set_position_global(cen - dist * trans_comp.get_z_axis_global());
81 camera_comp.set_ortho_size(radius);
82 camera_comp.update(trans_comp.get_transform_global());
86void run_camera_focus_transition(entt::handle camera,
87 const math::vec3& target_center,
92 if(duration <= 0.0f || !camera.all_of<transform_component, camera_component>())
97 ::unravel::focus_camera_on_bounds(camera, bs);
101 auto& trans_comp = camera.get<transform_component>();
102 auto& camera_comp = camera.get<camera_component>();
103 const auto& cam = camera_comp.get_camera();
105 float aspect = cam.get_aspect_ratio();
106 float fov = cam.get_fov();
107 float horizontal_fov = math::degrees(2.0f * math::atan(math::tan(math::radians(fov) / 2.0f) * aspect));
108 float mfov = math::min(fov, horizontal_fov);
109 float target_distance = radius / (math::sin(math::radians(mfov) / 2.0f));
111 math::vec3 start_position = trans_comp.get_position_global();
112 float start_ortho_size = camera_comp.get_ortho_size();
115 math::vec3 initial_target_position{};
119 math::vec3 forward = math::normalize(trans_comp.get_z_axis_global());
120 if(math::length(forward) < 0.001f)
122 forward = math::vec3{0.0f, 0.0f, -1.0f};
124 initial_target_position = target_center - target_distance * forward;
129 math::vec3 dir = math::normalize(target_center - start_position);
130 if(math::length(dir) < 0.001f)
132 dir = math::vec3{0.0f, 0.0f, -1.0f};
134 initial_target_position = target_center - target_distance * dir;
138 float distance_to_target = math::length(start_position - initial_target_position);
139 float proximity_threshold = target_distance * 0.15f;
142 float adjusted_target_distance = target_distance;
143 if(distance_to_target < proximity_threshold)
146 adjusted_target_distance = target_distance * 3.0f;
150 math::vec3 target_position{};
153 math::vec3 forward = math::normalize(trans_comp.get_z_axis_global());
154 if(math::length(forward) < 0.001f)
156 forward = math::vec3{0.0f, 0.0f, -1.0f};
158 target_position = target_center - adjusted_target_distance * forward;
162 math::vec3 dir = math::normalize(target_center - start_position);
163 if(math::length(dir) < 0.001f)
165 dir = math::vec3{0.0f, 0.0f, -1.0f};
167 target_position = target_center - adjusted_target_distance * dir;
171 auto seq_duration = std::chrono::duration_cast<seq::duration_t>(std::chrono::duration<float>(duration));
173 struct camera_transition_state
175 math::vec3 current_position;
176 float current_ortho_size;
179 auto state = std::make_shared<camera_transition_state>();
180 state->current_position = start_position;
181 state->current_ortho_size = start_ortho_size;
183 auto position_action =
seq::change_to(state->current_position, target_position, seq_duration, state, ease);
184 auto ortho_action =
seq::change_to(state->current_ortho_size, radius, seq_duration, state, ease);
186 auto combined_action =
seq::together(position_action, ortho_action);
187 combined_action.on_update.connect([camera, state, keep_rotation, target_center]()
191 auto& tc = camera.get<transform_component>();
192 auto& cc = camera.get<camera_component>();
193 tc.set_position_global(state->current_position);
196 tc.look_at(target_center);
198 cc.set_ortho_size(state->current_ortho_size);
199 cc.update(tc.get_transform_global());
207void focus_camera_on_bounds(entt::handle camera,
const math::bsphere& bounds,
float duration)
209 run_camera_focus_transition(camera, bounds.
position, bounds.
radius,
true, duration);
212void focus_camera_on_bounds(entt::handle camera,
const math::bbox& bounds,
float duration)
215 const float radius = math::length(bounds.
get_dimensions()) / 2.0f;
216 run_camera_focus_transition(camera,
center, radius,
true, duration);
220void calc_bounds_global_impl(
math::bbox& bounds, entt::handle
entity,
int depth)
222 auto& tc =
entity.get<transform_component>();
223 const auto world_xform = tc.get_transform_global();
226 if(
auto* mc =
entity.try_get<model_component>())
228 mc->update_world_bounds(world_xform);
229 auto b = mc->get_world_bounds();
230 for(
const auto& corner :
b.get_corners())
236 if(
auto* tc =
entity.try_get<text_component>())
238 auto b = tc->get_render_bounds();
239 for(
const auto& corner :
b.get_corners())
241 bounds.
add_point(world_xform.transform_coord(corner));
245 if(
auto* pc =
entity.try_get<particle_emitter_component>())
247 auto b = pc->get_updated_world_bounds(world_xform);
248 for(
const auto& corner :
b.get_corners())
257 for(
auto child : tc.get_children())
259 calc_bounds_global_impl(bounds, child, depth > 0 ? depth - 1 : -1);
267 APPLOG_TRACE(
"{}::{}", hpp::type_name_str<defaults>(), __func__);
269 return init_assets(ctx);
274 APPLOG_TRACE(
"{}::{}", hpp::type_name_str<defaults>(), __func__);
305 const auto id =
"engine:/embedded/cube";
306 auto instance = std::make_shared<mesh>();
308 manager.get_asset_from_instance(
id, instance);
311 const auto id =
"engine:/embedded/cube_rounded";
312 auto instance = std::make_shared<mesh>();
314 manager.get_asset_from_instance(
id, instance);
317 const auto id =
"engine:/embedded/sphere";
318 auto instance = std::make_shared<mesh>();
320 manager.get_asset_from_instance(
id, instance);
323 const auto id =
"engine:/embedded/plane";
324 auto instance = std::make_shared<mesh>();
326 manager.get_asset_from_instance(
id, instance);
329 const auto id =
"engine:/embedded/cylinder";
330 auto instance = std::make_shared<mesh>();
332 manager.get_asset_from_instance(
id, instance);
335 const auto id =
"engine:/embedded/capsule_2m";
336 auto instance = std::make_shared<mesh>();
338 manager.get_asset_from_instance(
id, instance);
341 const auto id =
"engine:/embedded/capsule_1m";
342 auto instance = std::make_shared<mesh>();
344 manager.get_asset_from_instance(
id, instance);
347 const auto id =
"engine:/embedded/cone";
348 auto instance = std::make_shared<mesh>();
350 manager.get_asset_from_instance(
id, instance);
353 const auto id =
"engine:/embedded/torus";
354 auto instance = std::make_shared<mesh>();
356 manager.get_asset_from_instance(
id, instance);
359 const auto id =
"engine:/embedded/teapot";
360 auto instance = std::make_shared<mesh>();
362 manager.get_asset_from_instance(
id, instance);
365 const auto id =
"engine:/embedded/icosahedron";
366 auto instance = std::make_shared<mesh>();
368 manager.get_asset_from_instance(
id, instance);
371 const auto id =
"engine:/embedded/dodecahedron";
372 auto instance = std::make_shared<mesh>();
374 manager.get_asset_from_instance(
id, instance);
377 for(
int i = 0; i < 20; ++i)
379 const auto id = std::string(
"engine:/embedded/icosphere") + std::to_string(i);
380 auto instance = std::make_shared<mesh>();
382 manager.get_asset_from_instance(
id, instance);
412 const auto id =
"engine:/embedded/standard";
413 auto instance = std::make_shared<pbr_material>();
414 auto asset = manager.get_asset_from_instance<
material>(id, instance);
420 const auto id =
"engine:/embedded/fallback";
421 auto instance = std::make_shared<pbr_material>();
424 instance->set_roughness(1.0f);
425 auto asset = manager.get_asset_from_instance<
material>(id, instance);
438 auto lod = am.get_asset<
mesh>(id);
442 auto object = scn.create_entity(
name);
446 auto bounds = lod.get()->get_bounds();
447 transf_comp.set_position_local({0.0f, bounds.get_extents().y, 0.0f});
451 model_comp.set_casts_reflection(
false);
452 model_comp.set_model(
model);
462 auto object = scn.instantiate(asset);
471 auto object = scn.instantiate(asset);
481 const std::string& key,
483 math::vec2 pos) -> entt::handle
485 math::vec3 projected_pos{0.0f, 0.0f, 0.0f};
486 cam.viewport_to_world(pos,
491 return create_prefab_at(ctx, scn, key, projected_pos);
503 std::string
name = fs::path(key).stem().string();
504 auto object = scn.create_entity(
name);
509 model_comp.set_casts_reflection(
false);
510 model_comp.set_model(mdl);
515 if(model_comp.is_skinned())
525 const std::string& key,
527 math::vec2 pos) -> entt::handle
529 math::vec3 projected_pos{0.0f, 0.0f, 0.0f};
530 cam.viewport_to_world(pos,
535 return create_mesh_entity_at(ctx, scn, key, projected_pos);
543 auto object = scn.create_entity(
name +
" Light");
550 transf_comp.rotate_by_euler_local({50.0f, -30.0f + 180.0f, 0.0f});
575 auto object = scn.create_entity(
name +
" Probe");
594 auto object = scn.create_entity(
name);
610 auto object = scn.create_entity(
name);
617 auto object = scn.create_entity(
name);
627 auto object = scn.create_entity(
name);
634 auto object = scn.create_entity(
name);
652 auto probe = reflection_comp.
get_probe();
654 probe.sphere_data.range = 1000.0f;
669 auto probe = reflection_comp.
get_probe();
671 probe.sphere_data.range = 1000.0f;
680 auto camera = create_camera_entity(ctx, scn,
"Main Camera");
685 assao_comp->enabled =
false;
688 auto ssr_comp = camera.try_get<ssr_component>();
691 ssr_comp->enabled =
false;
696 auto& transf_comp = camera.get<transform_component>();
697 transf_comp.set_position_local({10.0f, 6.6f, 10.0f});
698 transf_comp.rotate_by_euler_local({0.0f, 180.0f, 0.0f});
699 auto& camera_comp = camera.get<camera_component>();
700 camera_comp.set_viewport_size(
size);
706 auto& light_comp =
object.get_or_emplace<light_component>();
707 auto light = light_comp.get_light();
708 light.casts_shadows =
false;
709 light_comp.set_light(light);
711 object.emplace<skylight_component>();
715 auto object = create_reflection_probe_entity(ctx, scn,
probe_type::sphere,
"Envinroment");
716 auto& reflection_comp =
object.get_or_emplace<reflection_probe_component>();
717 auto probe = reflection_comp.get_probe();
719 probe.sphere_data.range = 1000.0f;
720 reflection_comp.set_probe(probe);
733 auto camera = create_default_3d_scene_for_preview(ctx, scn,
size);
736 auto object = create_embedded_mesh_entity(ctx, scn,
"Sphere");
738 auto model = model_comp.get_model();
740 model_comp.set_model(
model);
741 model_comp.set_casts_shadow(
false);
742 model_comp.set_casts_reflection(
false);
746 ::unravel::focus_camera_on_bounds(
camera, calc_bounds_sphere_global(
object,
false));
760 auto camera = create_default_3d_scene_for_preview(ctx, scn,
size);
763 auto object = scn.instantiate(asset);
767 if(
auto model_comp =
object.try_get<model_component>())
769 model_comp->set_casts_shadow(
false);
770 model_comp->set_casts_reflection(
false);
773 auto bounds = calc_bounds_sphere_global(
object);
774 if(bounds.radius < 1.0f)
776 float scale = 1.0f / bounds.radius;
782 ::unravel::focus_camera_on_bounds(
camera, calc_bounds_sphere_global(
object));
796 auto camera = create_default_3d_scene_for_preview(ctx, scn,
size);
798 auto object = create_mesh_entity_at(ctx, scn, asset.id());
800 if(
auto model_comp =
object.try_get<model_component>())
802 model_comp->set_casts_shadow(
false);
803 model_comp->set_casts_reflection(
false);
806 auto bounds = calc_bounds_sphere_global(
object);
807 if(bounds.radius < 1.0f)
809 float scale = 1.0f / bounds.radius;
815 ::unravel::focus_camera_on_bounds(
camera, calc_bounds_sphere_global(
object));
829 for(
const auto&
entity : entities)
843 ::unravel::focus_camera_on_bounds(
camera, bounds);
849 hpp::span<const entt::handle> entities,
857 for(
const auto&
entity : entities)
871 ::unravel::focus_camera_on_bounds(
camera, bounds, duration);
880 calc_bounds_global_impl(bounds,
entity, depth);
885 const math::vec3 one{1, 1, 1};
900 math::vec3 diag =
box.get_dimensions();
901 float max_abs = math::max(math::abs(diag.x), math::max(math::abs(diag.y), math::abs(diag.z)));
902 float radius = 0.5f * (use_bbox_diagonal ? math::length(diag) : max_abs);
const btCollisionObject * object
Provides storage for common representation of spherical bounding volume, and wraps up common function...
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 listeners. There can only be one instance of it per scene.
Class that contains core data for audio sources.
Class that contains core camera data, used for rendering and other purposes.
Class representing a camera. Contains functionality for manipulating and updating a camera....
Class that contains core light data, used for rendering and other purposes.
void set_light(const light &l)
Sets the light object.
Base class for materials used in rendering.
static auto default_normal_map() -> asset_handle< gfx::texture > &
Gets the default normal map.
static auto default_color_map() -> asset_handle< gfx::texture > &
Gets the default color map.
Main class representing a 3D mesh with support for different LODs, submeshes, and skinning.
Class that contains core data for meshes.
void set_casts_shadow(bool cast_shadow)
Sets whether the model casts shadows.
Structure describing a LOD group (set of meshes), LOD transitions, and their materials.
static auto fallback_material() -> asset_handle< material > &
Gets the fallback material.
void set_material(asset_handle< material > material, uint32_t index)
Sets the material for the specified index.
static auto default_material() -> asset_handle< material > &
Gets the default material.
void set_lod(asset_handle< mesh > mesh, uint32_t lod)
Sets the LOD (Level of Detail) mesh for the specified level.
Component that wraps particle system emitter functionality.
Class that contains core reflection probe data, used for rendering and other purposes.
auto get_probe() const -> const reflection_probe &
Gets the reflection probe object.
void set_probe(const reflection_probe &probe)
Sets the reflection probe object.
Class that contains sky light data.
void set_text(const std::string &text)
Sets the text content to be rendered.
#define APPLOG_TRACE(...)
float smooth_stop(float progress)
Modelled after quarter-cycle of sine wave (different phase)
void stop_all(const std::string &scope)
Stops all actions within the specified scope.
auto start(seq_action action, const seq_scope_policy &scope_policy, hpp::source_location location) -> seq_id_t
Starts a new action.
auto together(const std::vector< seq_action > &actions, const sentinel_t &sentinel) -> seq_action
Creates a simultaneous action that executes a list of actions together.
auto change_to(T &object, const std::decay_t< T > &end, const duration_t &duration, const sentinel_t &sentinel, const ease_t &ease_func=ease::linear) -> seq_action
Creates an action to change an object to a specified value over a specified duration.
auto replace(const std::string &str, const std::string &search, const std::string &replace) -> std::string
auto to_lower(const std::string &str) -> std::string
probe_type
Enum class representing the type of reflection probe.
@ sphere
Sphere type reflection probe.
@ box
Box type reflection probe.
light_type
Enum representing the type of light.
@ environment
Environment reflection method.
@ static_only
Static-only reflection method.
Represents a handle to an asset, providing access and management functions.
static auto get_layout() -> const vertex_layout &
Storage for box vector values and wraps up common functionality.
bbox & add_point(const vec3 &point)
Grows the bounding box based on the point passed.
bool is_populated() const
Checks if the bounding box is populated.
vec3 get_dimensions() const
Returns a vector containing the dimensions of the bounding box.
vec3 get_center() const
Returns a vector containing the exact center point of the box.
static auto from_point_normal(const vec3 &point, const vec3 &normal) -> plane
Creates a plane from a point and a normal.
Creates a default 3D scene for asset preview.
static auto create_reflection_probe_entity(rtti::context &ctx, scene &scn, probe_type type, const std::string &name) -> entt::handle
Creates a reflection probe entity.
static auto init_assets(rtti::context &ctx) -> bool
Initializes default assets.
static auto init(rtti::context &ctx) -> bool
Initializes default settings and assets.
static auto create_ui_document_entity(rtti::context &ctx, scene &scn, const std::string &name) -> entt::handle
Creates a UI document entity.
static auto create_text_entity(rtti::context &ctx, scene &scn, const std::string &name) -> entt::handle
Creates a text entity.
static auto create_audio_source_entity(rtti::context &ctx, scene &scn, const std::string &name) -> entt::handle
Creates a audio source entity.
static auto create_embedded_mesh_entity(rtti::context &ctx, scene &scn, const std::string &name) -> entt::handle
Creates an embedded mesh entity.
static auto calc_bounds_sphere_global(entt::handle entity, bool use_bbox_diagonal=true) -> math::bsphere
Calculates the bounding sphere of an entity.
static void focus_camera_on_entities(entt::handle camera, hpp::span< const entt::handle > entities)
Focuses a camera on a specified entity.
static auto create_particle_emitter_entity(rtti::context &ctx, scene &scn, const std::string &name) -> entt::handle
Creates a particle emitter entity.
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 calc_bounds_global(entt::handle entity, int depth=-1) -> math::bbox
Calculates the bounding box of an entity.
static auto create_light_entity(rtti::context &ctx, scene &scn, light_type type, const std::string &name) -> entt::handle
Creates a light entity.
static auto create_prefab_at(rtti::context &ctx, scene &scn, const std::string &key, const camera &cam, math::vec2 pos) -> entt::handle
Creates a prefab entity at a specified position.
static void create_default_3d_scene_for_editing(rtti::context &ctx, scene &scn)
Creates a default 3D scene for editing.
static auto create_camera_entity(rtti::context &ctx, scene &scn, const std::string &name) -> entt::handle
Creates a camera entity.
static auto create_mesh_entity_at(rtti::context &ctx, scene &scn, const std::string &key, const camera &cam, math::vec2 pos) -> entt::handle
Creates a mesh entity at a specified position.
static void create_default_3d_scene(rtti::context &ctx, scene &scn)
Creates a default 3D scene.
static auto deinit(rtti::context &ctx) -> bool
Deinitializes default settings and assets.
static auto default_light() -> asset_handle< font > &
static auto default_heavy() -> asset_handle< font > &
static auto default_extra_light() -> asset_handle< font > &
static auto default_regular() -> asset_handle< font > &
static auto default_bold() -> asset_handle< font > &
static auto default_semi_bold() -> asset_handle< font > &
static auto default_thin() -> asset_handle< font > &
static auto default_black() -> asset_handle< font > &
static auto default_medium() -> asset_handle< font > &
Struct representing a light.
light_type type
The type of the light.
math::color color
The color of the light.
float ambient_intensity
The ambient intensity of the light.
Represents a generic prefab with a buffer for serialized data.
Structure representing a reflection probe.
probe_type type
Type of the reflection probe.
reflect_method method
Reflection method.
Represents a scene in the ACE framework, managing entities and their relationships.
Component that holds a reference to a UI document for RmlUi rendering.