581 | | CPatchRData* data = visiblePatches[i]; |
582 | | const CBoundingBoxAligned& waterBounds = data->GetWaterBounds(); |
583 | | if (waterBounds.IsEmpty()) |
584 | | continue; |
585 | | |
586 | | CVector4D v1 = viewproj.Transform(CVector4D(waterBounds[0].X, waterBounds[1].Y, waterBounds[0].Z, 1.0f)); |
587 | | CVector4D v2 = viewproj.Transform(CVector4D(waterBounds[1].X, waterBounds[1].Y, waterBounds[0].Z, 1.0f)); |
588 | | CVector4D v3 = viewproj.Transform(CVector4D(waterBounds[0].X, waterBounds[1].Y, waterBounds[1].Z, 1.0f)); |
589 | | CVector4D v4 = viewproj.Transform(CVector4D(waterBounds[1].X, waterBounds[1].Y, waterBounds[1].Z, 1.0f)); |
591 | | #define ADDBOUND(v1, v2, v3, v4) \ |
592 | | if (v1.Z >= -v1.W) \ |
593 | | screenBounds += CVector3D(v1.X, v1.Y, v1.Z) * (1.0f / v1.W); \ |
594 | | else \ |
595 | | { \ |
596 | | float t = v1.Z + v1.W; \ |
597 | | if (v2.Z > -v2.W) \ |
598 | | { \ |
599 | | CVector4D c2 = v1 + (v2 - v1) * (t / (t - (v2.Z + v2.W))); \ |
600 | | screenBounds += CVector3D(c2.X, c2.Y, c2.Z) * (1.0f / c2.W); \ |
601 | | } \ |
602 | | if (v3.Z > -v3.W) \ |
603 | | { \ |
604 | | CVector4D c3 = v1 + (v3 - v1) * (t / (t - (v3.Z + v3.W))); \ |
605 | | screenBounds += CVector3D(c3.X, c3.Y, c3.Z) * (1.0f / c3.W); \ |
606 | | } \ |
607 | | if (v4.Z > -v4.W) \ |
608 | | { \ |
609 | | CVector4D c4 = v1 + (v4 - v1) * (t / (t - (v4.Z + v4.W))); \ |
610 | | screenBounds += CVector3D(c4.X, c4.Y, c4.Z) * (1.0f / c4.W); \ |
611 | | } \ |
612 | | } |
613 | | ADDBOUND(v1, v2, v3, v4); |
614 | | ADDBOUND(v2, v1, v3, v4); |
615 | | ADDBOUND(v3, v1, v2, v4); |
616 | | ADDBOUND(v4, v1, v2, v3); |
617 | | #undef ADDBOUND |
618 | | if (screenBounds[0].X >= 1.0f || screenBounds[1].X <= -1.0f || screenBounds[0].Y >= 1.0f || screenBounds[1].Y <= -1.0f) |
619 | | continue; |
| 582 | visiblePatches[i]->GetWaterBounds().Transform(viewproj, screenBounds); |