Prevent player from looking too far up or down

This commit is contained in:
James Lambert 2022-05-09 17:59:58 -06:00
parent ea0f4ce45c
commit 9d8ee1a693
3 changed files with 52 additions and 19 deletions

View file

@ -85,7 +85,7 @@ Gfx mat_portal_outline_portal_outline[] = {
gsSPSetGeometryMode(G_SHADE),
gsSPClearGeometryMode(G_LIGHTING),
gsDPSetRenderMode(G_RM_XLU_SURF, G_RM_XLU_SURF2),
gsDPSetCombineLERP(0, 0, 0, PRIMITIVE, 0, 0, 0, SHADE, 0, 0, 0, PRIMITIVE, 0, 0, 0, SHADE),
gsDPSetCombineLERP(0, 0, 0, PRIMITIVE, 0, 0, 0, PRIMITIVE, 0, 0, 0, PRIMITIVE, 0, 0, 0, PRIMITIVE),
gsSPTexture(65535, 65535, 0, 0, 1),
gsSPEndDisplayList(),
};

View file

@ -143,6 +143,13 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) {
quatMultVector(&transform->rotation, &gForward, &forward);
quatMultVector(&transform->rotation, &gRight, &right);
if (forward.y > 0.7f) {
quatMultVector(&transform->rotation, &gUp, &forward);
vector3Negate(&forward, &forward);
} else if (forward.y < -0.7f) {
quatMultVector(&transform->rotation, &gUp, &forward);
}
forward.y = 0.0f;
right.y = 0.0f;
@ -220,24 +227,44 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) {
struct Vector3 lookingForward;
vector3Negate(&gForward, &lookingForward);
quatMultVector(&player->body.transform.rotation, &lookingForward, &lookingForward);
// if player is looking close to directly up or down, don't correct the rotation
if (fabsf(lookingForward.y) < 0.99f) {
struct Quaternion upRotation;
quatLook(&lookingForward, &gUp, &upRotation);
quatLerp(&upRotation, &player->body.transform.rotation, 0.9f, &player->body.transform.rotation);
}
// yaw
struct Quaternion deltaRotate;
quatAxisAngle(&gUp, player->yawVelocity * FIXED_DELTA_TIME, &deltaRotate);
struct Quaternion tempRotation;
quatMultiply(&deltaRotate, &player->body.transform.rotation, &tempRotation);
// pitch
quatAxisAngle(&gRight, player->pitchVelocity * FIXED_DELTA_TIME, &deltaRotate);
quatMultiply(&tempRotation, &deltaRotate, &player->body.transform.rotation);
// prevent player from looking too far up or down
vector3Negate(&gForward, &lookingForward);
quatMultVector(&tempRotation, &lookingForward, &lookingForward);
struct Vector3 newLookingForward;
vector3Negate(&gForward, &newLookingForward);
quatMultVector(&player->body.transform.rotation, &newLookingForward, &newLookingForward);
float pitchSign = signf(player->pitchVelocity);
if (lookingForward.y * pitchSign > newLookingForward.y * pitchSign) {
struct Vector3 newForward = gZeroVec;
newForward.y = pitchSign;
struct Vector3 newUp;
quatMultVector(&tempRotation, &gUp, &newUp);
quatLook(&newForward, &newUp, &player->body.transform.rotation);
player->pitchVelocity = 0.0f;
}
cameraTransform->rotation = player->body.transform.rotation;
transformPoint(transform, &gCameraOffset, &cameraTransform->position);
playerUpdateGrabbedObject(player);
}

View file

@ -71,17 +71,6 @@ void portalInit(struct Portal* portal, enum PortalFlags flags) {
}
void portalRender(struct Portal* portal, struct Portal* otherPortal, struct RenderProps* props, SceneRenderCallback sceneRenderer, void* data, struct RenderState* renderState) {
if (props->currentDepth == 0) {
Mtx* matrix = renderStateRequestMatrices(renderState, 1);
transformToMatrixL(&portal->transform, matrix, SCENE_SCALE);
gSPMatrix(renderState->dl++, matrix, G_MTX_MODELVIEW | G_MTX_PUSH | G_MTX_MUL);
gDPSetPrimColor(renderState->dl++, 0, 0, 255, 128, 0, 255);
gSPDisplayList(renderState->dl++, portal_outline_portal_outline_mesh);
gSPPopMatrix(renderState->dl++, G_MTX_MODELVIEW);
return;
}
struct ScreenClipper clipper;
float portalTransform[4][4];
@ -95,6 +84,22 @@ void portalRender(struct Portal* portal, struct Portal* otherPortal, struct Rend
transformToMatrix(&finalTransform, portalTransform, SCENE_SCALE);
if (props->currentDepth == 0) {
Mtx* matrix = renderStateRequestMatrices(renderState, 1);
guMtxF2L(portalTransform, matrix);
gSPMatrix(renderState->dl++, matrix, G_MTX_MODELVIEW | G_MTX_PUSH | G_MTX_MUL);
gDPPipeSync(renderState->dl++);
if (portal->flags & PortalFlagsOddParity) {
gDPSetPrimColor(renderState->dl++, 0, 0, 0, 128, 255, 255);
} else {
gDPSetPrimColor(renderState->dl++, 0, 0, 255, 128, 0, 255);
}
gSPDisplayList(renderState->dl++, portal_outline_portal_outline_mesh);
gSPPopMatrix(renderState->dl++, G_MTX_MODELVIEW);
return;
}
screenClipperInitWithCamera(&clipper, &props->camera, (float)SCREEN_WD / (float)SCREEN_HT, portalTransform);
struct Box2D clippingBounds;
@ -121,6 +126,7 @@ void portalRender(struct Portal* portal, struct Portal* otherPortal, struct Rend
guMtxF2L(portalTransform, matrix);
gSPMatrix(renderState->dl++, matrix, G_MTX_MODELVIEW | G_MTX_PUSH | G_MTX_MUL);
gSPDisplayList(renderState->dl++, portal_mask_Circle_mesh);
gDPPipeSync(renderState->dl++);
if (portal->flags & PortalFlagsOddParity) {
gDPSetPrimColor(renderState->dl++, 0, 0, 0, 128, 255, 255);
} else {