antizona

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit 97b5b1dab80beed0681d4d9be6986d16f3eb8ac0
parent d3339c3c93cbaa9bc1efc4a0cb3dca9c0953039c
Author: averagecoder <averagecoder@noreply.codeberg.org>
Date:   Sun, 23 Aug 2026 20:57:05 +0300

fix: add size-based rendering

Diffstat:
Msrc/build.c | 28+++++++++++++++++++++++++++-
Msrc/render.c | 385+++++++++++++++++++++++++++++--------------------------------------------------
2 files changed, 168 insertions(+), 245 deletions(-)

diff --git a/src/build.c b/src/build.c @@ -66,6 +66,7 @@ struct col_triangle { float v0[3]; float v1[3]; float v2[3]; + float norm[3]; uint8_t surface; }; @@ -2006,7 +2007,7 @@ instantiate_collision(const char *model_name, const struct mat4 *world_mat) struct col_model *cm; struct col_triangle wt; struct col_cell *c; - float w, min_x, max_x, min_z, max_z; + float w, min_x, max_x, min_z, max_z, e1[3], e2[3], len; uint32_t i; int gx0, gx1, gz0, gz1, gx, gz; @@ -2021,6 +2022,31 @@ instantiate_collision(const char *model_name, const struct mat4 *world_mat) mat_transform(wt.v2, &w, world_mat, cm->tris[i].v2); wt.surface = cm->tris[i].surface; + e1[0] = wt.v1[0] - wt.v0[0]; + e1[1] = wt.v1[1] - wt.v0[1]; + e1[2] = wt.v1[2] - wt.v0[2]; + + e2[0] = wt.v2[0] - wt.v0[0]; + e2[1] = wt.v2[1] - wt.v0[1]; + e2[2] = wt.v2[2] - wt.v0[2]; + + wt.norm[0] = e1[1] * e2[2] - e1[2] * e2[1]; + wt.norm[1] = e1[2] * e2[0] - e1[0] * e2[2]; + wt.norm[2] = e1[0] * e2[1] - e1[1] * e2[0]; + + len = sqrtf(wt.norm[0] * wt.norm[0] + + wt.norm[1] * wt.norm[1] + + wt.norm[2] * wt.norm[2]); + if (len > 1e-6f) { + wt.norm[0] /= len; + wt.norm[1] /= len; + wt.norm[2] /= len; + } else { + wt.norm[0] = 0.0f; + wt.norm[1] = 1.0f; + wt.norm[2] = 0.0f; + } + min_x = fminf(wt.v0[0], fminf(wt.v1[0], wt.v2[0])); max_x = fmaxf(wt.v0[0], fmaxf(wt.v1[0], wt.v2[0])); min_z = fminf(wt.v0[2], fminf(wt.v1[2], wt.v2[2])); diff --git a/src/render.c b/src/render.c @@ -45,6 +45,7 @@ struct col_triangle { float v0[3]; float v1[3]; float v2[3]; + float norm[3]; uint8_t surface; }; @@ -417,7 +418,7 @@ draw_triangle_band(const struct render_triangle *tri, int min_y_band, int max_y_ { struct vertex v0, v1, v2, sv0, sv1, sv2, tmp; const struct texture *tex; - uint32_t *pixels; + const uint32_t *pixels; float area, inv_area, dy12, dy20, dx12, dx20, dy01; float p_x_start, p_y_start, w0_start, w1_start; float dw0_dx, dw0_dy, dw1_dx, dw1_dy; @@ -425,21 +426,30 @@ draw_triangle_band(const struct render_triangle *tri, int min_y_band, int max_y_ float d_inv_w_dx, d_u_w_dx, d_v_w_dx, d_f_w_dx, d_r_dx, d_g_dx, d_b_dx; float d_r_dx_255, d_g_dx_255, d_b_dx_255; float inv_slope_long, inv_slope_short1, inv_slope_short2; - float row_y, x_long, x_short; + float row_y, x_long, x_short, x_min, x_max; float dx, dy, row_w0, row_w1, row_w2; - float inv_w, u_w, v_w, f_w, r, g_val, b; - float wf, f, inv_f; - uint32_t sky_r, sky_g, sky_b, color, wa, fr, fg, fb, bg, tex_r, tex_g, tex_b; - uint8_t wa_tc, wr, wg, wb, tex_a; + float inv_w, u_w, v_w, f_w, r, g_val, b, wf, f, inv_f, min_inv_w; + uint32_t sky_r, sky_g, sky_b, color, bg, tex_r, tex_g, tex_b; + uint8_t tex_a, wa_tc, wr, wg, wb, wa; int min_x, max_x, min_y, max_y, row_min_x, row_max_x; - int tw, th, tw_mask, th_mask, py, px, idx, ir, ig, ib, tx, ty; - int m; - float min_inv_w; + int tw, th, tw_mask, th_mask, py, px, idx, ir, ig, ib, tx, ty, m; v0 = tri->v0; v1 = tri->v1; v2 = tri->v2; + min_y = (int)MIN(v0.y, MIN(v1.y, v2.y)); + max_y = (int)MAX(v0.y, MAX(v1.y, v2.y)); + if (max_y < min_y_band || min_y > max_y_band) { + return; + } + + min_x = (int)MIN(v0.x, MIN(v1.x, v2.x)); + max_x = (int)MAX(v0.x, MAX(v1.x, v2.x)); + if (min_x >= WIDTH || max_x < 0) { + return; + } + min_inv_w = MIN(v0.w, MIN(v1.w, v2.w)); if (min_inv_w < 0.0001f) { min_inv_w = 0.0001f; @@ -457,16 +467,11 @@ draw_triangle_band(const struct render_triangle *tri, int min_y_band, int max_y_ dx20 = v0.x - v2.x; dy01 = v1.y - v0.y; - min_x = (int)MIN(v0.x, MIN(v1.x, v2.x)); - max_x = (int)MAX(v0.x, MAX(v1.x, v2.x)); - min_y = (int)MIN(v0.y, MIN(v1.y, v2.y)); - max_y = (int)MAX(v0.y, MAX(v1.y, v2.y)); - if (min_x < 0) min_x = 0; if (max_x >= WIDTH) max_x = WIDTH - 1; if (min_y < min_y_band) min_y = min_y_band; if (max_y > max_y_band) max_y = max_y_band; - if (min_y > max_y) { + if (min_y > max_y || min_x > max_x) { return; } @@ -500,75 +505,49 @@ draw_triangle_band(const struct render_triangle *tri, int min_y_band, int max_y_ sky_g = g_sys->cur_weather.sky_bot[1]; sky_b = g_sys->cur_weather.sky_bot[2]; - sv0 = v0; - sv1 = v1; - sv2 = v2; + sv0 = v0; sv1 = v1; sv2 = v2; if (sv0.y > sv1.y) { tmp = sv0; sv0 = sv1; sv1 = tmp; } if (sv0.y > sv2.y) { tmp = sv0; sv0 = sv2; sv2 = tmp; } if (sv1.y > sv2.y) { tmp = sv1; sv1 = sv2; sv2 = tmp; } - inv_slope_long = 0.0f; - inv_slope_short1 = 0.0f; - inv_slope_short2 = 0.0f; + inv_slope_long = (sv2.y != sv0.y) ? (sv2.x - sv0.x) / (sv2.y - sv0.y) : 0.0f; + inv_slope_short1 = (sv1.y != sv0.y) ? (sv1.x - sv0.x) / (sv1.y - sv0.y) : 0.0f; + inv_slope_short2 = (sv2.y != sv1.y) ? (sv2.x - sv1.x) / (sv2.y - sv1.y) : 0.0f; - if (sv2.y != sv0.y) { - inv_slope_long = (sv2.x - sv0.x) / (sv2.y - sv0.y); - } - if (sv1.y != sv0.y) { - inv_slope_short1 = (sv1.x - sv0.x) / (sv1.y - sv0.y); - } - if (sv2.y != sv1.y) { - inv_slope_short2 = (sv2.x - sv1.x) / (sv2.y - sv1.y); - } - - if (tri->is_water && tri->tex && (uintptr_t)tri->tex != (uintptr_t)-1) { + if (tri->tex && (uintptr_t)tri->tex != (uintptr_t)-1 && !tri->is_water) { tex = tri->tex; - pixels = tex->pixels; - tw = tex->w; - th = tex->h; + m = tri->mip; + if (m < 0) m = 0; + if (m > 3) m = 3; + pixels = tex->mips[m]; + tw = tex->mip_w[m]; + th = tex->mip_h[m]; tw_mask = tw - 1; th_mask = th - 1; - wa_tc = g_sys->cur_weather.water[3]; - wr = g_sys->cur_weather.water[0]; - wg = g_sys->cur_weather.water[1]; - wb = g_sys->cur_weather.water[2]; for (py = min_y; py <= max_y; py++) { row_y = (float)py + 0.5f; - x_long = sv0.x; - if (sv2.y != sv0.y) { - x_long += (row_y - sv0.y) * inv_slope_long; - } - - if (row_y < sv1.y) { - x_short = sv0.x; - if (sv1.y != sv0.y) { - x_short += (row_y - sv0.y) * inv_slope_short1; - } - } else { - x_short = sv1.x; - if (sv2.y != sv1.y) { - x_short += (row_y - sv1.y) * inv_slope_short2; - } - } + x_long = sv0.x + (row_y - sv0.y) * inv_slope_long; + x_short = (row_y < sv1.y) ? + sv0.x + (row_y - sv0.y) * inv_slope_short1 : + sv1.x + (row_y - sv1.y) * inv_slope_short2; - float x_min = (x_long < x_short) ? x_long : x_short; - float x_max = (x_long < x_short) ? x_short : x_long; + x_min = (x_long < x_short) ? x_long : x_short; + x_max = (x_long < x_short) ? x_short : x_long; row_min_x = (int)ceilf(x_min - 0.5f); row_max_x = (int)floorf(x_max - 0.5f); if (row_min_x < min_x) row_min_x = min_x; if (row_max_x > max_x) row_max_x = max_x; - if (row_min_x > row_max_x) { - continue; - } + if (row_min_x > row_max_x) continue; dx = (row_min_x + 0.5f) - p_x_start; dy = row_y - p_y_start; row_w0 = w0_start + dw0_dx * dx + dw0_dy * dy; row_w1 = w1_start + dw1_dx * dx + dw1_dy * dy; row_w2 = 1.0f - row_w0 - row_w1; + inv_w = row_w0 * v0.w + row_w1 * v1.w + row_w2 * v2.w; u_w = row_w0 * u0_w + row_w1 * u1_w + row_w2 * u2_w; v_w = row_w0 * v0_w + row_w1 * v1_w + row_w2 * v2_w; @@ -580,88 +559,76 @@ draw_triangle_band(const struct render_triangle *tri, int min_y_band, int max_y_ for (px = row_min_x; px <= row_max_x; px++) { idx = py * WIDTH + px; if (inv_w > g_sys->zbuffer[idx] && inv_w >= min_inv_w * 0.99f) { - ir = (int)r; ir = ir > 255 ? 255 : (ir < 0 ? 0 : ir); - ig = (int)g_val; ig = ig > 255 ? 255 : (ig < 0 ? 0 : ig); - ib = (int)b; ib = ib > 255 ? 255 : (ib < 0 ? 0 : ib); wf = 1.0f / inv_w; - f = f_w * wf; - if (f > 1.0f) f = 1.0f; - if (f < 0.0f) f = 0.0f; - inv_f = 1.0f - f; tx = (int)(u_w * wf * tw) & tw_mask; ty = (int)(v_w * wf * th) & th_mask; color = pixels[ty * tw + tx]; - wa = (wa_tc * ((color >> 24) & 0xFF)) >> 8; - fr = ((((color >> 16) & 0xFF) * ir >> 8) * wr) >> 8; - fg = ((((color >> 8) & 0xFF) * ig >> 8) * wg) >> 8; - fb = ((color & 0xFF) * ib >> 8) * wb >> 8; - fr = (uint32_t)(fr * inv_f + sky_r * f); - fg = (uint32_t)(fg * inv_f + sky_g * f); - fb = (uint32_t)(fb * inv_f + sky_b * f); - bg = g_sys->pixels[idx]; - g_sys->pixels[idx] = (0xFF << 24) | - (((fr * wa + ((bg >> 16) & 0xFF) * (255 - wa)) >> 8) << 16) | - (((fg * wa + ((bg >> 8) & 0xFF) * (255 - wa)) >> 8) << 8) | - ((fb * wa + (bg & 0xFF) * (255 - wa)) >> 8); + tex_a = (color >> 24) & 0xFF; + if (tex_a > 127) { + ir = (int)r; if (ir > 255) ir = 255; else if (ir < 0) ir = 0; + ig = (int)g_val; if (ig > 255) ig = 255; else if (ig < 0) ig = 0; + ib = (int)b; if (ib > 255) ib = 255; else if (ib < 0) ib = 0; + + tex_r = ((color >> 16) & 0xFF) * ir >> 8; + tex_g = ((color >> 8) & 0xFF) * ig >> 8; + tex_b = (color & 0xFF) * ib >> 8; + + f = f_w * wf; + if (f > 0.001f) { + if (f > 1.0f) f = 1.0f; + inv_f = 1.0f - f; + tex_r = (uint32_t)(tex_r * inv_f + sky_r * f); + tex_g = (uint32_t)(tex_g * inv_f + sky_g * f); + tex_b = (uint32_t)(tex_b * inv_f + sky_b * f); + } + + g_sys->pixels[idx] = (tex_a << 24) | + (tex_r << 16) | (tex_g << 8) | tex_b; + g_sys->zbuffer[idx] = inv_w; + } } inv_w += d_inv_w_dx; u_w += d_u_w_dx; v_w += d_v_w_dx; f_w += d_f_w_dx; r += d_r_dx_255; g_val += d_g_dx_255; b += d_b_dx_255; } } - } else if (tri->tex && (uintptr_t)tri->tex != (uintptr_t)-1) { + } else if (tri->is_water && tri->tex && (uintptr_t)tri->tex != (uintptr_t)-1) { tex = tri->tex; - m = tri->mip; - if (m < 0) { - m = 0; - } - if (m > 3) { - m = 3; - } - pixels = tex->mips[m]; - tw = tex->mip_w[m]; - th = tex->mip_h[m]; + pixels = tex->pixels; + tw = tex->w; + th = tex->h; tw_mask = tw - 1; th_mask = th - 1; + wa_tc = g_sys->cur_weather.water[3]; + wr = g_sys->cur_weather.water[0]; + wg = g_sys->cur_weather.water[1]; + wb = g_sys->cur_weather.water[2]; for (py = min_y; py <= max_y; py++) { row_y = (float)py + 0.5f; - x_long = sv0.x; - if (sv2.y != sv0.y) { - x_long += (row_y - sv0.y) * inv_slope_long; - } + x_long = sv0.x + (row_y - sv0.y) * inv_slope_long; + x_short = (row_y < sv1.y) ? + sv0.x + (row_y - sv0.y) * inv_slope_short1 : + sv1.x + (row_y - sv1.y) * inv_slope_short2; - if (row_y < sv1.y) { - x_short = sv0.x; - if (sv1.y != sv0.y) { - x_short += (row_y - sv0.y) * inv_slope_short1; - } - } else { - x_short = sv1.x; - if (sv2.y != sv1.y) { - x_short += (row_y - sv1.y) * inv_slope_short2; - } - } - - float x_min = (x_long < x_short) ? x_long : x_short; - float x_max = (x_long < x_short) ? x_short : x_long; + x_min = (x_long < x_short) ? x_long : x_short; + x_max = (x_long < x_short) ? x_short : x_long; row_min_x = (int)ceilf(x_min - 0.5f); row_max_x = (int)floorf(x_max - 0.5f); if (row_min_x < min_x) row_min_x = min_x; if (row_max_x > max_x) row_max_x = max_x; - if (row_min_x > row_max_x) { - continue; - } + if (row_min_x > row_max_x) continue; dx = (row_min_x + 0.5f) - p_x_start; dy = row_y - p_y_start; row_w0 = w0_start + dw0_dx * dx + dw0_dy * dy; row_w1 = w1_start + dw1_dx * dx + dw1_dy * dy; row_w2 = 1.0f - row_w0 - row_w1; + inv_w = row_w0 * v0.w + row_w1 * v1.w + row_w2 * v2.w; u_w = row_w0 * u0_w + row_w1 * u1_w + row_w2 * u2_w; - v_w = row_w0 * v0_w + row_w1 * v1_w + row_w2 * v2_w; + v_w = row_w0 * v0_w + row_w1 * v1_w + row_w2 * v2.w; f_w = row_w0 * f0_w + row_w1 * f1_w + row_w2 * f2_w; r = (row_w0 * v0.r + row_w1 * v1.r + row_w2 * v2.r) * 255.0f; g_val = (row_w0 * v0.g + row_w1 * v1.g + row_w2 * v2.g) * 255.0f; @@ -670,107 +637,39 @@ draw_triangle_band(const struct render_triangle *tri, int min_y_band, int max_y_ for (px = row_min_x; px <= row_max_x; px++) { idx = py * WIDTH + px; if (inv_w > g_sys->zbuffer[idx] && inv_w >= min_inv_w * 0.99f) { + ir = (int)r; if (ir > 255) ir = 255; else if (ir < 0) ir = 0; + ig = (int)g_val; if (ig > 255) ig = 255; else if (ig < 0) ig = 0; + ib = (int)b; if (ib > 255) ib = 255; else if (ib < 0) ib = 0; wf = 1.0f / inv_w; + tx = (int)(u_w * wf * tw) & tw_mask; ty = (int)(v_w * wf * th) & th_mask; color = pixels[ty * tw + tx]; - tex_a = (color >> 24) & 0xFF; - if (tex_a > 127) { - ir = (int)r; ir = ir > 255 ? 255 : (ir < 0 ? 0 : ir); - ig = (int)g_val; ig = ig > 255 ? 255 : (ig < 0 ? 0 : ig); - ib = (int)b; ib = ib > 255 ? 255 : (ib < 0 ? 0 : ib); - f = f_w * wf; + + wa = (wa_tc * ((color >> 24) & 0xFF)) >> 8; + tex_r = ((((color >> 16) & 0xFF) * ir >> 8) * wr) >> 8; + tex_g = ((((color >> 8) & 0xFF) * ig >> 8) * wg) >> 8; + tex_b = ((color & 0xFF) * ib >> 8) * wb >> 8; + + f = f_w * wf; + if (f > 0.001f) { if (f > 1.0f) f = 1.0f; - if (f < 0.0f) f = 0.0f; inv_f = 1.0f - f; - tex_r = ((color >> 16) & 0xFF) * ir >> 8; - tex_g = ((color >> 8) & 0xFF) * ig >> 8; - tex_b = (color & 0xFF) * ib >> 8; tex_r = (uint32_t)(tex_r * inv_f + sky_r * f); tex_g = (uint32_t)(tex_g * inv_f + sky_g * f); tex_b = (uint32_t)(tex_b * inv_f + sky_b * f); - g_sys->pixels[idx] = (tex_a << 24) | - (tex_r << 16) | (tex_g << 8) | tex_b; - g_sys->zbuffer[idx] = inv_w; } + + bg = g_sys->pixels[idx]; + g_sys->pixels[idx] = (0xFF << 24) | + (((tex_r * wa + ((bg >> 16) & 0xFF) * (255 - wa)) >> 8) << 16) | + (((tex_g * wa + ((bg >> 8) & 0xFF) * (255 - wa)) >> 8) << 8) | + ((tex_b * wa + (bg & 0xFF) * (255 - wa)) >> 8); } inv_w += d_inv_w_dx; u_w += d_u_w_dx; v_w += d_v_w_dx; f_w += d_f_w_dx; r += d_r_dx_255; g_val += d_g_dx_255; b += d_b_dx_255; } } - } else { - for (py = min_y; py <= max_y; py++) { - row_y = (float)py + 0.5f; - x_long = sv0.x; - if (sv2.y != sv0.y) { - x_long += (row_y - sv0.y) * inv_slope_long; - } - - if (row_y < sv1.y) { - x_short = sv0.x; - if (sv1.y != sv0.y) { - x_short += (row_y - sv0.y) * inv_slope_short1; - } - } else { - x_short = sv1.x; - if (sv2.y != sv1.y) { - x_short += (row_y - sv1.y) * inv_slope_short2; - } - } - - float x_min = (x_long < x_short) ? x_long : x_short; - float x_max = (x_long < x_short) ? x_short : x_long; - - row_min_x = (int)ceilf(x_min - 0.5f); - row_max_x = (int)floorf(x_max - 0.5f); - - if (row_min_x < min_x) row_min_x = min_x; - if (row_max_x > max_x) row_max_x = max_x; - if (row_min_x > row_max_x) { - continue; - } - - dx = (row_min_x + 0.5f) - p_x_start; - dy = row_y - p_y_start; - row_w0 = w0_start + dw0_dx * dx + dw0_dy * dy; - row_w1 = w1_start + dw1_dx * dx + dw1_dy * dy; - row_w2 = 1.0f - row_w0 - row_w1; - inv_w = row_w0 * v0.w + row_w1 * v1.w + row_w2 * v2.w; - f_w = row_w0 * f0_w + row_w1 * f1_w + row_w2 * f2_w; - r = (row_w0 * v0.r + row_w1 * v1.r + row_w2 * v2.r) * 255.0f; - g_val = (row_w0 * v0.g + row_w1 * v1.g + row_w2 * v2.g) * 255.0f; - b = (row_w0 * v0.b + row_w1 * v1.b + row_w2 * v2.b) * 255.0f; - - for (px = row_min_x; px <= row_max_x; px++) { - idx = py * WIDTH + px; - if (inv_w > g_sys->zbuffer[idx] && inv_w >= min_inv_w * 0.99f) { - ir = (int)r; ir = ir > 255 ? 255 : (ir < 0 ? 0 : ir); - ig = (int)g_val; ig = ig > 255 ? 255 : (ig < 0 ? 0 : ig); - ib = (int)b; ib = ib > 255 ? 255 : (ib < 0 ? 0 : ib); - f = f_w / inv_w; - if (f > 1.0f) f = 1.0f; - if (f < 0.0f) f = 0.0f; - inv_f = 1.0f - f; - if (tri->tex == (void *)-1) { - bg = g_sys->pixels[idx]; - wa = (g_sys->cur_weather.water[3] * 100) >> 8; - g_sys->pixels[idx] = (0xFF << 24) | - (((g_sys->cur_weather.water[0] * wa + ((bg >> 16) & 0xFF) * (255 - wa)) >> 8) << 16) | - (((g_sys->cur_weather.water[1] * wa + ((bg >> 8) & 0xFF) * (255 - wa)) >> 8) << 8) | - (((g_sys->cur_weather.water[2] * wa + (bg & 0xFF) * (255 - wa)) >> 8)); - } else { - ir = (uint32_t)(ir * inv_f + sky_r * f); - ig = (uint32_t)(ig * inv_f + sky_g * f); - ib = (uint32_t)(ib * inv_f + sky_b * f); - g_sys->pixels[idx] = (0xFF << 24) | - (ir << 16) | (ig << 8) | ib; - } - g_sys->zbuffer[idx] = inv_w; - } - inv_w += d_inv_w_dx; f_w += d_f_w_dx; - r += d_r_dx * 255.0f; g_val += d_g_dx * 255.0f; b += d_b_dx * 255.0f; - } - } } } @@ -967,36 +866,6 @@ ray_tri_intersect_y(const struct col_triangle *t, float x, float z, float *out_y return (0); } -static inline void -tri_normal(const struct col_triangle *t, float n[3]) -{ - float e1[3], e2[3]; - float len; - - e1[0] = t->v1[0] - t->v0[0]; - e1[1] = t->v1[1] - t->v0[1]; - e1[2] = t->v1[2] - t->v0[2]; - - e2[0] = t->v2[0] - t->v0[0]; - e2[1] = t->v2[1] - t->v0[1]; - e2[2] = t->v2[2] - t->v0[2]; - - n[0] = e1[1] * e2[2] - e1[2] * e2[1]; - n[1] = e1[2] * e2[0] - e1[0] * e2[2]; - n[2] = e1[0] * e2[1] - e1[1] * e2[0]; - - len = sqrtf(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]); - if (len > 1e-6f) { - n[0] /= len; - n[1] /= len; - n[2] /= len; - } else { - n[0] = 0.0f; - n[1] = 1.0f; - n[2] = 0.0f; - } -} - static float get_ground_height(float px, float pz, float cur_y) { @@ -1023,7 +892,7 @@ get_ground_height(float px, float pz, float cur_y) } c = &g_col_grid[cx_idx][cz_idx]; for (i = 0; i < c->count; i++) { - tri_normal(&c->tris[i], norm); + if (c->tris[i].norm[1] < 0.45f) continue; if (norm[1] < 0.45f) { continue; } @@ -1088,7 +957,7 @@ move_and_slide(float *px, float *py, float *pz, float vx, float vz, float dt) c = &g_col_grid[cx_idx][cz_idx]; for (i = 0; i < (int)c->count; i++) { - tri_normal(&c->tris[i], norm); + if (c->tris[i].norm[1] > 0.5f) continue; if (norm[1] > 0.50f) { continue; } @@ -1794,11 +1663,12 @@ ped_lookup_model(int id) } static void -draw_scene(struct sys_gfx *g, const struct mat4 *proj, - const struct mat4 *view, float cam_x, float cam_y, float cam_z, +draw_scene(struct sys_gfx *g, const struct mat4 *proj, const struct mat4 *view, + float cam_x, float cam_y, float cam_z, float player_x, float player_y, float player_z, float player_yaw) { float val, pitch, fov_y, fov_x, far_clp, dx, dy, dz, dist_sq, w, r; + float obj_max_dist; int y_horiz, min_gx, max_gx, min_gz, max_gz, id, x, y, gx, gz, i; uint8_t sr, sg, sb, hr, hg, hb; uint32_t c; @@ -1825,15 +1695,19 @@ draw_scene(struct sys_gfx *g, const struct mat4 *proj, c = (hr << 16) | (hg << 8) | hb; if (y < y_horiz) { float f = (float)y / (float)(y_horiz > 0 ? y_horiz : 1); - c = ((sr + (uint8_t)(f * (hr - sr))) << 16) | ((sg + (uint8_t)(f * (hg - sg))) << 8) | (sb + (uint8_t)(f * (hb - sb))); + c = ((sr + (uint8_t)(f * (hr - sr))) << 16) | + ((sg + (uint8_t)(f * (hg - sg))) << 8) | + (sb + (uint8_t)(f * (hb - sb))); } for (x = 0; x < WIDTH; x++) { g->pixels[y * WIDTH + x] = c; } } + far_clp = g->cur_weather.far_clp; fov_y = tanf(60.0f * 0.5f * 3.14159f / 180.0f); fov_x = fov_y * ((float)WIDTH / HEIGHT); + min_gx = (int)((cam_x - far_clp - MAP_MIN) / ((MAP_MAX - MAP_MIN) / GRID_SZ)); max_gx = (int)((cam_x + far_clp - MAP_MIN) / ((MAP_MAX - MAP_MIN) / GRID_SZ)); min_gz = (int)((cam_z - far_clp - MAP_MIN) / ((MAP_MAX - MAP_MIN) / GRID_SZ)); @@ -1872,10 +1746,21 @@ draw_scene(struct sys_gfx *g, const struct mat4 *proj, dx = g_transforms.sphere_cx[id] - cam_x; dy = g_transforms.sphere_cy[id] - cam_y; dz = g_transforms.sphere_cz[id] - cam_z; - dist_sq = dx*dx + dy*dy + dz*dz; - if (dist_sq > (far_clp + g_transforms.sphere_r[id])*(far_clp + g_transforms.sphere_r[id])) { + dist_sq = dx * dx + dy * dy + dz * dz; + + obj_max_dist = g_transforms.sphere_r[id] * 35.0f; + if (obj_max_dist < 40.0f) { + obj_max_dist = 40.0f; + } + if (obj_max_dist > far_clp) { + obj_max_dist = far_clp; + } + + if (dist_sq > (obj_max_dist + g_transforms.sphere_r[id]) * + (obj_max_dist + g_transforms.sphere_r[id])) { continue; } + if (draw_count >= draw_cap) { draw_cap = draw_cap == 0 ? 1024 : draw_cap * 2; draw_list = realloc(draw_list, draw_cap * sizeof(struct draw_item)); @@ -1899,7 +1784,9 @@ draw_scene(struct sys_gfx *g, const struct mat4 *proj, mc.z = g_transforms.sphere_cz[id]; r = g_transforms.sphere_r[id] * 1.05f; mat_transform(&cv, &w, view, &mc); - if (cv.z + r < 0.1f || cv.z - r > far_clp || fabsf(cv.x) - r > cv.z * fov_x || fabsf(cv.y) - r > cv.z * fov_y) { + if (cv.z + r < 0.1f || cv.z - r > far_clp || + fabsf(cv.x) - r > cv.z * fov_x || + fabsf(cv.y) - r > cv.z * fov_y) { continue; } if (is_occluded(g, cv.x, cv.y, cv.z, r)) { @@ -1911,9 +1798,13 @@ draw_scene(struct sys_gfx *g, const struct mat4 *proj, } if (active_skin_id >= 0) { - const char *skin_model_name = ped_lookup_model(active_skin_id); + const char *skin_model_name; + + skin_model_name = ped_lookup_model(active_skin_id); if (skin_model_name) { - struct mesh *skin_mesh = cache_get_mesh(g_cache, skin_model_name); + struct mesh *skin_mesh; + + skin_mesh = cache_get_mesh(g_cache, skin_model_name); if (skin_mesh && skin_mesh->ply_verts) { struct mat4 rot_y, trans, world; @@ -1940,7 +1831,7 @@ static void update_weather(struct sys_gfx *g) { float t, snaps[8] = {0.0f, 5.0f, 6.0f, 7.0f, 12.0f, 19.0f, 20.0f, 22.0f}; - int i0, i1; + int i0, i1, i; float f; struct timecyc_entry *w0, *w1; @@ -1961,11 +1852,11 @@ update_weather(struct sys_gfx *g) } f = (wt - snaps[7]) / (24.0f - snaps[7] + snaps[0]); } else { - for (int i = 0; i < 7; i++) { - if (t >= snaps[i] && t < snaps[i+1]) { + for (i = 0; i < 7; i++) { + if (t >= snaps[i] && t < snaps[i + 1]) { i0 = i; i1 = i + 1; - f = (t - snaps[i]) / (snaps[i+1] - snaps[i]); + f = (t - snaps[i]) / (snaps[i + 1] - snaps[i]); break; } } @@ -1973,11 +1864,17 @@ update_weather(struct sys_gfx *g) w0 = &g->weathers[g->game_weather][i0]; w1 = &g->weathers[g->game_weather][i1]; #define LERP(c) g->cur_weather.c = w0->c + f * (w1->c - w0->c) - LERP(amb[0]); LERP(amb[1]); LERP(amb[2]); LERP(sky_top[0]); LERP(sky_top[1]); LERP(sky_top[2]); LERP(sky_bot[0]); LERP(sky_bot[1]); LERP(sky_bot[2]); - LERP(water[0]); LERP(water[1]); LERP(water[2]); LERP(water[3]); LERP(far_clp); LERP(fog_st); + LERP(amb[0]); LERP(amb[1]); LERP(amb[2]); + LERP(sky_top[0]); LERP(sky_top[1]); LERP(sky_top[2]); + LERP(sky_bot[0]); LERP(sky_bot[1]); LERP(sky_bot[2]); + LERP(water[0]); LERP(water[1]); LERP(water[2]); LERP(water[3]); + LERP(far_clp); LERP(fog_st); #undef LERP + if (g->far_clip_override > 10.0f) { g->cur_weather.far_clp = g->far_clip_override; + } else if (g->cur_weather.far_clp > 220.0f) { + g->cur_weather.far_clp = 220.0f; } }