Free Camera (#337)

* wip free cam

* Almost done, needs collision still

* Added free cam behind cvar

* added WIP collision

* Fixed & implemented "Manual mode" from WW & TP

* Fixed camera not rotating when Link is moving

* fixed initialized camera rotation

* Fixed camera getting stuck + made it smoother

* reduced deadzone

* fixed epona camera height + added WW z-target free camera

* Adjusted player camera height & fixed fov

* Fixed camera roll

* fixed fov when moving the camera while in z-target

* Camera resets to Auto when going through doors or changing maps

* Fixed building

* touch

* more touch work

* Added WIP mouse support to the free cam

* gui stuff

* fixed building

* fixed building error

* ok fixed building for real this time

* oops

* Fix compilation issues

* removed mouse stuff that magically appeared in this branch

* smoothed out stick values & removed remains of mouse support

* re-added manual camera when pressing Z

* reduced minimum Y position of camera

* Addressed dcsv's nitpicks

* part 2

* oops

Co-authored-by: David Chavez <david@dcvz.io>
This commit is contained in:
MelonSpeedruns 2022-07-12 18:40:18 -04:00 committed by GitHub
parent 3aa93b9855
commit 66ec623542
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 221 additions and 20 deletions

View file

@ -1409,7 +1409,125 @@ s32 Camera_Noop(Camera* camera) {
return true;
}
s32 SetCameraManual(Camera* camera) {
f32 newCamX = -D_8015BD7C->state.input[0].cur.cam_x;
f32 newCamY = D_8015BD7C->state.input[0].cur.cam_y;
if ((fabsf(newCamX) >= 15.0f || fabsf(newCamY) >= 15.0f) && camera->globalCtx->manualCamera == false) {
camera->globalCtx->manualCamera = true;
VecSph eyeAdjustment;
OLib_Vec3fDiffToVecSphGeo(&eyeAdjustment, &camera->at, &camera->eye);
camera->globalCtx->camX = eyeAdjustment.yaw;
camera->globalCtx->camY = eyeAdjustment.pitch;
}
if (camera->globalCtx->manualCamera) {
return 1;
}
return 0;
}
s32 Camera_Free(Camera* camera) {
Normal1* norm1 = (Normal1*)camera->paramData;
f32 playerHeight = Player_GetHeight(camera->player);
f32 sp94;
CamColChk camBgChk;
PosRot* playerPosRot = &camera->playerPosRot;
Vec3f at;
sCameraInterfaceFlags = norm1->interfaceFlags;
if (RELOAD_PARAMS) {
VecSph eyeAdjustment1;
OLib_Vec3fDiffToVecSphGeo(&eyeAdjustment1, &camera->at, &camera->eye);
camera->globalCtx->camX = eyeAdjustment1.yaw;
camera->globalCtx->camY = eyeAdjustment1.pitch;
CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values;
f32 yNormal = (1.0f + PCT(R_CAM_YOFFSET_NORM) - PCT(R_CAM_YOFFSET_NORM) * (68.0f / playerHeight));
sp94 = yNormal * PCT(playerHeight);
norm1->yOffset = NEXTSETTING * sp94;
norm1->distMin = NEXTSETTING * sp94;
norm1->distMax = NEXTSETTING * sp94;
norm1->pitchTarget = DEGF_TO_BINANG(NEXTSETTING);
norm1->unk_0C = NEXTSETTING;
norm1->unk_10 = NEXTSETTING;
norm1->unk_14 = NEXTPCT;
norm1->fovTarget = NEXTSETTING;
norm1->atLERPScaleMax = NEXTPCT;
norm1->interfaceFlags = NEXTSETTING;
}
if (R_RELOAD_CAM_PARAMS) {
Camera_CopyPREGToModeValues(camera);
}
VecSph eyeAdjustment;
const f32 camSpeed = 0.5f;
camera->animState = 0;
at.x = Camera_LERPCeilF(camera->player->actor.world.pos.x, camera->at.x, camSpeed, 1.0f);
at.y = Camera_LERPCeilF(camera->player->actor.world.pos.y + (camera->player->rideActor != NULL ? Player_GetHeight(camera->player) / 2 : Player_GetHeight(camera->player)) / 1.2f, camera->at.y, camSpeed, 1.0f);
at.z = Camera_LERPCeilF(camera->player->actor.world.pos.z, camera->at.z, camSpeed, 1.0f);
OLib_Vec3fDiffToVecSphGeo(&eyeAdjustment, &at, &camera->eye);
camBgChk.pos = camera->eye;
float maxRadius = 160.0f;
if (Camera_BGCheckInfo(camera, &at, &camBgChk)) {
VecSph collSphere;
OLib_Vec3fDiffToVecSphGeo(&collSphere, &at, &camBgChk.pos);
float rad = collSphere.r;
if (rad >= maxRadius) {
camera->dist = eyeAdjustment.r = Camera_LERPCeilF(maxRadius, camera->dist, camSpeed / 4, 1.0f);
} else {
camera->dist = eyeAdjustment.r = rad;
}
} else {
camera->dist = eyeAdjustment.r = Camera_LERPCeilF(maxRadius, camera->dist, camSpeed / 4, 1.0f);
}
f32 newCamX = -D_8015BD7C->state.input[0].cur.cam_x;
f32 newCamY = D_8015BD7C->state.input[0].cur.cam_y;
camera->globalCtx->camX += newCamX;
camera->globalCtx->camY += newCamY;
if (camera->globalCtx->camY > 0x32A4) {
camera->globalCtx->camY = 0x32A4;
}
if (camera->globalCtx->camY < -0x228C) {
camera->globalCtx->camY = -0x228C;
}
eyeAdjustment.yaw = camera->globalCtx->camX;
eyeAdjustment.pitch = camera->globalCtx->camY;
Camera_Vec3fVecSphGeoAdd(&camera->eye, &at, &eyeAdjustment);
camera->at = at;
camera->fov = Camera_LERPCeilF(60.0f, camera->fov, camSpeed / 2, 1.0f);
camera->roll = 0;
camera->eyeNext = camera->eye;
return 1;
}
s32 Camera_Normal1(Camera* camera) {
if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) {
Camera_Free(camera);
return 1;
}
Vec3f* eye = &camera->eye;
Vec3f* at = &camera->at;
Vec3f* eyeNext = &camera->eyeNext;
@ -1637,6 +1755,11 @@ s32 Camera_Normal1(Camera* camera) {
}
s32 Camera_Normal2(Camera* camera) {
if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) {
Camera_Free(camera);
return 1;
}
Vec3f* eye = &camera->eye;
Vec3f* at = &camera->at;
Vec3f* eyeNext = &camera->eyeNext;
@ -1803,6 +1926,11 @@ s32 Camera_Normal2(Camera* camera) {
// riding epona
s32 Camera_Normal3(Camera* camera) {
if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) {
Camera_Free(camera);
return 1;
}
Vec3f* eye = &camera->eye;
Vec3f* at = &camera->at;
Vec3f* eyeNext = &camera->eyeNext;
@ -1997,6 +2125,8 @@ s32 Camera_Parallel1(Camera* camera) {
OLib_Vec3fDiffToVecSphGeo(&atToEyeDir, at, eye);
OLib_Vec3fDiffToVecSphGeo(&atToEyeNextDir, at, eyeNext);
camera->globalCtx->manualCamera = false;
switch (camera->animState) {
case 0:
case 0xA:
@ -2162,6 +2292,11 @@ s32 Camera_Parallel0(Camera* camera) {
* Generic jump, jumping off ledges
*/
s32 Camera_Jump1(Camera* camera) {
if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) {
Camera_Free(camera);
return 1;
}
Vec3f* eye = &camera->eye;
Vec3f* at = &camera->at;
Vec3f* eyeNext = &camera->eyeNext;
@ -2307,6 +2442,11 @@ s32 Camera_Jump1(Camera* camera) {
// Climbing ladders/vines
s32 Camera_Jump2(Camera* camera) {
if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) {
Camera_Free(camera);
return 1;
}
Vec3f* eye = &camera->eye;
Vec3f* at = &camera->at;
Vec3f* eyeNext = &camera->eyeNext;
@ -2489,6 +2629,11 @@ s32 Camera_Jump2(Camera* camera) {
// swimming
s32 Camera_Jump3(Camera* camera) {
if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) {
Camera_Free(camera);
return 1;
}
Vec3f* eye = &camera->eye;
Vec3f* at = &camera->at;
Vec3f* eyeNext = &camera->eyeNext;
@ -2946,6 +3091,11 @@ s32 Camera_Battle3(Camera* camera) {
* setting value.
*/
s32 Camera_Battle4(Camera* camera) {
if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) {
Camera_Free(camera);
return 1;
}
Vec3f* eye = &camera->eye;
Vec3f* at = &camera->at;
Vec3f* eyeNext = &camera->eyeNext;
@ -4476,6 +4626,11 @@ s32 Camera_Data4(Camera* camera) {
* Hanging off of a ledge
*/
s32 Camera_Unique1(Camera* camera) {
if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) {
Camera_Free(camera);
return 1;
}
Vec3f* eye = &camera->eye;
Vec3f* at = &camera->at;
Vec3f* eyeNext = &camera->eyeNext;