Improve scripts & documentation for generating colors.txt files a bit.

This commit is contained in:
Rogier 2015-11-25 09:08:13 +01:00
parent 5974a26e05
commit 4de7e173bc
7 changed files with 272 additions and 109 deletions

View File

@ -278,6 +278,17 @@ set(COLORS_FILES
colors-average-alpha.txt
colors-cumulative-alpha.txt
)
set(DUMPNODES_FILES
dumpnodes/README.dumpnodes
dumpnodes/init.lua
)
set(DUMPNODES_MOD_FILES
dumpnodes/init.lua
)
set(DUMPNODES_SCRIPTS
dumpnodes/avgcolor.py
dumpnodes/mkcolors
)
#set(CPACK_SET_DESTDIR ON)
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Map generator for Minetest")
@ -313,6 +324,8 @@ if(WIN32)
install(FILES ${DOC_RST_FILES} DESTINATION "doc")
install(FILES ${DOC_HTML_FILES} DESTINATION "doc")
install(FILES ${DOC_IMAGE_FILES} DESTINATION "doc/images")
install(FILES ${DUMPNODES_FILES} DESTINATION "dumpnodes")
install(PROGRAMS ${DUMPNODES_SCRIPTS} DESTINATION "dumpnodes")
install(PROGRAMS "${PROJECT_BINARY_DIR}/minetestmapper.exe" DESTINATION ".")
elseif(CREATE_FLAT_PACKAGE)
@ -336,6 +349,8 @@ elseif(CREATE_FLAT_PACKAGE)
install(FILES ${DOC_RST_FILES} DESTINATION "doc")
install(FILES ${DOC_HTML_FILES} DESTINATION "doc")
install(FILES ${DOC_IMAGE_FILES} DESTINATION "doc/images")
install(FILES ${DUMPNODES_FILES} DESTINATION "dumpnodes")
install(PROGRAMS ${DUMPNODES_SCRIPTS} DESTINATION "dumpnodes")
install(PROGRAMS "${PROJECT_BINARY_DIR}/minetestmapper" DESTINATION ".")
else(WIN32)
@ -371,12 +386,17 @@ else(WIN32)
install(FILES ${DOC_RST_FILES} DESTINATION "share/doc/${PROJECT_NAME}/doc" COMPONENT mapper)
install(FILES ${DOC_HTML_FILES} DESTINATION "share/doc/${PROJECT_NAME}/doc" COMPONENT mapper)
install(FILES ${DOC_IMAGE_FILES} DESTINATION "share/doc/${PROJECT_NAME}/doc/images" COMPONENT mapper)
install(FILES ${DUMPNODES_FILES} DESTINATION "share/doc/${PROJECT_NAME}/dumpnodes" COMPONENT mapper)
install(PROGRAMS ${DUMPNODES_SCRIPTS} DESTINATION "share/doc/${PROJECT_NAME}/dumpnodes" COMPONENT mapper)
install(TARGETS minetestmapper RUNTIME DESTINATION bin COMPONENT mapper)
if(CMAKE_INSTALL_PREFIX STREQUAL "/usr")
# Require install prefix to be /usr when building .deb and .rpm packages
# (else minetestmapper will not find the default colors.txt file)
# When installing into /usr, assume minetest is also installed in /usr.
install(FILES ${DUMPNODES_MOD_FILES} DESTINATION "share/games/minetest/mods/dumpnodes" COMPONENT mapper)
# .deb settings
# Debian package building needs xxxxx, but cpack doesn't check for it first...
find_program(DPKG_AVAILABLE "dpkg")

View File

