Merge pull request #1541 from Wunkolo/block_class
Add block_class to accelerate block-conditionals
This commit is contained in:
184
overviewer_core/src/block_class.c
Normal file
184
overviewer_core/src/block_class.c
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Minecraft Overviewer.
|
||||||
|
*
|
||||||
|
* Minecraft Overviewer is free software: you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* Minecraft Overviewer is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "block_class.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
|
#include <immintrin.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool block_class_is_subset(
|
||||||
|
mc_block_t block,
|
||||||
|
const mc_block_t block_class[],
|
||||||
|
size_t block_class_len
|
||||||
|
) {
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
#ifdef __SSE2__
|
||||||
|
for (; i / 8 < block_class_len / 8; i += 8) {
|
||||||
|
const __m128i block_class_vec = _mm_loadu_si128(
|
||||||
|
(__m128i*)&block_class[i]
|
||||||
|
);
|
||||||
|
const __m128i block_vec = _mm_set1_epi16(block);
|
||||||
|
const __m128i block_cmp = _mm_cmpeq_epi16(block_vec,block_class_vec);
|
||||||
|
if (_mm_movemask_epi8(block_cmp)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __MMX__
|
||||||
|
for (; i / 4 < block_class_len / 4; i += 4) {
|
||||||
|
const __m64 block_class_vec = _mm_cvtsi64_m64(
|
||||||
|
*(uint64_t*)&block_class[i]
|
||||||
|
);
|
||||||
|
const __m64 block_vec = _mm_set1_pi16(block);
|
||||||
|
const __m64 block_cmp = _mm_cmpeq_pi16(block_vec,block_class_vec);
|
||||||
|
if (_mm_cvtm64_si64(block_cmp)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
for (; i < block_class_len; ++i) {
|
||||||
|
if (block == block_class[i]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const mc_block_t block_class_stair[] = {
|
||||||
|
block_oak_stairs,
|
||||||
|
block_stone_stairs,
|
||||||
|
block_brick_stairs,
|
||||||
|
block_stone_brick_stairs,
|
||||||
|
block_nether_brick_stairs,
|
||||||
|
block_sandstone_stairs,
|
||||||
|
block_spruce_stairs,
|
||||||
|
block_birch_stairs,
|
||||||
|
block_jungle_stairs,
|
||||||
|
block_quartz_stairs,
|
||||||
|
block_acacia_stairs,
|
||||||
|
block_dark_oak_stairs,
|
||||||
|
block_red_sandstone_stairs,
|
||||||
|
block_purpur_stairs
|
||||||
|
};
|
||||||
|
const size_t block_class_stair_len = COUNT_OF(block_class_stair);
|
||||||
|
|
||||||
|
const mc_block_t block_class_door[] = {
|
||||||
|
block_wooden_door,
|
||||||
|
block_iron_door,
|
||||||
|
block_spruce_door,
|
||||||
|
block_birch_door,
|
||||||
|
block_jungle_door,
|
||||||
|
block_acacia_door,
|
||||||
|
block_dark_oak_door
|
||||||
|
};
|
||||||
|
const size_t block_class_door_len = COUNT_OF(block_class_door);
|
||||||
|
|
||||||
|
const mc_block_t block_class_fence[] = {
|
||||||
|
block_fence,
|
||||||
|
block_nether_brick_fence,
|
||||||
|
block_spruce_fence,
|
||||||
|
block_birch_fence,
|
||||||
|
block_jungle_fence,
|
||||||
|
block_dark_oak_fence,
|
||||||
|
block_acacia_fence
|
||||||
|
};
|
||||||
|
const size_t block_class_fence_len = COUNT_OF(block_class_fence);
|
||||||
|
|
||||||
|
const mc_block_t block_class_fence_gate[] = {
|
||||||
|
block_fence_gate,
|
||||||
|
block_spruce_fence_gate,
|
||||||
|
block_birch_fence_gate,
|
||||||
|
block_jungle_fence_gate,
|
||||||
|
block_dark_oak_fence_gate,
|
||||||
|
block_acacia_fence_gate
|
||||||
|
};
|
||||||
|
const size_t block_class_fence_gate_len = COUNT_OF(block_class_fence_gate);
|
||||||
|
|
||||||
|
const mc_block_t block_class_ancil[] = {
|
||||||
|
block_wooden_door,
|
||||||
|
block_iron_door,
|
||||||
|
block_spruce_door,
|
||||||
|
block_birch_door,
|
||||||
|
block_jungle_door,
|
||||||
|
block_acacia_door,
|
||||||
|
block_dark_oak_door,
|
||||||
|
block_oak_stairs,
|
||||||
|
block_stone_stairs,
|
||||||
|
block_brick_stairs,
|
||||||
|
block_stone_brick_stairs,
|
||||||
|
block_nether_brick_stairs,
|
||||||
|
block_sandstone_stairs,
|
||||||
|
block_spruce_stairs,
|
||||||
|
block_birch_stairs,
|
||||||
|
block_jungle_stairs,
|
||||||
|
block_quartz_stairs,
|
||||||
|
block_acacia_stairs,
|
||||||
|
block_dark_oak_stairs,
|
||||||
|
block_red_sandstone_stairs,
|
||||||
|
block_purpur_stairs,
|
||||||
|
block_grass,
|
||||||
|
block_flowing_water,
|
||||||
|
block_water,
|
||||||
|
block_glass,
|
||||||
|
block_chest,
|
||||||
|
block_redstone_wire,
|
||||||
|
block_ice,
|
||||||
|
block_fence,
|
||||||
|
block_portal,
|
||||||
|
block_iron_bars,
|
||||||
|
block_glass_pane,
|
||||||
|
block_waterlily,
|
||||||
|
block_nether_brick_fence,
|
||||||
|
block_cobblestone_wall,
|
||||||
|
block_double_plant,
|
||||||
|
block_stained_glass_pane,
|
||||||
|
block_stained_glass,
|
||||||
|
block_trapped_chest,
|
||||||
|
block_spruce_fence,
|
||||||
|
block_birch_fence,
|
||||||
|
block_jungle_fence,
|
||||||
|
block_dark_oak_fence,
|
||||||
|
block_acacia_fence
|
||||||
|
};
|
||||||
|
const size_t block_class_ancil_len = COUNT_OF(block_class_ancil);
|
||||||
|
|
||||||
|
const mc_block_t block_class_alt_height[] = {
|
||||||
|
block_stone_slab,
|
||||||
|
block_oak_stairs,
|
||||||
|
block_stone_stairs,
|
||||||
|
block_brick_stairs,
|
||||||
|
block_stone_brick_stairs,
|
||||||
|
block_nether_brick_stairs,
|
||||||
|
block_sandstone_stairs,
|
||||||
|
block_spruce_stairs,
|
||||||
|
block_birch_stairs,
|
||||||
|
block_jungle_stairs,
|
||||||
|
block_quartz_stairs,
|
||||||
|
block_acacia_stairs,
|
||||||
|
block_dark_oak_stairs,
|
||||||
|
block_red_sandstone_stairs,
|
||||||
|
block_stone_slab2,
|
||||||
|
block_purpur_stairs,
|
||||||
|
block_purpur_slab,
|
||||||
|
block_wooden_slab
|
||||||
|
};
|
||||||
|
const size_t block_class_alt_height_len = COUNT_OF(block_class_alt_height);
|
||||||
|
|
||||||
51
overviewer_core/src/block_class.h
Normal file
51
overviewer_core/src/block_class.h
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Minecraft Overviewer.
|
||||||
|
*
|
||||||
|
* Minecraft Overviewer is free software: you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* Minecraft Overviewer is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __BLOCK_CLASS_H_INCLUDED__
|
||||||
|
#define __BLOCK_CLASS_H_INCLUDED__
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "mc_id.h"
|
||||||
|
|
||||||
|
bool block_class_is_subset(
|
||||||
|
mc_block_t block,
|
||||||
|
const mc_block_t block_class[],
|
||||||
|
size_t block_class_len
|
||||||
|
);
|
||||||
|
|
||||||
|
extern const mc_block_t block_class_stair[];
|
||||||
|
extern const size_t block_class_stair_len;
|
||||||
|
|
||||||
|
extern const mc_block_t block_class_door[];
|
||||||
|
extern const size_t block_class_door_len;
|
||||||
|
|
||||||
|
extern const mc_block_t block_class_fence[];
|
||||||
|
extern const size_t block_class_fence_len;
|
||||||
|
|
||||||
|
extern const mc_block_t block_class_fence_gate[];
|
||||||
|
extern const size_t block_class_fence_gate_len;
|
||||||
|
|
||||||
|
extern const mc_block_t block_class_ancil[];
|
||||||
|
extern const size_t block_class_ancil_len;
|
||||||
|
|
||||||
|
extern const mc_block_t block_class_alt_height[];
|
||||||
|
extern const size_t block_class_alt_height_len;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "overviewer.h"
|
#include "overviewer.h"
|
||||||
#include "mc_id.h"
|
#include "mc_id.h"
|
||||||
|
#include "block_class.h"
|
||||||
|
|
||||||
static PyObject *textures = NULL;
|
static PyObject *textures = NULL;
|
||||||
|
|
||||||
@@ -244,32 +245,6 @@ check_adjacent_blocks(RenderState *state, int x,int y,int z, unsigned short bloc
|
|||||||
return pdata;
|
return pdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
is_stairs(int block) {
|
|
||||||
/*
|
|
||||||
* Determines if a block is stairs of any material
|
|
||||||
*/
|
|
||||||
switch (block) {
|
|
||||||
case block_oak_stairs:
|
|
||||||
case block_stone_stairs:
|
|
||||||
case block_brick_stairs:
|
|
||||||
case block_stone_brick_stairs:
|
|
||||||
case block_nether_brick_stairs:
|
|
||||||
case block_sandstone_stairs:
|
|
||||||
case block_spruce_stairs:
|
|
||||||
case block_birch_stairs:
|
|
||||||
case block_jungle_stairs:
|
|
||||||
case block_quartz_stairs:
|
|
||||||
case block_acacia_stairs:
|
|
||||||
case block_dark_oak_stairs:
|
|
||||||
case block_red_sandstone_stairs:
|
|
||||||
case block_purpur_stairs:
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned short
|
unsigned short
|
||||||
generate_pseudo_data(RenderState *state, unsigned short ancilData) {
|
generate_pseudo_data(RenderState *state, unsigned short ancilData) {
|
||||||
/*
|
/*
|
||||||
@@ -284,13 +259,13 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
|
|||||||
if (get_data(state, BLOCKS, x, y+1, z) == 78)
|
if (get_data(state, BLOCKS, x, y+1, z) == 78)
|
||||||
return 0x10;
|
return 0x10;
|
||||||
return ancilData;
|
return ancilData;
|
||||||
} else if (state->block == block_flowing_water || state->block == block_water) { /* water */
|
} else if (block_class_is_subset(state->block, (mc_block_t[]){block_flowing_water,block_water}, 2)) { /* water */
|
||||||
data = check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f;
|
data = check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f;
|
||||||
/* an aditional bit for top is added to the 4 bits of check_adjacent_blocks */
|
/* an aditional bit for top is added to the 4 bits of check_adjacent_blocks */
|
||||||
if (get_data(state, BLOCKS, x, y+1, z) != state->block)
|
if (get_data(state, BLOCKS, x, y+1, z) != state->block)
|
||||||
data |= 0x10;
|
data |= 0x10;
|
||||||
return data;
|
return data;
|
||||||
} else if ((state->block == block_glass) || (state->block == block_ice) || (state->block == block_stained_glass)) { /* glass and ice and stained glass*/
|
} else if (block_class_is_subset(state->block, (mc_block_t[]){block_glass,block_ice,block_stained_glass}, 3)) { /* glass and ice and stained glass*/
|
||||||
/* an aditional bit for top is added to the 4 bits of check_adjacent_blocks
|
/* an aditional bit for top is added to the 4 bits of check_adjacent_blocks
|
||||||
* Note that stained glass encodes 16 colors using 4 bits. this pushes us over the 8-bits of an unsigned char,
|
* Note that stained glass encodes 16 colors using 4 bits. this pushes us over the 8-bits of an unsigned char,
|
||||||
* forcing us to use an unsigned short to hold 16 bits of pseudo ancil data
|
* forcing us to use an unsigned short to hold 16 bits of pseudo ancil data
|
||||||
@@ -302,8 +277,7 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
|
|||||||
}
|
}
|
||||||
data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f) | data;
|
data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f) | data;
|
||||||
return (data << 4) | (ancilData & 0x0f);
|
return (data << 4) | (ancilData & 0x0f);
|
||||||
} else if ((state->block == block_fence) || (state->block == block_spruce_fence) || (state->block == block_birch_fence) ||
|
} else if (block_class_is_subset(state->block, block_class_fence, block_class_fence_len)) { /* fences */
|
||||||
(state->block == block_jungle_fence) || (state->block == block_dark_oak_fence) || (state->block == block_acacia_fence)) { /* fences */
|
|
||||||
/* check for fences AND fence gates */
|
/* check for fences AND fence gates */
|
||||||
return check_adjacent_blocks(state, x, y, z, state->block) | check_adjacent_blocks(state, x, y, z, block_fence_gate) |
|
return check_adjacent_blocks(state, x, y, z, state->block) | check_adjacent_blocks(state, x, y, z, block_fence_gate) |
|
||||||
check_adjacent_blocks(state, x, y, z, block_fence_gate) | check_adjacent_blocks(state, x, y, z, block_birch_fence_gate) | check_adjacent_blocks(state, x, y, z, block_jungle_fence_gate) |
|
check_adjacent_blocks(state, x, y, z, block_fence_gate) | check_adjacent_blocks(state, x, y, z, block_birch_fence_gate) | check_adjacent_blocks(state, x, y, z, block_jungle_fence_gate) |
|
||||||
@@ -343,7 +317,7 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
|
|||||||
}
|
}
|
||||||
return final_data;
|
return final_data;
|
||||||
|
|
||||||
} else if (state->block == block_chest || state->block == block_trapped_chest) {
|
} else if (block_class_is_subset(state->block, (mc_block_t[]){block_chest,block_trapped_chest}, 2)) {
|
||||||
/* Orientation is given by ancilData, pseudo data needed to
|
/* Orientation is given by ancilData, pseudo data needed to
|
||||||
* choose from single or double chest and the correct half of
|
* choose from single or double chest and the correct half of
|
||||||
* the chest. */
|
* the chest. */
|
||||||
@@ -380,7 +354,7 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
|
|||||||
}
|
}
|
||||||
return final_data;
|
return final_data;
|
||||||
|
|
||||||
} else if ((state->block == block_iron_bars) || (state->block == block_glass_pane) || (state->block == block_stained_glass_pane)) {
|
} else if (block_class_is_subset(state->block, (mc_block_t[]){block_iron_bars,block_glass_pane, block_stained_glass_pane},3)) {
|
||||||
/* iron bars and glass panes:
|
/* iron bars and glass panes:
|
||||||
* they seem to stick to almost everything but air,
|
* they seem to stick to almost everything but air,
|
||||||
* not sure yet! Still a TODO! */
|
* not sure yet! Still a TODO! */
|
||||||
@@ -389,13 +363,11 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
|
|||||||
data = (check_adjacent_blocks(state, x, y, z, 0) ^ 0x0f);
|
data = (check_adjacent_blocks(state, x, y, z, 0) ^ 0x0f);
|
||||||
return (data << 4) | (ancilData & 0xf);
|
return (data << 4) | (ancilData & 0xf);
|
||||||
|
|
||||||
} else if ((state->block == block_portal) || (state->block == block_nether_brick_fence)) {
|
} else if (block_class_is_subset(state->block, (mc_block_t[]){block_portal,block_nether_brick_fence}, 2)) {
|
||||||
/* portal and nether brick fences */
|
/* portal and nether brick fences */
|
||||||
return check_adjacent_blocks(state, x, y, z, state->block);
|
return check_adjacent_blocks(state, x, y, z, state->block);
|
||||||
|
|
||||||
} else if ((state->block == block_wooden_door) || (state->block == block_iron_door) || (state->block == block_spruce_door) ||
|
} else if (block_class_is_subset(state->block, block_class_door, block_class_door_len)) {
|
||||||
(state->block == block_birch_door) || (state->block == block_jungle_door) || (state->block == block_acacia_door) ||
|
|
||||||
(state->block == block_dark_oak_door)) {
|
|
||||||
/* use bottom block data format plus one bit for top/down
|
/* use bottom block data format plus one bit for top/down
|
||||||
* block (0x8) and one bit for hinge position (0x10)
|
* block (0x8) and one bit for hinge position (0x10)
|
||||||
*/
|
*/
|
||||||
@@ -442,7 +414,7 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
|
|||||||
pr = pr * pr * 42317861 + pr * 11;
|
pr = pr * pr * 42317861 + pr * 11;
|
||||||
rotation = 3 & (pr >> 16);
|
rotation = 3 & (pr >> 16);
|
||||||
return rotation;
|
return rotation;
|
||||||
} else if (is_stairs(state->block)) { /* stairs */
|
} else if (block_class_is_subset(state->block, block_class_stair, block_class_stair_len)) { /* stairs */
|
||||||
/* 4 ancillary bits will be added to indicate which quarters of the block contain the
|
/* 4 ancillary bits will be added to indicate which quarters of the block contain the
|
||||||
* upper step. Regular stairs will have 2 bits set & corner stairs will have 1 or 3.
|
* upper step. Regular stairs will have 2 bits set & corner stairs will have 1 or 3.
|
||||||
* Southwest quarter is part of the upper step - 0x40
|
* Southwest quarter is part of the upper step - 0x40
|
||||||
@@ -499,10 +471,10 @@ generate_pseudo_data(RenderState *state, unsigned short ancilData) {
|
|||||||
|
|
||||||
/* get block & data for neighbors in this order: east, north, west, south */
|
/* get block & data for neighbors in this order: east, north, west, south */
|
||||||
/* so we can rotate things easily */
|
/* so we can rotate things easily */
|
||||||
stairs[0] = stairs[4] = is_stairs(get_data(state, BLOCKS, x+1, y, z));
|
stairs[0] = stairs[4] = block_class_is_subset(get_data(state, BLOCKS, x+1, y, z), block_class_stair, block_class_stair_len);
|
||||||
stairs[1] = stairs[5] = is_stairs(get_data(state, BLOCKS, x, y, z-1));
|
stairs[1] = stairs[5] = block_class_is_subset(get_data(state, BLOCKS, x, y, z-1), block_class_stair, block_class_stair_len);
|
||||||
stairs[2] = stairs[6] = is_stairs(get_data(state, BLOCKS, x-1, y, z));
|
stairs[2] = stairs[6] = block_class_is_subset(get_data(state, BLOCKS, x-1, y, z), block_class_stair, block_class_stair_len);
|
||||||
stairs[3] = stairs[7] = is_stairs(get_data(state, BLOCKS, x, y, z+1));
|
stairs[3] = stairs[7] = block_class_is_subset(get_data(state, BLOCKS, x, y, z+1), block_class_stair, block_class_stair_len);
|
||||||
neigh[0] = neigh[4] = FIX_ROT(get_data(state, DATA, x+1, y, z));
|
neigh[0] = neigh[4] = FIX_ROT(get_data(state, DATA, x+1, y, z));
|
||||||
neigh[1] = neigh[5] = FIX_ROT(get_data(state, DATA, x, y, z-1));
|
neigh[1] = neigh[5] = FIX_ROT(get_data(state, DATA, x, y, z-1));
|
||||||
neigh[2] = neigh[6] = FIX_ROT(get_data(state, DATA, x-1, y, z));
|
neigh[2] = neigh[6] = FIX_ROT(get_data(state, DATA, x-1, y, z));
|
||||||
@@ -698,29 +670,7 @@ chunk_render(PyObject *self, PyObject *args) {
|
|||||||
* grass, water, glass, chest, restone wire,
|
* grass, water, glass, chest, restone wire,
|
||||||
* ice, fence, portal, iron bars, glass panes,
|
* ice, fence, portal, iron bars, glass panes,
|
||||||
* trapped chests, stairs */
|
* trapped chests, stairs */
|
||||||
if ((state.block == block_grass) ||
|
if (block_class_is_subset(state.block, block_class_ancil, block_class_ancil_len)) {
|
||||||
(state.block == block_flowing_water) || (state.block == block_water) ||
|
|
||||||
(state.block == block_glass) || (state.block == block_chest) ||
|
|
||||||
(state.block == block_redstone_wire) ||
|
|
||||||
/* doors */
|
|
||||||
(state.block == block_wooden_door ) ||
|
|
||||||
(state.block == block_iron_door ) ||
|
|
||||||
(state.block == block_spruce_door ) ||
|
|
||||||
(state.block == block_birch_door ) ||
|
|
||||||
(state.block == block_jungle_door ) ||
|
|
||||||
(state.block == block_acacia_door ) ||
|
|
||||||
(state.block == block_dark_oak_door) ||
|
|
||||||
/* end doors */
|
|
||||||
(state.block == block_ice) ||
|
|
||||||
(state.block == block_fence) || (state.block == block_portal) ||
|
|
||||||
(state.block == block_iron_bars) || (state.block == block_glass_pane) ||
|
|
||||||
(state.block == block_waterlily) || (state.block == block_nether_brick_fence) ||
|
|
||||||
(state.block == block_cobblestone_wall) || (state.block == block_double_plant) ||
|
|
||||||
(state.block == block_stained_glass_pane) || (state.block == block_stained_glass) ||
|
|
||||||
(state.block == block_trapped_chest) || (state.block == block_spruce_fence) ||
|
|
||||||
(state.block == block_birch_fence) || (state.block == block_jungle_fence) ||
|
|
||||||
(state.block == block_dark_oak_fence) || (state.block == block_acacia_fence) ||
|
|
||||||
is_stairs(state.block)) {
|
|
||||||
ancilData = generate_pseudo_data(&state, ancilData);
|
ancilData = generate_pseudo_data(&state, ancilData);
|
||||||
state.block_pdata = ancilData;
|
state.block_pdata = ancilData;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
// increment this value if you've made a change to the c extesion
|
// increment this value if you've made a change to the c extesion
|
||||||
// and want to force users to rebuild
|
// and want to force users to rebuild
|
||||||
#define OVERVIEWER_EXTENSION_VERSION 57
|
#define OVERVIEWER_EXTENSION_VERSION 58
|
||||||
|
|
||||||
/* Python PIL, and numpy headers */
|
/* Python PIL, and numpy headers */
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "../overviewer.h"
|
#include "../overviewer.h"
|
||||||
#include "../mc_id.h"
|
#include "../mc_id.h"
|
||||||
|
#include "../block_class.h"
|
||||||
#include "biomes.h"
|
#include "biomes.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -95,19 +96,20 @@ base_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObjec
|
|||||||
*/
|
*/
|
||||||
if (/* grass, but not snowgrass */
|
if (/* grass, but not snowgrass */
|
||||||
(state->block == block_grass && get_data(state, BLOCKS, state->x, state->y+1, state->z) != 78) ||
|
(state->block == block_grass && get_data(state, BLOCKS, state->x, state->y+1, state->z) != 78) ||
|
||||||
/* water */
|
block_class_is_subset(state->block, (mc_block_t[]){
|
||||||
state->block == block_flowing_water || state->block == block_water ||
|
block_vine,
|
||||||
/* leaves */
|
block_waterlily,
|
||||||
state->block == block_leaves || state->block == block_leaves2 ||
|
block_flowing_water,
|
||||||
|
block_water,
|
||||||
|
block_leaves,
|
||||||
|
block_leaves2
|
||||||
|
},
|
||||||
|
6) ||
|
||||||
/* tallgrass, but not dead shrubs */
|
/* tallgrass, but not dead shrubs */
|
||||||
(state->block == block_tallgrass && state->block_data != 0) ||
|
(state->block == block_tallgrass && state->block_data != 0) ||
|
||||||
/* pumpkin/melon stem, not fully grown. Fully grown stems
|
/* pumpkin/melon stem, not fully grown. Fully grown stems
|
||||||
* get constant brown color (see textures.py) */
|
* get constant brown color (see textures.py) */
|
||||||
(((state->block == block_pumpkin_stem) || (state->block == block_melon_stem)) && (state->block_data != 7)) ||
|
(((state->block == block_pumpkin_stem) || (state->block == block_melon_stem)) && (state->block_data != 7)) ||
|
||||||
/* vines */
|
|
||||||
state->block == block_vine ||
|
|
||||||
/* lily pads */
|
|
||||||
state->block == block_waterlily ||
|
|
||||||
/* doublePlant grass & ferns */
|
/* doublePlant grass & ferns */
|
||||||
(state->block == block_double_plant && (state->block_data == 2 || state->block_data == 3)) ||
|
(state->block == block_double_plant && (state->block_data == 2 || state->block_data == 3)) ||
|
||||||
/* doublePlant grass & ferns tops */
|
/* doublePlant grass & ferns tops */
|
||||||
@@ -123,20 +125,25 @@ base_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObjec
|
|||||||
/* grass needs a special facemask */
|
/* grass needs a special facemask */
|
||||||
facemask = self->grass_texture;
|
facemask = self->grass_texture;
|
||||||
}
|
}
|
||||||
|
if(block_class_is_subset(state->block, (mc_block_t[]){
|
||||||
switch (state->block) {
|
block_grass,
|
||||||
case 2:
|
block_tallgrass,
|
||||||
/* grass */
|
block_pumpkin_stem,
|
||||||
|
block_melon_stem,
|
||||||
|
block_vine,
|
||||||
|
block_waterlily,
|
||||||
|
block_double_plant
|
||||||
|
},7)) {
|
||||||
color_table = self->grasscolor;
|
color_table = self->grasscolor;
|
||||||
break;
|
}
|
||||||
case 8:
|
else if(block_class_is_subset(state->block, (mc_block_t[]){
|
||||||
case 9:
|
block_flowing_water,block_water
|
||||||
/* water */
|
},2)) {
|
||||||
color_table = self->watercolor;
|
color_table = self->watercolor;
|
||||||
break;
|
}
|
||||||
case 18:
|
else if(block_class_is_subset(state->block, (mc_block_t[]){
|
||||||
case 161:
|
block_leaves,block_leaves2
|
||||||
/* leaves */
|
},2)) {
|
||||||
color_table = self->foliagecolor;
|
color_table = self->foliagecolor;
|
||||||
if (state->block_data == 2)
|
if (state->block_data == 2)
|
||||||
{
|
{
|
||||||
@@ -144,34 +151,7 @@ base_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObjec
|
|||||||
birch foliage color is flipped XY-ways */
|
birch foliage color is flipped XY-ways */
|
||||||
flip_xy = 1;
|
flip_xy = 1;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case 31:
|
|
||||||
/* tall grass */
|
|
||||||
color_table = self->grasscolor;
|
|
||||||
break;
|
|
||||||
case 104:
|
|
||||||
/* pumpkin stem */
|
|
||||||
color_table = self->grasscolor;
|
|
||||||
break;
|
|
||||||
case 105:
|
|
||||||
/* melon stem */
|
|
||||||
color_table = self->grasscolor;
|
|
||||||
break;
|
|
||||||
case 106:
|
|
||||||
/* vines */
|
|
||||||
color_table = self->grasscolor;
|
|
||||||
break;
|
|
||||||
case 111:
|
|
||||||
/* lily pads */
|
|
||||||
color_table = self->grasscolor;
|
|
||||||
break;
|
|
||||||
case 175:
|
|
||||||
/* doublePlant grass & ferns */
|
|
||||||
color_table = self->grasscolor;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (color_table) {
|
if (color_table) {
|
||||||
unsigned char biome;
|
unsigned char biome;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "../overviewer.h"
|
#include "../overviewer.h"
|
||||||
#include "../mc_id.h"
|
#include "../mc_id.h"
|
||||||
|
#include "../block_class.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
float opacity;
|
float opacity;
|
||||||
@@ -35,16 +36,17 @@ edge_lines_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, P
|
|||||||
PrimitiveEdgeLines *self = (PrimitiveEdgeLines *)data;
|
PrimitiveEdgeLines *self = (PrimitiveEdgeLines *)data;
|
||||||
|
|
||||||
/* Draw some edge lines! */
|
/* Draw some edge lines! */
|
||||||
if (state->block == block_stone_slab || state->block == block_snow_layer || !is_transparent(state->block)) {
|
if (block_class_is_subset(state->block, (mc_block_t[]){block_stone_slab,block_snow_layer}, 2)
|
||||||
|
|| !is_transparent(state->block)) {
|
||||||
Imaging img_i = imaging_python_to_c(state->img);
|
Imaging img_i = imaging_python_to_c(state->img);
|
||||||
unsigned char ink[] = {0, 0, 0, 255 * self->opacity};
|
unsigned char ink[] = {0, 0, 0, 255 * self->opacity};
|
||||||
unsigned short side_block;
|
unsigned short side_block;
|
||||||
int x = state->x, y = state->y, z = state->z;
|
int x = state->x, y = state->y, z = state->z;
|
||||||
|
|
||||||
int increment=0;
|
int increment=0;
|
||||||
if ((state->block == block_stone_slab || state->block == block_wooden_slab) && ((state->block_data & 0x8) == 0 )) // half-steps BUT no upsidown half-steps
|
if (block_class_is_subset(state->block, (mc_block_t[]){block_wooden_slab,block_stone_slab}, 2) && ((state->block_data & 0x8) == 0 )) // half-steps BUT no upsidown half-steps
|
||||||
increment=6;
|
increment=6;
|
||||||
else if ((state->block == block_snow_layer) || (state->block == block_unpowered_repeater) || (state->block == block_powered_repeater)) // snow, redstone repeaters (on and off)
|
else if (block_class_is_subset(state->block, (mc_block_t[]){block_snow_layer,block_unpowered_repeater,block_powered_repeater}, 3)) // snow, redstone repeaters (on and off)
|
||||||
increment=9;
|
increment=9;
|
||||||
|
|
||||||
/* +X side */
|
/* +X side */
|
||||||
@@ -52,9 +54,9 @@ edge_lines_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, P
|
|||||||
if (side_block != state->block && (is_transparent(side_block) || render_mode_hidden(state->rendermode, x+1, y, z)) &&
|
if (side_block != state->block && (is_transparent(side_block) || render_mode_hidden(state->rendermode, x+1, y, z)) &&
|
||||||
/* WARNING: ugly special case approaching */
|
/* WARNING: ugly special case approaching */
|
||||||
/* if the block is a slab and the side block is a stair don't draw anything, it can give very ugly results */
|
/* if the block is a slab and the side block is a stair don't draw anything, it can give very ugly results */
|
||||||
!((state->block == block_stone_slab || state->block == block_wooden_slab) && ((side_block == block_oak_stairs) || (side_block == block_stone_stairs) || (side_block == block_brick_stairs) ||
|
!(block_class_is_subset(state->block, (mc_block_t[]){block_wooden_slab, block_stone_slab}, 2)
|
||||||
(side_block == block_stone_brick_stairs) || (side_block == block_nether_brick_stairs) || (side_block == block_sandstone_stairs) || (side_block == block_spruce_stairs) || (side_block == block_birch_stairs) ||
|
&& (block_class_is_subset(side_block, block_class_stair, block_class_stair_len))
|
||||||
(side_block == block_jungle_stairs)))) {
|
)) {
|
||||||
ImagingDrawLine(img_i, state->imgx+12, state->imgy+1+increment, state->imgx+22+1, state->imgy+5+1+increment, &ink, 1);
|
ImagingDrawLine(img_i, state->imgx+12, state->imgy+1+increment, state->imgx+22+1, state->imgy+5+1+increment, &ink, 1);
|
||||||
ImagingDrawLine(img_i, state->imgx+12, state->imgy+increment, state->imgx+22+1, state->imgy+5+increment, &ink, 1);
|
ImagingDrawLine(img_i, state->imgx+12, state->imgy+increment, state->imgx+22+1, state->imgy+5+increment, &ink, 1);
|
||||||
}
|
}
|
||||||
@@ -64,9 +66,10 @@ edge_lines_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, P
|
|||||||
if (side_block != state->block && (is_transparent(side_block) || render_mode_hidden(state->rendermode, x, y, z-1)) &&
|
if (side_block != state->block && (is_transparent(side_block) || render_mode_hidden(state->rendermode, x, y, z-1)) &&
|
||||||
/* WARNING: ugly special case approaching */
|
/* WARNING: ugly special case approaching */
|
||||||
/* if the block is a slab and the side block is a stair don't draw anything, it can give very ugly results */
|
/* if the block is a slab and the side block is a stair don't draw anything, it can give very ugly results */
|
||||||
!((state->block == block_stone_slab || state->block == block_wooden_slab) && ((side_block == block_oak_stairs) || (side_block == block_stone_stairs) || (side_block == block_brick_stairs) ||
|
!(
|
||||||
(side_block == block_stone_brick_stairs) || (side_block == block_nether_brick_stairs) || (side_block == block_sandstone_stairs) || (side_block == block_spruce_stairs) || (side_block == block_birch_stairs) ||
|
block_class_is_subset(state->block, (mc_block_t[]){block_stone_slab,block_wooden_slab}, 2)
|
||||||
(side_block == block_jungle_stairs)))) {
|
&& (block_class_is_subset(side_block, block_class_stair, block_class_stair_len))
|
||||||
|
)) {
|
||||||
ImagingDrawLine(img_i, state->imgx, state->imgy+6+1+increment, state->imgx+12+1, state->imgy+1+increment, &ink, 1);
|
ImagingDrawLine(img_i, state->imgx, state->imgy+6+1+increment, state->imgx+12+1, state->imgy+1+increment, &ink, 1);
|
||||||
ImagingDrawLine(img_i, state->imgx, state->imgy+6+increment, state->imgx+12+1, state->imgy+increment, &ink, 1);
|
ImagingDrawLine(img_i, state->imgx, state->imgy+6+increment, state->imgx+12+1, state->imgy+increment, &ink, 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "../overviewer.h"
|
#include "../overviewer.h"
|
||||||
#include "../mc_id.h"
|
#include "../mc_id.h"
|
||||||
|
#include "../block_class.h"
|
||||||
#include "lighting.h"
|
#include "lighting.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
@@ -139,7 +140,7 @@ estimate_blocklevel(RenderPrimitiveLighting *self, RenderState *state,
|
|||||||
blocklevel = get_data(state, BLOCKLIGHT, x, y, z);
|
blocklevel = get_data(state, BLOCKLIGHT, x, y, z);
|
||||||
|
|
||||||
/* no longer a guess */
|
/* no longer a guess */
|
||||||
if (!(block == block_stone_slab || block == block_oak_stairs || block == block_stone_stairs || block == block_brick_stairs || block == block_stone_brick_stairs || block == block_red_sandstone_stairs || block == block_stone_slab2 || block == block_purpur_slab ) && authoratative) {
|
if (!block_class_is_subset(block, block_class_alt_height, block_class_alt_height_len) && authoratative) {
|
||||||
*authoratative = 1;
|
*authoratative = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,9 +161,7 @@ get_lighting_color(RenderPrimitiveLighting *self, RenderState *state,
|
|||||||
|
|
||||||
/* special half-step handling, stairs handling */
|
/* special half-step handling, stairs handling */
|
||||||
/* Anvil also needs to be here, blockid 145 */
|
/* Anvil also needs to be here, blockid 145 */
|
||||||
if (block == block_stone_slab || block == block_oak_stairs || block == block_stone_stairs || block == block_brick_stairs || block == block_stone_brick_stairs || block == block_nether_brick_stairs ||
|
if ( block_class_is_subset(block, block_class_alt_height, block_class_alt_height_len) || block == block_anvil) {
|
||||||
block == block_sandstone_stairs || block == block_spruce_stairs || block == block_birch_stairs || block == block_jungle_stairs || block == block_anvil || block == block_quartz_stairs ||
|
|
||||||
block == block_acacia_stairs || block == block_dark_oak_stairs || block == block_red_sandstone_stairs || block == block_stone_slab2 || block == block_purpur_stairs || block == block_purpur_slab ) {
|
|
||||||
unsigned int upper_block;
|
unsigned int upper_block;
|
||||||
|
|
||||||
/* stairs and half-blocks take the skylevel from the upper block if it's transparent */
|
/* stairs and half-blocks take the skylevel from the upper block if it's transparent */
|
||||||
@@ -171,10 +170,7 @@ get_lighting_color(RenderPrimitiveLighting *self, RenderState *state,
|
|||||||
do {
|
do {
|
||||||
upper_counter++;
|
upper_counter++;
|
||||||
upper_block = get_data(state, BLOCKS, x, y + upper_counter, z);
|
upper_block = get_data(state, BLOCKS, x, y + upper_counter, z);
|
||||||
} while (upper_block == block_stone_slab || upper_block == block_oak_stairs || upper_block == block_stone_stairs || upper_block == block_brick_stairs ||
|
} while (block_class_is_subset(upper_block, block_class_alt_height, block_class_alt_height_len));
|
||||||
upper_block == block_stone_brick_stairs || upper_block == block_nether_brick_stairs || upper_block == block_sandstone_stairs || upper_block == block_spruce_stairs ||
|
|
||||||
upper_block == block_birch_stairs || upper_block == block_jungle_stairs || upper_block == block_quartz_stairs || upper_block == block_acacia_stairs ||
|
|
||||||
upper_block == block_dark_oak_stairs || upper_block == block_red_sandstone_stairs || upper_block == block_stone_slab2 || upper_block == block_purpur_stairs || upper_block == block_purpur_slab );
|
|
||||||
if (is_transparent(upper_block)) {
|
if (is_transparent(upper_block)) {
|
||||||
skylevel = get_data(state, SKYLIGHT, x, y + upper_counter, z);
|
skylevel = get_data(state, SKYLIGHT, x, y + upper_counter, z);
|
||||||
} else {
|
} else {
|
||||||
@@ -187,7 +183,7 @@ get_lighting_color(RenderPrimitiveLighting *self, RenderState *state,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (block == block_flowing_lava || block == block_lava) {
|
if (block_class_is_subset(block, (mc_block_t[]){block_flowing_lava,block_lava}, 2)) {
|
||||||
/* lava blocks should always be lit! */
|
/* lava blocks should always be lit! */
|
||||||
*r = 255;
|
*r = 255;
|
||||||
*g = 255;
|
*g = 255;
|
||||||
@@ -306,7 +302,7 @@ lighting_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyO
|
|||||||
self = (RenderPrimitiveLighting *)data;
|
self = (RenderPrimitiveLighting *)data;
|
||||||
x = state->x, y = state->y, z = state->z;
|
x = state->x, y = state->y, z = state->z;
|
||||||
|
|
||||||
if ((state->block == block_flowing_water) || (state->block == block_water)) { /* special case for water */
|
if (block_class_is_subset(state->block, (mc_block_t[]){block_flowing_water,block_water}, 2)) { /* special case for water */
|
||||||
/* looks like we need a new case for lighting, there are
|
/* looks like we need a new case for lighting, there are
|
||||||
* blocks that are transparent for occlusion calculations and
|
* blocks that are transparent for occlusion calculations and
|
||||||
* need per-face shading if the face is drawn. */
|
* need per-face shading if the face is drawn. */
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "../overviewer.h"
|
#include "../overviewer.h"
|
||||||
#include "../mc_id.h"
|
#include "../mc_id.h"
|
||||||
|
#include "../block_class.h"
|
||||||
#include "nether.h"
|
#include "nether.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -36,7 +37,7 @@ walk_chunk(RenderState *state, RenderPrimitiveNether *data) {
|
|||||||
|
|
||||||
for (y = NETHER_ROOF-1; y>=0; y--) {
|
for (y = NETHER_ROOF-1; y>=0; y--) {
|
||||||
id = get_data(state, BLOCKS, x, y - (state->chunky * 16), z);
|
id = get_data(state, BLOCKS, x, y - (state->chunky * 16), z);
|
||||||
if (id == block_bedrock || id == block_netherrack || id == block_quartz_ore || id == block_lava)
|
if (block_class_is_subset(id, (mc_block_t[]){block_bedrock,block_netherrack,block_quartz_ore,block_lava}, 4))
|
||||||
data->remove_block[x+1][y][z+1] = 1;
|
data->remove_block[x+1][y][z+1] = 1;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "../overviewer.h"
|
#include "../overviewer.h"
|
||||||
#include "../mc_id.h"
|
#include "../mc_id.h"
|
||||||
|
#include "../block_class.h"
|
||||||
#include "lighting.h"
|
#include "lighting.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
@@ -219,7 +220,9 @@ smooth_lighting_draw(void *data, RenderState *state, PyObject *src, PyObject *ma
|
|||||||
|
|
||||||
/* special case for leaves, water 8, water 9, ice 79
|
/* special case for leaves, water 8, water 9, ice 79
|
||||||
-- these are also smooth-lit! */
|
-- these are also smooth-lit! */
|
||||||
if (state->block != block_leaves && state->block != block_flowing_water && state->block != block_water && state->block != block_ice && is_transparent(state->block))
|
if (!block_class_is_subset(state->block, (mc_block_t[]){
|
||||||
|
block_leaves,block_flowing_water,block_water,block_ice
|
||||||
|
}, 4) && is_transparent(state->block))
|
||||||
{
|
{
|
||||||
/* transparent blocks are rendered as usual, with flat lighting */
|
/* transparent blocks are rendered as usual, with flat lighting */
|
||||||
primitive_lighting.draw(data, state, src, mask, mask_light);
|
primitive_lighting.draw(data, state, src, mask, mask_light);
|
||||||
|
|||||||
@@ -14,4 +14,7 @@
|
|||||||
#define OV_BLEND(mask, in1, in2, tmp1, tmp2)\
|
#define OV_BLEND(mask, in1, in2, tmp1, tmp2)\
|
||||||
(OV_MULDIV255(in1, 255 - mask, tmp1) + OV_MULDIV255(in2, mask, tmp2))
|
(OV_MULDIV255(in1, 255 - mask, tmp1) + OV_MULDIV255(in2, mask, tmp2))
|
||||||
|
|
||||||
|
#define COUNT_OF(array) \
|
||||||
|
(sizeof(array) / sizeof(array[0]))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
2
setup.py
2
setup.py
@@ -175,7 +175,7 @@ for name in glob.glob("overviewer_core/src/primitives/*.c"):
|
|||||||
name = os.path.splitext(name)[0]
|
name = os.path.splitext(name)[0]
|
||||||
primitives.append(name)
|
primitives.append(name)
|
||||||
|
|
||||||
c_overviewer_files = ['main.c', 'composite.c', 'iterate.c', 'endian.c', 'rendermodes.c']
|
c_overviewer_files = ['main.c', 'composite.c', 'iterate.c', 'endian.c', 'rendermodes.c', 'block_class.c']
|
||||||
c_overviewer_files += map(lambda mode: 'primitives/%s.c' % (mode,), primitives)
|
c_overviewer_files += map(lambda mode: 'primitives/%s.c' % (mode,), primitives)
|
||||||
c_overviewer_files += ['Draw.c']
|
c_overviewer_files += ['Draw.c']
|
||||||
c_overviewer_includes = ['overviewer.h', 'rendermodes.h']
|
c_overviewer_includes = ['overviewer.h', 'rendermodes.h']
|
||||||
|
|||||||
Reference in New Issue
Block a user