Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Multiple Polygon Functions #153

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion code/midtown/mmdyna/bndtmpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ class mmBoundTemplate
// ?WinID@mmBoundTemplate@@2HA | mmdyna:bndtmpl2
ARTS_IMPORT static i32 WinID;

private:
public:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be made public?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.
It's required for mmBoundTemplate::VertPtr and the ->X/Y/Z Dims

// ?DoMakeTable@mmBoundTemplate@@AAEXHHH@Z | mmdyna:bndtmpl2
ARTS_IMPORT void DoMakeTable(i32 arg1, i32 arg2, i32 arg3);

Expand Down
165 changes: 165 additions & 0 deletions code/midtown/mmdyna/poly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,168 @@
define_dummy_symbol(mmdyna_poly);

#include "poly.h"

#include "mmdyna/bndtmpl.h"

f32 mmPolygon::CheckCellXSide(f32 plane_x, f32 z_min, f32 z_max)
{
f32 max_y = -999999.0f;
i32 vert_count = GetNumVerts();

for (i32 i = 0; i < vert_count; ++i)
{
const Vector3& cur_vert = mmBoundTemplate::VertPtr[VertIndices[i]];
const Vector3& next_vert = mmBoundTemplate::VertPtr[VertIndices[(i + 1) % vert_count]];

if ((cur_vert.x < plane_x && next_vert.x > plane_x) || (cur_vert.x > plane_x && next_vert.x < plane_x))
{
f32 factor = (plane_x - cur_vert.x) / (next_vert.x - cur_vert.x);
f32 z_int = (next_vert.z - cur_vert.z) * factor + cur_vert.z;

if (z_int >= z_min && z_int <= z_max)
{
f32 y_int = (next_vert.y - cur_vert.y) * factor + cur_vert.y;
max_y = std::max(max_y, y_int);
}
}
}

return max_y;
}

f32 mmPolygon::CheckCellZSide(f32 plane_z, f32 x_min, f32 x_max)
{
f32 max_y = -999999.0f;
i32 vert_count = GetNumVerts();

for (i32 i = 0; i < vert_count; ++i)
{
const Vector3& cur_vert = mmBoundTemplate::VertPtr[VertIndices[i]];
const Vector3& next_vert = mmBoundTemplate::VertPtr[VertIndices[(i + 1) % vert_count]];

if ((cur_vert.z < plane_z && next_vert.z > plane_z) || (cur_vert.z > plane_z && next_vert.z < plane_z))
{
f32 factor = (plane_z - cur_vert.z) / (next_vert.z - cur_vert.z);
f32 x_int = (next_vert.x - cur_vert.x) * factor + cur_vert.x;

if (x_int >= x_min && x_int <= x_max)
{
f32 y_int = (next_vert.y - cur_vert.y) * factor + cur_vert.y;
max_y = std::max(max_y, y_int);
}
}
}

return max_y;
}

f32 mmPolygon::CheckCorner(f32 x, f32 z, f32* plane_x, f32* plane_z, f32* plane_d)
{
if (PlaneN.y == 0.0f)
{
return -999999.0f;
}

i32 vert_count = GetNumVerts();

for (i32 i = 0; i < vert_count; ++i)
{
if (x * plane_x[i] + z * plane_z[i] + plane_d[i] < 0.0f)
{
return -999999.0f;
}
}

return -(PlaneN.x * x + PlaneD + PlaneN.z * z) / PlaneN.y;
}

f32 mmPolygon::CornersHeight(f32 x1, f32 z1, f32 x2, f32 z2)
{
f32 max_y = -999999.0f;
i32 vert_count = GetNumVerts();
f32 adjusted_sign = (PlaneN.y <= 0.0f) ? 1.0f : -1.0f;
f32 plane_x[4], plane_z[4], plane_d[4];

for (i32 i = 0; i < vert_count; ++i)
{
Vector3& cur_vert = mmBoundTemplate::VertPtr[VertIndices[i]];
Vector3& next_vert = mmBoundTemplate::VertPtr[VertIndices[(i + 1) % vert_count]];

plane_x[i] = -(next_vert.z - cur_vert.z) * adjusted_sign;
plane_z[i] = (next_vert.x - cur_vert.x) * adjusted_sign;
plane_d[i] = -(plane_x[i] * cur_vert.x + plane_z[i] * cur_vert.z);

f32 length = std::sqrt(plane_x[i] * plane_x[i] + plane_z[i] * plane_z[i]);

if (length < 1e-9)
return -999999.0f;

plane_x[i] *= 1.0f / length;
plane_z[i] *= 1.0f / length;
plane_d[i] *= 1.0f / length;
}

for (i32 i = 0; i < 4; ++i)
{
max_y = std::max(max_y, CheckCorner(x1, z1, plane_x, plane_z, plane_d));
max_y = std::max(max_y, CheckCorner(x1, z2, plane_x, plane_z, plane_d));
max_y = std::max(max_y, CheckCorner(x2, z1, plane_x, plane_z, plane_d));
max_y = std::max(max_y, CheckCorner(x2, z2, plane_x, plane_z, plane_d));
}

return max_y;
}

