Ejemplo n.º 1
0
inline unsigned char
estimate_blocklevel(RenderPrimitiveLighting *self, RenderState *state,
                         int x, int y, int z, int *authoratative) {

    /* placeholders for later data arrays, coordinates */
    unsigned char block, blocklevel;
    unsigned int average_count = 0, average_gather = 0, coeff = 0;

    /* defaults to "guess" until told otherwise */
    if (authoratative)
        *authoratative = 0;
    
    block = get_data(state, BLOCKS, x, y, z);
    
    if (authoratative == NULL) {
        int auth;
        
        /* iterate through all surrounding blocks to take an average */
        int dx, dy, dz, local_block;
        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 = get_data(state, BLOCKS, x+dx, y+dy, z+dz);
                    /* only add if the block is transparent, this seems to look better than
                       using every block */
                    if (auth && is_transparent(local_block)) {
                        average_gather += coeff;
                        average_count++;
                    }
                }
            }
        }
    }
    
    /* only return the average if at least one was authoratative */
    if (average_count > 0) {
        return average_gather / average_count;
    }
    
    blocklevel = get_data(state, BLOCKLIGHT, x, y, z);
    
    /* no longer a guess */
    if (!(block == 44 || block == 53 || block == 67 || block == 108 || block == 109) && authoratative) {
        *authoratative = 1;
    }
    
    return blocklevel;
}
Ejemplo n.º 2
0
inline void
get_lighting_color(RenderPrimitiveLighting *self, RenderState *state,
                   int x, int y, int z,
                   unsigned char *r, unsigned char *g, unsigned char *b) {

    /* placeholders for later data arrays, coordinates */
    unsigned char block, skylevel, blocklevel;
    
    block = get_data(state, BLOCKS, x, y, z);
    skylevel = get_data(state, SKYLIGHT, x, y, z);
    blocklevel = get_data(state, BLOCKLIGHT, x, y, z);

    /* special half-step handling, stairs handling */
    /* Anvil also needs to be here, blockid 145 */
    if (block == 44 || block == 53 || block == 67 || block == 108 || block == 109 || block == 114 ||
        block == 128 || block == 134 || block == 135 || block == 136 || block == 145 || block == 156) {
        unsigned int upper_block;
        
        /* stairs and half-blocks take the skylevel from the upper block if it's transparent */
        int upper_counter = 0;
        /* but if the upper_block is one of these special half-steps, we need to look at *its* upper_block */
        do {
            upper_counter++; 
            upper_block = get_data(state, BLOCKS, x, y + upper_counter, z);
        } while (upper_block == 44 || upper_block == 53 || upper_block == 67 || upper_block == 108 ||
                 upper_block == 109 || upper_block == 114 || upper_block == 128 || upper_block == 134 ||
                 upper_block == 135 || upper_block == 136 || upper_block == 156 );
        if (is_transparent(upper_block)) {
            skylevel = get_data(state, SKYLIGHT, x, y + upper_counter, z);
        } else {
            skylevel = 15;
        }
        
        /* the block has a bad blocklevel, estimate it from neigborhood
         * use given coordinates, no local ones! */
        blocklevel = estimate_blocklevel(self, state, x, y, z, NULL);

    }
    
    if (block == 10 || block == 11) {
        /* lava blocks should always be lit! */
        *r = 255;
        *g = 255;
        *b = 255;
        return;
    }
    
    self->calculate_light_color(self, MIN(skylevel, 15), MIN(blocklevel, 15), r, g, b);
}
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;
        for (dx = -1; dx <= 1; dx += 2) {
            for (dy = -1; dy <= 1; dy += 2) {
                for (dz = -1; dz <= 1; dz += 2) {
                    
                    /* skip if block is out of range */
                    if (x+dx < 0 || x+dx >= 16 ||
                        y+dy < 0 || y+dy >= 16 ||
                        z+dz < 0 || z+dz >= 128) {
                        continue;
                    }

                    coeff = estimate_blocklevel(self, state, x+dx, y+dy, z+dz, &auth);
                    local_block = getArrayByte3D(blocks, x+dx, y+dy, z+dz);
                    /* only add if the block is transparent, this seems to look better than
                       using every block */
                    if (auth && is_transparent(local_block)) {
                        average_gather += coeff;
                        average_count++;
                    }
                }
            }
        }
    }
    
    /* only return the average if at least one was authoratative */
    if (average_count > 0) {
        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) {

    /* 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;

    /* find out what chunk we're in, and translate accordingly */
    if (x >= 0 && y < 16) {
        blocks = state->blocks;
        skylight = self->skylight;
        blocklight = self->blocklight;
    } else if (x < 0) {
        local_x += 16;        
        blocks = state->left_blocks;
        skylight = self->left_skylight;
        blocklight = self->left_blocklight;
    } else if (y >= 16) {
        local_y -= 16;
        blocks = state->right_blocks;
        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 &&
          local_z >= 0 && local_z < 128)) {
        
        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 ||
        blocklight == Py_None || blocklight == NULL) {
        
        return self->calculate_darkness(15, 0);
    }
    
    block = getArrayByte3D(blocks, local_x, local_y, local_z);
    
    /* if this block is opaque, use a fully-lit coeff instead
       to prevent stippled lines along chunk boundaries! */
    if (!is_transparent(block)) {
        return self->calculate_darkness(15, 0);
    }
    
    skylevel = getArrayByte3D(skylight, local_x, local_y, local_z);
    blocklevel = getArrayByte3D(blocklight, local_x, local_y, local_z);

    /* special half-step handling */
    if (block == 44 || block == 53 || block == 67) {
        unsigned int upper_block;
        
        /* stairs and half-blocks take the skylevel from the upper block if it's transparent */
        if (local_z != 127) {
            int upper_counter = 0;
            /* but if the upper_block is one of these special half-steps, we need to look at *its* upper_block */
            do {
                upper_counter++; 
                upper_block = getArrayByte3D(blocks, local_x, local_y, local_z + upper_counter);
            } while ((upper_block == 44 || upper_block == 54 || upper_block == 67) && local_z < 127);
            if (is_transparent(upper_block)) {
                skylevel = getArrayByte3D(skylight, local_x, local_y, local_z + upper_counter);
            }
        } else {
            upper_block = 0;
            skylevel = 15;
        }
        
        /* the block has a bad blocklevel, estimate it from neigborhood
         * use given coordinates, no local ones! */
        blocklevel = estimate_blocklevel(self, state, x, y, z, NULL);

    }
    
    if (block == 10 || block == 11) {
        /* lava blocks should always be lit! */
        return 0.0f;
    }
    
    return self->calculate_darkness(skylevel, blocklevel);
}