/apps/demos/scenery: something...
This commit is contained in:
		| @@ -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)); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  |             /* total force, after ground interaction */ | ||||||
|  |             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); | ||||||
|  |             vbv[i] = vec3_add(vbv[i], vd); | ||||||
|  |             vbp[i] = vec3_add(vbp[i], vec3_scale(vbv[i], ctx.frame_duration)); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|     /* integrate forces and velocity */ |  | ||||||
|     for (size_t i = 0; i < 8; ++i) { | static void process_vehicle_mode(State *state) { | ||||||
|         Vec3 vd = vec3_scale(vec3_scale(Facc[i], (1.0f / VEHICLE_MASS)), ctx.frame_duration); |     SceneIngame *scn = (SceneIngame *)state->scene; | ||||||
|         if (vec3_length(vd) <= 0.02f) vd = (Vec3){0}; /* TODO: dirty hack... */ |  | ||||||
|         vbv[i] = vec3_add(vbv[i], vd); |     Vec3 const top_center = vec3_sub(vbp[4], vec3_scale(vec3_sub(vbp[4], vbp[6]), 1.0f / 2.0f)); | ||||||
|         vbp[i] = vec3_add(vbp[i], vec3_scale(vbv[i], ctx.frame_duration)); |     // 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; | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user