Smooth out camera real good
This commit is contained in:
parent
0cedae66a9
commit
4754b33dfe
4 changed files with 72 additions and 37 deletions
93
renderer.h
93
renderer.h
|
@ -1163,6 +1163,30 @@ void _LCR_rendererLoadMapChunk(uint8_t chunk, int8_t x, int8_t y, int8_t z)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Serves for smoothing out angle change, e.g. that of camera rotation.
|
||||
*/
|
||||
S3L_Unit _LCR_smoothRotation(S3L_Unit angleOld, S3L_Unit angleNew)
|
||||
{
|
||||
S3L_Unit angleDiff = angleNew - angleOld;
|
||||
|
||||
if (angleDiff == 0)
|
||||
return angleNew;
|
||||
|
||||
S3L_Unit angleDiffAbs = S3L_abs(angleDiff);
|
||||
|
||||
if (angleDiffAbs > S3L_F / 2) // consider e.g. 350 degrees minus 1 degree
|
||||
{
|
||||
angleDiffAbs -= S3L_F / 2;
|
||||
angleDiff += (angleDiff > 0) ? -1 * (S3L_F / 2) : (S3L_F / 2);
|
||||
}
|
||||
|
||||
if (angleDiffAbs > S3L_F / 4) // angle too big, rotate immediately
|
||||
return angleNew;
|
||||
|
||||
return angleOld + angleDiff / 4; // smoothly interpolate
|
||||
}
|
||||
|
||||
/**
|
||||
Loads the map models with 8 chunks that are nearest to a certain point
|
||||
towards which camera is looking.
|
||||
|
@ -1337,36 +1361,45 @@ void LCR_rendererCameraFollow(void)
|
|||
(LCR_SETTING_CAMERA_HEIGHT + LCR_SETTING_CAMERA_HEIGHT_BAND) *
|
||||
LCR_RENDERER_UNIT / 8);
|
||||
|
||||
LCR_renderer.scene.camera.transform.translation.x =
|
||||
S3L_clamp(
|
||||
LCR_renderer.scene.camera.transform.translation.x,
|
||||
LCR_renderer.carModel->transform.translation.x -
|
||||
LCR_SETTING_CAMERA_MAX_DISTANCE * LCR_RENDERER_UNIT / 4,
|
||||
LCR_renderer.carModel->transform.translation.x +
|
||||
LCR_SETTING_CAMERA_MAX_DISTANCE * LCR_RENDERER_UNIT / 4);
|
||||
S3L_Vec4 toCam =
|
||||
LCR_renderer.scene.camera.transform.translation;
|
||||
|
||||
LCR_renderer.scene.camera.transform.translation.z =
|
||||
S3L_clamp(
|
||||
LCR_renderer.scene.camera.transform.translation.z,
|
||||
LCR_renderer.carModel->transform.translation.z -
|
||||
LCR_SETTING_CAMERA_MAX_DISTANCE * LCR_RENDERER_UNIT / 4,
|
||||
LCR_renderer.carModel->transform.translation.z +
|
||||
LCR_SETTING_CAMERA_MAX_DISTANCE * LCR_RENDERER_UNIT / 4);
|
||||
S3L_vec3Sub(&toCam,
|
||||
LCR_renderer.carModel->transform.translation);
|
||||
|
||||
/* Hotfix for a Gimbal lock kinda issue, don't do lookAt when completely
|
||||
above the car, rather shift the camera a bit (needs some tuning). */
|
||||
if (S3L_abs(LCR_renderer.scene.camera.transform.translation.x -
|
||||
LCR_renderer.carModel->transform.translation.x) > 8 &&
|
||||
S3L_abs(LCR_renderer.scene.camera.transform.translation.z -
|
||||
LCR_renderer.carModel->transform.translation.z) > 8)
|
||||
S3L_lookAt(LCR_renderer.carModel->transform.translation,
|
||||
&(LCR_renderer.scene.camera.transform));
|
||||
else
|
||||
S3L_Unit horizontalDist =
|
||||
S3L_sqrt(toCam.x * toCam.x + toCam.z * toCam.z);
|
||||
|
||||
if (horizontalDist == 0)
|
||||
{
|
||||
LCR_renderer.scene.camera.transform.translation.x += 4;
|
||||
LCR_renderer.scene.camera.transform.translation.z -= 8;
|
||||
toCam.z = 1;
|
||||
horizontalDist = 1;
|
||||
}
|
||||
|
||||
S3L_Unit horizontalDistNew =
|
||||
S3L_clamp(horizontalDist,
|
||||
(LCR_SETTING_CAMERA_DISTANCE - LCR_SETTING_CAMERA_DISTANCE_BAND)
|
||||
* (LCR_RENDERER_UNIT / 4),
|
||||
(LCR_SETTING_CAMERA_DISTANCE + LCR_SETTING_CAMERA_DISTANCE_BAND)
|
||||
* (LCR_RENDERER_UNIT / 4));
|
||||
|
||||
if (horizontalDistNew != horizontalDist)
|
||||
{
|
||||
toCam.x = (toCam.x * horizontalDistNew) / horizontalDist;
|
||||
toCam.z = (toCam.z * horizontalDistNew) / horizontalDist;
|
||||
|
||||
LCR_renderer.scene.camera.transform.translation.x =
|
||||
LCR_renderer.carModel->transform.translation.x +
|
||||
(toCam.x * horizontalDistNew) / horizontalDist;
|
||||
|
||||
LCR_renderer.scene.camera.transform.translation.z =
|
||||
LCR_renderer.carModel->transform.translation.z +
|
||||
(toCam.z * horizontalDistNew) / horizontalDist;
|
||||
}
|
||||
|
||||
S3L_lookAt(LCR_renderer.carModel->transform.translation,
|
||||
&(LCR_renderer.scene.camera.transform));
|
||||
|
||||
#if LCR_SETTING_SMOOTH_ANIMATIONS
|
||||
// now average with previous transform to smooth the animation out:
|
||||
S3L_vec3Add(&(LCR_renderer.scene.camera.transform.translation),
|
||||
|
@ -1376,13 +1409,11 @@ void LCR_rendererCameraFollow(void)
|
|||
LCR_renderer.scene.camera.transform.translation.y /= 2;
|
||||
LCR_renderer.scene.camera.transform.translation.z /= 2;
|
||||
|
||||
transPrev.rotation.x -= LCR_renderer.scene.camera.transform.rotation.x;
|
||||
transPrev.rotation.y -= LCR_renderer.scene.camera.transform.rotation.y;
|
||||
LCR_renderer.scene.camera.transform.rotation.x = _LCR_smoothRotation(
|
||||
transPrev.rotation.x,LCR_renderer.scene.camera.transform.rotation.x);
|
||||
|
||||
if (S3L_abs(transPrev.rotation.y) < S3L_F / 5)
|
||||
LCR_renderer.scene.camera.transform.rotation.y += transPrev.rotation.y / 2;
|
||||
|
||||
LCR_renderer.scene.camera.transform.rotation.x += transPrev.rotation.x / 2;
|
||||
LCR_renderer.scene.camera.transform.rotation.y = _LCR_smoothRotation(
|
||||
transPrev.rotation.y,LCR_renderer.scene.camera.transform.rotation.y);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue