parent
7c18fd44c3
commit
3637430a41
2 changed files with 89 additions and 11 deletions
|
@ -22,6 +22,7 @@
|
|||
#ifndef ULTIMA8_WORLD_SORTITEM_H
|
||||
#define ULTIMA8_WORLD_SORTITEM_H
|
||||
|
||||
#include "common/str.h"
|
||||
#include "ultima/ultima8/misc/common_types.h"
|
||||
|
||||
namespace Ultima {
|
||||
|
@ -341,8 +342,8 @@ inline bool SortItem::below(const SortItem &si2) const {
|
|||
// Specialist z flat handling
|
||||
if (si1._flat && si2._flat) {
|
||||
// Differing z is easy for flats
|
||||
if (si1._zTop != si2._zTop)
|
||||
return si1._zTop < si2._zTop;
|
||||
if (si1._z != si2._z)
|
||||
return si1._z < si2._z;
|
||||
|
||||
// Equal z
|
||||
|
||||
|
@ -381,22 +382,32 @@ inline bool SortItem::below(const SortItem &si2) const {
|
|||
}
|
||||
|
||||
// Clearly in z
|
||||
if (si1._zTop <= si2._z)
|
||||
if (si1._z < si2._z && si1._zTop <= si2._z)
|
||||
return true;
|
||||
|
||||
if (si1._z >= si2._zTop)
|
||||
if (si1._z > si2._z && si1._z >= si2._zTop)
|
||||
return false;
|
||||
|
||||
// Overlapping z-bottom check
|
||||
// If an object's base (z-bottom) is higher another's, it should be rendered after.
|
||||
// This check must be on the z-bottom and not the z-top because two objects with the
|
||||
// same z-position may have different heights (think of a mouse sorting vs the Avatar).
|
||||
if (si1._z != si2._z)
|
||||
return si1._z < si2._z;
|
||||
|
||||
// Equal z
|
||||
|
||||
// Flat always gets drawn before
|
||||
if (si1._flat != si2._flat)
|
||||
return si1._flat > si2._flat;
|
||||
|
||||
// Trans always gets drawn after
|
||||
if (si1._trans != si2._trans)
|
||||
return si1._trans < si2._trans;
|
||||
}
|
||||
|
||||
// Are overlapping in all 3 dimentions if we come here
|
||||
|
||||
// Overlapping z-bottom check
|
||||
// If an object's base (z-bottom) is higher another's, it should be rendered after.
|
||||
// This check must be on the z-bottom and not the z-top because two objects with the
|
||||
// same z-position may have different heights (think of a mouse sorting vs the Avatar).
|
||||
if (si1._z != si2._z)
|
||||
return si1._z < si2._z;
|
||||
|
||||
// Land always gets drawn first
|
||||
if (si1._land != si2._land)
|
||||
return si1._land > si2._land;
|
||||
|
|
|
@ -155,6 +155,37 @@ class U8SortItemTestSuite : public CxxTest::TestSuite {
|
|||
TS_ASSERT(!si2.below(si1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Overlapping non-flat items draw transparent after
|
||||
* Test case for rendering issue at MainActor::teleport 41 17627 16339 48
|
||||
* Wall with window should render after non-window wall
|
||||
*/
|
||||
void test_nonflat_tranparent_sort() {
|
||||
Ultima::Ultima8::SortItem si1(nullptr);
|
||||
Ultima::Ultima8::SortItem si2(nullptr);
|
||||
|
||||
si1._x = 32;
|
||||
si1._y = 96;
|
||||
si1._z = 0;
|
||||
si1._xLeft = 0;
|
||||
si1._yFar = 0;
|
||||
si1._zTop = 40;
|
||||
si1._solid = true;
|
||||
|
||||
si2._x = 32;
|
||||
si2._y = 160;
|
||||
si2._z = 0;
|
||||
si2._xLeft = 0;
|
||||
si2._yFar = 32;
|
||||
si2._zTop = 40;
|
||||
si2._trans = true;
|
||||
si2._solid = true;
|
||||
si2._land = true;
|
||||
|
||||
TS_ASSERT(si1.below(si2));
|
||||
TS_ASSERT(!si2.below(si1));
|
||||
}
|
||||
|
||||
/* Overlapping non-flat occludes flat */
|
||||
void test_basic_occludes() {
|
||||
Ultima::Ultima8::SortItem si1(nullptr);
|
||||
|
@ -173,4 +204,40 @@ class U8SortItemTestSuite : public CxxTest::TestSuite {
|
|||
TS_ASSERT(si1.occludes(si2));
|
||||
TS_ASSERT(!si2.occludes(si1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Overlapping non-flat does occlude flat due to frame offset
|
||||
* Test case for rendering issue at MainActor::teleport 49 19167 17582 48
|
||||
*/
|
||||
void test_frame_offset_occludes() {
|
||||
Ultima::Ultima8::SortItem si1(nullptr);
|
||||
Ultima::Ultima8::SortItem si2(nullptr);
|
||||
|
||||
si1._xLeft = si2._xLeft = 0;
|
||||
si1._yFar = si2._yFar = 0;
|
||||
si1._z = si2._z = 0;
|
||||
si1._y = si2._y = 128;
|
||||
si1._x = si2._x = 128;
|
||||
si1._zTop = 16;
|
||||
si2._zTop = 0;
|
||||
|
||||
si1.calculateBoxBounds(0, 0);
|
||||
si2.calculateBoxBounds(0, 0);
|
||||
|
||||
// ShapeFrame (240:1)
|
||||
si1._sx = si1._sxBot - 32;
|
||||
si1._sy = si1._syBot - 48;
|
||||
si1._sx2 = si1._sx + 65;
|
||||
si1._sy2 = si1._sy + 48;
|
||||
|
||||
// ShapeFrame (301:1)
|
||||
si2._sx = si2._sxBot - 31;
|
||||
si2._sy = si2._syBot - 31;
|
||||
si2._sx2 = si2._sx + 62;
|
||||
si2._sy2 = si2._sy + 32;
|
||||
|
||||
// FIXME: This case fails here currently
|
||||
//TS_ASSERT(!si1.occludes(si2));
|
||||
TS_ASSERT(!si2.occludes(si1));
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue