Main Page   Class List   Class Members  

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

sdk/lowlevel/source/NvBlastActor.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 NVBLASTACTOR_H
00030 #define NVBLASTACTOR_H
00031 
00032 
00033 #include "NvBlastAsset.h"
00034 #include "NvBlastDLink.h"
00035 #include "NvBlastIteratorBase.h"
00036 #include "NvBlastSupportGraph.h"
00037 #include "NvBlastFamilyGraph.h"
00038 #include "NvBlastPreprocessorInternal.h"
00039 
00040 #include <cstring>
00041 
00042 
00043 namespace Nv
00044 {
00045 namespace Blast
00046 {
00047 
00048 // Forward declarations
00049 class FamilyGraph;
00050 struct FamilyHeader;
00051 
00058 class Actor : public NvBlastActor
00059 {
00060     friend struct FamilyHeader;
00061 
00062     friend void updateVisibleChunksFromSupportChunk<>(Actor*, IndexDLink<uint32_t>*, uint32_t*, uint32_t, uint32_t, const NvBlastChunk*, uint32_t);
00063 
00064 public:
00065     Actor() : m_familyOffset(0), m_firstVisibleChunkIndex(UINT32_MAX), m_visibleChunkCount(0), m_firstGraphNodeIndex(UINT32_MAX), m_graphNodeCount(0), m_leafChunkCount(0) {}
00066 
00068 
00074     FamilyHeader*       getFamilyHeader() const;
00075 
00081     const Asset*        getAsset() const;
00082 
00090     bool                isActive() const;
00091 
00097     bool                isSubSupportChunk() const;
00098 
00105     bool                isSingleSupportChunk() const;
00106 
00112     uint32_t            getIndex() const;
00113 
00120     uint32_t            getVisibleChunkCount() const;
00121 
00127     uint32_t            getFirstVisibleChunkIndex() const;
00128 
00135     uint32_t            getGraphNodeCount() const;
00136 
00142     uint32_t            getLeafChunkCount() const;
00143 
00149     uint32_t            getFirstGraphNodeIndex() const;
00150 
00156     uint32_t            getFirstSubsupportChunkIndex() const;
00157 
00163     const SupportGraph* getGraph() const;
00164 
00171     FamilyGraph*        getFamilyGraph() const;
00172 
00178     NvBlastChunk*       getChunks() const;
00179 
00185     NvBlastBond*        getBonds() const;
00186 
00194     float*              getLowerSupportChunkHealths() const;
00195 
00201     float*              getSubsupportChunkHealths() const;
00202 
00208     float*              getBondHealths() const;
00209 
00215     const uint32_t*     getGraphNodeIndexLinks() const;
00216 
00217 
00219 
00233     class VisibleChunkIt : public DListIt<uint32_t>
00234     {
00235     public:
00237         VisibleChunkIt(const Actor& actor);
00238     };
00239 
00253     class GraphNodeIt : public LListIt<uint32_t>
00254     {
00255     public:
00257         GraphNodeIt(const Actor& actor);
00258     };
00259 
00260 
00262 
00275     static Actor*       create(NvBlastFamily* family, const NvBlastActorDesc* desc, void* scratch, NvBlastLog logFn);
00276 
00285     static size_t       createRequiredScratch(const NvBlastFamily* family);
00286 
00298     static Actor*       deserialize(NvBlastFamily* family, const void* buffer, NvBlastLog logFn);
00299 
00309     uint32_t            serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) const;
00310 
00318     uint32_t            serializationRequiredStorage(NvBlastLog logFn) const;
00319 
00326     bool                release();
00327 
00328 
00330 
00334     void                generateFracture(NvBlastFractureBuffers* commandBuffers, const NvBlastDamageProgram& program, const void* programParams, NvBlastLog logFn, NvBlastTimers* timers) const;
00335 
00339     uint32_t            damageBond(uint32_t nodeIndex0, uint32_t nodeIndex1, float healthDamage);
00340 
00344     void                damageBond(uint32_t nodeIndex0, uint32_t nodeIndex1, uint32_t bondIndex, float healthDamage);
00345 
00349     uint32_t            damageBond(const NvBlastBondFractureData& cmd);
00350 
00354     void                applyFracture(NvBlastFractureBuffers* eventBuffers, const NvBlastFractureBuffers* commands, NvBlastLog logFn, NvBlastTimers* timers);
00355 
00361     size_t              splitRequiredScratch() const;
00362 
00366     uint32_t            split(NvBlastActorSplitEvent* result, uint32_t newActorsMaxCount, void* scratch, NvBlastLog logFn, NvBlastTimers* timers);
00367 
00377     uint32_t            findIslands(void* scratch);
00378 
00395     uint32_t            partition(Actor** newActors, uint32_t newActorsSize, NvBlastLog logFn);
00396 
00400     void                updateVisibleChunksFromGraphNodes();
00401 
00416     uint32_t            partitionSingleLowerSupportChunk(Actor** newActors, uint32_t newActorsSize, NvBlastLog logFn);
00417 
00432     uint32_t            partitionMultipleGraphNodes(Actor** newActors, uint32_t newActorsSize, NvBlastLog logFn);
00433 
00437     bool                isBoundToWorld() const;
00438 
00442     bool                isSplitRequired() const;
00443 
00444 private:
00445 
00447 
00455     uint32_t    m_familyOffset;
00456 
00461     uint32_t    m_firstVisibleChunkIndex;
00462 
00466     uint32_t    m_visibleChunkCount;
00467 
00472     uint32_t    m_firstGraphNodeIndex;
00473 
00477     uint32_t    m_graphNodeCount;
00478 
00482     uint32_t    m_leafChunkCount;
00483 };
00484 
00485 } // namespace Blast
00486 } // namespace Nv
00487 
00488 
00489 #include "NvBlastFamily.h"
00490 
00491 
00492 namespace Nv
00493 {
00494 namespace Blast
00495 {
00496 
00498 
00499 NV_INLINE FamilyHeader* Actor::getFamilyHeader() const
00500 {
00501     NVBLAST_ASSERT(isActive());
00502     return (FamilyHeader*)((uintptr_t)this - (uintptr_t)m_familyOffset);
00503 }
00504 
00505 
00506 NV_INLINE const Asset* Actor::getAsset() const
00507 {
00508     return getFamilyHeader()->m_asset;
00509 }
00510 
00511 
00512 NV_INLINE bool Actor::isActive() const
00513 {
00514     return m_familyOffset != 0;
00515 }
00516 
00517 
00518 NV_INLINE bool Actor::isSubSupportChunk() const
00519 {
00520     return m_graphNodeCount == 0;
00521 }
00522 
00523 
00524 NV_INLINE bool Actor::isSingleSupportChunk() const
00525 {
00526     return m_graphNodeCount == 1;
00527 }
00528 
00529 
00530 NV_INLINE uint32_t Actor::getIndex() const
00531 {
00532     NVBLAST_ASSERT(isActive());
00533     const FamilyHeader* header = getFamilyHeader();
00534     NVBLAST_ASSERT(header != nullptr);
00535     const size_t index = this - header->getActors();
00536     NVBLAST_ASSERT(index <= UINT32_MAX);
00537     return (uint32_t)index;
00538 }
00539 
00540 
00541 NV_INLINE uint32_t Actor::getVisibleChunkCount() const
00542 {
00543     return m_visibleChunkCount;
00544 }
00545 
00546 
00547 NV_INLINE uint32_t Actor::getFirstVisibleChunkIndex() const
00548 {
00549     return m_firstVisibleChunkIndex;
00550 }
00551 
00552 
00553 NV_INLINE uint32_t Actor::getGraphNodeCount() const
00554 {
00555     return m_graphNodeCount;
00556 }
00557 
00558 
00559 NV_INLINE uint32_t Actor::getLeafChunkCount() const
00560 {
00561     return m_leafChunkCount;
00562 }
00563 
00564 
00565 NV_INLINE uint32_t Actor::getFirstGraphNodeIndex() const
00566 {
00567     return m_firstGraphNodeIndex;
00568 }
00569 
00570 NV_INLINE uint32_t Actor::getFirstSubsupportChunkIndex() const
00571 {
00572     return getAsset()->m_firstSubsupportChunkIndex;
00573 }
00574 
00575 NV_INLINE const SupportGraph* Actor::getGraph() const
00576 {
00577     return &getAsset()->m_graph;
00578 }
00579 
00580 NV_INLINE FamilyGraph* Actor::getFamilyGraph() const
00581 {
00582     return getFamilyHeader()->getFamilyGraph();
00583 }
00584 
00585 NV_INLINE NvBlastChunk* Actor::getChunks() const
00586 {
00587     return getAsset()->getChunks();
00588 }
00589 
00590 NV_INLINE NvBlastBond* Actor::getBonds() const
00591 {
00592     return getAsset()->getBonds();
00593 }
00594 
00595 NV_INLINE float* Actor::getLowerSupportChunkHealths() const
00596 {
00597     return getFamilyHeader()->getLowerSupportChunkHealths();
00598 }
00599 
00600 NV_INLINE float*    Actor::getSubsupportChunkHealths() const
00601 {
00602     return getFamilyHeader()->getSubsupportChunkHealths();
00603 }
00604 
00605 NV_INLINE float* Actor::getBondHealths() const
00606 {
00607     return getFamilyHeader()->getBondHealths();
00608 }
00609 
00610 NV_INLINE const uint32_t* Actor::getGraphNodeIndexLinks() const
00611 {
00612     return getFamilyHeader()->getGraphNodeIndexLinks();
00613 }
00614 
00615 
00616 NV_INLINE bool Actor::release()
00617 {
00618     // Do nothing if this actor is not currently active.
00619     if (!isActive())
00620     {
00621         return false;
00622     }
00623 
00624     FamilyHeader* header = getFamilyHeader();
00625 
00626     // Clear the graph node list
00627     uint32_t* graphNodeIndexLinks = getFamilyHeader()->getGraphNodeIndexLinks();
00628     while (!isInvalidIndex(m_firstGraphNodeIndex))
00629     {
00630         const uint32_t graphNodeIndex = m_firstGraphNodeIndex;
00631         m_firstGraphNodeIndex = graphNodeIndexLinks[m_firstGraphNodeIndex];
00632         graphNodeIndexLinks[graphNodeIndex] = invalidIndex<uint32_t>();
00633         --m_graphNodeCount;
00634     }
00635     NVBLAST_ASSERT(m_graphNodeCount == 0);
00636 
00637     const Asset* asset = getAsset();
00638 
00639     // Clear the visible chunk list
00640     IndexDLink<uint32_t>* visibleChunkIndexLinks = header->getVisibleChunkIndexLinks();
00641     uint32_t* chunkActorIndices = header->getChunkActorIndices();
00642     while (!isInvalidIndex(m_firstVisibleChunkIndex))
00643     {
00644         // Descendants of the visible actor may be accessed again if the actor is deserialized.  Clear subtree.
00645         for (Asset::DepthFirstIt i(*asset, m_firstVisibleChunkIndex, true); (bool)i; ++i)
00646         {
00647             chunkActorIndices[(uint32_t)i] = invalidIndex<uint32_t>();
00648         }
00649         IndexDList<uint32_t>().removeListHead(m_firstVisibleChunkIndex, visibleChunkIndexLinks);
00650         --m_visibleChunkCount;
00651     }
00652     NVBLAST_ASSERT(m_visibleChunkCount == 0);
00653 
00654     // Clear the leaf chunk count
00655     m_leafChunkCount = 0;
00656 
00657     // This invalidates the actor and decrements the reference count
00658     header->returnActor(*this);
00659 
00660     return true;
00661 }
00662 
00663 
00664 NV_INLINE uint32_t Actor::partition(Actor** newActors, uint32_t newActorsSize, NvBlastLog logFn)
00665 {
00666     NVBLASTLL_CHECK(newActorsSize == 0 || newActors != nullptr, logFn, "Nv::Blast::Actor::partition: NULL newActors pointer array input with non-zero newActorCount.", return 0);
00667 
00668     // Call one of two partition functions depending on the actor's support status
00669     return m_graphNodeCount <= 1 ?
00670         partitionSingleLowerSupportChunk(newActors, newActorsSize, logFn) : // This actor will partition into subsupport chunks
00671         partitionMultipleGraphNodes(newActors, newActorsSize, logFn);       // This actor will partition into support chunks
00672 }
00673 
00674 
00675 NV_INLINE bool Actor::isBoundToWorld() const
00676 {
00677     const SupportGraph& graph = *getGraph();
00678 
00679     if (graph.m_nodeCount == 0)
00680     {
00681         return false;   // This shouldn't happen
00682     }
00683 
00684     const uint32_t lastGraphChunkIndex = graph.getChunkIndices()[graph.m_nodeCount - 1];
00685 
00686     if (!isInvalidIndex(lastGraphChunkIndex))
00687     {
00688         return false;   // There is no world node
00689     }
00690 
00691     return getFamilyGraph()->getIslandIds()[graph.m_nodeCount - 1] == getIndex();
00692 }
00693 
00694 
00695 NV_INLINE bool Actor::isSplitRequired() const
00696 {
00697     NVBLAST_ASSERT(isActive());
00698 
00699     if (getGraphNodeCount() <= 1)
00700     {
00701         uint32_t chunkHealthIndex = isSingleSupportChunk() ? getIndex() : getFirstVisibleChunkIndex() - getFirstSubsupportChunkIndex() + getGraph()->m_nodeCount;
00702         float* chunkHealths = getLowerSupportChunkHealths();
00703         if (chunkHealths[chunkHealthIndex] <= 0.0f)
00704         {
00705             const uint32_t chunkIndex = m_graphNodeCount == 0 ? m_firstVisibleChunkIndex : getGraph()->getChunkIndices()[m_firstGraphNodeIndex];
00706             if (!isInvalidIndex(chunkIndex))
00707             {
00708                 const NvBlastChunk& chunk = getChunks()[chunkIndex];
00709                 uint32_t childCount = chunk.childIndexStop - chunk.firstChildIndex;
00710                 return childCount > 0;
00711             }
00712         }
00713     }
00714     else
00715     {
00716         uint32_t* firstDirtyNodeIndices = getFamilyGraph()->getFirstDirtyNodeIndices();
00717         if (!isInvalidIndex(firstDirtyNodeIndices[getIndex()]))
00718         {
00719             return true;
00720         }
00721 
00722     }
00723     return false;
00724 }
00725 
00726 
00728 
00729 NV_INLINE Actor::VisibleChunkIt::VisibleChunkIt(const Actor& actor) : DListIt<uint32_t>(actor.m_firstVisibleChunkIndex, actor.getFamilyHeader()->getVisibleChunkIndexLinks())
00730 {
00731 }
00732 
00733 
00735 
00736 NV_INLINE Actor::GraphNodeIt::GraphNodeIt(const Actor& actor) : LListIt<uint32_t>(actor.m_firstGraphNodeIndex, actor.getFamilyHeader()->getGraphNodeIndexLinks())
00737 {
00738 }
00739 
00740 
00742 
00743 #if NVBLASTLL_CHECK_PARAMS
00744 
00747 static inline bool isValid(const NvBlastFractureBuffers* buffers)
00748 {
00749     if (buffers->chunkFractureCount != 0 && buffers->chunkFractures == nullptr)
00750         return false;
00751 
00752     if (buffers->bondFractureCount != 0 && buffers->bondFractures == nullptr)
00753         return false;
00754 
00755     return true;
00756 }
00757 #endif
00758 
00759 
00760 } // namespace Blast
00761 } // namespace Nv
00762 
00763 
00764 #endif // ifndef NVBLASTACTOR_H
Copyright © 2015-2017 NVIDIA Corporation, 2701 San Tomas Expressway, Santa Clara, CA 95050 U.S.A. All rights reserved. www.nvidia.com