0

changed material property lookups to use a bit table, not python sets

This commit is contained in:
Aaron Griffith
2011-11-11 16:07:10 -05:00
parent afd3ad639b
commit 944edf4ef8
5 changed files with 73 additions and 51 deletions

View File

@@ -20,14 +20,21 @@
static PyObject *textures = NULL; static PyObject *textures = NULL;
static PyObject *chunk_mod = NULL; static PyObject *chunk_mod = NULL;
static PyObject *blockmap = NULL; static PyObject *blockmap = NULL;
unsigned int max_blockid = 0;
unsigned int max_data = 0;
unsigned char *block_properties = NULL;
static PyObject *known_blocks = NULL; static PyObject *known_blocks = NULL;
static PyObject *transparent_blocks = NULL; static PyObject *transparent_blocks = NULL;
static unsigned int max_blockid = 0; static PyObject *solid_blocks = NULL;
static unsigned int max_data = 0; static PyObject *fluid_blocks = NULL;
static PyObject *nospawn_blocks = NULL;
PyObject *init_chunk_render(PyObject *self, PyObject *args) { PyObject *init_chunk_render(PyObject *self, PyObject *args) {
PyObject *tmp = NULL; PyObject *tmp = NULL;
unsigned int i;
/* this function only needs to be called once, anything more should be /* this function only needs to be called once, anything more should be
* ignored */ * ignored */
@@ -50,12 +57,6 @@ PyObject *init_chunk_render(PyObject *self, PyObject *args) {
blockmap = PyObject_GetAttrString(textures, "blockmap"); blockmap = PyObject_GetAttrString(textures, "blockmap");
if (!blockmap) if (!blockmap)
return NULL; return NULL;
known_blocks = PyObject_GetAttrString(textures, "known_blocks");
if (!known_blocks)
return NULL;
transparent_blocks = PyObject_GetAttrString(textures, "transparent_blocks");
if (!transparent_blocks)
return NULL;
tmp = PyObject_GetAttrString(textures, "max_blockid"); tmp = PyObject_GetAttrString(textures, "max_blockid");
if (!tmp) if (!tmp)
@@ -66,23 +67,44 @@ PyObject *init_chunk_render(PyObject *self, PyObject *args) {
return NULL; return NULL;
max_data = PyInt_AsLong(tmp); max_data = PyInt_AsLong(tmp);
/* assemble the property table */
known_blocks = PyObject_GetAttrString(textures, "known_blocks");
if (!known_blocks)
return NULL;
transparent_blocks = PyObject_GetAttrString(textures, "transparent_blocks");
if (!transparent_blocks)
return NULL;
solid_blocks = PyObject_GetAttrString(textures, "solid_blocks");
if (!solid_blocks)
return NULL;
fluid_blocks = PyObject_GetAttrString(textures, "fluid_blocks");
if (!fluid_blocks)
return NULL;
nospawn_blocks = PyObject_GetAttrString(textures, "nospawn_blocks");
if (!nospawn_blocks)
return NULL;
block_properties = calloc(max_blockid, sizeof(unsigned char));
for (i = 0; i < max_blockid; i++) {
PyObject *block = PyInt_FromLong(i);
if (PySequence_Contains(known_blocks, block))
block_properties[i] |= 1 << KNOWN;
if (PySequence_Contains(transparent_blocks, block))
block_properties[i] |= 1 << TRANSPARENT;
if (PySequence_Contains(solid_blocks, block))
block_properties[i] |= 1 << SOLID;
if (PySequence_Contains(fluid_blocks, block))
block_properties[i] |= 1 << FLUID;
if (PySequence_Contains(nospawn_blocks, block))
block_properties[i] |= 1 << NOSPAWN;
Py_DECREF(block);
}
Py_RETURN_NONE; Py_RETURN_NONE;
} }
int
is_transparent(unsigned char b) {
PyObject *block = PyInt_FromLong(b);
int ret = PySequence_Contains(transparent_blocks, block);
if (!ret)
{
ret = !(PySequence_Contains(known_blocks, block));
}
Py_DECREF(block);
return ret;
}
unsigned char unsigned char
check_adjacent_blocks(RenderState *state, int x,int y,int z, unsigned char blockid) { check_adjacent_blocks(RenderState *state, int x,int y,int z, unsigned char blockid) {
/* /*

View File

@@ -86,8 +86,32 @@ typedef struct {
PyObject *right_blocks; PyObject *right_blocks;
} RenderState; } RenderState;
PyObject *init_chunk_render(PyObject *self, PyObject *args); PyObject *init_chunk_render(PyObject *self, PyObject *args);
int is_transparent(unsigned char b);
PyObject *chunk_render(PyObject *self, PyObject *args); PyObject *chunk_render(PyObject *self, PyObject *args);
typedef enum
{
KNOWN,
TRANSPARENT,
SOLID,
FLUID,
NOSPAWN,
} BlockProperty;
/* globals set in init_chunk_render, here because they're used
in block_has_property */
extern unsigned int max_blockid;
extern unsigned int max_data;
extern unsigned char *block_properties;
static inline int
block_has_property(unsigned char b, BlockProperty prop) {
if (b >= max_blockid || !(block_properties[b] & (1 << KNOWN))) {
/* block is unknown, return defaults */
if (prop == TRANSPARENT)
return 1;
return 0;
}
return block_properties[b] & (1 << prop);
}
#define is_transparent(b) block_has_property((b), TRANSPARENT)
/* pull in the rendermode info */ /* pull in the rendermode info */
#include "rendermodes.h" #include "rendermodes.h"

View File

@@ -37,10 +37,6 @@ rendermode_overlay_start(void *data, RenderState *state, PyObject *options) {
Py_DECREF(facemasks_py); Py_DECREF(facemasks_py);
self->white_color = PyObject_GetAttrString(state->chunk, "white_color"); self->white_color = PyObject_GetAttrString(state->chunk, "white_color");
self->solid_blocks = PyObject_GetAttrString(state->textures, "solid_blocks");
self->fluid_blocks = PyObject_GetAttrString(state->textures, "fluid_blocks");
self->get_color = get_color; self->get_color = get_color;
return 0; return 0;
@@ -52,8 +48,6 @@ rendermode_overlay_finish(void *data, RenderState *state) {
Py_DECREF(self->facemask_top); Py_DECREF(self->facemask_top);
Py_DECREF(self->white_color); Py_DECREF(self->white_color);
Py_DECREF(self->solid_blocks);
Py_DECREF(self->fluid_blocks);
} }
static int static int
@@ -81,7 +75,6 @@ static void
rendermode_overlay_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { rendermode_overlay_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) {
RenderModeOverlay *self = (RenderModeOverlay *)data; RenderModeOverlay *self = (RenderModeOverlay *)data;
unsigned char r, g, b, a; unsigned char r, g, b, a;
PyObject *top_block_py, *block_py;
// exactly analogous to edge-line code for these special blocks // exactly analogous to edge-line code for these special blocks
int increment=0; int increment=0;
@@ -101,27 +94,19 @@ rendermode_overlay_draw(void *data, RenderState *state, PyObject *src, PyObject
} }
/* check to be sure this block is solid/fluid */ /* check to be sure this block is solid/fluid */
top_block_py = PyInt_FromLong(top_block); if (block_has_property(top_block, SOLID) || block_has_property(top_block, FLUID)) {
if (PySequence_Contains(self->solid_blocks, top_block_py) ||
PySequence_Contains(self->fluid_blocks, top_block_py)) {
/* top block is fluid or solid, skip drawing */ /* top block is fluid or solid, skip drawing */
Py_DECREF(top_block_py);
return; return;
} }
Py_DECREF(top_block_py);
} }
/* check to be sure this block is solid/fluid */ /* check to be sure this block is solid/fluid */
block_py = PyInt_FromLong(state->block); if (!block_has_property(state->block, SOLID) && !block_has_property(state->block, FLUID)) {
if (!PySequence_Contains(self->solid_blocks, block_py) &&
!PySequence_Contains(self->fluid_blocks, block_py)) {
/* not fluid or solid, skip drawing the overlay */ /* not fluid or solid, skip drawing the overlay */
Py_DECREF(block_py);
return; return;
} }
Py_DECREF(block_py);
/* get our color info */ /* get our color info */
self->get_color(data, state, &r, &g, &b, &a); self->get_color(data, state, &r, &g, &b, &a);

View File

@@ -35,13 +35,10 @@ static void get_color(void *data, RenderState *state,
/* default to no overlay, until told otherwise */ /* default to no overlay, until told otherwise */
*a = 0; *a = 0;
block_py = PyInt_FromLong(state->block); if (block_has_property(state->block, NOSPAWN)) {
if (PySequence_Contains(self->nospawn_blocks, block_py)) {
/* nothing can spawn on this */ /* nothing can spawn on this */
Py_DECREF(block_py);
return; return;
} }
Py_DECREF(block_py);
blocklight = getArrayByte3D(self->blocklight, x, y, MIN(127, z_light)); blocklight = getArrayByte3D(self->blocklight, x, y, MIN(127, z_light));
@@ -72,7 +69,6 @@ rendermode_spawn_start(void *data, RenderState *state, PyObject *options) {
/* now do custom initializations */ /* now do custom initializations */
self = (RenderModeSpawn *)data; self = (RenderModeSpawn *)data;
self->nospawn_blocks = PyObject_GetAttrString(state->textures, "nospawn_blocks");
self->blocklight = PyObject_GetAttrString(state->self, "blocklight"); self->blocklight = PyObject_GetAttrString(state->self, "blocklight");
self->skylight = PyObject_GetAttrString(state->self, "skylight"); self->skylight = PyObject_GetAttrString(state->self, "skylight");
@@ -87,7 +83,6 @@ rendermode_spawn_finish(void *data, RenderState *state) {
/* first free all *our* stuff */ /* first free all *our* stuff */
RenderModeSpawn* self = (RenderModeSpawn *)data; RenderModeSpawn* self = (RenderModeSpawn *)data;
Py_DECREF(self->nospawn_blocks);
Py_DECREF(self->blocklight); Py_DECREF(self->blocklight);
Py_DECREF(self->skylight); Py_DECREF(self->skylight);

View File

@@ -143,8 +143,6 @@ extern RenderModeInterface rendermode_normal;
typedef struct { typedef struct {
/* top facemask and white color image, for drawing overlays */ /* top facemask and white color image, for drawing overlays */
PyObject *facemask_top, *white_color; PyObject *facemask_top, *white_color;
/* only show overlay on top of solid or fluid blocks */
PyObject *solid_blocks, *fluid_blocks;
/* can be overridden in derived classes to control /* can be overridden in derived classes to control
overlay alpha and color overlay alpha and color
last four vars are r, g, b, a out */ last four vars are r, g, b, a out */
@@ -195,8 +193,6 @@ typedef struct {
/* inherits from overlay */ /* inherits from overlay */
RenderModeOverlay parent; RenderModeOverlay parent;
/* used to figure out which blocks are spawnable */
PyObject *nospawn_blocks;
PyObject *skylight, *blocklight; PyObject *skylight, *blocklight;
} RenderModeSpawn; } RenderModeSpawn;
extern RenderModeInterface rendermode_spawn; extern RenderModeInterface rendermode_spawn;