载入中...
搜索中...
未找到
ArchSpaceTypes.h
浏览该文件的文档.
1#pragma once
2
3#include "common/Result.h"
4
5#include <cmath>
6#include <cstdint>
7#include <string>
8#include <vector>
9
10namespace eve::archspace {
11
13enum class NodeKind : std::uint8_t { Site = 0, Building, Level, Wall, Slab, Zone, Item, Opening };
14
16enum class OpeningKind : std::uint8_t { Door = 0, Window };
17
19struct Vec2 {
20 double x = 0.0;
21 double z = 0.0;
22};
23
25struct Vec3 {
26 double x = 0.0;
27 double y = 0.0;
28 double z = 0.0;
29};
30
32struct Node {
33 std::string id;
35 std::string parentId;
36 std::string name;
37 std::vector<std::string> children;
38
39 // level
40 double elevation = 0.0;
41 double height = 3.0;
42
43 // wall
46 double thickness = 0.2;
47
48 // slab / zone
49 std::vector<Vec2> polygon;
50 double slabThickness = 0.2;
51
52 // item
54 double yawDegrees = 0.0;
55 std::string catalogId;
56
57 // opening
59 double t = 0.5;
60 double width = 0.9;
61 double openingHeight = 2.1;
62 double sill = 0.0;
63};
64
66struct MeshBake {
67 std::vector<Vec3> positions;
68 std::vector<std::uint32_t> indices;
69 std::vector<std::string> primitiveIds;
70};
71
77struct MeshArrays {
78 std::vector<float> positions;
79 std::vector<float> normals;
80 std::vector<float> uvs;
81 std::vector<std::uint32_t> indices;
82
84 [[nodiscard]] int vertexCount() const noexcept {
85 return static_cast<int>(positions.size() / 3);
86 }
88 [[nodiscard]] int indexCount() const noexcept { return static_cast<int>(indices.size()); }
90 [[nodiscard]] int triangleCount() const noexcept { return indexCount() / 3; }
91};
92
94[[nodiscard]] inline MeshArrays toMeshArrays(const MeshBake& bake) {
95 MeshArrays out;
96 out.positions.reserve(bake.positions.size() * 3);
97 out.normals.reserve(bake.positions.size() * 3);
98 out.uvs.reserve(bake.positions.size() * 2);
99 out.indices = bake.indices;
100 for (const Vec3& p : bake.positions) {
101 out.positions.push_back(static_cast<float>(p.x));
102 out.positions.push_back(static_cast<float>(p.y));
103 out.positions.push_back(static_cast<float>(p.z));
104 out.normals.push_back(0.f);
105 out.normals.push_back(1.f);
106 out.normals.push_back(0.f);
107 out.uvs.push_back(static_cast<float>(p.x));
108 out.uvs.push_back(static_cast<float>(p.z));
109 }
110 for (std::size_t i = 0; i + 2 < bake.indices.size(); i += 3) {
111 const std::uint32_t i0 = bake.indices[i], i1 = bake.indices[i + 1], i2 = bake.indices[i + 2];
112 if (i0 >= bake.positions.size() || i1 >= bake.positions.size() || i2 >= bake.positions.size()) continue;
113 const Vec3& a = bake.positions[i0];
114 const Vec3& b = bake.positions[i1];
115 const Vec3& c = bake.positions[i2];
116 Vec3 n{ (b.y - a.y) * (c.z - a.z) - (b.z - a.z) * (c.y - a.y),
117 (b.z - a.z) * (c.x - a.x) - (b.x - a.x) * (c.z - a.z),
118 (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x) };
119 const double len = std::sqrt(n.x * n.x + n.y * n.y + n.z * n.z);
120 if (len > 1e-8) {
121 n.x /= len;
122 n.y /= len;
123 n.z /= len;
124 } else {
125 n = {0, 1, 0};
126 }
127 for (std::uint32_t idx : {i0, i1, i2}) {
128 out.normals[idx * 3 + 0] = static_cast<float>(n.x);
129 out.normals[idx * 3 + 1] = static_cast<float>(n.y);
130 out.normals[idx * 3 + 2] = static_cast<float>(n.z);
131 }
132 }
133 return out;
134}
135
141[[nodiscard]] inline const char* nodeKindName(NodeKind kind) noexcept {
142 switch (kind) {
143 case NodeKind::Site: return "site";
144 case NodeKind::Building: return "building";
145 case NodeKind::Level: return "level";
146 case NodeKind::Wall: return "wall";
147 case NodeKind::Slab: return "slab";
148 case NodeKind::Zone: return "zone";
149 case NodeKind::Item: return "item";
150 case NodeKind::Opening: return "opening";
151 }
152 return "site";
153}
154
159[[nodiscard]] inline eve::Result<NodeKind> parseNodeKind(const std::string& text) noexcept {
161 if (text == "building") return eve::Result<NodeKind>::success(NodeKind::Building);
167 if (text == "opening") return eve::Result<NodeKind>::success(NodeKind::Opening);
170 eve::DiagnosticCode::InvalidArgument, "unknown ArchSpace node kind", "kind", {}, "archspace.kind"));
171}
172
178[[nodiscard]] inline const char* openingKindName(OpeningKind kind) noexcept {
179 return kind == OpeningKind::Window ? "window" : "door";
180}
181
186[[nodiscard]] inline eve::Result<OpeningKind> parseOpeningKind(const std::string& text) noexcept {
191 "unknown ArchSpace opening kind", "openingKind", {},
192 "archspace.opening"));
193}
194
195} // namespace eve::archspace
glm::vec4 p[6]
uint32_t i1
Definition Grass.cpp:61
uint32_t i2
Definition Grass.cpp:61
uint32_t i0
Definition Grass.cpp:61
glm::vec3 n
Definition Grass.cpp:63
std::int32_t c
std::string text
TokenKind kind
MeleePoint3 b
Definition MeleeHit.cpp:41
MeleePoint3 a
Definition MeleeHit.cpp:40
int idx
Move-only, checked operation results for the common layer.
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
MeshArrays toMeshArrays(const MeshBake &bake)
Convert a MeshBake into flat arrays with per-triangle normals.
OpeningKind
Opening semantic used by doors and windows hosted on walls.
eve::Result< NodeKind > parseNodeKind(const std::string &text) noexcept
Parse a node kind wire name.
NodeKind
Stable node kind discriminator for the architectural document.
const char * openingKindName(OpeningKind kind) noexcept
Stable wire name for an opening kind. @ownership Non-owning pointer to a static string literal; do no...
const char * nodeKindName(NodeKind kind) noexcept
Stable wire name for a node kind. @ownership Non-owning pointer to a static string literal; do not fr...
eve::Result< OpeningKind > parseOpeningKind(const std::string &text) noexcept
Parse an opening kind wire name.
Interleaved GPU-upload arrays derived from MeshBake.
std::vector< float > normals
std::vector< std::uint32_t > indices
std::vector< float > positions
std::vector< float > uvs
int indexCount() const noexcept
Index count.
int triangleCount() const noexcept
Triangle count.
int vertexCount() const noexcept
Vertex count.
Renderer-neutral triangle mesh rebuilt from the document.
std::vector< std::uint32_t > indices
std::vector< std::string > primitiveIds
std::vector< Vec3 > positions
One authored architectural node. Only fields for the active kind are meaningful.
std::vector< std::string > children
std::vector< Vec2 > polygon
Metres on the level XZ plane.
Metres in world/level space.