diff --git a/src/models/models.h b/src/models/models.h index 9e7b097..e4c2daf 100644 --- a/src/models/models.h +++ b/src/models/models.h @@ -2,6 +2,7 @@ #define __MODELS_H__ extern Gfx portal_mask_Circle_mesh[]; +extern Gfx portal_mask_Circle_mesh_tri_0[]; extern Gfx portal_outline_portal_outline_mesh[]; extern Gfx* cube_gfx; diff --git a/src/models/portal_mask.inc.h b/src/models/portal_mask.inc.h index 52af757..5fa89a1 100644 --- a/src/models/portal_mask.inc.h +++ b/src/models/portal_mask.inc.h @@ -42,20 +42,19 @@ Gfx portal_mask_Circle_mesh[] = { gsSPDisplayList(mat_portal_mask_portal_mask), gsSPDisplayList(portal_mask_Circle_mesh_tri_0), gsDPPipeSync(), - gsSPGeometryMode(G_CULL_BACK, G_CULL_FRONT), - gsDPSetPrimColor(0, 0, 0, 128, 255, 0), - gsSP1Triangle(0, 1, 2, 0), - gsSP1Triangle(0, 2, 3, 0), - gsSP1Triangle(2, 4, 3, 0), - gsSP1Triangle(3, 5, 0, 0), - gsSP1Triangle(3, 6, 5, 0), - gsSP1Triangle(5, 7, 0, 0), - gsDPPipeSync(), - gsSPGeometryMode(G_CULL_FRONT, G_CULL_BACK), + // gsSPGeometryMode(G_CULL_BACK, G_CULL_FRONT), + // gsDPSetPrimColor(0, 0, 0, 128, 255, 0), + // gsSP1Triangle(0, 1, 2, 0), + // gsSP1Triangle(0, 2, 3, 0), + // gsSP1Triangle(2, 4, 3, 0), + // gsSP1Triangle(3, 5, 0, 0), + // gsSP1Triangle(3, 6, 5, 0), + // gsSP1Triangle(5, 7, 0, 0), + // gsDPPipeSync(), + // gsSPGeometryMode(G_CULL_FRONT, G_CULL_BACK), gsSPSetGeometryMode(G_LIGHTING), gsSPClearGeometryMode(G_TEXTURE_GEN), gsDPSetCombineLERP(0, 0, 0, SHADE, 0, 0, 0, ENVIRONMENT, 0, 0, 0, SHADE, 0, 0, 0, ENVIRONMENT), gsSPTexture(65535, 65535, 0, 0, 0), gsSPEndDisplayList(), }; - diff --git a/src/models/portal_outline.inc.h b/src/models/portal_outline.inc.h index f3631b6..546726c 100644 --- a/src/models/portal_outline.inc.h +++ b/src/models/portal_outline.inc.h @@ -1,43 +1,43 @@ Vtx portal_outline_portal_outline_mesh_vtx_0[38] = { - {{{79, 152, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{85, 159, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{120, 0, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{0, 215, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{0, 204, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{72, 144, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{111, 0, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{85, -159, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{79, -152, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{0, -225, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{0, -215, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{-85, -159, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{-79, -152, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{-120, 0, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{-111, 0, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{-85, 159, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{-111, 0, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{-85, 159, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{-79, 152, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{0, 225, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{0, 215, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{85, 159, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{-72, 144, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{-102, 0, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{-72, -144, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{-79, -152, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{0, -204, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{0, -215, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{72, -144, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{79, -152, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{102, 0, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{111, 0, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{72, 144, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{111, 0, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{102, 0, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{-72, 144, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{0, 215, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, - {{{0, 204, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{79, 152, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{85, 159, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{120, 0, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{0, 215, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{0, 204, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{72, 144, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{111, 0, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{85, -159, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{79, -152, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{0, -225, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{0, -215, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{-85, -159, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{-79, -152, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{-120, 0, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{-111, 0, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{-85, 159, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{-111, 0, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{-85, 159, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{-79, 152, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{0, 225, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{0, 215, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{85, 159, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{-72, 144, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{-102, 0, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{-72, -144, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{-79, -152, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{0, -204, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{0, -215, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{72, -144, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{79, -152, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{102, 0, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{111, 0, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{72, 144, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{111, 0, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{102, 0, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{-72, 144, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{0, 215, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, + {{{0, 204, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}}, }; Gfx portal_outline_portal_outline_mesh_tri_0[] = { @@ -84,7 +84,7 @@ Gfx mat_portal_outline_portal_outline[] = { gsDPPipeSync(), gsSPSetGeometryMode(G_SHADE), gsSPClearGeometryMode(G_LIGHTING), - gsDPSetRenderMode(G_RM_XLU_SURF, G_RM_XLU_SURF2), + gsDPSetRenderMode(G_RM_ZB_OPA_SURF, G_RM_ZB_OPA_SURF2), gsDPSetCombineLERP(0, 0, 0, PRIMITIVE, 0, 0, 0, PRIMITIVE, 0, 0, 0, PRIMITIVE, 0, 0, 0, PRIMITIVE), gsSPTexture(65535, 65535, 0, 0, 1), gsSPEndDisplayList(), diff --git a/src/scene/portal.c b/src/scene/portal.c index 1ca184c..3964239 100644 --- a/src/scene/portal.c +++ b/src/scene/portal.c @@ -30,14 +30,35 @@ struct Vector3 gPortalOutlineUnscaled[PORTAL_LOOP_SIZE] = { {-0.353553f, 0.707107f, 0.0f}, }; +#define SHOW_EXTERNAL_VIEW 0 + +#if SHOW_EXTERNAL_VIEW + +struct Vector3 externalCameraPos = {16.0f, 8.0f, -16.0f}; +struct Vector3 externalLook = {4.0f, 2.0f, -4.0f}; + +#endif + struct Quaternion gVerticalFlip = {0.0f, 1.0f, 0.0f, 0.0f}; +#define STARTING_RENDER_DEPTH 2 + void renderPropsInit(struct RenderProps* props, struct Camera* camera, float aspectRatio, struct RenderState* renderState) { props->camera = *camera; props->aspectRatio = aspectRatio; props->perspectiveMatrix = cameraSetupMatrices(camera, renderState, aspectRatio, &props->perspectiveCorrect, &fullscreenViewport, &props->cullingInfo); props->viewport = &fullscreenViewport; props->currentDepth = STARTING_RENDER_DEPTH; + props->fromPortalIndex = NO_PORTAL; + +#if SHOW_EXTERNAL_VIEW + struct Camera externalCamera = *camera; + externalCamera.transform.position = externalCameraPos; + struct Vector3 offset; + vector3Sub(&externalLook, &externalCameraPos, &offset); + quatLook(&offset, &gUp, &externalCamera.transform.rotation); + props->perspectiveMatrix = cameraSetupMatrices(&externalCamera, renderState, aspectRatio, &props->perspectiveCorrect, &fullscreenViewport, NULL); +#endif props->minX = 0; props->minY = 0; @@ -94,6 +115,18 @@ void renderPropsNext(struct RenderProps* current, struct RenderProps* next, stru next->perspectiveMatrix = cameraSetupMatrices(&next->camera, renderState, next->aspectRatio, &next->perspectiveCorrect, viewport, &next->cullingInfo); +#if SHOW_EXTERNAL_VIEW + struct Transform externalTransform; + externalTransform.position = externalCameraPos; + externalTransform.scale = gOneVec; + struct Vector3 offset; + vector3Sub(&externalLook, &externalCameraPos, &offset); + quatLook(&offset, &gUp, &externalTransform.rotation); + struct Camera externalCamera = current->camera; + transformConcat(&portalCombined, &externalTransform, &externalCamera.transform); + next->perspectiveMatrix = cameraSetupMatrices(&externalCamera, renderState, (float)SCREEN_WD / (float)SCREEN_HT, &next->perspectiveCorrect, &fullscreenViewport, NULL); +#endif + // set the near clipping plane to be the exit portal surface quatMultVector(&toPortal->rotation, &gForward, &next->cullingInfo.clippingPlanes[4].normal); if (toPortal < fromPortal) { @@ -102,9 +135,12 @@ void renderPropsNext(struct RenderProps* current, struct RenderProps* next, stru next->cullingInfo.clippingPlanes[4].d = -vector3Dot(&next->cullingInfo.clippingPlanes[4].normal, &toPortal->position) * SCENE_SCALE; next->currentDepth = current->currentDepth - 1; + next->fromPortalIndex = toPortal < fromPortal ? 0 : 1; +#if !SHOW_EXTERNAL_VIEW gSPViewport(renderState->dl++, viewport); gDPSetScissor(renderState->dl++, G_SC_NON_INTERLACE, next->minX, next->minY, next->maxX, next->maxY); +#endif } void portalInit(struct Portal* portal, enum PortalFlags flags) { @@ -138,6 +174,7 @@ void portalRender(struct Portal* portal, struct Portal* otherPortal, struct Rend gDPSetPrimColor(renderState->dl++, 0, 0, 255, 128, 0, 255); } gSPDisplayList(renderState->dl++, portal_outline_portal_outline_mesh); + gSPDisplayList(renderState->dl++, portal_mask_Circle_mesh_tri_0); gSPPopMatrix(renderState->dl++, G_MTX_MODELVIEW); return; } @@ -148,18 +185,19 @@ void portalRender(struct Portal* portal, struct Portal* otherPortal, struct Rend screenClipperBoundingPoints(&clipper, gPortalOutline, sizeof(gPortalOutline) / sizeof(*gPortalOutline), &clippingBounds); - if (clippingBounds.min.x < clippingBounds.max.x && clippingBounds.min.y < clippingBounds.max.y) { - struct RenderProps nextProps; + struct RenderProps nextProps; - nextProps.minX = CALC_SCREEN_SPACE(clippingBounds.min.x, SCREEN_WD); - nextProps.maxX = CALC_SCREEN_SPACE(clippingBounds.max.x, SCREEN_WD); - nextProps.minY = CALC_SCREEN_SPACE(-clippingBounds.max.y, SCREEN_HT); - nextProps.maxY = CALC_SCREEN_SPACE(-clippingBounds.min.y, SCREEN_HT); + nextProps.minX = CALC_SCREEN_SPACE(clippingBounds.min.x, SCREEN_WD); + nextProps.maxX = CALC_SCREEN_SPACE(clippingBounds.max.x, SCREEN_WD); + nextProps.minY = CALC_SCREEN_SPACE(-clippingBounds.max.y, SCREEN_HT); + nextProps.maxY = CALC_SCREEN_SPACE(-clippingBounds.min.y, SCREEN_HT); - nextProps.minX = MAX(nextProps.minX, props->minX); - nextProps.maxX = MIN(nextProps.maxX, props->maxX); - nextProps.minY = MAX(nextProps.minY, props->minY); - nextProps.maxY = MIN(nextProps.maxY, props->maxY); + nextProps.minX = MAX(nextProps.minX, props->minX); + nextProps.maxX = MIN(nextProps.maxX, props->maxX); + nextProps.minY = MAX(nextProps.minY, props->minY); + nextProps.maxY = MIN(nextProps.maxY, props->maxY); + + if (nextProps.minX < nextProps.maxX && nextProps.minY < nextProps.maxY) { renderPropsNext(props, &nextProps, &portal->transform, &otherPortal->transform, renderState); sceneRenderer(data, &nextProps, renderState); diff --git a/src/scene/portal.h b/src/scene/portal.h index 9aa0ddb..119635e 100644 --- a/src/scene/portal.h +++ b/src/scene/portal.h @@ -25,6 +25,8 @@ struct RenderProps; typedef void SceneRenderCallback(void* data, struct RenderProps* properties, struct RenderState* renderState); +#define NO_PORTAL 0xFF + struct RenderProps { struct Camera camera; float aspectRatio; @@ -33,17 +35,15 @@ struct RenderProps { struct FrustrumCullingInformation cullingInfo; u16 perspectiveCorrect; - short currentDepth; + u8 currentDepth; + u8 fromPortalIndex; short minX; short minY; short maxX; short maxY; - }; -#define STARTING_RENDER_DEPTH 1 - void renderPropsInit(struct RenderProps* props, struct Camera* camera, float aspectRatio, struct RenderState* renderState); void renderPropsNext(struct RenderProps* current, struct RenderProps* next, struct Transform* fromPortal, struct Transform* toPortal, struct RenderState* renderState); diff --git a/src/scene/scene.c b/src/scene/scene.c index 44e7664..260f278 100644 --- a/src/scene/scene.c +++ b/src/scene/scene.c @@ -68,8 +68,12 @@ void sceneRenderWithProperties(void* data, struct RenderProps* properties, struc int closerPortal = vector3DistSqrd(&properties->camera.transform.position, &scene->portals[0].transform.position) > vector3DistSqrd(&properties->camera.transform.position, &scene->portals[1].transform.position) ? 0 : 1; - portalRender(&scene->portals[closerPortal], &scene->portals[1 - closerPortal], properties, sceneRenderWithProperties, data, renderState); - portalRender(&scene->portals[1 - closerPortal], &scene->portals[closerPortal], properties, sceneRenderWithProperties, data, renderState); + if (properties->fromPortalIndex != closerPortal) { + portalRender(&scene->portals[closerPortal], &scene->portals[1 - closerPortal], properties, sceneRenderWithProperties, data, renderState); + } + if (properties->fromPortalIndex != 1 - closerPortal) { + portalRender(&scene->portals[1 - closerPortal], &scene->portals[closerPortal], properties, sceneRenderWithProperties, data, renderState); + } gDPSetRenderMode(renderState->dl++, G_RM_ZB_OPA_SURF, G_RM_ZB_OPA_SURF2); @@ -115,7 +119,6 @@ void sceneRender(struct Scene* scene, struct RenderState* renderState, struct Gr renderPropsInit(&renderProperties, &scene->camera, (float)SCREEN_WD / (float)SCREEN_HT, renderState); renderProperties.camera = scene->camera; - renderProperties.currentDepth = STARTING_RENDER_DEPTH; gDPSetRenderMode(renderState->dl++, G_RM_ZB_OPA_SURF, G_RM_ZB_OPA_SURF2);