32void focus_camera_on_bounds(entt::handle camera,
const math::bsphere& bounds)
34 auto& trans_comp = camera.get<transform_component>();
35 auto& camera_comp = camera.get<camera_component>();
36 const auto& cam = camera_comp.get_camera();
40 float aspect = cam.get_aspect_ratio();
41 float fov = cam.get_fov();
43 float radius = bounds.
radius;
46 float hfov = math::degrees(2.0f * math::atan(math::tan(math::radians(fov) / 2.0f) * aspect));
48 float mfov = math::min(fov, hfov);
49 float dist = radius / (math::sin(math::radians(mfov) / 2.0f));
51 trans_comp.look_at(cen);
52 trans_comp.set_position_global(cen - dist * trans_comp.get_z_axis_global());
53 camera_comp.set_ortho_size(radius);
54 camera_comp.update(trans_comp.get_transform_global());
57void focus_camera_on_bounds(entt::handle camera,
const math::bbox& bounds)
59 auto& trans_comp = camera.get<transform_component>();
60 auto& camera_comp = camera.get<camera_component>();
61 const auto& cam = camera_comp.get_camera();
66 float aspect = cam.get_aspect_ratio();
67 float fov = cam.get_fov();
69 float radius = math::length(
size) / 2.0f;
72 float horizontal_fov = math::degrees(2.0f * math::atan(math::tan(math::radians(fov) / 2.0f) * aspect));
74 float mfov = math::min(fov, horizontal_fov);
75 float dist = radius / (math::sin(math::radians(mfov) / 2.0f));
77 trans_comp.look_at(cen);
78 trans_comp.set_position_global(cen - dist * trans_comp.get_z_axis_global());
79 camera_comp.set_ortho_size(radius);
80 camera_comp.update(trans_comp.get_transform_global());
84void run_camera_focus_transition(entt::handle camera,
85 const math::vec3& target_center,
90 if(duration <= 0.0f || !camera.all_of<transform_component, camera_component>())
95 ::unravel::focus_camera_on_bounds(camera, bs);
99 auto& trans_comp = camera.get<transform_component>();
100 auto& camera_comp = camera.get<camera_component>();
101 const auto& cam = camera_comp.get_camera();
103 float aspect = cam.get_aspect_ratio();
104 float fov = cam.get_fov();
105 float horizontal_fov = math::degrees(2.0f * math::atan(math::tan(math::radians(fov) / 2.0f) * aspect));
106 float mfov = math::min(fov, horizontal_fov);
107 float target_distance = radius / (math::sin(math::radians(mfov) / 2.0f));
109 math::vec3 start_position = trans_comp.get_position_global();
110 float start_ortho_size = camera_comp.get_ortho_size();
113 math::vec3 initial_target_position{};
117 math::vec3 forward = math::normalize(trans_comp.get_z_axis_global());
118 if(math::length(forward) < 0.001f)
120 forward = math::vec3{0.0f, 0.0f, -1.0f};
122 initial_target_position = target_center - target_distance * forward;
127 math::vec3 dir = math::normalize(target_center - start_position);
128 if(math::length(dir) < 0.001f)
130 dir = math::vec3{0.0f, 0.0f, -1.0f};
132 initial_target_position = target_center - target_distance * dir;
136 float distance_to_target = math::length(start_position - initial_target_position);
137 float proximity_threshold = target_distance * 0.15f;
140 float adjusted_target_distance = target_distance;
141 if(distance_to_target < proximity_threshold)
144 adjusted_target_distance = target_distance * 3.0f;
148 math::vec3 target_position{};
151 math::vec3 forward = math::normalize(trans_comp.get_z_axis_global());
152 if(math::length(forward) < 0.001f)
154 forward = math::vec3{0.0f, 0.0f, -1.0f};
156 target_position = target_center - adjusted_target_distance * forward;
160 math::vec3 dir = math::normalize(target_center - start_position);
161 if(math::length(dir) < 0.001f)
163 dir = math::vec3{0.0f, 0.0f, -1.0f};
165 target_position = target_center - adjusted_target_distance * dir;
169 auto seq_duration = std::chrono::duration_cast<seq::duration_t>(std::chrono::duration<float>(duration));
171 struct camera_transition_state
173 math::vec3 current_position;
174 float current_ortho_size;
177 auto state = std::make_shared<camera_transition_state>();
178 state->current_position = start_position;
179 state->current_ortho_size = start_ortho_size;
181 auto position_action =
seq::change_to(state->current_position, target_position, seq_duration, state, ease);
182 auto ortho_action =
seq::change_to(state->current_ortho_size, radius, seq_duration, state, ease);
184 auto combined_action =
seq::together(position_action, ortho_action);
185 combined_action.on_update.connect([camera, state, keep_rotation, target_center]()
189 auto& tc = camera.get<transform_component>();
190 auto& cc = camera.get<camera_component>();
191 tc.set_position_global(state->current_position);
194 tc.look_at(target_center);
196 cc.set_ortho_size(state->current_ortho_size);
197 cc.update(tc.get_transform_global());
205void focus_camera_on_bounds(entt::handle camera,
const math::bsphere& bounds,
float duration)
207 run_camera_focus_transition(camera, bounds.
position, bounds.
radius,
true, duration);
210void focus_camera_on_bounds(entt::handle camera,
const math::bbox& bounds,
float duration)
213 const float radius = math::length(bounds.
get_dimensions()) / 2.0f;
214 run_camera_focus_transition(camera,
center, radius,
true, duration);
218void calc_bounds_global_impl(
math::bbox& bounds, entt::handle
entity,
int depth)
220 auto& tc =
entity.get<transform_component>();
221 const auto world_xform = tc.get_transform_global();
224 if(
auto* mc =
entity.try_get<model_component>())
226 mc->update_world_bounds(world_xform);
227 auto b = mc->get_world_bounds();
228 for(
const auto& corner :
b.get_corners())
234 if(
auto* tc =
entity.try_get<text_component>())
236 auto b = tc->get_render_bounds();
237 for(
const auto& corner :
b.get_corners())
239 bounds.
add_point(world_xform.transform_coord(corner));
246 for(
auto child : tc.get_children())
248 calc_bounds_global_impl(bounds, child, depth > 0 ? depth - 1 : -1);
256 APPLOG_TRACE(
"{}::{}", hpp::type_name_str<defaults>(), __func__);
258 return init_assets(ctx);
263 APPLOG_TRACE(
"{}::{}", hpp::type_name_str<defaults>(), __func__);
294 const auto id =
"engine:/embedded/cube";
295 auto instance = std::make_shared<mesh>();
297 manager.get_asset_from_instance(
id, instance);
300 const auto id =
"engine:/embedded/cube_rounded";
301 auto instance = std::make_shared<mesh>();
303 manager.get_asset_from_instance(
id, instance);
306 const auto id =
"engine:/embedded/sphere";
307 auto instance = std::make_shared<mesh>();
309 manager.get_asset_from_instance(
id, instance);
312 const auto id =
"engine:/embedded/plane";
313 auto instance = std::make_shared<mesh>();
315 manager.get_asset_from_instance(
id, instance);
318 const auto id =
"engine:/embedded/cylinder";
319 auto instance = std::make_shared<mesh>();
321 manager.get_asset_from_instance(
id, instance);
324 const auto id =
"engine:/embedded/capsule_2m";
325 auto instance = std::make_shared<mesh>();
327 manager.get_asset_from_instance(
id, instance);
330 const auto id =
"engine:/embedded/capsule_1m";
331 auto instance = std::make_shared<mesh>();
333 manager.get_asset_from_instance(
id, instance);
336 const auto id =
"engine:/embedded/cone";
337 auto instance = std::make_shared<mesh>();
339 manager.get_asset_from_instance(
id, instance);
342 const auto id =
"engine:/embedded/torus";
343 auto instance = std::make_shared<mesh>();
345 manager.get_asset_from_instance(
id, instance);
348 const auto id =
"engine:/embedded/teapot";
349 auto instance = std::make_shared<mesh>();
351 manager.get_asset_from_instance(
id, instance);
354 const auto id =
"engine:/embedded/icosahedron";
355 auto instance = std::make_shared<mesh>();
357 manager.get_asset_from_instance(
id, instance);
360 const auto id =
"engine:/embedded/dodecahedron";
361 auto instance = std::make_shared<mesh>();
363 manager.get_asset_from_instance(
id, instance);
366 for(
int i = 0; i < 20; ++i)
368 const auto id = std::string(
"engine:/embedded/icosphere") + std::to_string(i);
369 auto instance = std::make_shared<mesh>();
371 manager.get_asset_from_instance(
id, instance);
401 const auto id =
"engine:/embedded/standard";
402 auto instance = std::make_shared<pbr_material>();
403 auto asset = manager.get_asset_from_instance<
material>(id, instance);
409 const auto id =
"engine:/embedded/fallback";
410 auto instance = std::make_shared<pbr_material>();
413 instance->set_roughness(1.0f);
414 auto asset = manager.get_asset_from_instance<
material>(id, instance);
427 auto lod = am.get_asset<
mesh>(id);
431 auto object = scn.create_entity(
name);
435 auto bounds = lod.get()->get_bounds();
436 transf_comp.set_position_local({0.0f, bounds.get_extents().y, 0.0f});
440 model_comp.set_casts_reflection(
false);
441 model_comp.set_model(
model);
451 auto object = scn.instantiate(asset);
460 auto object = scn.instantiate(asset);
470 const std::string& key,
472 math::vec2 pos) -> entt::handle
474 math::vec3 projected_pos{0.0f, 0.0f, 0.0f};
475 cam.viewport_to_world(pos,
480 return create_prefab_at(ctx, scn, key, projected_pos);
492 std::string
name = fs::path(key).stem().string();
493 auto object = scn.create_entity(
name);
498 model_comp.set_casts_reflection(
false);
499 model_comp.set_model(mdl);
504 if(model_comp.is_skinned())
514 const std::string& key,
516 math::vec2 pos) -> entt::handle
518 math::vec3 projected_pos{0.0f, 0.0f, 0.0f};
519 cam.viewport_to_world(pos,
524 return create_mesh_entity_at(ctx, scn, key, projected_pos);
532 auto object = scn.create_entity(
name +
" Light");
539 transf_comp.rotate_by_euler_local({50.0f, -30.0f + 180.0f, 0.0f});
564 auto object = scn.create_entity(
name +
" Probe");
583 auto object = scn.create_entity(
name);
599 auto object = scn.create_entity(
name);
606 auto object = scn.create_entity(
name);
628 auto probe = reflection_comp.
get_probe();
630 probe.sphere_data.range = 1000.0f;
645 auto probe = reflection_comp.
get_probe();
647 probe.sphere_data.range = 1000.0f;
656 auto camera = create_camera_entity(ctx, scn,
"Main Camera");
661 assao_comp->enabled =
false;
664 auto ssr_comp = camera.try_get<ssr_component>();
667 ssr_comp->enabled =
false;
672 auto& transf_comp = camera.get<transform_component>();
673 transf_comp.set_position_local({10.0f, 6.6f, 10.0f});
674 transf_comp.rotate_by_euler_local({0.0f, 180.0f, 0.0f});
675 auto& camera_comp = camera.get<camera_component>();
676 camera_comp.set_viewport_size(
size);
682 auto& light_comp =
object.get_or_emplace<light_component>();
683 auto light = light_comp.get_light();
684 light.casts_shadows =
false;
685 light_comp.set_light(light);
687 object.emplace<skylight_component>();
691 auto object = create_reflection_probe_entity(ctx, scn,
probe_type::sphere,
"Envinroment");
692 auto& reflection_comp =
object.get_or_emplace<reflection_probe_component>();
693 auto probe = reflection_comp.get_probe();
695 probe.sphere_data.range = 1000.0f;
696 reflection_comp.set_probe(probe);
708 auto camera = create_default_3d_scene_for_preview(ctx, scn,
size);
713 auto model = model_comp.get_model();
715 model_comp.set_model(
model);
716 model_comp.set_casts_shadow(
false);
717 model_comp.set_casts_reflection(
false);
729 auto camera = create_default_3d_scene_for_preview(ctx, scn,
size);
736 if(
auto model_comp =
object.try_get<model_component>())
738 model_comp->set_casts_shadow(
false);
739 model_comp->set_casts_reflection(
false);
743 if(bounds.radius < 1.0f)
745 float scale = 1.0f / bounds.radius;
760 auto camera = create_default_3d_scene_for_preview(ctx, scn,
size);
765 if(
auto model_comp =
object.try_get<model_component>())
767 model_comp->set_casts_shadow(
false);
768 model_comp->set_casts_reflection(
false);
772 if(bounds.radius < 1.0f)
774 float scale = 1.0f / bounds.radius;
790 for(
const auto&
entity : entities)
804 ::unravel::focus_camera_on_bounds(
camera, bounds);
810 const std::vector<entt::handle>& entities,
818 for(
const auto&
entity : entities)
832 ::unravel::focus_camera_on_bounds(
camera, bounds, duration);
841 calc_bounds_global_impl(bounds,
entity, depth);
846 const math::vec3 one{1, 1, 1};
861 math::vec3 diag =
box.get_dimensions();
862 float max_abs = math::max(math::abs(diag.x), math::max(math::abs(diag.y), math::abs(diag.z)));
863 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 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.
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.
auto id() const -> const std::string &
Gets the string identifier of the asset.
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.
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 void focus_camera_on_entities(entt::handle camera, const std::vector< entt::handle > &entities)
Focuses a camera on a specified entity.
static auto create_text_entity(rtti::context &ctx, scene &scn, const std::string &name) -> entt::handle
Creates a text entity.
static void create_default_3d_scene_for_asset_preview(rtti::context &ctx, scene &scn, const asset_handle< T > &asset, const usize32_t &size)
Creates a default 3D scene for asset preview.
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 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.
auto instantiate(const asset_handle< prefab > &pfb) -> entt::handle
Component that holds a reference to a UI document for RmlUi rendering.