Add follow camera
This commit is contained in:
parent
46c8a4eade
commit
e3d0b3219f
4 changed files with 164 additions and 27 deletions
22
game.h
22
game.h
|
@ -2,6 +2,28 @@
|
||||||
game: this file implements the backend of a complete, actually playable
|
game: this file implements the backend of a complete, actually playable
|
||||||
game, and is meant to be included and used by specific frontends (which
|
game, and is meant to be included and used by specific frontends (which
|
||||||
will handle each platform's hardware details and I/O).
|
will handle each platform's hardware details and I/O).
|
||||||
|
|
||||||
|
TODO: more documentation
|
||||||
|
|
||||||
|
UNITS: There are various kinds of units used to ensure independence of the
|
||||||
|
game modules. Here is a summary:
|
||||||
|
|
||||||
|
- LCR_GameUnit: data type, abstract unit of the game (racing module). One map
|
||||||
|
square is LCR_GAME_UNITs long, a full angle is also LCR_GAME_UNITs.
|
||||||
|
- LCR_GAME_UNIT: Size of one game square and full angle in LCR_GameUnits.
|
||||||
|
- S3L_Unit: data type, small3dlib's unit. May change with renderer change.
|
||||||
|
- S3L_FRACTIONS_PER_UNIT: small3dlib's value representing 1.0.
|
||||||
|
- LCR_RENDERER_UNIT: for the renderer one map square is this many S3L_Units.
|
||||||
|
- TPE_Unit: tinyphysicsengine's unit. May change with phys. engine change.
|
||||||
|
- TPE_FRACTIONS_PER_UNIT: tinyphysicsengine's value representing value 1.0.
|
||||||
|
- LCR_PHYSICS_UNIT: for the phys. eng. one map square is this many TPE_Units.
|
||||||
|
|
||||||
|
COORDINATE SYSTEM AND ROTATIONS: The game itself (racing module) is
|
||||||
|
independent of rendering and physics libraries, but out of convenient adopts
|
||||||
|
their coordinate system (X right, Y up, Z forward) and rotations (Euler
|
||||||
|
angles, by Z, then by X, then Y).
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LCR_GAME_H
|
#ifndef _LCR_GAME_H
|
||||||
|
|
42
racing.h
42
racing.h
|
@ -5,29 +5,29 @@
|
||||||
#ifndef _LCR_RACING_H
|
#ifndef _LCR_RACING_H
|
||||||
#define _LCR_RACING_H
|
#define _LCR_RACING_H
|
||||||
|
|
||||||
typedef int32_t LCR_GameUnit; ///< game spatial units
|
typedef int32_t LCR_GameUnit; ///< abstract game unit
|
||||||
|
|
||||||
#define LCR_GAME_UNIT 1024 ///< length of map square in game units
|
#define LCR_GAME_UNIT 1024 ///< length of map square in LCR_GameUnits
|
||||||
|
|
||||||
#define LCR_RACING_INPUT_FORW 0x01
|
#define LCR_RACING_INPUT_FORW 0x01
|
||||||
#define LCR_RACING_INPUT_RIGHT 0x02
|
#define LCR_RACING_INPUT_RIGHT 0x02
|
||||||
#define LCR_RACING_INPUT_BACK 0x04
|
#define LCR_RACING_INPUT_BACK 0x04
|
||||||
#define LCR_RACING_INPUT_LEFT 0x08
|
#define LCR_RACING_INPUT_LEFT 0x08
|
||||||
|
|
||||||
#define LCR_PHYSICS_UNIT 512 ///< length of map square for physics engine
|
#define LCR_PHYSICS_UNIT 1024 ///< length of map square for physics engine
|
||||||
|
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "tinyphysicsengine.h"
|
#include "tinyphysicsengine.h"
|
||||||
|
|
||||||
#define LCR_CAR_JOINTS 5
|
#define LCR_CAR_JOINTS 5
|
||||||
#define LCR_CAR_CONNECTIONS 8
|
#define LCR_CAR_CONNECTIONS 10
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
TPE_World physicsWorld;
|
TPE_World physicsWorld;
|
||||||
TPE_Body carBody;
|
TPE_Body carBody;
|
||||||
TPE_Joint carJoints[5];
|
TPE_Joint carJoints[LCR_CAR_JOINTS];
|
||||||
TPE_Connection carConnections[8];
|
TPE_Connection carConnections[LCR_CAR_CONNECTIONS];
|
||||||
} LCR_racing;
|
} LCR_racing;
|
||||||
|
|
||||||
TPE_Vec3 LCR_racingEnvironmentFunction(TPE_Vec3 point, TPE_Unit maxDist)
|
TPE_Vec3 LCR_racingEnvironmentFunction(TPE_Vec3 point, TPE_Unit maxDist)
|
||||||
|
@ -43,13 +43,13 @@ void LCR_racingInit(void)
|
||||||
LCR_log("initializing racing engine");
|
LCR_log("initializing racing engine");
|
||||||
|
|
||||||
// make the car body:
|
// make the car body:
|
||||||
TPE_makeCenterRect(LCR_racing.carJoints,
|
TPE_makeCenterRectFull(LCR_racing.carJoints,
|
||||||
LCR_racing.carConnections,
|
LCR_racing.carConnections,
|
||||||
LCR_GAME_UNIT / 3,
|
LCR_PHYSICS_UNIT / 2,
|
||||||
(LCR_GAME_UNIT) / 2,
|
(LCR_PHYSICS_UNIT * 3) / 4,
|
||||||
LCR_GAME_UNIT / 8);
|
LCR_PHYSICS_UNIT / 8);
|
||||||
|
|
||||||
LCR_racing.carJoints[4].position.y += LCR_PHYSICS_UNIT / 3;
|
LCR_racing.carJoints[4].position.y += LCR_PHYSICS_UNIT / 8;
|
||||||
LCR_racing.carJoints[4].sizeDivided *= 3;
|
LCR_racing.carJoints[4].sizeDivided *= 3;
|
||||||
LCR_racing.carJoints[4].sizeDivided /= 2;
|
LCR_racing.carJoints[4].sizeDivided /= 2;
|
||||||
|
|
||||||
|
@ -60,6 +60,8 @@ void LCR_racingInit(void)
|
||||||
|
|
||||||
TPE_worldInit(&(LCR_racing.physicsWorld),
|
TPE_worldInit(&(LCR_racing.physicsWorld),
|
||||||
&(LCR_racing.carBody),1,LCR_racingEnvironmentFunction);
|
&(LCR_racing.carBody),1,LCR_racingEnvironmentFunction);
|
||||||
|
|
||||||
|
TPE_bodyDeactivate(&(LCR_racing.carBody));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LCR_racingGetCarTransform(LCR_GameUnit position[3],
|
void LCR_racingGetCarTransform(LCR_GameUnit position[3],
|
||||||
|
@ -77,6 +79,12 @@ void LCR_racingGetCarTransform(LCR_GameUnit position[3],
|
||||||
position[1] = AVERAGE(y);
|
position[1] = AVERAGE(y);
|
||||||
position[2] = AVERAGE(z);
|
position[2] = AVERAGE(z);
|
||||||
#undef AVERAGE
|
#undef AVERAGE
|
||||||
|
|
||||||
|
TPE_Vec3 rot = TPE_bodyGetRotation(&(LCR_racing.carBody),0,2,1);
|
||||||
|
|
||||||
|
rotation[0] = (rot.x * LCR_GAME_UNIT) / TPE_FRACTIONS_PER_UNIT;
|
||||||
|
rotation[1] = (rot.y * LCR_GAME_UNIT) / TPE_FRACTIONS_PER_UNIT;
|
||||||
|
rotation[2] = (rot.z * LCR_GAME_UNIT) / TPE_FRACTIONS_PER_UNIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _LCR_drawPhysicsDebugPixel(uint16_t x, uint16_t y, uint8_t color)
|
void _LCR_drawPhysicsDebugPixel(uint16_t x, uint16_t y, uint8_t color)
|
||||||
|
@ -100,20 +108,24 @@ void LCR_racingStep(unsigned int input)
|
||||||
if (input)
|
if (input)
|
||||||
{
|
{
|
||||||
if (input & LCR_RACING_INPUT_FORW)
|
if (input & LCR_RACING_INPUT_FORW)
|
||||||
vel.z = LCR_GAME_UNIT / 32;
|
vel.z = LCR_PHYSICS_UNIT / 32;
|
||||||
|
|
||||||
if (input & LCR_RACING_INPUT_BACK)
|
if (input & LCR_RACING_INPUT_BACK)
|
||||||
vel.y = LCR_GAME_UNIT / 32;
|
vel.y = LCR_PHYSICS_UNIT / 32;
|
||||||
|
|
||||||
if (input & LCR_RACING_INPUT_RIGHT)
|
if (input & LCR_RACING_INPUT_RIGHT)
|
||||||
vel.x = LCR_GAME_UNIT / 32;
|
vel.x = LCR_PHYSICS_UNIT / 32;
|
||||||
|
|
||||||
if (input & LCR_RACING_INPUT_LEFT)
|
if (input & LCR_RACING_INPUT_LEFT)
|
||||||
vel.x = -1 * LCR_GAME_UNIT / 32;
|
vel.x = -1 * LCR_PHYSICS_UNIT / 32;
|
||||||
|
|
||||||
TPE_bodyAccelerate(&(LCR_racing.carBody),vel);
|
TPE_bodyAccelerate(&(LCR_racing.carBody),vel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TPE_bodyApplyGravity(&(LCR_racing.carBody),
|
||||||
|
TPE_FRACTIONS_PER_UNIT / 32
|
||||||
|
);
|
||||||
|
|
||||||
TPE_worldStep(&(LCR_racing.physicsWorld));
|
TPE_worldStep(&(LCR_racing.physicsWorld));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
105
renderer.h
105
renderer.h
|
@ -31,6 +31,8 @@
|
||||||
|
|
||||||
#define LCR_RENDERER_MODEL_COUNT 9
|
#define LCR_RENDERER_MODEL_COUNT 9
|
||||||
|
|
||||||
|
#define LCR_RENDERER_CAR_SCALE (LCR_RENDERER_UNIT / 4)
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
S3L_Scene scene;
|
S3L_Scene scene;
|
||||||
|
@ -91,6 +93,13 @@ void LCR_rendererSetCarTransform(LCR_GameUnit position[3],
|
||||||
(position[1] * LCR_RENDERER_UNIT) / LCR_GAME_UNIT;
|
(position[1] * LCR_RENDERER_UNIT) / LCR_GAME_UNIT;
|
||||||
LCR_renderer.carModel->transform.translation.z =
|
LCR_renderer.carModel->transform.translation.z =
|
||||||
(position[2] * LCR_RENDERER_UNIT) / LCR_GAME_UNIT;
|
(position[2] * LCR_RENDERER_UNIT) / LCR_GAME_UNIT;
|
||||||
|
|
||||||
|
LCR_renderer.carModel->transform.rotation.x = S3L_wrap((rotation[0] *
|
||||||
|
S3L_FRACTIONS_PER_UNIT) / LCR_GAME_UNIT,S3L_FRACTIONS_PER_UNIT);
|
||||||
|
LCR_renderer.carModel->transform.rotation.y = S3L_wrap((rotation[1] *
|
||||||
|
S3L_FRACTIONS_PER_UNIT) / LCR_GAME_UNIT,S3L_FRACTIONS_PER_UNIT);
|
||||||
|
LCR_renderer.carModel->transform.rotation.z = S3L_wrap((rotation[2] *
|
||||||
|
S3L_FRACTIONS_PER_UNIT) / LCR_GAME_UNIT,S3L_FRACTIONS_PER_UNIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _LCR_pixelFuncc3D(S3L_PixelInfo *pixel)
|
void _LCR_pixelFuncc3D(S3L_PixelInfo *pixel)
|
||||||
|
@ -790,15 +799,9 @@ uint8_t LCR_rendererInit(void)
|
||||||
LCR_renderer.wheelTurn = 0;
|
LCR_renderer.wheelTurn = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LCR_renderer.carModel->transform.translation.x -= 2 * LCR_RENDERER_UNIT;
|
LCR_renderer.carModel->transform.scale.x = LCR_RENDERER_CAR_SCALE;
|
||||||
LCR_renderer.carModel->transform.scale.x = LCR_RENDERER_UNIT / 3;
|
LCR_renderer.carModel->transform.scale.y = LCR_RENDERER_CAR_SCALE;
|
||||||
|
LCR_renderer.carModel->transform.scale.z = LCR_RENDERER_CAR_SCALE;
|
||||||
LCR_renderer.carModel->transform.scale.y =
|
|
||||||
LCR_renderer.carModel->transform.scale.x;
|
|
||||||
|
|
||||||
LCR_renderer.carModel->transform.scale.z =
|
|
||||||
LCR_renderer.carModel->transform.scale.x;
|
|
||||||
|
|
||||||
|
|
||||||
S3L_sceneInit(
|
S3L_sceneInit(
|
||||||
LCR_renderer.models,LCR_RENDERER_MODEL_COUNT,&LCR_renderer.scene);
|
LCR_renderer.models,LCR_RENDERER_MODEL_COUNT,&LCR_renderer.scene);
|
||||||
|
@ -1291,6 +1294,88 @@ void _LCR_rendererAnimateCar(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void LCR_rendererCameraFollow(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
LCR_renderer.scene.camera.transform.translation.y =
|
||||||
|
LCR_renderer.carModel->transform.translation.y + LCR_RENDERER_UNIT;
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
TPE_Vec3 cPos = TPE_vec3KeepWithinDistanceBand(
|
||||||
|
TPE_vec3(
|
||||||
|
s3l_scene.camera.transform.translation.x,
|
||||||
|
s3l_scene.camera.transform.translation.y,
|
||||||
|
s3l_scene.camera.transform.translation.z
|
||||||
|
),carBody->joints[4].position,4 * TPE_F,6 * TPE_F);
|
||||||
|
|
||||||
|
s3l_scene.camera.transform.translation.x = cPos.x;
|
||||||
|
s3l_scene.camera.transform.translation.y = cPos.y;
|
||||||
|
s3l_scene.camera.transform.translation.z = cPos.z;
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
S3L_Unit tmp =
|
||||||
|
LCR_renderer.scene.camera.transform.translation.y -
|
||||||
|
LCR_renderer.carModel->transform.translation.y;
|
||||||
|
|
||||||
|
tmp -= S3L_clamp(tmp,
|
||||||
|
(LCR_SETTING_CAMERA_HEIGHT -
|
||||||
|
LCR_SETTING_CAMERA_HEIGHT_BAND) * LCR_GAME_UNIT / 8,
|
||||||
|
(LCR_SETTING_CAMERA_HEIGHT +
|
||||||
|
LCR_SETTING_CAMERA_HEIGHT_BAND) * LCR_GAME_UNIT / 8);
|
||||||
|
|
||||||
|
LCR_renderer.scene.camera.transform.translation.y -= tmp;
|
||||||
|
*/
|
||||||
|
|
||||||
|
LCR_renderer.scene.camera.transform.translation.y =
|
||||||
|
S3L_clamp(
|
||||||
|
LCR_renderer.scene.camera.transform.translation.y,
|
||||||
|
LCR_renderer.carModel->transform.translation.y +
|
||||||
|
(LCR_SETTING_CAMERA_HEIGHT - LCR_SETTING_CAMERA_HEIGHT_BAND) *
|
||||||
|
LCR_GAME_UNIT / 8,
|
||||||
|
LCR_renderer.carModel->transform.translation.y +
|
||||||
|
(LCR_SETTING_CAMERA_HEIGHT + LCR_SETTING_CAMERA_HEIGHT_BAND) *
|
||||||
|
LCR_GAME_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_GAME_UNIT / 4,
|
||||||
|
LCR_renderer.carModel->transform.translation.x +
|
||||||
|
LCR_SETTING_CAMERA_MAX_DISTANCE * LCR_GAME_UNIT / 4);
|
||||||
|
|
||||||
|
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_GAME_UNIT / 4,
|
||||||
|
LCR_renderer.carModel->transform.translation.z +
|
||||||
|
LCR_SETTING_CAMERA_MAX_DISTANCE * LCR_GAME_UNIT / 4);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
S3L_lookAt(LCR_renderer.carModel->transform.translation,
|
||||||
|
&(LCR_renderer.scene.camera.transform));
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
TPE_Unit angleDiff = s3l_scene.camera.transform.rotation.y -
|
||||||
|
(TPE_vec2Angle(toCar.x,toCar.z) - 128);
|
||||||
|
|
||||||
|
s3l_scene.camera.transform.rotation.y -=
|
||||||
|
(angleDiff < 100 && angleDiff > -100) ? angleDiff / 2 : angleDiff;
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void LCR_rendererDraw(void)
|
void LCR_rendererDraw(void)
|
||||||
{
|
{
|
||||||
LCR_renderer.previousTriID = -1;
|
LCR_renderer.previousTriID = -1;
|
||||||
|
@ -1309,6 +1394,8 @@ LCR_renderer.wheelTurn = S3L_sin(LCR_renderer.frame * 4);
|
||||||
_LCR_rendererAnimateCar();
|
_LCR_rendererAnimateCar();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
LCR_rendererCameraFollow();
|
||||||
|
|
||||||
LCR_drawLevelFloor();
|
LCR_drawLevelFloor();
|
||||||
LCR_rendererDrawLOD();
|
LCR_rendererDrawLOD();
|
||||||
|
|
||||||
|
|
22
settings.h
22
settings.h
|
@ -94,10 +94,26 @@
|
||||||
|
|
||||||
#ifndef LCR_SETTING_CAR_ANIMATION_SUBDIVIDE
|
#ifndef LCR_SETTING_CAR_ANIMATION_SUBDIVIDE
|
||||||
/** How many frames will be used to complete whole animation of the car model.
|
/** How many frames will be used to complete whole animation of the car model.
|
||||||
0 turns off car animation completely (may be faster and smaller), 1 turns
|
0 turns off car animation completely (may be faster and smaller), 1 turns on
|
||||||
on highest quality animation, higher values lower animation quality and
|
highest quality animation, higher values lower animation quality and may
|
||||||
may increase performance. */
|
increase performance. */
|
||||||
#define LCR_SETTING_CAR_ANIMATION_SUBDIVIDE 4
|
#define LCR_SETTING_CAR_ANIMATION_SUBDIVIDE 4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef LCR_SETTING_CAMERA_HEIGHT
|
||||||
|
/** Base height of the car follow camera, in 4ths of map block height. */
|
||||||
|
#define LCR_SETTING_CAMERA_HEIGHT 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LCR_SETTING_CAMERA_HEIGHT_BAND
|
||||||
|
/** Size of height band of the follow camera, in same units as base height. */
|
||||||
|
#define LCR_SETTING_CAMERA_HEIGHT_BAND 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LCR_SETTING_CAMERA_MAX_DISTANCE
|
||||||
|
/** Maximum horizontal distance of the car follow camera, in 4ths of map block
|
||||||
|
width. */
|
||||||
|
#define LCR_SETTING_CAMERA_MAX_DISTANCE 2
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // guard
|
#endif // guard
|
||||||
|
|
Loading…
Reference in a new issue