Fix some more portal hole cutting bugs

This commit is contained in:
James Lambert 2022-07-05 17:56:39 -06:00
parent f7167ecd72
commit 12c7ae1741
4 changed files with 34 additions and 22 deletions

View file

@ -20,15 +20,17 @@ struct Vector3 gPortalOutline[PORTAL_LOOP_SIZE] = {
{-0.353553f * SCENE_SCALE, 0.707107f * SCENE_SCALE, 0.0f},
};
struct Vector3 gPortalOutlineUnscaled[PORTAL_LOOP_SIZE] = {
{-0.353553f, 0.707107f, 0.0f},
{-0.5f, 0.0f, 0.0f},
{-0.353553f, -0.707107f, 0.0f},
{0.0f, -1.0f, 0.0f},
{0.353553f, -0.707107f, 0.0f},
{0.5f, 0.0f, 0.0f},
{0.353553f, 0.707107f, 0.0f},
{0.0f, 1.0f, 0.0f},
#define PORTAL_OUTLINE_WORLD_SCALE 0.95f
struct Vector3 gPortalOutlineWorld[PORTAL_LOOP_SIZE] = {
{-0.353553f * PORTAL_OUTLINE_WORLD_SCALE, 0.707107f * PORTAL_OUTLINE_WORLD_SCALE, 0.0f},
{-0.5f * PORTAL_OUTLINE_WORLD_SCALE, 0.0f, 0.0f},
{-0.353553f * PORTAL_OUTLINE_WORLD_SCALE, -0.707107f * PORTAL_OUTLINE_WORLD_SCALE, 0.0f},
{0.0f, -1.0f * PORTAL_OUTLINE_WORLD_SCALE, 0.0f},
{0.353553f * PORTAL_OUTLINE_WORLD_SCALE, -0.707107f * PORTAL_OUTLINE_WORLD_SCALE, 0.0f},
{0.5f * PORTAL_OUTLINE_WORLD_SCALE, 0.0f, 0.0f},
{0.353553f * PORTAL_OUTLINE_WORLD_SCALE, 0.707107f * PORTAL_OUTLINE_WORLD_SCALE, 0.0f},
{0.0f, 1.0f * PORTAL_OUTLINE_WORLD_SCALE, 0.0f},
};
#define SHOW_EXTERNAL_VIEW 0

View file

@ -10,7 +10,7 @@
#define PORTAL_LOOP_SIZE 8
extern struct Vector3 gPortalOutlineUnscaled[PORTAL_LOOP_SIZE];
extern struct Vector3 gPortalOutlineWorld[PORTAL_LOOP_SIZE];
enum PortalFlags {
PortalFlagsOddParity = (1 << 0),

View file

@ -140,6 +140,8 @@ int portalSurfaceIsInside(struct PortalSurface* surface, struct Transform* porta
#define MAX_POS_ADJUST_ITERATIONS 3
#define PORTAL_EDGE_PADDING 3
int portalSurfaceAdjustPosition(struct PortalSurface* surface, struct Transform* portalAt, struct Vector2s16* output, struct Vector2s16* outlineLoopOutput) {
struct Vector2s16 minPortal;
struct Vector2s16 maxPortal;
@ -161,7 +163,7 @@ int portalSurfaceAdjustPosition(struct PortalSurface* surface, struct Transform*
for (int i = 0; i < PORTAL_LOOP_SIZE; ++i) {
struct Vector3 transformedPoint;
transformPoint(portalAt, &gPortalOutlineUnscaled[shouldReverse ? (PORTAL_LOOP_SIZE - 1) - i : i], &transformedPoint);
transformPoint(portalAt, &gPortalOutlineWorld[shouldReverse ? (PORTAL_LOOP_SIZE - 1) - i : i], &transformedPoint);
portalSurface2DPoint(surface, &transformedPoint, &outlineLoopOutput[i]);
minPortal.x = MIN(minPortal.x, outlineLoopOutput[i].x);
@ -173,8 +175,8 @@ int portalSurfaceAdjustPosition(struct PortalSurface* surface, struct Transform*
struct Vector2s16 halfSize;
halfSize.x = (maxPortal.x - minPortal.x) >> 1;
halfSize.y = (maxPortal.y - minPortal.y) >> 1;
halfSize.x = ((maxPortal.x - minPortal.x) >> 1) + PORTAL_EDGE_PADDING * 2;
halfSize.y = ((maxPortal.y - minPortal.y) >> 1) + PORTAL_EDGE_PADDING * 2;
int iteration = 0;

View file

@ -545,9 +545,14 @@ int portalSurfaceConnectToPoint(struct PortalSurfaceBuilder* surfaceBuilder, int
return 1;
}
struct Vector2s16* portalSurfaceIntersectEdgeWithLoop(struct PortalSurfaceBuilder* surfaceBuilder, struct Vector2s16* pointA, struct Vector2s16* pointDir) {
#define COLLAPSE_DISTANCE 8
struct Vector2s16* portalSurfaceIntersectEdgeWithLoop(struct PortalSurfaceBuilder* surfaceBuilder, struct Vector2s16* pointA, struct Vector2s16* pointB) {
struct SurfaceEdgeWithSide currentEdge = surfaceBuilder->edgeOnSearchLoop;
struct Vector2s16 pointDir;
vector2s16Sub(pointB, pointA, &pointDir);
int iteration;
for (iteration = 0;
@ -563,7 +568,7 @@ struct Vector2s16* portalSurfaceIntersectEdgeWithLoop(struct PortalSurfaceBuilde
struct Vector2s16 intersectionPoint;
enum IntersectionType intersectType = portalSurfaceIntersect(pointA, pointDir, edgeA, edgeB, &intersectionPoint);
enum IntersectionType intersectType = portalSurfaceIntersect(pointA, &pointDir, edgeA, edgeB, &intersectionPoint);
if (intersectionPoint.equalTest == pointA->equalTest) {
continue;
@ -572,6 +577,14 @@ struct Vector2s16* portalSurfaceIntersectEdgeWithLoop(struct PortalSurfaceBuilde
if (intersectType == IntersectionTypePoint) {
int newPointIndex;
if (vector2s16DistSqr(&intersectionPoint, pointA) <= COLLAPSE_DISTANCE * COLLAPSE_DISTANCE) {
intersectionPoint = *pointA;
}
if (vector2s16DistSqr(&intersectionPoint, pointB) <= COLLAPSE_DISTANCE * COLLAPSE_DISTANCE) {
intersectionPoint = *pointB;
}
if (intersectionPoint.equalTest == edgeA->equalTest) {
newPointIndex = SB_GET_CURRENT_POINT(edge, currentEdge.isReverse);
} else if (intersectionPoint.equalTest == edgeB->equalTest) {
@ -618,10 +631,7 @@ struct Vector2s16* portalSurfaceIntersectEdgeWithLoop(struct PortalSurfaceBuilde
}
}
struct Vector2s16 pointB;
vector2s16Add(pointA, pointDir, &pointB);
int newPointIndex = portalSurfaceNewVertex(surfaceBuilder, &pointB);
int newPointIndex = portalSurfaceNewVertex(surfaceBuilder, pointB);
portalSurfaceCalcVertex(surfaceBuilder, &surfaceBuilder->edgeOnSearchLoop, newPointIndex);
@ -935,14 +945,12 @@ int portalSurfacePokeHole(struct PortalSurface* surface, struct Vector2s16* loop
for (int index = 1; index <= PORTAL_LOOP_SIZE;) {
struct Vector2s16* next = &loop[index == PORTAL_LOOP_SIZE ? 0 : index];
struct Vector2s16 dir;
if (!portalSurfaceFindNextLoop(&surfaceBuilder, next)) {
goto error;
}
vector2s16Sub(next, prev, &dir);
struct Vector2s16* newPoint = portalSurfaceIntersectEdgeWithLoop(&surfaceBuilder, prev, &dir);
struct Vector2s16* newPoint = portalSurfaceIntersectEdgeWithLoop(&surfaceBuilder, prev, next);
if (!newPoint) {
goto error;