载入中...
搜索中...
未找到
CubeTypeRegistry.cpp
浏览该文件的文档.
2
3#include "common/Json.h"
4
5#include <cstring>
6
7namespace eve::voxel {
8
9namespace {
10
12
13const CubeTypeRegistry &kEmptyRegistry() {
14 static const CubeTypeRegistry reg;
15 return reg;
16}
17
18// 把某体素在面 dir 上应显示的纹理,从“基础类型 faceTex + orientation”旋转出来。
19// faceTex_variant[dir] = faceTex_base[rotateFaceY(dir, -orientation)]。
20void rotateFaceTex(const uint8_t src[6], int orientation, uint8_t dst[6]) {
21 for (int d = 0; d < 6; ++d) {
22 const FaceDir srcDir = rotateFaceY(FaceDir(d), (4 - (orientation & 3)) & 3);
23 dst[d] = src[int(srcDir)];
24 }
25}
26
27void readFaceTex(Value o, uint8_t out[6]) {
28 std::memset(out, 0, sizeof(uint8_t) * 6);
29 const Value arr = o.get("faceTex");
30 const size_t n = arr.size() < 6 ? arr.size() : 6;
31 for (size_t i = 0; i < n; ++i) out[i] = uint8_t(arr.at(i).asInt(0) & 0xFF);
32}
33
34CubeType parseCubeType(Value o) {
35 CubeType t;
36 if (!o.isObject()) return t;
37 t.name = o.getString("name");
38 readFaceTex(o, t.faceTex);
39 t.directional = o.getBool("directional", false);
40 t.composeGroup = o.getString("composeGroup");
41 t.connects = o.getBool("connects", false);
42 return t;
43}
44
45} // namespace
46
47const CubeTypeRegistry &CubeTypeRegistry::empty() { return kEmptyRegistry(); }
48
50 if (type.name.empty()) return 0;
51 auto it = byName_.find(type.name);
52 if (it != byName_.end()) return it->second;
53
54 const int variants = type.directional ? 4 : 1;
55 // 上限:id 为 uint8_t,0 保留给空气,最多 255 个类型槽位。
56 if (int(types_.size()) + variants > 256) return 0;
57
58 const uint8_t baseId = uint8_t(types_.size());
59 for (int o = 0; o < variants; ++o) {
60 CubeType v = type;
61 v.id = uint8_t(baseId + o);
62 if (type.directional && o > 0) {
63 rotateFaceTex(type.faceTex, o, v.faceTex);
64 }
65 types_.push_back(v);
66 }
67 byName_[type.name] = baseId;
68 return baseId;
69}
70
71int CubeTypeRegistry::loadFromJson(const std::string &json, std::string *error) {
72 std::string err;
73 const eve::json::Document doc = eve::json::Document::parse(json, &err);
74 if (!doc.valid()) {
75 if (error) *error = err.empty() ? "invalid json" : err;
76 return 0;
77 }
78
79 const Value root = doc.root();
80 int n = 0;
81 if (root.isArray()) {
82 for (size_t i = 0; i < root.size(); ++i) {
83 CubeType t = parseCubeType(root.at(i));
84 if (t.name.empty()) continue;
85 add(t);
86 ++n;
87 }
88 } else if (root.isObject()) {
89 CubeType t = parseCubeType(root);
90 if (!t.name.empty()) {
91 add(t);
92 ++n;
93 }
94 }
95 return n;
96}
97
98const CubeType *CubeTypeRegistry::find(const std::string &name) const {
99 auto it = byName_.find(name);
100 if (it == byName_.end()) return nullptr;
101 return &types_[it->second];
102}
103
104const CubeType *CubeTypeRegistry::find(uint8_t id) const {
105 if (id == 0 || size_t(id) >= types_.size()) return nullptr;
106 return &types_[id];
107}
108
109uint8_t CubeTypeRegistry::variantId(const std::string &name, int orientation) const {
110 auto it = byName_.find(name);
111 if (it == byName_.end()) return 0;
112 const CubeType &base = types_[it->second];
113 if (!base.directional) return base.id;
114 return uint8_t(base.id + (orientation & 3));
115}
116
118 byName_.clear();
119 types_.clear();
120 types_.push_back(CubeType{}); // index 0 = 空气占位
121}
122
123} // namespace eve::voxel
std::string type
std::string id
glm::vec3 n
Definition Grass.cpp:64
std::string error
const char * name
Definition RockMesh.cpp:21
int d
int v
bool valid() const
Definition Json.h:111
static Document parse(const std::string &text, std::string *error=nullptr)
Definition Json.cpp:449
Value root() const
Definition Json.h:112
const CubeType * find(const std::string &name) const
按名字返回 0 度变体;未找到返回 nullptr。
static const CubeTypeRegistry & empty()
进程级空注册表(默认参数与向后兼容回退用)。
uint8_t add(const CubeType &type)
注册一个方块类型,返回其基础类型 id(0 保留给空气)。 方向性方块会按 orientation ∈ {0,1,2,3} 绕 Y 轴旋转 faceTex, 展开成 4 个连续的具体类型变体;基础 id...
int loadFromJson(const std::string &json, std::string *error=nullptr)
从 JSON 数组或单对象批量注册,返回成功数量。 元素形如: { "name": "furnace", "faceTex": [4, 4, 4, 4, 5, 4],...
uint8_t variantId(const std::string &name, int orientation) const
名字 + orientation(0..3) 对应的具体类型 id;非方向性类型忽略 orientation。
std::variant< std::monostate, std::int64_t, double, std::string, bool > Value
Definition Database.h:24
方块类型定义:名字、各面图集纹理、方向性、组合声明。 方向性方块在注册时按 orientation 绕 Y 轴展开成多个"具体类型"变体, 每个变体持有旋转后的各面纹理;渲染端只消费纹理 id,不接触 ...
Definition Chunk.h:12
FaceDir rotateFaceY(FaceDir dir, int quarterTurns)
绕 Y 轴旋转一个面方向 quarterTurns 个 90°(右手定则:+X → -Z → -X → +Z)。 仅影响 4 个水平面(±X/±Z),±Y 顶/底保持不变。 供方向性方块在注册各面纹理时...
Definition FaceDir.h:74
FaceDir
Six axis-aligned face directions. Each chunk keeps a separate instance buffer per direction so camera...
Definition FaceDir.h:17
uint8_t id
0 保留为空气;1..255 类型索引(含方向变体)。
Definition CubeType.h:17
bool directional
是否可绕 Y 轴旋转。
Definition CubeType.h:21
std::string name
Definition CubeType.h:15