Jolt Physics
A multi core friendly Game Physics Engine
Loading...
Searching...
No Matches
TriangleCodecIndexed8BitPackSOA4Flags.h
Go to the documentation of this file.
1// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
8
10
25{
26public:
28 {
29 public:
32 };
33
35 static constexpr int TriangleHeaderSize = sizeof(TriangleHeader);
36
38 static constexpr bool ChangesOffsetOnPack = false;
39
46
54
62
69
70 static_assert(sizeof(VertexData) == 8, "Compiler added padding");
71
74 {
77 };
78
79 static_assert(sizeof(TriangleBlock) == 16, "Compiler added padding");
80
90
93 {
94 const VertexData * GetVertexData() const { return reinterpret_cast<const VertexData *>(reinterpret_cast<const uint8 *>(this) + ((mFlags & OFFSET_TO_VERTICES_MASK) << OFFSET_NON_SIGNIFICANT_BITS)); }
95 const TriangleBlock * GetTriangleBlock() const { return reinterpret_cast<const TriangleBlock *>(reinterpret_cast<const uint8 *>(this) + sizeof(TriangleBlockHeader)); }
96 const uint32 * GetUserData() const { uint32 offset = mFlags >> OFFSET_TO_VERTICES_BITS; return offset == 0? nullptr : reinterpret_cast<const uint32 *>(GetTriangleBlock() + offset); }
97
99 };
100
101 static_assert(sizeof(TriangleBlockHeader) == 4, "Compiler added padding");
102
105 {
106 public:
108 ValidationContext(const IndexedTriangleList &inTriangles, const VertexList &inVertices) :
109 mVertices(inVertices)
110 {
111 // Only used the referenced triangles, just like EncodingContext::Finalize does
112 for (const IndexedTriangle &i : inTriangles)
113 for (uint32 idx : i.mIdx)
114 mBounds.Encapsulate(Vec3(inVertices[idx]));
115 }
116
118 bool IsDegenerate(const IndexedTriangle &inTriangle) const
119 {
120 // Quantize the triangle in the same way as EncodingContext::Finalize does
121 UVec4 quantized_vertex[3];
122 Vec3 compress_scale = Vec3::sReplicate(COMPONENT_MASK) / Vec3::sMax(mBounds.GetSize(), Vec3::sReplicate(1.0e-20f));
123 for (int i = 0; i < 3; ++i)
124 quantized_vertex[i] = ((Vec3(mVertices[inTriangle.mIdx[i]]) - mBounds.mMin) * compress_scale + Vec3::sReplicate(0.5f)).ToInt();
125 return quantized_vertex[0] == quantized_vertex[1] || quantized_vertex[1] == quantized_vertex[2] || quantized_vertex[0] == quantized_vertex[2];
126 }
127
128 private:
129 const VertexList & mVertices;
130 AABox mBounds;
131 };
132
135 {
136 public:
138 static constexpr uint32 cNotFound = 0xffffffff;
139
141 explicit EncodingContext(const VertexList &inVertices) :
142 mVertexMap(inVertices.size(), cNotFound)
143 {
144 }
145
147 void PreparePack(const IndexedTriangle *inTriangles, uint inNumTriangles, bool inStoreUserData, uint64 &ioBufferSize)
148 {
149 // Add triangle block header
150 ioBufferSize += sizeof(TriangleBlockHeader);
151
152 // Compute first vertex that this batch will use (ensuring there's enough room if none of the vertices are shared)
153 uint start_vertex = Clamp((int)mVertexCount - 256 + (int)inNumTriangles * 3, 0, (int)mVertexCount);
154
155 // Pack vertices
156 uint padded_triangle_count = AlignUp(inNumTriangles, 4);
157 for (uint t = 0; t < padded_triangle_count; t += 4)
158 {
159 // Add triangle block header
160 ioBufferSize += sizeof(TriangleBlock);
161
162 for (uint vertex_nr = 0; vertex_nr < 3; ++vertex_nr)
163 for (uint block_tri_idx = 0; block_tri_idx < 4; ++block_tri_idx)
164 {
165 // Fetch vertex index. Create degenerate triangles for padding triangles.
166 bool triangle_available = t + block_tri_idx < inNumTriangles;
167 uint32 src_vertex_index = triangle_available? inTriangles[t + block_tri_idx].mIdx[vertex_nr] : inTriangles[inNumTriangles - 1].mIdx[0];
168
169 // Check if we've seen this vertex before and if it is in the range that we can encode
170 uint32 &vertex_index = mVertexMap[src_vertex_index];
171 if (vertex_index == cNotFound || vertex_index < start_vertex)
172 {
173 // Add vertex
174 vertex_index = mVertexCount;
175 mVertexCount++;
176 }
177 }
178 }
179
180 // Add user data
181 if (inStoreUserData)
182 ioBufferSize += inNumTriangles * sizeof(uint32);
183 }
184
186 void FinalizePreparePack(uint64 &ioBufferSize)
187 {
188 // Remember where the vertices are going to start in the output buffer
189 JPH_ASSERT(IsAligned(ioBufferSize, 4));
190 mVerticesStartIdx = size_t(ioBufferSize);
191
192 // Add vertices to buffer
193 ioBufferSize += uint64(mVertexCount) * sizeof(VertexData);
194
195 // Reserve the amount of memory we need for the vertices
196 mVertices.reserve(mVertexCount);
197
198 // Set vertex map back to 'not found'
199 for (uint32 &v : mVertexMap)
200 v = cNotFound;
201 }
202
205 size_t Pack(const IndexedTriangle *inTriangles, uint inNumTriangles, bool inStoreUserData, ByteBuffer &ioBuffer, const char *&outError)
206 {
207 JPH_ASSERT(inNumTriangles > 0);
208
209 // Determine position of triangles start
210 size_t triangle_block_start = ioBuffer.size();
211
212 // Allocate triangle block header
214
215 // Compute first vertex that this batch will use (ensuring there's enough room if none of the vertices are shared)
216 uint start_vertex = Clamp((int)mVertices.size() - 256 + (int)inNumTriangles * 3, 0, (int)mVertices.size());
217
218 // Store the start vertex offset relative to TriangleBlockHeader
219 size_t offset_to_vertices = mVerticesStartIdx - triangle_block_start + size_t(start_vertex) * sizeof(VertexData);
220 if (offset_to_vertices & OFFSET_NON_SIGNIFICANT_MASK)
221 {
222 outError = "TriangleCodecIndexed8BitPackSOA4Flags: Internal Error: Offset has non-significant bits set";
223 return size_t(-1);
224 }
225 offset_to_vertices >>= OFFSET_NON_SIGNIFICANT_BITS;
226 if (offset_to_vertices > OFFSET_TO_VERTICES_MASK)
227 {
228 outError = "TriangleCodecIndexed8BitPackSOA4Flags: Offset to vertices doesn't fit. Too much data.";
229 return size_t(-1);
230 }
231 header->mFlags = uint32(offset_to_vertices);
232
233 // When we store user data we need to store the offset to the user data in TriangleBlocks
234 uint padded_triangle_count = AlignUp(inNumTriangles, 4);
235 if (inStoreUserData)
236 {
237 uint32 num_blocks = padded_triangle_count >> 2;
238 JPH_ASSERT(num_blocks <= OFFSET_TO_USERDATA_MASK);
239 header->mFlags |= num_blocks << OFFSET_TO_VERTICES_BITS;
240 }
241
242 // Pack vertices
243 for (uint t = 0; t < padded_triangle_count; t += 4)
244 {
245 TriangleBlock *block = ioBuffer.Allocate<TriangleBlock>();
246 for (uint vertex_nr = 0; vertex_nr < 3; ++vertex_nr)
247 for (uint block_tri_idx = 0; block_tri_idx < 4; ++block_tri_idx)
248 {
249 // Fetch vertex index. Create degenerate triangles for padding triangles.
250 bool triangle_available = t + block_tri_idx < inNumTriangles;
251 uint32 src_vertex_index = triangle_available? inTriangles[t + block_tri_idx].mIdx[vertex_nr] : inTriangles[inNumTriangles - 1].mIdx[0];
252
253 // Check if we've seen this vertex before and if it is in the range that we can encode
254 uint32 &vertex_index = mVertexMap[src_vertex_index];
255 if (vertex_index == cNotFound || vertex_index < start_vertex)
256 {
257 // Add vertex
258 vertex_index = (uint32)mVertices.size();
259 mVertices.push_back(src_vertex_index);
260 }
261
262 // Store vertex index
263 uint32 vertex_offset = vertex_index - start_vertex;
264 if (vertex_offset > 0xff)
265 {
266 outError = "TriangleCodecIndexed8BitPackSOA4Flags: Offset doesn't fit in 8 bit";
267 return size_t(-1);
268 }
269 block->mIndices[vertex_nr][block_tri_idx] = (uint8)vertex_offset;
270
271 // Store flags
272 uint32 flags = triangle_available? inTriangles[t + block_tri_idx].mMaterialIndex : 0;
273 if (flags > 0xff)
274 {
275 outError = "TriangleCodecIndexed8BitPackSOA4Flags: Material index doesn't fit in 8 bit";
276 return size_t(-1);
277 }
278 block->mFlags[block_tri_idx] = (uint8)flags;
279 }
280 }
281
282 // Store user data
283 if (inStoreUserData)
284 {
285 uint32 *user_data = ioBuffer.Allocate<uint32>(inNumTriangles);
286 for (uint t = 0; t < inNumTriangles; ++t)
287 user_data[t] = inTriangles[t].mUserData;
288 }
289
290 return triangle_block_start;
291 }
292
294 void Finalize(const VertexList &inVertices, TriangleHeader *ioHeader, ByteBuffer &ioBuffer) const
295 {
296 // Assert that our reservations were correct
297 JPH_ASSERT(mVertices.size() == mVertexCount);
298 JPH_ASSERT(ioBuffer.size() == mVerticesStartIdx);
299
300 // Check if anything to do
301 if (mVertices.empty())
302 return;
303
304 // Calculate bounding box
305 AABox bounds;
306 for (uint32 v : mVertices)
307 bounds.Encapsulate(Vec3(inVertices[v]));
308
309 // Compress vertices
310 VertexData *vertices = ioBuffer.Allocate<VertexData>(mVertices.size());
311 Vec3 compress_scale = Vec3::sReplicate(COMPONENT_MASK) / Vec3::sMax(bounds.GetSize(), Vec3::sReplicate(1.0e-20f));
312 for (uint32 v : mVertices)
313 {
314 UVec4 c = ((Vec3(inVertices[v]) - bounds.mMin) * compress_scale + Vec3::sReplicate(0.5f)).ToInt();
318 vertices->mVertexXY = c.GetX() + (c.GetY() << COMPONENT_Y1);
319 vertices->mVertexZY = c.GetZ() + ((c.GetY() >> COMPONENT_Y1_BITS) << COMPONENT_Y2);
320 ++vertices;
321 }
322
323 // Store decompression information
324 bounds.mMin.StoreFloat3(&ioHeader->mOffset);
325 (bounds.GetSize() / Vec3::sReplicate(COMPONENT_MASK)).StoreFloat3(&ioHeader->mScale);
326 }
327
328 private:
329 using VertexMap = Array<uint32>;
330
331 uint32 mVertexCount = 0;
332 size_t mVerticesStartIdx = 0;
333 Array<uint32> mVertices;
334 VertexMap mVertexMap;
335 };
336
339 {
340 private:
342 JPH_INLINE void Unpack(const VertexData *inVertices, UVec4Arg inIndex, Vec4 &outX, Vec4 &outY, Vec4 &outZ) const
343 {
344 // Get compressed data
345 UVec4 c1 = UVec4::sGatherInt4<8>(&inVertices->mVertexXY, inIndex);
346 UVec4 c2 = UVec4::sGatherInt4<8>(&inVertices->mVertexZY, inIndex);
347
348 // Unpack the x y and z component
352
353 // Convert to float
354 outX = Vec4::sFusedMultiplyAdd(xc.ToFloat(), mScaleX, mOffsetX);
355 outY = Vec4::sFusedMultiplyAdd(yc.ToFloat(), mScaleY, mOffsetY);
356 outZ = Vec4::sFusedMultiplyAdd(zc.ToFloat(), mScaleZ, mOffsetZ);
357 }
358
360 JPH_INLINE void Unpack(const TriangleBlock *inBlock, const VertexData *inVertices, Vec4 &outX1, Vec4 &outY1, Vec4 &outZ1, Vec4 &outX2, Vec4 &outY2, Vec4 &outZ2, Vec4 &outX3, Vec4 &outY3, Vec4 &outZ3) const
361 {
362 // Get the indices for the three vertices (reads 4 bytes extra, but these are the flags so that's ok)
363 UVec4 indices = UVec4::sLoadInt4(reinterpret_cast<const uint32 *>(&inBlock->mIndices[0]));
364 UVec4 iv1 = indices.Expand4Byte0();
365 UVec4 iv2 = indices.Expand4Byte4();
366 UVec4 iv3 = indices.Expand4Byte8();
367
368 #ifdef JPH_CPU_BIG_ENDIAN
369 // On big endian systems we need to reverse the bytes
373 #endif
374
375 // Decompress the triangle data
376 Unpack(inVertices, iv1, outX1, outY1, outZ1);
377 Unpack(inVertices, iv2, outX2, outY2, outZ2);
378 Unpack(inVertices, iv3, outX3, outY3, outZ3);
379 }
380
381 public:
382 JPH_INLINE explicit DecodingContext(const TriangleHeader *inHeader) :
383 mOffsetX(Vec4::sReplicate(inHeader->mOffset.x)),
384 mOffsetY(Vec4::sReplicate(inHeader->mOffset.y)),
385 mOffsetZ(Vec4::sReplicate(inHeader->mOffset.z)),
386 mScaleX(Vec4::sReplicate(inHeader->mScale.x)),
387 mScaleY(Vec4::sReplicate(inHeader->mScale.y)),
388 mScaleZ(Vec4::sReplicate(inHeader->mScale.z))
389 {
390 }
391
393 JPH_INLINE void Unpack(const void *inTriangleStart, uint32 inNumTriangles, Vec3 *outTriangles) const
394 {
395 JPH_ASSERT(inNumTriangles > 0);
396 const TriangleBlockHeader *header = reinterpret_cast<const TriangleBlockHeader *>(inTriangleStart);
397 const VertexData *vertices = header->GetVertexData();
398 const TriangleBlock *t = header->GetTriangleBlock();
399 const TriangleBlock *end = t + ((inNumTriangles + 3) >> 2);
400
401 int triangles_left = inNumTriangles;
402
403 do
404 {
405 // Unpack the vertices for 4 triangles
406 Vec4 v1x, v1y, v1z, v2x, v2y, v2z, v3x, v3y, v3z;
407 Unpack(t, vertices, v1x, v1y, v1z, v2x, v2y, v2z, v3x, v3y, v3z);
408
409 // Transpose it so we get normal vectors
410 Mat44 v1 = Mat44(v1x, v1y, v1z, Vec4::sZero()).Transposed();
411 Mat44 v2 = Mat44(v2x, v2y, v2z, Vec4::sZero()).Transposed();
412 Mat44 v3 = Mat44(v3x, v3y, v3z, Vec4::sZero()).Transposed();
413
414 // Store triangle data
415 for (int i = 0; i < 4 && triangles_left > 0; ++i, --triangles_left)
416 {
417 *outTriangles++ = v1.GetColumn3(i);
418 *outTriangles++ = v2.GetColumn3(i);
419 *outTriangles++ = v3.GetColumn3(i);
420 }
421
422 ++t;
423 }
424 while (t < end);
425 }
426
428 JPH_INLINE float TestRay(Vec3Arg inRayOrigin, Vec3Arg inRayDirection, const void *inTriangleStart, uint32 inNumTriangles, float inClosest, uint32 &outClosestTriangleIndex) const
429 {
430 JPH_ASSERT(inNumTriangles > 0);
431 const TriangleBlockHeader *header = reinterpret_cast<const TriangleBlockHeader *>(inTriangleStart);
432 const VertexData *vertices = header->GetVertexData();
433 const TriangleBlock *t = header->GetTriangleBlock();
434 const TriangleBlock *end = t + ((inNumTriangles + 3) >> 2);
435
436 Vec4 closest = Vec4::sReplicate(inClosest);
437 UVec4 closest_triangle_idx = UVec4::sZero();
438
439 UVec4 start_triangle_idx = UVec4::sZero();
440 do
441 {
442 // Unpack the vertices for 4 triangles
443 Vec4 v1x, v1y, v1z, v2x, v2y, v2z, v3x, v3y, v3z;
444 Unpack(t, vertices, v1x, v1y, v1z, v2x, v2y, v2z, v3x, v3y, v3z);
445
446 // Perform ray vs triangle test
447 Vec4 distance = RayTriangle4(inRayOrigin, inRayDirection, v1x, v1y, v1z, v2x, v2y, v2z, v3x, v3y, v3z);
448
449 // Update closest with the smaller values
450 UVec4 smaller = Vec4::sLess(distance, closest);
451 closest = Vec4::sSelect(closest, distance, smaller);
452
453 // Update triangle index with the smallest values
454 UVec4 triangle_idx = start_triangle_idx + UVec4(0, 1, 2, 3);
455 closest_triangle_idx = UVec4::sSelect(closest_triangle_idx, triangle_idx, smaller);
456
457 // Next block
458 ++t;
459 start_triangle_idx += UVec4::sReplicate(4);
460 }
461 while (t < end);
462
463 // Get the smallest component
464 Vec4::sSort4(closest, closest_triangle_idx);
465 outClosestTriangleIndex = closest_triangle_idx.GetX();
466 return closest.GetX();
467 }
468
470 inline void GetTriangle(const void *inTriangleStart, uint32 inTriangleIdx, Vec3 &outV1, Vec3 &outV2, Vec3 &outV3) const
471 {
472 const TriangleBlockHeader *header = reinterpret_cast<const TriangleBlockHeader *>(inTriangleStart);
473 const VertexData *vertices = header->GetVertexData();
474 const TriangleBlock *block = header->GetTriangleBlock() + (inTriangleIdx >> 2);
475 uint32 block_triangle_idx = inTriangleIdx & 0b11;
476
477 // Get the 3 vertices
478 const VertexData &v1 = vertices[block->mIndices[0][block_triangle_idx]];
479 const VertexData &v2 = vertices[block->mIndices[1][block_triangle_idx]];
480 const VertexData &v3 = vertices[block->mIndices[2][block_triangle_idx]];
481
482 // Pack the vertices
483 UVec4 c1(v1.mVertexXY, v2.mVertexXY, v3.mVertexXY, 0);
484 UVec4 c2(v1.mVertexZY, v2.mVertexZY, v3.mVertexZY, 0);
485
486 // Unpack the x y and z component
490
491 // Convert to float
492 Vec4 vx = Vec4::sFusedMultiplyAdd(xc.ToFloat(), mScaleX, mOffsetX);
493 Vec4 vy = Vec4::sFusedMultiplyAdd(yc.ToFloat(), mScaleY, mOffsetY);
494 Vec4 vz = Vec4::sFusedMultiplyAdd(zc.ToFloat(), mScaleZ, mOffsetZ);
495
496 // Transpose it so we get normal vectors
497 Mat44 trans = Mat44(vx, vy, vz, Vec4::sZero()).Transposed();
498 outV1 = trans.GetAxisX();
499 outV2 = trans.GetAxisY();
500 outV3 = trans.GetAxisZ();
501 }
502
504 JPH_INLINE uint32 GetUserData(const void *inTriangleStart, uint32 inTriangleIdx) const
505 {
506 const TriangleBlockHeader *header = reinterpret_cast<const TriangleBlockHeader *>(inTriangleStart);
507 const uint32 *user_data = header->GetUserData();
508 return user_data != nullptr? user_data[inTriangleIdx] : 0;
509 }
510
512 JPH_INLINE static void sGetFlags(const void *inTriangleStart, uint32 inNumTriangles, uint8 *outTriangleFlags)
513 {
514 JPH_ASSERT(inNumTriangles > 0);
515 const TriangleBlockHeader *header = reinterpret_cast<const TriangleBlockHeader *>(inTriangleStart);
516 const TriangleBlock *t = header->GetTriangleBlock();
517 const TriangleBlock *end = t + ((inNumTriangles + 3) >> 2);
518
519 int triangles_left = inNumTriangles;
520 do
521 {
522 for (int i = 0; i < 4 && triangles_left > 0; ++i, --triangles_left)
523 *outTriangleFlags++ = t->mFlags[i];
524
525 ++t;
526 }
527 while (t < end);
528 }
529
531 JPH_INLINE static uint8 sGetFlags(const void *inTriangleStart, int inTriangleIndex)
532 {
533 const TriangleBlockHeader *header = reinterpret_cast<const TriangleBlockHeader *>(inTriangleStart);
534 const TriangleBlock *first_block = header->GetTriangleBlock();
535 return first_block[inTriangleIndex >> 2].mFlags[inTriangleIndex & 0b11];
536 }
537
539 JPH_INLINE void Unpack(const void *inTriangleStart, uint32 inNumTriangles, Vec3 *outTriangles, uint8 *outTriangleFlags) const
540 {
541 Unpack(inTriangleStart, inNumTriangles, outTriangles);
542 sGetFlags(inTriangleStart, inNumTriangles, outTriangleFlags);
543 }
544
545 private:
546 Vec4 mOffsetX;
547 Vec4 mOffsetY;
548 Vec4 mOffsetZ;
549 Vec4 mScaleX;
550 Vec4 mScaleY;
551 Vec4 mScaleZ;
552 };
553};
554
std::uint8_t uint8
Definition Core.h:482
std::uint64_t uint64
Definition Core.h:485
unsigned int uint
Definition Core.h:481
#define JPH_NAMESPACE_END
Definition Core.h:414
std::uint32_t uint32
Definition Core.h:484
#define JPH_NAMESPACE_BEGIN
Definition Core.h:408
#define JPH_ASSERT(...)
Definition IssueReporting.h:33
JPH_INLINE constexpr T Clamp(T inV, T inMin, T inMax)
Clamp a value between two values.
Definition Math.h:48
bool IsAligned(T inV, uint64 inAlignment)
Check if inV is inAlignment aligned.
Definition Math.h:91
T AlignUp(T inV, uint64 inAlignment)
Align inV up to the next inAlignment bytes.
Definition Math.h:83
JPH_INLINE Vec4 RayTriangle4(Vec3Arg inOrigin, Vec3Arg inDirection, Vec4Arg inV0X, Vec4Arg inV0Y, Vec4Arg inV0Z, Vec4Arg inV1X, Vec4Arg inV1Y, Vec4Arg inV1Z, Vec4Arg inV2X, Vec4Arg inV2Y, Vec4Arg inV2Z)
Intersect ray with 4 triangles in SOA format, returns 4 vector of closest points or FLT_MAX if no hit...
Definition RayTriangle.h:76
@ SWIZZLE_Z
Use the Z component.
Definition Swizzle.h:14
@ SWIZZLE_W
Use the W component.
Definition Swizzle.h:15
@ SWIZZLE_X
Use the X component.
Definition Swizzle.h:12
@ SWIZZLE_Y
Use the Y component.
Definition Swizzle.h:13
Axis aligned box.
Definition AABox.h:16
Vec3 GetSize() const
Get size of bounding box.
Definition AABox.h:126
Vec3 mMin
Bounding box min and max.
Definition AABox.h:309
void Encapsulate(Vec3Arg inPos)
Encapsulate point in bounding box.
Definition AABox.h:62
bool empty() const
Returns true if there are no elements in the array.
Definition Array.h:314
size_type size() const
Returns amount of elements in the array.
Definition Array.h:320
void push_back(const T &inValue)
Add element to the back of the array.
Definition Array.h:277
void reserve(size_type inNewSize)
Reserve array space.
Definition Array.h:113
Simple byte buffer, aligned to a cache line.
Definition ByteBuffer.h:16
Type * Allocate(size_t inSize=1)
Allocate block of data of inSize elements and return the pointer.
Definition ByteBuffer.h:33
Class that holds 3 floats. Used as a storage class. Convert to Vec3 for calculations.
Definition Float3.h:13
Triangle with 32-bit indices and material index.
Definition IndexedTriangle.h:80
uint32 mMaterialIndex
Definition IndexedTriangle.h:119
uint32 mIdx[3]
Definition IndexedTriangle.h:75
Holds a 4x4 matrix of floats, but supports also operations on the 3x3 upper left part of the matrix.
Definition Mat44.h:13
JPH_INLINE Vec3 GetAxisY() const
Definition Mat44.h:148
JPH_INLINE Vec3 GetAxisZ() const
Definition Mat44.h:150
JPH_INLINE Mat44 Transposed() const
Transpose matrix.
Definition Mat44.inl:467
JPH_INLINE Vec3 GetColumn3(uint inCol) const
Definition Mat44.h:158
JPH_INLINE Vec3 GetAxisX() const
Access to the columns.
Definition Mat44.h:146
This class is used to decode and decompress triangle data packed by the EncodingContext.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:339
void GetTriangle(const void *inTriangleStart, uint32 inTriangleIdx, Vec3 &outV1, Vec3 &outV2, Vec3 &outV3) const
Decode a single triangle.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:470
static JPH_INLINE uint8 sGetFlags(const void *inTriangleStart, int inTriangleIndex)
Get flags for a particular triangle.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:531
static JPH_INLINE void sGetFlags(const void *inTriangleStart, uint32 inNumTriangles, uint8 *outTriangleFlags)
Get flags for entire triangle block.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:512
JPH_INLINE uint32 GetUserData(const void *inTriangleStart, uint32 inTriangleIdx) const
Get user data for a triangle.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:504
JPH_INLINE void Unpack(const void *inTriangleStart, uint32 inNumTriangles, Vec3 *outTriangles, uint8 *outTriangleFlags) const
Unpacks triangles and flags, convenience function.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:539
JPH_INLINE void Unpack(const void *inTriangleStart, uint32 inNumTriangles, Vec3 *outTriangles) const
Unpacks triangles in the format t1v1,t1v2,t1v3, t2v1,t2v2,t2v3, ...
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:393
JPH_INLINE float TestRay(Vec3Arg inRayOrigin, Vec3Arg inRayDirection, const void *inTriangleStart, uint32 inNumTriangles, float inClosest, uint32 &outClosestTriangleIndex) const
Tests a ray against the packed triangles.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:428
JPH_INLINE DecodingContext(const TriangleHeader *inHeader)
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:382
This class is used to encode and compress triangle data into a byte buffer.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:135
void FinalizePreparePack(uint64 &ioBufferSize)
Mimics the size the Finalize() call would add to ioBufferSize.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:186
static constexpr uint32 cNotFound
Indicates a vertex hasn't been seen yet in the triangle list.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:138
EncodingContext(const VertexList &inVertices)
Construct the encoding context.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:141
void Finalize(const VertexList &inVertices, TriangleHeader *ioHeader, ByteBuffer &ioBuffer) const
After all triangles have been packed, this finalizes the header and triangle buffer.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:294
size_t Pack(const IndexedTriangle *inTriangles, uint inNumTriangles, bool inStoreUserData, ByteBuffer &ioBuffer, const char *&outError)
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:205
void PreparePack(const IndexedTriangle *inTriangles, uint inNumTriangles, bool inStoreUserData, uint64 &ioBufferSize)
Mimics the size a call to Pack() would add to the buffer.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:147
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:28
Float3 mOffset
Offset of all vertices.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:30
Float3 mScale
Scale of all vertices, vertex_position = mOffset + mScale * compressed_vertex_position.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:31
This class is used to validate that the triangle data will not be degenerate after compression.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:105
bool IsDegenerate(const IndexedTriangle &inTriangle) const
Test if a triangle will be degenerate after quantization.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:118
ValidationContext(const IndexedTriangleList &inTriangles, const VertexList &inVertices)
Constructor.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:108
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:25
static constexpr bool ChangesOffsetOnPack
If this codec could return a different offset than the current buffer size when calling Pack()
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:38
static constexpr int TriangleHeaderSize
Size of the header (an empty struct is always > 0 bytes so this needs a separate variable)
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:35
EComponentData
Amount of bits per component.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:42
@ COMPONENT_BITS
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:43
@ COMPONENT_MASK
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:44
ETriangleBlockHeaderFlags
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:82
@ OFFSET_NON_SIGNIFICANT_BITS
The offset from the current block to the start of the vertices must be a multiple of 4 bytes.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:85
@ OFFSET_TO_USERDATA_BITS
When user data is stored, this is the number of blocks to skip to get to the user data (0 = no user d...
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:87
@ OFFSET_TO_USERDATA_MASK
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:88
@ OFFSET_TO_VERTICES_MASK
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:84
@ OFFSET_NON_SIGNIFICANT_MASK
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:86
@ OFFSET_TO_VERTICES_BITS
Offset from current block to start of vertices in bytes.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:83
EVertexXY
Packed X and Y coordinate.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:49
@ COMPONENT_X
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:50
@ COMPONENT_Y1
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:51
@ COMPONENT_Y1_BITS
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:52
EVertexZY
Packed Z and Y coordinate.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:57
@ COMPONENT_Z
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:58
@ COMPONENT_Y2_BITS
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:60
@ COMPONENT_Y2
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:59
Definition UVec4.h:12
JPH_INLINE UVec4 Swizzle() const
Swizzle the elements in inV.
JPH_INLINE uint32 GetZ() const
Definition UVec4.h:104
JPH_INLINE UVec4 LogicalShiftLeft() const
Shift all components by Count bits to the left (filling with zeros from the left)
static JPH_INLINE UVec4 sSelect(UVec4Arg inNotSet, UVec4Arg inSet, UVec4Arg inControl)
Component wise select, returns inNotSet when highest bit of inControl = 0 and inSet when highest bit ...
Definition UVec4.inl:157
JPH_INLINE uint32 GetY() const
Definition UVec4.h:103
JPH_INLINE UVec4 LogicalShiftRight() const
Shift all components by Count bits to the right (filling with zeros from the right)
static JPH_INLINE UVec4 sReplicate(uint32 inV)
Replicate int inV across all components.
Definition UVec4.inl:56
JPH_INLINE UVec4 Expand4Byte4() const
Takes byte 4 .. 7 and expands them to X, Y, Z and W.
Definition UVec4.inl:510
JPH_INLINE UVec4 Expand4Byte0() const
Takes byte 0 .. 3 and expands them to X, Y, Z and W.
Definition UVec4.inl:495
static JPH_INLINE UVec4 sAnd(UVec4Arg inV1, UVec4Arg inV2)
Logical and (component wise)
Definition UVec4.inl:202
static JPH_INLINE UVec4 sOr(UVec4Arg inV1, UVec4Arg inV2)
Logical or (component wise)
Definition UVec4.inl:174
JPH_INLINE uint32 GetX() const
Get individual components.
Definition UVec4.h:102
JPH_INLINE UVec4 Expand4Byte8() const
Takes byte 8 .. 11 and expands them to X, Y, Z and W.
Definition UVec4.inl:525
static JPH_INLINE UVec4 sLoadInt4(const uint32 *inV)
Load 4 ints from memory.
Definition UVec4.inl:78
static JPH_INLINE UVec4 sZero()
Vector with all zeros.
Definition UVec4.inl:45
JPH_INLINE Vec4 ToFloat() const
Convert each component from an int to a float.
Definition UVec4.inl:329
Definition Vec3.h:17
static JPH_INLINE Vec3 sMax(Vec3Arg inV1, Vec3Arg inV2)
Return the maximum of each of the components.
Definition Vec3.inl:155
JPH_INLINE void StoreFloat3(Float3 *outV) const
Store 3 floats to memory.
Definition Vec3.inl:767
static JPH_INLINE Vec3 sReplicate(float inV)
Replicate inV across all components.
Definition Vec3.inl:114
Definition Vec4.h:14
static JPH_INLINE void sSort4(Vec4 &ioValue, UVec4 &ioIndex)
Definition Vec4.inl:304
static JPH_INLINE UVec4 sLess(Vec4Arg inV1, Vec4Arg inV2)
Less than (component wise)
Definition Vec4.inl:180
static JPH_INLINE Vec4 sFusedMultiplyAdd(Vec4Arg inMul1, Vec4Arg inMul2, Vec4Arg inAdd)
Calculates inMul1 * inMul2 + inAdd.
Definition Vec4.inl:236
JPH_INLINE float GetX() const
Get individual components.
Definition Vec4.h:113
static JPH_INLINE Vec4 sZero()
Vector with all zeros.
Definition Vec4.inl:63
static JPH_INLINE Vec4 sSelect(Vec4Arg inNotSet, Vec4Arg inSet, UVec4Arg inControl)
Component wise select, returns inNotSet when highest bit of inControl = 0 and inSet when highest bit ...
Definition Vec4.inl:254
static JPH_INLINE Vec4 sReplicate(float inV)
Replicate inV across all components.
Definition Vec4.inl:74
A triangle header, will be followed by one or more TriangleBlocks.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:93
const VertexData * GetVertexData() const
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:94
uint32 mFlags
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:98
const TriangleBlock * GetTriangleBlock() const
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:95
const uint32 * GetUserData() const
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:96
A block of 4 triangles.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:74
uint8 mFlags[4]
Triangle flags (could contain material and active edges)
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:76
uint8 mIndices[3][4]
8 bit indices to triangle vertices for 4 triangles in the form mIndices[vertex][triangle] where verte...
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:75
A single packed vertex.
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:65
uint32 mVertexXY
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:66
uint32 mVertexZY
Definition TriangleCodecIndexed8BitPackSOA4Flags.h:67