From d65a30be75ad6ba8fa32906566036c438b290ba0 Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Wed, 20 Oct 2021 19:09:10 +0800 Subject: [PATCH] Add functions for getting both local and world space bounds from scene objects --- src/game/states/loading.cpp | 12 +++++------- src/renderer/renderer.cpp | 8 ++++---- src/scene/billboard.cpp | 10 ++++++---- src/scene/billboard.hpp | 16 +++++++++++----- src/scene/camera.hpp | 11 +++++++++-- src/scene/light.cpp | 5 +++-- src/scene/light.hpp | 20 ++++++++++++++------ src/scene/lod-group.cpp | 5 +++-- src/scene/lod-group.hpp | 15 +++++++++++---- src/scene/model-instance.cpp | 18 +++++++++++++----- src/scene/model-instance.hpp | 15 +++++++++++---- src/scene/object.hpp | 9 +++++++-- src/scene/text.hpp | 14 +++++++++++--- 13 files changed, 108 insertions(+), 50 deletions(-) diff --git a/src/game/states/loading.cpp b/src/game/states/loading.cpp index 7180e1c..a2ba84c 100644 --- a/src/game/states/loading.cpp +++ b/src/game/states/loading.cpp @@ -318,13 +318,11 @@ void load_fonts(game::context* ctx) // Add text object to UI scene ctx->ui_scene->add_object(text_object); - - /* - // Output font bitmap - std::string bitmap_path = ctx->config_path + "bitmap-font-serif.png"; - stbi_flip_vertically_on_write(0); - stbi_write_png(bitmap_path.c_str(), font_bitmap.get_width(), font_bitmap.get_height(), font_bitmap.get_channel_count(), font_bitmap.get_pixels(), font_bitmap.get_width() * font_bitmap.get_channel_count()); - */ + // Center text object + const auto& text_aabb = static_cast&>(text_object->get_local_bounds()); + float text_w = text_aabb.max_point.x - text_aabb.min_point.x; + float text_h = text_aabb.max_point.y - text_aabb.min_point.y; + text_object->set_translation({std::round(-text_w * 0.5f), std::round(-text_h * 0.5f), 0.0f}); } } diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 5a7c6e8..0e9fac8 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -103,7 +103,7 @@ void renderer::render(float t, float dt, float alpha, const scene::collection& c // Get camera culling volume ctx.camera_culling_volume = camera->get_culling_mask(); if (!ctx.camera_culling_volume) - ctx.camera_culling_volume = &camera->get_bounds(); + ctx.camera_culling_volume = &camera->get_world_bounds(); // Queue render operations for each visible scene object for (const scene::object_base* object: *objects) @@ -149,7 +149,7 @@ void renderer::process_model_instance(const render::context& ctx, render::queue& // Get object culling volume const geom::bounding_volume* object_culling_volume = model_instance->get_culling_mask(); if (!object_culling_volume) - object_culling_volume = &model_instance->get_bounds(); + object_culling_volume = &model_instance->get_world_bounds(); // Perform view-frustum culling if (!ctx.camera_culling_volume->intersects(*object_culling_volume)) @@ -188,7 +188,7 @@ void renderer::process_billboard(const render::context& ctx, render::queue& queu // Get object culling volume const geom::bounding_volume* object_culling_volume = billboard->get_culling_mask(); if (!object_culling_volume) - object_culling_volume = &billboard->get_bounds(); + object_culling_volume = &billboard->get_world_bounds(); // Perform view-frustum culling if (!ctx.camera_culling_volume->intersects(*object_culling_volume)) @@ -236,7 +236,7 @@ void renderer::process_text(const render::context& ctx, render::queue& queue, co // Get object culling volume const geom::bounding_volume* object_culling_volume = text->get_culling_mask(); if (!object_culling_volume) - object_culling_volume = &text->get_bounds(); + object_culling_volume = &text->get_world_bounds(); // Perform view-frustum culling if (!ctx.camera_culling_volume->intersects(*object_culling_volume)) diff --git a/src/scene/billboard.cpp b/src/scene/billboard.cpp index f030114..dad95c9 100644 --- a/src/scene/billboard.cpp +++ b/src/scene/billboard.cpp @@ -23,10 +23,10 @@ namespace scene { -const typename billboard::aabb_type billboard::untransformed_bounds = {{-1, -1, -1}, {1, 1, 1}}; +const typename billboard::aabb_type billboard::local_bounds = {{-1, -1, -1}, {1, 1, 1}}; billboard::billboard(): - bounds(untransformed_bounds), + world_bounds(local_bounds), material(nullptr), type(billboard_type::flat), alignment_axis(global_up) @@ -39,10 +39,12 @@ billboard::billboard(const billboard& other) billboard& billboard::operator=(const billboard& other) { - bounds = other.bounds; material = other.material; type = other.type; alignment_axis = other.alignment_axis; + set_transform(other.get_transform()); + set_active(other.is_active()); + set_culling_mask(other.get_culling_mask()); return *this; } @@ -63,7 +65,7 @@ void billboard::set_alignment_axis(const float3& axis) void billboard::transformed() { - bounds = aabb_type::transform(untransformed_bounds, get_transform()); + world_bounds = aabb_type::transform(local_bounds, get_transform()); } void billboard::update_tweens() diff --git a/src/scene/billboard.hpp b/src/scene/billboard.hpp index 53d7e9c..c826930 100644 --- a/src/scene/billboard.hpp +++ b/src/scene/billboard.hpp @@ -61,7 +61,8 @@ public: /// Sets the axis around which the billboard will be rotated when the alignment is set to billboard_alignment::cylindrical. void set_alignment_axis(const float3& axis); - virtual const bounding_volume_type& get_bounds() const; + virtual const bounding_volume_type& get_local_bounds() const; + virtual const bounding_volume_type& get_world_bounds() const; material* get_material() const; billboard_type get_billboard_type() const; @@ -70,20 +71,25 @@ public: virtual void update_tweens(); private: - static const aabb_type untransformed_bounds; + static const aabb_type local_bounds; virtual void transformed(); - aabb_type bounds; + aabb_type world_bounds; material* material; billboard_type type; float3 alignment_axis; }; -inline const typename object_base::bounding_volume_type& billboard::get_bounds() const +inline const typename object_base::bounding_volume_type& billboard::get_local_bounds() const { - return bounds; + return local_bounds; +} + +inline const typename object_base::bounding_volume_type& billboard::get_world_bounds() const +{ + return world_bounds; } inline material* billboard::get_material() const diff --git a/src/scene/camera.hpp b/src/scene/camera.hpp index 65da8f5..53a58c9 100644 --- a/src/scene/camera.hpp +++ b/src/scene/camera.hpp @@ -89,7 +89,8 @@ public: void set_composite_index(int index); - virtual const bounding_volume_type& get_bounds() const; + virtual const bounding_volume_type& get_local_bounds() const; + virtual const bounding_volume_type& get_world_bounds() const; float is_orthographic() const; float get_clip_left() const; @@ -157,7 +158,13 @@ private: view_frustum_type view_frustum; }; -inline const typename object_base::bounding_volume_type& camera::get_bounds() const +inline const typename object_base::bounding_volume_type& camera::get_local_bounds() const +{ + /// @TODO: return local bounds, not world bounds + return view_frustum.get_bounds(); +} + +inline const typename object_base::bounding_volume_type& camera::get_world_bounds() const { return view_frustum.get_bounds(); } diff --git a/src/scene/light.cpp b/src/scene/light.cpp index d28bac7..0e0bbfa 100644 --- a/src/scene/light.cpp +++ b/src/scene/light.cpp @@ -23,7 +23,8 @@ namespace scene { light::light(): - bounds(get_translation(), 0.0f), + local_bounds{{0.0f, 0.0f, 0.0f}, 0.0f}, + world_bounds{{0.0f, 0.0f, 0.0f}, 0.0f}, color(float3{1.0f, 1.0f, 1.0f}, math::lerp), intensity(1.0f, math::lerp), scaled_color(float3{1.0f, 1.0f, 1.0f}, math::lerp) @@ -51,7 +52,7 @@ void light::update_tweens() void light::transformed() { - bounds = sphere_type(get_translation(), 0.0f); + world_bounds = {get_translation(), 0.0f}; } } // namespace scene diff --git a/src/scene/light.hpp b/src/scene/light.hpp index d81786e..adb439d 100644 --- a/src/scene/light.hpp +++ b/src/scene/light.hpp @@ -70,8 +70,11 @@ public: */ void set_intensity(float intensity); - /// Returns the bounding volume of the light. - virtual const bounding_volume_type& get_bounds() const; + /// Returns the local-space bounding volume of the light. + virtual const bounding_volume_type& get_local_bounds() const; + + /// Returns the world-space bounding volume of the light. + virtual const bounding_volume_type& get_world_bounds() const; /// Returns the light color. const float3& get_color() const; @@ -95,12 +98,18 @@ private: tween color; tween intensity; tween scaled_color; - sphere_type bounds; + sphere_type local_bounds; + sphere_type world_bounds; }; -inline const typename object_base::bounding_volume_type& light::get_bounds() const +inline const typename object_base::bounding_volume_type& light::get_local_bounds() const { - return bounds; + return local_bounds; +} + +inline const typename object_base::bounding_volume_type& light::get_world_bounds() const +{ + return world_bounds; } inline const float3& light::get_color() const @@ -136,4 +145,3 @@ inline const tween& light::get_scaled_color_tween() const } // namespace scene #endif // ANTKEEPER_SCENE_LIGHT_HPP - diff --git a/src/scene/lod-group.cpp b/src/scene/lod-group.cpp index 64b57f6..0cd9903 100644 --- a/src/scene/lod-group.cpp +++ b/src/scene/lod-group.cpp @@ -23,7 +23,8 @@ namespace scene { lod_group::lod_group(std::size_t level_count): - bounds(get_translation(), get_translation()) + local_bounds{{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}, + world_bounds{{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}} { resize(level_count); } @@ -68,7 +69,7 @@ void lod_group::remove_objects(std::size_t level) void lod_group::update_bounds() { - bounds = {get_translation(), get_translation()}; + world_bounds = {get_translation(), get_translation()}; } void lod_group::transformed() diff --git a/src/scene/lod-group.hpp b/src/scene/lod-group.hpp index 1d2795f..04984eb 100644 --- a/src/scene/lod-group.hpp +++ b/src/scene/lod-group.hpp @@ -82,7 +82,8 @@ public: */ void remove_objects(std::size_t level); - virtual const bounding_volume_type& get_bounds() const; + virtual const bounding_volume_type& get_local_bounds() const; + virtual const bounding_volume_type& get_world_bounds() const; /// Returns the number of detail levels in the group. std::size_t get_level_count() const; @@ -99,13 +100,19 @@ private: void update_bounds(); virtual void transformed(); - aabb_type bounds; + aabb_type local_bounds; + aabb_type world_bounds; std::vector> levels; }; -inline const typename object_base::bounding_volume_type& lod_group::get_bounds() const +inline const typename object_base::bounding_volume_type& lod_group::get_local_bounds() const { - return bounds; + return local_bounds; +} + +inline const typename object_base::bounding_volume_type& lod_group::get_world_bounds() const +{ + return world_bounds; } inline std::size_t lod_group::get_level_count() const diff --git a/src/scene/model-instance.cpp b/src/scene/model-instance.cpp index 5602d94..4bca3e6 100644 --- a/src/scene/model-instance.cpp +++ b/src/scene/model-instance.cpp @@ -26,7 +26,8 @@ namespace scene { model_instance::model_instance(::model* model): model(nullptr), pose(nullptr), - bounds(get_translation(), get_translation()), + local_bounds{{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}, + world_bounds{{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}, instanced(false), instance_count(0) { @@ -45,7 +46,8 @@ model_instance::model_instance(const model_instance& other) model_instance& model_instance::operator=(const model_instance& other) { - bounds = other.bounds; + local_bounds = other.local_bounds; + world_bounds = other.world_bounds; model = other.model; pose = other.pose; materials = other.materials; @@ -92,14 +94,20 @@ void model_instance::reset_materials() void model_instance::update_bounds() { if (model) - bounds = aabb_type::transform(model->get_bounds(), get_transform()); + { + local_bounds = aabb_type::transform(model->get_bounds(), get_transform()); + transformed(); + } else - bounds = {get_translation(), get_translation()}; + { + local_bounds = {{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}; + world_bounds = {get_translation(), get_translation()}; + } } void model_instance::transformed() { - update_bounds(); + world_bounds = aabb_type::transform(local_bounds, get_transform()); } void model_instance::update_tweens() diff --git a/src/scene/model-instance.hpp b/src/scene/model-instance.hpp index 2369f69..8de493d 100644 --- a/src/scene/model-instance.hpp +++ b/src/scene/model-instance.hpp @@ -65,7 +65,8 @@ public: */ void reset_materials(); - virtual const bounding_volume_type& get_bounds() const; + virtual const bounding_volume_type& get_local_bounds() const; + virtual const bounding_volume_type& get_world_bounds() const; const model* get_model() const; model* get_model(); @@ -88,14 +89,20 @@ private: model* model; pose* pose; std::vector materials; - aabb_type bounds; + aabb_type local_bounds; + aabb_type world_bounds; bool instanced; std::size_t instance_count; }; -inline const typename object_base::bounding_volume_type& model_instance::get_bounds() const +inline const typename object_base::bounding_volume_type& model_instance::get_local_bounds() const { - return bounds; + return local_bounds; +} + +inline const typename object_base::bounding_volume_type& model_instance::get_world_bounds() const +{ + return world_bounds; } inline const model* model_instance::get_model() const diff --git a/src/scene/object.hpp b/src/scene/object.hpp index fd76931..64eec6a 100644 --- a/src/scene/object.hpp +++ b/src/scene/object.hpp @@ -137,9 +137,14 @@ public: tween& get_transform_tween(); /** - * Returns the bounds of the object. + * Returns the local-space (untransformed) bounds of the object. */ - virtual const bounding_volume_type& get_bounds() const = 0; + virtual const bounding_volume_type& get_local_bounds() const = 0; + + /** + * Returns the world-space (transformed) bounds of the object. + */ + virtual const bounding_volume_type& get_world_bounds() const = 0; /** * Returns the culling mask of the object. diff --git a/src/scene/text.hpp b/src/scene/text.hpp index a56a258..26a11ef 100644 --- a/src/scene/text.hpp +++ b/src/scene/text.hpp @@ -105,8 +105,11 @@ public: /// Returns the text color. const float4& get_color() const; - /// @copydoc scene::object::get_bounds() const - virtual const bounding_volume_type& get_bounds() const; + /// @copydoc scene::object::get_local_bounds() const + virtual const bounding_volume_type& get_local_bounds() const; + + /// @copydoc scene::object::get_world_bounds() const + virtual const bounding_volume_type& get_world_bounds() const; /// @copydoc scene::object::update_tweens() virtual void update_tweens(); @@ -158,7 +161,12 @@ inline const float4& text::get_color() const return color; } -inline const typename object_base::bounding_volume_type& text::get_bounds() const +inline const typename object_base::bounding_volume_type& text::get_local_bounds() const +{ + return local_bounds; +} + +inline const typename object_base::bounding_volume_type& text::get_world_bounds() const { return world_bounds; }