rodecomp/Source/Contents/WorldOcclusion.cpp
2026-10-24 00:35:19 +00:00

71 lines
1.8 KiB
C++

#include "Contents/GroundGeometry.h"
#include "Contents/ModelActor.h"
#include "Contents/WorldOcclusion.h"
#include "Contents/WorldRayQuery.h"
#include "Contents/WorldSpatialTree.h"
#include "Render/RenderProjection.h"
#include <bit>
#include <cstring>
#include <emmintrin.h>
// OFFSET: 0x00CD5AD0
// FUNCTION: fn_21286
void MarkWorldOcclusionRay(
const float* ray,
float actorLimit,
float groundLimit,
WorldSpatialTree& root,
GroundGeometry& ground,
bool markGround
) {
float actorRay[7];
std::memcpy(actorRay, ray, 6 * sizeof(float));
actorRay[6] = actorLimit;
WorldRayQuery query;
query.Collect(ray, &root);
for (WorldSpatialTree* node : query.nodes) {
for (C3dActor* model : node->objects) {
model->MarkOccluded(actorRay);
}
}
if (markGround) {
for (WorldSpatialTree* node : query.nodes) {
int row = node->groundCells[1];
while (row <= node->groundCells[3]) {
int column = node->groundCells[0];
while (column <= node->groundCells[2]) {
ground.MarkRay(ray, column, row, groundLimit);
column = std::bit_cast<int>(static_cast<unsigned>(column) + 1u);
}
row = std::bit_cast<int>(static_cast<unsigned>(row) + 1u);
}
}
}
}
void MarkScreenWorldOcclusion(
const RenderProjection& projection,
int screenX,
int screenY,
float rendererScale,
const float* origin,
const float* cameraMatrix,
float playerHeight,
float cameraHeight,
WorldSpatialTree& root,
GroundGeometry& ground,
bool markGround
) {
const float shifted = static_cast<float>(screenY) - rendererScale * 23.0f;
const int y = _mm_cvttss_si32(_mm_set_ss(shifted));
float ray[6]{};
projection.Ray(screenX, y, origin, cameraMatrix, ray);
const float limit = (playerHeight + cameraHeight) - 16.0f;
MarkWorldOcclusionRay(ray, limit, limit, root, ground, markGround);
}