23#define __WIZARD_ENGINE_INTERNAL__
27std::array<std::vector<wze::collider*>, std::numeric_limits<uint8_t>::max()>
28 wze::collider::_worlds = {};
30std::vector<wze::collider*> wze::collider::contacts()
const {
31 std::vector<collider*> contacts;
33 std::for_each(_worlds.at(world()).begin(), _worlds.at(world()).end(),
34 [&](collider* contact) ->
void {
35 if (contact !=
this &&
36 body().overlap<bool>(contact->body())) {
37 contacts.push_back(contact);
44float wze::collider::contacts_mass(std::vector<collider*>
const& contacts) {
48 std::for_each(contacts.begin(), contacts.end(),
49 [&](collider
const* contact) ->
void {
50 mass += contact->mass();
56void wze::collider::dual_static_resolver(collider
const& other) {
57 std::pair<float, float> difference;
60 difference.first = other.body().x() - body().x();
61 difference.second = other.body().y() - body().y();
62 if (!(
bool)difference.first && !(
bool)difference.second) {
66 collision = body().overlap<
float>(other.body());
67 if (!(
bool)collision) {
73 _body.set_x(body().x() - difference.first * collision);
74 _body.set_y(body().y() - difference.second * collision);
77bool wze::collider::dual_dynamic_resolver(collider& other,
float force) {
78 std::pair<float, float> difference;
80 std::pair<float, float> movement;
82 difference.first = other.body().x() - body().x();
83 difference.second = other.body().y() - body().y();
84 if (!(
bool)difference.first && !(
bool)difference.second) {
88 collision = body().overlap<
float>(other.body());
89 if (!(
bool)collision) {
94 movement = dynamic_movement(collision, force, other.mass());
95 _body.set_x(body().x() - difference.first * movement.first);
96 _body.set_y(body().y() - difference.second * movement.first);
97 other._body.set_x(other.body().x() + difference.first * movement.second);
98 other._body.set_y(other.body().y() + difference.second * movement.second);
103std::pair<float, float>
104wze::collider::dynamic_movement(
float collision,
float force,
float mass) {
105 float other_movement;
109 other_movement = collision * force / (force + mass);
110 movement = collision - other_movement;
112 return {movement, other_movement};
115void wze::collider::align_entities()
const {
116 std::for_each(_worlds.at(world()).begin(), _worlds.at(world()).end(),
117 [](collider* instance) ->
void {
118 if (instance->entity::x() != instance->body().x()) {
119 instance->entity::set_x(instance->body().x());
121 if (instance->entity::y() != instance->body().y()) {
122 instance->entity::set_y(instance->body().y());
124 if (instance->entity::angle() !=
125 instance->body().angle()) {
126 instance->entity::set_angle(instance->body().angle());
135void wze::collider::set_body(polygon
const& body) {
137 entity::set_x(this->body().x());
138 entity::set_y(this->body().y());
139 entity::set_angle(this->body().angle());
140 entity::set_x_offset(this->body().x_offset());
141 entity::set_y_offset(this->body().y_offset());
142 entity::set_angle_offset(this->body().angle_offset());
143 entity::set_attach_x(this->body().attach_x());
144 entity::set_attach_y(this->body().attach_y());
145 entity::set_attach_angle(this->body().attach_angle());
146 entity::set_x_angle_lock(this->body().x_angle_lock());
147 entity::set_y_angle_lock(this->body().y_angle_lock());
150float wze::collider::force()
const {
154void wze::collider::set_force(
float force) {
158float wze::collider::mass()
const {
162void wze::collider::set_mass(
float mass) {
166uint8_t wze::collider::world()
const {
170void wze::collider::set_world(uint8_t world) {
171 if (this->world() != std::numeric_limits<uint8_t>::max()) {
172 _worlds.at(this->world())
173 .erase(std::find(_worlds.at(this->world()).begin(),
174 _worlds.at(this->world()).end(),
this));
177 if (this->world() != std::numeric_limits<uint8_t>::max()) {
178 _worlds.at(this->world()).push_back(
this);
182float wze::collider::x()
const {
186void wze::collider::set_x(
float x) {
189 if (world() == std::numeric_limits<uint8_t>::max()) {
190 entity::set_x(body().x());
194 push<&collider::solo_static_resolver<&polygon::x, &polygon::set_x>,
195 &collider::solo_dynamic_resolver<&polygon::x, &polygon::set_x>>(
200float wze::collider::y()
const {
204void wze::collider::set_y(
float y) {
207 if (world() == std::numeric_limits<uint8_t>::max()) {
208 entity::set_y(body().y());
212 push<&collider::solo_static_resolver<&polygon::y, &polygon::set_y>,
213 &collider::solo_dynamic_resolver<&polygon::y, &polygon::set_y>>(
218float wze::collider::angle()
const {
219 return _body.angle();
222void wze::collider::set_angle(
float angle) {
223 _body.set_angle(angle);
225 if (world() == std::numeric_limits<uint8_t>::max()) {
226 entity::set_angle(body().angle());
230 push<&collider::dual_static_resolver, &collider::dual_dynamic_resolver>(
235float wze::collider::scale()
const {
236 return body().scale();
239void wze::collider::set_scale(
float scale) {
240 _body.set_scale(scale);
242 if (world() == std::numeric_limits<uint8_t>::max()) {
246 push<&collider::dual_static_resolver, &collider::dual_dynamic_resolver>(
251float wze::collider::x_offset()
const {
252 return _body.x_offset();
255void wze::collider::set_x_offset(
float x_offset) {
256 _body.set_x_offset(x_offset);
257 entity::set_x_offset(body().x_offset());
260float wze::collider::y_offset()
const {
261 return body().y_offset();
264void wze::collider::set_y_offset(
float y_offset) {
265 _body.set_y_offset(y_offset);
266 entity::set_y_offset(body().y_offset());
269float wze::collider::angle_offset()
const {
270 return body().angle_offset();
273void wze::collider::set_angle_offset(
float angle_offset) {
274 _body.set_angle_offset(angle_offset);
275 entity::set_angle_offset(body().angle_offset());
278bool wze::collider::attach_x()
const {
279 return body().attach_x();
282void wze::collider::set_attach_x(
bool attach_x) {
283 _body.set_attach_x(attach_x);
284 entity::set_attach_x(body().attach_x());
287bool wze::collider::attach_y()
const {
288 return body().attach_y();
291void wze::collider::set_attach_y(
bool attach_y) {
292 _body.set_attach_y(attach_y);
293 entity::set_attach_y(body().attach_y());
296bool wze::collider::attach_angle()
const {
297 return body().attach_angle();
300void wze::collider::set_attach_angle(
bool attach_angle) {
301 _body.set_attach_angle(attach_angle);
302 entity::set_attach_angle(attach_angle);
305bool wze::collider::x_angle_lock()
const {
306 return body().x_angle_lock();
309void wze::collider::set_x_angle_lock(
bool x_angle_lock) {
310 _body.set_x_angle_lock(x_angle_lock);
311 entity::set_x_angle_lock(body().x_angle_lock());
314bool wze::collider::y_angle_lock()
const {
315 return body().y_angle_lock();
318void wze::collider::set_y_angle_lock(
bool y_angle_lock) {
319 _body.set_y_angle_lock(y_angle_lock);
320 entity::set_y_angle_lock(body().y_angle_lock());
323wze::collider::collider(polygon
const& body,
float force,
float mass,
325 std::vector<std::weak_ptr<component>>
const& components)
326 : entity(components), _world(std::numeric_limits<uint8_t>::max()) {
333wze::collider::collider(collider
const& other)
334 : entity(other), _world(std::numeric_limits<uint8_t>::max()) {
338wze::collider::~collider() {
339 if (world() != std::numeric_limits<uint8_t>::max()) {
340 _worlds.at(world()).erase(std::find(_worlds.at(world()).begin(),
341 _worlds.at(world()).end(),
this));
345wze::collider& wze::collider::operator=(collider
const& other) {
346 if (&other !=
this) {
347 entity::operator=(other);
348 set_body(other.body());
349 set_force(other.force());
350 set_mass(other.mass());
351 set_world(other.world());
static std::pair< float, float > normalize(float x, float y)
Normalizes a vector.
static constexpr float epsilon()
Single precision epsilon.