basic collider properties

This commit is contained in:
2019-11-28 22:03:10 +07:00
parent 5d77d42ed0
commit 08d80d1289
8 changed files with 350 additions and 26 deletions

View File

@@ -46,7 +46,7 @@ namespace e2d
class actor;
class behaviour;
class camera;
class box_collider;
class rect_collider;
class circle_collider;
class polygon_collider;
template < typename C >

View File

@@ -12,31 +12,59 @@
namespace e2d
{
class box_collider final {
class rect_collider final {
public:
box_collider() = default;
rect_collider() = default;
rect_collider& size(const v2f& value) noexcept;
[[nodiscard]] const v2f& size() const noexcept;
rect_collider& pivot(const v2f& value) noexcept;
[[nodiscard]] const v2f& pivot() const noexcept;
private:
v2f size_ = v2f::zero();
v2f pivot_ = v2f(0.5f);
};
class circle_collider final {
public:
circle_collider() = default;
circle_collider& radius(f32 value) noexcept;
[[nodiscard]] f32 radius() const noexcept;
circle_collider& pivot(const v2f& value) noexcept;
[[nodiscard]] const v2f& pivot() const noexcept;
private:
f32 radius_ = 0.f;
v2f pivot_ = v2f(0.5f);
};
class polygon_collider final {
public:
polygon_collider() = default;
polygon_collider& points(vector<v2f> value) noexcept;
[[nodiscard]] vector<v2f>& points() noexcept;
[[nodiscard]] const vector<v2f>& points() const noexcept;
polygon_collider& pivot(const v2f& value) noexcept;
[[nodiscard]] const v2f& pivot() const noexcept;
private:
vector<v2f> points_;
v2f pivot_ = v2f(0.5f);
};
}
namespace e2d
{
template <>
class factory_loader<box_collider> final : factory_loader<> {
class factory_loader<rect_collider> final : factory_loader<> {
public:
static const char* schema_source;
bool operator()(
box_collider& component,
rect_collider& component,
const fill_context& ctx) const;
bool operator()(
@@ -72,3 +100,70 @@ namespace e2d
const collect_context& ctx) const;
};
}
namespace e2d
{
inline rect_collider& rect_collider::size(const v2f& value) noexcept {
size_ = value;
return *this;
}
inline const v2f& rect_collider::size() const noexcept {
return size_;
}
inline rect_collider& rect_collider::pivot(const v2f& value) noexcept {
pivot_ = value;
return *this;
}
inline const v2f& rect_collider::pivot() const noexcept {
return pivot_;
}
}
namespace e2d
{
inline circle_collider& circle_collider::radius(f32 value) noexcept {
radius_ = value;
return *this;
}
inline f32 circle_collider::radius() const noexcept {
return radius_;
}
inline circle_collider& circle_collider::pivot(const v2f& value) noexcept {
pivot_ = value;
return *this;
}
inline const v2f& circle_collider::pivot() const noexcept {
return pivot_;
}
}
namespace e2d
{
inline polygon_collider& polygon_collider::points(vector<v2f> value) noexcept {
points_ = std::move(value);
return *this;
}
inline vector<v2f>& polygon_collider::points() noexcept {
return points_;
}
inline const vector<v2f>& polygon_collider::points() const noexcept {
return points_;
}
inline polygon_collider& polygon_collider::pivot(const v2f& value) noexcept {
pivot_ = value;
return *this;
}
inline const v2f& polygon_collider::pivot() const noexcept {
return pivot_;
}
}

View File

@@ -1,17 +1,32 @@
---@class box_collider
local box_collider = {
---@class rect_collider
local rect_collider = {
---@type v2f
size = v2f.zero(),
---@type v2f
pivot = v2f.new(0.5)
}
---@class circle_collider
local circle_collider = {
---@type number
radius = 0,
---@type v2f
pivot = v2f.new(0.5)
}
---@class polygon_collider
local polygon_collider = {
---@type v2f[]
points = {},
---@type v2f
pivot = v2f.new(0.5)
}
---@type box_collider
_G.box_collider = _G.box_collider or box_collider
---@type rect_collider
_G.rect_collider = _G.rect_collider or rect_collider
---@type circle_collider
_G.circle_collider = _G.circle_collider or circle_collider

View File

@@ -15,8 +15,8 @@ local gobject = {
---@type camera
camera = nil,
---@type box_collider
box_collider = nil,
---@type rect_collider
rect_collider = nil,
---@type circle_collider
circle_collider = nil,

View File

@@ -8,26 +8,177 @@
#include <enduro2d/high/gobject.hpp>
#include <enduro2d/high/components/colliders.hpp>
#include <enduro2d/high/components/disabled.hpp>
namespace
{
using namespace e2d;
void bind_box_collider(sol::state& l) {
l.new_usertype<gcomponent<box_collider>>("box_collider",
sol::no_constructor
void bind_rect_collider(sol::state& l) {
l.new_usertype<gcomponent<rect_collider>>("rect_collider",
sol::no_constructor,
"enable", [](gcomponent<rect_collider>& c){
c.owner().component<disabled<rect_collider>>().remove();
},
"disable", [](gcomponent<rect_collider>& c){
c.owner().component<disabled<rect_collider>>().ensure();
},
"enabled", sol::property(
[](const gcomponent<rect_collider>& c) -> bool {
return !c.owner().component<disabled<rect_collider>>().exists();
},
[](gcomponent<rect_collider>& c, bool yesno){
if ( yesno ) {
c.owner().component<disabled<rect_collider>>().remove();
} else {
c.owner().component<disabled<rect_collider>>().ensure();
}
}
),
"disabled", sol::property(
[](const gcomponent<rect_collider>& c) -> bool {
return c.owner().component<disabled<rect_collider>>().exists();
},
[](gcomponent<rect_collider>& c, bool yesno){
if ( yesno ) {
c.owner().component<disabled<rect_collider>>().ensure();
} else {
c.owner().component<disabled<rect_collider>>().remove();
}
}
),
"size", sol::property(
[](const gcomponent<rect_collider>& c) -> v2f {
return c->size();
},
[](gcomponent<rect_collider>& c, const v2f& v){
c->size(v);
}),
"pivot", sol::property(
[](const gcomponent<rect_collider>& c) -> v2f {
return c->pivot();
},
[](gcomponent<rect_collider>& c, const v2f& v){
c->pivot(v);
})
);
}
void bind_circle_collider(sol::state& l) {
l.new_usertype<gcomponent<circle_collider>>("circle_collider",
sol::no_constructor
sol::no_constructor,
"enable", [](gcomponent<circle_collider>& c){
c.owner().component<disabled<circle_collider>>().remove();
},
"disable", [](gcomponent<circle_collider>& c){
c.owner().component<disabled<circle_collider>>().ensure();
},
"enabled", sol::property(
[](const gcomponent<circle_collider>& c) -> bool {
return !c.owner().component<disabled<circle_collider>>().exists();
},
[](gcomponent<circle_collider>& c, bool yesno){
if ( yesno ) {
c.owner().component<disabled<circle_collider>>().remove();
} else {
c.owner().component<disabled<circle_collider>>().ensure();
}
}
),
"disabled", sol::property(
[](const gcomponent<circle_collider>& c) -> bool {
return c.owner().component<disabled<circle_collider>>().exists();
},
[](gcomponent<circle_collider>& c, bool yesno){
if ( yesno ) {
c.owner().component<disabled<circle_collider>>().ensure();
} else {
c.owner().component<disabled<circle_collider>>().remove();
}
}
),
"radius", sol::property(
[](const gcomponent<circle_collider>& c) -> f32 {
return c->radius();
},
[](gcomponent<circle_collider>& c, f32 v){
c->radius(v);
}),
"pivot", sol::property(
[](const gcomponent<circle_collider>& c) -> v2f {
return c->pivot();
},
[](gcomponent<circle_collider>& c, const v2f& v){
c->pivot(v);
})
);
}
void bind_polygon_collider(sol::state& l) {
l.new_usertype<gcomponent<polygon_collider>>("polygon_collider",
sol::no_constructor
sol::no_constructor,
"enable", [](gcomponent<polygon_collider>& c){
c.owner().component<disabled<polygon_collider>>().remove();
},
"disable", [](gcomponent<polygon_collider>& c){
c.owner().component<disabled<polygon_collider>>().ensure();
},
"enabled", sol::property(
[](const gcomponent<polygon_collider>& c) -> bool {
return !c.owner().component<disabled<polygon_collider>>().exists();
},
[](gcomponent<polygon_collider>& c, bool yesno){
if ( yesno ) {
c.owner().component<disabled<polygon_collider>>().remove();
} else {
c.owner().component<disabled<polygon_collider>>().ensure();
}
}
),
"disabled", sol::property(
[](const gcomponent<polygon_collider>& c) -> bool {
return c.owner().component<disabled<polygon_collider>>().exists();
},
[](gcomponent<polygon_collider>& c, bool yesno){
if ( yesno ) {
c.owner().component<disabled<polygon_collider>>().ensure();
} else {
c.owner().component<disabled<polygon_collider>>().remove();
}
}
),
"points", sol::property(
[](const gcomponent<polygon_collider>& c) -> vector<v2f> {
return c->points();
},
[](gcomponent<polygon_collider>& c, vector<v2f> v){
c->points(std::move(v));
}),
"pivot", sol::property(
[](const gcomponent<polygon_collider>& c) -> v2f {
return c->pivot();
},
[](gcomponent<polygon_collider>& c, const v2f& v){
c->pivot(v);
})
);
}
}
@@ -35,7 +186,7 @@ namespace
namespace e2d::bindings::high
{
void bind_colliders(sol::state& l) {
bind_box_collider(l);
bind_rect_collider(l);
bind_circle_collider(l);
bind_polygon_collider(l);
}

View File

@@ -42,7 +42,7 @@ namespace e2d::bindings::high
"actor", sol::property([](gobject& go){ return component_wrapper<actor>{go}; }),
"behaviour", sol::property([](gobject& go){ return component_wrapper<behaviour>{go}; }),
"camera", sol::property([](gobject& go){ return component_wrapper<camera>{go}; }),
"box_collider", sol::property([](gobject& go){ return component_wrapper<box_collider>{go}; }),
"rect_collider", sol::property([](gobject& go){ return component_wrapper<rect_collider>{go}; }),
"circle_collider", sol::property([](gobject& go){ return component_wrapper<circle_collider>{go}; }),
"polygon_collider", sol::property([](gobject& go){ return component_wrapper<polygon_collider>{go}; }),
"flipbook_player", sol::property([](gobject& go){ return component_wrapper<flipbook_player>{go}; }),

View File

@@ -8,23 +8,42 @@
namespace e2d
{
const char* factory_loader<box_collider>::schema_source = R"json({
const char* factory_loader<rect_collider>::schema_source = R"json({
"type" : "object",
"required" : [],
"additionalProperties" : false,
"properties" : {
"size" : { "$ref": "#/common_definitions/v2" },
"pivot" : { "$ref": "#/common_definitions/v2" }
}
})json";
bool factory_loader<box_collider>::operator()(
box_collider& component,
bool factory_loader<rect_collider>::operator()(
rect_collider& component,
const fill_context& ctx) const
{
E2D_UNUSED(component, ctx);
if ( ctx.root.HasMember("size") ) {
v2f size = component.size();
if ( !json_utils::try_parse_value(ctx.root["size"], size) ) {
the<debug>().error("RECT_COLLIDER: Incorrect formatting of 'size' property");
return false;
}
component.size(size);
}
if ( ctx.root.HasMember("pivot") ) {
v2f pivot = component.pivot();
if ( !json_utils::try_parse_value(ctx.root["pivot"], pivot) ) {
the<debug>().error("RECT_COLLIDER: Incorrect formatting of 'pivot' property");
return false;
}
component.pivot(pivot);
}
return true;
}
bool factory_loader<box_collider>::operator()(
bool factory_loader<rect_collider>::operator()(
asset_dependencies& dependencies,
const collect_context& ctx) const
{
@@ -41,6 +60,8 @@ namespace e2d
"required" : [],
"additionalProperties" : false,
"properties" : {
"radius" : { "type" : "number" },
"pivot" : { "$ref": "#/common_definitions/v2" }
}
})json";
@@ -48,7 +69,24 @@ namespace e2d
circle_collider& component,
const fill_context& ctx) const
{
E2D_UNUSED(component, ctx);
if ( ctx.root.HasMember("radius") ) {
f32 radius = component.radius();
if ( !json_utils::try_parse_value(ctx.root["radius"], radius) ) {
the<debug>().error("CIRCLE_COLLIDER: Incorrect formatting of 'radius' property");
return false;
}
component.radius(radius);
}
if ( ctx.root.HasMember("pivot") ) {
v2f pivot = component.pivot();
if ( !json_utils::try_parse_value(ctx.root["pivot"], pivot) ) {
the<debug>().error("CIRCLE_COLLIDER: Incorrect formatting of 'pivot' property");
return false;
}
component.pivot(pivot);
}
return true;
}
@@ -68,6 +106,14 @@ namespace e2d
"required" : [],
"additionalProperties" : false,
"properties" : {
"points" : { "$ref": "#/definitions/points" },
"pivot" : { "$ref": "#/common_definitions/v2" }
},
"definitions" : {
"points" : {
"type" : "array",
"items" : { "$ref": "#/common_definitions/v2" }
}
}
})json";
@@ -75,7 +121,24 @@ namespace e2d
polygon_collider& component,
const fill_context& ctx) const
{
E2D_UNUSED(component, ctx);
if ( ctx.root.HasMember("points") ) {
vector<v2f> points = component.points();
if ( !json_utils::try_parse_value(ctx.root["points"], points) ) {
the<debug>().error("POLYGON_COLLIDER: Incorrect formatting of 'points' property");
return false;
}
component.points(std::move(points));
}
if ( ctx.root.HasMember("pivot") ) {
v2f pivot = component.pivot();
if ( !json_utils::try_parse_value(ctx.root["pivot"], pivot) ) {
the<debug>().error("POLYGON_COLLIDER: Incorrect formatting of 'pivot' property");
return false;
}
component.pivot(pivot);
}
return true;
}

View File

@@ -182,7 +182,7 @@ namespace e2d
.register_component<actor>("actor")
.register_component<behaviour>("behaviour")
.register_component<camera>("camera")
.register_component<box_collider>("box_collider")
.register_component<rect_collider>("rect_collider")
.register_component<circle_collider>("circle_collider")
.register_component<polygon_collider>("polygon_collider")
.register_component<flipbook_player>("flipbook_player")