more collider props

This commit is contained in:
2020-01-17 05:49:33 +07:00
parent e85aed2a51
commit 7b7c87914b
2 changed files with 206 additions and 90 deletions

View File

@@ -12,49 +12,70 @@
#include "../gobject.hpp"
#include "../inspector.hpp"
namespace e2d::impl
{
template < typename Collider >
class collider_base {
public:
collider_base() = default;
Collider& pivot(const v2f& value) noexcept;
[[nodiscard]] const v2f& pivot() const noexcept;
Collider& sensor(bool value) noexcept;
[[nodiscard]] bool sensor() const noexcept;
Collider& density(f32 value) noexcept;
[[nodiscard]] f32 density() const noexcept;
Collider& friction(f32 value) noexcept;
[[nodiscard]] f32 friction() const noexcept;
Collider& restitution(f32 value) noexcept;
[[nodiscard]] f32 restitution() const noexcept;
private:
v2f pivot_ = v2f(0.5f);
bool sensor_ = false;
f32 density_ = 1.f;
f32 friction_ = 0.2f;
f32 restitution_ = 0.f;
};
}
namespace e2d
{
class rect_collider final {
class rect_collider final
: public impl::collider_base<rect_collider> {
public:
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 {
class circle_collider final
: public impl::collider_base<rect_collider> {
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 {
class polygon_collider final
: public impl::collider_base<rect_collider> {
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);
};
}
@@ -130,6 +151,64 @@ namespace e2d
};
}
namespace e2d::impl
{
template < typename Collider >
Collider& collider_base<Collider>::pivot(const v2f& value) noexcept {
pivot_ = value;
return static_cast<Collider&>(*this);
}
template < typename Collider >
const v2f& collider_base<Collider>::pivot() const noexcept {
return pivot_;
}
template < typename Collider >
Collider& collider_base<Collider>::sensor(bool value) noexcept {
sensor_ = value;
return static_cast<Collider&>(*this);
}
template < typename Collider >
bool collider_base<Collider>::sensor() const noexcept {
return sensor_;
}
template < typename Collider >
Collider& collider_base<Collider>::density(f32 value) noexcept {
density_ = value;
return static_cast<Collider&>(*this);
}
template < typename Collider >
f32 collider_base<Collider>::density() const noexcept {
return density_;
}
template < typename Collider >
Collider& collider_base<Collider>::friction(f32 value) noexcept {
friction_ = value;
return static_cast<Collider&>(*this);
}
template < typename Collider >
f32 collider_base<Collider>::friction() const noexcept {
return friction_;
}
template < typename Collider >
Collider& collider_base<Collider>::restitution(f32 value) noexcept {
restitution_ = value;
return static_cast<Collider&>(*this);
}
template < typename Collider >
f32 collider_base<Collider>::restitution() const noexcept {
return restitution_;
}
}
namespace e2d
{
inline rect_collider& rect_collider::size(const v2f& value) noexcept {
@@ -140,15 +219,6 @@ namespace e2d
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
@@ -161,15 +231,6 @@ namespace e2d
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
@@ -186,13 +247,4 @@ namespace e2d
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

@@ -6,6 +6,97 @@
#include <enduro2d/high/components/colliders.hpp>
namespace
{
using namespace e2d;
template < typename Collider >
bool collider_base_loader(
impl::collider_base<Collider>& component,
const factory_loader<>::fill_context& ctx)
{
if ( ctx.root.HasMember("pivot") ) {
v2f pivot = component.pivot();
if ( !json_utils::try_parse_value(ctx.root["pivot"], pivot) ) {
the<debug>().error("COLLIDER_BASE: Incorrect formatting of 'pivot' property");
return false;
}
component.pivot(pivot);
}
if ( ctx.root.HasMember("sensor") ) {
bool sensor = component.sensor();
if ( !json_utils::try_parse_value(ctx.root["sensor"], sensor) ) {
the<debug>().error("COLLIDER_BASE: Incorrect formatting of 'sensor' property");
return false;
}
component.sensor(sensor);
}
if ( ctx.root.HasMember("density") ) {
f32 density = component.density();
if ( !json_utils::try_parse_value(ctx.root["density"], density) ) {
the<debug>().error("COLLIDER_BASE: Incorrect formatting of 'density' property");
return false;
}
component.density(density);
}
if ( ctx.root.HasMember("friction") ) {
f32 friction = component.friction();
if ( !json_utils::try_parse_value(ctx.root["friction"], friction) ) {
the<debug>().error("COLLIDER_BASE: Incorrect formatting of 'friction' property");
return false;
}
component.friction(friction);
}
if ( ctx.root.HasMember("restitution") ) {
f32 restitution = component.restitution();
if ( !json_utils::try_parse_value(ctx.root["restitution"], restitution) ) {
the<debug>().error("COLLIDER_BASE: Incorrect formatting of 'restitution' property");
return false;
}
component.restitution(restitution);
}
return true;
}
template < typename Collider >
void collider_base_inspector(impl::collider_base<Collider>& c) {
if ( v2f pivot = c.pivot();
ImGui::DragFloat2("pivot", pivot.data(), 0.01f) )
{
c.pivot(pivot);
}
if ( bool sensor = c.sensor();
ImGui::Checkbox("sensor", &sensor) )
{
c.sensor(sensor);
}
if ( f32 density = c.density();
ImGui::DragFloat("density", &density, 0.01f, 0.f, std::numeric_limits<f32>::max()) )
{
c.density(density);
}
if ( f32 friction = c.friction();
ImGui::DragFloat("friction", &friction, 0.01f) )
{
c.friction(friction);
}
if ( f32 restitution = c.restitution();
ImGui::DragFloat("restitution", &restitution, 0.01f) )
{
c.restitution(restitution);
}
}
}
namespace e2d
{
const char* factory_loader<rect_collider>::schema_source = R"json({
@@ -14,7 +105,11 @@ namespace e2d
"additionalProperties" : false,
"properties" : {
"size" : { "$ref": "#/common_definitions/v2" },
"pivot" : { "$ref": "#/common_definitions/v2" }
"pivot" : { "$ref": "#/common_definitions/v2" },
"sensor" : { "type" : "boolean" },
"density" : { "type" : "number" },
"friction" : { "type" : "number" },
"restitution" : { "type" : "number" }
}
})json";
@@ -31,16 +126,7 @@ namespace e2d
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;
return collider_base_loader(component, ctx);
}
bool factory_loader<rect_collider>::operator()(
@@ -61,7 +147,11 @@ namespace e2d
"additionalProperties" : false,
"properties" : {
"radius" : { "type" : "number" },
"pivot" : { "$ref": "#/common_definitions/v2" }
"pivot" : { "$ref": "#/common_definitions/v2" },
"sensor" : { "type" : "boolean" },
"density" : { "type" : "number" },
"friction" : { "type" : "number" },
"restitution" : { "type" : "number" }
}
})json";
@@ -78,16 +168,7 @@ namespace e2d
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;
return collider_base_loader(component, ctx);
}
bool factory_loader<circle_collider>::operator()(
@@ -107,7 +188,11 @@ namespace e2d
"additionalProperties" : false,
"properties" : {
"points" : { "$ref": "#/definitions/points" },
"pivot" : { "$ref": "#/common_definitions/v2" }
"pivot" : { "$ref": "#/common_definitions/v2" },
"sensor" : { "type" : "boolean" },
"density" : { "type" : "number" },
"friction" : { "type" : "number" },
"restitution" : { "type" : "number" }
},
"definitions" : {
"points" : {
@@ -130,16 +215,7 @@ namespace e2d
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;
return collider_base_loader(component, ctx);
}
bool factory_loader<polygon_collider>::operator()(
@@ -162,11 +238,7 @@ namespace e2d
c->size(size);
}
if ( v2f pivot = c->pivot();
ImGui::DragFloat2("pivot", pivot.data(), 0.01f) )
{
c->pivot(pivot);
}
collider_base_inspector(*c);
}
}
@@ -181,11 +253,7 @@ namespace e2d
c->radius(radius);
}
if ( v2f pivot = c->pivot();
ImGui::DragFloat2("pivot", pivot.data(), 0.01f) )
{
c->pivot(pivot);
}
collider_base_inspector(*c);
}
}
@@ -218,10 +286,6 @@ namespace e2d
}
}
if ( v2f pivot = c->pivot();
ImGui::DragFloat2("pivot", pivot.data(), 0.01f) )
{
c->pivot(pivot);
}
collider_base_inspector(*c);
}
}