-
Notifications
You must be signed in to change notification settings - Fork 2
/
cadscene.hpp
234 lines (189 loc) · 5.07 KB
/
cadscene.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/*
* Copyright (c) 2014-2024, NVIDIA CORPORATION. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-FileCopyrightText: Copyright (c) 2014-2024 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef CADSCENE_H__
#define CADSCENE_H__
#include <cstring> // memset
#include <glm/glm.hpp>
#include <vector>
#include <cstdint>
class CadScene
{
public:
struct BBox
{
glm::vec4 min;
glm::vec4 max;
BBox()
: min(FLT_MAX)
, max(-FLT_MAX)
{
}
inline void merge(const glm::vec4& point)
{
min = glm::min(min, point);
max = glm::max(max, point);
}
inline void merge(const BBox& bbox)
{
min = glm::min(min, bbox.min);
max = glm::max(max, bbox.max);
}
inline BBox transformed(const glm::mat4& matrix, int dim = 3)
{
int i;
glm::vec4 box[16];
// create box corners
box[0] = glm::vec4(min.x, min.y, min.z, min.w);
box[1] = glm::vec4(max.x, min.y, min.z, min.w);
box[2] = glm::vec4(min.x, max.y, min.z, min.w);
box[3] = glm::vec4(max.x, max.y, min.z, min.w);
box[4] = glm::vec4(min.x, min.y, max.z, min.w);
box[5] = glm::vec4(max.x, min.y, max.z, min.w);
box[6] = glm::vec4(min.x, max.y, max.z, min.w);
box[7] = glm::vec4(max.x, max.y, max.z, min.w);
box[8] = glm::vec4(min.x, min.y, min.z, max.w);
box[9] = glm::vec4(max.x, min.y, min.z, max.w);
box[10] = glm::vec4(min.x, max.y, min.z, max.w);
box[11] = glm::vec4(max.x, max.y, min.z, max.w);
box[12] = glm::vec4(min.x, min.y, max.z, max.w);
box[13] = glm::vec4(max.x, min.y, max.z, max.w);
box[14] = glm::vec4(min.x, max.y, max.z, max.w);
box[15] = glm::vec4(max.x, max.y, max.z, max.w);
// transform box corners
// and find new mins,maxs
BBox bbox;
for(i = 0; i < (1 << dim); i++)
{
glm::vec4 point = matrix * box[i];
bbox.merge(point);
}
return bbox;
}
};
struct MaterialSide
{
glm::vec4 ambient;
glm::vec4 diffuse;
glm::vec4 specular;
glm::vec4 emissive;
};
// need to keep this 256 byte aligned (UBO range)
struct Material
{
MaterialSide sides[2];
unsigned int _pad[32];
Material() { memset(this, 0, sizeof(Material)); }
};
// need to keep this 256 byte aligned (UBO range)
struct MatrixNode
{
glm::mat4 worldMatrix;
glm::mat4 worldMatrixIT;
glm::mat4 objectMatrix;
glm::mat4 objectMatrixIT;
};
struct Vertex
{
glm::vec3 position;
uint16_t normalOctX;
uint16_t normalOctY;
};
struct DrawRange
{
size_t offset;
int count;
DrawRange()
: offset(0)
, count(0)
{
}
};
struct DrawStateInfo
{
int materialIndex;
int matrixIndex;
friend bool operator!=(const DrawStateInfo& lhs, const DrawStateInfo& rhs)
{
return lhs.materialIndex != rhs.materialIndex || lhs.matrixIndex != rhs.matrixIndex;
}
friend bool operator==(const DrawStateInfo& lhs, const DrawStateInfo& rhs)
{
return lhs.materialIndex == rhs.materialIndex && lhs.matrixIndex == rhs.matrixIndex;
}
};
struct DrawRangeCache
{
std::vector<DrawStateInfo> state;
std::vector<int> stateCount;
std::vector<size_t> offsets;
std::vector<int> counts;
};
struct GeometryPart
{
DrawRange indexSolid;
DrawRange indexWire;
};
struct Geometry
{
int cloneIdx;
size_t vboSize;
size_t iboSize;
Vertex* vboData;
unsigned int* iboData;
std::vector<GeometryPart> parts;
int numVertices;
int numIndexSolid;
int numIndexWire;
};
struct ObjectPart
{
int active;
int materialIndex;
int matrixIndex;
};
struct Object
{
int matrixIndex;
int geometryIndex;
std::vector<ObjectPart> parts;
DrawRangeCache cacheSolid;
DrawRangeCache cacheWire;
};
std::vector<Material> m_materials;
std::vector<BBox> m_geometryBboxes;
std::vector<Geometry> m_geometry;
std::vector<MatrixNode> m_matrices;
std::vector<Object> m_objects;
BBox m_bbox;
void updateObjectDrawCache(Object& object);
bool loadCSF(const char* filename, int clones = 0, int cloneaxis = 3);
void unload();
struct IndexingBits
{
uint32_t matrices = 0;
uint32_t materials = 0;
uint32_t packIndices(uint32_t matrixIndex, uint32_t materialIndex) const
{
return matrixIndex | (materialIndex << matrices);
}
};
IndexingBits getIndexingBits() const;
bool supportsIndexing() const;
};
#endif