f32 mmPolygon::MaxY(f32 x_min, f32 z_min, f32 x_max, f32 z_max)
{
f32 max_y = -999999.0f;
i32 vert_count = GetNumVerts();

for (i32 i = 0; i < vert_count; ++i)
{
Vector3& vert = mmBoundTemplate::VertPtr[VertIndices[i]];

if (vert.x >= x_min && vert.x <= x_max && vert.z >= z_min && vert.z <= z_max)
{
max_y = std::max(max_y, vert.y);
}
}

max_y = std::max(max_y, CornersHeight(x_min, z_min, x_max, z_max));

max_y = std::max(max_y, CheckCellXSide(x_min, z_min, z_max));
max_y = std::max(max_y, CheckCellXSide(x_max, z_min, z_max));

max_y = std::max(max_y, CheckCellZSide(z_min, x_min, x_max));
max_y = std::max(max_y, CheckCellZSide(z_max, x_min, x_max));

return max_y;
}

void mmPolygon::Plot(mmBoundTemplate* t, i32 poly_index)
{
if (IsQuad())
{
PlotTriangle(0, 1, 2, t, poly_index);
PlotTriangle(0, 2, 3, t, poly_index);
}
else
{
PlotTriangle(0, 1, 2, t, poly_index);
}
}

void mmPolygon::PlotScan(i32 x1, i32 x2, i32 z, mmBoundTemplate* t, i32 poly_index)
{
if (!t)
return;

z = std::clamp(z, 0, t->ZDim - 1);
x1 = std::clamp(x1, 0, t->XDim - 1);
x2 = std::clamp(x2, 0, t->XDim - 1);

for (i32 x = x1; x <= x2; ++x)
{
t->AddIndex(x, z, poly_index);
}
}
24 changes: 17 additions & 7 deletions code/midtown/mmdyna/poly.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,16 @@ class mmPolygon

private:
// ?CheckCellXSide@mmPolygon@@AAEMMMM@Z
ARTS_IMPORT f32 CheckCellXSide(f32 arg1, f32 arg2, f32 arg3);
ARTS_EXPORT f32 CheckCellXSide(f32 plane_x, f32 z_min, f32 z_max);

// ?CheckCellZSide@mmPolygon@@AAEMMMM@Z
ARTS_IMPORT f32 CheckCellZSide(f32 arg1, f32 arg2, f32 arg3);
ARTS_EXPORT f32 CheckCellZSide(f32 plane_z, f32 x_min, f32 x_max);

// ?CheckCorner@mmPolygon@@AAEMMMPAM00@Z
ARTS_IMPORT f32 CheckCorner(f32 arg1, f32 arg2, f32* arg3, f32* arg4, f32* arg5);
ARTS_EXPORT f32 CheckCorner(f32 x, f32 z, f32* plane_x, f32* plane_z, f32* plane_d);

// ?CornersHeight@mmPolygon@@AAEMMMMM@Z
ARTS_IMPORT f32 CornersHeight(f32 arg1, f32 arg2, f32 arg3, f32 arg4);
ARTS_EXPORT f32 CornersHeight(f32 x1, f32 z1, f32 x2, f32 z2);

#ifdef ARTS_DEV_BUILD
// ?Draw@mmPolygon@@AAEXXZ
Expand All @@ -90,17 +90,27 @@ class mmPolygon
ARTS_IMPORT void Init();

// ?MaxY@mmPolygon@@AAEMMMMM@Z
ARTS_IMPORT f32 MaxY(f32 arg1, f32 arg2, f32 arg3, f32 arg4);
ARTS_EXPORT f32 MaxY(f32 x_min, f32 z_min, f32 x_max, f32 z_max);

// ?Plot@mmPolygon@@AAEXPAVmmBoundTemplate@@H@Z
ARTS_IMPORT void Plot(mmBoundTemplate* arg1, i32 arg2);
ARTS_EXPORT void Plot(mmBoundTemplate* t, i32 poly_index);

// ?PlotScan@mmPolygon@@AAEXHHHPAVmmBoundTemplate@@H@Z
ARTS_IMPORT void PlotScan(i32 arg1, i32 arg2, i32 arg3, mmBoundTemplate* arg4, i32 arg5);
ARTS_EXPORT void PlotScan(i32 x1, i32 x2, i32 z, mmBoundTemplate* t, i32 poly_index);

// ?PlotTriangle@mmPolygon@@AAEXHHHPAVmmBoundTemplate@@H@Z
ARTS_IMPORT void PlotTriangle(i32 arg1, i32 arg2, i32 arg3, mmBoundTemplate* arg4, i32 arg5);

i32 GetNumVerts() const
{
return IsQuad() ? 4 : 3;
}

b32 IsQuad() const
{
return (Flags & 4) != 0;
}

public:
u16 RoomId;
u8 MtlIndex;
Expand Down