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 2 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
190 changes: 190 additions & 0 deletions code/midtown/mmdyna/poly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,193 @@
define_dummy_symbol(mmdyna_poly);

#include "poly.h"

#include "mmdyna/bndtmpl.h"

f32 mmPolygon::CheckCellXSide(f32 x_plane, f32 z_min, f32 z_max)
{
f32 max_y = -999999.0f;
i32 vert_count = (Flags & 4) != 0 ? 4 : 3;
Copy link
Owner

Choose a reason for hiding this comment

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

Could you replace the manual flag checks with functons? Like IsQuad() and GetNumVerts()


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

Choose a reason for hiding this comment

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

Can remove the modulo here

const Vector3& next_vert = mmBoundTemplate::VertPtr[VertIndices[(i + 1) % vert_count]];

if ((cur_vert.x < x_plane && next_vert.x > x_plane) || (cur_vert.x > x_plane && next_vert.x < x_plane))
{
f32 factor = (x_plane - 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;

if (y_int > max_y)
{
max_y = y_int;
}
Copy link
Owner

Choose a reason for hiding this comment

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

Can be replaced with std::max

}
}
}

return max_y;
}

f32 mmPolygon::CheckCellZSide(f32 z_plane, f32 x_min, f32 x_max)
{
f32 max_y = -999999.0f;
i32 vert_count = (Flags & 4) != 0 ? 4 : 3;

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

if ((cur_vert.z < z_plane && next_vert.z > z_plane) || (cur_vert.z > z_plane && next_vert.z < z_plane))
{
f32 factor = (z_plane - 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;

if (y_int > max_y)
{
max_y = y_int;
}
}
}
}

return max_y;
}

f32 mmPolygon::CheckCorner(f32 x, f32 z, f32* x_plane, f32* z_plane, f32* const_plane)
Copy link
Owner

Choose a reason for hiding this comment

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

I think maybe plane_x, plane_z, and plane_d may be better names for these

{
if (PlaneN.y == 0.0f)
{
return -999999.0f;
}

i32 vert_count = (Flags & 4) ? 4 : 3;

for (i32 i = 0; i < vert_count; ++i)
{
if (x * x_plane[i] + z * z_plane[i] + const_plane[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 = (Flags & 4) ? 4 : 3;
f32 adjusted_sign = (PlaneN.y <= 0.0f) ? 1.0f : -1.0f;
f32 x_plane[4], z_plane[4], const_plane[4], length, inverse_length;
Copy link
Owner

Choose a reason for hiding this comment

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

Try and avoid forward declaring variables when not necssary, i.e length, inverse_length


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]];

x_plane[i] = -(next_vert.z - cur_vert.z) * adjusted_sign;
z_plane[i] = (next_vert.x - cur_vert.x) * adjusted_sign;
const_plane[i] = -(x_plane[i] * cur_vert.x + z_plane[i] * cur_vert.z);

length = std::sqrt(x_plane[i] * x_plane[i] + z_plane[i] * z_plane[i]);

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

inverse_length = 1.0f / length;
x_plane[i] *= inverse_length;
z_plane[i] *= inverse_length;
const_plane[i] *= inverse_length;
}

for (i32 i = 0; i < 4; ++i)
{
f32 corner_height;

corner_height = CheckCorner(x1, z1, x_plane, z_plane, const_plane);
max_y = std::max(max_y, corner_height);

corner_height = CheckCorner(x1, z2, x_plane, z_plane, const_plane);
max_y = std::max(max_y, corner_height);

corner_height = CheckCorner(x2, z1, x_plane, z_plane, const_plane);
max_y = std::max(max_y, corner_height);

corner_height = CheckCorner(x2, z2, x_plane, z_plane, const_plane);
max_y = std::max(max_y, corner_height);
Copy link
Owner

Choose a reason for hiding this comment

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

You can just inline these into the param for max, not much point assigning them to a variable

}

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 = (Flags & 4) != 0 ? 4 : 3;

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);
}
}

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

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

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

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

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

return max_y;
}

void mmPolygon::Plot(mmBoundTemplate* t, i32 poly_index)
{
if (Flags & 4)
{
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);
}
}
14 changes: 7 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 x_plane, 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 z_plane, 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* x_plane, f32* z_plane, f32* const_plane);

// ?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,13 +90,13 @@ 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);
Expand Down