Compare commits

...

5 Commits

Author SHA1 Message Date
sfan5 0dc15ea360 Fix nodedef_gen and make texturing work maybe 2017-02-12 19:41:46 +01:00
sfan5 bd1e45fe26 Fix small oversight 2016-08-10 22:46:46 +02:00
sfan5 3b7f08a4f9 Add model for plants 2016-08-10 14:31:34 +02:00
sfan5 43b0c172f9 Structure code 2016-08-10 13:38:48 +02:00
sfan5 b695c14bf2 Allow specifying location of nodes.txt using -n 2016-08-10 12:21:33 +02:00
9 changed files with 267 additions and 543 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
*~ *~
*.bak *.bak
nodes.txt

1
models/plant.mtl Symbolic link
View File

@ -0,0 +1 @@
cube.mtl

15
models/plant.obj Normal file
View File

@ -0,0 +1,15 @@
v 0 1 1
v 0 0 1
v 1 1 0
v 1 0 0
v 1 1 1
v 1 0 1
v 0 1 0
v 0 0 0
# TODO: work out how this works with texturing
vn 0.7 0 0.7
vn 0.7 0 -0.7
f -8//-2 -7//-2 -5//-2 -6//-2
f -4//-1 -3//-1 -1//-1 -2//-1

227
mt2obj.py
View File

