minecraft: separate mesh for tallgrass
This commit is contained in:
parent
9d97d6448e
commit
8ce7ca035a
Binary file not shown.
@ -1,98 +1,7 @@
|
|||||||
import struct
|
import struct
|
||||||
|
|
||||||
def id_to_px(i):
|
|
||||||
x = i % 16
|
|
||||||
y = i // 16
|
|
||||||
return x * 16, y * 16
|
|
||||||
|
|
||||||
def px_to_id(px, py):
|
|
||||||
x = px // 16
|
|
||||||
y = py // 16
|
|
||||||
i = y * 16 + x
|
|
||||||
return i
|
|
||||||
|
|
||||||
unk = 185
|
unk = 185
|
||||||
|
|
||||||
mapping = [
|
|
||||||
(1, 1, "stone"),
|
|
||||||
(2, 0, "grass"),
|
|
||||||
(31, 0, "grass"), # fixme actually tallgrass
|
|
||||||
(3, 2, "dirt"),
|
|
||||||
(4, 16, "stonebrick"),
|
|
||||||
(5, 4, "wood"),
|
|
||||||
(6, 15, "sapling"),
|
|
||||||
(7, 17, "bedrock"),
|
|
||||||
(8, 205, "water"), # flowing
|
|
||||||
(9, 205, "water"), # still
|
|
||||||
(10, 237, "lava"), # flowing
|
|
||||||
(11, 237, "lava"), # still
|
|
||||||
(12, 18, "sand"),
|
|
||||||
(13, 19, "gravel"),
|
|
||||||
(14, 32, "oreGold"),
|
|
||||||
(15, 33, "oreIron"),
|
|
||||||
(16, 34, "oreCoal"),
|
|
||||||
(17, 20, "log"),
|
|
||||||
(18, 52, "leaves"),
|
|
||||||
(19, 48, "sponge"),
|
|
||||||
(20, 49, "glass"),
|
|
||||||
(35, 64, "cloth"),
|
|
||||||
(37, 13, "flower"),
|
|
||||||
(38, 12, "rose"),
|
|
||||||
(39, 29, "mushroom"),
|
|
||||||
(40, 28, "mushroom"),
|
|
||||||
(41, 39, "blockGold"),
|
|
||||||
(42, 38, "blockIron"),
|
|
||||||
(43, 5, "stoneSlab"), # double
|
|
||||||
(44, 5, "stoneSlab"), # single
|
|
||||||
(45, 7, "brick"),
|
|
||||||
(46, 8, "tnt"),
|
|
||||||
(47, 35, "bookshelf"),
|
|
||||||
(48, 36, "stoneMoss"),
|
|
||||||
(49, 37, "obsidian"),
|
|
||||||
(50, 80, "torch"),
|
|
||||||
(51, 31, "fire"),
|
|
||||||
(52, 65, "mobSpawner"),
|
|
||||||
(53, 4, "stairsWood"),
|
|
||||||
(54, 27, "chest"),
|
|
||||||
(55, 84, "redstoneDust"),
|
|
||||||
(56, 50, "oreDiamond"),
|
|
||||||
(57, 40, "blockDiamond"),
|
|
||||||
(58, 43, "workbench"),
|
|
||||||
(59, 88, "crops"),
|
|
||||||
(60, 87, "farmland"),
|
|
||||||
(61, 44, "furnace"), # off
|
|
||||||
(62, 61, "furnace"), # burning
|
|
||||||
(63, unk, "sign"),
|
|
||||||
(64, 81, "doorWood"),
|
|
||||||
(65, 83, "ladder"),
|
|
||||||
(66, 128, "rail"),
|
|
||||||
(67, 16, "stairsStone"),
|
|
||||||
(68, unk, "sign"),
|
|
||||||
(69, 96, "lever"),
|
|
||||||
(70, 6, "pressurePlate"),
|
|
||||||
(71, 82, "doorIron"),
|
|
||||||
(72, 6, "pressurePlate"),
|
|
||||||
(73, 51, "oreRedstone"),
|
|
||||||
(74, 51, "oreRedstone"),
|
|
||||||
(75, 115, "notGate"),
|
|
||||||
(76, 99, "notGate"),
|
|
||||||
(77, unk, "button"),
|
|
||||||
(78, 66, "snow"),
|
|
||||||
(79, 67, "ice"),
|
|
||||||
(80, 66, "snow"),
|
|
||||||
(81, 70, "cactus"),
|
|
||||||
(82, 72, "clay"),
|
|
||||||
(83, 73, "reeds"),
|
|
||||||
(84, 74, "jukebox"),
|
|
||||||
(85, 4, "fence"),
|
|
||||||
(86, 102, "pumpkin"),
|
|
||||||
(87, 103, "hellrock"),
|
|
||||||
(88, 104, "hellsand"),
|
|
||||||
(89, 105, "lightgem"),
|
|
||||||
(90, 14, "portal"),
|
|
||||||
(91, 102, "pumpkin"),
|
|
||||||
]
|
|
||||||
|
|
||||||
lookup = {
|
lookup = {
|
||||||
k: v for k, v, _ in mapping
|
k: v for k, v, _ in mapping
|
||||||
}
|
}
|
||||||
|
|||||||
36
minecraft/gen/cube.obj
Normal file
36
minecraft/gen/cube.obj
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# Blender 5.0.0
|
||||||
|
# www.blender.org
|
||||||
|
o Cube
|
||||||
|
v 1.000000 1.000000 -1.000000
|
||||||
|
v 1.000000 -1.000000 -1.000000
|
||||||
|
v 1.000000 1.000000 1.000000
|
||||||
|
v 1.000000 -1.000000 1.000000
|
||||||
|
v -1.000000 1.000000 -1.000000
|
||||||
|
v -1.000000 -1.000000 -1.000000
|
||||||
|
v -1.000000 1.000000 1.000000
|
||||||
|
v -1.000000 -1.000000 1.000000
|
||||||
|
vn -0.0000 1.0000 -0.0000
|
||||||
|
vn -0.0000 -0.0000 1.0000
|
||||||
|
vn -1.0000 -0.0000 -0.0000
|
||||||
|
vn -0.0000 -1.0000 -0.0000
|
||||||
|
vn 1.0000 -0.0000 -0.0000
|
||||||
|
vn -0.0000 -0.0000 -1.0000
|
||||||
|
vt 1.000000 0.000000
|
||||||
|
vt 0.000000 1.000000
|
||||||
|
vt 0.000000 0.000000
|
||||||
|
vt 1.000000 1.000000
|
||||||
|
vt -0.000000 0.000000
|
||||||
|
vt 1.000000 -0.000000
|
||||||
|
s 0
|
||||||
|
f 5/1/1 3/2/1 1/3/1
|
||||||
|
f 3/4/2 8/5/2 4/6/2
|
||||||
|
f 7/4/3 6/5/3 8/6/3
|
||||||
|
f 2/1/4 8/2/4 6/3/4
|
||||||
|
f 1/4/5 4/5/5 2/6/5
|
||||||
|
f 5/4/6 2/5/6 6/6/6
|
||||||
|
f 5/1/1 7/4/1 3/2/1
|
||||||
|
f 3/4/2 7/2/2 8/5/2
|
||||||
|
f 7/4/3 5/2/3 6/5/3
|
||||||
|
f 2/1/4 4/4/4 8/2/4
|
||||||
|
f 1/4/5 3/2/5 4/5/5
|
||||||
|
f 5/4/6 1/2/6 2/5/6
|
||||||
@ -1,134 +0,0 @@
|
|||||||
positions = [
|
|
||||||
(1.0, 1.0, -1.0),
|
|
||||||
(1.0, -1.0, -1.0),
|
|
||||||
(1.0, 1.0, 1.0),
|
|
||||||
(1.0, -1.0, 1.0),
|
|
||||||
(-1.0, 1.0, -1.0),
|
|
||||||
(-1.0, -1.0, -1.0),
|
|
||||||
(-1.0, 1.0, 1.0),
|
|
||||||
(-1.0, -1.0, 1.0)
|
|
||||||
]
|
|
||||||
|
|
||||||
normals = [
|
|
||||||
(0.0, 1.0, 0.0),
|
|
||||||
(0.0, 0.0, 1.0),
|
|
||||||
(-1.0, 0.0, 0.0),
|
|
||||||
(0.0, -1.0, 0.0),
|
|
||||||
(1.0, 0.0, 0.0),
|
|
||||||
(0.0, 0.0, -1.0),
|
|
||||||
]
|
|
||||||
|
|
||||||
textures = [
|
|
||||||
(1.0, 0.0),
|
|
||||||
(0.0, 1.0),
|
|
||||||
(0.0, 0.0),
|
|
||||||
(1.0, 1.0),
|
|
||||||
(0.0, 0.0),
|
|
||||||
(1.0, 0.0),
|
|
||||||
]
|
|
||||||
|
|
||||||
indices = [
|
|
||||||
[
|
|
||||||
[4, 0, 0],
|
|
||||||
[2, 1, 0],
|
|
||||||
[0, 2, 0],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
[2, 3, 1],
|
|
||||||
[7, 4, 1],
|
|
||||||
[3, 5, 1],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
[6, 3, 2],
|
|
||||||
[5, 4, 2],
|
|
||||||
[7, 5, 2],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
[1, 0, 3],
|
|
||||||
[7, 1, 3],
|
|
||||||
[5, 2, 3],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
[0, 3, 4],
|
|
||||||
[3, 4, 4],
|
|
||||||
[1, 5, 4],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
[4, 3, 5],
|
|
||||||
[1, 4, 5],
|
|
||||||
[5, 5, 5],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
[4, 0, 0],
|
|
||||||
[6, 3, 0],
|
|
||||||
[2, 1, 0],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
[2, 3, 1],
|
|
||||||
[6, 1, 1],
|
|
||||||
[7, 4, 1],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
[6, 3, 2],
|
|
||||||
[4, 1, 2],
|
|
||||||
[5, 4, 2],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
[1, 0, 3],
|
|
||||||
[3, 3, 3],
|
|
||||||
[7, 1, 3],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
[0, 3, 4],
|
|
||||||
[2, 1, 4],
|
|
||||||
[3, 4, 4],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
[4, 3, 5],
|
|
||||||
[0, 1, 5],
|
|
||||||
[1, 4, 5],
|
|
||||||
],
|
|
||||||
]
|
|
||||||
|
|
||||||
vertex_buffer = []
|
|
||||||
index_buffer = []
|
|
||||||
index_lookup = {}
|
|
||||||
|
|
||||||
for triangle in indices:
|
|
||||||
for p_ix, t_ix, n_ix in triangle:
|
|
||||||
key = (p_ix, n_ix, t_ix)
|
|
||||||
if key not in index_lookup:
|
|
||||||
position = positions[p_ix]
|
|
||||||
normal = normals[n_ix]
|
|
||||||
texture = textures[t_ix]
|
|
||||||
index = len(vertex_buffer)
|
|
||||||
index_lookup[key] = index
|
|
||||||
vertex_buffer.append((tuple(position),
|
|
||||||
tuple(normal),
|
|
||||||
tuple(texture)))
|
|
||||||
|
|
||||||
index_buffer.append(index_lookup[key])
|
|
||||||
|
|
||||||
def gen():
|
|
||||||
for position, normal, texture in vertex_buffer:
|
|
||||||
p = ", ".join(map(str, map(float, position)))
|
|
||||||
n = ", ".join(map(str, map(float, normal)))
|
|
||||||
t = ", ".join(map(str, map(float, texture)))
|
|
||||||
print(f"vertex_t(vec3({p}), vec3({n}), vec2({t})),")
|
|
||||||
|
|
||||||
for i in range(len(index_buffer) // 3):
|
|
||||||
tri = ", ".join(str(index_buffer[i * 3 + n]) for n in range(3))
|
|
||||||
print(f"{tri},")
|
|
||||||
|
|
||||||
from collections import defaultdict
|
|
||||||
by_normal = defaultdict(list)
|
|
||||||
for i in range(len(index_buffer) // 3):
|
|
||||||
tri = [index_buffer[i * 3 + n] for n in range(3)]
|
|
||||||
s = set(vertex_buffer[j][1] for j in tri)
|
|
||||||
assert len(s) == 1
|
|
||||||
normal, = iter(s)
|
|
||||||
by_normal[normal].append(tri)
|
|
||||||
|
|
||||||
from pprint import pprint
|
|
||||||
pprint(dict(by_normal))
|
|
||||||
pprint(vertex_buffer)
|
|
||||||
353
minecraft/gen/data.py
Normal file
353
minecraft/gen/data.py
Normal file
@ -0,0 +1,353 @@
|
|||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
class BlockID:
|
||||||
|
AIR = 0
|
||||||
|
STONE = 1
|
||||||
|
GRASS = 2
|
||||||
|
DIRT = 3
|
||||||
|
STONEBRICK = 4
|
||||||
|
WOOD = 5
|
||||||
|
SAPLING = 6
|
||||||
|
BEDROCK = 7
|
||||||
|
WATER = 8
|
||||||
|
WATER_CALM = 9
|
||||||
|
LAVA = 10
|
||||||
|
LAVA_CALM = 11
|
||||||
|
SAND = 12
|
||||||
|
GRAVEL = 13
|
||||||
|
ORE_GOLD = 14
|
||||||
|
ORE_IRON = 15
|
||||||
|
ORE_COAL = 16
|
||||||
|
TREE_TRUNK = 17
|
||||||
|
LEAVES = 18
|
||||||
|
SPONGE = 19
|
||||||
|
GLASS = 20
|
||||||
|
ORE_LAPIS = 21
|
||||||
|
BLOCK_LAPIS = 22
|
||||||
|
DISPENSER = 23
|
||||||
|
SANDSTONE = 24
|
||||||
|
NOTE_BLOCK = 25
|
||||||
|
BED = 26
|
||||||
|
RAIL_POWERED = 27
|
||||||
|
RAIL_ACTIVATOR = 28
|
||||||
|
PISTON_STICKY = 29
|
||||||
|
COBWEB = 30
|
||||||
|
TALL_GRASS = 31
|
||||||
|
DEAD_BUSH = 32
|
||||||
|
PISTON = 33
|
||||||
|
PISTON_HEAD = 34
|
||||||
|
CLOTH = 35
|
||||||
|
PISTON_MOVING = 36
|
||||||
|
FLOWER = 37
|
||||||
|
ROSE = 38
|
||||||
|
MUSHROOM_1 = 39
|
||||||
|
MUSHROOM_2 = 40
|
||||||
|
BLOCK_GOLD = 41
|
||||||
|
BLOCK_IRON = 42
|
||||||
|
STONESLAB_FULL = 43
|
||||||
|
STONESLAB_HALF = 44
|
||||||
|
BRICKS = 45
|
||||||
|
TNT = 46
|
||||||
|
BOOKSHELF = 47
|
||||||
|
MOSS_STONE = 48
|
||||||
|
OBSIDIAN = 49
|
||||||
|
TORCH = 50
|
||||||
|
FIRE = 51
|
||||||
|
SPAWNER = 52
|
||||||
|
STAIRS_WOOD = 53
|
||||||
|
CHEST = 54
|
||||||
|
WIRE = 55
|
||||||
|
ORE_EMERALD = 56
|
||||||
|
BLOCK_EMERALD = 57
|
||||||
|
WORKBENCH = 58
|
||||||
|
WHEAT = 59
|
||||||
|
FARMLAND = 60
|
||||||
|
FURNACE = 61
|
||||||
|
FURNACE_LIT = 62
|
||||||
|
SIGN = 63
|
||||||
|
DOOR_WOOD = 64
|
||||||
|
LADDER = 65
|
||||||
|
RAIL = 66
|
||||||
|
STAIRS_STONE = 67
|
||||||
|
SIGN_WALL = 68
|
||||||
|
LEVER = 69
|
||||||
|
PLATE_STONE = 70
|
||||||
|
DOOR_IRON = 71
|
||||||
|
PLATE_WOOD = 72
|
||||||
|
ORE_REDSTONE = 73
|
||||||
|
ORE_REDSTONE_LIT = 74
|
||||||
|
NOT_GATE_OFF = 75
|
||||||
|
NOT_GATE_ON = 76
|
||||||
|
BUTTON_STONE = 77
|
||||||
|
TOPSNOW = 78
|
||||||
|
ICE = 79
|
||||||
|
SNOW = 80
|
||||||
|
CACTUS = 81
|
||||||
|
CLAY = 82
|
||||||
|
REEDS = 83
|
||||||
|
JUKEBOX = 84
|
||||||
|
FENCE = 85
|
||||||
|
PUMPKIN = 86
|
||||||
|
NETHERRACK = 87
|
||||||
|
SOUL_SAND = 88
|
||||||
|
GLOWSTONE = 89
|
||||||
|
PORTAL = 90
|
||||||
|
PUMPKIN_LIT = 91
|
||||||
|
CAKE = 92
|
||||||
|
REPEATER_OFF = 93
|
||||||
|
REPEATER_ON = 94
|
||||||
|
INVISIBLE = 95
|
||||||
|
TRAPDOOR = 96
|
||||||
|
STONE_MONSTER_EGG = 97
|
||||||
|
STONE_BRICKS = 98
|
||||||
|
MUSHROOM1_BLOCK = 99
|
||||||
|
MUSHROOM2_BLOCK = 100
|
||||||
|
CLOTH_00 = 101
|
||||||
|
CLOTH_10 = 102
|
||||||
|
CLOTH_20 = 103
|
||||||
|
CLOTH_30 = 104
|
||||||
|
CLOTH_40 = 105
|
||||||
|
CLOTH_50 = 106
|
||||||
|
CLOTH_60 = 107
|
||||||
|
CLOTH_70 = 108
|
||||||
|
CLOTH_01 = 109
|
||||||
|
CLOTH_11 = 110
|
||||||
|
CLOTH_21 = 111
|
||||||
|
CLOTH_31 = 112
|
||||||
|
CLOTH_41 = 113
|
||||||
|
CLOTH_51 = 114
|
||||||
|
CLOTH_61 = 115
|
||||||
|
|
||||||
|
INFO_UPDATEGAME1 = 248
|
||||||
|
INFO_UPDATEGAME2 = 249
|
||||||
|
LEAVES_CARRIED = 254
|
||||||
|
|
||||||
|
class Texture:
|
||||||
|
GRASS_TOP = 0
|
||||||
|
STONE = 1
|
||||||
|
DIRT = 2
|
||||||
|
GRASS_SIDE = 3
|
||||||
|
PLANKS = 4
|
||||||
|
STONE_SLAB_SIDE = 5
|
||||||
|
STONE_SLAB_TOP = 6
|
||||||
|
BRICKS = 7
|
||||||
|
TNT_SIDE = 8
|
||||||
|
TNT_TOP = 9
|
||||||
|
TNT_BOTTOM = 10
|
||||||
|
COBWEB = 11
|
||||||
|
ROSE = 12
|
||||||
|
FLOWER = 13
|
||||||
|
WATER_STATIC = 14
|
||||||
|
SAPLING = 15
|
||||||
|
STONEBRICK = 16
|
||||||
|
BEDROCK = 17
|
||||||
|
SAND = 18
|
||||||
|
GRAVEL = 19
|
||||||
|
LOG_SIDE = 20
|
||||||
|
LOG_TOP = 21
|
||||||
|
IRON = 22
|
||||||
|
GOLD = 23
|
||||||
|
EMERALD = 24
|
||||||
|
CHEST_ONE_TOP = 25
|
||||||
|
CHEST_ONE_SIDE = 26
|
||||||
|
CHEST_ONE_FRONT = 27
|
||||||
|
MUSHROOM_RED = 28
|
||||||
|
MUSHROOM_BROWN = 29
|
||||||
|
OBSIDIAN_CRYING = 30
|
||||||
|
FIRE1 = 31
|
||||||
|
ORE_GOLD = 32
|
||||||
|
ORE_IRON = 33
|
||||||
|
ORE_COAL = 34
|
||||||
|
BOOKSHELF = 35
|
||||||
|
MOSSY_STONE = 36
|
||||||
|
OBSIDIAN = 37
|
||||||
|
GRASS_SIDE_OVERLAY = 38
|
||||||
|
TALL_GRASS = 39
|
||||||
|
NONE40 = 40
|
||||||
|
CHEST_TWO_FRONT_LEFT = 41
|
||||||
|
CHEST_TWO_FRONT_RIGHT = 42
|
||||||
|
WORKBENCH_TOP = 43
|
||||||
|
FURNACE_FRONT = 44
|
||||||
|
FURNACE_SIDE = 45
|
||||||
|
DISPENSER_SIDE = 46
|
||||||
|
FIRE2 = 47
|
||||||
|
SPONGE = 48
|
||||||
|
GLASS = 49
|
||||||
|
ORE_EMERALD = 50
|
||||||
|
ORE_RED_STONE = 51
|
||||||
|
LEAVES_TRANSPARENT = 52
|
||||||
|
LEAVES_OPAQUE = 53
|
||||||
|
NONE54 = 54
|
||||||
|
DEAD_BUSH = 55
|
||||||
|
NONE56 = 56
|
||||||
|
CHEST_TWO_BACK_LEFT = 57
|
||||||
|
CHEST_TWO_BACK_RIGHT = 58
|
||||||
|
WORKBENCH_SIDE_1 = 59
|
||||||
|
WORKBENCH_SIDE_2 = 60
|
||||||
|
FURNACE_LIT = 61
|
||||||
|
FURNACE_TOP = 62
|
||||||
|
NONE63 = 63
|
||||||
|
CLOTH_64 = 64
|
||||||
|
SPAWNER = 65
|
||||||
|
SNOW = 66
|
||||||
|
ICE = 67
|
||||||
|
GRASS_SIDE_SNOW = 68
|
||||||
|
CACTUS_TOP = 69
|
||||||
|
CACTUS_SIDE = 70
|
||||||
|
CACTUS_BOTTOM = 71
|
||||||
|
CLAY = 72
|
||||||
|
REEDS = 73
|
||||||
|
JUKEBOX_SIDE = 74
|
||||||
|
JUKEBOX_TOP = 75
|
||||||
|
NONE76 = 76
|
||||||
|
NONE77 = 77
|
||||||
|
NONE78 = 78
|
||||||
|
NONE79 = 79
|
||||||
|
TORCH_LIT = 80
|
||||||
|
DOOR_TOP = 81
|
||||||
|
DOOR_IRON_TOP = 82
|
||||||
|
LADDER = 83
|
||||||
|
TRAPDOOR = 84
|
||||||
|
NONE85 = 85
|
||||||
|
FARMLAND = 86
|
||||||
|
FARMLAND_DRY = 87
|
||||||
|
WHEAT_0 = 88
|
||||||
|
WHEAT_1 = 89
|
||||||
|
WHEAT_2 = 90
|
||||||
|
WHEAT_3 = 91
|
||||||
|
WHEAT_4 = 92
|
||||||
|
WHEAT_5 = 93
|
||||||
|
WHEAT_6 = 94
|
||||||
|
WHEAT_7 = 95
|
||||||
|
LEVER = 96
|
||||||
|
DOOR_BOTTOM = 97
|
||||||
|
DOOR_IRON_BOTTOM = 98
|
||||||
|
TORCH_RED_STONE = 99
|
||||||
|
NONE100 = 100
|
||||||
|
NONE101 = 101
|
||||||
|
PUMPKIN_TOP = 102
|
||||||
|
BLOODSTONE = 103
|
||||||
|
SOULSAND = 104
|
||||||
|
GLOWSTONE = 105
|
||||||
|
STICKY_PISTON = 106
|
||||||
|
PISTON = 107
|
||||||
|
NONE108 = 108
|
||||||
|
NONE109 = 109
|
||||||
|
NONE110 = 110
|
||||||
|
NONE111 = 111
|
||||||
|
RAIL_CURVED = 112
|
||||||
|
CLOTH_112 = 113
|
||||||
|
CLOTH_113 = 114
|
||||||
|
TORCH_RED_STONE_OFF = 115
|
||||||
|
LOG_SPRUCE = 116
|
||||||
|
LOG_BIRCH = 117
|
||||||
|
PUMPKIN_SIDE = 118
|
||||||
|
PUMPKIN_FACE = 119
|
||||||
|
PUMPKIN_FACE_LIT = 120
|
||||||
|
CAKE_TOP = 121
|
||||||
|
CAKE_SIDE = 122
|
||||||
|
CAKE_SIDE_BIT = 123
|
||||||
|
CAKE_BOTTOM = 124
|
||||||
|
NONE125 = 125
|
||||||
|
NONE126 = 126
|
||||||
|
NONE127 = 127
|
||||||
|
RAIL = 128
|
||||||
|
|
||||||
|
LAPIS = 144
|
||||||
|
ORE_LAPIS = 160
|
||||||
|
POWERED_RAIL = 163
|
||||||
|
REDSTONE_DUST = 164
|
||||||
|
|
||||||
|
DETECTOR_RAIL = 195
|
||||||
|
|
||||||
|
SANDSTONE_TOP = 176
|
||||||
|
SANDSTONE_SIDE = 192
|
||||||
|
WATER = 205
|
||||||
|
SANDSTONE_BOTTOM = 208
|
||||||
|
|
||||||
|
LAVA = 237
|
||||||
|
|
||||||
|
INFO_UPDATEGAME1 = 252
|
||||||
|
INFO_UPDATEGAME2 = 253
|
||||||
|
|
||||||
|
LAVA_PLACEHOLDER = 255
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Tile:
|
||||||
|
block_id: BlockID
|
||||||
|
texture: Texture
|
||||||
|
|
||||||
|
tiles = [
|
||||||
|
Tile(BlockID.STONE, Texture.STONE),
|
||||||
|
Tile(BlockID.GRASS, Texture.GRASS_TOP), # fixme
|
||||||
|
Tile(BlockID.DIRT, Texture.DIRT),
|
||||||
|
Tile(BlockID.STONEBRICK, Texture.STONEBRICK),
|
||||||
|
Tile(BlockID.WOOD, Texture.PLANKS),
|
||||||
|
Tile(BlockID.BEDROCK, Texture.BEDROCK),
|
||||||
|
Tile(BlockID.WATER, Texture.WATER), # fixme
|
||||||
|
Tile(BlockID.WATER_CALM, Texture.WATER), # fixme
|
||||||
|
Tile(BlockID.LAVA, Texture.LAVA), # fixme
|
||||||
|
Tile(BlockID.LAVA_CALM, Texture.LAVA), # fixme
|
||||||
|
Tile(BlockID.SAND, Texture.SAND),
|
||||||
|
Tile(BlockID.GRAVEL, Texture.GRAVEL),
|
||||||
|
Tile(BlockID.ORE_GOLD, Texture.ORE_GOLD),
|
||||||
|
Tile(BlockID.ORE_IRON, Texture.ORE_IRON),
|
||||||
|
Tile(BlockID.ORE_COAL, Texture.ORE_COAL),
|
||||||
|
Tile(BlockID.TREE_TRUNK, Texture.LOG_SIDE), # fixme
|
||||||
|
Tile(BlockID.LEAVES, Texture.LEAVES_TRANSPARENT), # fixme
|
||||||
|
Tile(BlockID.GLASS, Texture.GLASS),
|
||||||
|
Tile(BlockID.ORE_LAPIS, Texture.ORE_LAPIS),
|
||||||
|
Tile(BlockID.BLOCK_LAPIS, Texture.LAPIS),
|
||||||
|
Tile(BlockID.SANDSTONE, Texture.SANDSTONE_SIDE),
|
||||||
|
Tile(BlockID.FLOWER, Texture.FLOWER),
|
||||||
|
Tile(BlockID.ROSE, Texture.ROSE),
|
||||||
|
Tile(BlockID.MUSHROOM_1, Texture.MUSHROOM_BROWN),
|
||||||
|
Tile(BlockID.MUSHROOM_2, Texture.MUSHROOM_RED),
|
||||||
|
Tile(BlockID.BLOCK_GOLD, Texture.GOLD),
|
||||||
|
Tile(BlockID.BLOCK_IRON, Texture.IRON),
|
||||||
|
Tile(BlockID.STONESLAB_FULL, Texture.STONE_SLAB_SIDE), # fixme
|
||||||
|
Tile(BlockID.STONESLAB_HALF, Texture.STONE_SLAB_SIDE), # fixme
|
||||||
|
Tile(BlockID.BRICKS, Texture.BRICKS),
|
||||||
|
Tile(BlockID.TNT, Texture.TNT_SIDE),
|
||||||
|
Tile(BlockID.BOOKSHELF, Texture.BOOKSHELF),
|
||||||
|
Tile(BlockID.MOSS_STONE, Texture.MOSSY_STONE),
|
||||||
|
Tile(BlockID.OBSIDIAN, Texture.OBSIDIAN),
|
||||||
|
Tile(BlockID.TORCH, Texture.TORCH_LIT),
|
||||||
|
Tile(BlockID.STAIRS_WOOD, Texture.PLANKS), # fixme
|
||||||
|
Tile(BlockID.ORE_EMERALD, Texture.ORE_EMERALD),
|
||||||
|
Tile(BlockID.BLOCK_EMERALD, Texture.EMERALD),
|
||||||
|
Tile(BlockID.FARMLAND, Texture.FARMLAND), # fixme
|
||||||
|
Tile(BlockID.DOOR_WOOD, Texture.DOOR_TOP), # fixme
|
||||||
|
Tile(BlockID.LADDER, Texture.LADDER),
|
||||||
|
Tile(BlockID.STAIRS_STONE, Texture.STONEBRICK),
|
||||||
|
Tile(BlockID.DOOR_IRON, Texture.DOOR_IRON_TOP), # fixme
|
||||||
|
Tile(BlockID.ORE_REDSTONE, Texture.ORE_RED_STONE), # fixme
|
||||||
|
Tile(BlockID.ORE_REDSTONE_LIT, Texture.ORE_RED_STONE), # fixme
|
||||||
|
Tile(BlockID.TOPSNOW, Texture.SNOW),
|
||||||
|
Tile(BlockID.ICE, Texture.ICE),
|
||||||
|
Tile(BlockID.SNOW, Texture.SNOW),
|
||||||
|
Tile(BlockID.CACTUS, Texture.CACTUS_SIDE),
|
||||||
|
Tile(BlockID.CLAY, Texture.CLAY),
|
||||||
|
Tile(BlockID.REEDS, Texture.REEDS),
|
||||||
|
Tile(BlockID.FENCE, Texture.PLANKS),
|
||||||
|
Tile(BlockID.INVISIBLE, Texture.STONE),
|
||||||
|
Tile(BlockID.WOOD, Texture.PLANKS),
|
||||||
|
Tile(BlockID.LEAVES_CARRIED, Texture.LEAVES_TRANSPARENT), # fixme
|
||||||
|
Tile(BlockID.FIRE, Texture.FIRE1),
|
||||||
|
Tile(BlockID.SAPLING, Texture.SAPLING),
|
||||||
|
Tile(BlockID.SPONGE, Texture.SPONGE),
|
||||||
|
Tile(BlockID.TALL_GRASS, Texture.TALL_GRASS),
|
||||||
|
Tile(BlockID.DEAD_BUSH, Texture.DEAD_BUSH),
|
||||||
|
Tile(BlockID.PUMPKIN, Texture.PUMPKIN_FACE), # fixme
|
||||||
|
Tile(BlockID.PUMPKIN_LIT, Texture.PUMPKIN_FACE_LIT), # fixme
|
||||||
|
Tile(BlockID.NETHERRACK, Texture.BLOODSTONE),
|
||||||
|
Tile(BlockID.SOUL_SAND, Texture.SOULSAND),
|
||||||
|
Tile(BlockID.GLOWSTONE, Texture.GLOWSTONE),
|
||||||
|
Tile(BlockID.COBWEB, Texture.COBWEB),
|
||||||
|
Tile(BlockID.WORKBENCH, Texture.WORKBENCH_TOP), # fixme
|
||||||
|
Tile(BlockID.WHEAT, Texture.WHEAT_0),
|
||||||
|
]
|
||||||
|
|
||||||
|
tiles_by_id = {
|
||||||
|
tile.block_id: tile for tile in tiles
|
||||||
|
}
|
||||||
@ -7,6 +7,7 @@ from collections import defaultdict
|
|||||||
import mcregion
|
import mcregion
|
||||||
import vec3
|
import vec3
|
||||||
import vertex_buffer
|
import vertex_buffer
|
||||||
|
import data
|
||||||
|
|
||||||
def wrap_n(nc, chunk_c):
|
def wrap_n(nc, chunk_c):
|
||||||
if nc < 0:
|
if nc < 0:
|
||||||
@ -17,9 +18,15 @@ def wrap_n(nc, chunk_c):
|
|||||||
chunk_c = chunk_c + 1
|
chunk_c = chunk_c + 1
|
||||||
return nc, chunk_c
|
return nc, chunk_c
|
||||||
|
|
||||||
|
non_solid_blocks = {
|
||||||
|
data.BlockID.TALL_GRASS,
|
||||||
|
data.BlockID.MUSHROOM_1,
|
||||||
|
data.BlockID.MUSHROOM_2,
|
||||||
|
}
|
||||||
|
|
||||||
def block_neighbors(level_table, chunk_x, chunk_z, block_index):
|
def block_neighbors(level_table, chunk_x, chunk_z, block_index):
|
||||||
block_id = level_table[(chunk_x, chunk_z)].blocks[block_index]
|
block_id = level_table[(chunk_x, chunk_z)].blocks[block_index]
|
||||||
if block_id == 0:
|
if block_id == data.BlockID.AIR:
|
||||||
return
|
return
|
||||||
|
|
||||||
def neighbor_exists(nx, ny, nz):
|
def neighbor_exists(nx, ny, nz):
|
||||||
@ -36,7 +43,9 @@ def block_neighbors(level_table, chunk_x, chunk_z, block_index):
|
|||||||
if key not in level_table:
|
if key not in level_table:
|
||||||
return True
|
return True
|
||||||
n_block_id = level_table[key].blocks[n_block_index]
|
n_block_id = level_table[key].blocks[n_block_index]
|
||||||
return n_block_id != 0
|
|
||||||
|
has_neighbor = (n_block_id != data.BlockID.AIR) and (n_block_id not in non_solid_blocks)
|
||||||
|
return has_neighbor
|
||||||
|
|
||||||
x, y, z = mcregion.xyz_from_block_index(block_index)
|
x, y, z = mcregion.xyz_from_block_index(block_index)
|
||||||
|
|
||||||
@ -49,7 +58,7 @@ def block_neighbors(level_table, chunk_x, chunk_z, block_index):
|
|||||||
yield i
|
yield i
|
||||||
|
|
||||||
normal_indices = list(find_non_neighbors())
|
normal_indices = list(find_non_neighbors())
|
||||||
if normal_indices:
|
if block_id in non_solid_blocks or normal_indices:
|
||||||
yield center_position, block_id, normal_indices
|
yield center_position, block_id, normal_indices
|
||||||
|
|
||||||
def devoxelize_region(level_table):
|
def devoxelize_region(level_table):
|
||||||
@ -82,31 +91,61 @@ def build_block_configuration_table():
|
|||||||
indices.extend(vertex_buffer.faces_by_normal[vertex_buffer.normals[j]])
|
indices.extend(vertex_buffer.faces_by_normal[vertex_buffer.normals[j]])
|
||||||
yield indices
|
yield indices
|
||||||
|
|
||||||
|
non_cube_blocks = {
|
||||||
|
data.BlockID.TALL_GRASS,
|
||||||
|
}
|
||||||
|
|
||||||
|
def pack_instance_data(position, block_id):
|
||||||
|
packed = struct.pack("<hhhBB",
|
||||||
|
position[0], position[1], position[2],
|
||||||
|
block_id,
|
||||||
|
0)
|
||||||
|
return packed
|
||||||
|
|
||||||
def build_block_instances(blocks):
|
def build_block_instances(blocks):
|
||||||
by_configuration = defaultdict(list)
|
by_configuration = defaultdict(list)
|
||||||
|
|
||||||
|
deferred_blocks = []
|
||||||
|
|
||||||
for position, block_id, normal_indices in blocks:
|
for position, block_id, normal_indices in blocks:
|
||||||
|
if block_id in non_cube_blocks:
|
||||||
|
deferred_blocks.append((position, block_id))
|
||||||
|
continue
|
||||||
configuration = normal_indices_as_block_configuration(normal_indices)
|
configuration = normal_indices_as_block_configuration(normal_indices)
|
||||||
#print(position, block_id, block_configuration)
|
|
||||||
by_configuration[configuration].append((position, block_id))
|
by_configuration[configuration].append((position, block_id))
|
||||||
|
|
||||||
offset = 0
|
offset = 0
|
||||||
configuration_instance_count_offset = []
|
configuration_instance_count_offset = []
|
||||||
with open(f"{data_path}.instance.vtx", "wb") as f:
|
with open(f"{data_path}.instance.vtx", "wb") as f:
|
||||||
|
######################################################################
|
||||||
|
# cubes
|
||||||
|
######################################################################
|
||||||
for configuration in range(64):
|
for configuration in range(64):
|
||||||
if configuration not in by_configuration:
|
if configuration not in by_configuration:
|
||||||
configuration_instance_count_offset.append((0, 0))
|
configuration_instance_count_offset.append((0, 0))
|
||||||
continue
|
continue
|
||||||
blocks = by_configuration[configuration]
|
_blocks = by_configuration[configuration]
|
||||||
configuration_instance_count_offset.append((len(blocks), offset))
|
configuration_instance_count_offset.append((len(_blocks), offset))
|
||||||
for position, block_id in blocks:
|
for position, block_id in _blocks:
|
||||||
packed = struct.pack("<hhhBB",
|
assert block_id not in non_cube_blocks, block_id
|
||||||
position[0], position[1], position[2],
|
packed = pack_instance_data(position, block_id)
|
||||||
block_id,
|
|
||||||
0)
|
|
||||||
f.write(packed)
|
f.write(packed)
|
||||||
offset += len(packed)
|
offset += len(packed)
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
# non-cubes
|
||||||
|
######################################################################
|
||||||
|
nc_offset = offset
|
||||||
|
nc_instance_count = 0
|
||||||
|
for position, block_id in deferred_blocks:
|
||||||
|
if block_id not in non_cube_blocks:
|
||||||
|
continue
|
||||||
|
packed = pack_instance_data(position, block_id)
|
||||||
|
f.write(packed)
|
||||||
|
offset += len(packed)
|
||||||
|
nc_instance_count += 1
|
||||||
|
configuration_instance_count_offset.append((nc_instance_count, nc_offset))
|
||||||
|
|
||||||
with open(f"{data_path}.instance.cfg", "wb") as f:
|
with open(f"{data_path}.instance.cfg", "wb") as f:
|
||||||
for instance_count, offset in configuration_instance_count_offset:
|
for instance_count, offset in configuration_instance_count_offset:
|
||||||
print(instance_count, offset)
|
print(instance_count, offset)
|
||||||
|
|||||||
80
minecraft/gen/obj.py
Normal file
80
minecraft/gen/obj.py
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
def ignore(state, line):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def normalize_float(s):
|
||||||
|
f = float(s)
|
||||||
|
if f == -0.0:
|
||||||
|
return 0.0
|
||||||
|
return f
|
||||||
|
|
||||||
|
def parse_float_components(s, length):
|
||||||
|
components = s.split()
|
||||||
|
assert len(components) == length
|
||||||
|
return tuple(map(normalize_float, components))
|
||||||
|
|
||||||
|
def parse_position(state, line):
|
||||||
|
position = parse_float_components(line, 3)
|
||||||
|
state.position.append(position)
|
||||||
|
|
||||||
|
def parse_normal(state, line):
|
||||||
|
normal = parse_float_components(line, 3)
|
||||||
|
state.normal.append(normal)
|
||||||
|
|
||||||
|
def parse_texture(state, line):
|
||||||
|
texture = parse_float_components(line, 2)
|
||||||
|
state.texture.append(texture)
|
||||||
|
|
||||||
|
def parse_ptn(s):
|
||||||
|
ptn = tuple(int(i) - 1 for i in s.split("/"))
|
||||||
|
assert all(c >= 0 for c in ptn), ptn
|
||||||
|
assert len(ptn) == 3, ptn
|
||||||
|
return ptn
|
||||||
|
|
||||||
|
def parse_triangle(state, line):
|
||||||
|
indices = line.split()
|
||||||
|
assert len(indices) == 3, line
|
||||||
|
triangle = tuple(map(parse_ptn, indices))
|
||||||
|
state.triangle.append(triangle)
|
||||||
|
|
||||||
|
prefixes = [
|
||||||
|
("#", ignore),
|
||||||
|
("o ", ignore),
|
||||||
|
("s ", ignore),
|
||||||
|
("v ", parse_position),
|
||||||
|
("vn ", parse_normal),
|
||||||
|
("vt ", parse_texture),
|
||||||
|
("f ", parse_triangle),
|
||||||
|
]
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ObjState:
|
||||||
|
position: list
|
||||||
|
normal: list
|
||||||
|
texture: list
|
||||||
|
triangle: list
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.position = []
|
||||||
|
self.normal = []
|
||||||
|
self.texture = []
|
||||||
|
self.triangle = []
|
||||||
|
|
||||||
|
def parse_obj(s):
|
||||||
|
state = ObjState()
|
||||||
|
lines = s.strip().split("\n")
|
||||||
|
for line in lines:
|
||||||
|
for prefix, func in prefixes:
|
||||||
|
if line.startswith(prefix):
|
||||||
|
line = line.removeprefix(prefix)
|
||||||
|
func(state, line)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
assert False, line
|
||||||
|
return state
|
||||||
|
|
||||||
|
def parse_obj_from_filename(filename):
|
||||||
|
with open(filename, "r") as f:
|
||||||
|
buf = f.read()
|
||||||
|
return parse_obj(buf)
|
||||||
25
minecraft/gen/obj_state.py
Normal file
25
minecraft/gen/obj_state.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
from collections import defaultdict
|
||||||
|
import obj
|
||||||
|
|
||||||
|
def append_triangles(state, vertex_buffer, index_buffer, index_lookup):
|
||||||
|
for triangle in state.triangle:
|
||||||
|
for p_ix, t_ix, n_ix in triangle:
|
||||||
|
key = (p_ix, n_ix, t_ix)
|
||||||
|
if key not in index_lookup:
|
||||||
|
position = state.position[p_ix]
|
||||||
|
normal = state.normal[n_ix]
|
||||||
|
texture = state.texture[t_ix]
|
||||||
|
index = len(vertex_buffer)
|
||||||
|
index_lookup[key] = index
|
||||||
|
vertex_buffer.append((position, normal, texture))
|
||||||
|
index_buffer.append(index_lookup[key])
|
||||||
|
|
||||||
|
def build_faces_by_normal(vertex_buffer, index_buffer):
|
||||||
|
by_normal = defaultdict(list)
|
||||||
|
for i in range(len(index_buffer) // 3):
|
||||||
|
tri = [index_buffer[i * 3 + n] for n in range(3)]
|
||||||
|
s = set(vertex_buffer[j][1] for j in tri)
|
||||||
|
assert len(s) == 1, s
|
||||||
|
normal, = iter(s)
|
||||||
|
by_normal[normal].extend(tri)
|
||||||
|
return by_normal
|
||||||
24
minecraft/gen/tallgrass.obj
Normal file
24
minecraft/gen/tallgrass.obj
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Blender 5.0.0
|
||||||
|
# www.blender.org
|
||||||
|
o TallGrass
|
||||||
|
v 0.800011 0.600021 0.800011
|
||||||
|
v 0.800011 -1.000000 0.800011
|
||||||
|
v -0.800010 -1.000000 0.800011
|
||||||
|
v -0.800011 0.600021 0.800011
|
||||||
|
v -0.800011 0.600021 -0.800011
|
||||||
|
v -0.800011 -1.000000 -0.800011
|
||||||
|
v 0.800011 -1.000000 -0.800011
|
||||||
|
v 0.800010 0.600022 -0.800011
|
||||||
|
vn 0.7071 -0.0000 0.7071
|
||||||
|
vn 0.7071 -0.0000 -0.7071
|
||||||
|
vt 1.000000 1.000000
|
||||||
|
vt 0.000000 -0.000000
|
||||||
|
vt 1.000000 0.000000
|
||||||
|
vt 1.000000 1.000000
|
||||||
|
vt -0.000000 1.000000
|
||||||
|
vt 1.000000 0.000000
|
||||||
|
s 0
|
||||||
|
f 3/1/1 8/2/1 4/3/1
|
||||||
|
f 5/2/2 2/4/2 6/5/2
|
||||||
|
f 3/1/1 7/5/1 8/2/1
|
||||||
|
f 5/2/2 1/6/2 2/4/2
|
||||||
@ -1,41 +1,8 @@
|
|||||||
import struct
|
import struct
|
||||||
import vec3
|
import vec3
|
||||||
|
import obj
|
||||||
vertex_table = [
|
import obj_state
|
||||||
((-1.0, 1.0, -1.0), (0.0, 1.0, 0.0), (1.0, 0.0)),
|
import sys
|
||||||
((1.0, 1.0, 1.0), (0.0, 1.0, 0.0), (0.0, 1.0)),
|
|
||||||
((1.0, 1.0, -1.0), (0.0, 1.0, 0.0), (0.0, 0.0)),
|
|
||||||
((1.0, 1.0, 1.0), (0.0, 0.0, 1.0), (1.0, 1.0)),
|
|
||||||
((-1.0, -1.0, 1.0), (0.0, 0.0, 1.0), (0.0, 0.0)),
|
|
||||||
((1.0, -1.0, 1.0), (0.0, 0.0, 1.0), (1.0, 0.0)),
|
|
||||||
((-1.0, 1.0, 1.0), (-1.0, 0.0, 0.0), (1.0, 1.0)),
|
|
||||||
((-1.0, -1.0, -1.0), (-1.0, 0.0, 0.0), (0.0, 0.0)),
|
|
||||||
((-1.0, -1.0, 1.0), (-1.0, 0.0, 0.0), (1.0, 0.0)),
|
|
||||||
((1.0, -1.0, -1.0), (0.0, -1.0, 0.0), (1.0, 0.0)),
|
|
||||||
((-1.0, -1.0, 1.0), (0.0, -1.0, 0.0), (0.0, 1.0)),
|
|
||||||
((-1.0, -1.0, -1.0), (0.0, -1.0, 0.0), (0.0, 0.0)),
|
|
||||||
((1.0, 1.0, -1.0), (1.0, 0.0, 0.0), (1.0, 1.0)),
|
|
||||||
((1.0, -1.0, 1.0), (1.0, 0.0, 0.0), (0.0, 0.0)),
|
|
||||||
((1.0, -1.0, -1.0), (1.0, 0.0, 0.0), (1.0, 0.0)),
|
|
||||||
((-1.0, 1.0, -1.0), (0.0, 0.0, -1.0), (1.0, 1.0)),
|
|
||||||
((1.0, -1.0, -1.0), (0.0, 0.0, -1.0), (0.0, 0.0)),
|
|
||||||
((-1.0, -1.0, -1.0), (0.0, 0.0, -1.0), (1.0, 0.0)),
|
|
||||||
((-1.0, 1.0, 1.0), (0.0, 1.0, 0.0), (1.0, 1.0)),
|
|
||||||
((-1.0, 1.0, 1.0), (0.0, 0.0, 1.0), (0.0, 1.0)),
|
|
||||||
((-1.0, 1.0, -1.0), (-1.0, 0.0, 0.0), (0.0, 1.0)),
|
|
||||||
((1.0, -1.0, 1.0), (0.0, -1.0, 0.0), (1.0, 1.0)),
|
|
||||||
((1.0, 1.0, 1.0), (1.0, 0.0, 0.0), (0.0, 1.0)),
|
|
||||||
((1.0, 1.0, -1.0), (0.0, 0.0, -1.0), (0.0, 1.0))
|
|
||||||
]
|
|
||||||
|
|
||||||
faces_by_normal = {
|
|
||||||
(-1.0, 0.0, 0.0): [6, 7, 8, 6, 20, 7],
|
|
||||||
(0.0, -1.0, 0.0): [9, 10, 11, 9, 21, 10],
|
|
||||||
(0.0, 0.0, -1.0): [15, 16, 17, 15, 23, 16],
|
|
||||||
(0.0, 0.0, 1.0): [3, 4, 5, 3, 19, 4],
|
|
||||||
(0.0, 1.0, 0.0): [0, 1, 2, 0, 18, 1],
|
|
||||||
(1.0, 0.0, 0.0): [12, 13, 14, 12, 22, 13]
|
|
||||||
}
|
|
||||||
|
|
||||||
normals = [
|
normals = [
|
||||||
(-1.0, 0.0, 0.0),
|
(-1.0, 0.0, 0.0),
|
||||||
@ -46,7 +13,9 @@ normals = [
|
|||||||
(1.0, 0.0, 0.0),
|
(1.0, 0.0, 0.0),
|
||||||
]
|
]
|
||||||
|
|
||||||
def build_configuration_index_buffers(f):
|
def build_configuration_index_buffers(f, faces_by_normal):
|
||||||
|
assert(set(normals) == set(faces_by_normal.keys()))
|
||||||
|
|
||||||
offset = 0
|
offset = 0
|
||||||
configuration_offsets = []
|
configuration_offsets = []
|
||||||
for configuration in range(64):
|
for configuration in range(64):
|
||||||
@ -65,14 +34,37 @@ def build_configuration_index_buffers(f):
|
|||||||
if i % 8 == 7:
|
if i % 8 == 7:
|
||||||
print()
|
print()
|
||||||
|
|
||||||
def build_vertex_buffer(f):
|
def build_vertex_buffer(f, vertex_buffer):
|
||||||
for position, normal, texture in vertex_table:
|
for position, normal, texture in vertex_buffer:
|
||||||
position = vec3.mul(position, 0.5)
|
position = vec3.mul(position, 0.5)
|
||||||
f.write(struct.pack("<eeeeeeee", *position, *normal, *texture))
|
f.write(struct.pack("<eeeeeeee", *position, *normal, *texture))
|
||||||
|
|
||||||
if __name__ == "__main__":
|
def write_indices(f, index_buffer, start, count):
|
||||||
with open("configuration.idx", "wb") as f:
|
for i in range(count):
|
||||||
build_configuration_index_buffers(f)
|
f.write(struct.pack("<B", index_buffer[start + i]))
|
||||||
|
|
||||||
with open("per_vertex.vtx", "wb") as f:
|
def main():
|
||||||
build_vertex_buffer(f)
|
vertex_buffer = []
|
||||||
|
index_buffer = []
|
||||||
|
index_lookup = {}
|
||||||
|
|
||||||
|
cube_state = obj.parse_obj_from_filename("cube.obj")
|
||||||
|
|
||||||
|
obj_state.append_triangles(cube_state, vertex_buffer, index_buffer, index_lookup)
|
||||||
|
cube_faces_by_normal = obj_state.build_faces_by_normal(vertex_buffer, index_buffer)
|
||||||
|
|
||||||
|
tallgrass_index_start = len(index_buffer)
|
||||||
|
tallgrass_state = obj.parse_obj_from_filename("tallgrass.obj")
|
||||||
|
obj_state.append_triangles(tallgrass_state, vertex_buffer, index_buffer, index_lookup)
|
||||||
|
tallgrass_index_count = len(index_buffer) - tallgrass_index_start
|
||||||
|
print(tallgrass_index_start, tallgrass_index_count)
|
||||||
|
|
||||||
|
with open("../configuration.idx", "wb") as f:
|
||||||
|
build_configuration_index_buffers(f, cube_faces_by_normal)
|
||||||
|
write_indices(f, index_buffer, tallgrass_index_start, tallgrass_index_count)
|
||||||
|
|
||||||
|
with open("../per_vertex.vtx", "wb") as f:
|
||||||
|
build_vertex_buffer(f, vertex_buffer)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -12,7 +12,7 @@ uniform sampler2D TerrainSampler;
|
|||||||
|
|
||||||
int Textures[256] = int[256](
|
int Textures[256] = int[256](
|
||||||
185, 1, 0, 2, 16, 4, 15, 17, 205, 205, 237, 237, 18, 19, 32, 33,
|
185, 1, 0, 2, 16, 4, 15, 17, 205, 205, 237, 237, 18, 19, 32, 33,
|
||||||
34, 20, 52, 48, 49, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 0,
|
34, 20, 52, 48, 49, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 39,
|
||||||
185, 185, 185, 64, 185, 13, 12, 29, 28, 39, 38, 5, 5, 7, 8, 35,
|
185, 185, 185, 64, 185, 13, 12, 29, 28, 39, 38, 5, 5, 7, 8, 35,
|
||||||
36, 37, 80, 31, 65, 4, 27, 84, 50, 40, 43, 88, 87, 44, 61, 185,
|
36, 37, 80, 31, 65, 4, 27, 84, 50, 40, 43, 88, 87, 44, 61, 185,
|
||||||
81, 83, 128, 16, 185, 96, 6, 82, 6, 51, 51, 115, 99, 185, 66, 67,
|
81, 83, 128, 16, 185, 96, 6, 82, 6, 51, 51, 115, 99, 185, 66, 67,
|
||||||
@ -46,11 +46,13 @@ void main()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (int(fs_in.BlockID) == 18) // leaves
|
if (fs_in.BlockID == 18 || fs_in.BlockID == 31) // leaves
|
||||||
texture_color.xyz *= vec3(0.125, 0.494, 0.027);
|
texture_color.xyz *= vec3(0.125, 0.494, 0.027);
|
||||||
|
|
||||||
if (diffuse_intensity < 0.1)
|
if (diffuse_intensity < 0.1)
|
||||||
diffuse_intensity = 0.1;
|
diffuse_intensity = 0.1;
|
||||||
|
if (fs_in.BlockID == 31) // tall_grass
|
||||||
|
diffuse_intensity = 1.0;
|
||||||
|
|
||||||
FragColor = vec4(texture_color.xyz * vec3(diffuse_intensity), 1.0);
|
FragColor = vec4(texture_color.xyz * vec3(diffuse_intensity), 1.0);
|
||||||
}
|
}
|
||||||
|
|||||||
26
src/test.cpp
26
src/test.cpp
@ -34,7 +34,7 @@ struct char_tpl {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const int region_count = 4;
|
static const int region_count = 4;
|
||||||
static const char_tpl vertex_paths[region_count] = {
|
static const char_tpl vertex_paths[] = {
|
||||||
{ "minecraft/region.0.0.instance.vtx", "minecraft/region.0.0.instance.cfg" },
|
{ "minecraft/region.0.0.instance.vtx", "minecraft/region.0.0.instance.cfg" },
|
||||||
{ "minecraft/region.-1.0.instance.vtx", "minecraft/region.-1.0.instance.cfg" },
|
{ "minecraft/region.-1.0.instance.vtx", "minecraft/region.-1.0.instance.cfg" },
|
||||||
{ "minecraft/region.0.-1.instance.vtx", "minecraft/region.0.-1.instance.cfg" },
|
{ "minecraft/region.0.-1.instance.vtx", "minecraft/region.0.-1.instance.cfg" },
|
||||||
@ -49,11 +49,13 @@ static unsigned int per_vertex_buffer;
|
|||||||
static const int vertex_size = 8;
|
static const int vertex_size = 8;
|
||||||
static const int per_vertex_size = (3 + 3 + 2) * 2;
|
static const int per_vertex_size = (3 + 3 + 2) * 2;
|
||||||
|
|
||||||
|
static const int instance_cfg_length = 64 + 1;
|
||||||
|
|
||||||
struct instance_cfg {
|
struct instance_cfg {
|
||||||
struct {
|
struct region_instance {
|
||||||
int instance_count;
|
int instance_count;
|
||||||
int offset;
|
int offset;
|
||||||
} cfg[64];
|
} cfg[instance_cfg_length];
|
||||||
};
|
};
|
||||||
|
|
||||||
static instance_cfg instance_cfg[region_count];
|
static instance_cfg instance_cfg[region_count];
|
||||||
@ -160,7 +162,7 @@ void load_instance_cfg(int i)
|
|||||||
{
|
{
|
||||||
int data_size;
|
int data_size;
|
||||||
void * data = read_file(vertex_paths[i].cfg, &data_size);
|
void * data = read_file(vertex_paths[i].cfg, &data_size);
|
||||||
assert(data_size == 512);
|
assert(data_size == (sizeof (struct instance_cfg)));
|
||||||
|
|
||||||
memcpy(&instance_cfg[i], data, data_size);
|
memcpy(&instance_cfg[i], data, data_size);
|
||||||
}
|
}
|
||||||
@ -308,6 +310,9 @@ void draw()
|
|||||||
for (int region_index = 0; region_index < region_count; region_index++) {
|
for (int region_index = 0; region_index < region_count; region_index++) {
|
||||||
glBindVertexBuffer(1, per_instance_vertex_buffers[region_index], 0, vertex_size);
|
glBindVertexBuffer(1, per_instance_vertex_buffers[region_index], 0, vertex_size);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// cube blocks
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
for (int configuration = 1; configuration < 64; configuration++) {
|
for (int configuration = 1; configuration < 64; configuration++) {
|
||||||
int element_count = 6 * popcount(configuration);
|
int element_count = 6 * popcount(configuration);
|
||||||
const void * indices = (void *)((ptrdiff_t)index_buffer_configuration_offsets[configuration]); // index into configuration.idx
|
const void * indices = (void *)((ptrdiff_t)index_buffer_configuration_offsets[configuration]); // index into configuration.idx
|
||||||
@ -320,5 +325,18 @@ void draw()
|
|||||||
|
|
||||||
glDrawElementsInstancedBaseInstance(GL_TRIANGLES, element_count, GL_UNSIGNED_BYTE, indices, instance_count, base_instance);
|
glDrawElementsInstancedBaseInstance(GL_TRIANGLES, element_count, GL_UNSIGNED_BYTE, indices, instance_count, base_instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// non-cube blocks
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
{
|
||||||
|
int element_count = 6 * 2;
|
||||||
|
const void * indices = (void *)((ptrdiff_t)1152);
|
||||||
|
int instance_count = instance_cfg[region_index].cfg[64].instance_count;
|
||||||
|
int base_instance = instance_cfg[region_index].cfg[64].offset / vertex_size; // index into region.0.0.instance.vtx
|
||||||
|
if (instance_count == 0)
|
||||||
|
continue;
|
||||||
|
glDrawElementsInstancedBaseInstance(GL_TRIANGLES, element_count, GL_UNSIGNED_BYTE, indices, instance_count, base_instance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user