Add signposts. Add transform_image_angle function.
This commit is contained in:
90
textures.py
90
textures.py
@@ -19,7 +19,7 @@ import os.path
|
|||||||
import zipfile
|
import zipfile
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
import math
|
import math
|
||||||
|
from random import randint
|
||||||
import numpy
|
import numpy
|
||||||
from PIL import Image, ImageEnhance, ImageOps, ImageDraw
|
from PIL import Image, ImageEnhance, ImageOps, ImageDraw
|
||||||
|
|
||||||
@@ -191,6 +191,46 @@ def transform_image_slope(img, blockID=None):
|
|||||||
return newimg
|
return newimg
|
||||||
|
|
||||||
|
|
||||||
|
def transform_image_angle(img, angle, blockID=None):
|
||||||
|
"""Takes an image an shears it in arbitrary angle with the axis of
|
||||||
|
rotation being vertical.
|
||||||
|
|
||||||
|
WARNING! Don't use angle = pi/2 (or multiplies), it will return
|
||||||
|
a blank image (or maybe garbage).
|
||||||
|
|
||||||
|
NOTE: angle is in the image not in game, so for the left side of a
|
||||||
|
block angle = 30 degree.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Take the same size as trasform_image_side
|
||||||
|
img = img.resize((12,12), Image.ANTIALIAS)
|
||||||
|
|
||||||
|
# some values
|
||||||
|
cos_angle = math.cos(angle)
|
||||||
|
sin_angle = math.sin(angle)
|
||||||
|
|
||||||
|
# function_x and function_y are used to keep the result image in the
|
||||||
|
# same position, and constant_x and constant_y are the coordinates
|
||||||
|
# for the center for angle = 0.
|
||||||
|
constant_x = 6.
|
||||||
|
constant_y = 6.
|
||||||
|
function_x = 6.*(1-cos_angle)
|
||||||
|
function_y = -6*sin_angle
|
||||||
|
big_term = ( (sin_angle * (function_x + constant_x)) - cos_angle* (function_y + constant_y))/cos_angle
|
||||||
|
|
||||||
|
# The numpy array is not really used, but is helpful to
|
||||||
|
# see the matrix used for the transformation.
|
||||||
|
transform = numpy.array([[1./cos_angle, 0, -(function_x + constant_x)/cos_angle],
|
||||||
|
[-sin_angle/(cos_angle), 1., big_term ],
|
||||||
|
[0, 0, 1.]])
|
||||||
|
|
||||||
|
transform = tuple(transform[0]) + tuple(transform[1])
|
||||||
|
|
||||||
|
newimg = img.transform((24,24), Image.AFFINE, transform)
|
||||||
|
|
||||||
|
return newimg
|
||||||
|
|
||||||
|
|
||||||
def _build_block(top, side, blockID=None):
|
def _build_block(top, side, blockID=None):
|
||||||
"""From a top texture and a side texture, build a block image.
|
"""From a top texture and a side texture, build a block image.
|
||||||
top and side should be 16x16 image objects. Returns a 24x24 image
|
top and side should be 16x16 image objects. Returns a 24x24 image
|
||||||
@@ -982,6 +1022,49 @@ def generate_special_texture(blockID, data):
|
|||||||
return (img.convert("RGB"), img.split()[3])
|
return (img.convert("RGB"), img.split()[3])
|
||||||
|
|
||||||
|
|
||||||
|
if blockID == 63: # singposts
|
||||||
|
|
||||||
|
texture = terrain_images[4].copy()
|
||||||
|
# cut the wood to the size of a signpost
|
||||||
|
ImageDraw.Draw(texture).rectangle((0,12,15,15),outline=(0,0,0,0),fill=(0,0,0,0))
|
||||||
|
|
||||||
|
# If the signpost is looking directly to the image, draw some
|
||||||
|
# random dots, they will look as text.
|
||||||
|
if data in (0,1,2,3,4,5,15):
|
||||||
|
for i in range(15):
|
||||||
|
x = randint(4,11)
|
||||||
|
y = randint(3,7)
|
||||||
|
texture.putpixel((x,y),(0,0,0,255))
|
||||||
|
|
||||||
|
# Minecraft uses wood texture for the signpost stick
|
||||||
|
texture_stick = terrain_images[20]
|
||||||
|
texture_stick = texture_stick.resize((12,12), Image.ANTIALIAS)
|
||||||
|
ImageDraw.Draw(texture_stick).rectangle((2,0,12,12),outline=(0,0,0,0),fill=(0,0,0,0))
|
||||||
|
|
||||||
|
img = Image.new("RGBA", (24,24), (38,92,255,0))
|
||||||
|
|
||||||
|
# W N ~90 E S ~270
|
||||||
|
angles = (330.,345.,0.,15.,30.,55.,95.,120.,150.,165.,180.,195.,210.,230.,265.,310.)
|
||||||
|
angle = math.radians(angles[data])
|
||||||
|
post = transform_image_angle(texture, angle)
|
||||||
|
|
||||||
|
# choose the position of the "3D effect"
|
||||||
|
incrementx = 0
|
||||||
|
if data in (1,6,7,8,9,14):
|
||||||
|
incrementx = -1
|
||||||
|
elif data in (3,4,5,11,12,13):
|
||||||
|
incrementx = +1
|
||||||
|
|
||||||
|
composite.alpha_over(img, texture_stick,(11, 8),texture_stick)
|
||||||
|
# post2 is a brighter signpost pasted with a small sift,
|
||||||
|
# gives to the signpost some 3D effect.
|
||||||
|
post2 = ImageEnhance.Brightness(post).enhance(1.2)
|
||||||
|
composite.alpha_over(img, post2,(incrementx, -3),post2)
|
||||||
|
composite.alpha_over(img, post, (0,-2), post)
|
||||||
|
|
||||||
|
return (img.convert("RGB"), img.split()[3])
|
||||||
|
|
||||||
|
|
||||||
if blockID in (64,71): #wooden door, or iron door
|
if blockID in (64,71): #wooden door, or iron door
|
||||||
if data & 0x8 == 0x8: # top of the door
|
if data & 0x8 == 0x8: # top of the door
|
||||||
raw_door = terrain_images[81 if blockID == 64 else 82]
|
raw_door = terrain_images[81 if blockID == 64 else 82]
|
||||||
@@ -1492,8 +1575,8 @@ def getBiomeData(worlddir, chunkX, chunkY):
|
|||||||
# please, if possible, keep the ascending order of blockid value)
|
# please, if possible, keep the ascending order of blockid value)
|
||||||
|
|
||||||
special_blocks = set([ 2, 6, 9, 17, 18, 26, 23, 27, 28, 35, 43, 44, 50,
|
special_blocks = set([ 2, 6, 9, 17, 18, 26, 23, 27, 28, 35, 43, 44, 50,
|
||||||
51, 53, 54, 55, 58, 59, 61, 62, 64, 65, 66, 67, 71,
|
51, 53, 54, 55, 58, 59, 61, 62, 63, 64, 65, 66, 67,
|
||||||
75, 76, 85, 86, 90, 91, 92, 93, 94])
|
71, 75, 76, 85, 86, 90, 91, 92, 93, 94])
|
||||||
|
|
||||||
# this is a map of special blockIDs to a list of all
|
# this is a map of special blockIDs to a list of all
|
||||||
# possible values for ancillary data that it might have.
|
# possible values for ancillary data that it might have.
|
||||||
@@ -1519,6 +1602,7 @@ special_map[58] = (0,) # crafting table
|
|||||||
special_map[59] = range(8) # crops, grow from 0 to 7
|
special_map[59] = range(8) # crops, grow from 0 to 7
|
||||||
special_map[61] = range(6) # furnace, orientation
|
special_map[61] = range(6) # furnace, orientation
|
||||||
special_map[62] = range(6) # burning furnace, orientation
|
special_map[62] = range(6) # burning furnace, orientation
|
||||||
|
special_map[63] = range(16) # signpost, orientation
|
||||||
special_map[64] = range(16) # wooden door, open/close and orientation
|
special_map[64] = range(16) # wooden door, open/close and orientation
|
||||||
special_map[65] = (2,3,4,5) # ladder, orientation
|
special_map[65] = (2,3,4,5) # ladder, orientation
|
||||||
special_map[66] = range(10) # minecrart tracks, orientation, slope
|
special_map[66] = range(10) # minecrart tracks, orientation, slope
|
||||||
|
|||||||
Reference in New Issue
Block a user