Skip to content

Commit

Permalink
Fix handling of waveset bounding boxes.
Browse files Browse the repository at this point in the history
See CWE's `plGeometrySpans::AdjustBounds()` for the source of this
change. Wavesets are flattened at runtime to the water height and are
perturbed along the world Z axis. The input mesh, OTOH, conforms to the
bottom of the pool. This means that if we simply spit out the bounding
box of the input mesh, the resulting bounding box will be too deep in
the -Z direction and not contain any of the +Z displacement needed. This
means that the waveset could vanish due to culling.
  • Loading branch information
Hoikas committed Apr 7, 2024
1 parent ebb8db0 commit 1d9370e
Showing 1 changed file with 31 additions and 7 deletions.
38 changes: 31 additions & 7 deletions core/PRP/Geometry/plDrawableSpans.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -531,14 +531,38 @@ void plDrawableSpans::calcBounds()
hsBounds3Ext world;

world.setFlags(hsBounds3Ext::kAxisAligned);
auto localPoints = std::make_unique<hsVector3[]>(verts.size());
auto worldPoints = std::make_unique<hsVector3[]>(verts.size());
for (size_t j = 0; j < verts.size(); j++) {
localPoints[j] = verts[j].fPos;
worldPoints[j] = fIcicles[i]->getLocalToWorld().multPoint(verts[j].fPos);
if (fIcicles[i]->getProps() & plSpan::kWaterHeight) {
constexpr float kMaxWaveHeight = 5.f;

auto localPoints = std::make_unique<hsVector3[]>(verts.size());
for (size_t j = 0; j < verts.size(); j++)
localPoints[j] = verts[j].fPos;
loc.setFromPoints(verts.size(), localPoints.get());

// Water is flattened at runtime to the water height Z
// coordinate. The bounding box needs to be bloated out
// a bit, though, to account for the maximum possible geometry
// waves.
hsVector3 reboundPts[]{ loc.getMins(), loc.getMaxs() };
for (hsVector3& pt : reboundPts)
pt = fIcicles[i]->getLocalToWorld().multPoint(pt);
reboundPts[0].Z = fIcicles[i]->getWaterHeight() - kMaxWaveHeight;
reboundPts[1].Z = fIcicles[i]->getWaterHeight() + kMaxWaveHeight;

world.setFromPoints(std::size(reboundPts), reboundPts);
for (hsVector3& pt : reboundPts)
pt = fIcicles[i]->getWorldToLocal().multPoint(pt);
loc.setFromPoints(std::size(reboundPts), reboundPts);
} else {
auto localPoints = std::make_unique<hsVector3[]>(verts.size());
auto worldPoints = std::make_unique<hsVector3[]>(verts.size());
for (size_t j = 0; j < verts.size(); j++) {
localPoints[j] = verts[j].fPos;
worldPoints[j] = fIcicles[i]->getLocalToWorld().multPoint(verts[j].fPos);
}
loc.setFromPoints(verts.size(), localPoints.get());
world.setFromPoints(verts.size(), worldPoints.get());
}
loc.setFromPoints(verts.size(), localPoints.get());
world.setFromPoints(verts.size(), worldPoints.get());
loc.unalign();

fIcicles[i]->setLocalBounds(loc);
Expand Down

0 comments on commit 1d9370e

Please sign in to comment.