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.blockentity.utils;
7 
8 import voxelman.log;
9 import voxelman.container.buffer;
10 import voxelman.math;
11 import voxelman.geometry;
12 
13 import voxelman.world.block;
14 import voxelman.core.config;
15 import voxelman.core.events;
16 import voxelman.world.storage;
17 import voxelman.world.mesh.chunkmesh;
18 
19 import voxelman.world.blockentity;
20 
21 enum BLOCK_ENTITY_FLAG = 1 << 15;
22 enum BLOCK_INDEX_MASK = (1 << 15) - 1;
23 
24 pragma(inline, true)
25 bool isBlockEntity(BlockId blockId)
26 {
27 	enum n = BlockId.sizeof*8 - 1;
28 	return blockId >> n; // highest bit
29 }
30 
31 ushort blockEntityIndexFromBlockId(BlockId blockId) {
32 	return blockId & BLOCK_INDEX_MASK;
33 }
34 
35 BlockId blockIdFromBlockEntityIndex(ushort blockIndex) {
36 	return blockIndex | BLOCK_ENTITY_FLAG;
37 }
38 
39 struct BlockEntityMeshingData
40 {
41 	Buffer!MeshVertex[] output;
42 	ubyte[4] delegate(ushort blockIndex, CubeSide side) occlusionHandler;
43 	ubvec3 color;
44 	ubyte sides;
45 	ivec3 chunkPos;
46 	ivec3 entityPos;
47 	BlockEntityData data;
48 	ushort blockIndex;
49 }
50 
51 struct BlockEntityDebugContext
52 {
53 	import voxelman.graphics.plugin;
54 	BlockWorldPos bwp;
55 	BlockEntityData data;
56 	GraphicsPlugin graphics;
57 }
58 
59 alias BlockEntityMeshhandler = void function(BlockEntityMeshingData);
60 
61 alias SolidityHandler = Solidity function(CubeSide side, ivec3 chunkPos, ivec3 entityPos, BlockEntityData data);
62 alias BlockShapeHandler = BlockShape function(ivec3 chunkPos, ivec3 entityPos, BlockEntityData data);
63 alias EntityBoxHandler = WorldBox function(BlockWorldPos bwp, BlockEntityData data);
64 alias EntityDebugHandler = void function(ref BlockEntityDebugContext);
65 WorldBox nullBoxHandler(BlockWorldPos bwp, BlockEntityData data)
66 {
67 	return WorldBox(bwp.xyz, ivec3(1,1,1), cast(ushort)bwp.w);
68 }
69 
70 void nullBlockEntityMeshhandler(BlockEntityMeshingData) {}
71 
72 Solidity nullSolidityHandler(CubeSide side, ivec3 chunkPos, ivec3 entityPos, BlockEntityData data) {
73 	return Solidity.solid;
74 }
75 
76 BlockShape nullBlockShapeHandler(ivec3 chunkPos, ivec3 entityPos, BlockEntityData data) {
77 	return fullShape;
78 }
79 
80 struct BlockEntityInfo
81 {
82 	string name;
83 	BlockEntityMeshhandler meshHandler = &nullBlockEntityMeshhandler;
84 	SolidityHandler sideSolidity = &nullSolidityHandler;
85 	BlockShapeHandler blockShape = &nullBlockShapeHandler;
86 	EntityBoxHandler boxHandler = &nullBoxHandler;
87 	EntityDebugHandler debugHandler;
88 	ubvec3 color;
89 	//bool isVisible = true;
90 	size_t id;
91 }
92 BlockEntityInfo unknownBlockEntity = BlockEntityInfo("Unknown");
93 
94 struct BlockEntityInfoTable
95 {
96 	immutable(BlockEntityInfo)[] blockEntityInfos;
97 	size_t length() {return blockEntityInfos.length; }
98 	BlockEntityInfo opIndex(ushort blockEntityId) {
99 		blockEntityId = blockEntityId;
100 		if (blockEntityId >= blockEntityInfos.length)
101 			return unknownBlockEntity;
102 		return blockEntityInfos[blockEntityId];
103 	}
104 }