@ -26,6 +26,12 @@ import re
def str2bool(text): def str2bool(text):
return text.strip().lower() in ["1", "true", "yes"] return text.strip().lower() in ["1", "true", "yes"]
def getarg(optargs, name, default=None):
for a in optargs:
if a[0] == name:
return a[1]
return default
def splitinto(text, delim, n): def splitinto(text, delim, n):
ret = text.split(delim) ret = text.split(delim)
if len(ret) <= n: if len(ret) <= n:
@ -55,6 +61,8 @@ def convert(desc, vals):
out += int(val, 16), out += int(val, 16),
elif c == 'b': # bool elif c == 'b': # bool
out += str2bool(val), out += str2bool(val),
elif c == 'A': # special: arglist
out += parse_arglist(val),
i += 1 i += 1
return out return out
@ -88,6 +96,32 @@ def parse_arglist(s):
out[tmp1] = tmp2 out[tmp1] = tmp2
return out return out
class MtsReader():
def __init__(self):
self.dim = (0, 0, 0) # W x H x D
self.namemap = {}
self.data = b""
def decode(self, f):
assert(f.mode == "rb")
if f.read(4) != b"MTSM":
raise Exception("Incorrect magic value, this isn't a schematic!")
ver = struct.unpack("!H", f.read(2))[0]
if ver not in (3, 4):
raise Exception("Wrong file version: got %d, expected 3 or 4" % ver)
self.dim = struct.unpack("!HHH", f.read(6))
f.seek(self.dim[1], 1) # skip some stuff
count = struct.unpack("!H", f.read(2))[0]
for i in range(count):
l = struct.unpack("!H", f.read(2))[0]
self.namemap[i] = f.read(l).decode("ascii")
self.data = zlib.decompress(f.read())
def dimensions(self):
return self.dim
def getnode(self, x, y, z):
off = (x + y*self.dim[0] + z*self.dim[0]*self.dim[1]) * 2
nid = struct.unpack("!H", self.data[off:off+2])[0]
return self.namemap[nid]
class PreprocessingException(Exception): class PreprocessingException(Exception):
pass pass
@ -124,6 +158,8 @@ class Preprocessor():
for m in re.finditer(r'{([a-zA-Z0-9_-]+)}', line): for m in re.finditer(r'{([a-zA-Z0-9_-]+)}', line):
name = m.group(1) name = m.group(1)
if name not in self.vars.keys(): if name not in self.vars.keys():
# TODO: this is currently required as undefined vars can
# occur in ifdef sections (which are processed later)
tmp += line[last:m.start()] + "???" tmp += line[last:m.start()] + "???"
last = m.end() last = m.end()
continue continue
@ -144,7 +180,6 @@ class Preprocessor():
if inst == "define": if inst == "define":
args = self._splitinto(args, " ", 2) args = self._splitinto(args, " ", 2)
self.vars[args[0]] = args[1] self.vars[args[0]] = args[1]
return None
elif inst == "if": elif inst == "if":
self._assertne(args) self._assertne(args)
self.state = 1 if str2bool(args) else 2 self.state = 1 if str2bool(args) else 2
@ -165,121 +200,103 @@ class Preprocessor():
return None return None
return line return line
nodetbl = {} def usage():
r_entry = re.compile(r'^(\S+) (\S+) (\d+) (\d+) (\d+) (\S+)(?: (\d+))?$')
f = open("nodes.txt", "r")
for l in f:
m = r_entry.match(l)
nodetbl[m.group(1)] = convert('siiisi', m.groups()[1:])
f.close()
optargs, args = getopt.getopt(sys.argv[1:], 't')
# TODO: structure code below
if len(args) < 1:
print("Usage: %s <.mts schematic>" % sys.argv[0]) print("Usage: %s <.mts schematic>" % sys.argv[0])
print("Converts .mts schematics to Wavefront .obj geometry files") print("Converts .mts schematics to Wavefront .obj geometry files")
print("")
print("Output files are written into directory of source file.") print("Output files are written into directory of source file.")
print('') print("")
print('Options:') print("Options:")
print('\t-t\t\tEnable textures') print(" -t Enable textures")
print(" -n Set path to nodes.txt")
exit(1) exit(1)
else:
sch = open(args[0], "rb")
if sch.read(4) != b"MTSM": optargs, args = getopt.getopt(sys.argv[1:], 'tn:')
print("This file does not look like an MTS schematic..") if len(args) != 1:
usage()
nodetbl = {}
r_entry = re.compile(r'(\S+) (\S+) (\d+) (\d+) (\d+) (\S+)(?: (\d+))?')
with open(getarg(optargs, "-n", default="nodes.txt"), "r") as f:
for line in f:
m = r_entry.match(line)
nodetbl[m.group(1)] = convert('siiiAi', m.groups()[1:])
schem = MtsReader()
with open(args[0], "rb") as f:
try:
schem.decode(f)
except Exception as e:
print(str(e), file=sys.stderr)
exit(1) exit(1)
v = struct.unpack("!H", sch.read(2))[0]
if v != 4: filepart = ".".join(args[0].split(".")[:-1])
print("Wrong file version: got %d, expected %d" % (v, 4)) objfile = filepart + ".obj"
exit(1) mtlfile = filepart + ".mtl"
width, height, depth = struct.unpack("!HHH", sch.read(6))
sch.seek(height, 1) nodes_seen = set()
nodecount = struct.unpack("!H", sch.read(2))[0] with open(objfile, "w") as obj:
nodemap = {} obj.write("# Exported by mt2obj (https://github.com/sfan5/mt2obj)\nmtllib %s\n\n\n" % mtlfile)
for i in range(nodecount):
l = struct.unpack("!H", sch.read(2))[0]
name = sch.read(l).decode('ascii')
nodemap[i] = name
# TODO use zlib.decompressobj() instead of decompressing everything at once
cdata = sch.read()
sch.close()
data = zlib.decompress(cdata)
del cdata
filepart = args[0][:args[0].find(".")]
obj = open(filepart + ".obj", "w")
obj.write("# Exported by mt2obj\nmtllib %s\n\n\n" % (filepart + ".mtl", ))
i = 0 i = 0
foundnodes = [] for x in range(schem.dimensions()[0]):
unknownnodes = [] for y in range(schem.dimensions()[1]):
for x in range(width): for z in range(schem.dimensions()[2]):
for y in range(height): node = schem.getnode(x, y, z)
for z in range(depth): if node == "air":
off = (x + y*width + z*width*height) * 2
nid = struct.unpack("!H", data[off:off + 2])[0]
nname = nodemap[nid]
if nname == "air":
continue continue
if not nname in nodetbl.keys(): nodes_seen.add(node)
if not nname in unknownnodes: if node not in nodetbl.keys():
unknownnodes.append(nname)
continue continue
else: obj.write("o node%d\nusemtl %s\n" % (i, node.replace(":", "__")))
if not nname in foundnodes: with open("models/%s.obj" % nodetbl[node][0], "r") as objdef:
foundnodes.append(nname) pp = Preprocessor(omit_empty=True)
obj.write("o node%d\n" % i) pp.addvars(nodetbl[node][4])
obj.write("usemtl %s\n" % nname.replace(":", "__")) pp.setvar("TEXTURES", "1" if getarg(optargs, "-t") == "" else "0")
objd = open("models/" + nodetbl[nname][0] + ".obj", 'r') for line in objdef:
pp = Preprocessor(omit_empty=True) line = pp.process(line.rstrip("\r\n"))
pp.addvars(parse_arglist(nodetbl[nname][4])) if line is None:
pp.setvar("TEXTURES", str(('-t', '') in optargs)) continue
for line in objd: # Translate vertice coordinates
line = pp.process(line[:-1]) if line.startswith("v "):
if line is None: vx, vy, vz = (float(e) for e in line.split(" ")[1:])
continue vx += x
if line.startswith("v "): vy += y
tmp = line.split(" ") vz += z
vx, vy, vz = float(tmp[1]), float(tmp[2]), float(tmp[3]) obj.write("v %.1f %.1f %.1f\n" % (vx, vy, vz))
vx += x else:
vy += y obj.write(line)
vz += z obj.write("\n")
obj.write("v %.1f %.1f %.1f\n" % (vx, vy, vz))
else:
obj.write(line + "\n")
del pp
objd.close()
obj.write("\n") obj.write("\n")
i += 1 i += 1
obj.close()
mtl = open(filepart + ".mtl", "w") with open(mtlfile, "w") as mtl:
mtl.write("# Generated by mt2obj\n\n") mtl.write("# Generated by mt2obj (https://github.com/sfan5/mt2obj)\n\n")
for node in foundnodes: for node in nodes_seen:
if node not in nodetbl.keys():
continue
mtl.write("newmtl %s\n" % node.replace(":", "__")) mtl.write("newmtl %s\n" % node.replace(":", "__"))
c = nodetbl[node] c = nodetbl[node]
mtld = open("models/" + nodetbl[node][0] + ".mtl", 'r') with open("models/%s.mtl" % c[0], "r") as mtldef:
pp = Preprocessor(omit_empty=True) pp = Preprocessor(omit_empty=True)
pp.addvars(parse_arglist(nodetbl[node][4])) pp.addvars(c[4])
pp.addvars({ pp.addvars({
'r': str(c[1]/255), "r": str(c[1]/255),
'g': str(c[2]/255), "g": str(c[2]/255),
'b': str(c[3]/255), "b": str(c[3]/255),
'a': str(c[5]/255 if len(c) > 5 else 1.0), "a": str(c[5]/255 if len(c) > 5 else 1.0),
'TEXTURES': str(('-t', '') in optargs), "TEXTURES": "1" if getarg(optargs, "-t") == "" else "0",
}) })
for line in mtld: for line in mtldef:
line = pp.process(line[:-1]) line = pp.process(line.rstrip("\r\n"))
if line is None: if line is None:
continue continue
mtl.write(line + "\n") mtl.write(line + "\n")
del pp
mtl.write("\n") mtl.write("\n")
mtld.close()
mtl.close() nodes_unknown = nodes_seen - set(nodetbl.keys())
if len(unknownnodes) > 0: if len(nodes_unknown) > 0:
print("There were some unknown nodes that were ignored during the conversion:") print("There were some unknown nodes that were ignored during conversion:")
for e in unknownnodes: for node in nodes_unknown:
print(e) print(" " + node)

