22 #ifndef ULTIMA8_WORLD_SORTITEM_H 23 #define ULTIMA8_WORLD_SORTITEM_H 25 #include "common/str.h" 26 #include "ultima/ultima8/misc/common_types.h" 27 #include "ultima/ultima8/misc/rect.h" 28 #include "ultima/ultima8/misc/box.h" 44 SortItem() : _next(
nullptr), _prev(
nullptr), _itemNum(0),
45 _shape(
nullptr), _order(-1), _depends(), _shapeNum(0),
46 _frame(0), _flags(0), _extFlags(0), _sr(),
47 _x(0), _y(0), _z(0), _xLeft(0),
48 _yFar(0), _zTop(0), _sxLeft(0), _sxRight(0), _sxTop(0),
49 _syTop(0), _sxBot(0), _syBot(0),_fbigsq(
false), _flat(
false),
50 _occl(
false), _solid(
false), _draw(
false), _roof(
false),
51 _noisy(
false), _anim(
false), _trans(
false), _fixed(
false),
52 _land(
false), _occluded(
false), _sprite(
false),
98 #ifdef SORTITEM_OCCLUSION_EXPERIMENTAL 102 #endif // SORTITEM_OCCLUSION_EXPERIMENTAL 133 Node() : _next(
nullptr), _prev(
nullptr), val(
nullptr) { }
150 bool operator != (
const iterator &o)
const {
164 tail->_next = unused;
172 if (!unused) unused =
new Node();
174 unused = unused->_next;
178 if (tail) tail->_next = nn;
179 if (!list) list = nn;
185 void insert_sorted(
SortItem *other) {
186 if (!unused) unused =
new Node();
188 unused = unused->_next;
191 for (
Node *n = list; n !=
nullptr; n = n->_next) {
193 if (other->listLessThan(*(n->val))) {
195 nn->_prev = n->_prev;
197 if (nn->_prev) nn->_prev->_next = nn;
204 if (tail) tail->_next = nn;
205 if (!list) list = nn;
211 DependsList() : list(
nullptr), tail(
nullptr), unused(
nullptr) { }
216 Node *n = unused->_next;
229 void setBoxBounds(
const Box &box, int32 sx, int32 sy);
231 inline Box getBoxBounds()
const {
236 box._xd = _x - _xLeft;
237 box._yd = _y - _yFar;
238 box._zd = _zTop - _z;
243 inline bool contains(int32 sx, int32 sy)
const;
246 inline bool overlap(
const SortItem &si2)
const;
249 inline bool occludes(
const SortItem &si2)
const;
252 bool below(
const SortItem &si2)
const;
255 inline bool listLessThan(
const SortItem &si2)
const {
257 if (si1._sprite != si2._sprite)
258 return si1._sprite < si2._sprite;
260 if (si1._z != si2._z)
261 return si1._z < si2._z;
263 return si1._flat > si2._flat;
269 inline bool SortItem::contains(int32 sx, int32 sy)
const {
270 if (!_sr.contains(sx, sy))
273 const int point_top_diff[2] = { _sxTop - sx, _syTop - sy };
274 const int point_bot_diff[2] = { _sxBot - sx, _syBot - sy };
281 const int32 dot_top_left = point_top_diff[0] + point_top_diff[1] * 2;
284 const int32 dot_top_right = -point_top_diff[0] + point_top_diff[1] * 2;
287 const int32 dot_bot_left = point_bot_diff[0] - point_bot_diff[1] * 2;
290 const int32 dot_bot_right = -point_bot_diff[0] - point_bot_diff[1] * 2;
292 const bool right_clear = _sxRight < sx;
293 const bool left_clear = _sxLeft > sx;
294 const bool top_left_clear = dot_top_left > 0;
295 const bool top_right_clear = dot_top_right > 0;
296 const bool bot_left_clear = dot_bot_left > 0;
297 const bool bot_right_clear = dot_bot_right > 0;
299 const bool clear = right_clear || left_clear ||
300 (bot_right_clear || bot_left_clear) ||
301 (top_right_clear || top_left_clear);
306 inline bool SortItem::overlap(
const SortItem &si2)
const {
307 if (!_sr.intersects(si2._sr))
310 const int point_top_diff[2] = { _sxTop - si2._sxBot, _syTop - si2._syBot };
311 const int point_bot_diff[2] = { _sxBot - si2._sxTop, _syBot - si2._syTop };
318 const int32 dot_top_left = point_top_diff[0] + point_top_diff[1] * 2;
321 const int32 dot_top_right = -point_top_diff[0] + point_top_diff[1] * 2;
324 const int32 dot_bot_left = point_bot_diff[0] - point_bot_diff[1] * 2;
327 const int32 dot_bot_right = -point_bot_diff[0] - point_bot_diff[1] * 2;
329 const bool right_clear = _sxRight <= si2._sxLeft;
330 const bool left_clear = _sxLeft >= si2._sxRight;
331 const bool top_left_clear = dot_top_left >= 0;
332 const bool top_right_clear = dot_top_right >= 0;
333 const bool bot_left_clear = dot_bot_left >= 0;
334 const bool bot_right_clear = dot_bot_right >= 0;
336 const bool clear = right_clear || left_clear ||
337 (bot_right_clear || bot_left_clear) ||
338 (top_right_clear || top_left_clear);
343 inline bool SortItem::occludes(
const SortItem &si2)
const {
344 if (!_sr.contains(si2._sr))
347 const int point_top_diff[2] = { _sxTop - si2._sxTop, _syTop - si2._syTop };
348 const int point_bot_diff[2] = { _sxBot - si2._sxBot, _syBot - si2._syBot };
355 const int32 dot_top_left = point_top_diff[0] + point_top_diff[1] * 2;
358 const int32 dot_top_right = -point_top_diff[0] + point_top_diff[1] * 2;
361 const int32 dot_bot_left = point_bot_diff[0] - point_bot_diff[1] * 2;
364 const int32 dot_bot_right = -point_bot_diff[0] - point_bot_diff[1] * 2;
367 const bool right_res = _sxRight >= si2._sxRight;
368 const bool left_res = _sxLeft <= si2._sxLeft;
369 const bool top_left_res = dot_top_left <= 0;
370 const bool top_right_res = dot_top_right <= 0;
371 const bool bot_left_res = dot_bot_left <= 0;
372 const bool bot_right_res = dot_bot_right <= 0;
374 return right_res && left_res && bot_right_res && bot_left_res &&
375 top_right_res && top_left_res;
Definition: sort_item.h:129
Definition: detection.h:27
Definition: sort_item.h:43
Definition: sort_item.h:128
Definition: sort_item.h:140