1 /** 2 Copyright: Copyright (c) 2016-2018 Andrey Penechko. 3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 4 Authors: Andrey Penechko. 5 */ 6 module voxelman.world.block.shape; 7 8 import voxelman.log; 9 import voxelman.core.config; 10 11 import slope = voxelman.world.mesh.tables.slope; 12 13 /* 14 block shapes: 15 16 empty empty x6 17 full full x6 18 half full + empty + half x4 19 stairs stairs x2 + half x2 + fullx2 20 slope slope x2 + full x2 + empty x2 21 corner slope x3 + empty x3 22 inner slope x3 + full x3 23 pyramid slope x2 + full x1 + empty x3 24 25 side masks: 26 27 empty 28 full 29 half 30 slope 31 stairs 32 33 corners: (1 corner has mesh, 0 has no mesh) 34 35 empty 0 x8 36 full 1 x8 37 half 1 x4 + 0 x4 38 stairs 1 x6 + 0 x2 39 slope 1 x6 + 0 x2 40 corner 1 x4 + 0 x4 41 inner 1 x7 + 0 x1 42 pyramid 1 x5 + 0 x5 43 44 has middle piece 45 46 empty no 47 full no 48 half yes 49 stairs yes 50 slope yes 51 corner yes 52 inner yes 53 pyramid yes 54 */ 55 56 // index is side shape 57 // value is 58 ubyte[] blockSideCorners = [ 59 // 3210 corners 60 0b_0000, // empty 61 0b_1111, // full 62 0b_0110, // half 63 0b_0111, // slope 64 0b_0111, // stairs 65 ]; 66 67 enum NUM_SIDE_MASKS = ShapeSideMask.max + 1; 68 69 enum ShapeSideMask : ubyte 70 { 71 empty, 72 water, 73 full, 74 half, 75 slope0, // top-left 76 slope1, // bot-left 77 slope2, // bot-right 78 slope3, // top-right 79 stairs, 80 } 81 82 struct ShapeSide 83 { 84 ShapeSideMask mask; 85 ubyte rotation; 86 } 87 88 struct BlockShape 89 { 90 ShapeSideMask[6] sideMasks; 91 ubyte corners; // bits are corners 92 bool hasGeometry; 93 bool hasInternalGeometry; 94 } 95 96 import std.range : repeat, take; 97 import std.array : array; 98 const ShapeSideMask[6] fullShapeSides = ShapeSideMask.full.repeat.take(6).array; 99 const ShapeSideMask[6] waterShapeSides = ShapeSideMask.water.repeat.take(6).array; 100 const ShapeSideMask[6] emptyShapeSides = ShapeSideMask.empty.repeat.take(6).array; 101 102 const BlockShape unknownShape = BlockShape(fullShapeSides, 0b_0000_0000, false, false); 103 const BlockShape fullShape = BlockShape(fullShapeSides, 0b_1111_1111, true, false); 104 const BlockShape waterShape = BlockShape(waterShapeSides, 0b_1111_1111, false, false); 105 const BlockShape emptyShape = BlockShape(emptyShapeSides, 0b_0000_0000, false, false); 106 107 BlockShape slopeShapeFromMeta(BlockMetadata metadata) 108 { 109 return slope.metaToShapeTable[metadata]; 110 } 111 112 /* 113 struct SideIntersectionTable 114 { 115 ubyte[] table; 116 size_t numTypes; 117 118 /// Returns true if current shape side is visible 119 pragma(inline, true) 120 bool get(const ShapeSideMask current, const ShapeSideMask other) 121 { 122 size_t index = current * numTypes + other; 123 return (table[index>>3] & (1 << (index & 0b111))) != 0; 124 } 125 126 void set(const ShapeSideMask current, const ShapeSideMask other) 127 { 128 size_t index = current * numTypes + other; 129 table[index>>3] |= (1 << (index & 0b111)); 130 } 131 132 void reset(const ShapeSideMask current, const ShapeSideMask other) 133 { 134 size_t index = current * numTypes + other; 135 table[index>>3] &= ~(1 << (index & 0b111)); 136 } 137 } 138 139 SideIntersectionTable sideIntersectionTable(size_t numTypes) 140 { 141 size_t tableBits = numTypes * numTypes; 142 size_t tableBytes = tableBits/8 + 1; 143 return SideIntersectionTable(new ubyte[tableBytes], numTypes); 144 }*/ 145 146 struct SideIntersectionTable 147 { 148 bool[] table; 149 size_t numTypes; 150 151 /// Returns true if current shape side is visible 152 pragma(inline, true) 153 bool get(const ShapeSideMask current, const ShapeSideMask other) 154 { 155 size_t index = current * numTypes + other; 156 return table[index]; 157 } 158 159 void set(const ShapeSideMask current, const ShapeSideMask other) 160 { 161 size_t index = current * numTypes + other; 162 table[index] = true; 163 } 164 165 void reset(const ShapeSideMask current, const ShapeSideMask other) 166 { 167 size_t index = current * numTypes + other; 168 table[index] = false; 169 } 170 } 171 172 SideIntersectionTable sideIntersectionTable(size_t numTypes) 173 { 174 size_t tableBits = numTypes * numTypes; 175 //size_t tableBytes = tableBits/8 + 1; 176 return SideIntersectionTable(new bool[tableBits], numTypes); 177 }