diff --git a/src/scene/portal.c b/src/scene/portal.c index 45fb662..37ebba5 100644 --- a/src/scene/portal.c +++ b/src/scene/portal.c @@ -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 diff --git a/src/scene/portal.h b/src/scene/portal.h index 51779a7..4a84162 100644 --- a/src/scene/portal.h +++ b/src/scene/portal.h @@ -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), diff --git a/src/scene/portal_surface.c b/src/scene/portal_surface.c index 3497427..3c83b3d 100644 --- a/src/scene/portal_surface.c +++ b/src/scene/portal_surface.c @@ -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; diff --git a/src/scene/portal_surface_generator.c b/src/scene/portal_surface_generator.c index 3cbb35a..6b64fc4 100644 --- a/src/scene/portal_surface_generator.c +++ b/src/scene/portal_surface_generator.c @@ -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;