22 #ifndef ULTIMA8_WORLD_SORTITEM_H 23 #define ULTIMA8_WORLD_SORTITEM_H 25 #include "common/rect.h" 26 #include "common/str.h" 27 #include "ultima/ultima8/misc/box.h" 43 SortItem() : _next(
nullptr), _prev(
nullptr), _itemNum(0),
44 _shape(
nullptr), _order(-1), _depends(), _shapeNum(0),
45 _frame(0), _flags(0), _extFlags(0), _sr(),
46 _x(0), _y(0), _z(0), _xLeft(0),
47 _yFar(0), _zTop(0), _sxLeft(0), _sxRight(0), _sxTop(0),
48 _syTop(0), _sxBot(0), _syBot(0),_fbigsq(
false), _flat(
false),
49 _occl(
false), _solid(
false), _draw(
false), _roof(
false),
50 _noisy(
false), _anim(
false), _trans(
false), _fixed(
false),
51 _land(
false), _occluded(
false), _sprite(
false),
97 #ifdef SORTITEM_OCCLUSION_EXPERIMENTAL 101 #endif // SORTITEM_OCCLUSION_EXPERIMENTAL 132 Node() : _next(
nullptr), _prev(
nullptr), val(
nullptr) { }
149 bool operator != (
const iterator &o)
const {
163 tail->_next = unused;
171 if (!unused) unused =
new Node();
173 unused = unused->_next;
177 if (tail) tail->_next = nn;
178 if (!list) list = nn;
184 void insert_sorted(
SortItem *other) {
185 if (!unused) unused =
new Node();
187 unused = unused->_next;
190 for (
Node *n = list; n !=
nullptr; n = n->_next) {
192 if (other->listLessThan(*(n->val))) {
194 nn->_prev = n->_prev;
196 if (nn->_prev) nn->_prev->_next = nn;
203 if (tail) tail->_next = nn;
204 if (!list) list = nn;
210 DependsList() : list(
nullptr), tail(
nullptr), unused(
nullptr) { }
215 Node *n = unused->_next;
228 void setBoxBounds(
const Box &box, int32 sx, int32 sy);
230 inline Box getBoxBounds()
const {
235 box._xd = _x - _xLeft;
236 box._yd = _y - _yFar;
237 box._zd = _zTop - _z;
242 inline bool contains(int32 sx, int32 sy)
const;
245 inline bool overlap(
const SortItem &si2)
const;
248 inline bool occludes(
const SortItem &si2)
const;
251 bool below(
const SortItem &si2)
const;
254 inline bool listLessThan(
const SortItem &si2)
const {
256 if (si1._sprite != si2._sprite)
257 return si1._sprite < si2._sprite;
259 if (si1._z != si2._z)
260 return si1._z < si2._z;
262 return si1._flat > si2._flat;
268 inline bool SortItem::contains(int32 sx, int32 sy)
const {
269 if (!_sr.contains(sx, sy))
272 const int point_top_diff[2] = { _sxTop - sx, _syTop - sy };
273 const int point_bot_diff[2] = { _sxBot - sx, _syBot - sy };
280 const int32 dot_top_left = point_top_diff[0] + point_top_diff[1] * 2;
283 const int32 dot_top_right = -point_top_diff[0] + point_top_diff[1] * 2;
286 const int32 dot_bot_left = point_bot_diff[0] - point_bot_diff[1] * 2;
289 const int32 dot_bot_right = -point_bot_diff[0] - point_bot_diff[1] * 2;
291 const bool right_clear = _sxRight < sx;
292 const bool left_clear = _sxLeft > sx;
293 const bool top_left_clear = dot_top_left > 0;
294 const bool top_right_clear = dot_top_right > 0;
295 const bool bot_left_clear = dot_bot_left > 0;
296 const bool bot_right_clear = dot_bot_right > 0;
298 const bool clear = right_clear || left_clear ||
299 (bot_right_clear || bot_left_clear) ||
300 (top_right_clear || top_left_clear);
305 inline bool SortItem::overlap(
const SortItem &si2)
const {
306 if (!_sr.intersects(si2._sr))
309 const int point_top_diff[2] = { _sxTop - si2._sxBot, _syTop - si2._syBot };
310 const int point_bot_diff[2] = { _sxBot - si2._sxTop, _syBot - si2._syTop };
317 const int32 dot_top_left = point_top_diff[0] + point_top_diff[1] * 2;
320 const int32 dot_top_right = -point_top_diff[0] + point_top_diff[1] * 2;
323 const int32 dot_bot_left = point_bot_diff[0] - point_bot_diff[1] * 2;
326 const int32 dot_bot_right = -point_bot_diff[0] - point_bot_diff[1] * 2;
328 const bool right_clear = _sxRight <= si2._sxLeft;
329 const bool left_clear = _sxLeft >= si2._sxRight;
330 const bool top_left_clear = dot_top_left >= 0;
331 const bool top_right_clear = dot_top_right >= 0;
332 const bool bot_left_clear = dot_bot_left >= 0;
333 const bool bot_right_clear = dot_bot_right >= 0;
335 const bool clear = right_clear || left_clear ||
336 (bot_right_clear || bot_left_clear) ||
337 (top_right_clear || top_left_clear);
342 inline bool SortItem::occludes(
const SortItem &si2)
const {
343 if (!_sr.contains(si2._sr))
346 const int point_top_diff[2] = { _sxTop - si2._sxTop, _syTop - si2._syTop };
347 const int point_bot_diff[2] = { _sxBot - si2._sxBot, _syBot - si2._syBot };
354 const int32 dot_top_left = point_top_diff[0] + point_top_diff[1] * 2;
357 const int32 dot_top_right = -point_top_diff[0] + point_top_diff[1] * 2;
360 const int32 dot_bot_left = point_bot_diff[0] - point_bot_diff[1] * 2;
363 const int32 dot_bot_right = -point_bot_diff[0] - point_bot_diff[1] * 2;
366 const bool right_res = _sxRight >= si2._sxRight;
367 const bool left_res = _sxLeft <= si2._sxLeft;
368 const bool top_left_res = dot_top_left <= 0;
369 const bool top_right_res = dot_top_right <= 0;
370 const bool bot_left_res = dot_bot_left <= 0;
371 const bool bot_right_res = dot_bot_right <= 0;
373 return right_res && left_res && bot_right_res && bot_left_res &&
374 top_right_res && top_left_res;
Definition: sort_item.h:128
Definition: detection.h:27
Definition: sort_item.h:42
Definition: sort_item.h:127
Definition: sort_item.h:139