/apps/demos/scenery: drift ! steer !
This commit is contained in:
parent
f90b973d86
commit
787977b747
@ -65,6 +65,7 @@ static float heightmap[TERRAIN_DISTANCE][TERRAIN_DISTANCE];
|
|||||||
#define VEHICLE_SPRING_GC 100.0f
|
#define VEHICLE_SPRING_GC 100.0f
|
||||||
#define VEHICLE_FRICTION_S 1000.0f
|
#define VEHICLE_FRICTION_S 1000.0f
|
||||||
#define VEHICLE_FRICTION_K 100.0f
|
#define VEHICLE_FRICTION_K 100.0f
|
||||||
|
#define VEHICLE_FRICTION_V 4000.0f
|
||||||
|
|
||||||
/* TODO: shock springs, that are more loose, which are used to simulate the wheels */
|
/* TODO: shock springs, that are more loose, which are used to simulate the wheels */
|
||||||
/* initial, ideal corner positions */
|
/* initial, ideal corner positions */
|
||||||
@ -97,7 +98,10 @@ static uint8_t vbs[28][2] = {
|
|||||||
|
|
||||||
{0, 6}, {1, 7}, {2, 4}, {3, 5},
|
{0, 6}, {1, 7}, {2, 4}, {3, 5},
|
||||||
};
|
};
|
||||||
|
/* ackermann steering geometry */
|
||||||
|
static float vehicle_turning_extend;
|
||||||
|
static float vehicle_turning_speed = 0.12f;
|
||||||
|
static float vehicle_turning_extend_limit = VEHICLE_WIDTH * 1.75f;
|
||||||
|
|
||||||
static float height_at(SceneIngame *scn, Vec2 position);
|
static float height_at(SceneIngame *scn, Vec2 position);
|
||||||
static Vec3 normal_at(SceneIngame *scn, Vec2 position);
|
static Vec3 normal_at(SceneIngame *scn, Vec2 position);
|
||||||
@ -117,6 +121,15 @@ static void process_vehicle(SceneIngame *scn) {
|
|||||||
/* apply gravity */
|
/* apply gravity */
|
||||||
Vec3 Facc[8] = {0};
|
Vec3 Facc[8] = {0};
|
||||||
|
|
||||||
|
/* steering */
|
||||||
|
if (input_action_pressed("player_left"))
|
||||||
|
vehicle_turning_extend -= vehicle_turning_speed;
|
||||||
|
|
||||||
|
if (input_action_pressed("player_right"))
|
||||||
|
vehicle_turning_extend += vehicle_turning_speed;
|
||||||
|
|
||||||
|
vehicle_turning_extend = clampf(vehicle_turning_extend, -vehicle_turning_extend_limit, vehicle_turning_extend_limit);
|
||||||
|
|
||||||
Vec3 const Fg = { .y = -VEHICLE_MASS * G_CONST };
|
Vec3 const Fg = { .y = -VEHICLE_MASS * G_CONST };
|
||||||
for (size_t i = 0; i < 8; ++i)
|
for (size_t i = 0; i < 8; ++i)
|
||||||
Facc[i] = vec3_add(Facc[i], Fg);
|
Facc[i] = vec3_add(Facc[i], Fg);
|
||||||
@ -144,12 +157,15 @@ 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) {
|
||||||
/* wheel processing */
|
/* back wheel processing: acceleration */
|
||||||
if (i == 0 || i == 3 || i == 4 || i == 7) {
|
if (i == 0 || i == 3 || i == 4 || i == 7) {
|
||||||
if (scn->camera_mode == 2 && input_action_pressed("player_forward")) {
|
float scale = 0;
|
||||||
Vec3 dir = i == 0 ? vec3_sub(vbp[1], vbp[0]) : vec3_sub(vbp[2], vbp[3]);
|
if (scn->camera_mode == 2 && input_action_pressed("player_forward"))
|
||||||
Facc[i] = vec3_add(Facc[i], vec3_scale(vec3_norm(dir), 6500));
|
scale += 1;
|
||||||
}
|
if (scn->camera_mode == 2 && input_action_pressed("player_backward"))
|
||||||
|
scale -= 1;
|
||||||
|
Vec3 const dir = vec3_sub(vbp[1], vbp[0]);
|
||||||
|
Facc[i] = vec3_add(Facc[i], vec3_scale(vec3_norm(dir), 6500 * scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* normal force, for displacement */
|
/* normal force, for displacement */
|
||||||
@ -162,41 +178,64 @@ static void process_vehicle(SceneIngame *scn) {
|
|||||||
/* friction force, perpendicular to normal force */
|
/* friction force, perpendicular to normal force */
|
||||||
/* TODO: is it right? aren't vn+vol should be = |v| */
|
/* TODO: is it right? aren't vn+vol should be = |v| */
|
||||||
Vec3 const von = vec3_norm(vec3_cross(n, vec3_cross(v, n)));
|
Vec3 const von = vec3_norm(vec3_cross(n, vec3_cross(v, n)));
|
||||||
draw_line_3d(vbp[i], vec3_add(vbp[i], von), 1, (Color){255,255,0,255});
|
|
||||||
Vec3 const vo = vec3_scale(vec3_scale(von, vec3_length(v) - vn), -1);
|
Vec3 const vo = vec3_scale(vec3_scale(von, vec3_length(v) - vn), -1);
|
||||||
float const vol = vec3_length(vo);
|
float const vol = vec3_length(vo);
|
||||||
Vec3 const Fon = vec3_norm(vec3_cross(n, vec3_cross(Facc[i], n)));
|
Vec3 const Fon = vec3_norm(vec3_cross(n, vec3_cross(Facc[i], n)));
|
||||||
Vec3 Fo = vec3_scale(vec3_scale(Fon, vec3_length(Facc[i]) - vec3_dot(Facc[i], n)), -1);
|
Vec3 Fo = vec3_scale(vec3_scale(Fon, vec3_length(Facc[i]) - vec3_dot(Facc[i], n)), -1);
|
||||||
draw_line_3d(vbp[i], vec3_add(vbp[i], Fon), 1, (Color){255,255,0,255});
|
|
||||||
/* portion of total force along the surface */
|
/* portion of total force along the surface */
|
||||||
float const Fol = vec3_length(Fo);
|
float const Fol = vec3_length(Fo);
|
||||||
float const fkxn = VEHICLE_FRICTION_K * xn;
|
float const fkxn = VEHICLE_FRICTION_K * xn;
|
||||||
/* at rest, might want to start moving */
|
/* at rest, might want to start moving */
|
||||||
if (fabsf(0.0f - vol) <= 0.0001f) {
|
if (fabsf(0.0f - vol) <= 0.0001f) {
|
||||||
/* cannot overcome static friction, force along the surface is zeroed */
|
/* cannot overcome static friction, force along the surface is zeroed */
|
||||||
if (Fol <= VEHICLE_FRICTION_S * xn) {log_info("test 0"); Fo = vec3_scale(Fo, -1);}
|
if (Fol <= VEHICLE_FRICTION_S * xn) { Fo = vec3_scale(Fo, -1);}
|
||||||
/* resist the force by friction, while starting to move */
|
/* resist the force by friction, while starting to move */
|
||||||
else {log_info("test 1"); Fo = vec3_sub(Fo, vec3_scale(von, fkxn));}
|
else { Fo = vec3_sub(Fo, vec3_scale(von, fkxn));}
|
||||||
/* not at rest, stop accelerating along the surface */
|
/* not at rest, stop accelerating along the surface */
|
||||||
} else if (vol + (Fol / VEHICLE_MASS) * ctx.frame_duration <= fkxn * ctx.frame_duration * 2) {
|
} else if (vol + (Fol / VEHICLE_MASS) * ctx.frame_duration <= fkxn * ctx.frame_duration * 2) {
|
||||||
/* ugh ... */
|
/* ugh ... */
|
||||||
vbv[i] = vec3_add(vbv[i], vo);
|
vbv[i] = vec3_add(vbv[i], vo);
|
||||||
log_info("test 2");
|
|
||||||
/* just apply friction */
|
/* just apply friction */
|
||||||
} else {
|
} else {
|
||||||
Fo = vec3_scale(von, -fkxn * 400);
|
Fo = vec3_scale(von, -fkxn * 400);
|
||||||
}
|
}
|
||||||
Facc[i] = vec3_add(Facc[i], Fo);
|
Facc[i] = vec3_add(Facc[i], Fo);
|
||||||
// Facc[i] = vec3_sub(Fo, Fn);
|
|
||||||
// Facc[i] = vec3_sub(Fo, Fn);
|
/* front wheel processing */
|
||||||
Vec3 vd = vec3_scale(vec3_scale(Facc[i], (1.0f / VEHICLE_MASS)), ctx.frame_duration);
|
if (i == 1 || i == 5 || i == 2 || i == 6) {
|
||||||
vbv[i] = vec3_add(vbv[i], vd);
|
/* steering influences "center of turning", which is a point */
|
||||||
vbp[i] = vec3_add(vbp[i], vec3_scale(vbv[i], ctx.frame_duration));
|
/* laying on line defined by rear axle */
|
||||||
} else {
|
/* front arms are rotated to be perpendicular to center of turning, */
|
||||||
Vec3 vd = vec3_scale(vec3_scale(Facc[i], (1.0f / VEHICLE_MASS)), ctx.frame_duration);
|
/* which then are used to dissipate forces, thus providing control */
|
||||||
vbv[i] = vec3_add(vbv[i], vd);
|
Vec3 const rear_bar = vec3_sub(vbp[0], vbp[3]);
|
||||||
vbp[i] = vec3_add(vbp[i], vec3_scale(vbv[i], ctx.frame_duration));
|
Vec3 const rear_center = vec3_add(vbp[3], vec3_scale(rear_bar, 0.5));
|
||||||
|
Vec3 a, b, r;
|
||||||
|
if (i == 1) {
|
||||||
|
a = vec3_sub(vbp[3], vbp[2]);
|
||||||
|
b = vec3_sub(rear_center, vbp[2]);
|
||||||
|
r = vbp[2];
|
||||||
|
} else {
|
||||||
|
a = vec3_sub(vbp[0], vbp[1]);
|
||||||
|
b = vec3_sub(rear_center, vbp[1]);
|
||||||
|
r = vbp[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
float const arm_angle = vec3_angle(a, b);
|
||||||
|
Vec3 const turn_center = vec3_add(rear_center, vec3_scale(vec3_norm(rear_bar), vehicle_turning_extend));
|
||||||
|
Vec3 const arm = vec3_sub(r, turn_center);
|
||||||
|
Vec3 const n = vec3_norm(vec3_cross(a, b));
|
||||||
|
Vec3 const wheel = vec3_norm(vec3_rotate(arm, -arm_angle, n));
|
||||||
|
Vec3 const p = vec3_norm(vec3_cross(wheel, n));
|
||||||
|
draw_line_3d(r, vec3_add(r, wheel), 1, (Color){0,255,255,255});
|
||||||
|
|
||||||
|
Vec3 const Fp = vec3_scale(p, vec3_dot(vbv[i], p) * -VEHICLE_FRICTION_V);
|
||||||
|
Facc[i] = vec3_add(Facc[i], Fp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vec3 vd = vec3_scale(vec3_scale(Facc[i], (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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +86,10 @@ static inline Vec3 vec3_norm(Vec3 a) {
|
|||||||
return vec3_scale(a, 1.0f / n);
|
return vec3_scale(a, 1.0f / n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline float vec3_angle(Vec3 a, Vec3 b) {
|
||||||
|
return acosf(vec3_dot(vec3_norm(a), vec3_norm(b)));
|
||||||
|
}
|
||||||
|
|
||||||
static inline Vec3 vec3_rotate(Vec3 v, float angle, Vec3 axis) {
|
static inline Vec3 vec3_rotate(Vec3 v, float angle, Vec3 axis) {
|
||||||
/* from cglm */
|
/* from cglm */
|
||||||
Vec3 v1, v2, k;
|
Vec3 v1, v2, k;
|
||||||
|
Loading…
Reference in New Issue
Block a user