/apps/demos/scenery: separate height_at(), position grass right
This commit is contained in:
		| @@ -48,6 +48,35 @@ static void process_fly_mode(State *state) { | ||||
| } | ||||
|  | ||||
|  | ||||
| static float height_at(SceneIngame *scn, Vec2 position) { | ||||
|     float height0, height1, height2, weight0, weight1, weight2; | ||||
|  | ||||
|     int const x = (int)(HALF_TERRAIN_DISTANCE + (position.x - scn->pos.x)); | ||||
|     int const y = (int)(HALF_TERRAIN_DISTANCE + (position.y - scn->pos.z)); | ||||
|  | ||||
|     height0 = heightmap[x][y]; | ||||
|     height1 = heightmap[x + 1][y + 1]; | ||||
|  | ||||
|     Vec2 incell = { position.x - floorf(position.x), position.y - floorf(position.y) }; | ||||
|  | ||||
|     /* who needs barycentric coordinates, am i right? */ | ||||
|     weight0 = 1 / sqrtf(powf(incell.x, 2) + powf(incell.y, 2)); | ||||
|     weight1 = 1 / sqrtf(powf(1 - incell.x, 2) + powf(1 - incell.y, 2)); | ||||
|  | ||||
|     /* find which triangle we're directly under */ | ||||
|     /* for this manhattan distance is sufficient */ | ||||
|     if (incell.x + (1 - incell.y) < (1 - incell.x) + incell.y) { | ||||
|         height2 = heightmap[x][y + 1]; | ||||
|         weight2 = 1 / sqrtf(powf(incell.x, 2) + powf(1 - incell.y, 2)); | ||||
|     } else { | ||||
|         height2 = heightmap[x + 1][y]; | ||||
|         weight2 = 1 / sqrtf(powf(1 - incell.x, 2) + powf(incell.y, 2)); | ||||
|     } | ||||
|  | ||||
|     return (height0 * weight0 + height1 * weight1 + height2 * weight2) / (weight0 + weight1 + weight2); | ||||
| } | ||||
|  | ||||
|  | ||||
| static void process_ground_mode(State *state) { | ||||
|     SceneIngame *scn = (SceneIngame *)state->scene; | ||||
|  | ||||
| @@ -61,35 +90,13 @@ static void process_ground_mode(State *state) { | ||||
|  | ||||
|     /* gravity */ | ||||
|     { | ||||
|         float height0, height1, height2, weight0, weight1, weight2; | ||||
|  | ||||
|         height0 = heightmap[(int)HALF_TERRAIN_DISTANCE][(int)HALF_TERRAIN_DISTANCE]; | ||||
|         height1 = heightmap[(int)HALF_TERRAIN_DISTANCE + 1][(int)HALF_TERRAIN_DISTANCE + 1]; | ||||
|  | ||||
|         Vec2 incell = { scn->pos.x - floorf(scn->pos.x), scn->pos.z - floorf(scn->pos.z) }; | ||||
|  | ||||
|         /* who needs barycentric coordinates, am i right? */ | ||||
|         weight0 = 1 / sqrtf(powf(incell.x, 2) + powf(incell.y, 2)); | ||||
|         weight1 = 1 / sqrtf(powf(1 - incell.x, 2) + powf(1 - incell.y, 2)); | ||||
|  | ||||
|         /* find which triangle we're directly under */ | ||||
|         /* for this manhattan distance is sufficient */ | ||||
|         if (incell.x + (1 - incell.y) < (1 - incell.x) + incell.y) { | ||||
|             height2 = heightmap[(int)HALF_TERRAIN_DISTANCE][(int)HALF_TERRAIN_DISTANCE + 1]; | ||||
|             weight2 = 1 / sqrtf(powf(incell.x, 2) + powf(1 - incell.y, 2)); | ||||
|         } else { | ||||
|             height2 = heightmap[(int)HALF_TERRAIN_DISTANCE + 1][(int)HALF_TERRAIN_DISTANCE]; | ||||
|             weight2 = 1 / sqrtf(powf(1 - incell.x, 2) + powf(incell.y, 2)); | ||||
|         } | ||||
|  | ||||
|         float height = (height0 * weight0 + height1 * weight1 + height2 * weight2) / (weight0 + weight1 + weight2); | ||||
|         float const height = height_at(scn, (Vec2){scn->pos.x, scn->pos.z}); | ||||
|  | ||||
|         if (target.y > height + PLAYER_HEIGHT) | ||||
|             target.y = target.y - 0.4f; | ||||
|  | ||||
|         if (target.y < height + PLAYER_HEIGHT) | ||||
|             target.y = height + PLAYER_HEIGHT; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /* movement */ | ||||
| @@ -159,7 +166,10 @@ static void draw_terrain(SceneIngame *scn) { | ||||
|                             (Vec2){ 0, 0 }, | ||||
|                             (Vec2){ 0, 128 }); | ||||
|  | ||||
|             draw_billboard("/assets/grasses/10.png", (Vec3){ (float)x, d1 + 0.1f, (float)y }, (Vec2){0.3f, 0.3f}, (Color){255, 255, 255, 255}, true); | ||||
|             draw_billboard("/assets/grasses/10.png", | ||||
|                           (Vec3){ (float)x, d0 + 0.15f, (float)y }, | ||||
|                           (Vec2){0.3f, 0.3f}, | ||||
|                           (Color){255, 255, 255, 255}, true); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user