@ -1,109 +0,0 @@
==FILE== mods/dumpnodes/init.lua
local function nd_get_tiles(nd)
if nd.tiles then
return nd.tiles
elseif nd.tile_images then
return nd.tile_images
end
return nil
end
minetest.register_chatcommand("dumpnodes", {
params = "",
description = "",
func = function(plname, param)
local n = 0
local ntbl = {}
for nn, nd in pairs(minetest.registered_nodes) do
local prefix, name = nn:match('(.*):(.*)')
if prefix == nil or name == nil or prefix == '' or name == '' then
-- nothing
else
if ntbl[prefix] == nil then
ntbl[prefix] = {}
end
ntbl[prefix][name] = nd
end
end
local out, err = io.open('nodes.txt', 'wb')
if not out then
return minetest.chat_send_player(plname, 'io.open: ' .. err)
end
for prefix, i in pairs(ntbl) do
out:write('# ' .. prefix .. '\n')
for name, nd in pairs(i) do
if nd.drawtype ~= 'airlike' and nd_get_tiles(nd) ~= nil then
local tl = nd_get_tiles(nd)[1]
if type(tl) == 'table' then
tl = tl.name
end
tl = (tl .. '^'):match('(.-)^')
out:write(prefix .. ':' .. name .. ' ' .. tl .. '\n')
n = n + 1
end
end
out:write('\n')
end
out:close()
minetest.chat_send_player(plname, n .. " nodes dumped.")
end,
})
==FILE== avgcolor.py
#!/usr/bin/env python
import sys
from PIL import Image
def avg2(a, b):
return int((a + b) / 2.0)
def avg2t3i0(a, b):
return tuple(avg2(t[0], t[1]) for t in zip(a[:3], b[:3]))
if len(sys.argv) <= 1:
print("Usage: %s <input>" % sys.argv[0])
else:
inp = Image.open(sys.argv[1])
inp = inp.convert('RGBA')
ind = inp.load()
avgc = -1
for x in range(inp.size[0]):
for y in range(inp.size[1]):
pxl = ind[x, y]
if pxl[3] < 128:
continue
if avgc == -1:
avgc = pxl[:3]
else:
avgc = avg2t3i0(avgc, pxl)
if avgc == -1:
sys.stderr.write('Warning: did not find average color\n')
print('0 0 0')
else:
print("%d %d %d" % avgc)
==COMMAND==
while read -r p; do
set -- junk $p
shift
if [[ ! $1 == "#" && ! $1 == "" ]]; then
echo $1 `python /path/to/avgcolor.py $(find /path/to/minetest/directory/ -type f -name $2)`
fi
done < nodes.txt > colors.txt
# Use nicer colors for water and lava
sed -r \
-e 's/^(default:water_[a-z]+) [0-9 ]+$/\1 39 66 106 128 224/' \
-e 's/^(default:river_water_[a-z]+) [0-9 ]+$/\1 59 99 159 192 224/' \
-e 's/^(default:lava_[a-z]+) [0-9 ]+$/\1 255 100 0/' \
-e 's/^(default:[a-z_]*glass[_a-z0-9]*) ([0-9 ]+)$/\1 \2 64 16/' \
-e 's/^(xpanes:bar_[0-9]*) ([0-9 ]+)$/\1 64 64 64/' \
-e 's/^(xpanes:pane_[0-9]*) ([0-9 ]+)$/\1 192 192 227 64 16/' \
< colors.txt \
> tmp$$ \
&& mv tmp$$ colors.txt
==INSTRUCTIONS==
1) Make sure avgcolors.py outputs the usage instructions
2) Add the dumpnodes mod to Minetest
3) Create a world and load dumpnodes & all mods you want to have a color entry for
4) Execute /dumpnodes ingame
5) Use the command to generate colors.txt (obviously don't forget to replace /path/to/... with the actual path)

View File

@ -1730,6 +1730,27 @@ Colors Files Search Locations
* For compatibility, in the current directory as a last resort.
This causes a warning message to be printed.
Generating colors.txt files
---------------------------
While the colors.txt file provided with minetestmapper contains color definitions for a
large number of nodes of different popular mods, it is not, and cannot be complete.
For users on linux and unix(-like) systems, a few scripts are provided to aid in the
creation of a colors.txt file based on the actual mods the user is using. Unfortunately,
these scripts are still a bit unpolished. They may run without any problem, and they
may generate a perfect colors.txt file on first run. However, it may also require some
effort to get them to produce a good colors.txt file, and the resulting file may very
well need some manual modifications of some colors to make them look better.
Please consult `<../dumpnodes/README.dumpnodes>`_ for more information on how to use
the scripts.
The scripts are not supported on Windows. While it is probably possible to get them
to work, be prepared to do some research on the subject of getting bash scripts to run
on windows, and be prepared to invest some time... Alternatively, be prepared to
rewrite at least the bash script in another scripting language.
More Information
================

104
dumpnodes/README.dumpnodes Normal file
View File

@ -0,0 +1,104 @@
Generating a colors.txt file
============================
Simple instructions for generating a colors.txt file on unix/linux.
While it is known that generating a colors.txt file is not a
user-friendly experience for those who are not comfortable
using the unix/linux command-line, this is an attempt to make it
as simple and understandable as possible, given the current state
of affairs.
If many of the steps below are cryptic to you, then you might be
better off using an existing colors file, and adding any extra
colors you need by hand.
More experienced users should adapt this procedure to their
own needs.
Note in general that a generated colors.txt file may contain incorrect
or undesirable colors for some nodes, or it may lack transparency
information for nodes.
Manual reviewing (e.g. comparison to an existing colors file)
is recommended.
Steps
=====
(to be performed from the command-line)
1) A directory 'dumpnodes' (containing this file you are reading,
as well as some other files) is provided with minetestmapper.
Copy this directory to the minetest 'mods' directory (i.e.
install dumpnodes as a mod)
2) Change to the new (copied) directory (<somelocation>/mods/dumpnodes)
3) Make sure 'avgcolors.py' and 'mkcolors' are executable. To make them
executable, issue the command:
chmod +x avgcolors.py mkcolors
4) Verify that avgcolors.py works. Type:
./avgcolors.py
it should print:
Usage: ./avgcolor.py <input>
Possible reasons for failure:
- avgcolor.py is not in the current directory
- avgcolor.py is not executable
- python is not installed
- ...?
5) Verify that mkcolors works. Type:
./mkcolors
it should print:
Usage: mkcolors search-dir [...]
Possible reasons for failure:
- mkcolors is not in the current directory
- mkcolors is not executable
- avgcolors.py is not in the current directory
- avgcolors.py does not work, See above.
- /bin/bash is not installed
- ...?
6) Start minetest while in the 'dumpnodes' directory
(It can be started from another directory, but the resulting
nodes.txt file will have to be copied to the dumpnodes
directory in order to perform subsequent steps)
7) Create a world and load dumpnodes & all mods you want to have a color entry for
8) Start the world & issue the command '/dumpnodes' wile in the game
Minetest reports back: '<some number> nodes dumped'
9) Exit the world
10) In the dumpnodes directory, you'll find a file 'nodes.txt'
If not, see point 6 above, or find the nodes.txt file, and copy it to the
dumpnodes directory
11) Make sure you're still in the directory of the dumpnodes mod.
12) Run mkcolors. The first parameter is the minetest directory that contains
the 'games' and the 'mods' subdirectories.
Normally that would be two directories up from where you are (../../)
./mkcolors ../../
or else, enter something like:
./mkcolors /path/to/minetest/directory
NOTE: mkcolors may take some time to run.
13) You should now find a (an updated) colors.txt file alongside the nodes.txt
file. Copy it to where you want it to be. Your world directory, or the
minetest directory are good locations; see the minetestmapper documentation
to learn where and how minetestmapper searches for colors files.
14) Optionally, delete the temporary world that you created.
Things this procedure does not take into account:
- Colors cannot be generated yet based on texture packs.
(reason: mkcolors would not know which texture pack to select)
Workaround: specify all directories where to search for node textures
on the command-line of mkcolors. Omit any directories that should not
be searched, or their parent directories. E.g.
./mkcolors /path/to/mods /path/to/games/minetest /path/to/textures/mytextures
Be sure to include at least the minetest mods directory and the minetest games
directory. Specify the directories in the right order: the first texture that is found
will be used.
- Node colors from mods and games installed in system locations are not automatically
computed.
Workaround: create symbolic links to those desired mods or games in your
personal mods and/or games directories. E.g.:
ln -s /usr/share/games/minetest/games/minetest /home/personal/path/to/minetest/games/
ln -s /usr/share/games/minetest/mods/some_mod /home/personal/path/to/minetest/mods/
or specify the additional search locations on the mkcolors command-line:
./mkcolors /home/user/minetest /usr/share/games/minetest
- Windows
Currently, there is no windows version of the relevant scripts. It is recommended
to use a colors.txt file generated by somebody else.

