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:
| M | src/build.c | | | 28 | +++++++++++++++++++++++++++- |
| M | src/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;
}
}