Compare commits

...

5 Commits

Author SHA1 Message Date
entuland 045f3b39f9 disabled automatic flagging of RGB mode and updated README 2019-01-12 19:53:34 +01:00
entuland 05a4b2c65f first implementation targeting #6 2019-01-06 00:43:00 +01:00
entuland fe83a869cd support colorfacedir nodes 2018-07-06 12:30:53 +02:00
entuland d6a43d1495 remove debug statements 2018-07-01 09:16:33 +02:00
entuland de73940b2f integrated smartfs improvements/fixes 2018-07-01 08:52:59 +02:00
5 changed files with 609 additions and 38 deletions

View File

@ -52,7 +52,7 @@ Once you're done with your build, go to the Canvas block and right click it: you
Here you can also decide whether or not to generate a backup matrix which you can later import to recreate the build, you can also specify what variants you want your mesh to be available in.
Backup matrices are additional files that record your build's colors. The mod doesn't use them as of now, and even if it did, it would only allow you to rebuild your creation using wool blocks. These files can be safely omitted if you're not worried about rebuilding your creations (that is, if you don't dismantle them or if you don't care about recapturing them).
Backup matrices are additional files that record your build's nodes and colors. They can be used to rebuild the captures with the original nodes or as wool depending on their matching colors. These files can be safely omitted if you're not worried about rebuilding your creations (that is, if you don't dismantle them or if you don't care about recapturing them).
This capture interface also gives you access to the `Manage Meshes` and the `Giveme Meshes` interfaces, which will be covered later on in this documentation:
@ -73,7 +73,9 @@ During world startup the mod will move all the temporary files to the `/models`
You can't have two meshes with the same name (during the saving process the mod checks both the temporary meshes that haven't been loaded yet and those that have been already moved to the mod's folder).
By default, four versions of each mesh will be available (which you can toggle in the interface for each capture):
By default, four versions of each mesh will be available (which you can toggle in the interface for each capture).
You can optionally ignore variants and create meshes that rely on RGB colors, more about that in the [RGB Colors](#rgb-colors) section.
- plain versions: they use flat colors averaged from the colors of each wool block, with a bordered variant
@ -109,6 +111,35 @@ If you're playing in creative mode all such meshes, including all canvases, show
![Creative search](/screenshots/creative-search.png)
# RGB colors
One of the latest additions to this mod has been allowing the capture of nodes using RGB colors specified in the [/default/colors.txt](/default/colors.txt) file (duped to `/custom.colors.txt` for customization) - this file has been taken from [Minetest Mapper](https://github.com/minetest/minetestmapper/blob/master/colors.txt).
(discussion about this new RGB feature [here](https://github.com/entuland/wesh/issues/6))
Selecting the `Ignore variants, use RGB` option in the capture screen will result in a mesh using a custom palette, built on the fly, that looks like this...
```
variants = {
rgb = "[combine:4x1:0,0=(px.png\\^[colorize\\:#42701f):1,0=(px.png\\^[colorize\\:#6c9343):2,0=(px.png\\^[colorize\\:#5f4027):3,0=(px.png\\^[colorize\\:#763018)",
},
```
...instead of the regular variants:
```
variants = {
wool = "wool-72.png",
plain = "plain-16.png",
plainborder = "plain-border-72.png",
woolborder = "wool-border-72.png",
},
```
This RGB palette is *not* compatible with the regular variants and you cannot use RGB meshes with the normal palettes - more about variants in the [Custom properties](#specifying-custom-properties) section.
If you want to have the same mesh with RBB custom palette *and* with the usual variants you need to capture it twice with different names.
# Privileges
Three separate privileges are available:
@ -173,15 +204,17 @@ Finally, matrices can be accessed and rebuilt immediately, without the need for
# Specifying custom properties
In the `.obj.dat` file of each mesh you'll find something like this:
return {
description = "Your mesh name",
variants = {
plain = "plain-16.png",
plainborder = "plain-border-72.png",
wool = "wool-72.png",
woolborder = "wool-border-72.png",
},
}
```
return {
description = "Your mesh name",
variants = {
plain = "plain-16.png",
plainborder = "plain-border-72.png",
wool = "wool-72.png",
woolborder = "wool-border-72.png",
},
}
```
(please consider that the number `16` here above indicates the size of the texture, it has nothing to do with the size of the canvas you use to capture your build)
@ -209,6 +242,8 @@ The above doesn't depend on variants available in `nodevariants.lua` - as long a
Have a look at `wool-72.png` to see where each color goes, or use the included [textures-72.xcf](/textures/textures-72.xcf) file (GIMP format) which has layers for adding the borders as well.
As explained in [RGB Colors](#rgb-colors), the regular variants and the RGB custom palette are not compatible. You cannot add regular variants to the `.obj.dat` file of a mesh captured in RGB mode, and you cannot add a custom RGB palette to a mesh captured using the regular variants. If you need both modes, capture the mesh twice with different names.
You can as well override any property you would normally pass to node_register(), such as `walkable`, `groups`, `collision_box`, `selection_box` and so forth. The only property that doesn't get really overridden but just _mangled_ according to the variants is the `description` one. You shouldn't even be overriding `tiles` cause they will be built according to the `variants` property (property which is specific to this mod's `.obj.dat` files).
A couple considerations:
@ -219,3 +254,5 @@ A couple considerations:
# Changing default colors assigned to nodes
The file [/default/nodecolors.conf](/default/nodecolors.conf) contains the `modname:nodename = color` associations for all the nodes that get loaded in a minetest_game world. This file will be copied over to `/custom.nodecolors.conf` at startup (if no such file exists); in `/custom.nodecolors.conf` you're free to alter existing colors and to add new nodes, just make sure you stick to wool colors cause any invalid color will be replaced by `air`.
In RGB mode the colors are determined by [/default/colors.txt](/default/colors.txt), which gets duped at startup to `/custom.colors.txt` for customization. This file uses a different format `modname:nodename R G B` where R, G and B are *decimal* integers ranging from zero to 255.

409
default/colors.txt Normal file
View File

@ -0,0 +1,409 @@
# only alter this file if it's named "custom.colors.txt"
# alter the color mapping (R G B integer triplets) as you please
# and comment out the nodes you don't want to use for mesh building in the game
# the original mappings are in "default/colors.txt"
# taken from https://github.com/minetest/minetestmapper/blob/master/colors.txt
# beds
beds:bed_bottom 130 3 3
beds:bed_top 178 116 116
beds:fancy_bed_bottom 135 23 14
beds:fancy_bed_top 172 112 103
# bones
bones:bones 86 86 86
# carts
carts:brakerail 129 110 81
carts:powerrail 154 136 81
carts:rail 143 123 90
# default
default:acacia_bush_leaves 90 124 55
default:acacia_bush_sapling 85 118 58
default:acacia_bush_stem 84 76 69
default:acacia_leaves 108 147 67
default:acacia_sapling 87 116 61
default:acacia_tree 188 109 90
default:acacia_wood 146 60 37
default:apple 145 20 9
default:aspen_leaves 70 104 27
default:aspen_sapling 82 110 43
default:aspen_tree 218 197 166
default:aspen_wood 209 198 169
default:bookshelf 128 99 55
default:brick 117 71 69
default:bronzeblock 185 110 15
default:bush_leaves 34 52 29
default:bush_sapling 65 60 40
default:bush_stem 45 33 23
default:cactus 52 116 15
default:cave_ice 167 206 247
default:chest 140 108 65
default:chest_locked 140 108 65
default:chest_locked_open 140 108 65
default:chest_open 140 108 65
default:clay 182 182 182
default:cloud 255 255 255
default:coalblock 57 57 57
default:cobble 88 84 82
default:copperblock 192 126 63
default:coral_brown 139 104 72
default:coral_orange 191 62 12
default:coral_skeleton 235 230 214
default:desert_cobble 107 65 49
default:desert_sand 206 165 98
default:desert_sandstone 195 152 92
default:desert_sandstone_block 192 151 94
default:desert_sandstone_brick 191 151 94
default:desert_stone 129 79 60
default:desert_stone_block 130 79 60
default:desert_stonebrick 129 79 60
default:diamondblock 135 217 223
default:dirt 95 64 39
default:dirt_with_coniferous_litter 107 88 68
default:dirt_with_dry_grass 187 148 77
default:dirt_with_grass 66 112 31
default:dirt_with_grass_footsteps 66 112 31
default:dirt_with_rainforest_litter 74 38 8
default:dirt_with_snow 224 225 238
default:dry_grass_1 208 172 87
default:dry_grass_2 210 174 87
default:dry_grass_3 210 174 87
default:dry_grass_4 211 175 88
default:dry_grass_5 213 178 92
default:dry_shrub 101 66 17
default:emergent_jungle_sapling 48 39 15
default:fence_acacia_wood 147 60 38
default:fence_aspen_wood 210 199 170
default:fence_junglewood 54 37 11
default:fence_pine_wood 221 184 129
default:fence_wood 129 100 55
default:fern_1 81 114 48
default:fern_2 86 118 50
default:fern_3 88 121 52
default:furnace 100 96 94
default:furnace_active 100 96 94
default:glass 194 194 227 64 16
default:goldblock 230 201 29
default:grass_1 97 138 53
default:grass_2 95 136 54
default:grass_3 91 133 52
default:grass_4 86 130 45
default:grass_5 83 124 47
default:gravel 131 131 131
default:ice 167 206 247
default:junglegrass 63 105 25
default:jungleleaves 20 28 15
default:junglesapling 48 38 14
default:jungletree 105 76 41
default:junglewood 54 37 11
default:ladder_steel 126 126 126
default:ladder_wood 123 90 34
default:lava_flowing 255 100 0
default:lava_source 255 100 0
default:leaves 34 52 29
default:marram_grass_1 96 133 89
default:marram_grass_2 87 126 83
default:marram_grass_3 85 125 82
default:mese 220 220 0
default:mese_post_light 131 102 57
default:meselamp 211 213 139
default:mossycobble 86 90 68
default:obsidian 19 21 24
default:obsidian_block 20 22 25
default:obsidian_glass 19 21 23 64 16
default:obsidianbrick 20 22 24
default:papyrus 94 132 33
default:pine_needles 11 48 18
default:pine_sapling 27 48 25
default:pine_tree 182 155 124
default:pine_wood 221 184 128
default:river_water_flowing 39 66 106 128 224
default:river_water_source 39 66 106 128 224
default:sand 214 207 158
default:sand_with_kelp 214 207 158
default:sandstone 197 193 143
default:sandstone_block 195 190 141
default:sandstonebrick 193 189 140
default:sapling 65 59 40
default:sign_wall_steel 144 144 144
default:sign_wall_wood 145 101 64
default:silver_sand 193 191 179
default:silver_sandstone 195 192 181
default:silver_sandstone_block 192 190 179
default:silver_sandstone_brick 190 188 178
default:snow 224 225 238
default:snowblock 224 225 238
default:steelblock 194 194 194
default:stone 97 94 93
default:stone_block 99 96 95
default:stone_with_coal 97 94 93
default:stone_with_copper 97 94 93
default:stone_with_diamond 97 94 93
default:stone_with_gold 97 94 93
default:stone_with_iron 97 94 93
default:stone_with_mese 97 94 93
default:stone_with_tin 97 94 93
default:stonebrick 99 96 95
default:tinblock 149 149 149
default:torch 120 98 67
default:torch_ceiling 120 98 67
default:torch_wall 120 98 67
default:tree 164 131 88
default:water_flowing 39 66 106 128 224
default:water_source 39 66 106 128 224
default:wood 128 99 55
# doors
doors:door_glass_a 184 184 216 64 16
doors:door_glass_b 184 184 216 64 16
doors:door_obsidian_glass_a 27 28 29 64 16
doors:door_obsidian_glass_b 27 28 29 64 16
doors:door_steel_a 201 201 201
doors:door_steel_b 201 201 201
doors:door_wood_a 87 67 35
doors:door_wood_b 87 67 35
doors:gate_acacia_wood_closed 146 60 37
doors:gate_acacia_wood_open 146 60 37
doors:gate_aspen_wood_closed 209 198 169
doors:gate_aspen_wood_open 209 198 169
doors:gate_junglewood_closed 54 37 11
doors:gate_junglewood_open 54 37 11
doors:gate_pine_wood_closed 221 184 128
doors:gate_pine_wood_open 221 184 128
doors:gate_wood_closed 128 99 55
doors:gate_wood_open 128 99 55
doors:trapdoor 128 99 50
doors:trapdoor_open 136 106 59
doors:trapdoor_steel 199 199 199
doors:trapdoor_steel_open 206 206 206
# farming
farming:cotton_1 88 116 39
farming:cotton_2 87 116 38
farming:cotton_3 97 120 41
farming:cotton_4 106 113 47
farming:cotton_5 114 104 53
farming:cotton_6 119 94 59
farming:cotton_7 92 69 37
farming:cotton_8 110 91 61
farming:desert_sand_soil 159 131 70
farming:desert_sand_soil_wet 119 98 52
farming:seed_cotton 90 85 57
farming:seed_wheat 175 159 93
farming:soil 95 64 39
farming:soil_wet 95 64 39
farming:straw 211 182 67
farming:wheat_1 107 174 32
farming:wheat_2 133 175 50
farming:wheat_3 162 182 82
farming:wheat_4 169 187 93
farming:wheat_5 169 178 94
farming:wheat_6 172 176 85
farming:wheat_7 192 181 81
farming:wheat_8 186 161 35
# fire
fire:basic_flame 218 120 36
fire:permanent_flame 218 120 36
# fireflies
fireflies:firefly_bottle 190 191 198
# flowers
flowers:chrysanthemum_green 101 140 39
flowers:dandelion_white 178 176 140
flowers:dandelion_yellow 194 159 17
flowers:geranium 72 87 155
flowers:mushroom_brown 106 79 72
flowers:mushroom_red 192 85 85
flowers:rose 118 48 24
flowers:tulip 130 99 36
flowers:tulip_black 72 103 63
flowers:viola 106 60 159
flowers:waterlily 102 158 61
# stairs
stairs:slab_acacia_wood 146 60 37
stairs:slab_aspen_wood 209 198 169
stairs:slab_brick 117 71 69
stairs:slab_bronzeblock 185 110 15
stairs:slab_cobble 88 84 82
stairs:slab_copperblock 192 126 63
stairs:slab_desert_cobble 107 65 49
stairs:slab_desert_sandstone 195 152 92
stairs:slab_desert_sandstone_block 192 151 94
stairs:slab_desert_sandstone_brick 191 151 94
stairs:slab_desert_stone 129 79 60
stairs:slab_desert_stone_block 130 79 60
stairs:slab_desert_stonebrick 129 79 60
stairs:slab_goldblock 230 201 29
stairs:slab_ice 167 206 247
stairs:slab_junglewood 54 37 11
stairs:slab_mossycobble 86 90 68
stairs:slab_obsidian 19 21 24
stairs:slab_obsidian_block 20 22 25
stairs:slab_obsidianbrick 20 22 24
stairs:slab_pine_wood 221 184 128
stairs:slab_sandstone 197 193 143
stairs:slab_sandstone_block 195 190 141
stairs:slab_sandstonebrick 193 189 140
stairs:slab_silver_sandstone 195 192 181
stairs:slab_silver_sandstone_block 192 190 179
stairs:slab_silver_sandstone_brick 190 188 178
stairs:slab_snowblock 224 225 238
stairs:slab_steelblock 194 194 194
stairs:slab_stone 97 94 93
stairs:slab_stone_block 99 96 95
stairs:slab_stonebrick 99 96 95
stairs:slab_straw 211 182 67
stairs:slab_tinblock 149 149 149
stairs:slab_wood 128 99 55
stairs:stair_acacia_wood 146 60 37
stairs:stair_aspen_wood 209 198 169
stairs:stair_brick 117 71 69
stairs:stair_bronzeblock 185 110 15
stairs:stair_cobble 88 84 82
stairs:stair_copperblock 192 126 63
stairs:stair_desert_cobble 107 65 49
stairs:stair_desert_sandstone 195 152 92
stairs:stair_desert_sandstone_block 192 151 94
stairs:stair_desert_sandstone_brick 191 151 94
stairs:stair_desert_stone 129 79 60
stairs:stair_desert_stone_block 130 79 60
stairs:stair_desert_stonebrick 129 79 60
stairs:stair_goldblock 230 201 29
stairs:stair_ice 167 206 247
stairs:stair_inner_acacia_wood 146 60 37
stairs:stair_inner_aspen_wood 209 198 169
stairs:stair_inner_brick 117 71 69
stairs:stair_inner_bronzeblock 185 110 15
stairs:stair_inner_cobble 88 84 82
stairs:stair_inner_copperblock 192 126 63
stairs:stair_inner_desert_cobble 107 65 49
stairs:stair_inner_desert_sandstone 195 152 92
stairs:stair_inner_desert_sandstone_block 192 151 94
stairs:stair_inner_desert_sandstone_brick 191 151 94
stairs:stair_inner_desert_stone 129 79 60
stairs:stair_inner_desert_stone_block 130 79 60
stairs:stair_inner_desert_stonebrick 129 79 60
stairs:stair_inner_goldblock 230 201 29
stairs:stair_inner_ice 167 206 247
stairs:stair_inner_junglewood 54 37 11
stairs:stair_inner_mossycobble 86 90 68
stairs:stair_inner_obsidian 19 21 24
stairs:stair_inner_obsidian_block 20 22 25
stairs:stair_inner_obsidianbrick 20 22 24
stairs:stair_inner_pine_wood 221 184 128
stairs:stair_inner_sandstone 197 193 143
stairs:stair_inner_sandstone_block 195 190 141
stairs:stair_inner_sandstonebrick 193 189 140
stairs:stair_inner_silver_sandstone 195 192 181
stairs:stair_inner_silver_sandstone_block 192 190 179
stairs:stair_inner_silver_sandstone_brick 190 188 178
stairs:stair_inner_snowblock 224 225 238
stairs:stair_inner_steelblock 194 194 194
stairs:stair_inner_stone 97 94 93
stairs:stair_inner_stone_block 99 96 95
stairs:stair_inner_stonebrick 99 96 95
stairs:stair_inner_straw 211 182 67
stairs:stair_inner_tinblock 149 149 149
stairs:stair_inner_wood 128 99 55
stairs:stair_junglewood 54 37 11
stairs:stair_mossycobble 86 90 68
stairs:stair_obsidian 19 21 24
stairs:stair_obsidian_block 20 22 25
stairs:stair_obsidianbrick 20 22 24
stairs:stair_outer_acacia_wood 146 60 37
stairs:stair_outer_aspen_wood 209 198 169
stairs:stair_outer_brick 117 71 69
stairs:stair_outer_bronzeblock 185 110 15
stairs:stair_outer_cobble 88 84 82
stairs:stair_outer_copperblock 192 126 63
stairs:stair_outer_desert_cobble 107 65 49
stairs:stair_outer_desert_sandstone 195 152 92
stairs:stair_outer_desert_sandstone_block 192 151 94
stairs:stair_outer_desert_sandstone_brick 191 151 94
stairs:stair_outer_desert_stone 129 79 60
stairs:stair_outer_desert_stone_block 130 79 60
stairs:stair_outer_desert_stonebrick 129 79 60
stairs:stair_outer_goldblock 230 201 29
stairs:stair_outer_ice 167 206 247
stairs:stair_outer_junglewood 54 37 11
stairs:stair_outer_mossycobble 86 90 68
stairs:stair_outer_obsidian 19 21 24
stairs:stair_outer_obsidian_block 20 22 25
stairs:stair_outer_obsidianbrick 20 22 24
stairs:stair_outer_pine_wood 221 184 128
stairs:stair_outer_sandstone 197 193 143
stairs:stair_outer_sandstone_block 195 190 141
stairs:stair_outer_sandstonebrick 193 189 140
stairs:stair_outer_silver_sandstone 195 192 181
stairs:stair_outer_silver_sandstone_block 192 190 179
stairs:stair_outer_silver_sandstone_brick 190 188 178
stairs:stair_outer_snowblock 224 225 238
stairs:stair_outer_steelblock 194 194 194
stairs:stair_outer_stone 97 94 93
stairs:stair_outer_stone_block 99 96 95
stairs:stair_outer_stonebrick 99 96 95
stairs:stair_outer_straw 211 182 67
stairs:stair_outer_tinblock 149 149 149
stairs:stair_outer_wood 128 99 55
stairs:stair_pine_wood 221 184 128
stairs:stair_sandstone 197 193 143
stairs:stair_sandstone_block 195 190 141
stairs:stair_sandstonebrick 193 189 140
stairs:stair_silver_sandstone 195 192 181
stairs:stair_silver_sandstone_block 192 190 179
stairs:stair_silver_sandstone_brick 190 188 178
stairs:stair_snowblock 224 225 238
stairs:stair_steelblock 194 194 194
stairs:stair_stone 97 94 93
stairs:stair_stone_block 99 96 95
stairs:stair_stonebrick 99 96 95
stairs:stair_straw 211 182 67
stairs:stair_tinblock 149 149 149
stairs:stair_wood 128 99 55
# tnt
tnt:gunpowder 6 6 6
tnt:gunpowder_burning 112 103 2
tnt:tnt 181 0 0
tnt:tnt_burning 190 8 0
# vessels
vessels:drinking_glass 206 214 228
vessels:glass_bottle 188 190 201
vessels:shelf 128 99 55
vessels:steel_bottle 193 192 191
# walls
walls:cobble 88 84 82
walls:desertcobble 107 65 49
walls:mossycobble 86 90 68
# wool
wool:black 29 29 29
wool:blue 0 72 145
wool:brown 86 42 0
wool:cyan 0 130 139
wool:dark_green 32 102 0
wool:dark_grey 59 59 59
wool:green 92 216 28
wool:grey 131 131 131
wool:magenta 200 3 109
wool:orange 213 81 21
wool:pink 255 131 131
wool:red 168 17 17
wool:violet 92 2 169
wool:white 220 220 220
wool:yellow 254 225 15
# xpanes
xpanes:bar 114 114 114 64 16
xpanes:bar_flat 114 114 114 64 16
xpanes:obsidian_pane 16 16 17 64 16
xpanes:obsidian_pane_flat 16 16 17 64 16
xpanes:pane 192 192 227 64 16
xpanes:pane_flat 192 192 227 64 16

157
init.lua
View File

@ -117,6 +117,7 @@ function wesh.init_colors()
-- The same loop will also fill the nodename_to_color table with default fallbacks for wool
wesh.nodename_to_color = {}
wesh.nodename_to_rgb = {}
wesh.color_vertices = {}
for i, color in ipairs(wesh.colors) do
local t = {}
@ -149,6 +150,25 @@ function wesh.init_colors()
end
file:close()
local full_rgb_filename = custom_or_default(wesh.name, wesh.mod_path, "colors.txt")
if not full_rgb_filename then return end
local rgb_file = io.open(full_rgb_filename, "rb")
if not rgb_file then return end
-- The following loop will fill the nodename_to_rgb table with custom values
local rgb_content = rgb_file:read("*all")
local rgb_lines = rgb_content:gsub("(\r\n)+", "\r"):gsub("\r+", "\n"):split("\n")
for _, line in ipairs(rgb_lines) do
line = line:gsub("%s+", " ")
if line:sub(1,1) ~= "#" then
local parts = line:split(" ")
if #parts == 4 then
wesh.nodename_to_rgb[parts[1]] = { tonumber(parts[2]), tonumber(parts[3]), tonumber(parts[4]) }
end
end
end
rgb_file:close()
end
function wesh.init_geometry()
@ -289,12 +309,13 @@ function wesh.transform_facedir(canvas_facedir, node_facedir, invert_canvas)
if not wesh.transform_cache then
wesh.transform_cache = {}
end
local rotation = node_facedir % 32 -- get first 5 bits
local remaining = node_facedir - rotation
local cache_key = canvas_facedir .. "," .. rotation .. "," .. (invert_canvas and 1 or 0)
local cache_key = canvas_facedir .. "," .. node_facedir .. "," .. (invert_canvas and 1 or 0)
print(cache_key)
if not wesh.transform_cache[cache_key] then
local canvas_transform = wesh.get_facedir_transform(canvas_facedir)
local node_transform = wesh.get_facedir_transform(node_facedir)
local node_transform = wesh.get_facedir_transform(rotation)
if invert_canvas then
canvas_transform = canvas_transform:invert()
end
@ -302,9 +323,7 @@ function wesh.transform_facedir(canvas_facedir, node_facedir, invert_canvas)
wesh.transform_cache[cache_key] = wesh.matrix_to_facedir(transform)
end
print(cache_key .. " == " .. wesh.transform_cache[cache_key])
return wesh.transform_cache[cache_key]
return wesh.transform_cache[cache_key] + remaining
end
function wesh.init_variants()
@ -418,24 +437,30 @@ end
function wesh.reset_geometry(canvas)
canvas.matrix = {}
canvas.wool_matrix = {}
canvas.node_matrix = {}
canvas.vertices = {}
canvas.vertices_indices = {}
canvas.faces = {}
canvas.voxel_count = 0
canvas.nodename_count = 0
canvas.custom_texture_vertices_mapping = {}
canvas.custom_texture_colors = {}
local function reset(p)
if not canvas.matrix[p.x] then
canvas.matrix[p.x] = {}
canvas.wool_matrix[p.x] = {}
canvas.node_matrix[p.x] = {}
end
if not canvas.matrix[p.x][p.y] then
canvas.matrix[p.x][p.y] = {}
canvas.wool_matrix[p.x][p.y] = {}
canvas.node_matrix[p.x][p.y] = {}
end
canvas.wool_matrix[p.x][p.y][p.z] = "air"
canvas.matrix[p.x][p.y][p.z] = "air"
canvas.node_matrix[p.x][p.y][p.z] = {
name = "air",
@ -457,10 +482,11 @@ wesh.forms.capture = smartfs.create("wesh.forms.capture", function(state)
local capture_button = state:button(5, 0.2, 2, 1, "capture", "Capture")
state:checkbox(0.5, 1, "generate_matrix", "Generate backup matrix"):setValue(true)
state:checkbox(0.5, 1.5, "ignore_variants", "Ignore variants, use RGB")
state:label(0.5, 2, "label_variants", "Select one or more variants:")
state:label(0.5, 2.5, "label_variants", "Select one or more variants:")
local variants_x = 0.5
local variants_y = 2.5
local variants_y = 3
local delete_button = state:button(5, 2.2, 2, 0, "delete", "Manage\nMeshes")
local give_button = state:button(5, 3.2, 2, 0, "give", "Giveme\nMeshes")
@ -772,21 +798,27 @@ function wesh.mesh_capture_confirmed(button_or_field, state)
canvas.generate_matrix = state:get("generate_matrix"):getValue()
canvas.max_faces = tonumber(state:get("max_faces"):getText()) or wesh.default_max_faces
canvas.ignore_variants = state:get("ignore_variants"):getValue()
canvas.chosen_variants = {}
local no_variants = true
for name, texture in pairs(wesh.variants) do
if state:get("variant_" .. name):getValue() then
canvas.chosen_variants[name] = texture
no_variants = false
if not canvas.ignore_variants then
local no_variants = true
for name, texture in pairs(wesh.variants) do
if state:get("variant_" .. name):getValue() then
canvas.chosen_variants[name] = texture
no_variants = false
end
end
if no_variants then
wesh.notify(playername, "Please choose at least one variant")
return
end
end
if no_variants then
wesh.notify(playername, "Please choose at least one variant")
return
end
canvas.boundary = {}
if wesh.save_new_mesh(canvas, playername, meshname) then
minetest.close_formspec(playername, "wesh.forms.capture")
@ -850,15 +882,50 @@ function wesh.save_new_mesh(canvas, playername, description)
-- this will be the actual content of the .obj file
local vt_section = wesh.vertex_textures
if canvas.ignore_variants then
vt_section = wesh.generate_custom_vt(canvas)
end
local v_section = wesh.vertices_to_string(canvas)
local vn_section = wesh.normals_to_string()
local f_section = table.concat(canvas.faces, "\n")
local f_section = table.concat(canvas.faces)
meshdata = vt_section .. v_section .. vn_section .. f_section
end
return wesh.save_mesh_to_file(obj_filename, meshdata, description, playername, canvas)
end
function wesh.color_to_hex(color)
local r = string.format("%x", color[1])
local g = string.format("%x", color[2])
local b = string.format("%x", color[3])
if #r + #g + #b ~= 3 then
r = #r == 1 and "0" .. r or r
g = #g == 1 and "0" .. g or g
b = #b == 1 and "0" .. b or b
end
return r .. g .. b
end
function wesh.generate_custom_vt(canvas)
local vt_section = {}
local tile_strings = {}
local colors = canvas.custom_texture_colors
table.insert(tile_strings, "[combine:" .. #colors .. "x1")
local step = 1 / #colors
local gap = step / 100
for i, color in ipairs(colors) do
table.insert(vt_section, "vt " .. step * (i - 1) + gap .. "\n")
table.insert(vt_section, "vt " .. step * i - gap .. "\n")
table.insert(tile_strings, ":" .. (i - 1) .. ",0=(px.png\\^[colorize\\:#" .. wesh.color_to_hex(color) .. ")")
end
canvas.tile_string = table.concat(tile_strings)
return table.concat(vt_section)
end
-- ========================================================================
-- file generation
-- ========================================================================
@ -882,6 +949,9 @@ function wesh.prepare_data_file(description, canvas)
fixed = boxes,
}
}
if canvas.ignore_variants then
data.variants = { rgb = canvas.tile_string }
end
return wesh.serialize(data, 2)
end
@ -924,7 +994,7 @@ function wesh.save_mesh_to_file(obj_filename, meshdata, description, playername,
end
local matrix_data = {
colors = canvas.matrix,
colors = canvas.wool_matrix,
nodes = canvas.node_matrix,
}
@ -1490,7 +1560,7 @@ function wesh.construct_face(rel_pos, canvas, texture_vertices, facename, vertic
local index = wesh.get_vertex_index(rel_pos, canvas, vertex)
table.insert(face_line, index .. "/" .. texture_vertices[i] .. "/" .. normal_index .. " ")
end
table.insert(canvas.faces, table.concat(face_line))
table.insert(canvas.faces, table.concat(face_line) .. "\n")
if canvas.max_faces > 0 and #canvas.faces > canvas.max_faces then
error({ msg = canvas.max_faces .. " faces limit exceeded"})
end
@ -1498,11 +1568,33 @@ end
function wesh.get_texture_vertices(color)
if not wesh.color_vertices[color] then
return wesh.color_vertices.air
error({ msg = "unable to find color " .. dump(color) .. " in wesh.color_vertices"})
end
return wesh.color_vertices[color]
end
function wesh.get_custom_texture_vertices(color, canvas)
if type(color) ~= "table" then
error({ msg = "passed color variable " .. dump(color) .. " isn't a table"})
end
if #color ~= 3 then
error({ msg = "bad length of color table " .. dump(color)})
end
local index = table.concat(color, "-")
local vi = canvas.custom_texture_vertices_mapping[index]
if not vi then
vi = #canvas.custom_texture_colors * 2 + 1
table.insert(canvas.custom_texture_colors, color)
canvas.custom_texture_vertices_mapping[index] = vi
end
return {vi, vi, vi + 1, vi + 1}
end
function wesh.get_vertex_index(pos, canvas, vertex_number)
-- get integral offset of vertices related to voxel center
local offset = wesh.cube_vertices[vertex_number]
@ -1567,13 +1659,22 @@ function wesh.node_to_voxel(rel_pos, canvas)
local paramtype2 = node and wesh.get_nodedef_field(node.name, "paramtype2")
if paramtype2 == "facedir" then
if paramtype2 == "facedir" or paramtype2 == "colorfacedir" then
nodedata[2] = wesh.transform_facedir(canvas.facedir, node.param2, true)
end
local nodename = nodedata[1]
local color = wesh.nodename_to_color[nodename] or "air"
local color = ""
local rgb_color = wesh.nodename_to_rgb[nodename] or "air"
local wool_color = wesh.nodename_to_color[nodename] or "air"
if canvas.ignore_variants then
color = rgb_color
else
color = wool_color
end
if color ~= "air" then
canvas.voxel_count = canvas.voxel_count + 1
@ -1584,6 +1685,7 @@ function wesh.node_to_voxel(rel_pos, canvas)
canvas.nodename_count = canvas.nodename_count + 1
end
canvas.wool_matrix[rel_pos.x][rel_pos.y][rel_pos.z] = wool_color
canvas.matrix[rel_pos.x][rel_pos.y][rel_pos.z] = color
canvas.node_matrix[rel_pos.x][rel_pos.y][rel_pos.z] = nodedata
end
@ -1600,7 +1702,12 @@ function wesh.voxel_to_faces(rel_pos, canvas)
local color = wesh.get_voxel_color(rel_pos, canvas)
if color == "air" then return end
for facename, facedata in pairs(wesh.face_construction) do
local texture_vertices = wesh.get_texture_vertices(color)
local texture_vertices = ""
if canvas.ignore_variants then
texture_vertices = wesh.get_custom_texture_vertices(color, canvas)
else
texture_vertices = wesh.get_texture_vertices(color)
end
wesh.construct_face(rel_pos, canvas, texture_vertices, facename, facedata.vertices, facedata.normal)
end
end

View File

@ -1046,6 +1046,12 @@ smartfs.element("field", {
self:getCloseOnEnterString()
end
end,
setLabel = function(self,text)
self.data.label = text
end,
getLabel = function(self)
return self.data.label
end,
setText = function(self,text)
self:setValue(text)
end,
@ -1169,6 +1175,10 @@ smartfs.element("list", {
if not self.data.items then
self.data.items = {}
end
local escaped = {}
for i, v in ipairs(self.data.items) do
escaped[i] = minetest.formspec_escape(v)
end
return "textlist["..
self.data.pos.x..","..self.data.pos.y..
";"..
@ -1176,7 +1186,7 @@ smartfs.element("list", {
";"..
self:getAbsName()..
";"..
table.concat(self.data.items, ",")..
table.concat(escaped, ",")..
";"..
tostring(self.data.selected or "")..
";"..
@ -1205,7 +1215,7 @@ smartfs.element("list", {
self._doubleClick = func
end,
addItem = function(self, item)
table.insert(self.data.items, minetest.formspec_escape(item))
table.insert(self.data.items, item)
-- return the index of item. It is the last one
return #self.data.items
end,
@ -1291,6 +1301,14 @@ smartfs.element("dropdown", {
self.data.selected = idx
self.data.value = self:getItem(idx) or ""
end,
setSelectedItem = function(self,itm)
for idx, item in ipairs(self.data.items) do
if item == itm then
self.data.selected = idx
self.data.value = item
end
end
end,
getSelected = function(self)
self.data.selected = 1
if #self.data.items > 1 then

BIN
textures/px.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 B