28
dumpnodes/avgcolor.py Executable file
View File

@ -0,0 +1,28 @@
#!/usr/bin/env python
import sys
from PIL import Image
def avg2(a, b):
return int((a + b) / 2.0)
def avg2t3i0(a, b):
return tuple(avg2(t[0], t[1]) for t in zip(a[:3], b[:3]))
if len(sys.argv) <= 1:
print("Usage: %s <input>" % sys.argv[0])
else:
inp = Image.open(sys.argv[1])
inp = inp.convert('RGBA')
ind = inp.load()
avgc = -1
for x in range(inp.size[0]):
for y in range(inp.size[1]):
pxl = ind[x, y]
if pxl[3] < 128:
continue
if avgc == -1:
avgc = pxl[:3]
else:
avgc = avg2t3i0(avgc, pxl)
if avgc != -1:
print("%d %d %d" % avgc)

50
dumpnodes/init.lua Normal file
View File

@ -0,0 +1,50 @@
local function nd_get_tiles(nd)
if nd.tiles then
return nd.tiles
elseif nd.tile_images then
return nd.tile_images
end
return nil
end
minetest.register_chatcommand("dumpnodes", {
params = "",
description = "",
func = function(plname, param)
local n = 0
local ntbl = {}
for nn, nd in pairs(minetest.registered_nodes) do
local prefix, name = nn:match('(.*):(.*)')
if prefix == nil or name == nil or prefix == '' or name == '' then
-- nothing
else
if ntbl[prefix] == nil then
ntbl[prefix] = {}
end
ntbl[prefix][name] = nd
end
end
local out, err = io.open('nodes.txt', 'wb')
if not out then
return minetest.chat_send_player(plname, 'io.open: ' .. err)
end
for prefix, i in pairs(ntbl) do
out:write('# ' .. prefix .. '\n')
for name, nd in pairs(i) do
if nd.drawtype ~= 'airlike' and nd_get_tiles(nd) ~= nil then
local tl = nd_get_tiles(nd)[1]
if type(tl) == 'table' then
tl = tl.name
end
tl = (tl .. '^'):match('(.-)^')
out:write(prefix .. ':' .. name .. ' ' .. tl .. '\n')
n = n + 1
end
end
out:write('\n')
end
out:close()
minetest.chat_send_player(plname, n .. " nodes dumped.")
end,
})

