Move the average lighting coeff to another function. Take the average over blockmap.
Fixes problems with stairs in night and lighting rendermode.
This commit is contained in:
@@ -33,21 +33,106 @@ static float calculate_darkness(unsigned char skylight, unsigned char blocklight
|
||||
* was calculated correctly from available light data, it will be true. You
|
||||
* may (and probably should) pass NULL.
|
||||
*/
|
||||
|
||||
inline unsigned char
|
||||
estimate_blocklevel(RenderModeLighting *self, RenderState *state,
|
||||
int x, int y, int z, int *authoratative) {
|
||||
|
||||
/* placeholders for later data arrays, coordinates */
|
||||
PyObject *blocks = NULL;
|
||||
PyObject *blocklight = NULL;
|
||||
int local_x = x, local_y = y, local_z = z;
|
||||
unsigned char block, blocklevel;
|
||||
unsigned int average_count = 0, average_gather = 0, coeff = 0;
|
||||
|
||||
/* 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;
|
||||
blocklight = self->blocklight;
|
||||
} else if (x < 0) {
|
||||
local_x += 16;
|
||||
blocks = state->left_blocks;
|
||||
blocklight = self->left_blocklight;
|
||||
} else if (y >= 16) {
|
||||
local_y -= 16;
|
||||
blocks = state->right_blocks;
|
||||
blocklight = self->right_blocklight;
|
||||
}
|
||||
|
||||
/* make sure we have correctly-ranged coordinates */
|
||||
if (!(local_x >= 0 && local_x < 16 &&
|
||||
local_y >= 0 && local_y < 16 &&
|
||||
local_z >= 0 && local_z < 128)) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* also, make sure we have enough info to correctly calculate lighting */
|
||||
if (blocks == Py_None || blocks == NULL ||
|
||||
blocklight == Py_None || blocklight == NULL) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
block = getArrayByte3D(blocks, local_x, local_y, local_z);
|
||||
|
||||
if (authoratative == NULL) {
|
||||
int auth;
|
||||
|
||||
/* iterate through all surrounding blocks to take an average */
|
||||
int dx, dy, dz, local_block;
|
||||
//~ printf("\n[Starting loop]\n");
|
||||
for (dx = -1; dx <= 1; dx += 2) {
|
||||
for (dy = -1; dy <= 1; dy += 2) {
|
||||
for (dz = -1; dz <= 1; dz += 2) {
|
||||
coeff = estimate_blocklevel(self, state, x+dx, y+dy, z+dz, &auth);
|
||||
local_block = getArrayByte3D(blocks, x+dx, y+dy, z+dz);
|
||||
if (auth && is_transparent(local_block)) {
|
||||
average_gather += coeff;
|
||||
average_count++;
|
||||
}
|
||||
//~ printf(" [Inside the loop] Coeff = %d, average_gather = %d, average_count = %d, auth = %d, block = %d\n", coeff, average_gather, average_count, auth, local_block);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* only return the average if at least one was authoratative */
|
||||
if (average_count > 0) {
|
||||
int result;
|
||||
float resultf;
|
||||
result = average_gather / average_count;
|
||||
resultf = average_gather / average_count;
|
||||
//~ printf("[Outside the loop] average_gather = %d, average_count = %d\n", average_gather, average_count);
|
||||
//~ printf("[Outside the loop] result = %d, resultf = %f\n", result, resultf);
|
||||
return average_gather / average_count;
|
||||
}
|
||||
|
||||
blocklevel = getArrayByte3D(blocklight, local_x, local_y, local_z);
|
||||
|
||||
/* no longer a guess */
|
||||
if (!(block == 44 || block == 53 || block == 67) && authoratative) {
|
||||
*authoratative = 1;
|
||||
}
|
||||
|
||||
return blocklevel;
|
||||
}
|
||||
|
||||
inline float
|
||||
get_lighting_coefficient(RenderModeLighting *self, RenderState *state,
|
||||
int x, int y, int z, int *authoratative) {
|
||||
|
||||
int x, int y, int z) {
|
||||
|
||||
/* 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;
|
||||
unsigned char block, skylevel, blocklevel;
|
||||
|
||||
/* 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;
|
||||
@@ -64,7 +149,7 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state,
|
||||
skylight = self->right_skylight;
|
||||
blocklight = self->right_blocklight;
|
||||
}
|
||||
|
||||
|
||||
/* make sure we have correctly-ranged coordinates */
|
||||
if (!(local_x >= 0 && local_x < 16 &&
|
||||
local_y >= 0 && local_y < 16 &&
|
||||
@@ -72,7 +157,7 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state,
|
||||
|
||||
return self->calculate_darkness(15, 0);
|
||||
}
|
||||
|
||||
|
||||
/* also, make sure we have enough info to correctly calculate lighting */
|
||||
if (blocks == Py_None || blocks == NULL ||
|
||||
skylight == Py_None || skylight == NULL ||
|
||||
@@ -89,13 +174,16 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state,
|
||||
return self->calculate_darkness(15, 0);
|
||||
}
|
||||
|
||||
skylevel = getArrayByte3D(skylight, local_x, local_y, local_z);
|
||||
blocklevel = getArrayByte3D(blocklight, local_x, local_y, local_z);
|
||||
//~ if (block == 0 && blocklevel != 0) {
|
||||
//~ printf("Para este aire tenemos skylevel %d, blocklevel %d\n", skylevel, blocklevel);
|
||||
//~ }
|
||||
|
||||
/* only do special half-step handling if no authoratative pointer was
|
||||
passed in, which is a sign that we're recursing */
|
||||
if ((block == 44 || block == 53 || block == 67) && authoratative == NULL) {
|
||||
float average_gather = 0.0f;
|
||||
unsigned int average_count = 0, upper_block;
|
||||
int auth;
|
||||
float coeff;
|
||||
if (block == 44 || block == 53 || block == 67) {
|
||||
unsigned int upper_block;
|
||||
|
||||
if (local_z != 127) { /* stairs and half-blocks take the skylevel from the upper block if it's transparent */
|
||||
upper_block = getArrayByte3D(blocks, local_x, local_y, local_z + 1);
|
||||
@@ -108,29 +196,10 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state,
|
||||
skylevel = 15;
|
||||
blocklevel = getArrayByte3D(blocklight, local_x, local_y, local_z);
|
||||
}
|
||||
|
||||
/* use given coordinates, no local ones! */
|
||||
blocklevel = estimate_blocklevel(self, state, x, y, z, NULL);
|
||||
|
||||
if (skylevel) { /* if we have a good skylevel use it, if not iterate */
|
||||
return self->calculate_darkness(skylevel, blocklevel);
|
||||
} else {
|
||||
|
||||
/* 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) {
|
||||
@@ -138,13 +207,6 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state,
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
skylevel = getArrayByte3D(skylight, local_x, local_y, local_z);
|
||||
blocklevel = getArrayByte3D(blocklight, local_x, local_y, local_z);
|
||||
|
||||
/* no longer a guess */
|
||||
if (authoratative)
|
||||
*authoratative = 1;
|
||||
|
||||
return self->calculate_darkness(skylevel, blocklevel);
|
||||
}
|
||||
|
||||
@@ -164,7 +226,7 @@ do_shading_with_mask(RenderModeLighting *self, RenderState *state,
|
||||
}
|
||||
}
|
||||
|
||||
black_coeff = get_lighting_coefficient(self, state, x, y, z, NULL);
|
||||
black_coeff = get_lighting_coefficient(self, state, x, y, z);
|
||||
alpha_over_full(state->img, self->black_color, mask, black_coeff, state->imgx, state->imgy, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ typedef struct {
|
||||
} RenderModeLighting;
|
||||
extern RenderModeInterface rendermode_lighting;
|
||||
inline float get_lighting_coefficient(RenderModeLighting *self, RenderState *state,
|
||||
int x, int y, int z, int *authoratative);
|
||||
int x, int y, int z);
|
||||
|
||||
/* NIGHT */
|
||||
typedef struct {
|
||||
|
||||
Reference in New Issue
Block a user