diff options
| author | Bryan Galdrikian <[email protected]> | 2019-09-17 09:16:55 -0700 |
|---|---|---|
| committer | Bryan Galdrikian <[email protected]> | 2019-09-17 09:16:55 -0700 |
| commit | 9f4fc41dc5d857e3c7c3500fc71953e54d780a39 (patch) | |
| tree | 20a548f0eda0ff2f0510ef57f6d038e480dd8611 /sdk/lowlevel/source | |
| parent | Fixing chunk hierarchy optimization/merge bugs (diff) | |
| download | blast-1.1.5_pre5.tar.xz blast-1.1.5_pre5.zip | |
* NvBlastAsset::testForValidChunkOrder (used when creating an NvBlastAsset) is now more strict, requiring parent chunk descriptors to come before their children. It is still less strict than the order created by NvBlastBuildAssetDescChunkReorderMap.v1.1.5_releasev1.1.5_rc1v1.1.5_pre5dev
* Added FractureTool::setApproximateBonding function. Signals the tool to create bonds by proximity instead of just using cut plane data.
* Chunks which have been merged using the uniteChunks function may be merged again
* Restored chunk volume calculation
* NvBlastBuildAssetDescChunkReorderMap failure cases fixed.
Diffstat (limited to 'sdk/lowlevel/source')
| -rwxr-xr-x | sdk/lowlevel/source/NvBlastAsset.cpp | 78 | ||||
| -rwxr-xr-x | sdk/lowlevel/source/NvBlastAsset.h | 31 | ||||
| -rwxr-xr-x | sdk/lowlevel/source/NvBlastAssetHelper.cpp | 139 |
3 files changed, 159 insertions, 89 deletions
diff --git a/sdk/lowlevel/source/NvBlastAsset.cpp b/sdk/lowlevel/source/NvBlastAsset.cpp index c82fa29..553599d 100755 --- a/sdk/lowlevel/source/NvBlastAsset.cpp +++ b/sdk/lowlevel/source/NvBlastAsset.cpp @@ -777,42 +777,48 @@ bool Asset::ensureExactSupportCoverage(uint32_t& supportChunkCount, uint32_t& le bool Asset::testForValidChunkOrder(uint32_t chunkCount, const NvBlastChunkDesc* chunkDescs, const char* chunkAnnotation, void* scratch)
{
- char* chunkMarks = static_cast<char*>(memset(scratch, 0, chunkCount));
-
- uint32_t currentParentChunkIndex = invalidIndex<uint32_t>();
- for (uint32_t i = 0; i < chunkCount; ++i)
- {
- const uint32_t parentChunkIndex = chunkDescs[i].parentChunkIndex;
- if (parentChunkIndex != currentParentChunkIndex)
- {
- if (!isInvalidIndex(currentParentChunkIndex))
- {
- chunkMarks[currentParentChunkIndex] = 1;
- }
- currentParentChunkIndex = parentChunkIndex;
- if (isInvalidIndex(currentParentChunkIndex))
- {
- return false;
- }
- else if (chunkMarks[currentParentChunkIndex] != 0)
- {
- return false;
- }
- }
-
- if (i < chunkCount - 1)
- {
- const bool upperSupport0 = (chunkAnnotation[i] & ChunkAnnotation::UpperSupport) != 0;
- const bool upperSupport1 = (chunkAnnotation[i + 1] & ChunkAnnotation::UpperSupport) != 0;
-
- if (!upperSupport0 && upperSupport1)
- {
- return false;
- }
- }
- }
-
- return true;
+ char* chunkMarks = static_cast<char*>(memset(scratch, 0, chunkCount));
+
+ uint32_t currentParentChunkIndex = invalidIndex<uint32_t>();
+ for (uint32_t i = 0; i < chunkCount; ++i)
+ {
+ const uint32_t parentChunkIndex = chunkDescs[i].parentChunkIndex;
+
+ if (!isInvalidIndex(parentChunkIndex) && parentChunkIndex >= i) // 'chunks should come after their parents'
+ {
+ return false;
+ }
+
+ if (parentChunkIndex != currentParentChunkIndex)
+ {
+ if (!isInvalidIndex(currentParentChunkIndex))
+ {
+ chunkMarks[currentParentChunkIndex] = 1;
+ }
+ currentParentChunkIndex = parentChunkIndex;
+ if (isInvalidIndex(currentParentChunkIndex)) // 'root chunks should go first'
+ {
+ return false;
+ }
+ else if (chunkMarks[currentParentChunkIndex] != 0) // 'all chunks with same parent index should go in a row'
+ {
+ return false;
+ }
+ }
+
+ if (i < chunkCount - 1)
+ {
+ const bool upperSupport0 = (chunkAnnotation[i] & ChunkAnnotation::UpperSupport) != 0;
+ const bool upperSupport1 = (chunkAnnotation[i + 1] & ChunkAnnotation::UpperSupport) != 0;
+
+ if (!upperSupport0 && upperSupport1) // 'upper-support chunks should come before subsupport chunks'
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
}
} // namespace Blast
diff --git a/sdk/lowlevel/source/NvBlastAsset.h b/sdk/lowlevel/source/NvBlastAsset.h index 7113517..8ed3c57 100755 --- a/sdk/lowlevel/source/NvBlastAsset.h +++ b/sdk/lowlevel/source/NvBlastAsset.h @@ -156,21 +156,22 @@ public: static bool ensureExactSupportCoverage(uint32_t& supportChunkCount, uint32_t& leafChunkCount, char* chunkAnnotation, uint32_t chunkCount, NvBlastChunkDesc* chunkDescs, bool testOnly, NvBlastLog logFn);
/**
- Tests a set of chunk descriptors to see if chunks are in valid chunk order.
-
- Chunk order conditions checked:
- 1. 'all chunks with same parent index should go in a row'.
- 2. 'root chunks should go first'.
- 3. 'upper-support chunks should come before subsupport chunks'.
-
- \param[in] chunkCount The number of chunk descriptors.
- \param[in] chunkDescs An array of chunk descriptors of length chunkCount.
- \param[in] chunkAnnotation Annotation generated from ensureExactSupportCoverage (see ensureExactSupportCoverage).
- \param[in] scratch User-supplied scratch memory of chunkCount bytes.
-
- \return true if the descriptors meet the ordering conditions, false otherwise.
- */
- static bool testForValidChunkOrder(uint32_t chunkCount, const NvBlastChunkDesc* chunkDescs, const char* chunkAnnotation, void* scratch);
+ Tests a set of chunk descriptors to see if chunks are in valid chunk order.
+
+ Chunk order conditions checked:
+ 1. 'all chunks with same parent index should go in a row'.
+ 2. 'chunks should come after their parents'.
+ 3. 'root chunks should go first'.
+ 4. 'upper-support chunks should come before subsupport chunks'.
+
+ \param[in] chunkCount The number of chunk descriptors.
+ \param[in] chunkDescs An array of chunk descriptors of length chunkCount.
+ \param[in] chunkAnnotation Annotation generated from ensureExactSupportCoverage (see ensureExactSupportCoverage).
+ \param[in] scratch User-supplied scratch memory of chunkCount bytes.
+
+ \return true if the descriptors meet the ordering conditions, false otherwise.
+ */
+ static bool testForValidChunkOrder(uint32_t chunkCount, const NvBlastChunkDesc* chunkDescs, const char* chunkAnnotation, void* scratch);
//////// Data ////////
diff --git a/sdk/lowlevel/source/NvBlastAssetHelper.cpp b/sdk/lowlevel/source/NvBlastAssetHelper.cpp index 1c8b7bd..9930bad 100755 --- a/sdk/lowlevel/source/NvBlastAssetHelper.cpp +++ b/sdk/lowlevel/source/NvBlastAssetHelper.cpp @@ -47,28 +47,49 @@ Class to hold chunk descriptor and annotation context for sorting a list of indi class ChunksOrdered
{
public:
- ChunksOrdered(const NvBlastChunkDesc* descs, const char* annotation) : m_descs(descs), m_annotation(annotation) {}
-
- bool operator () (uint32_t i0, uint32_t i1) const
- {
- const bool upperSupport0 = (m_annotation[i0] & Asset::ChunkAnnotation::UpperSupport) != 0;
- const bool upperSupport1 = (m_annotation[i1] & Asset::ChunkAnnotation::UpperSupport) != 0;
-
- if (upperSupport0 != upperSupport1)
- {
- return upperSupport0; // If one is uppersupport and one is subsupport, uppersupport should come first
- }
-
- // Parent chunk index (+1 so that UINT32_MAX becomes the lowest value)
- const uint32_t p0 = m_descs[i0].parentChunkIndex + 1;
- const uint32_t p1 = m_descs[i1].parentChunkIndex + 1;
-
- return p0 < p1; // With the same support relationship, order by parent index
- }
+ ChunksOrdered(const NvBlastChunkDesc* descs, const char* annotation)
+ : m_descs(descs), m_annotation(annotation), m_chunkMap(nullptr), m_chunkInvMap(nullptr) {}
+
+ // Map and inverse to apply to chunk descs
+ bool setMap(const uint32_t* map, const uint32_t* inv)
+ {
+ if ((map == nullptr) != (inv == nullptr))
+ {
+ return false;
+ }
+ m_chunkMap = map;
+ m_chunkInvMap = inv;
+ return true;
+ }
+
+ bool operator () (uint32_t ii0, uint32_t ii1) const
+ {
+ const uint32_t i0 = m_chunkMap ? m_chunkMap[ii0] : ii0;
+ const uint32_t i1 = m_chunkMap ? m_chunkMap[ii1] : ii1;
+
+ const bool upperSupport0 = (m_annotation[i0] & Asset::ChunkAnnotation::UpperSupport) != 0;
+ const bool upperSupport1 = (m_annotation[i1] & Asset::ChunkAnnotation::UpperSupport) != 0;
+
+ if (upperSupport0 != upperSupport1)
+ {
+ return upperSupport0; // If one is uppersupport and one is subsupport, uppersupport should come first
+ }
+
+ const uint32_t p0 = m_descs[i0].parentChunkIndex;
+ const uint32_t p1 = m_descs[i1].parentChunkIndex;
+
+ // Parent chunk index (+1 so that UINT32_MAX becomes the lowest value)
+ const uint32_t pp0 = 1 + (m_chunkInvMap && !isInvalidIndex(p0) ? m_chunkInvMap[p0] : p0);
+ const uint32_t pp1 = 1 + (m_chunkInvMap && !isInvalidIndex(p1) ? m_chunkInvMap[p1] : p1);
+
+ return pp0 < pp1; // With the same support relationship, order by parent index
+ }
private:
- const NvBlastChunkDesc* m_descs;
- const char* m_annotation;
+ const NvBlastChunkDesc* m_descs;
+ const char* m_annotation;
+ const uint32_t* m_chunkMap;
+ const uint32_t* m_chunkInvMap;
};
} // namespace Blast
@@ -86,6 +107,7 @@ bool NvBlastBuildAssetDescChunkReorderMap(uint32_t* chunkReorderMap, const NvBla NVBLASTLL_CHECK(chunkReorderMap == nullptr || chunkCount != 0, logFn, "NvBlastBuildAssetDescChunkReorderMap: NULL chunkReorderMap input with non-zero chunkCount", return false);
NVBLASTLL_CHECK(chunkCount == 0 || scratch != nullptr, logFn, "NvBlastBuildAssetDescChunkReorderMap: NULL scratch input with non-zero chunkCount", return false);
+ uint32_t* composedMap = static_cast<uint32_t*>(scratch); scratch = pointerOffset(scratch, chunkCount * sizeof(uint32_t));
uint32_t* chunkMap = static_cast<uint32_t*>(scratch); scratch = pointerOffset(scratch, chunkCount * sizeof(uint32_t));
char* chunkAnnotation = static_cast<char*>(scratch); scratch = pointerOffset(scratch, chunkCount * sizeof(char));
@@ -97,24 +119,65 @@ bool NvBlastBuildAssetDescChunkReorderMap(uint32_t* chunkReorderMap, const NvBla return false;
}
- // check order for fast out (identity map)
- if (Asset::testForValidChunkOrder(chunkCount, chunkDescs, chunkAnnotation, scratch))
- {
- for (uint32_t i = 0; i < chunkCount; ++i)
- {
- chunkReorderMap[i] = i;
- }
-
- return true;
- }
-
- for (uint32_t i = 0; i < chunkCount; ++i)
- {
- chunkMap[i] = i;
- }
- std::sort(chunkMap, chunkMap + chunkCount, ChunksOrdered(chunkDescs, chunkAnnotation));
-
- invertMap(chunkReorderMap, chunkMap, chunkCount);
+ // Initialize composedMap and its inverse to identity
+ for (uint32_t i = 0; i < chunkCount; ++i)
+ {
+ composedMap[i] = i;
+ chunkReorderMap[i] = i;
+ }
+
+ // Create a chunk ordering operator using the composedMap
+ ChunksOrdered chunksOrdered(chunkDescs, chunkAnnotation);
+ chunksOrdered.setMap(composedMap, chunkReorderMap);
+
+ // Check initial order
+ bool ordered = true;
+ if (chunkCount > 1)
+ {
+ for (uint32_t i = chunkCount - 1; ordered && i--;)
+ {
+ ordered = !chunksOrdered(i + 1, i);
+ }
+ }
+ if (ordered)
+ {
+ return true; // Initially ordered, return true
+ }
+
+ NVBLAST_ASSERT(chunkCount > 1);
+
+ // Max depth is bounded by chunkCount, so that is the vound on the number of iterations
+ uint32_t iter = chunkCount;
+ do
+ {
+ // Reorder based on current composed map
+ for (uint32_t i = 0; i < chunkCount; ++i)
+ {
+ chunkMap[i] = i;
+ }
+ std::stable_sort(chunkMap, chunkMap + chunkCount, chunksOrdered);
+
+ // Fold chunkMap into composedMap
+ for (uint32_t i = 0; i < chunkCount; ++i)
+ {
+ chunkMap[i] = composedMap[chunkMap[i]];
+ }
+ for (uint32_t i = 0; i < chunkCount; ++i)
+ {
+ composedMap[i] = chunkMap[i];
+ chunkMap[i] = i;
+ }
+ invertMap(chunkReorderMap, composedMap, chunkCount);
+
+ // Check order
+ ordered = true;
+ for (uint32_t i = chunkCount - 1; ordered && i--;)
+ {
+ ordered = !chunksOrdered(i + 1, i);
+ }
+ } while (!ordered && iter--);
+
+ NVBLAST_ASSERT(ordered);
return false;
}
|