92 lines
2.1 KiB
C++
92 lines
2.1 KiB
C++
#include "app/scene.h"
|
|
|
|
namespace app {
|
|
Scene::~Scene() {
|
|
for (const uint64_t &id : element_ids)
|
|
element_pool.release(id);
|
|
}
|
|
|
|
void Scene::add_element(uint64_t element_id) {
|
|
auto it = std::lower_bound(
|
|
element_ids.begin(),
|
|
element_ids.end(),
|
|
element_id,
|
|
[](auto &a, auto &b) {
|
|
auto e_a = element_pool[a];
|
|
auto e_b = element_pool[b];
|
|
return e_a->z < e_b->z || (e_a->z == e_b->z && a < b);
|
|
}
|
|
);
|
|
element_pool.use(element_id);
|
|
element_ids.insert(it, element_id);
|
|
}
|
|
|
|
void Scene::delete_element(uint64_t element_id) {
|
|
auto it = std::find(element_ids.begin(), element_ids.end(), element_id);
|
|
if (it != element_ids.end()) {
|
|
element_pool.release(element_id);
|
|
element_ids.erase(it);
|
|
}
|
|
}
|
|
|
|
void Scene::update_scene(mrb_value dt_val) {
|
|
if (mrb_nil_p(update.proc))
|
|
return;
|
|
update.call(1, &dt_val);
|
|
}
|
|
|
|
void Scene::click(Vec2<float> position) {
|
|
std::vector<uint64_t> clicked_elements = elements_at(position);
|
|
for (const uint64_t &id : clicked_elements)
|
|
element_pool[id]->click();
|
|
}
|
|
|
|
void Scene::render(uint64_t abs_time) {
|
|
for (const uint64_t &e : element_ids)
|
|
element_pool[e]->render(abs_time);
|
|
}
|
|
|
|
std::vector<uint64_t> Scene::elements_at(Vec2<float> position) {
|
|
std::vector<uint64_t> result;
|
|
|
|
for (auto it = element_ids.rbegin(); it != element_ids.rend(); ++it) {
|
|
Element *e = element_pool[*it];
|
|
Vec2<float> size = e->size();
|
|
Rect rect = Rect::from(size);
|
|
if (rect.contains(world_to_local(position, e))) {
|
|
if (e->click_mode == ClickMode::PASS) {
|
|
result.push_back(*it);
|
|
} else if (e->click_mode == ClickMode::BLOCK) {
|
|
result.push_back(*it);
|
|
break;
|
|
} else {
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
Vec2<float> Scene::world_to_local(Vec2<float> p, Element *e) {
|
|
Vec2<float> size = e->size();
|
|
Vec2<float> pivot = e->pivot * size * e->scale;
|
|
p = p - e->position;
|
|
|
|
float rad = -e->rotation * (M_PI / 180.0f);
|
|
float c = cos(rad);
|
|
float s = sin(rad);
|
|
|
|
p = p - pivot;
|
|
p = {
|
|
p.x * c - p.y * s,
|
|
p.x * s + p.y * c
|
|
};
|
|
|
|
p = p + pivot;
|
|
p = p / e->scale;
|
|
|
|
return p;
|
|
}
|
|
} // namespace app
|