00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef NVBLASTCHUNKHIERARCHY_H
00030 #define NVBLASTCHUNKHIERARCHY_H
00031
00032
00033 #include "NvBlastIndexFns.h"
00034 #include "NvBlastDLink.h"
00035 #include "NvBlast.h"
00036 #include "NvBlastAssert.h"
00037 #include "NvBlastIteratorBase.h"
00038
00039
00040 namespace Nv
00041 {
00042 namespace Blast
00043 {
00044
00049 class ChunkDepthFirstIt : public IteratorBase<uint32_t>
00050 {
00051 public:
00053 ChunkDepthFirstIt(const NvBlastChunk* chunks, uint32_t startChunkIndex, uint32_t chunkIndexLimit) :
00054 IteratorBase<uint32_t>(startChunkIndex), m_chunks(chunks), m_stop(startChunkIndex), m_limit(chunkIndexLimit)
00055 {
00056 if (m_curr >= m_limit)
00057 {
00058 m_curr = invalidIndex<uint32_t>();
00059 }
00060 }
00061
00063 uint32_t operator ++ ()
00064 {
00065 NVBLAST_ASSERT(!isInvalidIndex(m_curr));
00066 const NvBlastChunk* chunk = m_chunks + m_curr;
00067 if (chunk->childIndexStop > chunk->firstChildIndex && chunk->firstChildIndex < m_limit)
00068 {
00069 m_curr = chunk->firstChildIndex;
00070 }
00071 else
00072 {
00073 for (;;)
00074 {
00075 if (m_curr == m_stop)
00076 {
00077 m_curr = invalidIndex<uint32_t>();
00078 break;
00079 }
00080 NVBLAST_ASSERT(!isInvalidIndex(chunk->parentChunkIndex));
00081 const NvBlastChunk* parentChunk = m_chunks + chunk->parentChunkIndex;
00082 if (++m_curr < parentChunk->childIndexStop)
00083 {
00084 break;
00085 }
00086 m_curr = chunk->parentChunkIndex;
00087 chunk = parentChunk;
00088 }
00089 }
00090 return m_curr;
00091 }
00092
00093 private:
00094 const NvBlastChunk* m_chunks;
00095 uint32_t m_stop;
00096 uint32_t m_limit;
00097 };
00098
00099
00105 NV_INLINE uint32_t enumerateChunkHierarchyBreadthFirst
00106 (
00107 uint32_t* chunkIndices,
00108 uint32_t chunkIndicesSize,
00109 const NvBlastChunk* chunks,
00110 uint32_t chunkIndex,
00111 bool includeRoot = true,
00112 uint32_t chunkIndexLimit = invalidIndex<uint32_t>()
00113 )
00114 {
00115 if (chunkIndicesSize == 0)
00116 {
00117 return 0;
00118 }
00119 uint32_t chunkIndexCount = 0;
00120 bool rootHandled = false;
00121 if (includeRoot)
00122 {
00123 chunkIndices[chunkIndexCount++] = chunkIndex;
00124 rootHandled = true;
00125 }
00126 for (uint32_t curr = 0; !rootHandled || curr < chunkIndexCount;)
00127 {
00128 const NvBlastChunk& chunk = chunks[rootHandled ? chunkIndices[curr] : chunkIndex];
00129 if (chunk.firstChildIndex < chunkIndexLimit)
00130 {
00131 const uint32_t childIndexStop = chunk.childIndexStop < chunkIndexLimit ? chunk.childIndexStop : chunkIndexLimit;
00132 const uint32_t childIndexBufferStop = chunk.firstChildIndex + (chunkIndicesSize - chunkIndexCount);
00133 const uint32_t stop = childIndexStop < childIndexBufferStop ? childIndexStop : childIndexBufferStop;
00134 for (uint32_t childIndex = chunk.firstChildIndex; childIndex < stop; ++childIndex)
00135 {
00136 chunkIndices[chunkIndexCount++] = childIndex;
00137 }
00138 }
00139 if (rootHandled)
00140 {
00141 ++curr;
00142 }
00143 rootHandled = true;
00144 }
00145 return chunkIndexCount;
00146 }
00147
00148
00152 template<class VisibilityRep>
00153 void updateVisibleChunksFromSupportChunk
00154 (
00155 VisibilityRep* actors,
00156 IndexDLink<uint32_t>* visibleChunkIndexLinks,
00157 uint32_t* chunkActorIndices,
00158 uint32_t actorIndex,
00159 uint32_t supportChunkIndex,
00160 const NvBlastChunk* chunks,
00161 uint32_t upperSupportChunkCount
00162 )
00163 {
00164 uint32_t chunkIndex = supportChunkIndex;
00165 uint32_t chunkActorIndex = chunkActorIndices[supportChunkIndex];
00166 uint32_t newChunkActorIndex = actorIndex;
00167 VisibilityRep& thisActor = actors[actorIndex];
00168
00169 do
00170 {
00171 if (chunkActorIndex == newChunkActorIndex)
00172 {
00173 break;
00174 }
00175
00176 const uint32_t parentChunkIndex = chunks[chunkIndex].parentChunkIndex;
00177 const uint32_t parentChunkActorIndex = parentChunkIndex != invalidIndex<uint32_t>() ? chunkActorIndices[parentChunkIndex] : invalidIndex<uint32_t>();
00178 const bool chunkVisible = chunkActorIndex != parentChunkActorIndex;
00179
00180
00181 if (chunkVisible && !isInvalidIndex(chunkActorIndex))
00182 {
00183 VisibilityRep& chunkActor = actors[chunkActorIndex];
00184 IndexDList<uint32_t>().removeFromList(chunkActor.m_firstVisibleChunkIndex, visibleChunkIndexLinks, chunkIndex);
00185 --chunkActor.m_visibleChunkCount;
00186 }
00187
00188
00189 const uint32_t oldChunkActorIndex = chunkActorIndices[chunkIndex];
00190 chunkActorIndices[chunkIndex] = newChunkActorIndex;
00191 if (newChunkActorIndex != invalidIndex<uint32_t>() && parentChunkActorIndex != newChunkActorIndex)
00192 {
00193
00194 IndexDList<uint32_t>().insertListHead(thisActor.m_firstVisibleChunkIndex, visibleChunkIndexLinks, chunkIndex);
00195 ++thisActor.m_visibleChunkCount;
00196
00197 if (actorIndex != oldChunkActorIndex)
00198 {
00199 const NvBlastChunk& chunk = chunks[chunkIndex];
00200 if (chunk.firstChildIndex < upperSupportChunkCount)
00201 {
00202 for (uint32_t childChunkIndex = chunk.firstChildIndex; childChunkIndex < chunk.childIndexStop; ++childChunkIndex)
00203 {
00204 if (chunkActorIndices[childChunkIndex] == actorIndex)
00205 {
00206 IndexDList<uint32_t>().removeFromList(thisActor.m_firstVisibleChunkIndex, visibleChunkIndexLinks, childChunkIndex);
00207 --thisActor.m_visibleChunkCount;
00208 }
00209 }
00210 }
00211 }
00212 }
00213
00214 if (parentChunkIndex != invalidIndex<uint32_t>())
00215 {
00216
00217 const NvBlastChunk& parentChunk = chunks[parentChunkIndex];
00218 bool uniform = true;
00219 for (uint32_t childChunkIndex = parentChunk.firstChildIndex; uniform && childChunkIndex < parentChunk.childIndexStop; ++childChunkIndex)
00220 {
00221 uniform = (newChunkActorIndex == chunkActorIndices[childChunkIndex]);
00222 }
00223 if (!uniform)
00224 {
00225 newChunkActorIndex = invalidIndex<uint32_t>();
00226 for (uint32_t childChunkIndex = parentChunk.firstChildIndex; childChunkIndex < parentChunk.childIndexStop; ++childChunkIndex)
00227 {
00228 const uint32_t childChunkActorIndex = chunkActorIndices[childChunkIndex];
00229 if (childChunkActorIndex != invalidIndex<uint32_t>() && childChunkActorIndex == parentChunkActorIndex)
00230 {
00231
00232 VisibilityRep& childChunkActor = actors[childChunkActorIndex];
00233 IndexDList<uint32_t>().insertListHead(childChunkActor.m_firstVisibleChunkIndex, visibleChunkIndexLinks, childChunkIndex);
00234 ++childChunkActor.m_visibleChunkCount;
00235 }
00236 }
00237 }
00238 }
00239
00240
00241 chunkIndex = parentChunkIndex;
00242 chunkActorIndex = parentChunkActorIndex;
00243 } while (chunkIndex != invalidIndex<uint32_t>());
00244 }
00245
00246 }
00247 }
00248
00249
00250 #endif // ifndef NVBLASTCHUNKHIERARCHY_H