View File

@ -1,46 +1,54 @@
local function nd_get_tiles(nd) local function nd_get_tiles(nd)
local tiles local tiles = nd.tiles or nd.tile_images or {}
if nd.tiles then for k,v in ipairs(tiles) do
tiles = nd.tiles if type(v) == 'table' then
elseif nd.tile_images then tiles[k] = v.name
tiles = nd.tile_images end
end
--if type(tiles) == 'table' then
-- tiles = tiles.name
--end
if tiles == nil then
tiles = {}
end end
return tiles return tiles
end end
local function nd_get_drawtype(nd)
return nd.drawtype or "normal"
end
local drawtype_map = {
["normal"] = "cube",
["plantlike"] = "plant",
-- do these actually work?
["glasslike"] = "cube",
["allfaces"] = "cube",
["allfaces_optional"] = "cube",
}
minetest.register_chatcommand("dump", { minetest.register_chatcommand("dump", {
params = "", params = "",
description = "", description = "",
func = function(plname, param) func = function(plname, param)
local n = 0 local n = 0
local out, err = io.open('nodes.pre.txt', 'wb') minetest.mkdir("out")
local out, err = io.open('out/nodes.pre.txt', 'wb')
if not out then if not out then
return minetest.chat_send_player(plname, 'io.open: ' .. err) return minetest.chat_send_player(plname, 'io.open: ' .. err)
end end
for nn, nd in pairs(minetest.registered_nodes) do for nn, nd in pairs(minetest.registered_nodes) do
if nd.drawtype == nil or nd.drawtype == "normal" then local tiles = nd_get_tiles(nd)
local tiles = nd_get_tiles(nd) local mapped = drawtype_map[nd_get_drawtype(nd)]
local texprefix = nn:gsub(":", "__") if mapped ~= nil and #tiles > 0 then
--[[ local texfilename = nn:gsub(":", "__") .. ".png"
for i, t in ipairs(tiles) do local usable_tex
minetest.generateAndSaveTexture(t, texprefix .. i .. ".png") if #tiles == 1 then -- TODO multiple tiles
end usable_tex = texfilename
--]]
if #tiles == 1 then
out:write(nn .. " cube - - - texture=" .. texprefix .. ".png " .. texprefix .. ".png\n")
minetest.generateAndSaveTexture(tiles[1], texprefix .. ".png")
n = n + 1
else
-- TODO
end end
minetest.generateAndSaveTexture(tiles[1], "out/" .. texfilename)
usable_tex = usable_tex and ("texture=" .. usable_tex) or ":"
out:write(string.format("%s %s - - - %s %s\n", nn, mapped, usable_tex, texfilename))
n = n + 1
end end
end end
out:close() out:close()
minetest.chat_send_player(plname, n .. " nodes dumped.") minetest.chat_send_player(plname, n .. " nodes dumped.")
end, end,

81
nodedef_gen/minetest.diff Normal file
View File

@ -0,0 +1,81 @@
diff --git a/src/game.cpp b/src/game.cpp
index 1735737d..1f1d8826 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -1876,6 +1876,9 @@ void Game::shutdown()
****************************************************************************/
/****************************************************************************/
+IWritableTextureSource *g_tsrc;
+video::IVideoDriver *g_driver;
+
bool Game::init(
const std::string &map_dir,
std::string *address,
@@ -1883,8 +1886,10 @@ bool Game::init(
const SubgameSpec &gamespec)
{
showOverlayMessage(wgettext("Loading..."), 0, 0);
+ g_driver = driver;
texture_src = createTextureSource(device);
+ g_tsrc = texture_src;
shader_src = createShaderSource(device);
itemdef_manager = createItemDefManager();
diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp
index c2679164..af3f145a 100644
--- a/src/script/lua_api/l_util.cpp
+++ b/src/script/lua_api/l_util.cpp
@@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "util/base64.h"
#include "config.h"
#include "version.h"
+#include "client/tile.h"
#include <algorithm>
@@ -486,6 +487,21 @@ int ModApiUtil::l_get_version(lua_State *L)
return 1;
}
+extern IWritableTextureSource *g_tsrc;
+extern irr::video::IVideoDriver *g_driver;
+
+// generateAndSaveTexture(texture_name, out_filename)
+int ModApiUtil::l_generateAndSaveTexture(lua_State *L)
+{
+ std::string texname = luaL_checkstring(L, 1);
+ std::string outfile = luaL_checkstring(L, 2);
+
+ irr::video::IImage *img = g_tsrc->generateImage(texname);
+ g_driver->writeImageToFile(img, outfile.c_str());
+
+ return 0;
+}
+
void ModApiUtil::Initialize(lua_State *L, int top)
{
@@ -524,6 +540,7 @@ void ModApiUtil::Initialize(lua_State *L, int top)
API_FCT(decode_base64);
API_FCT(get_version);
+ API_FCT(generateAndSaveTexture);
}
void ModApiUtil::InitializeAsync(AsyncEngine& engine)
diff --git a/src/script/lua_api/l_util.h b/src/script/lua_api/l_util.h
index 9910704b..8ac49848 100644
--- a/src/script/lua_api/l_util.h
+++ b/src/script/lua_api/l_util.h
@@ -107,6 +107,9 @@ class ModApiUtil : public ModApiBase {
// get_version()
static int l_get_version(lua_State *L);
+ // generateAndSaveTexture(texture_name, out_filename)
+ static int l_generateAndSaveTexture(lua_State *L);
+
public:
static void Initialize(lua_State *L, int top);

View File

@ -1,114 +0,0 @@
From e6e2c06760597fd712fe2cc7c56751bcb6a0036c Mon Sep 17 00:00:00 2001
From: sfan5 <sfan5@live.de>
Date: Fri, 3 Oct 2014 11:24:16 +0200
Subject: [PATCH] Add minetest.generateAndSaveTexture
---
src/game.cpp | 5 +++++
src/script/lua_api/l_util.cpp | 18 ++++++++++++++++++
src/script/lua_api/l_util.h | 3 +++
src/tile.h | 1 +
4 files changed, 27 insertions(+)
diff --git a/src/game.cpp b/src/game.cpp
index a8f6bc9..f4ef64f 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -1119,6 +1119,9 @@ static void updateChat(Client& client, f32 dtime, bool show_debug,
show_chat && recent_chat_count != 0 && !show_profiler);
}
+IWritableTextureSource *g_tsrc;
+video::IVideoDriver *g_driver;
+
/******************************************************************************/
void the_game(bool &kill, bool random_input, InputHandler *input,
IrrlichtDevice *device, gui::IGUIFont* font, std::string map_dir,
@@ -1130,6 +1133,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
{
GUIFormSpecMenu* current_formspec = 0;
video::IVideoDriver* driver = device->getVideoDriver();
+ g_driver = driver;
scene::ISceneManager* smgr = device->getSceneManager();
// Calculate text height using the font
@@ -1147,6 +1151,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
// Create texture source
IWritableTextureSource *tsrc = createTextureSource(device);
+ g_tsrc = tsrc;
// Create shader source
IWritableShaderSource *shsrc = createShaderSource(device);
diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp
index eb6c183..91fe581 100644
--- a/src/script/lua_api/l_util.cpp
+++ b/src/script/lua_api/l_util.cpp
@@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "tool.h"
#include "filesys.h"
#include "settings.h"
+#include "tile.h"
#include "main.h" //required for g_settings, g_settings_path
// debug(...)
@@ -320,6 +321,21 @@ int ModApiUtil::l_decompress(lua_State *L)
return 1;
}
+extern IWritableTextureSource *g_tsrc;
+extern irr::video::IVideoDriver *g_driver;
+
+// generateAndSaveTexture(texture_name, out_filename)
+int ModApiUtil::l_generateAndSaveTexture(lua_State *L)
+{
+ std::string texname = luaL_checkstring(L, 1);
+ std::string outfile = luaL_checkstring(L, 2);
+
+ irr::video::IImage *img = g_tsrc->generateImage(texname);
+ g_driver->writeImageToFile(img, outfile.c_str());
+
+ return 0;
+}
+
void ModApiUtil::Initialize(lua_State *L, int top)
{
API_FCT(debug);
@@ -345,6 +361,8 @@ void ModApiUtil::Initialize(lua_State *L, int top)
API_FCT(compress);
API_FCT(decompress);
+
+ API_FCT(generateAndSaveTexture);
}
void ModApiUtil::InitializeAsync(AsyncEngine& engine)
diff --git a/src/script/lua_api/l_util.h b/src/script/lua_api/l_util.h
index e824323..d656171 100644
--- a/src/script/lua_api/l_util.h
+++ b/src/script/lua_api/l_util.h
@@ -87,6 +87,9 @@ class ModApiUtil : public ModApiBase {
// decompress(data, method, ...)
static int l_decompress(lua_State *L);
+ // generateAndSaveTexture(texture_name, out_filename)
+ static int l_generateAndSaveTexture(lua_State *L);
+
public:
static void Initialize(lua_State *L, int top);
diff --git a/src/tile.h b/src/tile.h
index 78aaef0..7bd0b60 100644
--- a/src/tile.h
+++ b/src/tile.h
@@ -123,6 +123,7 @@ class IWritableTextureSource : public ITextureSource
virtual bool isKnownSourceImage(const std::string &name)=0;
virtual video::ITexture* generateTextureFromMesh(
const TextureFromMeshParams &params)=0;
+ virtual video::IImage* generateImage(const std::string &name)=0;
virtual void processQueue()=0;
virtual void insertSourceImage(const std::string &name, video::IImage *img)=0;
--
2.1.2

View File

@ -1,28 +1,26 @@
#!/usr/bin/env python #!/usr/bin/env python3
import sys import sys
from PIL import Image from PIL import Image
def avg2(a, b): def mix(a, b):
return int((a + b) / 2.0) return (
(a[0] + b[0]) / 2,
def avg2t3i0(a, b): (a[1] + b[1]) / 2,
return tuple(avg2(t[0], t[1]) for t in zip(a[:3], b[:3])) (a[2] + b[2]) / 2
)
def avgcolor(name): def avgcolor(name):
inp = Image.open(name) inp = Image.open(name).convert('RGBA')
inp = inp.convert('RGBA')
ind = inp.load() ind = inp.load()
avgc = -1 avgc = None
for x in range(inp.size[0]): for x in range(inp.size[0]):
for y in range(inp.size[1]): for y in range(inp.size[1]):
pxl = ind[x, y] pxl = ind[x, y]
if pxl[3] < 128: if pxl[3] < 128:
continue continue
if avgc == -1: pxl = pxl[:3]
avgc = pxl[:3] avgc = pxl if avgc is None else mix(avgc, pxl)
else: if avgc is None:
avgc = avg2t3i0(avgc, pxl)
if avgc == -1:
return "0 0 0" return "0 0 0"
else: else:
return "%d %d %d" % avgc return "%d %d %d" % avgc
@ -33,7 +31,7 @@ else:
fin = open(sys.argv[1], "r") fin = open(sys.argv[1], "r")
fout = open(sys.argv[2], "w") fout = open(sys.argv[2], "w")
for line in fin: for line in fin:
line = line[:-1] # cut off the \n line = line.rstrip("\n")
# nodename modelname r g b params texture # nodename modelname r g b params texture
# ^ ^ ^ ^^^^^^^ # ^ ^ ^ ^^^^^^^
a = line.split(" ") a = line.split(" ")

283
nodes.txt
View File

@ -1,283 +0,0 @@
beds:bed_top_red cube 131 22 22 :
beds:bed_bottom_blue cube 10 11 122 :
beds:bed_bottom_grey cube 147 147 147 :
beds:bed_bottom_white cube 215 215 215 :
beds:bed_bottom_green cube 12 92 10 :
beds:bed_bottom_orange cube 217 123 10 :
beds:bed_top_blue cube 11 12 122 :
beds:bed_bottom_violet cube 129 10 180 :
beds:bed_top_green cube 13 92 11 :
beds:bed_bottom_black cube 10 10 10 :
beds:bed_bottom_yellow cube 215 214 0 :
beds:bed_bottom_red cube 131 21 21 :
beds:bed_top_white cube 215 215 215 :
beds:bed_top_yellow cube 215 214 0 :
beds:bed_top_violet cube 129 11 180 :
beds:bed_top_grey cube 147 147 147 :
beds:bed_top_black cube 11 11 11 :
beds:bed_top_orange cube 216 123 11 :
nuke:hardcore_mese_tnt cube 173 173 0 :
nuke:iron_tnt cube 158 158 157 :
nuke:hardcore_iron_tnt cube 158 158 157 :
nuke:mese_tnt cube 173 173 0 :
christmas:present_green_violet cube 189 36 157 :
christmas:present_blue_green cube 62 186 50 :
christmas:present_orange_green cube 62 186 50 :
christmas:tree cube 45 36 24 :
christmas:present_orange_violet cube 189 36 157 :
christmas:present_blue_orange cube 245 207 20 :
christmas:present_blue_violet cube 189 36 157 :
christmas:star cube 236 252 55 :
christmas:present_green_orange cube 245 207 20 :
christmas:leaves cube 33 54 30 :
snow:moss cube 51 64 29 :
snow:snow5 cube 225 227 255 :
snow:snow3 cube 225 227 255 :
snow:needles_decorated cube 7 50 19 :
snow:needles cube 6 49 18 :
snow:snow8 cube 225 227 255 :
snow:star cube 214 142 0 :
snow:snow cube 225 227 255 :
snow:xmas_tree cube 87 88 28 :
snow:sapling_pine cube 3 54 20 :
snow:snow6 cube 225 227 255 :
snow:snow_block cube 225 227 255 :
snow:snow7 cube 225 227 255 :
snow:snow_brick cube 223 225 253 :
snow:dirt_with_snow cube 225 227 255 :
snow:snow4 cube 225 227 255 :
snow:snow2 cube 225 227 255 :
snow:ice cube 155 155 254 :
stairs:stair_wood_tile_full cube 78 64 44 :
stairs:stair_mossycobble cube 102 116 85 :
stairs:slab_jungle_wood cube 51 35 12 :
stairs:slab_wood_tile_center cube 128 100 57 :
stairs:stair_wood_tile cube 78 65 44 :
stairs:stair_cobble cube 133 133 133 :
stairs:slab_invisible cube 0 0 0 :
stairs:stair_stonebrick cube 104 100 99 :
stairs:slab_iron_glass cube 222 222 222 :
stairs:stair_wood cube 128 100 57 :
stairs:stair_stone cube 91 88 87 :
stairs:stair_obsidian cube 16 16 16 :
stairs:stair_copperblock cube 110 86 60 :
stairs:stair_super_glow_glass cube 255 255 120 :
stairs:slab_iron_stone cube 134 134 134 :
stairs:stair_stone_tile cube 97 97 97 :
stairs:stair_desert_stone cube 122 74 57 :
stairs:slab_bronzeblock cube 116 70 26 :
stairs:stair_goldblock cube 126 116 35 :
stairs:stair_iron_checker cube 142 142 142 :
stairs:stair_steelblock cube 153 153 153 :
stairs:slab_coal_stone cube 70 70 70 :
stairs:slab_obsidian_glass cube 16 17 17 :
stairs:stair_sandstone cube 180 162 121 :
stairs:stair_iron_stone cube 134 134 134 :
stairs:slab_steelblock cube 153 153 153 :
stairs:stair_split_stone_tile cube 97 97 97 :
stairs:stair_brick cube 156 157 151 :
stairs:stair_sandstonebrick cube 160 144 108 :
stairs:slab_mossycobble cube 102 116 85 :
stairs:stair_glass cube 192 192 227 :
stairs:slab_cactus_checker cube 130 138 130 :
stairs:slab_jungletree cube 120 106 78 :
stairs:stair_coal_stone cube 70 70 70 :
stairs:slab_junglewood cube 51 35 12 :
stairs:stair_jungletree cube 120 106 78 :
stairs:slab_wood cube 128 100 57 :
stairs:stair_iron_stone_bricks cube 104 98 97 :
stairs:stair_coal_checker cube 133 133 133 :
stairs:stair_plankstone cube 66 51 23 :
stairs:stair_obsidian_glass cube 16 17 17 :
stairs:slab_desert_stone cube 122 74 57 :
stairs:slab_iron_stone_bricks cube 104 98 97 :
stairs:slab_glass cube 192 192 227 :
stairs:stair_bronzeblock cube 116 70 26 :
stairs:slab_desert_stonebrick cube 105 64 49 :
stairs:slab_tree cube 66 52 35 :
stairs:slab_stone cube 91 88 87 :
stairs:stair_cactus_checker cube 130 138 130 :
stairs:slab_diamondblock cube 103 195 201 :
stairs:slab_super_glow_glass cube 255 255 120 :
stairs:slab_cobble cube 133 133 133 :
stairs:stair_tree cube 66 52 35 :
stairs:slab_wood_tile cube 78 65 44 :
stairs:slab_glow_glass cube 255 226 114 :
stairs:slab_wood_tile_full cube 78 64 44 :
stairs:stair_coal_stone_bricks cube 79 76 75 :
stairs:slab_coal_glass cube 130 130 130 :
stairs:stair_coal_glass cube 130 130 130 :
stairs:slab_brick cube 156 157 151 :
stairs:slab_stone_tile cube 97 97 97 :
stairs:slab_goldblock cube 126 116 35 :
stairs:slab_plankstone cube 66 51 23 :
stairs:slab_coal_stone_bricks cube 79 76 75 :
stairs:stair_jungle_wood cube 51 35 12 :
stairs:stair_circle_stone_bricks cube 91 88 87 :
stairs:slab_iron_checker cube 142 142 142 :
stairs:stair_wood_tile_center cube 128 100 57 :
stairs:slab_stonebrick cube 104 100 99 :
stairs:slab_sandstonebrick cube 160 144 108 :
stairs:stair_invisible cube 0 0 0 :
stairs:stair_iron_glass cube 222 222 222 :
stairs:stair_desert_stonebrick cube 105 64 49 :
stairs:stair_diamondblock cube 103 195 201 :
stairs:slab_sandstone cube 180 162 121 :
stairs:slab_copperblock cube 110 86 60 :
stairs:stair_glow_glass cube 255 226 114 :
stairs:stair_junglewood cube 51 35 12 :
stairs:slab_circle_stone_bricks cube 91 88 87 :
stairs:slab_obsidian cube 16 16 16 :
stairs:slab_coal_checker cube 133 133 133 :
stairs:slab_split_stone_tile cube 97 97 97 :
mg:savannawood cube 128 113 57 :
mg:pineleaves cube 16 30 14 :
mg:savannasapling cube 32 36 13 :
mg:pinewood cube 120 93 66 :
mg:pinetree cube 26 21 14 :
mg:savannaleaves cube 70 62 41 :
mg:pinesapling cube 12 12 5 :
mg:savannatree cube 52 51 37 :
mg:dirt_with_dry_grass cube 114 99 53 :
bones:bones cube 74 74 74 :
default:glass cube 192 192 227 : 64
default:water_flowing cube 39 66 106 : 128
default:junglesapling cube 37 34 14 :
default:sandstonebrick cube 160 144 108 :
default:furnace_active cube 97 93 91 :
default:sign_wall cube 163 141 106 :
default:lava_source cube 255 100 0 :
default:goldblock cube 126 116 35 :
default:obsidian_glass cube 16 17 17 : 64
default:stone_with_copper cube 91 88 87 :
default:grass_1 cube 72 109 32 :
default:papyrus cube 98 173 32 :
default:ice cube 155 155 254 :
default:wood cube 128 100 57 :
default:stone_with_mese cube 91 88 87 :
default:diamondblock cube 103 195 201 :
default:coalblock cube 58 58 58 :
default:stone_with_gold cube 91 88 87 :
default:apple cube 50 0 0 :
default:grass_4 cube 73 112 33 :
default:dirt_with_grass_footsteps cube 101 138 35 :
default:desert_stonebrick cube 105 64 49 :
default:cloud cube 255 255 255 :
default:stone_with_iron cube 91 88 87 :
default:bronzeblock cube 116 70 26 :
default:dirt_with_snow cube 225 227 255 :
default:fence_wood cube 128 100 57 :
default:desert_sand cube 209 165 97 :
default:steelblock cube 153 153 153 :
default:rail cube 114 82 33 :
default:nyancat_rainbow cube 58 19 128 :
default:lava_flowing cube 255 100 0 :
default:sapling cube 63 59 40 :
default:snow cube 225 227 255 :
default:furnace cube 97 93 91 :
default:desert_stone cube 122 74 57 :
default:tree cube 66 52 35 :
default:jungletree cube 120 106 78 :
default:cactus cube 132 143 108 :
default:water_source cube 39 66 106 : 128
default:mese cube 200 202 0 :
default:stone_with_coal cube 91 88 87 :
default:nyancat cube 38 16 66 :
default:snowblock cube 225 227 255 :
default:stonebrick cube 104 100 99 :
default:jungleleaves cube 18 25 14 :
default:sandstone cube 180 162 121 :
default:dirt_with_grass cube 72 107 44 :
default:brick cube 156 157 151 :
default:junglegrass cube 82 133 35 :
default:cobble cube 133 133 133 :
default:grass_3 cube 71 109 32 :
default:stone cube 91 88 87 :
default:sand cube 219 209 167 :
default:obsidian cube 16 16 16 :
default:bookshelf cube 128 100 57 :
default:leaves cube 30 47 28 :
default:grass_5 cube 73 112 33 :
default:ladder cube 153 109 39 :
default:dirt cube 122 83 58 :
default:mossycobble cube 102 116 85 :
default:stone_with_diamond cube 91 88 87 :
default:grass_2 cube 71 109 32 :
default:chest cube 238 219 171 :
default:gravel cube 92 84 76 :
default:torch cube 213 154 84 :
default:clay cube 178 178 178 :
default:chest_locked cube 238 219 171 :
default:copperblock cube 110 86 60 :
default:dry_shrub cube 117 75 14 :
default:junglewood cube 51 35 12 :
signs:sign_yard cube 163 141 106 :
signs:sign_post cube 4 2 0 :
junglegrass:shortest cube 55 92 21 :
junglegrass:short cube 49 89 15 :
junglegrass:medium cube 83 135 36 :
doors:door_wood_t_2 cube 87 64 30 :
doors:door_wood_b_1 cube 87 64 30 :
doors:door_wood_t_1 cube 87 64 30 :
doors:door_steel_t_1 cube 162 162 162 :
doors:door_steel_t_2 cube 162 162 162 :
doors:door_steel_b_1 cube 162 162 162 :
doors:door_wood_b_2 cube 87 64 30 :
doors:door_steel_b_2 cube 162 162 162 :
poisonivy:climbing cube 91 143 24 :
poisonivy:sproutling cube 111 166 30 :
poisonivy:seedling cube 127 190 34 :
wool:magenta cube 210 3 121 texture=wool_magenta.png
wool:blue cube 0 78 152 texture=wool_blue.png
wool:cyan cube 0 142 150 :
wool:orange cube 220 91 24 texture=wool_orange.png
wool:grey cube 141 141 141 :
wool:dark_grey cube 65 65 65 :
wool:pink cube 255 144 144 :
wool:white cube 228 228 228 :
wool:violet cube 96 2 177 :
wool:black cube 33 33 33 :
wool:green cube 99 230 28 :
wool:brown cube 95 49 0 :
wool:yellow cube 253 237 16 texture=wool_yellow.png
wool:dark_green cube 36 109 0 :
wool:red cube 180 20 20 :
fire:basic_flame cube 147 47 11 :
vessels:glass_bottle cube 211 212 211 :
vessels:steel_bottle cube 109 109 109 :
vessels:drinking_glass cube 220 220 220 :
flowers:rose cube 159 9 0 :
flowers:potted_tulip cube 114 41 22 :
flowers:viola cube 108 83 106 :
flowers:tulip cube 91 146 5 :
flowers:geranium cube 54 72 184 :
flowers:potted_dandelion_yellow cube 116 43 22 :
flowers:waterlily cube 46 108 0 :
flowers:waterlily_225 cube 49 110 2 :
flowers:dandelion_yellow cube 147 178 3 :
flowers:potted_geranium cube 76 60 124 :
flowers:dandelion_white cube 136 179 95 :
flowers:potted_rose cube 115 40 22 :
flowers:waterlily_675 cube 165 194 103 :
flowers:waterlily_45 cube 150 179 101 :
flowers:potted_dandelion_white cube 116 43 25 :
flowers:seaweed cube 28 112 11 :
flowers:potted_viola cube 115 41 24 :
farming:wheat_6 cube 165 151 74 :
farming:cotton_4 cube 58 46 27 :
farming:cotton_7 cube 194 189 185 :
farming:soil_wet cube 73 40 19 :
farming:cotton_3 cube 57 48 27 :
farming:wheat_1 cube 130 186 84 :
farming:wheat_7 cube 178 159 81 :
farming:cotton_5 cube 65 49 31 :
farming:soil cube 110 75 53 :
farming:wheat_8 cube 177 160 81 :
farming:wheat_2 cube 142 190 86 :
farming:wheat_4 cube 168 186 83 :
farming:wheat_5 cube 177 166 79 :
farming:wheat_3 cube 148 185 83 :
farming:cotton_1 cube 66 61 31 :
farming:cotton_2 cube 59 51 28 :
farming:cotton_6 cube 75 60 44 :
farming:cotton_8 cube 228 226 225 :