diff --git a/tracking/include/collision_object.h b/tracking/include/collision_object.h index a4df399..f275f31 100644 --- a/tracking/include/collision_object.h +++ b/tracking/include/collision_object.h @@ -20,7 +20,7 @@ class CollisionObject { CollisionObject(glm::vec2 position, glm::vec2 velocity, const std::string &filename, std::shared_ptr effect_shader); - void update(std::vector &players, const ofEasyCam &camera); + void update(std::vector &players, const std::vector &objects, const ofEasyCam &camera); void draw() const; std::pair global_effect_triggered(); @@ -30,11 +30,13 @@ class CollisionObject { float width() const; float height() const; glm::vec2 position() const; + glm::vec2 velocity() const; std::shared_ptr effect_shader() const; protected: void play_random_pluck(); std::pair check_collision_with_bodies(std::vector &players, const ofEasyCam &camera); + std::pair check_collision_with_objects(const std::vector &objects); const float _min_speed = 5; const float _max_speed = 20; diff --git a/tracking/src/collision_object.cpp b/tracking/src/collision_object.cpp index 55866c9..a8632a2 100644 --- a/tracking/src/collision_object.cpp +++ b/tracking/src/collision_object.cpp @@ -8,8 +8,8 @@ #include #include -#include #include +#include CollisionObject::CollisionObject() : CollisionObject({0, 0}, {0, 0}, "", std::make_shared()) {} @@ -39,7 +39,8 @@ CollisionObject::CollisionObject(glm::vec2 position, glm::vec2 velocity, const s } } -void CollisionObject::update(std::vector &players, const ofEasyCam &camera) { +void CollisionObject::update(std::vector &players, const std::vector &objects, + const ofEasyCam &camera) { if (_position.x <= 0 || _position.x + width() >= ofGetWidth()) { play_random_pluck(); _velocity.x *= -1; @@ -60,6 +61,10 @@ void CollisionObject::update(std::vector &players, const ofEasyCam &came _can_collide = true; } + if (auto [collided, dir] = check_collision_with_objects(objects); collided) { + _velocity = dir; + } + _velocity *= _friction; auto speed = glm::length(_velocity); @@ -143,10 +148,47 @@ std::pair CollisionObject::check_collision_with_bodies(std::vec return {false, {0, 0}}; } +std::pair CollisionObject::check_collision_with_objects(const std::vector &objects) { + auto this_bounds = ofRectangle(position().x, position().y, width(), height()); + for (const auto &object: objects) { + if (this == &object) { + continue; + } + + auto other_bounds = ofRectangle(object.position().x, object.position().y, object.width(), object.height()); + if (this_bounds.intersects(other_bounds)) { + glm::vec2 new_velocity = _velocity; + + // Calculate overlap on X and Y axes + float overlap_left = this_bounds.getRight() - other_bounds.getLeft(); + float overlap_right = other_bounds.getRight() - this_bounds.getLeft(); + float overlap_top = this_bounds.getBottom() - other_bounds.getTop(); + float overlap_bottom = other_bounds.getBottom() - this_bounds.getTop(); + + float x_overlap = std::min(overlap_left, overlap_right); + float y_overlap = std::min(overlap_top, overlap_bottom); + + const auto intersection = this_bounds.getIntersection(other_bounds); + + if (x_overlap < y_overlap) { + new_velocity.x = -(new_velocity.x); // bounce horizontally + } else { + new_velocity.y = -(new_velocity.y); // bounce vertically + } + + return {true, new_velocity}; + } + } + + return {false, _velocity}; +} + float CollisionObject::width() const { return _image.getWidth(); } float CollisionObject::height() const { return _image.getHeight(); } glm::vec2 CollisionObject::position() const { return _position; } +glm::vec2 CollisionObject::velocity() const { return _velocity; } + std::shared_ptr CollisionObject::effect_shader() const { return _effect_shader; } diff --git a/tracking/src/tracking_scene.cpp b/tracking/src/tracking_scene.cpp index ff7ca6e..88248e3 100644 --- a/tracking/src/tracking_scene.cpp +++ b/tracking/src/tracking_scene.cpp @@ -79,7 +79,7 @@ void TrackingScene::update() { } for (auto &collision_object: _collision_objects) { - collision_object.update(_players, _camera); + collision_object.update(_players, _collision_objects, _camera); if (ofGetSystemTimeMillis() - _global_effect_trigger_time > _global_effect_duration) { auto [triggered, position] = collision_object.global_effect_triggered();