/apps/demos/scenery: something...
This commit is contained in:
parent
4e5ff9433c
commit
ed8e826b94
@ -53,17 +53,18 @@ static float heightmap[TERRAIN_DISTANCE][TERRAIN_DISTANCE];
|
|||||||
/* else if length(v(o) + (F(o)/m)*t) <= (f(k)*x(n)*t), v(o) = 0 */
|
/* else if length(v(o) + (F(o)/m)*t) <= (f(k)*x(n)*t), v(o) = 0 */
|
||||||
/* else, F = -unit(v(o)*f(k)*x(n)) */
|
/* else, F = -unit(v(o)*f(k)*x(n)) */
|
||||||
|
|
||||||
#define VEHICLE_MASS 200.0f
|
#define VEHICLE_MASS 150.0f
|
||||||
#define VEHICLE_LENGTH 3.0f
|
#define VEHICLE_LENGTH 3.0f
|
||||||
#define VEHICLE_WIDTH 1.7f
|
#define VEHICLE_WIDTH 1.7f
|
||||||
#define VEHICLE_HEIGHT 1.3f
|
#define VEHICLE_HEIGHT 1.3f
|
||||||
/* spring constant */
|
/* spring constant */
|
||||||
#define VEHICLE_SPRING_K 50000.0f
|
#define VEHICLE_SPRING_K 80000.0f
|
||||||
/* damping constant */
|
/* damping constant */
|
||||||
#define VEHICLE_SPRING_C 200.0f
|
#define VEHICLE_SPRING_C 500.0f
|
||||||
#define VEHICLE_FRICTION_S 50000.0f
|
#define VEHICLE_FRICTION_S 1000.0f
|
||||||
#define VEHICLE_FRICTION_K 700.0f
|
#define VEHICLE_FRICTION_K 100.0f
|
||||||
|
|
||||||
|
/* TODO: shock springs, that are more loose, which are used to simulate the wheels */
|
||||||
/* initial, ideal corner positions */
|
/* initial, ideal corner positions */
|
||||||
static const Vec3 vbpi[8] = {
|
static const Vec3 vbpi[8] = {
|
||||||
[0] = { 0, 0, 0 },
|
[0] = { 0, 0, 0 },
|
||||||
@ -141,48 +142,83 @@ static void process_vehicle(SceneIngame *scn) {
|
|||||||
Vec3 const v = vbv[i];
|
Vec3 const v = vbv[i];
|
||||||
float const h = height_at(scn, (Vec2){ p.x, p.z });
|
float const h = height_at(scn, (Vec2){ p.x, p.z });
|
||||||
if (h >= p.y) {
|
if (h >= p.y) {
|
||||||
/* displacement force */
|
/* wheel processing */
|
||||||
|
if (i == 0 || i == 3) {
|
||||||
|
if (scn->camera_mode == 2 && input_action_pressed("player_forward")) {
|
||||||
|
Vec3 const dir = i == 0 ? vec3_sub(vbp[0], vbp[1]) : vec3_sub(vbp[3], vbp[2]);
|
||||||
|
Facc[i] = vec3_add(Facc[i], vec3_scale(vec3_norm(dir), 18000));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* normal force, for displacement */
|
||||||
Vec3 const n = normal_at(scn, (Vec2){ p.x, p.z });
|
Vec3 const n = normal_at(scn, (Vec2){ p.x, p.z });
|
||||||
float const xn = (h - p.y) * n.y;
|
float const xn = (h - p.y) * n.y;
|
||||||
float const vn = vec3_dot(v, n);
|
float const vn = vec3_dot(v, n);
|
||||||
Vec3 const Fd = vec3_scale(n, -VEHICLE_SPRING_K * xn - VEHICLE_SPRING_C * vn);
|
Vec3 const Fn = vec3_scale(n, -VEHICLE_SPRING_K * xn - VEHICLE_SPRING_C * vn);
|
||||||
Facc[i] = vec3_sub(Facc[i], Fd);
|
|
||||||
|
|
||||||
/* friction force, perpendicular to displacement */
|
/* friction force, perpendicular to normal force */
|
||||||
/* portions aligned to surface normal */
|
Vec3 const vo = vec3_sub(v, vec3_scale(n, vn));
|
||||||
Vec3 const vov = vec3_sub(v, vec3_scale(n, vn));
|
float const vol = vec3_length(vo);
|
||||||
draw_line_3d(vbp[i], vec3_add(vbp[i], vec3_scale(vov, 3)), 1, (Color){255, 0, 0, 255});
|
Vec3 Fo = vec3_sub(Facc[i], vec3_scale(n, vec3_dot(Facc[i], n)));
|
||||||
float const vo = vec3_length(vov);
|
/* portion of total force along the surface */
|
||||||
Vec3 const Fov = vec3_sub(Facc[i], vec3_scale(n, vec3_dot(Facc[i], n)));
|
float const Fol = vec3_length(Fo);
|
||||||
float const Fo = vec3_length(Fov);
|
float const fkxn = VEHICLE_FRICTION_K * xn * 50;
|
||||||
float const fkxn = VEHICLE_FRICTION_K * xn;
|
/* at rest, might want to start moving */
|
||||||
if (fabsf(0.0f - vo) <= 0.001f) {
|
if (fabsf(0.0f - vol) <= 0.0001f) {
|
||||||
/* cannot overcome static friction, zero force along the surface */
|
/* cannot overcome static friction, force along the surface is zeroed */
|
||||||
if (Fo <= VEHICLE_FRICTION_S * xn) {
|
if (Fol <= VEHICLE_FRICTION_S * xn) Fo = (Vec3){0};
|
||||||
// Facc[i] = vec3_sub(Facc[i], Fov);
|
/* resist the force by friction, while starting to move */
|
||||||
Facc[i] = (Vec3){0};
|
else Fo = vec3_sub(Fo, vec3_scale(vec3_norm(Fo), fkxn));
|
||||||
}
|
/* not at rest, stop accelerating along the surface */
|
||||||
/* apply kinematic friction */
|
} else if (vol + (Fol / VEHICLE_MASS) * ctx.frame_duration <= fkxn * ctx.frame_duration) {
|
||||||
else {
|
log_info("test 1");
|
||||||
Facc[i] = vec3_sub(Fov, vec3_scale(vec3_norm(Fov), fkxn));
|
// vbv[i] = vec3_sub(vbp[i], vo);
|
||||||
}
|
|
||||||
/* velocity with gain along the surface will not overcome */
|
|
||||||
} else if (vec3_length(vec3_add(vov, vec3_scale(vec3_scale(Fov, (1.0f / VEHICLE_MASS)), ctx.frame_duration))) <= fkxn * ctx.frame_duration) {
|
|
||||||
// vbv[i] = vec3_sub(vbv[i], vov);
|
|
||||||
vbv[i] = (Vec3){0};
|
vbv[i] = (Vec3){0};
|
||||||
|
/* just apply friction */
|
||||||
} else {
|
} else {
|
||||||
Facc[i] = vec3_sub(Facc[i], vec3_scale(vec3_norm(vov), fkxn));
|
log_info("test 2, depth: %f", xn);
|
||||||
}
|
Fo = vec3_add(Fo, vec3_scale(vec3_norm(vo), -fkxn * 100));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* integrate forces and velocity */
|
/* total force, after ground interaction */
|
||||||
for (size_t i = 0; i < 8; ++i) {
|
Vec3 const Ft = vec3_add(vec3_scale(Fn, -1), Fo);
|
||||||
|
Vec3 vd = vec3_scale(vec3_scale(Ft, (1.0f / VEHICLE_MASS)), ctx.frame_duration);
|
||||||
|
vbv[i] = vec3_add(vbv[i], vd);
|
||||||
|
vbp[i] = vec3_add(vbp[i], vec3_scale(vbv[i], ctx.frame_duration));
|
||||||
|
} else {
|
||||||
|
/* in air */
|
||||||
Vec3 vd = vec3_scale(vec3_scale(Facc[i], (1.0f / VEHICLE_MASS)), ctx.frame_duration);
|
Vec3 vd = vec3_scale(vec3_scale(Facc[i], (1.0f / VEHICLE_MASS)), ctx.frame_duration);
|
||||||
if (vec3_length(vd) <= 0.02f) vd = (Vec3){0}; /* TODO: dirty hack... */
|
|
||||||
vbv[i] = vec3_add(vbv[i], vd);
|
vbv[i] = vec3_add(vbv[i], vd);
|
||||||
vbp[i] = vec3_add(vbp[i], vec3_scale(vbv[i], ctx.frame_duration));
|
vbp[i] = vec3_add(vbp[i], vec3_scale(vbv[i], ctx.frame_duration));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void process_vehicle_mode(State *state) {
|
||||||
|
SceneIngame *scn = (SceneIngame *)state->scene;
|
||||||
|
|
||||||
|
Vec3 const top_center = vec3_sub(vbp[4], vec3_scale(vec3_sub(vbp[4], vbp[6]), 1.0f / 2.0f));
|
||||||
|
// Vec3 const front_center = vec3_add(vbp[4], vec3_scale(vec3_sub(vbp[4], vbp[7]), 1.0f / 2.0f));
|
||||||
|
// Vec3 const facing_direction = vec3_sub(top_center, front_center);
|
||||||
|
|
||||||
|
float yawc, yaws, pitchc, pitchs;
|
||||||
|
sincosf(scn->yaw + (float)M_PI_2, &yaws, &yawc);
|
||||||
|
sincosf(scn->pitch, &pitchs, &pitchc);
|
||||||
|
|
||||||
|
Vec3 const looking_direction = vec3_norm(((Vec3){
|
||||||
|
yawc * pitchc,
|
||||||
|
pitchs,
|
||||||
|
yaws * pitchc,
|
||||||
|
}));
|
||||||
|
|
||||||
|
Vec3 const orbit = vec3_sub(top_center, vec3_scale(looking_direction, 10));
|
||||||
|
|
||||||
|
draw_camera(orbit, looking_direction, (Vec3){0,1,0}, (float)M_PI_2 * 0.8f, 1, TERRAIN_RADIUS * sqrtf(3));
|
||||||
|
|
||||||
|
scn->looking_direction = looking_direction;
|
||||||
|
|
||||||
|
scn->pos = top_center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -435,12 +471,14 @@ static void ingame_tick(State *state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (input_action_just_pressed("toggle_camera_mode"))
|
if (input_action_just_pressed("toggle_camera_mode"))
|
||||||
scn->flying_camera = !scn->flying_camera;
|
scn->camera_mode = scn->camera_mode == 2 ? 0 : scn->camera_mode + 1;
|
||||||
|
|
||||||
if (scn->flying_camera) {
|
if (scn->camera_mode == 1) {
|
||||||
process_fly_mode(state);
|
process_fly_mode(state);
|
||||||
} else {
|
} else if (scn->camera_mode == 0) {
|
||||||
process_ground_mode(state);
|
process_ground_mode(state);
|
||||||
|
} else if (scn->camera_mode) {
|
||||||
|
process_vehicle_mode(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* toggle mouse capture with end key */
|
/* toggle mouse capture with end key */
|
||||||
|
@ -21,7 +21,7 @@ typedef struct SceneIngame {
|
|||||||
float roll;
|
float roll;
|
||||||
|
|
||||||
bool mouse_captured;
|
bool mouse_captured;
|
||||||
bool flying_camera;
|
int camera_mode;
|
||||||
} SceneIngame;
|
} SceneIngame;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user