diff options
| author | Stanislaw Halik <sthalik@misaki.pl> | 2023-09-01 22:27:30 +0200 |
|---|---|---|
| committer | Stanislaw Halik <sthalik@misaki.pl> | 2023-09-01 22:27:30 +0200 |
| commit | 31fd5bbc08234686cf798a93a18e0bb73615d1bf (patch) | |
| tree | 59b964d01885916c5d49fef3c168ff10dcbdd93f /src/entity.cpp | |
| parent | 053ea3aa1c443c368f8b43591e3e970e12b50c70 (diff) | |
rename entity -> object
Diffstat (limited to 'src/entity.cpp')
| -rw-r--r-- | src/entity.cpp | 300 |
1 files changed, 0 insertions, 300 deletions
diff --git a/src/entity.cpp b/src/entity.cpp deleted file mode 100644 index 2a8c5aa1..00000000 --- a/src/entity.cpp +++ /dev/null @@ -1,300 +0,0 @@ -#include "entity.hpp" -#include "world.hpp" -#include "rotation.inl" -#include "anim-atlas.hpp" -#include "src/RTree-search.hpp" -#include "compat/exception.hpp" -#include "shaders/shader.hpp" -#include <cmath> -#include <algorithm> - -namespace floormat { - -namespace { - -constexpr auto entity_id_lessp = [](const auto& a, const auto& b) { return a->id < b->id; }; - -} // namespace - -bool entity_proto::operator==(const entity_proto&) const = default; -entity_proto& entity_proto::operator=(const entity_proto&) = default; -entity_proto::~entity_proto() noexcept = default; -entity_proto::entity_proto() = default; -entity_proto::entity_proto(const entity_proto&) = default; -entity_type entity_proto::type_of() const noexcept { return type; } - -entity::entity(object_id id, struct chunk& c, const entity_proto& proto) : - id{id}, c{&c}, atlas{proto.atlas}, - offset{proto.offset}, bbox_offset{proto.bbox_offset}, - bbox_size{proto.bbox_size}, delta{proto.delta}, - frame{proto.frame}, r{proto.r}, pass{proto.pass} -{ - fm_soft_assert(atlas); - fm_soft_assert(atlas->check_rotation(r)); - fm_soft_assert(frame < atlas->info().nframes); -} - -entity::~entity() noexcept -{ - fm_debug_assert(id); - if (c->_teardown || c->_world->_teardown) [[unlikely]] - return; - if (chunk::bbox bb; c->_bbox_for_scenery(*this, bb)) - c->_remove_bbox(bb); - c->_world->do_kill_entity(id); - const_cast<object_id&>(id) = 0; -} - -float entity::ordinal() const -{ - return ordinal(coord.local(), offset, atlas->group(r).z_offset); -} - -float entity::ordinal(local_coords xy, Vector2b offset, Vector2s z_offset) const -{ - constexpr auto inv_tile_size = 1.f/TILE_SIZE2; - auto offset_ = ordinal_offset(offset); - auto vec = Vector2(xy) + offset_*inv_tile_size; - return vec[0] + vec[1] + Vector2(z_offset).sum(); -} - -struct chunk& entity::chunk() const -{ - return *c; -} - -size_t entity::index() const -{ - auto& c = chunk(); - const auto fn = [id = id](const auto& a, const auto&) { return a->id < id; }; - auto& es = c._entities; - auto it = std::lower_bound(es.cbegin(), es.cend(), nullptr, fn); - fm_assert(it != es.cend()); - fm_assert((*it)->id == id); - return (size_t)std::distance(es.cbegin(), it); -} - -bool entity::is_virtual() const -{ - return false; -} - -bool entity::can_rotate(global_coords coord, rotation new_r, rotation old_r, Vector2b offset, Vector2b bbox_offset, Vector2ub bbox_size) -{ - if (bbox_offset.isZero() && bbox_size[0] == bbox_size[1]) - return true; - const auto offset_ = rotate_point(offset, old_r, new_r); - const auto bbox_offset_ = rotate_point(bbox_offset, old_r, new_r); - const auto bbox_size_ = rotate_size(bbox_size, old_r, new_r); - return can_move_to({}, coord, offset_, bbox_offset_, bbox_size_); -} - -bool entity::can_rotate(rotation new_r) -{ - if (new_r == r) - return true; - - return can_rotate(coord, new_r, r, offset, bbox_offset, bbox_size); -} - -void entity::rotate(size_t, rotation new_r) -{ - fm_assert(atlas->check_rotation(new_r)); - auto offset_ = !is_dynamic() ? rotate_point(offset, r, new_r) : offset; - auto bbox_offset_ = rotate_point(bbox_offset, r, new_r); - auto bbox_size_ = rotate_size(bbox_size, r, new_r); - set_bbox(offset_, bbox_offset_, bbox_size_, pass); - if (r != new_r && !is_dynamic()) - c->mark_scenery_modified(); - - const_cast<rotation&>(r) = new_r; -} - -template <typename T> constexpr T sgn(T val) { return T(T(0) < val) - T(val < T(0)); } - -Pair<global_coords, Vector2b> entity::normalize_coords(global_coords coord, Vector2b cur_offset, Vector2i new_offset) -{ - auto off_tmp = Vector2i(cur_offset) + new_offset; - auto off_new = off_tmp % iTILE_SIZE2; - constexpr auto half_tile = iTILE_SIZE2/2; - for (auto i = 0uz; i < 2; i++) - { - auto sign = sgn(off_new[i]); - auto absval = std::abs(off_new[i]); - if (absval > half_tile[i]) - { - Vector2i v(0); - v[i] = sign; - coord += v; - off_new[i] = (iTILE_SIZE[i] - absval)*-sign; - } - } - return { coord, Vector2b(off_new) }; -} - -template<bool neighbor = true> -static bool do_search(struct chunk* c, chunk_coords_ coord, object_id id, Vector2 min, Vector2 max, Vector2b off = {}) -{ - if constexpr(neighbor) - { - const auto ch = chunk_coords{(int16_t)(coord.x + off[0]), (int16_t)(coord.y + off[1])}; - constexpr auto size = TILE_SIZE2 * TILE_MAX_DIM, grace = TILE_SIZE2 * 4; - const auto off_ = Vector2(off) * size; - min -= off_; - max -= off_; - if (!(min + grace >= Vector2{} && max - grace <= size)) [[likely]] - return true; - auto& w = c->world(); - c = w.at({ch, coord.z}); - if (!c) [[unlikely]] - return true; - } - bool ret = true; - c->rtree()->Search(min.data(), max.data(), [&](object_id data, const auto&) { - auto x = std::bit_cast<collision_data>(data); - if (x.data != id && x.pass != (uint64_t)pass_mode::pass) - return ret = false; - else - return true; - }); - return ret; -} - -bool entity::can_move_to(Vector2i delta, global_coords coord2, Vector2b offset, Vector2b bbox_offset, Vector2ub bbox_size) -{ - auto [coord_, offset_] = normalize_coords(coord2, offset, delta); - - if (coord_.z() != coord.z()) [[unlikely]] - return false; - - auto& w = *c->_world; - auto& c_ = coord_.chunk() == coord.chunk() ? *c : w[{coord_.chunk(), coord_.z()}]; - - const auto center = Vector2(coord_.local())*TILE_SIZE2 + Vector2(offset_) + Vector2(bbox_offset), - half_bbox = Vector2(bbox_size)*.5f, - min = center - half_bbox, max = min + Vector2(bbox_size); - auto ch = chunk_coords_{coord_.chunk(), coord_.z()}; - if (!do_search<false>(&c_, ch, id, min, max)) - return false; - for (const auto& off : world::neighbor_offsets) - if (!do_search(&c_, ch, id, min, max, off)) - return false; - return true; -} - -bool entity::can_move_to(Vector2i delta) -{ - return can_move_to(delta, coord, offset, bbox_offset, bbox_size); -} - -size_t entity::move_to(size_t& i, Vector2i delta, rotation new_r) -{ - if (!can_rotate(new_r)) - return i; - - auto& es = c->_entities; - fm_debug_assert(i < es.size()); - auto e_ = es[i]; - - fm_assert(&*e_ == this); - auto& w = *c->_world; - const auto [coord_, offset_] = normalize_coords(coord, offset, delta); - - if (coord_ == coord && offset_ == offset) - return i; - - if (!is_dynamic()) - c->mark_scenery_modified(); - - chunk::bbox bb0, bb1; - const auto bb_offset = rotate_point(bbox_offset, r, new_r); - const auto bb_size = rotate_size(bbox_size, r, new_r); - bool b0 = c->_bbox_for_scenery(*this, bb0), - b1 = c->_bbox_for_scenery(*this, coord_.local(), offset_, bb_offset, bb_size, bb1); - - if (coord_.chunk() == coord.chunk()) - { - c->_replace_bbox(bb0, bb1, b0, b1); - const_cast<global_coords&>(coord) = coord_; - set_bbox_(offset_, bb_offset, bb_size, pass); - const_cast<rotation&>(r) = new_r; - //for (auto i = 0uz; const auto& x : es) fm_debug("%zu %s %f", i++, x->atlas->name().data(), x->ordinal()); - //fm_debug("insert (%hd;%hd|%hhd;%hhd) %td -> %zu | %f", coord_.chunk().x, coord_.chunk().y, coord_.local().x, coord_.local().y, pos1, es.size(), e.ordinal()); - } - else - { - //fm_debug("change-chunk (%hd;%hd|%hhd;%hhd)", coord_.chunk().x, coord_.chunk().y, coord_.local().x, coord_.local().y); - auto& c2 = w[{coord_.chunk(), coord_.z()}]; - if (!is_dynamic()) - c2.mark_scenery_modified(); - c2._add_bbox(bb1); - c->remove_entity(i); - auto& es = c2._entities; - auto it = std::lower_bound(es.cbegin(), es.cend(), e_, entity_id_lessp); - const_cast<global_coords&>(coord) = coord_; - set_bbox_(offset_, bb_offset, bb_size, pass); - const_cast<rotation&>(r) = new_r; - const_cast<struct chunk*&>(c) = &c2; - i = (size_t)std::distance(es.cbegin(), it); - es.insert(it, std::move(e_)); - } - - return i; -} - -void entity::move_to(Magnum::Vector2i delta) -{ - auto i = index(); - (void)move_to(i, delta, r); -} - -void entity::set_bbox_(Vector2b offset_, Vector2b bbox_offset_, Vector2ub bbox_size_, pass_mode pass_) -{ - const_cast<Vector2b&>(offset) = offset_; - const_cast<Vector2b&>(bbox_offset) = bbox_offset_; - const_cast<Vector2ub&>(bbox_size) = bbox_size_; - const_cast<pass_mode&>(pass) = pass_; -} - -entity::operator entity_proto() const -{ - entity_proto ret; - ret.atlas = atlas; - ret.offset = offset; - ret.bbox_offset = bbox_offset; - ret.bbox_size = bbox_size; - ret.delta = delta; - ret.frame = frame; - ret.type = type(); - ret.r = r; - ret.pass = pass; - return ret; -} - -void entity::set_bbox(Vector2b offset_, Vector2b bbox_offset_, Vector2ub bbox_size_, pass_mode pass) -{ - if (offset != offset_) - if (!is_dynamic()) - c->mark_scenery_modified(); - - chunk::bbox bb0, bb; - const bool b0 = c->_bbox_for_scenery(*this, bb0); - set_bbox_(offset_, bbox_offset_, bbox_size_, pass); - const bool b = c->_bbox_for_scenery(*this, bb); - c->_replace_bbox(bb0, bb, b0, b); -} - -bool entity::can_activate(size_t) const { return false; } -bool entity::activate(size_t) { return false; } - -bool entity::is_dynamic() const -{ - return atlas->info().fps > 0; -} - -entity_type entity::type_of() const noexcept -{ - return type(); -} - -} // namespace floormat |