49
dumpnodes/mkcolors Executable file
View File

@ -0,0 +1,49 @@
#! /bin/bash
if ! ./avgcolor.py >& /dev/null; then
echo "${0##*/}: ERROR: could not run avgcolor.py (`pwd`/avgcolor.py)" 1>&2
exit 1
fi
if [ -z "$1" ]; then
echo "Usage: ${0##*/} search-dir [...]" 1>&2
exit 1
fi
for file in "$@"; do
if [ ! -d "$file" ]; then
echo "${0##*/}: ERROR: $file does not exist or is not a directory" 1>&2
exit 1
fi
done
cat nodes.txt \
| sed \
-e 's/[ \t]*#.*//' \
-e '/^[ \t]*$/d' \
| while read -r node tile; do
filename="$(find -L "$@" -type f -name "$tile" | head -1)"
if [ -z "$filename" ]; then
echo "WARNING: could not find file '$tile' for node '$node'" 1>&2
continue
fi
avgcolor="$(./avgcolor.py "$filename")"
if [ -z "$avgcolor" ]; then
echo "WARNING: failed to compute average color for node '$node' (tile: $tile)" 1>&2
if expr "$node" : "^xpanes:bar_[0-9]\+$" > /dev/null; then
# Hack to generate xpanes:bar_* anyway
echo "$node 0 0 0"
fi
else
echo "$node $avgcolor"
fi
done \
| sed -r \
-e 's/^(default:water_[a-z]+) [0-9 ]+$/\1 49 82 132 128 224/' \
-e 's/^(default:river_water_[a-z]+) [0-9 ]+$/\1 59 99 159 192 224/' \
-e 's/^(default:lava_[a-z]+) [0-9 ]+$/\1 255 100 0/' \
-e 's/^(default:[a-z_]*glass[_a-z0-9]*) ([0-9 ]+)$/\1 \2 64 16/' \
-e 's/^(xpanes:bar_[0-9]*) ([0-9 ]+)$/\1 64 64 64/' \
-e 's/^(xpanes:pane_[0-9]*) ([0-9 ]+)$/\1 192 192 227 64 16/' \
> colors.txt