OpenGothic
Open source reimplementation of Gothic I and II
Loading...
Searching...
No Matches
packedmesh.h
Go to the documentation of this file.
1#pragma once
2
3#include <zenkit/Mesh.hh>
4#include <zenkit/MultiResolutionMesh.hh>
5#include <zenkit/SoftSkinMesh.hh>
6#include <zenkit/Material.hh>
7
8#include <Tempest/Vec>
9#include <utility>
10
11#include "resources.h"
12
13class Bounds;
14
16 public:
19
20 enum {
21 MaxVert = 64,
22 MaxPrim = 64,
25 };
26
33
34 struct SubMesh final {
35 zenkit::Material material;
36 size_t iboOffset = 0;
37 size_t iboLength = 0;
38 };
39
40 struct Cluster final {
41 Tempest::Vec3 pos;
42 float r = 0;
43 };
44
45 enum BVH_NodeType : uint32_t {
46 BVH_NullNode = 0x00000000,
47 BVH_BoxNode = 0x10000000,
48 BVH_Tri1Node = 0x20000000,
49 BVH_Tri2Node = 0x30000000,
50 };
51
52 struct BVHNode {
53 // Alternative 64-byte BVH node layout, which specifies the bounds of
54 // the children rather than the node itself. This layout is used by
55 // Aila and Laine in their seminal GPU ray tracing paper.
56 Tempest::Vec3 lmin; uint32_t left;
57 Tempest::Vec3 lmax; uint32_t right;
58 Tempest::Vec3 rmin; uint32_t padd0;
59 Tempest::Vec3 rmax; uint32_t padd1;
60 };
61
62 struct Leaf64 {
63 Tempest::Vec3 bbmin; uint32_t ptr;
64 Tempest::Vec3 bbmax; uint32_t padd0;
65 };
66 using UVec4 = Tempest::BasicPoint<uint32_t,4>;
67
68 std::vector<Vertex> vertices;
69 std::vector<VertexA> verticesA;
70 std::vector<uint32_t> indices;
71 std::vector<uint8_t> indices8;
72
73 std::vector<SubMesh> subMeshes;
74 std::vector<Cluster> meshletBounds;
75
76 std::vector<uint32_t> verticesId; // only for morph meshes
77 bool isUsingAlphaTest = true;
78
79 // sw-raytracing
80 std::vector<BVHNode> bvhNodes;
81 std::vector<UVec4> bvh8Nodes;
82
83 PackedMesh(const zenkit::MultiResolutionMesh& mesh, PkgType type);
84 PackedMesh(const zenkit::Mesh& mesh, PkgType type);
85 PackedMesh(const zenkit::SoftSkinMesh& mesh);
86
87 void debug(std::ostream &out) const;
88
89 std::pair<Tempest::Vec3,Tempest::Vec3> bbox() const;
90
91 private:
92 Tempest::Vec3 mBbox[2];
93
94 struct Prim {
95 uint32_t primId = 0;
96 uint32_t mat = 0;
97 };
98
99 struct SkeletalData {
100 Tempest::Vec3 localPositions[4] = {};
101 uint8_t boneIndices[4] = {};
102 float weights[4] = {};
103 };
104
105 using Vert = std::pair<uint32_t,uint32_t>;
106 struct PrimitiveHeap;
107 struct Meshlet {
108 Vert vert [MaxVert] = {};
109 uint8_t indexes[MaxInd ] = {};
110 uint8_t vertSz = 0;
111 uint8_t indSz = 0;
112 Cluster bounds;
113
114 void flush(std::vector<Vertex>& vertices,
115 std::vector<uint32_t>& indices, std::vector<uint8_t>& indices8,
116 std::vector<Cluster>& instances, const zenkit::Mesh& mesh);
117
118 void flush(std::vector<Vertex>& vertices, std::vector<VertexA>& verticesA,
119 std::vector<uint32_t>& indices, std::vector<uint8_t>& indices8,
120 std::vector<uint32_t>* verticesId, const std::vector<zenkit::Vec3>& vbo,
121 const std::vector<zenkit::MeshWedge>& wedgeList,
122 const std::vector<SkeletalData>* skeletal);
123 bool validate() const;
124
125 bool insert(const Vert& a, const Vert& b, const Vert& c);
126 void clear();
127 void updateBounds(const zenkit::Mesh& mesh);
128 void updateBounds(const zenkit::MultiResolutionMesh& mesh);
129 void updateBounds(const std::vector<zenkit::Vec3>& vbo);
130 bool canMerge(const Meshlet& other) const;
131 bool hasIntersection(const Meshlet& other) const;
132 float qDistance(const Meshlet& other) const;
133 void merge(const Meshlet& other);
134 };
135
136 struct HalfEdge {
137 float sah = 0;
138 uint32_t iMax = 0;
139 uint32_t iMin = 0;
140 uint32_t prim = 0;
141 bool wnd = false;
142 };
143
144 struct Fragment {
145 Tempest::Vec3 centroid;
146 Tempest::Vec3 bbmin, bbmax;
147
148 uint32_t ibo[4] = {};
149 uint32_t prim0 = 0;
150 uint32_t prim1 = 0xFFFFFFFF;
151 };
152
153 struct Block {
154 Tempest::Vec3 bbmin;
155 Tempest::Vec3 bbmax;
156 Fragment* frag = nullptr;
157 size_t size = 0;
158 };
159
160 struct CWBVH8 {
161 float p[3];
162 uint8_t e[3], imask;
163
164 uint32_t pNodes = 0;
165 uint32_t pPrimitives = 0;
166 uint8_t meta [8] = {};
167
168 uint8_t qmin_x[8] = {};
169 uint8_t qmax_x[8] = {};
170 uint8_t qmin_y[8] = {};
171 uint8_t qmax_y[8] = {};
172 uint8_t qmin_z[8] = {};
173 uint8_t qmax_z[8] = {};
174 };
175 static_assert(sizeof(CWBVH8)==80);
176
177 bool addTriangle(Meshlet& dest, const zenkit::Mesh* mesh, const zenkit::SubMesh* proto_mesh, size_t id);
178
179 void packPhysics(const zenkit::Mesh& mesh, PkgType type);
180
181 // bvh common
182 static void quadAddPrim(Fragment& f, const zenkit::Mesh& shp, uint32_t prim0, uint32_t prim1, uint32_t iMin, uint32_t iMax);
183 static auto packQuads(const zenkit::Mesh& mesh) -> std::vector<PackedMesh::Fragment>;
184
185 static auto findNodeSplit(const Fragment* frag, size_t size, const bool useSah) -> std::pair<uint32_t, float>;
186 static auto findNodeSplitSah(Fragment* frag, size_t size) -> std::pair<uint32_t, bool>;
187 static void packBlocks(Block* out, uint32_t& outSz, uint8_t destSz, Fragment* frag, size_t size);
188 static void computeBbox(Tempest::Vec3& bbmin, Tempest::Vec3& bbmax, const Fragment* frag, size_t size);
189 void packBVH(const zenkit::Mesh& mesh);
190
191 // bvh2
192 void packBVH2(const zenkit::Mesh& mesh);
193 uint32_t packBVH2(const zenkit::Mesh& mesh, std::vector<BVHNode>& nodes, Fragment* frag, size_t size, size_t parentSz);
194
195 // cwbvh8
196 void packCWBVH8(const zenkit::Mesh& mesh);
197 CWBVH8 packCWBVH8(const zenkit::Mesh& mesh, std::vector<UVec4>& nodes, Fragment* frag, size_t size);
198
199 CWBVH8 packCWBVH8(const zenkit::Mesh& mesh, std::vector<UVec4>& nodes,
200 const std::vector<uint32_t>& ibo, Fragment* frag, size_t size);
201 void packCW8Blocks(Block* out, uint32_t& outSz, const zenkit::Mesh& mesh, std::vector<UVec4>& nodes,
202 Fragment* frag, size_t size, uint8_t depth);
203 CWBVH8 nodeFromBlocks(Block* block);
204 void orderBlocks(Block* block, const uint32_t numBlocks, const Tempest::Vec3 bbmin, const Tempest::Vec3 bbmax);
205
206 //
207 void packMeshletsLnd(const zenkit::Mesh& mesh);
208 void packMeshletsObj(const zenkit::MultiResolutionMesh& mesh, PkgType type,
209 const std::vector<SkeletalData>* skeletal);
210
211 std::vector<Meshlet> buildMeshlets(const zenkit::Mesh* mesh, const zenkit::SubMesh* proto_mesh,
212 PrimitiveHeap& heap, std::vector<bool>& used);
213
214 void computeBbox();
215
216 void dbgUtilization(const std::vector<Meshlet>& meshlets);
217 void dbgMeshlets(const zenkit::Mesh& mesh, const std::vector<Meshlet*>& meshlets);
218 };
219
std::vector< UVec4 > bvh8Nodes
Definition packedmesh.h:81
std::vector< BVHNode > bvhNodes
Definition packedmesh.h:80
std::pair< Tempest::Vec3, Tempest::Vec3 > bbox() const
std::vector< Cluster > meshletBounds
Definition packedmesh.h:74
Tempest::BasicPoint< uint32_t, 4 > UVec4
Definition packedmesh.h:66
std::vector< SubMesh > subMeshes
Definition packedmesh.h:73
void debug(std::ostream &out) const
std::vector< uint32_t > indices
Definition packedmesh.h:70
std::vector< VertexA > verticesA
Definition packedmesh.h:69
std::vector< uint8_t > indices8
Definition packedmesh.h:71
std::vector< uint32_t > verticesId
Definition packedmesh.h:76
std::vector< Vertex > vertices
Definition packedmesh.h:68
bool isUsingAlphaTest
Definition packedmesh.h:77
Tempest::Vec3 rmax
Definition packedmesh.h:59
Tempest::Vec3 lmin
Definition packedmesh.h:56
Tempest::Vec3 lmax
Definition packedmesh.h:57
Tempest::Vec3 rmin
Definition packedmesh.h:58
Tempest::Vec3 pos
Definition packedmesh.h:41
Tempest::Vec3 bbmax
Definition packedmesh.h:64
Tempest::Vec3 bbmin
Definition packedmesh.h:63
zenkit::Material material
Definition packedmesh.h:35