mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-16 14:08:59 +07:00
camera modes
This commit is contained in:
@@ -17,32 +17,50 @@ namespace e2d
|
|||||||
class camera final {
|
class camera final {
|
||||||
public:
|
public:
|
||||||
class gizmos final {};
|
class gizmos final {};
|
||||||
|
public:
|
||||||
|
ENUM_HPP_CLASS_DECL(modes, u8,
|
||||||
|
(manual)
|
||||||
|
(stretch)
|
||||||
|
(flexible)
|
||||||
|
(fixed_fit)
|
||||||
|
(fixed_crop))
|
||||||
public:
|
public:
|
||||||
camera() = default;
|
camera() = default;
|
||||||
|
|
||||||
camera& depth(i32 value) noexcept;
|
camera& depth(i32 value) noexcept;
|
||||||
|
camera& mode(modes value) noexcept;
|
||||||
camera& znear(f32 value) noexcept;
|
camera& znear(f32 value) noexcept;
|
||||||
camera& zfar(f32 value) noexcept;
|
camera& zfar(f32 value) noexcept;
|
||||||
|
camera& view(const m4f& value) noexcept;
|
||||||
camera& viewport(const b2f& value) noexcept;
|
camera& viewport(const b2f& value) noexcept;
|
||||||
|
camera& projection(const m4f& value) noexcept;
|
||||||
camera& target(const render_target_ptr& value) noexcept;
|
camera& target(const render_target_ptr& value) noexcept;
|
||||||
camera& background(const color& value) noexcept;
|
camera& background(const color& value) noexcept;
|
||||||
|
|
||||||
[[nodiscard]] i32 depth() const noexcept;
|
[[nodiscard]] i32 depth() const noexcept;
|
||||||
|
[[nodiscard]] modes mode() const noexcept;
|
||||||
[[nodiscard]] f32 znear() const noexcept;
|
[[nodiscard]] f32 znear() const noexcept;
|
||||||
[[nodiscard]] f32 zfar() const noexcept;
|
[[nodiscard]] f32 zfar() const noexcept;
|
||||||
|
[[nodiscard]] const m4f& view() const noexcept;
|
||||||
[[nodiscard]] const b2f& viewport() const noexcept;
|
[[nodiscard]] const b2f& viewport() const noexcept;
|
||||||
|
[[nodiscard]] const m4f& projection() const noexcept;
|
||||||
[[nodiscard]] const render_target_ptr& target() const noexcept;
|
[[nodiscard]] const render_target_ptr& target() const noexcept;
|
||||||
[[nodiscard]] const color& background() const noexcept;
|
[[nodiscard]] const color& background() const noexcept;
|
||||||
private:
|
private:
|
||||||
i32 depth_ = 0;
|
i32 depth_ = 0;
|
||||||
|
modes mode_ = modes::flexible;
|
||||||
f32 znear_ = 0.f;
|
f32 znear_ = 0.f;
|
||||||
f32 zfar_ = 1000.f;
|
f32 zfar_ = 1000.f;
|
||||||
|
m4f view_ = m4f::identity();
|
||||||
b2f viewport_ = b2f::unit();
|
b2f viewport_ = b2f::unit();
|
||||||
|
m4f projection_ = m4f::identity();
|
||||||
render_target_ptr target_ = nullptr;
|
render_target_ptr target_ = nullptr;
|
||||||
color background_ = color::clear();
|
color background_ = color::clear();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ENUM_HPP_REGISTER_TRAITS(e2d::camera::modes)
|
||||||
|
|
||||||
namespace e2d
|
namespace e2d
|
||||||
{
|
{
|
||||||
template <>
|
template <>
|
||||||
@@ -92,6 +110,11 @@ namespace e2d
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline camera& camera::mode(modes value) noexcept {
|
||||||
|
mode_ = value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
inline camera& camera::znear(f32 value) noexcept {
|
inline camera& camera::znear(f32 value) noexcept {
|
||||||
znear_ = value;
|
znear_ = value;
|
||||||
return *this;
|
return *this;
|
||||||
@@ -102,11 +125,21 @@ namespace e2d
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline camera& camera::view(const m4f& value) noexcept {
|
||||||
|
view_ = value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
inline camera& camera::viewport(const b2f& value) noexcept {
|
inline camera& camera::viewport(const b2f& value) noexcept {
|
||||||
viewport_ = value;
|
viewport_ = value;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline camera& camera::projection(const m4f& value) noexcept {
|
||||||
|
projection_ = value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
inline camera& camera::target(const render_target_ptr& value) noexcept {
|
inline camera& camera::target(const render_target_ptr& value) noexcept {
|
||||||
target_ = value;
|
target_ = value;
|
||||||
return *this;
|
return *this;
|
||||||
@@ -121,6 +154,10 @@ namespace e2d
|
|||||||
return depth_;
|
return depth_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline camera::modes camera::mode() const noexcept {
|
||||||
|
return mode_;
|
||||||
|
}
|
||||||
|
|
||||||
inline f32 camera::znear() const noexcept {
|
inline f32 camera::znear() const noexcept {
|
||||||
return znear_;
|
return znear_;
|
||||||
}
|
}
|
||||||
@@ -129,10 +166,18 @@ namespace e2d
|
|||||||
return zfar_;
|
return zfar_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const m4f& camera::view() const noexcept {
|
||||||
|
return view_;
|
||||||
|
}
|
||||||
|
|
||||||
inline const b2f& camera::viewport() const noexcept {
|
inline const b2f& camera::viewport() const noexcept {
|
||||||
return viewport_;
|
return viewport_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const m4f& camera::projection() const noexcept {
|
||||||
|
return projection_;
|
||||||
|
}
|
||||||
|
|
||||||
inline const render_target_ptr& camera::target() const noexcept {
|
inline const render_target_ptr& camera::target() const noexcept {
|
||||||
return target_;
|
return target_;
|
||||||
}
|
}
|
||||||
@@ -141,16 +186,3 @@ namespace e2d
|
|||||||
return background_;
|
return background_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace e2d::cameras
|
|
||||||
{
|
|
||||||
inline m4f make_projection_matrix(const camera& camera, const window& window) noexcept {
|
|
||||||
const v2u target_size = camera.target()
|
|
||||||
? camera.target()->size()
|
|
||||||
: window.real_size();
|
|
||||||
return math::make_orthographic_lh_matrix4(
|
|
||||||
target_size.cast_to<f32>(),
|
|
||||||
camera.znear(),
|
|
||||||
math::max(camera.zfar(), camera.znear() + math::default_precision<f32>()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
84
samples/bin/library/prefabs/background_prefab.json
Normal file
84
samples/bin/library/prefabs/background_prefab.json
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
{
|
||||||
|
"components" : {},
|
||||||
|
"children" : [{
|
||||||
|
"prototype" : "sprite_prefab.json",
|
||||||
|
"components" : {
|
||||||
|
"actor" : {
|
||||||
|
"translation" : [-512,0]
|
||||||
|
},
|
||||||
|
"sprite_renderer" : {
|
||||||
|
"sprite" : "../sprites/background_sprite.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"prototype" : "sprite_prefab.json",
|
||||||
|
"components" : {
|
||||||
|
"actor" : {
|
||||||
|
"translation" : [-256,0]
|
||||||
|
},
|
||||||
|
"sprite_renderer" : {
|
||||||
|
"sprite" : "../sprites/background_sprite.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"prototype" : "sprite_prefab.json",
|
||||||
|
"components" : {
|
||||||
|
"actor" : {
|
||||||
|
"translation" : [0,0]
|
||||||
|
},
|
||||||
|
"sprite_renderer" : {
|
||||||
|
"sprite" : "../sprites/background_sprite.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"prototype" : "sprite_prefab.json",
|
||||||
|
"components" : {
|
||||||
|
"actor" : {
|
||||||
|
"translation" : [256,0]
|
||||||
|
},
|
||||||
|
"sprite_renderer" : {
|
||||||
|
"sprite" : "../sprites/background_sprite.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"prototype" : "sprite_prefab.json",
|
||||||
|
"components" : {
|
||||||
|
"actor" : {
|
||||||
|
"translation" : [-512,-256]
|
||||||
|
},
|
||||||
|
"sprite_renderer" : {
|
||||||
|
"sprite" : "../sprites/background_sprite.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"prototype" : "sprite_prefab.json",
|
||||||
|
"components" : {
|
||||||
|
"actor" : {
|
||||||
|
"translation" : [-256,-256]
|
||||||
|
},
|
||||||
|
"sprite_renderer" : {
|
||||||
|
"sprite" : "../sprites/background_sprite.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"prototype" : "sprite_prefab.json",
|
||||||
|
"components" : {
|
||||||
|
"actor" : {
|
||||||
|
"translation" : [0,-256]
|
||||||
|
},
|
||||||
|
"sprite_renderer" : {
|
||||||
|
"sprite" : "../sprites/background_sprite.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"prototype" : "sprite_prefab.json",
|
||||||
|
"components" : {
|
||||||
|
"actor" : {
|
||||||
|
"translation" : [256,-256]
|
||||||
|
},
|
||||||
|
"sprite_renderer" : {
|
||||||
|
"sprite" : "../sprites/background_sprite.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
@@ -7,6 +7,8 @@
|
|||||||
},
|
},
|
||||||
"children" : [{
|
"children" : [{
|
||||||
"prototype" : "../prefabs/camera_prefab.json"
|
"prototype" : "../prefabs/camera_prefab.json"
|
||||||
|
},{
|
||||||
|
"prototype" : "../prefabs/background_prefab.json"
|
||||||
},{
|
},{
|
||||||
"prototype" : "../prefabs/gnome_prefab.json",
|
"prototype" : "../prefabs/gnome_prefab.json",
|
||||||
"components" : {
|
"components" : {
|
||||||
@@ -28,7 +30,7 @@
|
|||||||
"outline_color" : [0,0,0,255]
|
"outline_color" : [0,0,0,255]
|
||||||
},
|
},
|
||||||
"actor" : {
|
"actor" : {
|
||||||
"translation" : [-315,-235],
|
"translation" : [-502,-246],
|
||||||
"scale" : 1
|
"scale" : 1
|
||||||
},
|
},
|
||||||
"behaviour" : {
|
"behaviour" : {
|
||||||
|
|||||||
@@ -9,19 +9,37 @@ local camera = {
|
|||||||
---@type integer
|
---@type integer
|
||||||
depth = 0,
|
depth = 0,
|
||||||
|
|
||||||
|
---@type camera_modes
|
||||||
|
mode = camera.modes.flexible,
|
||||||
|
|
||||||
---@type number
|
---@type number
|
||||||
znear = 0.0,
|
znear = 0.0,
|
||||||
|
|
||||||
---@type number
|
---@type number
|
||||||
zfar = 1000.0,
|
zfar = 1000.0,
|
||||||
|
|
||||||
|
---@type m4f
|
||||||
|
view = m4f.identity(),
|
||||||
|
|
||||||
---@type rect
|
---@type rect
|
||||||
viewport = rect.zero(),
|
viewport = rect.zero(),
|
||||||
|
|
||||||
|
---@type m4f
|
||||||
|
projection = m4f.identity(),
|
||||||
|
|
||||||
---@type color
|
---@type color
|
||||||
background = color.white()
|
background = color.white()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---@class camera_modes
|
||||||
|
camera.modes = {
|
||||||
|
manual = "manual",
|
||||||
|
stretch = "stretch",
|
||||||
|
flexible = "flexible",
|
||||||
|
fixed_fit = "fixed_fit",
|
||||||
|
fixed_crop = "fixed_crop"
|
||||||
|
}
|
||||||
|
|
||||||
---@overload fun(self: camera)
|
---@overload fun(self: camera)
|
||||||
---@param self camera
|
---@param self camera
|
||||||
function camera.enable(self) end
|
function camera.enable(self) end
|
||||||
|
|||||||
3
samples/bin/library/sprites/background.png
Executable file
3
samples/bin/library/sprites/background.png
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:d0739fc3ed0d3c14226ba7cb58d3afec1564f7a5101b1544f8b372e7d5ac18a5
|
||||||
|
size 3132
|
||||||
5
samples/bin/library/sprites/background_sprite.json
Normal file
5
samples/bin/library/sprites/background_sprite.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"texture" : "background.png",
|
||||||
|
"pivot" : { "x" : 0, "y" : 0 },
|
||||||
|
"texrect" : { "x" : 0, "y" : 0, "w" : 256, "h" : 256 }
|
||||||
|
}
|
||||||
@@ -60,7 +60,8 @@ int e2d_main(int argc, char *argv[]) {
|
|||||||
const auto starter_params = starter::parameters(
|
const auto starter_params = starter::parameters(
|
||||||
engine::parameters("sample_07", "enduro2d")
|
engine::parameters("sample_07", "enduro2d")
|
||||||
.window_params(engine::window_parameters()
|
.window_params(engine::window_parameters()
|
||||||
.size({1024, 768}))
|
.size({1024, 512})
|
||||||
|
.resizable(true))
|
||||||
.timer_params(engine::timer_parameters()
|
.timer_params(engine::timer_parameters()
|
||||||
.maximal_framerate(100)));
|
.maximal_framerate(100)));
|
||||||
modules::initialize<starter>(argc, argv, starter_params).start<game>();
|
modules::initialize<starter>(argc, argv, starter_params).start<game>();
|
||||||
|
|||||||
@@ -58,6 +58,14 @@ namespace e2d::bindings::high
|
|||||||
c->depth(v);
|
c->depth(v);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
"mode", sol::property(
|
||||||
|
[](const gcomponent<camera>& c) -> camera::modes {
|
||||||
|
return c->mode();
|
||||||
|
},
|
||||||
|
[](gcomponent<camera>& c, camera::modes v){
|
||||||
|
c->mode(v);
|
||||||
|
}),
|
||||||
|
|
||||||
"znear", sol::property(
|
"znear", sol::property(
|
||||||
[](const gcomponent<camera>& c) -> f32 {
|
[](const gcomponent<camera>& c) -> f32 {
|
||||||
return c->znear();
|
return c->znear();
|
||||||
@@ -74,6 +82,14 @@ namespace e2d::bindings::high
|
|||||||
c->zfar(v);
|
c->zfar(v);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
"view", sol::property(
|
||||||
|
[](const gcomponent<camera>& c) -> m4f {
|
||||||
|
return c->view();
|
||||||
|
},
|
||||||
|
[](gcomponent<camera>& c, const m4f& v){
|
||||||
|
c->view(v);
|
||||||
|
}),
|
||||||
|
|
||||||
"viewport", sol::property(
|
"viewport", sol::property(
|
||||||
[](const gcomponent<camera>& c) -> b2f {
|
[](const gcomponent<camera>& c) -> b2f {
|
||||||
return c->viewport();
|
return c->viewport();
|
||||||
@@ -82,6 +98,14 @@ namespace e2d::bindings::high
|
|||||||
c->viewport(v);
|
c->viewport(v);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
"projection", sol::property(
|
||||||
|
[](const gcomponent<camera>& c) -> m4f {
|
||||||
|
return c->projection();
|
||||||
|
},
|
||||||
|
[](gcomponent<camera>& c, const m4f& v){
|
||||||
|
c->projection(v);
|
||||||
|
}),
|
||||||
|
|
||||||
"background", sol::property(
|
"background", sol::property(
|
||||||
[](const gcomponent<camera>& c) -> color {
|
[](const gcomponent<camera>& c) -> color {
|
||||||
return c->background();
|
return c->background();
|
||||||
@@ -90,5 +114,16 @@ namespace e2d::bindings::high
|
|||||||
c->background(v);
|
c->background(v);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#define CAMERA_MODE_PAIR(x) {#x, camera::modes::x},
|
||||||
|
l["camera"].get_or_create<sol::table>()
|
||||||
|
.new_enum<camera::modes>("modes", {
|
||||||
|
CAMERA_MODE_PAIR(manual)
|
||||||
|
CAMERA_MODE_PAIR(stretch)
|
||||||
|
CAMERA_MODE_PAIR(flexible)
|
||||||
|
CAMERA_MODE_PAIR(fixed_fit)
|
||||||
|
CAMERA_MODE_PAIR(fixed_crop)
|
||||||
|
});
|
||||||
|
#undef CAMERA_MODE_PAIR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,11 +13,26 @@ namespace e2d
|
|||||||
"required" : [],
|
"required" : [],
|
||||||
"additionalProperties" : false,
|
"additionalProperties" : false,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"depth" : { "type" : "number" },
|
"depth" : { "type" : "integer" },
|
||||||
|
"mode" : { "$ref": "#/definitions/modes" },
|
||||||
"znear" : { "type" : "number" },
|
"znear" : { "type" : "number" },
|
||||||
"zfar" : { "type" : "number" },
|
"zfar" : { "type" : "number" },
|
||||||
|
"view" : { "$ref": "#/common_definitions/m4" },
|
||||||
"viewport" : { "$ref": "#/common_definitions/b2" },
|
"viewport" : { "$ref": "#/common_definitions/b2" },
|
||||||
|
"projection" : { "$ref": "#/common_definitions/m4" },
|
||||||
"background" : { "$ref": "#/common_definitions/color" }
|
"background" : { "$ref": "#/common_definitions/color" }
|
||||||
|
},
|
||||||
|
"definitions" : {
|
||||||
|
"modes" : {
|
||||||
|
"type" : "string",
|
||||||
|
"enum" : [
|
||||||
|
"manual",
|
||||||
|
"stretch",
|
||||||
|
"flexible",
|
||||||
|
"fixed_fit",
|
||||||
|
"fixed_crop"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})json";
|
})json";
|
||||||
|
|
||||||
@@ -34,6 +49,15 @@ namespace e2d
|
|||||||
component.depth(depth);
|
component.depth(depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ctx.root.HasMember("mode") ) {
|
||||||
|
camera::modes mode = component.mode();
|
||||||
|
if ( !json_utils::try_parse_value(ctx.root["mode"], mode) ) {
|
||||||
|
the<debug>().error("CAMERA: Incorrect formatting of 'mode' property");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
component.mode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
if ( ctx.root.HasMember("znear") ) {
|
if ( ctx.root.HasMember("znear") ) {
|
||||||
f32 znear = component.znear();
|
f32 znear = component.znear();
|
||||||
if ( !json_utils::try_parse_value(ctx.root["znear"], znear) ) {
|
if ( !json_utils::try_parse_value(ctx.root["znear"], znear) ) {
|
||||||
@@ -52,6 +76,15 @@ namespace e2d
|
|||||||
component.zfar(zfar);
|
component.zfar(zfar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ctx.root.HasMember("view") ) {
|
||||||
|
m4f view = component.view();
|
||||||
|
if ( !json_utils::try_parse_value(ctx.root["view"], view) ) {
|
||||||
|
the<debug>().error("CAMERA: Incorrect formatting of 'view' property");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
component.view(view);
|
||||||
|
}
|
||||||
|
|
||||||
if ( ctx.root.HasMember("viewport") ) {
|
if ( ctx.root.HasMember("viewport") ) {
|
||||||
b2f viewport = component.viewport();
|
b2f viewport = component.viewport();
|
||||||
if ( !json_utils::try_parse_value(ctx.root["viewport"], viewport) ) {
|
if ( !json_utils::try_parse_value(ctx.root["viewport"], viewport) ) {
|
||||||
@@ -61,6 +94,15 @@ namespace e2d
|
|||||||
component.viewport(viewport);
|
component.viewport(viewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ctx.root.HasMember("projection") ) {
|
||||||
|
m4f projection = component.projection();
|
||||||
|
if ( !json_utils::try_parse_value(ctx.root["projection"], projection) ) {
|
||||||
|
the<debug>().error("CAMERA: Incorrect formatting of 'projection' property");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
component.projection(projection);
|
||||||
|
}
|
||||||
|
|
||||||
if ( ctx.root.HasMember("target") ) {
|
if ( ctx.root.HasMember("target") ) {
|
||||||
//TODO(BlackMat): add 'target' property parsing
|
//TODO(BlackMat): add 'target' property parsing
|
||||||
}
|
}
|
||||||
@@ -133,6 +175,12 @@ namespace e2d
|
|||||||
c->depth(depth);
|
c->depth(depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( camera::modes mode = c->mode();
|
||||||
|
imgui_utils::show_enum_combo_box("mode", &mode) )
|
||||||
|
{
|
||||||
|
c->mode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
if ( ImGui::TreeNode("clipping") ) {
|
if ( ImGui::TreeNode("clipping") ) {
|
||||||
E2D_DEFER([](){ ImGui::TreePop(); });
|
E2D_DEFER([](){ ImGui::TreePop(); });
|
||||||
|
|
||||||
@@ -151,6 +199,8 @@ namespace e2d
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///TODO(BlackMat): add 'view' inspector
|
||||||
|
|
||||||
if ( ImGui::TreeNode("viewport") ) {
|
if ( ImGui::TreeNode("viewport") ) {
|
||||||
E2D_DEFER([](){ ImGui::TreePop(); });
|
E2D_DEFER([](){ ImGui::TreePop(); });
|
||||||
|
|
||||||
@@ -167,6 +217,7 @@ namespace e2d
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///TODO(BlackMat): add 'projection' inspector
|
||||||
///TODO(BlackMat): add 'target' inspector
|
///TODO(BlackMat): add 'target' inspector
|
||||||
|
|
||||||
if ( color background = c->background();
|
if ( color background = c->background();
|
||||||
|
|||||||
@@ -6,8 +6,73 @@
|
|||||||
|
|
||||||
#include <enduro2d/high/systems/camera_system.hpp>
|
#include <enduro2d/high/systems/camera_system.hpp>
|
||||||
|
|
||||||
|
#include <enduro2d/high/components/actor.hpp>
|
||||||
#include <enduro2d/high/components/camera.hpp>
|
#include <enduro2d/high/components/camera.hpp>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
using namespace e2d;
|
||||||
|
|
||||||
|
m4f make_camera_view(const actor& actor) noexcept {
|
||||||
|
return actor.node()
|
||||||
|
? math::inversed(actor.node()->world_matrix()).first
|
||||||
|
: m4f::identity();
|
||||||
|
}
|
||||||
|
|
||||||
|
m4f make_camera_projection(const camera& camera, const window& window) noexcept {
|
||||||
|
const f32 ortho_znear = camera.znear();
|
||||||
|
const f32 ortho_zfar = math::max(
|
||||||
|
camera.zfar(),
|
||||||
|
camera.znear() + math::default_precision<f32>());
|
||||||
|
|
||||||
|
const v2f target_size = camera.target()
|
||||||
|
? camera.target()->size().cast_to<f32>()
|
||||||
|
: window.real_size().cast_to<f32>();
|
||||||
|
const v2f virtual_size = window.virtual_size().cast_to<f32>();
|
||||||
|
|
||||||
|
if ( math::is_near_zero(math::length_squared(target_size), 0.f) ||
|
||||||
|
math::is_near_zero(math::length_squared(virtual_size), 0.f) )
|
||||||
|
{
|
||||||
|
return camera.projection();
|
||||||
|
}
|
||||||
|
|
||||||
|
const f32 target_aspect = target_size.x / target_size.y;
|
||||||
|
const f32 virtual_aspect = virtual_size.x / virtual_size.y;
|
||||||
|
|
||||||
|
switch ( camera.mode() ) {
|
||||||
|
case camera::modes::manual:
|
||||||
|
return camera.projection();
|
||||||
|
case camera::modes::stretch:
|
||||||
|
return math::make_orthographic_lh_matrix4(
|
||||||
|
virtual_size,
|
||||||
|
ortho_znear,
|
||||||
|
ortho_zfar);
|
||||||
|
case camera::modes::flexible:
|
||||||
|
return math::make_orthographic_lh_matrix4(
|
||||||
|
target_size,
|
||||||
|
ortho_znear,
|
||||||
|
ortho_zfar);
|
||||||
|
case camera::modes::fixed_fit:
|
||||||
|
return math::make_orthographic_lh_matrix4(
|
||||||
|
target_aspect < virtual_aspect
|
||||||
|
? v2f(virtual_size.x, virtual_size.y * (virtual_aspect / target_aspect))
|
||||||
|
: v2f(virtual_size.x * (target_aspect / virtual_aspect), virtual_size.y),
|
||||||
|
ortho_znear,
|
||||||
|
ortho_zfar);
|
||||||
|
case camera::modes::fixed_crop:
|
||||||
|
return math::make_orthographic_lh_matrix4(
|
||||||
|
virtual_aspect < target_aspect
|
||||||
|
? v2f(virtual_size.x, virtual_size.y * (virtual_aspect / target_aspect))
|
||||||
|
: v2f(virtual_size.x * (target_aspect / virtual_aspect), virtual_size.y),
|
||||||
|
ortho_znear,
|
||||||
|
ortho_zfar);
|
||||||
|
default:
|
||||||
|
E2D_ASSERT_MSG(false, "unexpected camera mode");
|
||||||
|
return camera.projection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace e2d
|
namespace e2d
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@@ -16,12 +81,28 @@ namespace e2d
|
|||||||
|
|
||||||
class camera_system::internal_state final : private noncopyable {
|
class camera_system::internal_state final : private noncopyable {
|
||||||
public:
|
public:
|
||||||
internal_state() = default;
|
internal_state(window& w)
|
||||||
|
: window_(w) {}
|
||||||
~internal_state() noexcept = default;
|
~internal_state() noexcept = default;
|
||||||
|
|
||||||
void process_update(ecs::registry& owner) {
|
void process_update(ecs::registry& owner) {
|
||||||
E2D_UNUSED(owner);
|
owner.for_joined_components<camera, actor>([](
|
||||||
|
const ecs::const_entity&,
|
||||||
|
camera& c,
|
||||||
|
const actor& a)
|
||||||
|
{
|
||||||
|
c.view(make_camera_view(a));
|
||||||
|
});
|
||||||
|
|
||||||
|
owner.for_each_component<camera>([this](
|
||||||
|
const ecs::const_entity&,
|
||||||
|
camera& c)
|
||||||
|
{
|
||||||
|
c.projection(make_camera_projection(c, window_));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
private:
|
||||||
|
window& window_;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -29,7 +110,7 @@ namespace e2d
|
|||||||
//
|
//
|
||||||
|
|
||||||
camera_system::camera_system()
|
camera_system::camera_system()
|
||||||
: state_(new internal_state()) {}
|
: state_(new internal_state(the<window>())) {}
|
||||||
camera_system::~camera_system() noexcept = default;
|
camera_system::~camera_system() noexcept = default;
|
||||||
|
|
||||||
void camera_system::process(
|
void camera_system::process(
|
||||||
|
|||||||
@@ -22,9 +22,8 @@ namespace
|
|||||||
|
|
||||||
class imgui_gizmos_context final : public component_inspector<>::gizmos_context {
|
class imgui_gizmos_context final : public component_inspector<>::gizmos_context {
|
||||||
public:
|
public:
|
||||||
imgui_gizmos_context(editor& e, window& w, inspector& i)
|
imgui_gizmos_context(editor& e, inspector& i)
|
||||||
: editor_(e)
|
: editor_(e)
|
||||||
, window_(w)
|
|
||||||
, inspector_(i) {}
|
, inspector_(i) {}
|
||||||
|
|
||||||
bool setup_camera(const ecs::const_entity& cam_e) {
|
bool setup_camera(const ecs::const_entity& cam_e) {
|
||||||
@@ -41,8 +40,8 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
camera_vp_ =
|
camera_vp_ =
|
||||||
math::inversed(cam_n->world_matrix()).first *
|
cam.view() *
|
||||||
cameras::make_projection_matrix(cam, window_) *
|
cam.projection() *
|
||||||
math::make_scale_matrix4(0.5f, 0.5f) *
|
math::make_scale_matrix4(0.5f, 0.5f) *
|
||||||
math::make_translation_matrix4(0.5f, 0.5f) *
|
math::make_translation_matrix4(0.5f, 0.5f) *
|
||||||
math::make_scale_matrix4(cam.viewport().size) *
|
math::make_scale_matrix4(cam.viewport().size) *
|
||||||
@@ -186,7 +185,6 @@ namespace
|
|||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
editor& editor_;
|
editor& editor_;
|
||||||
window& window_;
|
|
||||||
inspector& inspector_;
|
inspector& inspector_;
|
||||||
m4f camera_vp_ = m4f::identity();
|
m4f camera_vp_ = m4f::identity();
|
||||||
m4f go_matrix_ = m4f::identity();
|
m4f go_matrix_ = m4f::identity();
|
||||||
@@ -229,9 +227,9 @@ namespace e2d
|
|||||||
|
|
||||||
class gizmos_system::internal_state final : private noncopyable {
|
class gizmos_system::internal_state final : private noncopyable {
|
||||||
public:
|
public:
|
||||||
internal_state(dbgui& d, window& w, editor& e, inspector& i)
|
internal_state(dbgui& d, editor& e, inspector& i)
|
||||||
: dbgui_(d)
|
: dbgui_(d)
|
||||||
, gcontext_(e, w, i) {}
|
, gcontext_(e, i) {}
|
||||||
~internal_state() noexcept = default;
|
~internal_state() noexcept = default;
|
||||||
|
|
||||||
void process_render(const ecs::const_entity& cam_e, ecs::registry& owner) {
|
void process_render(const ecs::const_entity& cam_e, ecs::registry& owner) {
|
||||||
@@ -256,7 +254,7 @@ namespace e2d
|
|||||||
//
|
//
|
||||||
|
|
||||||
gizmos_system::gizmos_system()
|
gizmos_system::gizmos_system()
|
||||||
: state_(new internal_state(the<dbgui>(), the<window>(), the<editor>(), the<inspector>())) {}
|
: state_(new internal_state(the<dbgui>(), the<editor>(), the<inspector>())) {}
|
||||||
gizmos_system::~gizmos_system() noexcept = default;
|
gizmos_system::~gizmos_system() noexcept = default;
|
||||||
|
|
||||||
void gizmos_system::process(
|
void gizmos_system::process(
|
||||||
|
|||||||
@@ -50,16 +50,8 @@ namespace e2d::render_system_impl
|
|||||||
: render_(render)
|
: render_(render)
|
||||||
, batcher_(batcher)
|
, batcher_(batcher)
|
||||||
{
|
{
|
||||||
const m4f& cam_w = cam_n
|
const m4f& m_v = cam.view();
|
||||||
? cam_n->world_matrix()
|
const m4f& m_p = cam.projection();
|
||||||
: m4f::identity();
|
|
||||||
const std::pair<m4f, bool> cam_w_inv = math::inversed(cam_w);
|
|
||||||
|
|
||||||
const m4f& m_v = cam_w_inv.second
|
|
||||||
? cam_w_inv.first
|
|
||||||
: m4f::identity();
|
|
||||||
|
|
||||||
const m4f& m_p = cameras::make_projection_matrix(cam, window);
|
|
||||||
|
|
||||||
batcher_.flush()
|
batcher_.flush()
|
||||||
.property(screen_s_property_hash, cam.target()
|
.property(screen_s_property_hash, cam.target()
|
||||||
|
|||||||
Reference in New Issue
Block a user