From d36bd20e6a3151401fc45ff4af5ccd39ba29ec99 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Wed, 23 Mar 2011 02:52:19 -0400 Subject: [PATCH] fixed lighting for half-step blocks --- src/rendermode-lighting.c | 51 ++++++++++++++++++++++++++++++++++----- src/rendermode-spawn.c | 4 +-- src/rendermodes.h | 3 ++- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/src/rendermode-lighting.c b/src/rendermode-lighting.c index a8f2bc2..e9b5aae 100644 --- a/src/rendermode-lighting.c +++ b/src/rendermode-lighting.c @@ -25,16 +25,28 @@ static float calculate_darkness(unsigned char skylight, unsigned char blocklight } /* loads the appropriate light data for the given (possibly non-local) - coordinates, and returns a black_coeff - this is exposed, so other (derived) rendermodes can use it */ + * coordinates, and returns a black_coeff this is exposed, so other (derived) + * rendermodes can use it + * + * authoratative is a return slot for whether or not this lighting calculation + * is true, or a guess. If we guessed, *authoratative will be false, but if it + * was calculated correctly from available light data, it will be true. You + * may (and probably should) pass NULL. + */ inline float -get_lighting_coefficient(RenderModeLighting *self, RenderState *state, int x, int y, int z) { +get_lighting_coefficient(RenderModeLighting *self, RenderState *state, + int x, int y, int z, int *authoratative) { + /* placeholders for later data arrays, coordinates */ PyObject *blocks = NULL; PyObject *skylight = NULL; PyObject *blocklight = NULL; int local_x = x, local_y = y, local_z = z; + /* defaults to "guess" until told otherwise */ + if (authoratative) + *authoratative = 0; + /* find out what chunk we're in, and translate accordingly */ if (x >= 0 && y < 16) { blocks = state->blocks; @@ -76,8 +88,31 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state, int x, in return self->calculate_darkness(15, 0); } - if (block == 44) { - /* TODO special handling for half-blocks! */ + /* only do special half-step handling if no authoratative pointer was + passed in, which is a sign that we're recursing */ + if (block == 44 && authoratative == NULL) { + float average_gather = 0.0f; + unsigned int average_count = 0; + int auth; + float coeff; + + /* iterate through all surrounding blocks to take an average */ + int dx, dy, dz; + for (dx = -1; dx <= 1; dx += 2) { + for (dy = -1; dy <= 1; dy += 2) { + for (dz = -1; dz <= 1; dz += 2) { + coeff = get_lighting_coefficient(self, state, x+dx, y+dy, z+dz, &auth); + if (auth) { + average_gather += coeff; + average_count++; + } + } + } + } + + /* only return the average if at least one was authoratative */ + if (average_count > 0) + return average_gather / average_count; } if (block == 10 || block == 11) { @@ -88,6 +123,10 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state, int x, in unsigned char skylevel = getArrayByte3D(skylight, local_x, local_y, local_z); unsigned char blocklevel = getArrayByte3D(blocklight, local_x, local_y, local_z); + /* no longer a guess */ + if (authoratative) + *authoratative = 1; + return self->calculate_darkness(skylevel, blocklevel); } @@ -105,7 +144,7 @@ do_shading_for_face(RenderModeLighting *self, RenderState *state, } } - float black_coeff = get_lighting_coefficient(self, state, x, y, z); + float black_coeff = get_lighting_coefficient(self, state, x, y, z, NULL); PyObject *mask = PyObject_CallMethod(facemask, "copy", NULL); // new ref brightness(mask, black_coeff); diff --git a/src/rendermode-spawn.c b/src/rendermode-spawn.c index 08e26de..aa7a8c6 100644 --- a/src/rendermode-spawn.c +++ b/src/rendermode-spawn.c @@ -67,9 +67,9 @@ rendermode_spawn_draw(void *data, RenderState *state, PyObject *src, PyObject *m this block for transparents, the block above for non-transparent */ float darkness = 0.0; if (is_transparent(state->block)) { - darkness = get_lighting_coefficient((RenderModeLighting *)self, state, x, y, z); + darkness = get_lighting_coefficient((RenderModeLighting *)self, state, x, y, z, NULL); } else { - darkness = get_lighting_coefficient((RenderModeLighting *)self, state, x, y, z+1); + darkness = get_lighting_coefficient((RenderModeLighting *)self, state, x, y, z+1, NULL); } /* if it's dark enough... */ diff --git a/src/rendermodes.h b/src/rendermodes.h index c8916e0..da94343 100644 --- a/src/rendermodes.h +++ b/src/rendermodes.h @@ -82,7 +82,8 @@ typedef struct { float (*calculate_darkness)(unsigned char, unsigned char); } RenderModeLighting; extern RenderModeInterface rendermode_lighting; -inline float get_lighting_coefficient(RenderModeLighting *self, RenderState *state, int x, int y, int z); +inline float get_lighting_coefficient(RenderModeLighting *self, RenderState *state, + int x, int y, int z, int *authoratative); /* NIGHT */ typedef struct {