Improve scripts & documentation for generating colors.txt files a bit.
This commit is contained in:
parent
5974a26e05
commit
4de7e173bc
@ -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")
|
||||
|
@ -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)
|
@ -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
104
dumpnodes/README.dumpnodes
Normal 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
28
dumpnodes/avgcolor.py
Executable 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
50
dumpnodes/init.lua
Normal 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
49
dumpnodes/mkcolors
Executable 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user