Main Page   Class List   Class Members  

  • Main Page
  • User's Guide
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

sdk/lowlevel/source/NvBlastChunkHierarchy.h

Go to the documentation of this file.
00001 // This code contains NVIDIA Confidential Information and is disclosed to you
00002 // under a form of NVIDIA software license agreement provided separately to you.
00003 //
00004 // Notice
00005 // NVIDIA Corporation and its licensors retain all intellectual property and
00006 // proprietary rights in and to this software and related documentation and
00007 // any modifications thereto. Any use, reproduction, disclosure, or
00008 // distribution of this software and related documentation without an express
00009 // license agreement from NVIDIA Corporation is strictly prohibited.
00010 //
00011 // ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
00012 // NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
00013 // THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
00014 // MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
00015 //
00016 // Information and code furnished is believed to be accurate and reliable.
00017 // However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
00018 // information or for any infringement of patents or other rights of third parties that may
00019 // result from its use. No license is granted by implication or otherwise under any patent
00020 // or patent rights of NVIDIA Corporation. Details are subject to change without notice.
00021 // This code supersedes and replaces all information previously supplied.
00022 // NVIDIA Corporation products are not authorized for use as critical
00023 // components in life support devices or systems without express written approval of
00024 // NVIDIA Corporation.
00025 //
00026 // Copyright (c) 2016-2020 NVIDIA Corporation. All rights reserved.
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));   // This should not be possible with this search
00081                 const NvBlastChunk* parentChunk = m_chunks + chunk->parentChunkIndex;
00082                 if (++m_curr < parentChunk->childIndexStop)
00083                 {
00084                     break;  // Sibling chunk is valid, that's the next chunk
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;  // Nothing to do
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         // If the chunk is visible, it needs to be removed from its old actor's visibility list
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         // Now update the chunk's actor index
00189         const uint32_t oldChunkActorIndex = chunkActorIndices[chunkIndex];
00190         chunkActorIndices[chunkIndex] = newChunkActorIndex;
00191         if (newChunkActorIndex != invalidIndex<uint32_t>() && parentChunkActorIndex != newChunkActorIndex)
00192         {
00193             // The chunk is now visible.  Add it to this actor's visibility list
00194             IndexDList<uint32_t>().insertListHead(thisActor.m_firstVisibleChunkIndex, visibleChunkIndexLinks, chunkIndex);
00195             ++thisActor.m_visibleChunkCount;
00196             // Remove its children from this actor's visibility list
00197             if (actorIndex != oldChunkActorIndex)
00198             {
00199                 const NvBlastChunk& chunk = chunks[chunkIndex];
00200                 if (chunk.firstChildIndex < upperSupportChunkCount) // Only need to deal with upper-support children
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             // If all of its siblings have the same index, then the parent will too.  Otherwise, the parent will have an invalid index and its children will be visible
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                         // The child was invisible.  Add it to its actor's visibility list
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         // Climb the hierarchy
00241         chunkIndex = parentChunkIndex;
00242         chunkActorIndex = parentChunkActorIndex;
00243     } while (chunkIndex != invalidIndex<uint32_t>());
00244 }
00245 
00246 } // namespace Blast
00247 } // namespace Nv
00248 
00249 
00250 #endif // ifndef NVBLASTCHUNKHIERARCHY_H
Copyright © 2015-2017 NVIDIA Corporation, 2701 San Tomas Expressway, Santa Clara, CA 95050 U.S.A. All rights reserved. www.nvidia.com