0

Add piston variant rendering & fix lighting

- Fix extended pistons rendering as if they were retracted
- Fix retracted pistons rendering completely dark when using a
  lighting rendermode primitive
- Use piston head 'facing' property to determine rotation
- Use piston head 'type' property to determine if sticky or not
This commit is contained in:
Joseph Camp
2020-02-08 18:31:30 +00:00
parent 2a7280f8bf
commit 4ee5673e0d
3 changed files with 107 additions and 120 deletions

View File

@@ -316,9 +316,10 @@ lighting_draw(void* data, RenderState* state, PyObject* src, PyObject* mask, PyO
if ((state->block_pdata & 4) == 4) { /* bottom right */
do_shading_with_mask(self, state, x, y, z + 1, self->facemasks[2]);
}
/* leaves and ice are transparent for occlusion calculations but they
* per face-shading to look as in game */
} else if (is_transparent(state->block) && (state->block != 18) && (state->block != 79)) {
/* leaves, ice, and pistons are transparent for occlusion calculations
* but they need per face-shading to look as in game */
} else if (is_transparent(state->block) &&
!block_class_is_subset(state->block, (mc_block_t[]){block_leaves, block_ice, block_piston, block_sticky_piston}, 4)) {
/* transparent: do shading on whole block */
do_shading_with_mask(self, state, x, y, z, mask_light);
} else {

View File

@@ -1488,169 +1488,150 @@ def rails(self, blockid, data):
return img
# sticky and normal piston body
@material(blockid=[29, 33], data=[0,1,2,3,4,5,8,9,10,11,12,13], transparent=True, solid=True, nospawn=True)
@material(blockid=[29, 33], data=[0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13],
transparent=True, solid=True, nospawn=True)
def piston(self, blockid, data):
# first, rotation
# Masked to not clobber block head/foot info
if self.rotation == 1:
if (data & 0b0111) == 2: data = data & 0b1000 | 5
elif (data & 0b0111) == 3: data = data & 0b1000 | 4
elif (data & 0b0111) == 4: data = data & 0b1000 | 2
elif (data & 0b0111) == 5: data = data & 0b1000 | 3
elif self.rotation == 2:
if (data & 0b0111) == 2: data = data & 0b1000 | 3
elif (data & 0b0111) == 3: data = data & 0b1000 | 2
elif (data & 0b0111) == 4: data = data & 0b1000 | 5
elif (data & 0b0111) == 5: data = data & 0b1000 | 4
elif self.rotation == 3:
if (data & 0b0111) == 2: data = data & 0b1000 | 4
elif (data & 0b0111) == 3: data = data & 0b1000 | 5
elif (data & 0b0111) == 4: data = data & 0b1000 | 3
elif (data & 0b0111) == 5: data = data & 0b1000 | 2
if blockid == 29: # sticky
if self.rotation in [1, 2, 3] and (data & 0b111) in [2, 3, 4, 5]:
rotation_map = {1: {2: 5, 3: 4, 4: 2, 5: 3},
2: {2: 3, 3: 2, 4: 5, 5: 4},
3: {2: 4, 3: 5, 4: 3, 5: 2}}
data = (data & 0b1000) | rotation_map[self.rotation][data & 0b111]
if blockid == 29: # sticky
piston_t = self.load_image_texture("assets/minecraft/textures/block/piston_top_sticky.png").copy()
else: # normal
else: # normal
piston_t = self.load_image_texture("assets/minecraft/textures/block/piston_top.png").copy()
# other textures
side_t = self.load_image_texture("assets/minecraft/textures/block/piston_side.png").copy()
back_t = self.load_image_texture("assets/minecraft/textures/block/piston_bottom.png").copy()
interior_t = self.load_image_texture("assets/minecraft/textures/block/piston_inner.png").copy()
if data & 0x08 == 0x08: # pushed out, non full blocks, tricky stuff
if data & 0x08 == 0x08: # pushed out, non full blocks, tricky stuff
# remove piston texture from piston body
ImageDraw.Draw(side_t).rectangle((0, 0,16,3),outline=(0,0,0,0),fill=(0,0,0,0))
if data & 0x07 == 0x0: # down
ImageDraw.Draw(side_t).rectangle((0, 0, 16, 3), outline=(0, 0, 0, 0), fill=(0, 0, 0, 0))
if data & 0x07 == 0x0: # down
side_t = side_t.rotate(180)
img = self.build_full_block(back_t ,None ,None ,side_t, side_t)
elif data & 0x07 == 0x1: # up
img = self.build_full_block((interior_t, 4) ,None ,None ,side_t, side_t)
elif data & 0x07 == 0x2: # east
img = self.build_full_block(side_t , None, None ,side_t.rotate(90), back_t)
elif data & 0x07 == 0x3: # west
img = self.build_full_block(side_t.rotate(180) ,None ,None ,side_t.rotate(270), None)
img = self.build_full_block(back_t, None, None, side_t, side_t)
elif data & 0x07 == 0x1: # up
img = self.build_full_block((interior_t, 4), None, None, side_t, side_t)
elif data & 0x07 == 0x2: # north
img = self.build_full_block(side_t, None, None, side_t.rotate(90), back_t)
elif data & 0x07 == 0x3: # south
img = self.build_full_block(side_t.rotate(180), None, None, side_t.rotate(270), None)
temp = self.transform_image_side(interior_t)
temp = temp.transpose(Image.FLIP_LEFT_RIGHT)
alpha_over(img, temp, (9,5), temp)
elif data & 0x07 == 0x4: # north
img = self.build_full_block(side_t.rotate(90) ,None ,None , None, side_t.rotate(270))
alpha_over(img, temp, (9, 4), temp)
elif data & 0x07 == 0x4: # west
img = self.build_full_block(side_t.rotate(90), None, None, None, side_t.rotate(270))
temp = self.transform_image_side(interior_t)
alpha_over(img, temp, (3,5), temp)
elif data & 0x07 == 0x5: # south
img = self.build_full_block(side_t.rotate(270) ,None , None ,back_t, side_t.rotate(90))
alpha_over(img, temp, (3, 4), temp)
elif data & 0x07 == 0x5: # east
img = self.build_full_block(side_t.rotate(270), None, None, back_t, side_t.rotate(90))
else: # pushed in, normal full blocks, easy stuff
if data & 0x07 == 0x0: # down
else: # pushed in, normal full blocks, easy stuff
if data & 0x07 == 0x0: # down
side_t = side_t.rotate(180)
img = self.build_full_block(back_t ,None ,None ,side_t, side_t)
elif data & 0x07 == 0x1: # up
img = self.build_full_block(piston_t ,None ,None ,side_t, side_t)
elif data & 0x07 == 0x2: # east
img = self.build_full_block(side_t ,None ,None ,side_t.rotate(90), back_t)
elif data & 0x07 == 0x3: # west
img = self.build_full_block(side_t.rotate(180) ,None ,None ,side_t.rotate(270), piston_t)
elif data & 0x07 == 0x4: # north
img = self.build_full_block(side_t.rotate(90) ,None ,None ,piston_t, side_t.rotate(270))
elif data & 0x07 == 0x5: # south
img = self.build_full_block(side_t.rotate(270) ,None ,None ,back_t, side_t.rotate(90))
img = self.build_full_block(back_t, None, None, side_t, side_t)
elif data & 0x07 == 0x1: # up
img = self.build_full_block(piston_t, None, None, side_t, side_t)
elif data & 0x07 == 0x2: # north
img = self.build_full_block(side_t, None, None, side_t.rotate(90), back_t)
elif data & 0x07 == 0x3: # south
img = self.build_full_block(side_t.rotate(180), None, None, side_t.rotate(270), piston_t)
elif data & 0x07 == 0x4: # west
img = self.build_full_block(side_t.rotate(90), None, None, piston_t, side_t.rotate(270))
elif data & 0x07 == 0x5: # east
img = self.build_full_block(side_t.rotate(270), None, None, back_t, side_t.rotate(90))
return img
# sticky and normal piston shaft
@material(blockid=34, data=[0,1,2,3,4,5,8,9,10,11,12,13], transparent=True, nospawn=True)
@material(blockid=34, data=[0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13], transparent=True, nospawn=True)
def piston_extension(self, blockid, data):
# first, rotation
# Masked to not clobber block head/foot info
if self.rotation == 1:
if (data & 0b0111) == 2: data = data & 0b1000 | 5
elif (data & 0b0111) == 3: data = data & 0b1000 | 4
elif (data & 0b0111) == 4: data = data & 0b1000 | 2
elif (data & 0b0111) == 5: data = data & 0b1000 | 3
elif self.rotation == 2:
if (data & 0b0111) == 2: data = data & 0b1000 | 3
elif (data & 0b0111) == 3: data = data & 0b1000 | 2
elif (data & 0b0111) == 4: data = data & 0b1000 | 5
elif (data & 0b0111) == 5: data = data & 0b1000 | 4
elif self.rotation == 3:
if (data & 0b0111) == 2: data = data & 0b1000 | 4
elif (data & 0b0111) == 3: data = data & 0b1000 | 5
elif (data & 0b0111) == 4: data = data & 0b1000 | 3
elif (data & 0b0111) == 5: data = data & 0b1000 | 2
if (data & 0x8) == 0x8: # sticky
if self.rotation in [1, 2, 3] and (data & 0b111) in [2, 3, 4, 5]:
rotation_map = {1: {2: 5, 3: 4, 4: 2, 5: 3},
2: {2: 3, 3: 2, 4: 5, 5: 4},
3: {2: 4, 3: 5, 4: 3, 5: 2}}
data = (data & 0b1000) | rotation_map[self.rotation][data & 0b111]
if data & 0x8 == 0x8: # sticky
piston_t = self.load_image_texture("assets/minecraft/textures/block/piston_top_sticky.png").copy()
else: # normal
else: # normal
piston_t = self.load_image_texture("assets/minecraft/textures/block/piston_top.png").copy()
# other textures
side_t = self.load_image_texture("assets/minecraft/textures/block/piston_side.png").copy()
back_t = self.load_image_texture("assets/minecraft/textures/block/piston_top.png").copy()
# crop piston body
ImageDraw.Draw(side_t).rectangle((0, 4,16,16),outline=(0,0,0,0),fill=(0,0,0,0))
ImageDraw.Draw(side_t).rectangle((0, 4, 16, 16), outline=(0, 0, 0, 0), fill=(0, 0, 0, 0))
# generate the horizontal piston extension stick
h_stick = Image.new("RGBA", (24,24), self.bgcolor)
h_stick = Image.new("RGBA", (24, 24), self.bgcolor)
temp = self.transform_image_side(side_t)
alpha_over(h_stick, temp, (1,7), temp)
alpha_over(h_stick, temp, (1, 7), temp)
temp = self.transform_image_top(side_t.rotate(90))
alpha_over(h_stick, temp, (1,1), temp)
alpha_over(h_stick, temp, (1, 1), temp)
# Darken it
sidealpha = h_stick.split()[3]
h_stick = ImageEnhance.Brightness(h_stick).enhance(0.85)
h_stick.putalpha(sidealpha)
# generate the vertical piston extension stick
v_stick = Image.new("RGBA", (24,24), self.bgcolor)
v_stick = Image.new("RGBA", (24, 24), self.bgcolor)
temp = self.transform_image_side(side_t.rotate(90))
alpha_over(v_stick, temp, (12,6), temp)
alpha_over(v_stick, temp, (12, 6), temp)
temp = temp.transpose(Image.FLIP_LEFT_RIGHT)
alpha_over(v_stick, temp, (1,6), temp)
alpha_over(v_stick, temp, (1, 6), temp)
# Darken it
sidealpha = v_stick.split()[3]
v_stick = ImageEnhance.Brightness(v_stick).enhance(0.85)
v_stick.putalpha(sidealpha)
# Piston orientation is stored in the 3 first bits
if data & 0x07 == 0x0: # down
if data & 0x07 == 0x0: # down
side_t = side_t.rotate(180)
img = self.build_full_block((back_t, 12) ,None ,None ,side_t, side_t)
alpha_over(img, v_stick, (0,-3), v_stick)
elif data & 0x07 == 0x1: # up
img = Image.new("RGBA", (24,24), self.bgcolor)
img2 = self.build_full_block(piston_t ,None ,None ,side_t, side_t)
alpha_over(img, v_stick, (0,4), v_stick)
alpha_over(img, img2, (0,0), img2)
elif data & 0x07 == 0x2: # east
img = self.build_full_block(side_t ,None ,None ,side_t.rotate(90), None)
img = self.build_full_block((back_t, 12), None, None, side_t, side_t)
alpha_over(img, v_stick, (0, -3), v_stick)
elif data & 0x07 == 0x1: # up
img = Image.new("RGBA", (24, 24), self.bgcolor)
img2 = self.build_full_block(piston_t, None, None, side_t, side_t)
alpha_over(img, v_stick, (0, 4), v_stick)
alpha_over(img, img2, (0, 0), img2)
elif data & 0x07 == 0x2: # north
img = self.build_full_block(side_t, None, None, side_t.rotate(90), None)
temp = self.transform_image_side(back_t).transpose(Image.FLIP_LEFT_RIGHT)
alpha_over(img, temp, (2,2), temp)
alpha_over(img, h_stick, (6,3), h_stick)
elif data & 0x07 == 0x3: # west
img = Image.new("RGBA", (24,24), self.bgcolor)
img2 = self.build_full_block(side_t.rotate(180) ,None ,None ,side_t.rotate(270), piston_t)
alpha_over(img, h_stick, (0,0), h_stick)
alpha_over(img, img2, (0,0), img2)
elif data & 0x07 == 0x4: # north
img = self.build_full_block(side_t.rotate(90) ,None ,None , piston_t, side_t.rotate(270))
alpha_over(img, h_stick.transpose(Image.FLIP_LEFT_RIGHT), (0,0), h_stick.transpose(Image.FLIP_LEFT_RIGHT))
elif data & 0x07 == 0x5: # south
img = Image.new("RGBA", (24,24), self.bgcolor)
img2 = self.build_full_block(side_t.rotate(270) ,None ,None ,None, side_t.rotate(90))
alpha_over(img, temp, (2, 2), temp)
alpha_over(img, h_stick, (6, 3), h_stick)
elif data & 0x07 == 0x3: # south
img = Image.new("RGBA", (24, 24), self.bgcolor)
img2 = self.build_full_block(side_t.rotate(180), None, None, side_t.rotate(270), piston_t)
alpha_over(img, h_stick, (0, 0), h_stick)
alpha_over(img, img2, (0, 0), img2)
elif data & 0x07 == 0x4: # west
img = self.build_full_block(side_t.rotate(90), None, None, piston_t, side_t.rotate(270))
h_stick = h_stick.transpose(Image.FLIP_LEFT_RIGHT)
alpha_over(img, h_stick, (0, 0), h_stick)
elif data & 0x07 == 0x5: # east
img = Image.new("RGBA", (24, 24), self.bgcolor)
img2 = self.build_full_block(side_t.rotate(270), None, None, None, side_t.rotate(90))
h_stick = h_stick.transpose(Image.FLIP_LEFT_RIGHT)
temp = self.transform_image_side(back_t)
alpha_over(img2, temp, (10,2), temp)
alpha_over(img, img2, (0,0), img2)
alpha_over(img, h_stick.transpose(Image.FLIP_LEFT_RIGHT), (-3,2), h_stick.transpose(Image.FLIP_LEFT_RIGHT))
alpha_over(img2, temp, (10, 2), temp)
alpha_over(img, img2, (0, 0), img2)
alpha_over(img, h_stick, (-3, 2), h_stick)
return img
# cobweb
sprite(blockid=30, imagename="assets/minecraft/textures/block/cobweb.png", nospawn=True)

View File

@@ -1029,9 +1029,14 @@ class RegionSet(object):
data = {'east': 6, 'west': 6, 'south': 5, 'north': 5}[facing]
elif key == 'minecraft:nether_wart':
data = int(palette_entry['Properties']['age'])
elif key.endswith('shulker_box') or key.endswith('piston') or key in ['minecraft:observer', 'minecraft:dropper', 'minecraft:dispenser']:
facing = palette_entry['Properties']['facing']
data = {'down': 0, 'up': 1, 'north': 2, 'south': 3, 'west': 4, 'east': 5}[facing]
elif (key.endswith('shulker_box') or key.endswith('piston') or
key in ['minecraft:observer', 'minecraft:dropper', 'minecraft:dispenser',
'minecraft:piston_head']):
p = palette_entry['Properties']
data = {'down': 0, 'up': 1, 'north': 2, 'south': 3, 'west': 4, 'east': 5}[p['facing']]
if ((key.endswith('piston') and p.get('extended', 'false') == 'true') or
(key == 'minecraft:piston_head' and p.get('type', 'normal') == 'sticky')):
data |= 0x08
elif key.endswith('_log') or key.endswith('_wood') or key == 'minecraft:bone_block':
axis = palette_entry['Properties']['axis']
if axis == 'x':