diff options
Diffstat (limited to 'sdk/toolkit/source')
18 files changed, 5039 insertions, 5039 deletions
diff --git a/sdk/toolkit/source/NvBlastTkActorImpl.cpp b/sdk/toolkit/source/NvBlastTkActorImpl.cpp index 32114ef..0074237 100644..100755 --- a/sdk/toolkit/source/NvBlastTkActorImpl.cpp +++ b/sdk/toolkit/source/NvBlastTkActorImpl.cpp @@ -1,373 +1,373 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#include "NvBlastPreprocessor.h" - -#include "NvBlastTkFrameworkImpl.h" -#include "NvBlastTkActorImpl.h" -#include "NvBlastTkGroupImpl.h" -#include "NvBlastTkAssetImpl.h" -#include "NvBlastTkFamilyImpl.h" -#include "NvBlastTkJointImpl.h" - -#include "NvBlast.h" -#include "NvBlastAssert.h" -#include "NvBlastMemory.h" - - -namespace Nv -{ -namespace Blast -{ - -TkActorImpl* TkActorImpl::create(const TkActorDesc& desc) -{ - const TkAssetImpl* asset = static_cast<const TkAssetImpl*>(desc.asset); - - TkFamilyImpl* family = TkFamilyImpl::create(asset); - - NvBlastFamily* familyLL = family->getFamilyLLInternal(); - Array<char>::type scratch((uint32_t)NvBlastFamilyGetRequiredScratchForCreateFirstActor(familyLL, logLL)); - NvBlastActor* actorLL = NvBlastFamilyCreateFirstActor(familyLL, &desc, scratch.begin(), logLL); - if (actorLL == nullptr) - { - NVBLAST_LOG_ERROR("TkActorImpl::create: low-level actor could not be created."); - return nullptr; - } - - TkActorImpl* actor = family->addActor(actorLL); - - if (actor != nullptr) - { - // Add internal joints - const uint32_t internalJointCount = asset->getJointDescCountInternal(); - const TkAssetJointDesc* jointDescs = asset->getJointDescsInternal(); - const NvBlastSupportGraph graph = asset->getGraph(); - TkJointImpl* joints = family->getInternalJoints(); - for (uint32_t jointNum = 0; jointNum < internalJointCount; ++jointNum) - { - const TkAssetJointDesc& assetJointDesc = jointDescs[jointNum]; - NVBLAST_ASSERT(assetJointDesc.nodeIndices[0] < graph.nodeCount && assetJointDesc.nodeIndices[1] < graph.nodeCount); - TkJointDesc jointDesc; - jointDesc.families[0] = jointDesc.families[1] = family; - jointDesc.chunkIndices[0] = graph.chunkIndices[assetJointDesc.nodeIndices[0]]; - jointDesc.chunkIndices[1] = graph.chunkIndices[assetJointDesc.nodeIndices[1]]; - jointDesc.attachPositions[0] = assetJointDesc.attachPositions[0]; - jointDesc.attachPositions[1] = assetJointDesc.attachPositions[1]; - TkJointImpl* joint = new (joints + jointNum) TkJointImpl(jointDesc, family); - actor->addJoint(joint->m_links[0]); - } - - // Mark as damaged to trigger first split call. It could be the case that asset is already split into few actors initially. - actor->markAsDamaged(); - } - - return actor; -} - - -//////// Member functions //////// - -TkActorImpl::TkActorImpl() - : m_actorLL(nullptr) - , m_family(nullptr) - , m_group(nullptr) - , m_groupJobIndex(invalidIndex<uint32_t>()) - , m_flags(0) - , m_jointCount(0) -{ -#if NV_PROFILE - NvBlastTimersReset(&m_timers); -#endif -} - - -TkActorImpl::~TkActorImpl() -{ -} - - -void TkActorImpl::release() -{ - // Disassoaciate all joints - - // Copy joint array for safety against implementation of joint->setActor - TkJointImpl** joints = reinterpret_cast<TkJointImpl**>(NvBlastAlloca(sizeof(TkJointImpl*)*getJointCountInternal())); - TkJointImpl** stop = joints + getJointCountInternal(); - TkJointImpl** jointHandle = joints; - for (JointIt j(*this); (bool)j; ++j) - { - *jointHandle++ = *j; - } - jointHandle = joints; - while (jointHandle < stop) - { - NVBLAST_ASSERT(*jointHandle != nullptr); - NVBLAST_ASSERT((*jointHandle)->getDataInternal().actors[0] == this || (*jointHandle)->getDataInternal().actors[1] == this); - (*jointHandle++)->setActors(nullptr, nullptr); - } - NVBLAST_ASSERT(getJointCountInternal() == 0); - - if (m_group != nullptr) - { - m_group->removeActor(*this); - } - - if (m_actorLL != nullptr) - { - NvBlastActorDeactivate(m_actorLL, logLL); - } - - if (m_family != nullptr) - { - m_family->removeActor(this); - - // Make sure we dispatch any remaining events when this family is emptied, since it will no longer be done by any group - if (m_family->getActorCountInternal() == 0) - { - m_family->getQueue().dispatch(); - } - } -} - - -const NvBlastActor* TkActorImpl::getActorLL() const -{ - return m_actorLL; -} - - -TkFamily& TkActorImpl::getFamily() const -{ - return getFamilyImpl(); -} - - -uint32_t TkActorImpl::getIndex() const -{ - return getIndexInternal(); -} - - -TkGroup* TkActorImpl::getGroup() const -{ - return getGroupImpl(); -} - - -TkGroup* TkActorImpl::removeFromGroup() -{ - if (m_group == nullptr) - { - NVBLAST_LOG_WARNING("TkActorImpl::removeFromGroup: actor not in a group."); - return nullptr; - } - - if (m_group->isProcessing()) - { - NVBLAST_LOG_ERROR("TkActorImpl::removeFromGroup: cannot alter Group while processing."); - return nullptr; - } - - TkGroup* group = m_group; - - return m_group->removeActor(*this) ? group : nullptr; -} - - -NvBlastFamily* TkActorImpl::getFamilyLL() const -{ - return m_family->getFamilyLLInternal(); -} - - -const TkAsset* TkActorImpl::getAsset() const -{ - return m_family->getAssetImpl(); -} - - -uint32_t TkActorImpl::getVisibleChunkCount() const -{ - return NvBlastActorGetVisibleChunkCount(m_actorLL, logLL); -} - - -uint32_t TkActorImpl::getVisibleChunkIndices(uint32_t* visibleChunkIndices, uint32_t visibleChunkIndicesSize) const -{ - return NvBlastActorGetVisibleChunkIndices(visibleChunkIndices, visibleChunkIndicesSize, m_actorLL, logLL); -} - - -uint32_t TkActorImpl::getGraphNodeCount() const -{ - return NvBlastActorGetGraphNodeCount(m_actorLL, logLL); -} - - -uint32_t TkActorImpl::getGraphNodeIndices(uint32_t* graphNodeIndices, uint32_t graphNodeIndicesSize) const -{ - return NvBlastActorGetGraphNodeIndices(graphNodeIndices, graphNodeIndicesSize, m_actorLL, logLL); -} - - -const float* TkActorImpl::getBondHealths() const -{ - return NvBlastActorGetBondHealths(m_actorLL, logLL); -} - - -uint32_t TkActorImpl::getSplitMaxActorCount() const -{ - return NvBlastActorGetMaxActorCountForSplit(m_actorLL, logLL); -} - - -bool TkActorImpl::isDamaged() const -{ - NVBLAST_ASSERT(!m_flags.isSet(TkActorFlag::DAMAGED) || (m_flags.isSet(TkActorFlag::DAMAGED) && m_flags.isSet(TkActorFlag::PENDING))); - return m_flags.isSet(TkActorFlag::DAMAGED); -} - - -void TkActorImpl::markAsDamaged() -{ - m_flags |= TkActorFlag::DAMAGED; - makePending(); -} - - -void TkActorImpl::makePending() -{ - if (m_group != nullptr && !isPending()) - { - m_group->enqueue(this); - } - - m_flags |= TkActorFlag::PENDING; -} - - -TkActorImpl::operator Nv::Blast::TkActorData() const -{ - TkActorData data = { m_family, userData, getIndex() }; - return data; -} - - -void TkActorImpl::damage(const NvBlastDamageProgram& program, const void* programParams) -{ - BLAST_PROFILE_SCOPE_L("TkActor::damage"); - - if (m_group == nullptr) - { - NVBLAST_LOG_WARNING("TkActor::damage: actor is not in a group, cannot fracture."); - return; - } - - if (m_group->isProcessing()) - { - NVBLAST_LOG_WARNING("TkActor::damage: group is being processed, cannot fracture this actor."); - return; - } - - if (NvBlastActorCanFracture(m_actorLL, logLL)) - { - m_damageBuffer.pushBack(DamageData{ program, programParams}); - makePending(); - } -} - - -void TkActorImpl::generateFracture(NvBlastFractureBuffers* commands, const NvBlastDamageProgram& program, const void* programParams) const -{ - BLAST_PROFILE_SCOPE_L("TkActor::generateFracture"); - - if (m_group && m_group->isProcessing()) - { - NVBLAST_LOG_WARNING("TkActor::generateFracture: group is being processed, cannot fracture this actor."); - return; - } - - // const context, must make m_timers mutable otherwise - NvBlastActorGenerateFracture(commands, m_actorLL, program, programParams, logLL, const_cast<NvBlastTimers*>(&m_timers)); -} - - -void TkActorImpl::applyFracture(NvBlastFractureBuffers* eventBuffers, const NvBlastFractureBuffers* commands) -{ - BLAST_PROFILE_SCOPE_L("TkActor::applyFracture"); - - if (m_group && m_group->isProcessing()) - { - NVBLAST_LOG_WARNING("TkActor::applyFracture: group is being processed, cannot fracture this actor."); - return; - } - - NvBlastActorApplyFracture(eventBuffers, m_actorLL, commands, logLL, &m_timers); - - if (commands->chunkFractureCount > 0 || commands->bondFractureCount > 0) - { - markAsDamaged(); - - TkFractureCommands* fevt = getFamilyImpl().getQueue().allocData<TkFractureCommands>(); - fevt->tkActorData = *this; - fevt->buffers = *commands; - getFamilyImpl().getQueue().addEvent(fevt); - getFamilyImpl().getQueue().dispatch(); - } -} - - -uint32_t TkActorImpl::getJointCount() const -{ - return getJointCountInternal(); -} - - -uint32_t TkActorImpl::getJoints(TkJoint** joints, uint32_t jointsSize) const -{ - uint32_t jointsWritten = 0; - - for (JointIt j(*this); (bool)j && jointsWritten < jointsSize; ++j) - { - joints[jointsWritten++] = *j; - } - - return jointsWritten; -} - - -bool TkActorImpl::isBoundToWorld() const -{ - return NvBlastActorIsBoundToWorld(m_actorLL, logLL); -} - - -} // namespace Blast -} // namespace Nv +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#include "NvBlastPreprocessor.h"
+
+#include "NvBlastTkFrameworkImpl.h"
+#include "NvBlastTkActorImpl.h"
+#include "NvBlastTkGroupImpl.h"
+#include "NvBlastTkAssetImpl.h"
+#include "NvBlastTkFamilyImpl.h"
+#include "NvBlastTkJointImpl.h"
+
+#include "NvBlast.h"
+#include "NvBlastAssert.h"
+#include "NvBlastMemory.h"
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+TkActorImpl* TkActorImpl::create(const TkActorDesc& desc)
+{
+ const TkAssetImpl* asset = static_cast<const TkAssetImpl*>(desc.asset);
+
+ TkFamilyImpl* family = TkFamilyImpl::create(asset);
+
+ NvBlastFamily* familyLL = family->getFamilyLLInternal();
+ Array<char>::type scratch((uint32_t)NvBlastFamilyGetRequiredScratchForCreateFirstActor(familyLL, logLL));
+ NvBlastActor* actorLL = NvBlastFamilyCreateFirstActor(familyLL, &desc, scratch.begin(), logLL);
+ if (actorLL == nullptr)
+ {
+ NVBLAST_LOG_ERROR("TkActorImpl::create: low-level actor could not be created.");
+ return nullptr;
+ }
+
+ TkActorImpl* actor = family->addActor(actorLL);
+
+ if (actor != nullptr)
+ {
+ // Add internal joints
+ const uint32_t internalJointCount = asset->getJointDescCountInternal();
+ const TkAssetJointDesc* jointDescs = asset->getJointDescsInternal();
+ const NvBlastSupportGraph graph = asset->getGraph();
+ TkJointImpl* joints = family->getInternalJoints();
+ for (uint32_t jointNum = 0; jointNum < internalJointCount; ++jointNum)
+ {
+ const TkAssetJointDesc& assetJointDesc = jointDescs[jointNum];
+ NVBLAST_ASSERT(assetJointDesc.nodeIndices[0] < graph.nodeCount && assetJointDesc.nodeIndices[1] < graph.nodeCount);
+ TkJointDesc jointDesc;
+ jointDesc.families[0] = jointDesc.families[1] = family;
+ jointDesc.chunkIndices[0] = graph.chunkIndices[assetJointDesc.nodeIndices[0]];
+ jointDesc.chunkIndices[1] = graph.chunkIndices[assetJointDesc.nodeIndices[1]];
+ jointDesc.attachPositions[0] = assetJointDesc.attachPositions[0];
+ jointDesc.attachPositions[1] = assetJointDesc.attachPositions[1];
+ TkJointImpl* joint = new (joints + jointNum) TkJointImpl(jointDesc, family);
+ actor->addJoint(joint->m_links[0]);
+ }
+
+ // Mark as damaged to trigger first split call. It could be the case that asset is already split into few actors initially.
+ actor->markAsDamaged();
+ }
+
+ return actor;
+}
+
+
+//////// Member functions ////////
+
+TkActorImpl::TkActorImpl()
+ : m_actorLL(nullptr)
+ , m_family(nullptr)
+ , m_group(nullptr)
+ , m_groupJobIndex(invalidIndex<uint32_t>())
+ , m_flags(0)
+ , m_jointCount(0)
+{
+#if NV_PROFILE
+ NvBlastTimersReset(&m_timers);
+#endif
+}
+
+
+TkActorImpl::~TkActorImpl()
+{
+}
+
+
+void TkActorImpl::release()
+{
+ // Disassoaciate all joints
+
+ // Copy joint array for safety against implementation of joint->setActor
+ TkJointImpl** joints = reinterpret_cast<TkJointImpl**>(NvBlastAlloca(sizeof(TkJointImpl*)*getJointCountInternal()));
+ TkJointImpl** stop = joints + getJointCountInternal();
+ TkJointImpl** jointHandle = joints;
+ for (JointIt j(*this); (bool)j; ++j)
+ {
+ *jointHandle++ = *j;
+ }
+ jointHandle = joints;
+ while (jointHandle < stop)
+ {
+ NVBLAST_ASSERT(*jointHandle != nullptr);
+ NVBLAST_ASSERT((*jointHandle)->getDataInternal().actors[0] == this || (*jointHandle)->getDataInternal().actors[1] == this);
+ (*jointHandle++)->setActors(nullptr, nullptr);
+ }
+ NVBLAST_ASSERT(getJointCountInternal() == 0);
+
+ if (m_group != nullptr)
+ {
+ m_group->removeActor(*this);
+ }
+
+ if (m_actorLL != nullptr)
+ {
+ NvBlastActorDeactivate(m_actorLL, logLL);
+ }
+
+ if (m_family != nullptr)
+ {
+ m_family->removeActor(this);
+
+ // Make sure we dispatch any remaining events when this family is emptied, since it will no longer be done by any group
+ if (m_family->getActorCountInternal() == 0)
+ {
+ m_family->getQueue().dispatch();
+ }
+ }
+}
+
+
+const NvBlastActor* TkActorImpl::getActorLL() const
+{
+ return m_actorLL;
+}
+
+
+TkFamily& TkActorImpl::getFamily() const
+{
+ return getFamilyImpl();
+}
+
+
+uint32_t TkActorImpl::getIndex() const
+{
+ return getIndexInternal();
+}
+
+
+TkGroup* TkActorImpl::getGroup() const
+{
+ return getGroupImpl();
+}
+
+
+TkGroup* TkActorImpl::removeFromGroup()
+{
+ if (m_group == nullptr)
+ {
+ NVBLAST_LOG_WARNING("TkActorImpl::removeFromGroup: actor not in a group.");
+ return nullptr;
+ }
+
+ if (m_group->isProcessing())
+ {
+ NVBLAST_LOG_ERROR("TkActorImpl::removeFromGroup: cannot alter Group while processing.");
+ return nullptr;
+ }
+
+ TkGroup* group = m_group;
+
+ return m_group->removeActor(*this) ? group : nullptr;
+}
+
+
+NvBlastFamily* TkActorImpl::getFamilyLL() const
+{
+ return m_family->getFamilyLLInternal();
+}
+
+
+const TkAsset* TkActorImpl::getAsset() const
+{
+ return m_family->getAssetImpl();
+}
+
+
+uint32_t TkActorImpl::getVisibleChunkCount() const
+{
+ return NvBlastActorGetVisibleChunkCount(m_actorLL, logLL);
+}
+
+
+uint32_t TkActorImpl::getVisibleChunkIndices(uint32_t* visibleChunkIndices, uint32_t visibleChunkIndicesSize) const
+{
+ return NvBlastActorGetVisibleChunkIndices(visibleChunkIndices, visibleChunkIndicesSize, m_actorLL, logLL);
+}
+
+
+uint32_t TkActorImpl::getGraphNodeCount() const
+{
+ return NvBlastActorGetGraphNodeCount(m_actorLL, logLL);
+}
+
+
+uint32_t TkActorImpl::getGraphNodeIndices(uint32_t* graphNodeIndices, uint32_t graphNodeIndicesSize) const
+{
+ return NvBlastActorGetGraphNodeIndices(graphNodeIndices, graphNodeIndicesSize, m_actorLL, logLL);
+}
+
+
+const float* TkActorImpl::getBondHealths() const
+{
+ return NvBlastActorGetBondHealths(m_actorLL, logLL);
+}
+
+
+uint32_t TkActorImpl::getSplitMaxActorCount() const
+{
+ return NvBlastActorGetMaxActorCountForSplit(m_actorLL, logLL);
+}
+
+
+bool TkActorImpl::isDamaged() const
+{
+ NVBLAST_ASSERT(!m_flags.isSet(TkActorFlag::DAMAGED) || (m_flags.isSet(TkActorFlag::DAMAGED) && m_flags.isSet(TkActorFlag::PENDING)));
+ return m_flags.isSet(TkActorFlag::DAMAGED);
+}
+
+
+void TkActorImpl::markAsDamaged()
+{
+ m_flags |= TkActorFlag::DAMAGED;
+ makePending();
+}
+
+
+void TkActorImpl::makePending()
+{
+ if (m_group != nullptr && !isPending())
+ {
+ m_group->enqueue(this);
+ }
+
+ m_flags |= TkActorFlag::PENDING;
+}
+
+
+TkActorImpl::operator Nv::Blast::TkActorData() const
+{
+ TkActorData data = { m_family, userData, getIndex() };
+ return data;
+}
+
+
+void TkActorImpl::damage(const NvBlastDamageProgram& program, const void* programParams)
+{
+ BLAST_PROFILE_SCOPE_L("TkActor::damage");
+
+ if (m_group == nullptr)
+ {
+ NVBLAST_LOG_WARNING("TkActor::damage: actor is not in a group, cannot fracture.");
+ return;
+ }
+
+ if (m_group->isProcessing())
+ {
+ NVBLAST_LOG_WARNING("TkActor::damage: group is being processed, cannot fracture this actor.");
+ return;
+ }
+
+ if (NvBlastActorCanFracture(m_actorLL, logLL))
+ {
+ m_damageBuffer.pushBack(DamageData{ program, programParams});
+ makePending();
+ }
+}
+
+
+void TkActorImpl::generateFracture(NvBlastFractureBuffers* commands, const NvBlastDamageProgram& program, const void* programParams) const
+{
+ BLAST_PROFILE_SCOPE_L("TkActor::generateFracture");
+
+ if (m_group && m_group->isProcessing())
+ {
+ NVBLAST_LOG_WARNING("TkActor::generateFracture: group is being processed, cannot fracture this actor.");
+ return;
+ }
+
+ // const context, must make m_timers mutable otherwise
+ NvBlastActorGenerateFracture(commands, m_actorLL, program, programParams, logLL, const_cast<NvBlastTimers*>(&m_timers));
+}
+
+
+void TkActorImpl::applyFracture(NvBlastFractureBuffers* eventBuffers, const NvBlastFractureBuffers* commands)
+{
+ BLAST_PROFILE_SCOPE_L("TkActor::applyFracture");
+
+ if (m_group && m_group->isProcessing())
+ {
+ NVBLAST_LOG_WARNING("TkActor::applyFracture: group is being processed, cannot fracture this actor.");
+ return;
+ }
+
+ NvBlastActorApplyFracture(eventBuffers, m_actorLL, commands, logLL, &m_timers);
+
+ if (commands->chunkFractureCount > 0 || commands->bondFractureCount > 0)
+ {
+ markAsDamaged();
+
+ TkFractureCommands* fevt = getFamilyImpl().getQueue().allocData<TkFractureCommands>();
+ fevt->tkActorData = *this;
+ fevt->buffers = *commands;
+ getFamilyImpl().getQueue().addEvent(fevt);
+ getFamilyImpl().getQueue().dispatch();
+ }
+}
+
+
+uint32_t TkActorImpl::getJointCount() const
+{
+ return getJointCountInternal();
+}
+
+
+uint32_t TkActorImpl::getJoints(TkJoint** joints, uint32_t jointsSize) const
+{
+ uint32_t jointsWritten = 0;
+
+ for (JointIt j(*this); (bool)j && jointsWritten < jointsSize; ++j)
+ {
+ joints[jointsWritten++] = *j;
+ }
+
+ return jointsWritten;
+}
+
+
+bool TkActorImpl::isBoundToWorld() const
+{
+ return NvBlastActorIsBoundToWorld(m_actorLL, logLL);
+}
+
+
+} // namespace Blast
+} // namespace Nv
diff --git a/sdk/toolkit/source/NvBlastTkActorImpl.h b/sdk/toolkit/source/NvBlastTkActorImpl.h index 8feeb9c..482f0de 100644..100755 --- a/sdk/toolkit/source/NvBlastTkActorImpl.h +++ b/sdk/toolkit/source/NvBlastTkActorImpl.h @@ -1,342 +1,342 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#ifndef NVBLASTTKACTORIMPL_H -#define NVBLASTTKACTORIMPL_H - - -#include "NvBlastTkCommon.h" - -#include "NvBlastAssert.h" -#include "NvBlastDLink.h" -#include "NvBlastIteratorBase.h" - -#include "NvBlastTkJointImpl.h" - -#include "NvBlast.h" - -#include "NvBlastTkActor.h" - -#include "PxFlags.h" - -namespace Nv -{ -namespace Blast -{ - -// Forward declarations: -class TkGroupImpl; -class TkFamilyImpl; -class TkAssetImpl; -class TkJointImpl; - - -/** -Struct-enum for actor status flags, used in TkGroup processing. -*/ -struct TkActorFlag -{ - enum Enum - { - DAMAGED = (1 << 0), //!< The actor had fractures applied successfully and will take the split step. - PENDING = (1 << 1), //!< The actor will be processed when its group executes, used to update job queues when moving group. - }; -}; - - -/** -Implementation of TkActor. -*/ -class TkActorImpl : public TkActor -{ -public: - TkActorImpl(); - ~TkActorImpl(); - - // Begin TkActor - virtual const NvBlastActor* getActorLL() const override; - - virtual TkFamily& getFamily() const override; - - virtual uint32_t getIndex() const override; - - virtual TkGroup* getGroup() const override; - - virtual TkGroup* removeFromGroup() override; - - virtual const TkAsset* getAsset() const override; - - virtual uint32_t getVisibleChunkCount() const override; - - virtual uint32_t getVisibleChunkIndices(uint32_t* visibleChunkIndices, uint32_t visibleChunkIndicesSize) const override; - - virtual uint32_t getGraphNodeCount() const override; - - virtual uint32_t getGraphNodeIndices(uint32_t* graphNodeIndices, uint32_t graphNodeIndicesSize) const override; - - virtual const float* getBondHealths() const override; - - virtual uint32_t getSplitMaxActorCount() const override; - - virtual void damage(const NvBlastDamageProgram& program, const void* programParams) override; - - virtual bool isPending() const override; - - virtual void generateFracture(NvBlastFractureBuffers* commands, const NvBlastDamageProgram& program, const void* programParams) const override; - - virtual void applyFracture(NvBlastFractureBuffers* eventBuffers, const NvBlastFractureBuffers* commands) override; - - virtual uint32_t getJointCount() const override; - - virtual uint32_t getJoints(TkJoint** joints, uint32_t jointsSize) const override; - - virtual bool isBoundToWorld() const override; - // End TkActor - - // Begin TkObject - virtual void release() override; - // End TkObject - - - // Public methods - - /** - Factory create method. - - \param[in] desc Actor descriptor set by the user. - - \return a pointer to a new TkActorImpl object if successful, NULL otherwise. - */ - static TkActorImpl* create(const TkActorDesc& desc); - - /** - TkActorImpl objects are created in an array within a TkFamilyImpl. Actors may become - 'inactive' without their memory being freed. If inactive, the actor should be treated as if - it has been released. - - \return the active status of this TkActorImpl. - */ - bool isActive() const; - - /** - Utility to return the low-level family to which the low-level actor belongs. - - \return a pointer to the NvBlastFamily to which the low-level actor belongs. - */ - NvBlastFamily* getFamilyLL() const; - - /** - Utility to access the TkFamily to which this actor belongs. - - \return a reference to the TkFamilyImpl to which this TkActorImpl belongs. - */ - TkFamilyImpl& getFamilyImpl() const; - - /** - \return the index of this actor with its TkFamilyImpl. - */ - uint32_t getIndexInternal() const; - - /** - Access to the group to which this actor belongs, if any. - - \return a pointer to the TkGroupImpl to which this TkActorImpl belongs, if any. If this actor is not in a group, this function returns NULL. - */ - TkGroupImpl* getGroupImpl() const; - - /** - Access to the low-level actor associated with this TkActorImpl. - - \return a pointer to the NvBlastActor associated with this TkActorImpl. If this actor is inactive (see isActive), this function returns NULL. - */ - NvBlastActor* getActorLLInternal() const; - - /** - \return the number of TkJointImpl objects that reference this actor. - */ - uint32_t getJointCountInternal() const; - - /** - Joint iterator. Usage: - - Given a TkActorImpl a, - - for (TkActorImpl::JointIt i(a); (bool)i; ++i) - { - TkJointImpl* joint = (TkJointImpl*)i; - // ... - } - */ - class JointIt : public DList::It - { - public: - /** Constructed from an actor. */ - JointIt(const TkActorImpl& actor, Direction dir = Forward); - - /** Current joint. */ - TkJointImpl* operator * () const; - }; - - /** - Implicit converter to TkActorData for events. - */ - operator Nv::Blast::TkActorData() const; - -private: - /** - Functions to raise or check 'damaged' state: this actor will take the split step. - 'damaged' actors automatically become 'pending' also. - */ - void markAsDamaged(); - bool isDamaged() const; - - /** - Raise actor to 'pending' state: this actor will be processed when its group executes next. - Enqueues the actor in its group's job list if a group is set. Otherwise the group will enqueue the actor when it is added. - */ - void makePending(); - - /** - Functions to add or remove an internal reference to a joint. (Joints and actors mutually reference each other.) - */ - void addJoint(TkJointLink& jointLink); - void removeJoint(TkJointLink& jointLink); - - struct DamageData - { - NvBlastDamageProgram program; - const void* programParams; - }; - - // Data - - NvBlastActor* m_actorLL; //!< The low-level actor associated with this actor - TkFamilyImpl* m_family; //!< The TkFamilyImpl to which this actor belongs - TkGroupImpl* m_group; //!< The TkGroupImpl (if any) to which this actor belongs - uint32_t m_groupJobIndex; //!< The index of this actor's job within its group's job list - physx::PxFlags<TkActorFlag::Enum, char> m_flags; //!< Status flags for this actor - Array<DamageData>::type m_damageBuffer; //!< Buffered damage input - uint32_t m_jointCount; //!< The number of joints referenced in m_jointList - DList m_jointList; //!< A doubly-linked list of joint references - -//#if NV_PROFILE - NvBlastTimers m_timers; //!< If profiling, each actor stores timing data -//#endif - - friend class TkWorker; // m_damageBuffer and m_flags - friend class TkGroupImpl; - friend class TkFamilyImpl; - friend class TkJointImpl; - friend class TkFrameworkImpl; -}; - - -//////// TkActorImpl inline methods //////// - -NV_INLINE TkFamilyImpl& TkActorImpl::getFamilyImpl() const -{ - NVBLAST_ASSERT(m_family != nullptr); - - return *m_family; -} - - -NV_INLINE uint32_t TkActorImpl::getIndexInternal() const -{ - NVBLAST_ASSERT(isActive()); - return NvBlastActorGetIndex(m_actorLL, logLL); -} - - -NV_INLINE NvBlastActor* TkActorImpl::getActorLLInternal() const -{ - return m_actorLL; -} - - -NV_INLINE uint32_t TkActorImpl::getJointCountInternal() const -{ - return m_jointCount; -} - - -NV_INLINE TkGroupImpl* TkActorImpl::getGroupImpl() const -{ - return m_group; -} - - -NV_INLINE bool TkActorImpl::isActive() const -{ - return m_actorLL != nullptr; -} - - -NV_INLINE bool TkActorImpl::isPending() const -{ - return m_flags.isSet(TkActorFlag::PENDING); -} - - -NV_INLINE void TkActorImpl::addJoint(TkJointLink& jointLink) -{ - NVBLAST_ASSERT(m_jointList.isSolitary(jointLink)); - - m_jointList.insertHead(jointLink); - ++m_jointCount; -} - - -NV_INLINE void TkActorImpl::removeJoint(TkJointLink& jointLink) -{ - NVBLAST_ASSERT(!m_jointList.isSolitary(jointLink)); - NVBLAST_ASSERT(m_jointCount > 0); - if (m_jointCount > 0) - { - --m_jointCount; - m_jointList.remove(jointLink); - } -} - - -//////// TkActorImpl::JointIt methods //////// - -NV_INLINE TkActorImpl::JointIt::JointIt(const TkActorImpl& actor, Direction dir) : DList::It(actor.m_jointList, dir) {} - - -NV_INLINE TkJointImpl* TkActorImpl::JointIt::operator * () const -{ - const DLink* link = (const DLink*)(*this); - return reinterpret_cast<const TkJointLink*>(link)->m_joint; -} - -} // namespace Blast -} // namespace Nv - - -#endif // ifndef NVBLASTTKACTORIMPL_H +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#ifndef NVBLASTTKACTORIMPL_H
+#define NVBLASTTKACTORIMPL_H
+
+
+#include "NvBlastTkCommon.h"
+
+#include "NvBlastAssert.h"
+#include "NvBlastDLink.h"
+#include "NvBlastIteratorBase.h"
+
+#include "NvBlastTkJointImpl.h"
+
+#include "NvBlast.h"
+
+#include "NvBlastTkActor.h"
+
+#include "PxFlags.h"
+
+namespace Nv
+{
+namespace Blast
+{
+
+// Forward declarations:
+class TkGroupImpl;
+class TkFamilyImpl;
+class TkAssetImpl;
+class TkJointImpl;
+
+
+/**
+Struct-enum for actor status flags, used in TkGroup processing.
+*/
+struct TkActorFlag
+{
+ enum Enum
+ {
+ DAMAGED = (1 << 0), //!< The actor had fractures applied successfully and will take the split step.
+ PENDING = (1 << 1), //!< The actor will be processed when its group executes, used to update job queues when moving group.
+ };
+};
+
+
+/**
+Implementation of TkActor.
+*/
+class TkActorImpl : public TkActor
+{
+public:
+ TkActorImpl();
+ ~TkActorImpl();
+
+ // Begin TkActor
+ virtual const NvBlastActor* getActorLL() const override;
+
+ virtual TkFamily& getFamily() const override;
+
+ virtual uint32_t getIndex() const override;
+
+ virtual TkGroup* getGroup() const override;
+
+ virtual TkGroup* removeFromGroup() override;
+
+ virtual const TkAsset* getAsset() const override;
+
+ virtual uint32_t getVisibleChunkCount() const override;
+
+ virtual uint32_t getVisibleChunkIndices(uint32_t* visibleChunkIndices, uint32_t visibleChunkIndicesSize) const override;
+
+ virtual uint32_t getGraphNodeCount() const override;
+
+ virtual uint32_t getGraphNodeIndices(uint32_t* graphNodeIndices, uint32_t graphNodeIndicesSize) const override;
+
+ virtual const float* getBondHealths() const override;
+
+ virtual uint32_t getSplitMaxActorCount() const override;
+
+ virtual void damage(const NvBlastDamageProgram& program, const void* programParams) override;
+
+ virtual bool isPending() const override;
+
+ virtual void generateFracture(NvBlastFractureBuffers* commands, const NvBlastDamageProgram& program, const void* programParams) const override;
+
+ virtual void applyFracture(NvBlastFractureBuffers* eventBuffers, const NvBlastFractureBuffers* commands) override;
+
+ virtual uint32_t getJointCount() const override;
+
+ virtual uint32_t getJoints(TkJoint** joints, uint32_t jointsSize) const override;
+
+ virtual bool isBoundToWorld() const override;
+ // End TkActor
+
+ // Begin TkObject
+ virtual void release() override;
+ // End TkObject
+
+
+ // Public methods
+
+ /**
+ Factory create method.
+
+ \param[in] desc Actor descriptor set by the user.
+
+ \return a pointer to a new TkActorImpl object if successful, NULL otherwise.
+ */
+ static TkActorImpl* create(const TkActorDesc& desc);
+
+ /**
+ TkActorImpl objects are created in an array within a TkFamilyImpl. Actors may become
+ 'inactive' without their memory being freed. If inactive, the actor should be treated as if
+ it has been released.
+
+ \return the active status of this TkActorImpl.
+ */
+ bool isActive() const;
+
+ /**
+ Utility to return the low-level family to which the low-level actor belongs.
+
+ \return a pointer to the NvBlastFamily to which the low-level actor belongs.
+ */
+ NvBlastFamily* getFamilyLL() const;
+
+ /**
+ Utility to access the TkFamily to which this actor belongs.
+
+ \return a reference to the TkFamilyImpl to which this TkActorImpl belongs.
+ */
+ TkFamilyImpl& getFamilyImpl() const;
+
+ /**
+ \return the index of this actor with its TkFamilyImpl.
+ */
+ uint32_t getIndexInternal() const;
+
+ /**
+ Access to the group to which this actor belongs, if any.
+
+ \return a pointer to the TkGroupImpl to which this TkActorImpl belongs, if any. If this actor is not in a group, this function returns NULL.
+ */
+ TkGroupImpl* getGroupImpl() const;
+
+ /**
+ Access to the low-level actor associated with this TkActorImpl.
+
+ \return a pointer to the NvBlastActor associated with this TkActorImpl. If this actor is inactive (see isActive), this function returns NULL.
+ */
+ NvBlastActor* getActorLLInternal() const;
+
+ /**
+ \return the number of TkJointImpl objects that reference this actor.
+ */
+ uint32_t getJointCountInternal() const;
+
+ /**
+ Joint iterator. Usage:
+
+ Given a TkActorImpl a,
+
+ for (TkActorImpl::JointIt i(a); (bool)i; ++i)
+ {
+ TkJointImpl* joint = (TkJointImpl*)i;
+ // ...
+ }
+ */
+ class JointIt : public DList::It
+ {
+ public:
+ /** Constructed from an actor. */
+ JointIt(const TkActorImpl& actor, Direction dir = Forward);
+
+ /** Current joint. */
+ TkJointImpl* operator * () const;
+ };
+
+ /**
+ Implicit converter to TkActorData for events.
+ */
+ operator Nv::Blast::TkActorData() const;
+
+private:
+ /**
+ Functions to raise or check 'damaged' state: this actor will take the split step.
+ 'damaged' actors automatically become 'pending' also.
+ */
+ void markAsDamaged();
+ bool isDamaged() const;
+
+ /**
+ Raise actor to 'pending' state: this actor will be processed when its group executes next.
+ Enqueues the actor in its group's job list if a group is set. Otherwise the group will enqueue the actor when it is added.
+ */
+ void makePending();
+
+ /**
+ Functions to add or remove an internal reference to a joint. (Joints and actors mutually reference each other.)
+ */
+ void addJoint(TkJointLink& jointLink);
+ void removeJoint(TkJointLink& jointLink);
+
+ struct DamageData
+ {
+ NvBlastDamageProgram program;
+ const void* programParams;
+ };
+
+ // Data
+
+ NvBlastActor* m_actorLL; //!< The low-level actor associated with this actor
+ TkFamilyImpl* m_family; //!< The TkFamilyImpl to which this actor belongs
+ TkGroupImpl* m_group; //!< The TkGroupImpl (if any) to which this actor belongs
+ uint32_t m_groupJobIndex; //!< The index of this actor's job within its group's job list
+ physx::PxFlags<TkActorFlag::Enum, char> m_flags; //!< Status flags for this actor
+ Array<DamageData>::type m_damageBuffer; //!< Buffered damage input
+ uint32_t m_jointCount; //!< The number of joints referenced in m_jointList
+ DList m_jointList; //!< A doubly-linked list of joint references
+
+//#if NV_PROFILE
+ NvBlastTimers m_timers; //!< If profiling, each actor stores timing data
+//#endif
+
+ friend class TkWorker; // m_damageBuffer and m_flags
+ friend class TkGroupImpl;
+ friend class TkFamilyImpl;
+ friend class TkJointImpl;
+ friend class TkFrameworkImpl;
+};
+
+
+//////// TkActorImpl inline methods ////////
+
+NV_INLINE TkFamilyImpl& TkActorImpl::getFamilyImpl() const
+{
+ NVBLAST_ASSERT(m_family != nullptr);
+
+ return *m_family;
+}
+
+
+NV_INLINE uint32_t TkActorImpl::getIndexInternal() const
+{
+ NVBLAST_ASSERT(isActive());
+ return NvBlastActorGetIndex(m_actorLL, logLL);
+}
+
+
+NV_INLINE NvBlastActor* TkActorImpl::getActorLLInternal() const
+{
+ return m_actorLL;
+}
+
+
+NV_INLINE uint32_t TkActorImpl::getJointCountInternal() const
+{
+ return m_jointCount;
+}
+
+
+NV_INLINE TkGroupImpl* TkActorImpl::getGroupImpl() const
+{
+ return m_group;
+}
+
+
+NV_INLINE bool TkActorImpl::isActive() const
+{
+ return m_actorLL != nullptr;
+}
+
+
+NV_INLINE bool TkActorImpl::isPending() const
+{
+ return m_flags.isSet(TkActorFlag::PENDING);
+}
+
+
+NV_INLINE void TkActorImpl::addJoint(TkJointLink& jointLink)
+{
+ NVBLAST_ASSERT(m_jointList.isSolitary(jointLink));
+
+ m_jointList.insertHead(jointLink);
+ ++m_jointCount;
+}
+
+
+NV_INLINE void TkActorImpl::removeJoint(TkJointLink& jointLink)
+{
+ NVBLAST_ASSERT(!m_jointList.isSolitary(jointLink));
+ NVBLAST_ASSERT(m_jointCount > 0);
+ if (m_jointCount > 0)
+ {
+ --m_jointCount;
+ m_jointList.remove(jointLink);
+ }
+}
+
+
+//////// TkActorImpl::JointIt methods ////////
+
+NV_INLINE TkActorImpl::JointIt::JointIt(const TkActorImpl& actor, Direction dir) : DList::It(actor.m_jointList, dir) {}
+
+
+NV_INLINE TkJointImpl* TkActorImpl::JointIt::operator * () const
+{
+ const DLink* link = (const DLink*)(*this);
+ return reinterpret_cast<const TkJointLink*>(link)->m_joint;
+}
+
+} // namespace Blast
+} // namespace Nv
+
+
+#endif // ifndef NVBLASTTKACTORIMPL_H
diff --git a/sdk/toolkit/source/NvBlastTkAssetImpl.cpp b/sdk/toolkit/source/NvBlastTkAssetImpl.cpp index 2f3b9cc..55c35d3 100644..100755 --- a/sdk/toolkit/source/NvBlastTkAssetImpl.cpp +++ b/sdk/toolkit/source/NvBlastTkAssetImpl.cpp @@ -1,276 +1,276 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#include "NvBlastTkFrameworkImpl.h" -#include "NvBlastTkAssetImpl.h" -#include "NvBlastTkFamilyImpl.h" - -#include "NvBlast.h" -#include "NvBlastMemory.h" - - -namespace Nv -{ -namespace Blast -{ - -//////// Static data //////// - -NVBLASTTK_DEFINE_TYPE_IDENTIFIABLE(Asset); - - -//////// Member functions //////// - -TkAssetImpl::TkAssetImpl() - : m_assetLL(nullptr), m_ownsAsset(false) -{ -} - - -TkAssetImpl::TkAssetImpl(const NvBlastID& id) - : TkAssetType(id), m_assetLL(nullptr), m_ownsAsset(false) -{ -} - - -TkAssetImpl::~TkAssetImpl() -{ - if (m_assetLL != nullptr && m_ownsAsset) - { - NVBLAST_FREE(m_assetLL); - } -} - - -const NvBlastAsset* TkAssetImpl::getAssetLL() const -{ - return getAssetLLInternal(); -} - - -uint32_t TkAssetImpl::getChunkCount() const -{ - return NvBlastAssetGetChunkCount(m_assetLL, logLL); -} - - -uint32_t TkAssetImpl::getLeafChunkCount() const -{ - return NvBlastAssetGetLeafChunkCount(m_assetLL, logLL); -} - - -uint32_t TkAssetImpl::getBondCount() const -{ - return NvBlastAssetGetBondCount(m_assetLL, logLL); -} - - -const NvBlastChunk* TkAssetImpl::getChunks() const -{ - return NvBlastAssetGetChunks(m_assetLL, logLL); -} - - -const NvBlastBond* TkAssetImpl::getBonds() const -{ - return NvBlastAssetGetBonds(m_assetLL, logLL); -} - - -const NvBlastSupportGraph TkAssetImpl::getGraph() const -{ - return NvBlastAssetGetSupportGraph(m_assetLL, logLL); -} - - -uint32_t TkAssetImpl::getDataSize() const -{ - return NvBlastAssetGetSize(m_assetLL, logLL); -} - - -uint32_t TkAssetImpl::getJointDescCount() const -{ - return getJointDescCountInternal(); -} - - -const TkAssetJointDesc* TkAssetImpl::getJointDescs() const -{ - return getJointDescsInternal(); -} - - -void TkAssetImpl::release() -{ - const TkType& tkType = TkFamilyImpl::s_type; - const uint32_t num = TkFrameworkImpl::get()->getObjectCount(tkType); - - if (num) - { - Array<TkIdentifiable*>::type dependents(num); - TkFrameworkImpl::get()->getObjects(dependents.begin(), dependents.size(), tkType); - - for (TkObject* o : dependents) - { - TkFamilyImpl* f = static_cast<TkFamilyImpl*>(o); - if (f->getAssetImpl() == this) - { - f->release(); - } - } - } - - NVBLAST_DELETE(this, TkAssetImpl); -} - - -//////// Static functions //////// - -TkAssetImpl* TkAssetImpl::create(const TkAssetDesc& desc) -{ - TkAssetImpl* asset = NVBLAST_NEW(TkAssetImpl); - - Array<char>::type scratch((uint32_t)NvBlastGetRequiredScratchForCreateAsset(&desc, logLL)); - void* mem = NVBLAST_ALLOC_NAMED(NvBlastGetAssetMemorySize(&desc, logLL), "TkAssetImpl::create"); - asset->m_assetLL = NvBlastCreateAsset(mem, &desc, scratch.begin(), logLL); - if (asset->m_assetLL == nullptr) - { - NVBLAST_LOG_ERROR("TkAssetImpl::create: low-level asset could not be created."); - asset->release(); - return nullptr; - } - - if (desc.bondFlags != nullptr) - { - for (uint32_t bondN = 0; bondN < desc.bondCount; ++bondN) - { - if (0 != (desc.bondFlags[bondN] & TkAssetDesc::BondJointed)) - { - const NvBlastBondDesc& bondDesc = desc.bondDescs[bondN]; - const uint32_t c0 = bondDesc.chunkIndices[0]; - const uint32_t c1 = bondDesc.chunkIndices[1]; - if (c0 >= desc.chunkCount || c1 >= desc.chunkCount) - { - NVBLAST_LOG_WARNING("TkAssetImpl::create: joint flag set for badly described bond. No joint descriptor created."); - continue; - } - - if (!asset->addJointDesc(c0, c1)) - { - NVBLAST_LOG_WARNING("TkAssetImpl::create: no bond corresponds to the user-described bond indices. No joint descriptor created."); - } - } - } - } - - asset->m_ownsAsset = true; -// asset->setID(NvBlastAssetGetID(asset->m_assetLL, logLL)); // Keeping LL and Tk IDs distinct - - return asset; -} - - -TkAssetImpl* TkAssetImpl::create(const NvBlastAsset* assetLL, Nv::Blast::TkAssetJointDesc* jointDescs, uint32_t jointDescCount, bool ownsAsset) -{ - TkAssetImpl* asset = NVBLAST_NEW(TkAssetImpl); - - //NOTE: Why are we passing in a const NvBlastAsset* and then discarding the const? - asset->m_assetLL = const_cast<NvBlastAsset*>(assetLL); - if (asset->m_assetLL == nullptr) - { - NVBLAST_LOG_ERROR("TkAssetImpl::create: low-level asset could not be created."); - asset->release(); - return nullptr; - } - - asset->m_ownsAsset = ownsAsset; - asset->setID(NvBlastAssetGetID(asset->m_assetLL, logLL)); - - asset->m_jointDescs.resize(jointDescCount); - for (uint32_t i = 0; i < asset->m_jointDescs.size(); ++i) - { - asset->m_jointDescs[i] = jointDescs[i]; - } - - return asset; -} - -bool TkAssetImpl::addJointDesc(uint32_t chunkIndex0, uint32_t chunkIndex1) -{ - if (m_assetLL == nullptr) - { - return false; - } - - const uint32_t upperSupportChunkCount = NvBlastAssetGetFirstSubsupportChunkIndex(m_assetLL, logLL); - if (chunkIndex0 >= upperSupportChunkCount || chunkIndex1 >= upperSupportChunkCount) - { - return false; - } - - const uint32_t* chunkToGraphNodeMap = NvBlastAssetGetChunkToGraphNodeMap(m_assetLL, logLL); - const uint32_t node0 = chunkToGraphNodeMap[chunkIndex0]; - const uint32_t node1 = chunkToGraphNodeMap[chunkIndex1]; - const NvBlastSupportGraph graph = NvBlastAssetGetSupportGraph(m_assetLL, logLL); - if (node0 >= graph.nodeCount && node1 >= graph.nodeCount) - { - return false; - } - - // Find bond index - // Iterate through all neighbors of node0 chunk - uint32_t bondIndex = 0xFFFFFFFF; - for (uint32_t i = graph.adjacencyPartition[node0]; i < graph.adjacencyPartition[node0 + 1]; i++) - { - if (graph.adjacentNodeIndices[i] == node1) - { - bondIndex = graph.adjacentBondIndices[i]; - break; - } - } - - if (bondIndex >= NvBlastAssetGetBondCount(m_assetLL, logLL)) - { - return false; - } - - const NvBlastBond& bond = NvBlastAssetGetBonds(m_assetLL, logLL)[bondIndex]; - - TkAssetJointDesc jointDesc; - jointDesc.attachPositions[0] = jointDesc.attachPositions[1] = physx::PxVec3(bond.centroid[0], bond.centroid[1], bond.centroid[2]); - jointDesc.nodeIndices[0] = node0; - jointDesc.nodeIndices[1] = node1; - m_jointDescs.pushBack(jointDesc); - - return true; -} - -} // namespace Blast -} // namespace Nv +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#include "NvBlastTkFrameworkImpl.h"
+#include "NvBlastTkAssetImpl.h"
+#include "NvBlastTkFamilyImpl.h"
+
+#include "NvBlast.h"
+#include "NvBlastMemory.h"
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+//////// Static data ////////
+
+NVBLASTTK_DEFINE_TYPE_IDENTIFIABLE(Asset);
+
+
+//////// Member functions ////////
+
+TkAssetImpl::TkAssetImpl()
+ : m_assetLL(nullptr), m_ownsAsset(false)
+{
+}
+
+
+TkAssetImpl::TkAssetImpl(const NvBlastID& id)
+ : TkAssetType(id), m_assetLL(nullptr), m_ownsAsset(false)
+{
+}
+
+
+TkAssetImpl::~TkAssetImpl()
+{
+ if (m_assetLL != nullptr && m_ownsAsset)
+ {
+ NVBLAST_FREE(m_assetLL);
+ }
+}
+
+
+const NvBlastAsset* TkAssetImpl::getAssetLL() const
+{
+ return getAssetLLInternal();
+}
+
+
+uint32_t TkAssetImpl::getChunkCount() const
+{
+ return NvBlastAssetGetChunkCount(m_assetLL, logLL);
+}
+
+
+uint32_t TkAssetImpl::getLeafChunkCount() const
+{
+ return NvBlastAssetGetLeafChunkCount(m_assetLL, logLL);
+}
+
+
+uint32_t TkAssetImpl::getBondCount() const
+{
+ return NvBlastAssetGetBondCount(m_assetLL, logLL);
+}
+
+
+const NvBlastChunk* TkAssetImpl::getChunks() const
+{
+ return NvBlastAssetGetChunks(m_assetLL, logLL);
+}
+
+
+const NvBlastBond* TkAssetImpl::getBonds() const
+{
+ return NvBlastAssetGetBonds(m_assetLL, logLL);
+}
+
+
+const NvBlastSupportGraph TkAssetImpl::getGraph() const
+{
+ return NvBlastAssetGetSupportGraph(m_assetLL, logLL);
+}
+
+
+uint32_t TkAssetImpl::getDataSize() const
+{
+ return NvBlastAssetGetSize(m_assetLL, logLL);
+}
+
+
+uint32_t TkAssetImpl::getJointDescCount() const
+{
+ return getJointDescCountInternal();
+}
+
+
+const TkAssetJointDesc* TkAssetImpl::getJointDescs() const
+{
+ return getJointDescsInternal();
+}
+
+
+void TkAssetImpl::release()
+{
+ const TkType& tkType = TkFamilyImpl::s_type;
+ const uint32_t num = TkFrameworkImpl::get()->getObjectCount(tkType);
+
+ if (num)
+ {
+ Array<TkIdentifiable*>::type dependents(num);
+ TkFrameworkImpl::get()->getObjects(dependents.begin(), dependents.size(), tkType);
+
+ for (TkObject* o : dependents)
+ {
+ TkFamilyImpl* f = static_cast<TkFamilyImpl*>(o);
+ if (f->getAssetImpl() == this)
+ {
+ f->release();
+ }
+ }
+ }
+
+ NVBLAST_DELETE(this, TkAssetImpl);
+}
+
+
+//////// Static functions ////////
+
+TkAssetImpl* TkAssetImpl::create(const TkAssetDesc& desc)
+{
+ TkAssetImpl* asset = NVBLAST_NEW(TkAssetImpl);
+
+ Array<char>::type scratch((uint32_t)NvBlastGetRequiredScratchForCreateAsset(&desc, logLL));
+ void* mem = NVBLAST_ALLOC_NAMED(NvBlastGetAssetMemorySize(&desc, logLL), "TkAssetImpl::create");
+ asset->m_assetLL = NvBlastCreateAsset(mem, &desc, scratch.begin(), logLL);
+ if (asset->m_assetLL == nullptr)
+ {
+ NVBLAST_LOG_ERROR("TkAssetImpl::create: low-level asset could not be created.");
+ asset->release();
+ return nullptr;
+ }
+
+ if (desc.bondFlags != nullptr)
+ {
+ for (uint32_t bondN = 0; bondN < desc.bondCount; ++bondN)
+ {
+ if (0 != (desc.bondFlags[bondN] & TkAssetDesc::BondJointed))
+ {
+ const NvBlastBondDesc& bondDesc = desc.bondDescs[bondN];
+ const uint32_t c0 = bondDesc.chunkIndices[0];
+ const uint32_t c1 = bondDesc.chunkIndices[1];
+ if (c0 >= desc.chunkCount || c1 >= desc.chunkCount)
+ {
+ NVBLAST_LOG_WARNING("TkAssetImpl::create: joint flag set for badly described bond. No joint descriptor created.");
+ continue;
+ }
+
+ if (!asset->addJointDesc(c0, c1))
+ {
+ NVBLAST_LOG_WARNING("TkAssetImpl::create: no bond corresponds to the user-described bond indices. No joint descriptor created.");
+ }
+ }
+ }
+ }
+
+ asset->m_ownsAsset = true;
+// asset->setID(NvBlastAssetGetID(asset->m_assetLL, logLL)); // Keeping LL and Tk IDs distinct
+
+ return asset;
+}
+
+
+TkAssetImpl* TkAssetImpl::create(const NvBlastAsset* assetLL, Nv::Blast::TkAssetJointDesc* jointDescs, uint32_t jointDescCount, bool ownsAsset)
+{
+ TkAssetImpl* asset = NVBLAST_NEW(TkAssetImpl);
+
+ //NOTE: Why are we passing in a const NvBlastAsset* and then discarding the const?
+ asset->m_assetLL = const_cast<NvBlastAsset*>(assetLL);
+ if (asset->m_assetLL == nullptr)
+ {
+ NVBLAST_LOG_ERROR("TkAssetImpl::create: low-level asset could not be created.");
+ asset->release();
+ return nullptr;
+ }
+
+ asset->m_ownsAsset = ownsAsset;
+ asset->setID(NvBlastAssetGetID(asset->m_assetLL, logLL));
+
+ asset->m_jointDescs.resize(jointDescCount);
+ for (uint32_t i = 0; i < asset->m_jointDescs.size(); ++i)
+ {
+ asset->m_jointDescs[i] = jointDescs[i];
+ }
+
+ return asset;
+}
+
+bool TkAssetImpl::addJointDesc(uint32_t chunkIndex0, uint32_t chunkIndex1)
+{
+ if (m_assetLL == nullptr)
+ {
+ return false;
+ }
+
+ const uint32_t upperSupportChunkCount = NvBlastAssetGetFirstSubsupportChunkIndex(m_assetLL, logLL);
+ if (chunkIndex0 >= upperSupportChunkCount || chunkIndex1 >= upperSupportChunkCount)
+ {
+ return false;
+ }
+
+ const uint32_t* chunkToGraphNodeMap = NvBlastAssetGetChunkToGraphNodeMap(m_assetLL, logLL);
+ const uint32_t node0 = chunkToGraphNodeMap[chunkIndex0];
+ const uint32_t node1 = chunkToGraphNodeMap[chunkIndex1];
+ const NvBlastSupportGraph graph = NvBlastAssetGetSupportGraph(m_assetLL, logLL);
+ if (node0 >= graph.nodeCount && node1 >= graph.nodeCount)
+ {
+ return false;
+ }
+
+ // Find bond index
+ // Iterate through all neighbors of node0 chunk
+ uint32_t bondIndex = 0xFFFFFFFF;
+ for (uint32_t i = graph.adjacencyPartition[node0]; i < graph.adjacencyPartition[node0 + 1]; i++)
+ {
+ if (graph.adjacentNodeIndices[i] == node1)
+ {
+ bondIndex = graph.adjacentBondIndices[i];
+ break;
+ }
+ }
+
+ if (bondIndex >= NvBlastAssetGetBondCount(m_assetLL, logLL))
+ {
+ return false;
+ }
+
+ const NvBlastBond& bond = NvBlastAssetGetBonds(m_assetLL, logLL)[bondIndex];
+
+ TkAssetJointDesc jointDesc;
+ jointDesc.attachPositions[0] = jointDesc.attachPositions[1] = physx::PxVec3(bond.centroid[0], bond.centroid[1], bond.centroid[2]);
+ jointDesc.nodeIndices[0] = node0;
+ jointDesc.nodeIndices[1] = node1;
+ m_jointDescs.pushBack(jointDesc);
+
+ return true;
+}
+
+} // namespace Blast
+} // namespace Nv
diff --git a/sdk/toolkit/source/NvBlastTkAssetImpl.h b/sdk/toolkit/source/NvBlastTkAssetImpl.h index 8c7b597..3ae9cfc 100644..100755 --- a/sdk/toolkit/source/NvBlastTkAssetImpl.h +++ b/sdk/toolkit/source/NvBlastTkAssetImpl.h @@ -1,163 +1,163 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#ifndef NVBLASTTKASSETIMPL_H -#define NVBLASTTKASSETIMPL_H - - -#include "NvBlastTkCommon.h" -#include "NvBlastTkJoint.h" -#include "NvBlastTkAsset.h" -#include "NvBlastTkTypeImpl.h" -#include "NvBlastArray.h" - - -// Forward declarations -struct NvBlastAsset; - - -namespace Nv -{ -namespace Blast -{ - -/** -Implementation of TkAsset -*/ -NVBLASTTK_IMPL_DECLARE(Asset) -{ -public: - TkAssetImpl(); - TkAssetImpl(const NvBlastID& id); - ~TkAssetImpl(); - - NVBLASTTK_IMPL_DEFINE_IDENTIFIABLE('A', 'S', 'S', 'T'); - - // Public methods - - /** - Factory create method. This method creates a low-level asset and stores a reference to it. - - \param[in] desc Asset descriptor set by the user. - - \return a pointer to a new TkAssetImpl object if successful, NULL otherwise. - */ - static TkAssetImpl* create(const TkAssetDesc& desc); - - /** - Static method to create an asset from an existing low-level asset. - - \param[in] assetLL A valid low-level asset passed in by the user. - \param[in] jointDescs Optional joint descriptors to add to the new asset. - \param[in] jointDescCount The number of joint descriptors in the jointDescs array. If non-zero, jointDescs cannot be NULL. - \param[in] ownsAsset Whether or not to let this TkAssetImpl object release the low-level NvBlastAsset memory upon its own release. - - \return a pointer to a new TkAssetImpl object if successful, NULL otherwise. - */ - static TkAssetImpl* create(const NvBlastAsset* assetLL, Nv::Blast::TkAssetJointDesc* jointDescs = nullptr, uint32_t jointDescCount = 0, bool ownsAsset = false); - - /** - \return a pointer to the underlying low-level NvBlastAsset associated with this asset. - */ - const NvBlastAsset* getAssetLLInternal() const; - - /** - \return the number of internal joint descriptors stored with this asset. - */ - uint32_t getJointDescCountInternal() const; - - /** - \return the array of internal joint descriptors stored with this asset, with size given by getJointDescCountInternal(). - */ - const TkAssetJointDesc* getJointDescsInternal() const; - - // Begin TkAsset - virtual const NvBlastAsset* getAssetLL() const override; - - virtual uint32_t getChunkCount() const override; - - virtual uint32_t getLeafChunkCount() const override; - - virtual uint32_t getBondCount() const override; - - virtual const NvBlastChunk* getChunks() const override; - - virtual const NvBlastBond* getBonds() const override; - - virtual const NvBlastSupportGraph getGraph() const override; - - virtual uint32_t getDataSize() const override; - - virtual uint32_t getJointDescCount() const override; - - virtual const TkAssetJointDesc* getJointDescs() const override; - // End TkAsset - -private: - /** - Utility to add a joint descriptor between the indexed chunks. The two chunks - must be support chunks, and there must exist a bond between them. The joint's - attachment positions will be the bond centroid. - - \param[in] chunkIndex0 The first chunk index. - \param[in] chunkIndex1 The second chunk index. - - \return true iff successful. - */ - bool addJointDesc(uint32_t chunkIndex0, uint32_t chunkIndex1); - - NvBlastAsset* m_assetLL; //!< The underlying low-level asset. - Array<TkAssetJointDesc>::type m_jointDescs; //!< The array of internal joint descriptors. - bool m_ownsAsset; //!< Whether or not this asset should release its low-level asset upon its own release. -}; - - -//////// TkAssetImpl inline methods //////// - -NV_INLINE const NvBlastAsset* TkAssetImpl::getAssetLLInternal() const -{ - return m_assetLL; -} - - -NV_INLINE uint32_t TkAssetImpl::getJointDescCountInternal() const -{ - return m_jointDescs.size(); -} - - -NV_INLINE const TkAssetJointDesc* TkAssetImpl::getJointDescsInternal() const -{ - return m_jointDescs.begin(); -} - -} // namespace Blast -} // namespace Nv - - -#endif // ifndef NVBLASTTKASSETIMPL_H +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#ifndef NVBLASTTKASSETIMPL_H
+#define NVBLASTTKASSETIMPL_H
+
+
+#include "NvBlastTkCommon.h"
+#include "NvBlastTkJoint.h"
+#include "NvBlastTkAsset.h"
+#include "NvBlastTkTypeImpl.h"
+#include "NvBlastArray.h"
+
+
+// Forward declarations
+struct NvBlastAsset;
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+/**
+Implementation of TkAsset
+*/
+NVBLASTTK_IMPL_DECLARE(Asset)
+{
+public:
+ TkAssetImpl();
+ TkAssetImpl(const NvBlastID& id);
+ ~TkAssetImpl();
+
+ NVBLASTTK_IMPL_DEFINE_IDENTIFIABLE('A', 'S', 'S', 'T');
+
+ // Public methods
+
+ /**
+ Factory create method. This method creates a low-level asset and stores a reference to it.
+
+ \param[in] desc Asset descriptor set by the user.
+
+ \return a pointer to a new TkAssetImpl object if successful, NULL otherwise.
+ */
+ static TkAssetImpl* create(const TkAssetDesc& desc);
+
+ /**
+ Static method to create an asset from an existing low-level asset.
+
+ \param[in] assetLL A valid low-level asset passed in by the user.
+ \param[in] jointDescs Optional joint descriptors to add to the new asset.
+ \param[in] jointDescCount The number of joint descriptors in the jointDescs array. If non-zero, jointDescs cannot be NULL.
+ \param[in] ownsAsset Whether or not to let this TkAssetImpl object release the low-level NvBlastAsset memory upon its own release.
+
+ \return a pointer to a new TkAssetImpl object if successful, NULL otherwise.
+ */
+ static TkAssetImpl* create(const NvBlastAsset* assetLL, Nv::Blast::TkAssetJointDesc* jointDescs = nullptr, uint32_t jointDescCount = 0, bool ownsAsset = false);
+
+ /**
+ \return a pointer to the underlying low-level NvBlastAsset associated with this asset.
+ */
+ const NvBlastAsset* getAssetLLInternal() const;
+
+ /**
+ \return the number of internal joint descriptors stored with this asset.
+ */
+ uint32_t getJointDescCountInternal() const;
+
+ /**
+ \return the array of internal joint descriptors stored with this asset, with size given by getJointDescCountInternal().
+ */
+ const TkAssetJointDesc* getJointDescsInternal() const;
+
+ // Begin TkAsset
+ virtual const NvBlastAsset* getAssetLL() const override;
+
+ virtual uint32_t getChunkCount() const override;
+
+ virtual uint32_t getLeafChunkCount() const override;
+
+ virtual uint32_t getBondCount() const override;
+
+ virtual const NvBlastChunk* getChunks() const override;
+
+ virtual const NvBlastBond* getBonds() const override;
+
+ virtual const NvBlastSupportGraph getGraph() const override;
+
+ virtual uint32_t getDataSize() const override;
+
+ virtual uint32_t getJointDescCount() const override;
+
+ virtual const TkAssetJointDesc* getJointDescs() const override;
+ // End TkAsset
+
+private:
+ /**
+ Utility to add a joint descriptor between the indexed chunks. The two chunks
+ must be support chunks, and there must exist a bond between them. The joint's
+ attachment positions will be the bond centroid.
+
+ \param[in] chunkIndex0 The first chunk index.
+ \param[in] chunkIndex1 The second chunk index.
+
+ \return true iff successful.
+ */
+ bool addJointDesc(uint32_t chunkIndex0, uint32_t chunkIndex1);
+
+ NvBlastAsset* m_assetLL; //!< The underlying low-level asset.
+ Array<TkAssetJointDesc>::type m_jointDescs; //!< The array of internal joint descriptors.
+ bool m_ownsAsset; //!< Whether or not this asset should release its low-level asset upon its own release.
+};
+
+
+//////// TkAssetImpl inline methods ////////
+
+NV_INLINE const NvBlastAsset* TkAssetImpl::getAssetLLInternal() const
+{
+ return m_assetLL;
+}
+
+
+NV_INLINE uint32_t TkAssetImpl::getJointDescCountInternal() const
+{
+ return m_jointDescs.size();
+}
+
+
+NV_INLINE const TkAssetJointDesc* TkAssetImpl::getJointDescsInternal() const
+{
+ return m_jointDescs.begin();
+}
+
+} // namespace Blast
+} // namespace Nv
+
+
+#endif // ifndef NVBLASTTKASSETIMPL_H
diff --git a/sdk/toolkit/source/NvBlastTkCommon.h b/sdk/toolkit/source/NvBlastTkCommon.h index f38b1a5..372a911 100644..100755 --- a/sdk/toolkit/source/NvBlastTkCommon.h +++ b/sdk/toolkit/source/NvBlastTkCommon.h @@ -1,107 +1,107 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#ifndef NVBLASTTKCOMMON_H -#define NVBLASTTKCOMMON_H - - -#include "NvBlastGlobals.h" -#include "NvBlastTkGUID.h" - - -// Macro to define standard object classes. An intermediate class is defined which holds common implementations. -#define NVBLASTTK_IMPL_DECLARE(_name) \ -class Tk##_name##Type : public Tk##_name \ -{ \ -public: \ - /* Blank constructor generates a new NvBlastID and informs framework */ \ - Tk##_name##Type() \ - { \ - memset(&m_ID, 0, sizeof(NvBlastID)); \ - setID(TkGenerateGUID(this)); \ - TkFrameworkImpl::get()->onCreate(*this); \ - } \ - \ - /* This constructor takes an existing NvBlastID and informs framework */ \ - Tk##_name##Type(const NvBlastID& id) \ - { \ - memset(&m_ID, 0, sizeof(NvBlastID)); \ - setID(id); \ - TkFrameworkImpl::get()->onCreate(*this); \ - } \ - \ - /* Destructor informs framework */ \ - ~Tk##_name##Type() { TkFrameworkImpl::get()->onDestroy(*this); } \ - \ - /* Begin TkIdentifiable */ \ - virtual void setID(const NvBlastID& id) override \ - { \ - /* Inform framework of ID change */ \ - TkFrameworkImpl::get()->onIDChange(*this, m_ID, id); \ - m_ID = id; \ - } \ - virtual const NvBlastID& getID() const override { return getIDInternal(); } \ - virtual const TkType& getType() const override { return s_type; } \ - /* End TkIdentifiable */ \ - \ - /* Begin public API */ \ - \ - /* Inline method for internal access to NvBlastID */ \ - const NvBlastID& getIDInternal() const { return m_ID; } \ - \ - /* End public API */ \ - \ - /* Static type information */ \ - static TkTypeImpl s_type; \ - \ -private: \ - NvBlastID m_ID; /* NvBlastID for a TkIdentifiable object */ \ -}; \ - \ -/* Derive object implementation from common implementation class above */ \ -class Tk##_name##Impl final : public Tk##_name##Type - - -// Macro to declare standard object interfaces, enums, etc. -#define NVBLASTTK_IMPL_DEFINE_IDENTIFIABLE(_id0, _id1, _id2, _id3) \ - /* Begin TkObject */ \ - virtual void release() override; \ - /* End TkObject */ \ - \ - /* Enums */ \ - \ - /* Generate a ClassID enum used to identify this TkIdentifiable. */ \ - enum { ClassID = NVBLAST_FOURCC(_id0, _id1, _id2, _id3) } - - -// Macro to define class type data -#define NVBLASTTK_DEFINE_TYPE_IDENTIFIABLE(_name) \ - TkTypeImpl Tk##_name##Type::s_type("Tk" #_name, Tk##_name##Impl::ClassID, 0) - - -#endif // ifndef NVBLASTTKCOMMON_H +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#ifndef NVBLASTTKCOMMON_H
+#define NVBLASTTKCOMMON_H
+
+
+#include "NvBlastGlobals.h"
+#include "NvBlastTkGUID.h"
+
+
+// Macro to define standard object classes. An intermediate class is defined which holds common implementations.
+#define NVBLASTTK_IMPL_DECLARE(_name) \
+class Tk##_name##Type : public Tk##_name \
+{ \
+public: \
+ /* Blank constructor generates a new NvBlastID and informs framework */ \
+ Tk##_name##Type() \
+ { \
+ memset(&m_ID, 0, sizeof(NvBlastID)); \
+ setID(TkGenerateGUID(this)); \
+ TkFrameworkImpl::get()->onCreate(*this); \
+ } \
+ \
+ /* This constructor takes an existing NvBlastID and informs framework */ \
+ Tk##_name##Type(const NvBlastID& id) \
+ { \
+ memset(&m_ID, 0, sizeof(NvBlastID)); \
+ setID(id); \
+ TkFrameworkImpl::get()->onCreate(*this); \
+ } \
+ \
+ /* Destructor informs framework */ \
+ ~Tk##_name##Type() { TkFrameworkImpl::get()->onDestroy(*this); } \
+ \
+ /* Begin TkIdentifiable */ \
+ virtual void setID(const NvBlastID& id) override \
+ { \
+ /* Inform framework of ID change */ \
+ TkFrameworkImpl::get()->onIDChange(*this, m_ID, id); \
+ m_ID = id; \
+ } \
+ virtual const NvBlastID& getID() const override { return getIDInternal(); } \
+ virtual const TkType& getType() const override { return s_type; } \
+ /* End TkIdentifiable */ \
+ \
+ /* Begin public API */ \
+ \
+ /* Inline method for internal access to NvBlastID */ \
+ const NvBlastID& getIDInternal() const { return m_ID; } \
+ \
+ /* End public API */ \
+ \
+ /* Static type information */ \
+ static TkTypeImpl s_type; \
+ \
+private: \
+ NvBlastID m_ID; /* NvBlastID for a TkIdentifiable object */ \
+}; \
+ \
+/* Derive object implementation from common implementation class above */ \
+class Tk##_name##Impl final : public Tk##_name##Type
+
+
+// Macro to declare standard object interfaces, enums, etc.
+#define NVBLASTTK_IMPL_DEFINE_IDENTIFIABLE(_id0, _id1, _id2, _id3) \
+ /* Begin TkObject */ \
+ virtual void release() override; \
+ /* End TkObject */ \
+ \
+ /* Enums */ \
+ \
+ /* Generate a ClassID enum used to identify this TkIdentifiable. */ \
+ enum { ClassID = NVBLAST_FOURCC(_id0, _id1, _id2, _id3) }
+
+
+// Macro to define class type data
+#define NVBLASTTK_DEFINE_TYPE_IDENTIFIABLE(_name) \
+ TkTypeImpl Tk##_name##Type::s_type("Tk" #_name, Tk##_name##Impl::ClassID, 0)
+
+
+#endif // ifndef NVBLASTTKCOMMON_H
diff --git a/sdk/toolkit/source/NvBlastTkEventQueue.h b/sdk/toolkit/source/NvBlastTkEventQueue.h index 2e56a89..86d793f 100644..100755 --- a/sdk/toolkit/source/NvBlastTkEventQueue.h +++ b/sdk/toolkit/source/NvBlastTkEventQueue.h @@ -1,248 +1,248 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#ifndef NVBLASTTKEVENTQUEUE_H -#define NVBLASTTKEVENTQUEUE_H - -#include <algorithm> -#include <vector> - -#include <mutex> -#include <atomic> - -#include "NvBlastTkFrameworkImpl.h" -#include "NvBlastAssert.h" - - -namespace Nv { -namespace Blast { - -/** -A dispatcher queue providing preallocation and thread-safe insertions therein. - -Typical usage: -- preallocate space for events and payload: - - reserveEvents, reserveData -- enable asserts to detect undersized storage (allocations are not thread safe): - - protect(true) -- get pointers to payload data and events to fill in, thread safe for preallocated memory: - - allocData, addEvent -- back on main thread, ensure consistency: - - protect(false) - -- continue adding events and payload on main thread if necessary like above (allocations are safe here) -eventually dispatch, or reset if dispatched by proxy -*/ -class TkEventQueue -{ -public: - TkEventQueue() : m_currentEvent(0), m_poolCapacity(0), m_pool(nullptr), m_allowAllocs(true) {} - - /** - Peek events queue for dispatch. - Do not use in protected state. - */ - operator const Array<TkEvent>::type&() - { - NVBLAST_ASSERT(m_allowAllocs); - NVBLAST_ASSERT(m_currentEvent == m_events.size()); - return m_events; - } - - /** - Debug help to catch (unwanted) allocations during task work. - Note that this will not actually avoid allocations, but assert in debug builds. - - Set true before using in distributed environment. - Set false to return to single-thread mode. - */ - void protect(bool enable) - { - // During parallel use, m_events.size() and m_currentEvent are allowed to diverge. - // This is fine because resizeUninitialized does not alter the stored data. - NVBLAST_ASSERT(m_currentEvent <= m_events.capacity()); - m_events.resizeUninitialized(m_currentEvent); - m_allowAllocs = !enable; - } - - /** - Restores initial state. - Data memory is currently not being reused. To be improved. - */ - void reset() - { - m_events.clear(); - m_currentEvent = 0; - for (void* mem : m_memory) - { - NVBLAST_FREE(mem); - } - m_memory.clear(); - m_currentData = 0; - m_allowAllocs = true; - m_poolCapacity = 0; - m_pool = nullptr; - } - - /** - Queue an event with a payload. - */ - template<class T> - void addEvent(T* payload) - { - uint32_t index = m_currentEvent.fetch_add(1); - - // Should not allocate in protected state. - NVBLAST_ASSERT(m_allowAllocs || m_currentEvent <= m_events.capacity()); - - m_events.resizeUninitialized(m_currentEvent); - - // During parallel use, m_events.size() and m_currentEvent are allowed to diverge. - // Consistency is restored in protect(). - NVBLAST_ASSERT(!m_allowAllocs || m_currentEvent == m_events.size()); - - TkEvent& evt = m_events[index]; - evt.type = TkEvent::Type(T::EVENT_TYPE); - evt.payload = payload; - } - - /** - Request storage for payload. - */ - template<typename T> - T* allocData() - { - uint32_t index = m_currentData.fetch_add(sizeof(T)); - if (m_currentData <= m_poolCapacity) - { - return reinterpret_cast<T*>(&m_pool[index]); - } - else - { - // Could do larger block allocation here. - reserveData(sizeof(T)); - // Account for the requested size. - m_currentData = sizeof(T); - return reinterpret_cast<T*>(&m_pool[0]); - } - } - - /** - Preallocate a memory block of size Bytes for payload data. - Note that this will inevitably allocate a new memory block. - Subsequent calls to allocData will use this memory piecewise. - */ - void reserveData(size_t size) - { - NVBLAST_ASSERT(m_allowAllocs); - m_pool = reinterpret_cast<uint8_t*>(allocDataBySize(size)); - m_poolCapacity = size; - m_currentData = 0; - } - - /** - Preallocate space for events. - */ - void reserveEvents(uint32_t n) - { - NVBLAST_ASSERT(m_allowAllocs); - m_events.reserve(m_events.size() + n); - } - - /** - Add a listener to dispatch to. - */ - void addListener(TkEventListener& l) - { - m_listeners.pushBack(&l); - } - - /** - Remove a listener from dispatch list. - */ - void removeListener(TkEventListener& l) - { - m_listeners.findAndReplaceWithLast(&l); - } - - /** - Dispatch the stored events to the registered listeners. - After dispatch, all data is invalidated. - */ - void dispatch() - { - dispatch(*this); - reset(); - } - - /** - Proxy function to dispatch events to this queue's listeners. - */ - void dispatch(const Array<TkEvent>::type& events) const - { - if (events.size()) - { - for (TkEventListener* l : m_listeners) - { - BLAST_PROFILE_SCOPE_M("TkEventQueue::dispatch"); - l->receive(events.begin(), events.size()); - } - } - } - -private: - /** - Allocates and stores a block of size Bytes of payload data. - */ - void* allocDataBySize(size_t size) - { - void* memory = nullptr; - if (size > 0) - { - memory = NVBLAST_ALLOC_NAMED(size, "TkEventQueue Data"); - m_memory.pushBack(memory); - } - return memory; - } - - - Array<TkEvent>::type m_events; //!< holds events - Array<void*>::type m_memory; //!< holds allocated data memory blocks - std::atomic<uint32_t> m_currentEvent; //!< reference index for event insertion - std::atomic<uint32_t> m_currentData; //!< reference index for data insertion - size_t m_poolCapacity; //!< size of the currently active memory block (m_pool) - uint8_t* m_pool; //!< the current memory block allocData() uses - bool m_allowAllocs; //!< assert guard - InlineArray<TkEventListener*,4>::type m_listeners; //!< objects to dispatch to -}; - -} // namespace Blast -} // namespace Nv - - -#endif // ifndef NVBLASTTKEVENTQUEUE_H +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#ifndef NVBLASTTKEVENTQUEUE_H
+#define NVBLASTTKEVENTQUEUE_H
+
+#include <algorithm>
+#include <vector>
+
+#include <mutex>
+#include <atomic>
+
+#include "NvBlastTkFrameworkImpl.h"
+#include "NvBlastAssert.h"
+
+
+namespace Nv {
+namespace Blast {
+
+/**
+A dispatcher queue providing preallocation and thread-safe insertions therein.
+
+Typical usage:
+- preallocate space for events and payload:
+ - reserveEvents, reserveData
+- enable asserts to detect undersized storage (allocations are not thread safe):
+ - protect(true)
+- get pointers to payload data and events to fill in, thread safe for preallocated memory:
+ - allocData, addEvent
+- back on main thread, ensure consistency:
+ - protect(false)
+
+- continue adding events and payload on main thread if necessary like above (allocations are safe here)
+eventually dispatch, or reset if dispatched by proxy
+*/
+class TkEventQueue
+{
+public:
+ TkEventQueue() : m_currentEvent(0), m_poolCapacity(0), m_pool(nullptr), m_allowAllocs(true) {}
+
+ /**
+ Peek events queue for dispatch.
+ Do not use in protected state.
+ */
+ operator const Array<TkEvent>::type&()
+ {
+ NVBLAST_ASSERT(m_allowAllocs);
+ NVBLAST_ASSERT(m_currentEvent == m_events.size());
+ return m_events;
+ }
+
+ /**
+ Debug help to catch (unwanted) allocations during task work.
+ Note that this will not actually avoid allocations, but assert in debug builds.
+
+ Set true before using in distributed environment.
+ Set false to return to single-thread mode.
+ */
+ void protect(bool enable)
+ {
+ // During parallel use, m_events.size() and m_currentEvent are allowed to diverge.
+ // This is fine because resizeUninitialized does not alter the stored data.
+ NVBLAST_ASSERT(m_currentEvent <= m_events.capacity());
+ m_events.resizeUninitialized(m_currentEvent);
+ m_allowAllocs = !enable;
+ }
+
+ /**
+ Restores initial state.
+ Data memory is currently not being reused. To be improved.
+ */
+ void reset()
+ {
+ m_events.clear();
+ m_currentEvent = 0;
+ for (void* mem : m_memory)
+ {
+ NVBLAST_FREE(mem);
+ }
+ m_memory.clear();
+ m_currentData = 0;
+ m_allowAllocs = true;
+ m_poolCapacity = 0;
+ m_pool = nullptr;
+ }
+
+ /**
+ Queue an event with a payload.
+ */
+ template<class T>
+ void addEvent(T* payload)
+ {
+ uint32_t index = m_currentEvent.fetch_add(1);
+
+ // Should not allocate in protected state.
+ NVBLAST_ASSERT(m_allowAllocs || m_currentEvent <= m_events.capacity());
+
+ m_events.resizeUninitialized(m_currentEvent);
+
+ // During parallel use, m_events.size() and m_currentEvent are allowed to diverge.
+ // Consistency is restored in protect().
+ NVBLAST_ASSERT(!m_allowAllocs || m_currentEvent == m_events.size());
+
+ TkEvent& evt = m_events[index];
+ evt.type = TkEvent::Type(T::EVENT_TYPE);
+ evt.payload = payload;
+ }
+
+ /**
+ Request storage for payload.
+ */
+ template<typename T>
+ T* allocData()
+ {
+ uint32_t index = m_currentData.fetch_add(sizeof(T));
+ if (m_currentData <= m_poolCapacity)
+ {
+ return reinterpret_cast<T*>(&m_pool[index]);
+ }
+ else
+ {
+ // Could do larger block allocation here.
+ reserveData(sizeof(T));
+ // Account for the requested size.
+ m_currentData = sizeof(T);
+ return reinterpret_cast<T*>(&m_pool[0]);
+ }
+ }
+
+ /**
+ Preallocate a memory block of size Bytes for payload data.
+ Note that this will inevitably allocate a new memory block.
+ Subsequent calls to allocData will use this memory piecewise.
+ */
+ void reserveData(size_t size)
+ {
+ NVBLAST_ASSERT(m_allowAllocs);
+ m_pool = reinterpret_cast<uint8_t*>(allocDataBySize(size));
+ m_poolCapacity = size;
+ m_currentData = 0;
+ }
+
+ /**
+ Preallocate space for events.
+ */
+ void reserveEvents(uint32_t n)
+ {
+ NVBLAST_ASSERT(m_allowAllocs);
+ m_events.reserve(m_events.size() + n);
+ }
+
+ /**
+ Add a listener to dispatch to.
+ */
+ void addListener(TkEventListener& l)
+ {
+ m_listeners.pushBack(&l);
+ }
+
+ /**
+ Remove a listener from dispatch list.
+ */
+ void removeListener(TkEventListener& l)
+ {
+ m_listeners.findAndReplaceWithLast(&l);
+ }
+
+ /**
+ Dispatch the stored events to the registered listeners.
+ After dispatch, all data is invalidated.
+ */
+ void dispatch()
+ {
+ dispatch(*this);
+ reset();
+ }
+
+ /**
+ Proxy function to dispatch events to this queue's listeners.
+ */
+ void dispatch(const Array<TkEvent>::type& events) const
+ {
+ if (events.size())
+ {
+ for (TkEventListener* l : m_listeners)
+ {
+ BLAST_PROFILE_SCOPE_M("TkEventQueue::dispatch");
+ l->receive(events.begin(), events.size());
+ }
+ }
+ }
+
+private:
+ /**
+ Allocates and stores a block of size Bytes of payload data.
+ */
+ void* allocDataBySize(size_t size)
+ {
+ void* memory = nullptr;
+ if (size > 0)
+ {
+ memory = NVBLAST_ALLOC_NAMED(size, "TkEventQueue Data");
+ m_memory.pushBack(memory);
+ }
+ return memory;
+ }
+
+
+ Array<TkEvent>::type m_events; //!< holds events
+ Array<void*>::type m_memory; //!< holds allocated data memory blocks
+ std::atomic<uint32_t> m_currentEvent; //!< reference index for event insertion
+ std::atomic<uint32_t> m_currentData; //!< reference index for data insertion
+ size_t m_poolCapacity; //!< size of the currently active memory block (m_pool)
+ uint8_t* m_pool; //!< the current memory block allocData() uses
+ bool m_allowAllocs; //!< assert guard
+ InlineArray<TkEventListener*,4>::type m_listeners; //!< objects to dispatch to
+};
+
+} // namespace Blast
+} // namespace Nv
+
+
+#endif // ifndef NVBLASTTKEVENTQUEUE_H
diff --git a/sdk/toolkit/source/NvBlastTkFamilyImpl.cpp b/sdk/toolkit/source/NvBlastTkFamilyImpl.cpp index 50b3266..26133f0 100644..100755 --- a/sdk/toolkit/source/NvBlastTkFamilyImpl.cpp +++ b/sdk/toolkit/source/NvBlastTkFamilyImpl.cpp @@ -1,558 +1,558 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#include "NvBlastTkFrameworkImpl.h" -#include "NvBlastTkFamilyImpl.h" -#include "NvBlastTkGroupImpl.h" -#include "NvBlastTkAssetImpl.h" -#include "NvBlastTkActorImpl.h" -#include "NvBlastTkJointImpl.h" - -#include "NvBlastIndexFns.h" -#include "NvBlastMemory.h" - - -namespace Nv -{ -namespace Blast -{ - -//////// Static data //////// - -NVBLASTTK_DEFINE_TYPE_IDENTIFIABLE(Family); - - -//////// Member functions //////// - -TkFamilyImpl::TkFamilyImpl() : m_familyLL(nullptr), m_internalJointCount(0), m_asset(nullptr) -{ -} - - -TkFamilyImpl::TkFamilyImpl(const NvBlastID& id) : TkFamilyType(id), m_familyLL(nullptr), m_internalJointCount(0), m_asset(nullptr) -{ -} - - -TkFamilyImpl::~TkFamilyImpl() -{ - if (m_familyLL != nullptr) - { - uint32_t familyActorCount = NvBlastFamilyGetActorCount(m_familyLL, logLL); - if (familyActorCount != 0) - { - NVBLAST_LOG_WARNING("TkFamilyImpl::~TkFamilyImpl(): family actor count is not 0."); - } - NVBLAST_FREE(m_familyLL); - } -} - - -void TkFamilyImpl::release() -{ - for (TkActorImpl& actor : m_actors) - { - if (actor.isActive()) - { - actor.release(); - } - } - - m_actors.clear(); - - NVBLAST_DELETE(this, TkFamilyImpl); -} - - -const NvBlastFamily* TkFamilyImpl::getFamilyLL() const -{ - return m_familyLL; -} - - -TkActorImpl* TkFamilyImpl::addActor(NvBlastActor* actorLL) -{ - TkActorImpl* actor = getActorByActorLL(actorLL); - NVBLAST_ASSERT(actor); - actor->m_actorLL = actorLL; - actor->m_family = this; - return actor; -} - - -void TkFamilyImpl::removeActor(TkActorImpl* actor) -{ - NVBLAST_ASSERT(actor != nullptr && actor->m_family == this); - //actor->m_family = nullptr; - actor->m_actorLL = nullptr; -} - - -uint32_t TkFamilyImpl::getActorCount() const -{ - return getActorCountInternal(); -} - - -uint32_t TkFamilyImpl::getActors(TkActor** buffer, uint32_t bufferSize, uint32_t indexStart /*= 0*/) const -{ - uint32_t actorCount = getActorCount(); - if (actorCount <= indexStart) - { - NVBLAST_LOG_WARNING("TkFamilyImpl::getActors: indexStart beyond end of actor list."); - return 0; - } - - actorCount -= indexStart; - if (actorCount > bufferSize) - { - actorCount = static_cast<uint32_t>(bufferSize); - } - - uint32_t index = 0; - for (const TkActorImpl& actor : m_actors) - { - if (actor.isActive()) - { - if (index >= indexStart) - { - if ((index - indexStart) >= actorCount) - { - break; - } - else - { - *buffer++ = const_cast<TkActorImpl*>(&actor); - } - } - index++; - } - } - - return actorCount; -} - - -NV_INLINE bool areLLActorsEqual(const NvBlastActor* actor0, const NvBlastActor* actor1, Array<uint32_t>::type& scratch) -{ - if (NvBlastActorGetGraphNodeCount(actor0, logLL) != NvBlastActorGetGraphNodeCount(actor1, logLL)) - { - return false; - } - - const uint32_t chunkCount = NvBlastActorGetVisibleChunkCount(actor0, logLL); - if (chunkCount != NvBlastActorGetVisibleChunkCount(actor1, logLL)) - { - return false; - } - - scratch.resize(chunkCount * 2); - NvBlastActorGetVisibleChunkIndices(scratch.begin(), chunkCount, actor0, logLL); - NvBlastActorGetVisibleChunkIndices(scratch.begin() + chunkCount, chunkCount, actor1, logLL); - return memcmp(scratch.begin(), scratch.begin() + chunkCount, chunkCount * sizeof(uint32_t)) == 0; -} - - -void TkFamilyImpl::reinitialize(const NvBlastFamily* newFamily, TkGroup* group) -{ - NVBLAST_ASSERT(newFamily); -#if NV_ENABLE_ASSERTS - NvBlastID id0 = NvBlastFamilyGetAssetID(m_familyLL, logLL); - NvBlastID id1 = NvBlastFamilyGetAssetID(newFamily, logLL); - NVBLAST_ASSERT(TkGUIDsEqual(&id0, &id1)); -#endif - NVBLAST_ASSERT(NvBlastFamilyGetSize(m_familyLL, logLL) == NvBlastFamilyGetSize(newFamily, logLL)); - - // alloc and init new family - const uint32_t blockSize = NvBlastFamilyGetSize(newFamily, logLL); - NvBlastFamily* newFamilyCopy = (NvBlastFamily*)NVBLAST_ALLOC_NAMED(blockSize, "TkFamilyImpl::reinitialize"); - memcpy(newFamilyCopy, newFamily, blockSize); - NvBlastFamilySetAsset(newFamilyCopy, m_asset->getAssetLL(), logLL); - - // get actors from new family - Array<NvBlastActor*>::type newLLActors(NvBlastFamilyGetActorCount(newFamilyCopy, logLL)); - uint32_t actorCount = NvBlastFamilyGetActors(newLLActors.begin(), newLLActors.size(), newFamilyCopy, logLL); - - // reset actor families to nullptr (we use it as a flag later) - for (TkActorImpl& actor : m_actors) - { - if (actor.isActive()) - { - actor.m_family = nullptr; - } - } - - // prepare split event with new actors - auto newActorsSplitEvent = getQueue().allocData<TkSplitEvent>(); - Array<TkActor*>::type children(actorCount); - children.resizeUninitialized(0); - newActorsSplitEvent->children = children.begin(); - - // scratch - Array<uint32_t>::type scratch(m_asset->getChunkCount()); - - for (uint32_t i = 0; i < actorCount; ++i) - { - NvBlastActor* newLLActor = newLLActors[i]; - uint32_t actorIndex = NvBlastActorGetIndex(newLLActor, logLL); - TkActorImpl& tkActor = *getActorByIndex(actorIndex); - - tkActor.m_family = this; - - if (!tkActor.isActive() || !areLLActorsEqual(newLLActor, tkActor.m_actorLL, scratch)) - { - if (tkActor.isActive()) - { - auto removeSplitEvent = getQueue().allocData<TkSplitEvent>(); - removeSplitEvent->parentData.family = this; - removeSplitEvent->numChildren = 0; - removeSplitEvent->parentData.userData = tkActor.userData; - removeSplitEvent->parentData.index = tkActor.getIndex(); - getQueue().addEvent(removeSplitEvent); - } - - tkActor.m_actorLL = newLLActor; - - // switch groups - TkGroupImpl* prevGroup = tkActor.m_group; - if (prevGroup != group) - { - if (prevGroup) - { - prevGroup->removeActor(tkActor); - } - if (group) - { - group->addActor(tkActor); - } - } - - children.pushBack(&tkActor); - } - else - { - tkActor.m_actorLL = newLLActor; - } - } - - // if m_family is still nullptr for an active actor -> remove it. It doesn't exist in new family. - for (TkActorImpl& tkActor : m_actors) - { - if (tkActor.isActive() && tkActor.m_family == nullptr) - { - tkActor.m_family = this; - if (tkActor.m_group) - { - tkActor.m_group->removeActor(tkActor); - } - - auto removeSplitEvent = getQueue().allocData<TkSplitEvent>(); - removeSplitEvent->parentData.family = this; - removeSplitEvent->numChildren = 0; - removeSplitEvent->parentData.userData = tkActor.userData; - removeSplitEvent->parentData.index = tkActor.getIndex(); - getQueue().addEvent(removeSplitEvent); - - tkActor.m_actorLL = nullptr; - } - } - - // add split event with all new actors - newActorsSplitEvent->parentData.family = this; - newActorsSplitEvent->parentData.userData = 0; - newActorsSplitEvent->parentData.index = invalidIndex<uint32_t>(); - newActorsSplitEvent->numChildren = children.size(); - if (newActorsSplitEvent->numChildren > 0) - { - getQueue().addEvent(newActorsSplitEvent); - } - - // replace family - NVBLAST_FREE(m_familyLL); - m_familyLL = newFamilyCopy; - - // update joints - for (TkActorImpl& tkActor : m_actors) - { - if (!tkActor.m_jointList.isEmpty()) - { - updateJoints(&tkActor); - } - } - - getQueue().dispatch(); -} - - -TkActorImpl* TkFamilyImpl::getActorByChunk(uint32_t chunk) -{ - if (chunk >= NvBlastAssetGetChunkCount(m_asset->getAssetLLInternal(), logLL)) - { - NVBLAST_LOG_WARNING("TkFamilyImpl::getActorByChunk: invalid chunk index. Returning NULL."); - return nullptr; - } - - NvBlastActor* actorLL = NvBlastFamilyGetChunkActor(m_familyLL, chunk, logLL); - return actorLL ? getActorByActorLL(actorLL) : nullptr; -} - - -void TkFamilyImpl::applyFractureInternal(const NvBlastFractureBuffers* commands) -{ - NvBlastSupportGraph graph = getAsset()->getGraph(); - - // apply bond fracture commands on relevant actors - { - TkActorImpl* currActor = nullptr; - NvBlastBondFractureData* bondFractures = commands->bondFractures; - uint32_t bondFracturesCount = 0; - - auto applyFracture = [&]() - { - if (bondFracturesCount > 0) - { - if (currActor != nullptr && currActor->isActive()) - { - NvBlastFractureBuffers newCommands; - newCommands.bondFractures = bondFractures; - newCommands.bondFractureCount = bondFracturesCount; - newCommands.chunkFractures = nullptr; - newCommands.chunkFractureCount = 0; - currActor->applyFracture(nullptr, &newCommands); - } - - bondFractures += bondFracturesCount; - bondFracturesCount = 0; - } - }; - - for (uint32_t i = 0; i < commands->bondFractureCount; ++i, ++bondFracturesCount) - { - const NvBlastBondFractureData& command = commands->bondFractures[i]; - uint32_t chunk0 = graph.chunkIndices[command.nodeIndex0]; - uint32_t chunk1 = graph.chunkIndices[command.nodeIndex1]; - TkActorImpl* actor0 = getActorByChunk(chunk0); - TkActorImpl* actor1 = getActorByChunk(chunk1); - if (actor0 != actor1) - { - // skipping this event, bond already broken - actor0 = nullptr; - } - if (actor0 != currActor) - { - applyFracture(); - currActor = actor0; - } - } - - if (bondFracturesCount > 0) - { - applyFracture(); - } - } - - // apply chunk fracture commands on relevant actors - { - TkActorImpl* currActor = nullptr; - NvBlastChunkFractureData* chunkFractures = commands->chunkFractures; - uint32_t chunkFracturesCount = 0; - - auto applyFracture = [&]() - { - if (chunkFracturesCount > 0) - { - if (currActor != nullptr && currActor->isActive()) - { - NvBlastFractureBuffers newCommands; - newCommands.bondFractures = nullptr; - newCommands.bondFractureCount = 0; - newCommands.chunkFractures = chunkFractures; - newCommands.chunkFractureCount = chunkFracturesCount; - currActor->applyFracture(nullptr, &newCommands); - } - - chunkFractures += chunkFracturesCount; - chunkFracturesCount = 0; - } - }; - - for (uint32_t i = 0; i < commands->chunkFractureCount; ++i, ++chunkFracturesCount) - { - const NvBlastChunkFractureData& command = commands->chunkFractures[i]; - TkActorImpl* actor = getActorByChunk(command.chunkIndex); - if (actor != currActor) - { - applyFracture(); - currActor = actor; - } - } - if (chunkFracturesCount > 0) - { - applyFracture(); - } - } -} - - -void TkFamilyImpl::updateJoints(TkActorImpl* actor, TkEventQueue* alternateQueue) -{ - // Copy joint array for safety against implementation of joint->setActor - TkJointImpl** joints = reinterpret_cast<TkJointImpl**>(NvBlastAlloca(sizeof(TkJointImpl*)*actor->getJointCountInternal())); - TkJointImpl** stop = joints + actor->getJointCountInternal(); - TkJointImpl** jointHandle = joints; - for (TkActorImpl::JointIt j(*actor); (bool)j; ++j) - { - *jointHandle++ = *j; - } - jointHandle = joints; - while (jointHandle < stop) - { - TkJointImpl* joint = *jointHandle++; - - const TkJointData& data = joint->getDataInternal(); - - TkActorImpl* actor0 = data.actors[0] != nullptr ? - static_cast<TkActorImpl&>(*data.actors[0]).getFamilyImpl().getActorByChunk(data.chunkIndices[0]) : nullptr; - - TkActorImpl* actor1 = data.actors[1] != nullptr ? - static_cast<TkActorImpl&>(*data.actors[1]).getFamilyImpl().getActorByChunk(data.chunkIndices[1]) : nullptr; - - joint->setActors(actor0, actor1, alternateQueue); - } -} - - -const TkAsset* TkFamilyImpl::getAsset() const -{ - return m_asset; -} - - -//////// Static functions //////// - -TkFamilyImpl* TkFamilyImpl::create(const TkAssetImpl* asset) -{ - TkFamilyImpl* family = NVBLAST_NEW(TkFamilyImpl); - family->m_asset = asset; - void* mem = NVBLAST_ALLOC_NAMED(NvBlastAssetGetFamilyMemorySize(asset->getAssetLL(), logLL), "TkFamilyImpl::create"); - family->m_familyLL = NvBlastAssetCreateFamily(mem, asset->getAssetLL(), logLL); - //family->addListener(*TkFrameworkImpl::get()); - - if (family->m_familyLL == nullptr) - { - NVBLAST_LOG_ERROR("TkFamilyImpl::create: low-level family could not be created."); - family->release(); - return nullptr; - } - - uint32_t maxActorCount = NvBlastFamilyGetMaxActorCount(family->m_familyLL, logLL); - family->m_actors.resize(maxActorCount); - - family->m_internalJointBuffer.resize(asset->getJointDescCountInternal() * sizeof(TkJointImpl), 0); - family->m_internalJointCount = asset->getJointDescCountInternal(); - - return family; -} - - -TkJointImpl** TkFamilyImpl::createExternalJointHandle(const NvBlastID& otherFamilyID, uint32_t chunkIndex0, uint32_t chunkIndex1) -{ - JointSet* jointSet; - const FamilyIDMap::Entry* jointSetIndexEntry = m_familyIDMap.find(otherFamilyID); - uint32_t otherFamilyIndex; - if (jointSetIndexEntry != nullptr) - { - otherFamilyIndex = jointSetIndexEntry->second; - jointSet = m_jointSets[otherFamilyIndex]; - } - else - { - jointSet = NVBLAST_NEW(JointSet); - NVBLAST_CHECK_ERROR(jointSet != nullptr, "TkFamilyImpl::addExternalJoint: failed to create joint set for other family ID.", return nullptr); - jointSet->m_familyID = otherFamilyID; - otherFamilyIndex = m_jointSets.size(); - m_familyIDMap[otherFamilyID] = otherFamilyIndex; - m_jointSets.pushBack(jointSet); - } - - const ExternalJointKey key(chunkIndex0, chunkIndex1); - const bool jointExists = jointSet->m_joints.find(key) != nullptr; - NVBLAST_CHECK_WARNING(!jointExists, "TkFamilyImpl::addExternalJoint: joint already added.", return nullptr); - - return &jointSet->m_joints[key]; -} - - -bool TkFamilyImpl::deleteExternalJointHandle(TkJointImpl*& joint, const NvBlastID& otherFamilyID, uint32_t chunkIndex0, uint32_t chunkIndex1) -{ - const FamilyIDMap::Entry* jointSetIndexEntry = m_familyIDMap.find(otherFamilyID); - if (jointSetIndexEntry != nullptr) - { - const uint32_t jointSetIndex = jointSetIndexEntry->second; - HashMap<ExternalJointKey, TkJointImpl*>::type::Entry e; - if (m_jointSets[jointSetIndex]->m_joints.erase(ExternalJointKey(chunkIndex0, chunkIndex1), e)) - { - // Delete the joint set if it is empty - if (m_jointSets[jointSetIndex]->m_joints.size() == 0) - { - NVBLAST_DELETE(m_jointSets[jointSetIndex], JointSet); - m_jointSets.replaceWithLast(jointSetIndex); - m_familyIDMap.erase(otherFamilyID); - if (jointSetIndex < m_jointSets.size()) - { - m_familyIDMap[m_jointSets[jointSetIndex]->m_familyID] = jointSetIndex; - } - } - - // Return value that was stored - joint = e.second; - return true; - } - } - - return false; -} - - -TkJointImpl* TkFamilyImpl::findExternalJoint(const TkFamilyImpl* otherFamily, ExternalJointKey key) const -{ - const FamilyIDMap::Entry* jointSetIndexEntry = m_familyIDMap.find(getFamilyID(otherFamily)); - if (jointSetIndexEntry != nullptr) - { - const HashMap<ExternalJointKey, TkJointImpl*>::type::Entry* e = m_jointSets[jointSetIndexEntry->second]->m_joints.find(key); - if (e != nullptr) - { - return e->second; - } - } - - return nullptr; -} - -} // namespace Blast -} // namespace Nv +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#include "NvBlastTkFrameworkImpl.h"
+#include "NvBlastTkFamilyImpl.h"
+#include "NvBlastTkGroupImpl.h"
+#include "NvBlastTkAssetImpl.h"
+#include "NvBlastTkActorImpl.h"
+#include "NvBlastTkJointImpl.h"
+
+#include "NvBlastIndexFns.h"
+#include "NvBlastMemory.h"
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+//////// Static data ////////
+
+NVBLASTTK_DEFINE_TYPE_IDENTIFIABLE(Family);
+
+
+//////// Member functions ////////
+
+TkFamilyImpl::TkFamilyImpl() : m_familyLL(nullptr), m_internalJointCount(0), m_asset(nullptr)
+{
+}
+
+
+TkFamilyImpl::TkFamilyImpl(const NvBlastID& id) : TkFamilyType(id), m_familyLL(nullptr), m_internalJointCount(0), m_asset(nullptr)
+{
+}
+
+
+TkFamilyImpl::~TkFamilyImpl()
+{
+ if (m_familyLL != nullptr)
+ {
+ uint32_t familyActorCount = NvBlastFamilyGetActorCount(m_familyLL, logLL);
+ if (familyActorCount != 0)
+ {
+ NVBLAST_LOG_WARNING("TkFamilyImpl::~TkFamilyImpl(): family actor count is not 0.");
+ }
+ NVBLAST_FREE(m_familyLL);
+ }
+}
+
+
+void TkFamilyImpl::release()
+{
+ for (TkActorImpl& actor : m_actors)
+ {
+ if (actor.isActive())
+ {
+ actor.release();
+ }
+ }
+
+ m_actors.clear();
+
+ NVBLAST_DELETE(this, TkFamilyImpl);
+}
+
+
+const NvBlastFamily* TkFamilyImpl::getFamilyLL() const
+{
+ return m_familyLL;
+}
+
+
+TkActorImpl* TkFamilyImpl::addActor(NvBlastActor* actorLL)
+{
+ TkActorImpl* actor = getActorByActorLL(actorLL);
+ NVBLAST_ASSERT(actor);
+ actor->m_actorLL = actorLL;
+ actor->m_family = this;
+ return actor;
+}
+
+
+void TkFamilyImpl::removeActor(TkActorImpl* actor)
+{
+ NVBLAST_ASSERT(actor != nullptr && actor->m_family == this);
+ //actor->m_family = nullptr;
+ actor->m_actorLL = nullptr;
+}
+
+
+uint32_t TkFamilyImpl::getActorCount() const
+{
+ return getActorCountInternal();
+}
+
+
+uint32_t TkFamilyImpl::getActors(TkActor** buffer, uint32_t bufferSize, uint32_t indexStart /*= 0*/) const
+{
+ uint32_t actorCount = getActorCount();
+ if (actorCount <= indexStart)
+ {
+ NVBLAST_LOG_WARNING("TkFamilyImpl::getActors: indexStart beyond end of actor list.");
+ return 0;
+ }
+
+ actorCount -= indexStart;
+ if (actorCount > bufferSize)
+ {
+ actorCount = static_cast<uint32_t>(bufferSize);
+ }
+
+ uint32_t index = 0;
+ for (const TkActorImpl& actor : m_actors)
+ {
+ if (actor.isActive())
+ {
+ if (index >= indexStart)
+ {
+ if ((index - indexStart) >= actorCount)
+ {
+ break;
+ }
+ else
+ {
+ *buffer++ = const_cast<TkActorImpl*>(&actor);
+ }
+ }
+ index++;
+ }
+ }
+
+ return actorCount;
+}
+
+
+NV_INLINE bool areLLActorsEqual(const NvBlastActor* actor0, const NvBlastActor* actor1, Array<uint32_t>::type& scratch)
+{
+ if (NvBlastActorGetGraphNodeCount(actor0, logLL) != NvBlastActorGetGraphNodeCount(actor1, logLL))
+ {
+ return false;
+ }
+
+ const uint32_t chunkCount = NvBlastActorGetVisibleChunkCount(actor0, logLL);
+ if (chunkCount != NvBlastActorGetVisibleChunkCount(actor1, logLL))
+ {
+ return false;
+ }
+
+ scratch.resize(chunkCount * 2);
+ NvBlastActorGetVisibleChunkIndices(scratch.begin(), chunkCount, actor0, logLL);
+ NvBlastActorGetVisibleChunkIndices(scratch.begin() + chunkCount, chunkCount, actor1, logLL);
+ return memcmp(scratch.begin(), scratch.begin() + chunkCount, chunkCount * sizeof(uint32_t)) == 0;
+}
+
+
+void TkFamilyImpl::reinitialize(const NvBlastFamily* newFamily, TkGroup* group)
+{
+ NVBLAST_ASSERT(newFamily);
+#if NV_ENABLE_ASSERTS
+ NvBlastID id0 = NvBlastFamilyGetAssetID(m_familyLL, logLL);
+ NvBlastID id1 = NvBlastFamilyGetAssetID(newFamily, logLL);
+ NVBLAST_ASSERT(TkGUIDsEqual(&id0, &id1));
+#endif
+ NVBLAST_ASSERT(NvBlastFamilyGetSize(m_familyLL, logLL) == NvBlastFamilyGetSize(newFamily, logLL));
+
+ // alloc and init new family
+ const uint32_t blockSize = NvBlastFamilyGetSize(newFamily, logLL);
+ NvBlastFamily* newFamilyCopy = (NvBlastFamily*)NVBLAST_ALLOC_NAMED(blockSize, "TkFamilyImpl::reinitialize");
+ memcpy(newFamilyCopy, newFamily, blockSize);
+ NvBlastFamilySetAsset(newFamilyCopy, m_asset->getAssetLL(), logLL);
+
+ // get actors from new family
+ Array<NvBlastActor*>::type newLLActors(NvBlastFamilyGetActorCount(newFamilyCopy, logLL));
+ uint32_t actorCount = NvBlastFamilyGetActors(newLLActors.begin(), newLLActors.size(), newFamilyCopy, logLL);
+
+ // reset actor families to nullptr (we use it as a flag later)
+ for (TkActorImpl& actor : m_actors)
+ {
+ if (actor.isActive())
+ {
+ actor.m_family = nullptr;
+ }
+ }
+
+ // prepare split event with new actors
+ auto newActorsSplitEvent = getQueue().allocData<TkSplitEvent>();
+ Array<TkActor*>::type children(actorCount);
+ children.resizeUninitialized(0);
+ newActorsSplitEvent->children = children.begin();
+
+ // scratch
+ Array<uint32_t>::type scratch(m_asset->getChunkCount());
+
+ for (uint32_t i = 0; i < actorCount; ++i)
+ {
+ NvBlastActor* newLLActor = newLLActors[i];
+ uint32_t actorIndex = NvBlastActorGetIndex(newLLActor, logLL);
+ TkActorImpl& tkActor = *getActorByIndex(actorIndex);
+
+ tkActor.m_family = this;
+
+ if (!tkActor.isActive() || !areLLActorsEqual(newLLActor, tkActor.m_actorLL, scratch))
+ {
+ if (tkActor.isActive())
+ {
+ auto removeSplitEvent = getQueue().allocData<TkSplitEvent>();
+ removeSplitEvent->parentData.family = this;
+ removeSplitEvent->numChildren = 0;
+ removeSplitEvent->parentData.userData = tkActor.userData;
+ removeSplitEvent->parentData.index = tkActor.getIndex();
+ getQueue().addEvent(removeSplitEvent);
+ }
+
+ tkActor.m_actorLL = newLLActor;
+
+ // switch groups
+ TkGroupImpl* prevGroup = tkActor.m_group;
+ if (prevGroup != group)
+ {
+ if (prevGroup)
+ {
+ prevGroup->removeActor(tkActor);
+ }
+ if (group)
+ {
+ group->addActor(tkActor);
+ }
+ }
+
+ children.pushBack(&tkActor);
+ }
+ else
+ {
+ tkActor.m_actorLL = newLLActor;
+ }
+ }
+
+ // if m_family is still nullptr for an active actor -> remove it. It doesn't exist in new family.
+ for (TkActorImpl& tkActor : m_actors)
+ {
+ if (tkActor.isActive() && tkActor.m_family == nullptr)
+ {
+ tkActor.m_family = this;
+ if (tkActor.m_group)
+ {
+ tkActor.m_group->removeActor(tkActor);
+ }
+
+ auto removeSplitEvent = getQueue().allocData<TkSplitEvent>();
+ removeSplitEvent->parentData.family = this;
+ removeSplitEvent->numChildren = 0;
+ removeSplitEvent->parentData.userData = tkActor.userData;
+ removeSplitEvent->parentData.index = tkActor.getIndex();
+ getQueue().addEvent(removeSplitEvent);
+
+ tkActor.m_actorLL = nullptr;
+ }
+ }
+
+ // add split event with all new actors
+ newActorsSplitEvent->parentData.family = this;
+ newActorsSplitEvent->parentData.userData = 0;
+ newActorsSplitEvent->parentData.index = invalidIndex<uint32_t>();
+ newActorsSplitEvent->numChildren = children.size();
+ if (newActorsSplitEvent->numChildren > 0)
+ {
+ getQueue().addEvent(newActorsSplitEvent);
+ }
+
+ // replace family
+ NVBLAST_FREE(m_familyLL);
+ m_familyLL = newFamilyCopy;
+
+ // update joints
+ for (TkActorImpl& tkActor : m_actors)
+ {
+ if (!tkActor.m_jointList.isEmpty())
+ {
+ updateJoints(&tkActor);
+ }
+ }
+
+ getQueue().dispatch();
+}
+
+
+TkActorImpl* TkFamilyImpl::getActorByChunk(uint32_t chunk)
+{
+ if (chunk >= NvBlastAssetGetChunkCount(m_asset->getAssetLLInternal(), logLL))
+ {
+ NVBLAST_LOG_WARNING("TkFamilyImpl::getActorByChunk: invalid chunk index. Returning NULL.");
+ return nullptr;
+ }
+
+ NvBlastActor* actorLL = NvBlastFamilyGetChunkActor(m_familyLL, chunk, logLL);
+ return actorLL ? getActorByActorLL(actorLL) : nullptr;
+}
+
+
+void TkFamilyImpl::applyFractureInternal(const NvBlastFractureBuffers* commands)
+{
+ NvBlastSupportGraph graph = getAsset()->getGraph();
+
+ // apply bond fracture commands on relevant actors
+ {
+ TkActorImpl* currActor = nullptr;
+ NvBlastBondFractureData* bondFractures = commands->bondFractures;
+ uint32_t bondFracturesCount = 0;
+
+ auto applyFracture = [&]()
+ {
+ if (bondFracturesCount > 0)
+ {
+ if (currActor != nullptr && currActor->isActive())
+ {
+ NvBlastFractureBuffers newCommands;
+ newCommands.bondFractures = bondFractures;
+ newCommands.bondFractureCount = bondFracturesCount;
+ newCommands.chunkFractures = nullptr;
+ newCommands.chunkFractureCount = 0;
+ currActor->applyFracture(nullptr, &newCommands);
+ }
+
+ bondFractures += bondFracturesCount;
+ bondFracturesCount = 0;
+ }
+ };
+
+ for (uint32_t i = 0; i < commands->bondFractureCount; ++i, ++bondFracturesCount)
+ {
+ const NvBlastBondFractureData& command = commands->bondFractures[i];
+ uint32_t chunk0 = graph.chunkIndices[command.nodeIndex0];
+ uint32_t chunk1 = graph.chunkIndices[command.nodeIndex1];
+ TkActorImpl* actor0 = getActorByChunk(chunk0);
+ TkActorImpl* actor1 = getActorByChunk(chunk1);
+ if (actor0 != actor1)
+ {
+ // skipping this event, bond already broken
+ actor0 = nullptr;
+ }
+ if (actor0 != currActor)
+ {
+ applyFracture();
+ currActor = actor0;
+ }
+ }
+
+ if (bondFracturesCount > 0)
+ {
+ applyFracture();
+ }
+ }
+
+ // apply chunk fracture commands on relevant actors
+ {
+ TkActorImpl* currActor = nullptr;
+ NvBlastChunkFractureData* chunkFractures = commands->chunkFractures;
+ uint32_t chunkFracturesCount = 0;
+
+ auto applyFracture = [&]()
+ {
+ if (chunkFracturesCount > 0)
+ {
+ if (currActor != nullptr && currActor->isActive())
+ {
+ NvBlastFractureBuffers newCommands;
+ newCommands.bondFractures = nullptr;
+ newCommands.bondFractureCount = 0;
+ newCommands.chunkFractures = chunkFractures;
+ newCommands.chunkFractureCount = chunkFracturesCount;
+ currActor->applyFracture(nullptr, &newCommands);
+ }
+
+ chunkFractures += chunkFracturesCount;
+ chunkFracturesCount = 0;
+ }
+ };
+
+ for (uint32_t i = 0; i < commands->chunkFractureCount; ++i, ++chunkFracturesCount)
+ {
+ const NvBlastChunkFractureData& command = commands->chunkFractures[i];
+ TkActorImpl* actor = getActorByChunk(command.chunkIndex);
+ if (actor != currActor)
+ {
+ applyFracture();
+ currActor = actor;
+ }
+ }
+ if (chunkFracturesCount > 0)
+ {
+ applyFracture();
+ }
+ }
+}
+
+
+void TkFamilyImpl::updateJoints(TkActorImpl* actor, TkEventQueue* alternateQueue)
+{
+ // Copy joint array for safety against implementation of joint->setActor
+ TkJointImpl** joints = reinterpret_cast<TkJointImpl**>(NvBlastAlloca(sizeof(TkJointImpl*)*actor->getJointCountInternal()));
+ TkJointImpl** stop = joints + actor->getJointCountInternal();
+ TkJointImpl** jointHandle = joints;
+ for (TkActorImpl::JointIt j(*actor); (bool)j; ++j)
+ {
+ *jointHandle++ = *j;
+ }
+ jointHandle = joints;
+ while (jointHandle < stop)
+ {
+ TkJointImpl* joint = *jointHandle++;
+
+ const TkJointData& data = joint->getDataInternal();
+
+ TkActorImpl* actor0 = data.actors[0] != nullptr ?
+ static_cast<TkActorImpl&>(*data.actors[0]).getFamilyImpl().getActorByChunk(data.chunkIndices[0]) : nullptr;
+
+ TkActorImpl* actor1 = data.actors[1] != nullptr ?
+ static_cast<TkActorImpl&>(*data.actors[1]).getFamilyImpl().getActorByChunk(data.chunkIndices[1]) : nullptr;
+
+ joint->setActors(actor0, actor1, alternateQueue);
+ }
+}
+
+
+const TkAsset* TkFamilyImpl::getAsset() const
+{
+ return m_asset;
+}
+
+
+//////// Static functions ////////
+
+TkFamilyImpl* TkFamilyImpl::create(const TkAssetImpl* asset)
+{
+ TkFamilyImpl* family = NVBLAST_NEW(TkFamilyImpl);
+ family->m_asset = asset;
+ void* mem = NVBLAST_ALLOC_NAMED(NvBlastAssetGetFamilyMemorySize(asset->getAssetLL(), logLL), "TkFamilyImpl::create");
+ family->m_familyLL = NvBlastAssetCreateFamily(mem, asset->getAssetLL(), logLL);
+ //family->addListener(*TkFrameworkImpl::get());
+
+ if (family->m_familyLL == nullptr)
+ {
+ NVBLAST_LOG_ERROR("TkFamilyImpl::create: low-level family could not be created.");
+ family->release();
+ return nullptr;
+ }
+
+ uint32_t maxActorCount = NvBlastFamilyGetMaxActorCount(family->m_familyLL, logLL);
+ family->m_actors.resize(maxActorCount);
+
+ family->m_internalJointBuffer.resize(asset->getJointDescCountInternal() * sizeof(TkJointImpl), 0);
+ family->m_internalJointCount = asset->getJointDescCountInternal();
+
+ return family;
+}
+
+
+TkJointImpl** TkFamilyImpl::createExternalJointHandle(const NvBlastID& otherFamilyID, uint32_t chunkIndex0, uint32_t chunkIndex1)
+{
+ JointSet* jointSet;
+ const FamilyIDMap::Entry* jointSetIndexEntry = m_familyIDMap.find(otherFamilyID);
+ uint32_t otherFamilyIndex;
+ if (jointSetIndexEntry != nullptr)
+ {
+ otherFamilyIndex = jointSetIndexEntry->second;
+ jointSet = m_jointSets[otherFamilyIndex];
+ }
+ else
+ {
+ jointSet = NVBLAST_NEW(JointSet);
+ NVBLAST_CHECK_ERROR(jointSet != nullptr, "TkFamilyImpl::addExternalJoint: failed to create joint set for other family ID.", return nullptr);
+ jointSet->m_familyID = otherFamilyID;
+ otherFamilyIndex = m_jointSets.size();
+ m_familyIDMap[otherFamilyID] = otherFamilyIndex;
+ m_jointSets.pushBack(jointSet);
+ }
+
+ const ExternalJointKey key(chunkIndex0, chunkIndex1);
+ const bool jointExists = jointSet->m_joints.find(key) != nullptr;
+ NVBLAST_CHECK_WARNING(!jointExists, "TkFamilyImpl::addExternalJoint: joint already added.", return nullptr);
+
+ return &jointSet->m_joints[key];
+}
+
+
+bool TkFamilyImpl::deleteExternalJointHandle(TkJointImpl*& joint, const NvBlastID& otherFamilyID, uint32_t chunkIndex0, uint32_t chunkIndex1)
+{
+ const FamilyIDMap::Entry* jointSetIndexEntry = m_familyIDMap.find(otherFamilyID);
+ if (jointSetIndexEntry != nullptr)
+ {
+ const uint32_t jointSetIndex = jointSetIndexEntry->second;
+ HashMap<ExternalJointKey, TkJointImpl*>::type::Entry e;
+ if (m_jointSets[jointSetIndex]->m_joints.erase(ExternalJointKey(chunkIndex0, chunkIndex1), e))
+ {
+ // Delete the joint set if it is empty
+ if (m_jointSets[jointSetIndex]->m_joints.size() == 0)
+ {
+ NVBLAST_DELETE(m_jointSets[jointSetIndex], JointSet);
+ m_jointSets.replaceWithLast(jointSetIndex);
+ m_familyIDMap.erase(otherFamilyID);
+ if (jointSetIndex < m_jointSets.size())
+ {
+ m_familyIDMap[m_jointSets[jointSetIndex]->m_familyID] = jointSetIndex;
+ }
+ }
+
+ // Return value that was stored
+ joint = e.second;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+TkJointImpl* TkFamilyImpl::findExternalJoint(const TkFamilyImpl* otherFamily, ExternalJointKey key) const
+{
+ const FamilyIDMap::Entry* jointSetIndexEntry = m_familyIDMap.find(getFamilyID(otherFamily));
+ if (jointSetIndexEntry != nullptr)
+ {
+ const HashMap<ExternalJointKey, TkJointImpl*>::type::Entry* e = m_jointSets[jointSetIndexEntry->second]->m_joints.find(key);
+ if (e != nullptr)
+ {
+ return e->second;
+ }
+ }
+
+ return nullptr;
+}
+
+} // namespace Blast
+} // namespace Nv
diff --git a/sdk/toolkit/source/NvBlastTkFamilyImpl.h b/sdk/toolkit/source/NvBlastTkFamilyImpl.h index 7eec486..7a33d10 100644..100755 --- a/sdk/toolkit/source/NvBlastTkFamilyImpl.h +++ b/sdk/toolkit/source/NvBlastTkFamilyImpl.h @@ -1,229 +1,229 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#ifndef NVBLASTTKFAMILYIMPL_H -#define NVBLASTTKFAMILYIMPL_H - -#include "NvBlastTkCommon.h" - -#include "NvBlastTkFamily.h" -#include "NvBlastTkTypeImpl.h" -#include "NvBlastTkActorImpl.h" - -#include "NvBlastTkEventQueue.h" -#include "NvBlastHashSet.h" -#include "NvBlastHashMap.h" - -#include "NvBlast.h" -#include "NvBlastAssert.h" -#include "NvBlastDLink.h" - - -// Forward declarations -struct NvBlastFamily; - -namespace Nv -{ -namespace Blast -{ - -// Forward declarations -class TkGroupImpl; -class TkAssetImpl; - - -NVBLASTTK_IMPL_DECLARE(Family) -{ -public: - TkFamilyImpl(); - TkFamilyImpl(const NvBlastID& id); - ~TkFamilyImpl(); - - NVBLASTTK_IMPL_DEFINE_IDENTIFIABLE('A', 'C', 'T', 'F'); - - // Begin TkFamily - virtual const NvBlastFamily* getFamilyLL() const override; - - virtual uint32_t getActorCount() const override; - - virtual uint32_t getActors(TkActor** buffer, uint32_t bufferSize, uint32_t indexStart = 0) const override; - - virtual void addListener(TkEventListener& l) override { m_queue.addListener(l); } - - virtual void removeListener(TkEventListener& l) override { m_queue.removeListener(l); } - - virtual void applyFracture(const NvBlastFractureBuffers* commands) override { applyFractureInternal(commands); } - - virtual const TkAsset* getAsset() const override; - - virtual void reinitialize(const NvBlastFamily* newFamily, TkGroup* group) override; - // End TkFamily - - // Public methods - static TkFamilyImpl* create(const TkAssetImpl* asset); - - const TkAssetImpl* getAssetImpl() const; - - NvBlastFamily* getFamilyLLInternal() const; - - uint32_t getActorCountInternal() const; - - TkActorImpl* addActor(NvBlastActor* actorLL); - - void applyFractureInternal(const NvBlastFractureBuffers* commands); - - void removeActor(TkActorImpl* actorLL); - - TkEventQueue& getQueue() { return m_queue; } - - TkActorImpl* getActorByActorLL(const NvBlastActor* actorLL); - - void updateJoints(TkActorImpl* actor, TkEventQueue* alternateQueue = nullptr); - - Array<TkActorImpl>::type& getActorsInternal(); - - uint32_t getInternalJointCount() const; - - TkJointImpl* getInternalJoints() const; - - TkJointImpl** createExternalJointHandle(const NvBlastID& otherFamilyID, uint32_t chunkIndex0, uint32_t chunkIndex1); - - bool deleteExternalJointHandle(TkJointImpl*& joint, const NvBlastID& otherFamilyID, uint32_t chunkIndex0, uint32_t chunkIndex1); - - void releaseJoint(TkJointImpl& joint); - - TkActorImpl* getActorByChunk(uint32_t chunkIndex); - - typedef physx::shdfnd::Pair<uint32_t, uint32_t> ExternalJointKey; //!< The chunk indices within the TkFamily objects joined by the joint. These chunks will be support chunks. - - TkJointImpl* findExternalJoint(const TkFamilyImpl* otherFamily, ExternalJointKey key) const; - -private: - TkActorImpl* getActorByIndex(uint32_t index); - - struct JointSet - { - NvBlastID m_familyID; - HashMap<ExternalJointKey, TkJointImpl*>::type m_joints; - }; - - typedef HashMap<NvBlastID, uint32_t>::type FamilyIDMap; - - NvBlastFamily* m_familyLL; - Array<TkActorImpl>::type m_actors; - uint32_t m_internalJointCount; - Array<uint8_t>::type m_internalJointBuffer; - Array<JointSet*>::type m_jointSets; - FamilyIDMap m_familyIDMap; - const TkAssetImpl* m_asset; - - TkEventQueue m_queue; -}; - - -//////// TkFamilyImpl inline methods //////// - -NV_INLINE const TkAssetImpl* TkFamilyImpl::getAssetImpl() const -{ - return m_asset; -} - - -NV_INLINE NvBlastFamily* TkFamilyImpl::getFamilyLLInternal() const -{ - return m_familyLL; -} - - -NV_INLINE uint32_t TkFamilyImpl::getActorCountInternal() const -{ - NVBLAST_ASSERT(m_familyLL != nullptr); - - return NvBlastFamilyGetActorCount(m_familyLL, logLL); -} - - -NV_INLINE TkActorImpl* TkFamilyImpl::getActorByIndex(uint32_t index) -{ - NVBLAST_ASSERT(index < m_actors.size()); - return &m_actors[index]; -} - - -NV_INLINE TkActorImpl* TkFamilyImpl::getActorByActorLL(const NvBlastActor* actorLL) -{ - uint32_t index = NvBlastActorGetIndex(actorLL, logLL); - return getActorByIndex(index); -} - - -NV_INLINE Array<TkActorImpl>::type& TkFamilyImpl::getActorsInternal() -{ - return m_actors; -} - - -NV_INLINE uint32_t TkFamilyImpl::getInternalJointCount() const -{ - return m_internalJointCount; -} - - -NV_INLINE TkJointImpl* TkFamilyImpl::getInternalJoints() const -{ - return const_cast<TkJointImpl*>(reinterpret_cast<const TkJointImpl*>(m_internalJointBuffer.begin())); -} - - -NV_INLINE void TkFamilyImpl::releaseJoint(TkJointImpl& joint) -{ - NVBLAST_ASSERT(joint.m_owner == this); - NVBLAST_ASSERT(&joint >= getInternalJoints() && &joint < getInternalJoints() + getInternalJointCount() * sizeof(TkJointImpl)); - - joint.~TkJointImpl(); - joint.m_owner = nullptr; -} - - -//////// Inline global functions //////// - -NV_INLINE const NvBlastID& getFamilyID(const TkActor* actor) -{ - return actor != nullptr ? static_cast<const TkActorImpl*>(actor)->getFamilyImpl().getIDInternal() : *reinterpret_cast<const NvBlastID*>("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); -} - -NV_INLINE const NvBlastID& getFamilyID(const TkFamilyImpl* family) -{ - return family != nullptr ? family->getIDInternal() : *reinterpret_cast<const NvBlastID*>("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); -} - -} // namespace Blast -} // namespace Nv - - -#endif // ifndef NVBLASTTKFAMILYIMPL_H +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#ifndef NVBLASTTKFAMILYIMPL_H
+#define NVBLASTTKFAMILYIMPL_H
+
+#include "NvBlastTkCommon.h"
+
+#include "NvBlastTkFamily.h"
+#include "NvBlastTkTypeImpl.h"
+#include "NvBlastTkActorImpl.h"
+
+#include "NvBlastTkEventQueue.h"
+#include "NvBlastHashSet.h"
+#include "NvBlastHashMap.h"
+
+#include "NvBlast.h"
+#include "NvBlastAssert.h"
+#include "NvBlastDLink.h"
+
+
+// Forward declarations
+struct NvBlastFamily;
+
+namespace Nv
+{
+namespace Blast
+{
+
+// Forward declarations
+class TkGroupImpl;
+class TkAssetImpl;
+
+
+NVBLASTTK_IMPL_DECLARE(Family)
+{
+public:
+ TkFamilyImpl();
+ TkFamilyImpl(const NvBlastID& id);
+ ~TkFamilyImpl();
+
+ NVBLASTTK_IMPL_DEFINE_IDENTIFIABLE('A', 'C', 'T', 'F');
+
+ // Begin TkFamily
+ virtual const NvBlastFamily* getFamilyLL() const override;
+
+ virtual uint32_t getActorCount() const override;
+
+ virtual uint32_t getActors(TkActor** buffer, uint32_t bufferSize, uint32_t indexStart = 0) const override;
+
+ virtual void addListener(TkEventListener& l) override { m_queue.addListener(l); }
+
+ virtual void removeListener(TkEventListener& l) override { m_queue.removeListener(l); }
+
+ virtual void applyFracture(const NvBlastFractureBuffers* commands) override { applyFractureInternal(commands); }
+
+ virtual const TkAsset* getAsset() const override;
+
+ virtual void reinitialize(const NvBlastFamily* newFamily, TkGroup* group) override;
+ // End TkFamily
+
+ // Public methods
+ static TkFamilyImpl* create(const TkAssetImpl* asset);
+
+ const TkAssetImpl* getAssetImpl() const;
+
+ NvBlastFamily* getFamilyLLInternal() const;
+
+ uint32_t getActorCountInternal() const;
+
+ TkActorImpl* addActor(NvBlastActor* actorLL);
+
+ void applyFractureInternal(const NvBlastFractureBuffers* commands);
+
+ void removeActor(TkActorImpl* actorLL);
+
+ TkEventQueue& getQueue() { return m_queue; }
+
+ TkActorImpl* getActorByActorLL(const NvBlastActor* actorLL);
+
+ void updateJoints(TkActorImpl* actor, TkEventQueue* alternateQueue = nullptr);
+
+ Array<TkActorImpl>::type& getActorsInternal();
+
+ uint32_t getInternalJointCount() const;
+
+ TkJointImpl* getInternalJoints() const;
+
+ TkJointImpl** createExternalJointHandle(const NvBlastID& otherFamilyID, uint32_t chunkIndex0, uint32_t chunkIndex1);
+
+ bool deleteExternalJointHandle(TkJointImpl*& joint, const NvBlastID& otherFamilyID, uint32_t chunkIndex0, uint32_t chunkIndex1);
+
+ void releaseJoint(TkJointImpl& joint);
+
+ TkActorImpl* getActorByChunk(uint32_t chunkIndex);
+
+ typedef physx::shdfnd::Pair<uint32_t, uint32_t> ExternalJointKey; //!< The chunk indices within the TkFamily objects joined by the joint. These chunks will be support chunks.
+
+ TkJointImpl* findExternalJoint(const TkFamilyImpl* otherFamily, ExternalJointKey key) const;
+
+private:
+ TkActorImpl* getActorByIndex(uint32_t index);
+
+ struct JointSet
+ {
+ NvBlastID m_familyID;
+ HashMap<ExternalJointKey, TkJointImpl*>::type m_joints;
+ };
+
+ typedef HashMap<NvBlastID, uint32_t>::type FamilyIDMap;
+
+ NvBlastFamily* m_familyLL;
+ Array<TkActorImpl>::type m_actors;
+ uint32_t m_internalJointCount;
+ Array<uint8_t>::type m_internalJointBuffer;
+ Array<JointSet*>::type m_jointSets;
+ FamilyIDMap m_familyIDMap;
+ const TkAssetImpl* m_asset;
+
+ TkEventQueue m_queue;
+};
+
+
+//////// TkFamilyImpl inline methods ////////
+
+NV_INLINE const TkAssetImpl* TkFamilyImpl::getAssetImpl() const
+{
+ return m_asset;
+}
+
+
+NV_INLINE NvBlastFamily* TkFamilyImpl::getFamilyLLInternal() const
+{
+ return m_familyLL;
+}
+
+
+NV_INLINE uint32_t TkFamilyImpl::getActorCountInternal() const
+{
+ NVBLAST_ASSERT(m_familyLL != nullptr);
+
+ return NvBlastFamilyGetActorCount(m_familyLL, logLL);
+}
+
+
+NV_INLINE TkActorImpl* TkFamilyImpl::getActorByIndex(uint32_t index)
+{
+ NVBLAST_ASSERT(index < m_actors.size());
+ return &m_actors[index];
+}
+
+
+NV_INLINE TkActorImpl* TkFamilyImpl::getActorByActorLL(const NvBlastActor* actorLL)
+{
+ uint32_t index = NvBlastActorGetIndex(actorLL, logLL);
+ return getActorByIndex(index);
+}
+
+
+NV_INLINE Array<TkActorImpl>::type& TkFamilyImpl::getActorsInternal()
+{
+ return m_actors;
+}
+
+
+NV_INLINE uint32_t TkFamilyImpl::getInternalJointCount() const
+{
+ return m_internalJointCount;
+}
+
+
+NV_INLINE TkJointImpl* TkFamilyImpl::getInternalJoints() const
+{
+ return const_cast<TkJointImpl*>(reinterpret_cast<const TkJointImpl*>(m_internalJointBuffer.begin()));
+}
+
+
+NV_INLINE void TkFamilyImpl::releaseJoint(TkJointImpl& joint)
+{
+ NVBLAST_ASSERT(joint.m_owner == this);
+ NVBLAST_ASSERT(&joint >= getInternalJoints() && &joint < getInternalJoints() + getInternalJointCount() * sizeof(TkJointImpl));
+
+ joint.~TkJointImpl();
+ joint.m_owner = nullptr;
+}
+
+
+//////// Inline global functions ////////
+
+NV_INLINE const NvBlastID& getFamilyID(const TkActor* actor)
+{
+ return actor != nullptr ? static_cast<const TkActorImpl*>(actor)->getFamilyImpl().getIDInternal() : *reinterpret_cast<const NvBlastID*>("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
+}
+
+NV_INLINE const NvBlastID& getFamilyID(const TkFamilyImpl* family)
+{
+ return family != nullptr ? family->getIDInternal() : *reinterpret_cast<const NvBlastID*>("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
+}
+
+} // namespace Blast
+} // namespace Nv
+
+
+#endif // ifndef NVBLASTTKFAMILYIMPL_H
diff --git a/sdk/toolkit/source/NvBlastTkFrameworkImpl.cpp b/sdk/toolkit/source/NvBlastTkFrameworkImpl.cpp index 1d88701..65e1d45 100644..100755 --- a/sdk/toolkit/source/NvBlastTkFrameworkImpl.cpp +++ b/sdk/toolkit/source/NvBlastTkFrameworkImpl.cpp @@ -1,463 +1,463 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#include "NvBlastAssert.h" - -#include "NvBlastTkFrameworkImpl.h" -#include "NvBlastTkAssetImpl.h" -#include "NvBlastTkFamilyImpl.h" -#include "NvBlastTkGroupImpl.h" -#include "NvBlastTkActorImpl.h" -#include "NvBlastTkJointImpl.h" -#include "NvBlastTkTypeImpl.h" - -#include "NvBlastGlobals.h" - -#include <algorithm> - - -using namespace physx; -using namespace physx::shdfnd; - - -NV_INLINE bool operator < (const NvBlastID& id1, const NvBlastID& id2) -{ - return memcmp(&id1, &id2, sizeof(NvBlastID)) < 0; -} - - -namespace Nv -{ -namespace Blast -{ - -//////// Local definitions //////// - -// Map type ID to static type data -#define NVBLASTTK_REGISTER_TYPE(_name) \ - if (!Tk##_name##Impl::s_type.indexIsValid()) \ - { \ - Tk##_name##Impl::s_type.setIndex(TkTypeIndex::_name); \ - } \ - m_types[TkTypeIndex::_name] = &Tk##_name##Impl::s_type; \ - m_typeIDToIndex[Tk##_name##Impl::s_type.getID()] = TkTypeIndex::_name - - -#define NVBLASTTK_RELEASE_TYPE(_name) \ - { \ - TkTypeImpl& type = Tk##_name##Impl::s_type; \ - auto& toRelease = m_objects[type.getIndex()]; \ - for (TkObject* obj : toRelease) \ - { \ - obj->release(); \ - } \ - } - - -//////// TkFrameworkImpl static variables //////// - -TkFrameworkImpl* TkFrameworkImpl::s_framework = nullptr; - - -//////// TkFrameworkImpl static function //////// - -TkFrameworkImpl* TkFrameworkImpl::get() -{ - return s_framework; -} - - -bool TkFrameworkImpl::set(TkFrameworkImpl* framework) -{ - if (s_framework != nullptr) - { - if (framework != nullptr) - { - NVBLAST_LOG_ERROR("TkFrameworkImpl::set: framework already set. Pass NULL to this function to destroy framework."); - return false; - } - - NVBLAST_DELETE(s_framework, TkFrameworkImpl); - } - - s_framework = framework; - - return true; -} - - -//////// TkFrameworkImpl methods //////// - -TkFrameworkImpl::TkFrameworkImpl() - : TkFramework() -{ - // Register types - m_types.resize(TkTypeIndex::TypeCount); - m_objects.resize(TkTypeIndex::TypeCount); - NVBLASTTK_REGISTER_TYPE(Asset); - NVBLASTTK_REGISTER_TYPE(Family); - NVBLASTTK_REGISTER_TYPE(Group); -} - - -TkFrameworkImpl::~TkFrameworkImpl() -{ -} - - -void TkFrameworkImpl::release() -{ - // Special release of joints, which are not TkIdentifiable: - Array<TkJointImpl*>::type joints; // Since the EraseIterator is not exposed - joints.reserve(m_joints.size()); - for (auto j = m_joints.getIterator(); !j.done(); ++j) - { - joints.pushBack(*j); - } - for (uint32_t i = 0; i < joints.size(); ++i) - { - joints[i]->release(); - } - NVBLAST_ASSERT(m_joints.size() == 0); - joints.reset(); // Since we will be deleting the allocator - - NVBLASTTK_RELEASE_TYPE(Group); - NVBLASTTK_RELEASE_TYPE(Asset); - set(nullptr); -} - - -const TkType* TkFrameworkImpl::getType(TkTypeIndex::Enum typeIndex) const -{ - if (typeIndex < 0 || typeIndex >= TkTypeIndex::TypeCount) - { - NVBLAST_LOG_WARNING("TkFrameworkImpl::getType: invalid typeIndex."); - return nullptr; - } - - return m_types[typeIndex]; -} - - -TkIdentifiable* TkFrameworkImpl::findObjectByID(const NvBlastID& id) const -{ - TkIdentifiable* object = findObjectByIDInternal(id); - - if (object == nullptr) - { - NVBLAST_LOG_WARNING("TkFrameworkImpl::findObjectByID: object not found."); - } - - return object; -} - - -uint32_t TkFrameworkImpl::getObjectCount(const TkType& type) const -{ - const uint32_t index = static_cast<const TkTypeImpl&>(type).getIndex(); - - if (index >= m_objects.size()) - { - NVBLAST_LOG_ERROR("TkFrameworkImpl::getObjectCount: BlastTk object type unrecognized."); - return 0; - - } - - return m_objects[index].size(); -} - - -uint32_t TkFrameworkImpl::getObjects(TkIdentifiable** buffer, uint32_t bufferSize, const TkType& type, uint32_t indexStart /* = 0 */) const -{ - const uint32_t index = static_cast<const TkTypeImpl&>(type).getIndex(); - - if (index >= m_objects.size()) - { - NVBLAST_LOG_ERROR("TkFrameworkImpl::getObjectCount: BlastTk object type unrecognized."); - return 0; - } - - const auto& objectArray = m_objects[index]; - - uint32_t objectCount = objectArray.size(); - if (objectCount <= indexStart) - { - NVBLAST_LOG_WARNING("TkFrameworkImpl::getObjects: indexStart beyond end of object list."); - return 0; - } - - objectCount -= indexStart; - if (objectCount > bufferSize) - { - objectCount = bufferSize; - } - - memcpy(buffer, objectArray.begin() + indexStart, objectCount * sizeof(TkObject*)); - - return objectCount; -} - - -bool TkFrameworkImpl::reorderAssetDescChunks(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount, NvBlastBondDesc* bondDescs, uint32_t bondCount, uint32_t* chunkReorderMap /*= nullptr*/, bool keepBondNormalChunkOrder /*= false*/) const -{ - uint32_t* map = chunkReorderMap != nullptr ? chunkReorderMap : static_cast<uint32_t*>(NVBLAST_ALLOC_NAMED(chunkCount * sizeof(uint32_t), "reorderAssetDescChunks:chunkReorderMap")); - void* scratch = NVBLAST_ALLOC_NAMED(chunkCount * sizeof(NvBlastChunkDesc), "reorderAssetDescChunks:scratch"); - const bool result = NvBlastReorderAssetDescChunks(chunkDescs, chunkCount, bondDescs, bondCount, map, keepBondNormalChunkOrder, scratch, logLL); - NVBLAST_FREE(scratch); - if (chunkReorderMap == nullptr) - { - NVBLAST_FREE(map); - } - return result; -} - - -bool TkFrameworkImpl::ensureAssetExactSupportCoverage(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount) const -{ - void* scratch = NVBLAST_ALLOC_NAMED(chunkCount, "ensureAssetExactSupportCoverage:scratch"); - const bool result = NvBlastEnsureAssetExactSupportCoverage(chunkDescs, chunkCount, scratch, logLL); - NVBLAST_FREE(scratch); - return result; -} - - -TkAsset* TkFrameworkImpl::createAsset(const TkAssetDesc& desc) -{ - TkAssetImpl* asset = TkAssetImpl::create(desc); - if (asset == nullptr) - { - NVBLAST_LOG_ERROR("TkFrameworkImpl::createAsset: failed to create asset."); - } - - return asset; -} - - -TkAsset* TkFrameworkImpl::createAsset(const NvBlastAsset* assetLL, Nv::Blast::TkAssetJointDesc* jointDescs, uint32_t jointDescCount, bool ownsAsset) -{ - TkAssetImpl* asset = TkAssetImpl::create(assetLL, jointDescs, jointDescCount, ownsAsset); - if (asset == nullptr) - { - NVBLAST_LOG_ERROR("TkFrameworkImpl::createAsset: failed to create asset."); - } - - return asset; -} - - -TkGroup* TkFrameworkImpl::createGroup(const TkGroupDesc& desc) -{ - TkGroupImpl* group = TkGroupImpl::create(desc); - if (group == nullptr) - { - NVBLAST_LOG_ERROR("TkFrameworkImpl::createGroup: failed to create group."); - } - - return group; -} - - -TkActor* TkFrameworkImpl::createActor(const TkActorDesc& desc) -{ - TkActor* actor = TkActorImpl::create(desc); - if (actor == nullptr) - { - NVBLAST_LOG_ERROR("TkFrameworkImpl::createActor: failed to create actor."); - } - - return actor; -} - - -TkJoint* TkFrameworkImpl::createJoint(const TkJointDesc& desc) -{ - TkJointImpl** handle0 = nullptr; - TkJointImpl** handle1 = nullptr; - - TkFamilyImpl* family0 = static_cast<TkFamilyImpl*>(desc.families[0]); - TkFamilyImpl* family1 = static_cast<TkFamilyImpl*>(desc.families[1]); - - NVBLAST_CHECK_ERROR(family0 != nullptr || family1 != nullptr, "TkFrameworkImpl::createJoint: at least one family in the TkJointDesc must be valid.", return nullptr); - - NVBLAST_CHECK_ERROR(family0 == nullptr || desc.chunkIndices[0] < family0->getAssetImpl()->getChunkCount(), "TkFrameworkImpl::createJoint: desc.chunkIndices[0] is invalid.", return nullptr); - NVBLAST_CHECK_ERROR(family1 == nullptr || desc.chunkIndices[1] < family1->getAssetImpl()->getChunkCount(), "TkFrameworkImpl::createJoint: desc.chunkIndices[1] is invalid.", return nullptr); - - const bool actorsAreTheSame = family0 == family1 && family0->getActorByChunk(desc.chunkIndices[0]) == family1->getActorByChunk(desc.chunkIndices[1]); - NVBLAST_CHECK_ERROR(!actorsAreTheSame, "TkFrameworkImpl::createJoint: the chunks listed in the TkJointDesc must be in different actors.", return nullptr); - - if (family0 != nullptr) - { - const bool isSupportChunk = !isInvalidIndex(NvBlastAssetGetChunkToGraphNodeMap(family0->getAssetImpl()->getAssetLLInternal(), logLL)[desc.chunkIndices[0]]); - NVBLAST_CHECK_ERROR(isSupportChunk, "TkFrameworkImpl::createJoint: desc.chunkIndices[0] is not a support chunk in the asset for desc.families[0]. Joint not created.", return nullptr); - handle0 = family0->createExternalJointHandle(getFamilyID(family1), desc.chunkIndices[0], desc.chunkIndices[1]); - NVBLAST_CHECK_ERROR(handle0 != nullptr, "TkFrameworkImpl::createJoint: could not create joint handle in family[0]. Joint not created.", return nullptr); - } - - if (family1 != nullptr) - { - const bool isSupportChunk = !isInvalidIndex(NvBlastAssetGetChunkToGraphNodeMap(family1->getAssetImpl()->getAssetLLInternal(), logLL)[desc.chunkIndices[1]]); - NVBLAST_CHECK_ERROR(isSupportChunk, "TkFrameworkImpl::createJoint: desc.chunkIndices[1] is not a support chunk in the asset for desc.families[1]. Joint not created.", return nullptr); - if (family1 != family0) - { - handle1 = family1->createExternalJointHandle(getFamilyID(family0), desc.chunkIndices[1], desc.chunkIndices[0]); - NVBLAST_CHECK_ERROR(handle1 != nullptr, "TkFrameworkImpl::createJoint: could not create joint handle in family[1]. Joint not created.", return nullptr); - } - } - - TkJointImpl* joint = NVBLAST_NEW(TkJointImpl)(desc, nullptr); - NVBLAST_CHECK_ERROR(joint != nullptr, "TkFrameworkImpl::createJoint: failed to create joint.", return nullptr); - - const TkJointData& jointData = joint->getDataInternal(); - - if (handle0 != nullptr) - { - *handle0 = joint; - static_cast<TkActorImpl*>(jointData.actors[0])->addJoint(joint->m_links[0]); - } - - if (handle1 != nullptr) - { - *handle1 = joint; - if (jointData.actors[0] != jointData.actors[1]) - { - static_cast<TkActorImpl*>(jointData.actors[1])->addJoint(joint->m_links[1]); - } - } - - return joint; -} - - -void TkFrameworkImpl::onCreate(TkIdentifiable& object) -{ - const TkTypeImpl& type = static_cast<const TkTypeImpl&>(object.getType()); - - const uint32_t index = type.getIndex(); - - if (index >= m_objects.size()) - { - if (!isInvalidIndex(index)) - { - NVBLAST_LOG_ERROR("TkFrameworkImpl::addObject: object type unrecognized."); - } - return; - } - - auto& objectArray = m_objects[index]; - NVBLAST_ASSERT(objectArray.find(&object) == objectArray.end()); - objectArray.pushBack(&object); -} - - -void TkFrameworkImpl::onDestroy(TkIdentifiable& object) -{ - // remove from id map if present - const auto id = object.getID(); - if (!TkGUIDIsZero(&id)) - { - m_IDToObject.erase(id); - } - - // remove from object list - const TkTypeImpl& type = static_cast<const TkTypeImpl&>(object.getType()); - - const uint32_t index = type.getIndex(); - - if (index >= m_objects.size()) - { - if (!isInvalidIndex(index)) - { - NVBLAST_LOG_ERROR("TkFrameworkImpl::removeObject: object type unrecognized."); - } - return; - } - - auto& objectArray = m_objects[index]; - objectArray.findAndReplaceWithLast(&object); -} - - -void TkFrameworkImpl::onCreate(TkJointImpl& joint) -{ - NVBLAST_CHECK_ERROR(m_joints.insert(&joint), "TkFrameworkImpl::onCreate: Joint already tracked.", return); -} - - -void TkFrameworkImpl::onDestroy(TkJointImpl& joint) -{ - NVBLAST_CHECK_ERROR(m_joints.erase(&joint), "TkFrameworkImpl::onDestroy: Joint not tracked.", return); -} - - -void TkFrameworkImpl::onIDChange(TkIdentifiable& object, const NvBlastID& IDPrev, const NvBlastID& IDCurr) -{ - if (!TkGUIDIsZero(&IDPrev)) - { - if (!m_IDToObject.erase(IDPrev)) - { - NVBLAST_LOG_ERROR("TkFrameworkImpl::reportIDChanged: object with previous ID doesn't exist."); - } - } - - if (!TkGUIDIsZero(&IDCurr)) - { - auto& value = m_IDToObject[IDCurr]; - if (value != nullptr) - { - NVBLAST_LOG_ERROR("TkFrameworkImpl::reportIDChanged: object with new ID already exists."); - return; - } - value = &object; - } -} - -} // namespace Blast -} // namespace Nv - - -//////// Global API implementation //////// - -Nv::Blast::TkFramework* NvBlastTkFrameworkCreate() -{ - if (Nv::Blast::TkFrameworkImpl::get() != nullptr) - { - NVBLAST_LOG_ERROR("TkFramework::create: framework already created. Use TkFramework::get() to access."); - return nullptr; - } - - Nv::Blast::TkFrameworkImpl* framework = NVBLAST_NEW(Nv::Blast::TkFrameworkImpl) (); - Nv::Blast::TkFrameworkImpl::set(framework); - - return Nv::Blast::TkFrameworkImpl::get(); -} - - -Nv::Blast::TkFramework* NvBlastTkFrameworkGet() -{ - return Nv::Blast::TkFrameworkImpl::get(); -} +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#include "NvBlastAssert.h"
+
+#include "NvBlastTkFrameworkImpl.h"
+#include "NvBlastTkAssetImpl.h"
+#include "NvBlastTkFamilyImpl.h"
+#include "NvBlastTkGroupImpl.h"
+#include "NvBlastTkActorImpl.h"
+#include "NvBlastTkJointImpl.h"
+#include "NvBlastTkTypeImpl.h"
+
+#include "NvBlastGlobals.h"
+
+#include <algorithm>
+
+
+using namespace physx;
+using namespace physx::shdfnd;
+
+
+NV_INLINE bool operator < (const NvBlastID& id1, const NvBlastID& id2)
+{
+ return memcmp(&id1, &id2, sizeof(NvBlastID)) < 0;
+}
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+//////// Local definitions ////////
+
+// Map type ID to static type data
+#define NVBLASTTK_REGISTER_TYPE(_name) \
+ if (!Tk##_name##Impl::s_type.indexIsValid()) \
+ { \
+ Tk##_name##Impl::s_type.setIndex(TkTypeIndex::_name); \
+ } \
+ m_types[TkTypeIndex::_name] = &Tk##_name##Impl::s_type; \
+ m_typeIDToIndex[Tk##_name##Impl::s_type.getID()] = TkTypeIndex::_name
+
+
+#define NVBLASTTK_RELEASE_TYPE(_name) \
+ { \
+ TkTypeImpl& type = Tk##_name##Impl::s_type; \
+ auto& toRelease = m_objects[type.getIndex()]; \
+ for (TkObject* obj : toRelease) \
+ { \
+ obj->release(); \
+ } \
+ }
+
+
+//////// TkFrameworkImpl static variables ////////
+
+TkFrameworkImpl* TkFrameworkImpl::s_framework = nullptr;
+
+
+//////// TkFrameworkImpl static function ////////
+
+TkFrameworkImpl* TkFrameworkImpl::get()
+{
+ return s_framework;
+}
+
+
+bool TkFrameworkImpl::set(TkFrameworkImpl* framework)
+{
+ if (s_framework != nullptr)
+ {
+ if (framework != nullptr)
+ {
+ NVBLAST_LOG_ERROR("TkFrameworkImpl::set: framework already set. Pass NULL to this function to destroy framework.");
+ return false;
+ }
+
+ NVBLAST_DELETE(s_framework, TkFrameworkImpl);
+ }
+
+ s_framework = framework;
+
+ return true;
+}
+
+
+//////// TkFrameworkImpl methods ////////
+
+TkFrameworkImpl::TkFrameworkImpl()
+ : TkFramework()
+{
+ // Register types
+ m_types.resize(TkTypeIndex::TypeCount);
+ m_objects.resize(TkTypeIndex::TypeCount);
+ NVBLASTTK_REGISTER_TYPE(Asset);
+ NVBLASTTK_REGISTER_TYPE(Family);
+ NVBLASTTK_REGISTER_TYPE(Group);
+}
+
+
+TkFrameworkImpl::~TkFrameworkImpl()
+{
+}
+
+
+void TkFrameworkImpl::release()
+{
+ // Special release of joints, which are not TkIdentifiable:
+ Array<TkJointImpl*>::type joints; // Since the EraseIterator is not exposed
+ joints.reserve(m_joints.size());
+ for (auto j = m_joints.getIterator(); !j.done(); ++j)
+ {
+ joints.pushBack(*j);
+ }
+ for (uint32_t i = 0; i < joints.size(); ++i)
+ {
+ joints[i]->release();
+ }
+ NVBLAST_ASSERT(m_joints.size() == 0);
+ joints.reset(); // Since we will be deleting the allocator
+
+ NVBLASTTK_RELEASE_TYPE(Group);
+ NVBLASTTK_RELEASE_TYPE(Asset);
+ set(nullptr);
+}
+
+
+const TkType* TkFrameworkImpl::getType(TkTypeIndex::Enum typeIndex) const
+{
+ if (typeIndex < 0 || typeIndex >= TkTypeIndex::TypeCount)
+ {
+ NVBLAST_LOG_WARNING("TkFrameworkImpl::getType: invalid typeIndex.");
+ return nullptr;
+ }
+
+ return m_types[typeIndex];
+}
+
+
+TkIdentifiable* TkFrameworkImpl::findObjectByID(const NvBlastID& id) const
+{
+ TkIdentifiable* object = findObjectByIDInternal(id);
+
+ if (object == nullptr)
+ {
+ NVBLAST_LOG_WARNING("TkFrameworkImpl::findObjectByID: object not found.");
+ }
+
+ return object;
+}
+
+
+uint32_t TkFrameworkImpl::getObjectCount(const TkType& type) const
+{
+ const uint32_t index = static_cast<const TkTypeImpl&>(type).getIndex();
+
+ if (index >= m_objects.size())
+ {
+ NVBLAST_LOG_ERROR("TkFrameworkImpl::getObjectCount: BlastTk object type unrecognized.");
+ return 0;
+
+ }
+
+ return m_objects[index].size();
+}
+
+
+uint32_t TkFrameworkImpl::getObjects(TkIdentifiable** buffer, uint32_t bufferSize, const TkType& type, uint32_t indexStart /* = 0 */) const
+{
+ const uint32_t index = static_cast<const TkTypeImpl&>(type).getIndex();
+
+ if (index >= m_objects.size())
+ {
+ NVBLAST_LOG_ERROR("TkFrameworkImpl::getObjectCount: BlastTk object type unrecognized.");
+ return 0;
+ }
+
+ const auto& objectArray = m_objects[index];
+
+ uint32_t objectCount = objectArray.size();
+ if (objectCount <= indexStart)
+ {
+ NVBLAST_LOG_WARNING("TkFrameworkImpl::getObjects: indexStart beyond end of object list.");
+ return 0;
+ }
+
+ objectCount -= indexStart;
+ if (objectCount > bufferSize)
+ {
+ objectCount = bufferSize;
+ }
+
+ memcpy(buffer, objectArray.begin() + indexStart, objectCount * sizeof(TkObject*));
+
+ return objectCount;
+}
+
+
+bool TkFrameworkImpl::reorderAssetDescChunks(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount, NvBlastBondDesc* bondDescs, uint32_t bondCount, uint32_t* chunkReorderMap /*= nullptr*/, bool keepBondNormalChunkOrder /*= false*/) const
+{
+ uint32_t* map = chunkReorderMap != nullptr ? chunkReorderMap : static_cast<uint32_t*>(NVBLAST_ALLOC_NAMED(chunkCount * sizeof(uint32_t), "reorderAssetDescChunks:chunkReorderMap"));
+ void* scratch = NVBLAST_ALLOC_NAMED(chunkCount * sizeof(NvBlastChunkDesc), "reorderAssetDescChunks:scratch");
+ const bool result = NvBlastReorderAssetDescChunks(chunkDescs, chunkCount, bondDescs, bondCount, map, keepBondNormalChunkOrder, scratch, logLL);
+ NVBLAST_FREE(scratch);
+ if (chunkReorderMap == nullptr)
+ {
+ NVBLAST_FREE(map);
+ }
+ return result;
+}
+
+
+bool TkFrameworkImpl::ensureAssetExactSupportCoverage(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount) const
+{
+ void* scratch = NVBLAST_ALLOC_NAMED(chunkCount, "ensureAssetExactSupportCoverage:scratch");
+ const bool result = NvBlastEnsureAssetExactSupportCoverage(chunkDescs, chunkCount, scratch, logLL);
+ NVBLAST_FREE(scratch);
+ return result;
+}
+
+
+TkAsset* TkFrameworkImpl::createAsset(const TkAssetDesc& desc)
+{
+ TkAssetImpl* asset = TkAssetImpl::create(desc);
+ if (asset == nullptr)
+ {
+ NVBLAST_LOG_ERROR("TkFrameworkImpl::createAsset: failed to create asset.");
+ }
+
+ return asset;
+}
+
+
+TkAsset* TkFrameworkImpl::createAsset(const NvBlastAsset* assetLL, Nv::Blast::TkAssetJointDesc* jointDescs, uint32_t jointDescCount, bool ownsAsset)
+{
+ TkAssetImpl* asset = TkAssetImpl::create(assetLL, jointDescs, jointDescCount, ownsAsset);
+ if (asset == nullptr)
+ {
+ NVBLAST_LOG_ERROR("TkFrameworkImpl::createAsset: failed to create asset.");
+ }
+
+ return asset;
+}
+
+
+TkGroup* TkFrameworkImpl::createGroup(const TkGroupDesc& desc)
+{
+ TkGroupImpl* group = TkGroupImpl::create(desc);
+ if (group == nullptr)
+ {
+ NVBLAST_LOG_ERROR("TkFrameworkImpl::createGroup: failed to create group.");
+ }
+
+ return group;
+}
+
+
+TkActor* TkFrameworkImpl::createActor(const TkActorDesc& desc)
+{
+ TkActor* actor = TkActorImpl::create(desc);
+ if (actor == nullptr)
+ {
+ NVBLAST_LOG_ERROR("TkFrameworkImpl::createActor: failed to create actor.");
+ }
+
+ return actor;
+}
+
+
+TkJoint* TkFrameworkImpl::createJoint(const TkJointDesc& desc)
+{
+ TkJointImpl** handle0 = nullptr;
+ TkJointImpl** handle1 = nullptr;
+
+ TkFamilyImpl* family0 = static_cast<TkFamilyImpl*>(desc.families[0]);
+ TkFamilyImpl* family1 = static_cast<TkFamilyImpl*>(desc.families[1]);
+
+ NVBLAST_CHECK_ERROR(family0 != nullptr || family1 != nullptr, "TkFrameworkImpl::createJoint: at least one family in the TkJointDesc must be valid.", return nullptr);
+
+ NVBLAST_CHECK_ERROR(family0 == nullptr || desc.chunkIndices[0] < family0->getAssetImpl()->getChunkCount(), "TkFrameworkImpl::createJoint: desc.chunkIndices[0] is invalid.", return nullptr);
+ NVBLAST_CHECK_ERROR(family1 == nullptr || desc.chunkIndices[1] < family1->getAssetImpl()->getChunkCount(), "TkFrameworkImpl::createJoint: desc.chunkIndices[1] is invalid.", return nullptr);
+
+ const bool actorsAreTheSame = family0 == family1 && family0->getActorByChunk(desc.chunkIndices[0]) == family1->getActorByChunk(desc.chunkIndices[1]);
+ NVBLAST_CHECK_ERROR(!actorsAreTheSame, "TkFrameworkImpl::createJoint: the chunks listed in the TkJointDesc must be in different actors.", return nullptr);
+
+ if (family0 != nullptr)
+ {
+ const bool isSupportChunk = !isInvalidIndex(NvBlastAssetGetChunkToGraphNodeMap(family0->getAssetImpl()->getAssetLLInternal(), logLL)[desc.chunkIndices[0]]);
+ NVBLAST_CHECK_ERROR(isSupportChunk, "TkFrameworkImpl::createJoint: desc.chunkIndices[0] is not a support chunk in the asset for desc.families[0]. Joint not created.", return nullptr);
+ handle0 = family0->createExternalJointHandle(getFamilyID(family1), desc.chunkIndices[0], desc.chunkIndices[1]);
+ NVBLAST_CHECK_ERROR(handle0 != nullptr, "TkFrameworkImpl::createJoint: could not create joint handle in family[0]. Joint not created.", return nullptr);
+ }
+
+ if (family1 != nullptr)
+ {
+ const bool isSupportChunk = !isInvalidIndex(NvBlastAssetGetChunkToGraphNodeMap(family1->getAssetImpl()->getAssetLLInternal(), logLL)[desc.chunkIndices[1]]);
+ NVBLAST_CHECK_ERROR(isSupportChunk, "TkFrameworkImpl::createJoint: desc.chunkIndices[1] is not a support chunk in the asset for desc.families[1]. Joint not created.", return nullptr);
+ if (family1 != family0)
+ {
+ handle1 = family1->createExternalJointHandle(getFamilyID(family0), desc.chunkIndices[1], desc.chunkIndices[0]);
+ NVBLAST_CHECK_ERROR(handle1 != nullptr, "TkFrameworkImpl::createJoint: could not create joint handle in family[1]. Joint not created.", return nullptr);
+ }
+ }
+
+ TkJointImpl* joint = NVBLAST_NEW(TkJointImpl)(desc, nullptr);
+ NVBLAST_CHECK_ERROR(joint != nullptr, "TkFrameworkImpl::createJoint: failed to create joint.", return nullptr);
+
+ const TkJointData& jointData = joint->getDataInternal();
+
+ if (handle0 != nullptr)
+ {
+ *handle0 = joint;
+ static_cast<TkActorImpl*>(jointData.actors[0])->addJoint(joint->m_links[0]);
+ }
+
+ if (handle1 != nullptr)
+ {
+ *handle1 = joint;
+ if (jointData.actors[0] != jointData.actors[1])
+ {
+ static_cast<TkActorImpl*>(jointData.actors[1])->addJoint(joint->m_links[1]);
+ }
+ }
+
+ return joint;
+}
+
+
+void TkFrameworkImpl::onCreate(TkIdentifiable& object)
+{
+ const TkTypeImpl& type = static_cast<const TkTypeImpl&>(object.getType());
+
+ const uint32_t index = type.getIndex();
+
+ if (index >= m_objects.size())
+ {
+ if (!isInvalidIndex(index))
+ {
+ NVBLAST_LOG_ERROR("TkFrameworkImpl::addObject: object type unrecognized.");
+ }
+ return;
+ }
+
+ auto& objectArray = m_objects[index];
+ NVBLAST_ASSERT(objectArray.find(&object) == objectArray.end());
+ objectArray.pushBack(&object);
+}
+
+
+void TkFrameworkImpl::onDestroy(TkIdentifiable& object)
+{
+ // remove from id map if present
+ const auto id = object.getID();
+ if (!TkGUIDIsZero(&id))
+ {
+ m_IDToObject.erase(id);
+ }
+
+ // remove from object list
+ const TkTypeImpl& type = static_cast<const TkTypeImpl&>(object.getType());
+
+ const uint32_t index = type.getIndex();
+
+ if (index >= m_objects.size())
+ {
+ if (!isInvalidIndex(index))
+ {
+ NVBLAST_LOG_ERROR("TkFrameworkImpl::removeObject: object type unrecognized.");
+ }
+ return;
+ }
+
+ auto& objectArray = m_objects[index];
+ objectArray.findAndReplaceWithLast(&object);
+}
+
+
+void TkFrameworkImpl::onCreate(TkJointImpl& joint)
+{
+ NVBLAST_CHECK_ERROR(m_joints.insert(&joint), "TkFrameworkImpl::onCreate: Joint already tracked.", return);
+}
+
+
+void TkFrameworkImpl::onDestroy(TkJointImpl& joint)
+{
+ NVBLAST_CHECK_ERROR(m_joints.erase(&joint), "TkFrameworkImpl::onDestroy: Joint not tracked.", return);
+}
+
+
+void TkFrameworkImpl::onIDChange(TkIdentifiable& object, const NvBlastID& IDPrev, const NvBlastID& IDCurr)
+{
+ if (!TkGUIDIsZero(&IDPrev))
+ {
+ if (!m_IDToObject.erase(IDPrev))
+ {
+ NVBLAST_LOG_ERROR("TkFrameworkImpl::reportIDChanged: object with previous ID doesn't exist.");
+ }
+ }
+
+ if (!TkGUIDIsZero(&IDCurr))
+ {
+ auto& value = m_IDToObject[IDCurr];
+ if (value != nullptr)
+ {
+ NVBLAST_LOG_ERROR("TkFrameworkImpl::reportIDChanged: object with new ID already exists.");
+ return;
+ }
+ value = &object;
+ }
+}
+
+} // namespace Blast
+} // namespace Nv
+
+
+//////// Global API implementation ////////
+
+Nv::Blast::TkFramework* NvBlastTkFrameworkCreate()
+{
+ if (Nv::Blast::TkFrameworkImpl::get() != nullptr)
+ {
+ NVBLAST_LOG_ERROR("TkFramework::create: framework already created. Use TkFramework::get() to access.");
+ return nullptr;
+ }
+
+ Nv::Blast::TkFrameworkImpl* framework = NVBLAST_NEW(Nv::Blast::TkFrameworkImpl) ();
+ Nv::Blast::TkFrameworkImpl::set(framework);
+
+ return Nv::Blast::TkFrameworkImpl::get();
+}
+
+
+Nv::Blast::TkFramework* NvBlastTkFrameworkGet()
+{
+ return Nv::Blast::TkFrameworkImpl::get();
+}
diff --git a/sdk/toolkit/source/NvBlastTkFrameworkImpl.h b/sdk/toolkit/source/NvBlastTkFrameworkImpl.h index 29914c2..497ab10 100644..100755 --- a/sdk/toolkit/source/NvBlastTkFrameworkImpl.h +++ b/sdk/toolkit/source/NvBlastTkFrameworkImpl.h @@ -1,162 +1,162 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#ifndef NVBLASTTKFRAMEWORKIMPL_H -#define NVBLASTTKFRAMEWORKIMPL_H - -#include "NvBlastTkFramework.h" -#include "NvBlastProfilerInternal.h" - -#include "NvBlastTkCommon.h" - -#include "NvBlastArray.h" -#include "NvBlastHashMap.h" -#include "NvBlastHashSet.h" - - -namespace Nv -{ -namespace Blast -{ - -// Forward declarations -class TkTypeImpl; -class TkJointImpl; - -/** -Implementation of TkFramework -*/ -class TkFrameworkImpl : public TkFramework -{ -public: - TkFrameworkImpl(); - ~TkFrameworkImpl(); - - // Begin TkFramework - virtual void release() override; - - virtual const TkType* getType(TkTypeIndex::Enum typeIndex) const override; - - virtual TkIdentifiable* findObjectByID(const NvBlastID& id) const override; - - virtual uint32_t getObjectCount(const TkType& type) const override; - - virtual uint32_t getObjects(TkIdentifiable** buffer, uint32_t bufferSize, const TkType& type, uint32_t indexStart = 0) const override; - - virtual bool reorderAssetDescChunks(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount, NvBlastBondDesc* bondDescs, uint32_t bondCount, uint32_t* chunkReorderMap = nullptr, bool keepBondNormalChunkOrder = false) const override; - - virtual bool ensureAssetExactSupportCoverage(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount) const override; - - virtual TkAsset* createAsset(const TkAssetDesc& desc) override; - - virtual TkAsset* createAsset(const NvBlastAsset* assetLL, Nv::Blast::TkAssetJointDesc* jointDescs = nullptr, uint32_t jointDescCount = 0, bool ownsAsset = false) override; - - virtual TkGroup* createGroup(const TkGroupDesc& desc) override; - - virtual TkActor* createActor(const TkActorDesc& desc) override; - - virtual TkJoint* createJoint(const TkJointDesc& desc) override; - // End TkFramework - - // Public methods - /** - To be called by any TkIdentifiable object when it is created, so the framework can track it. - */ - void onCreate(TkIdentifiable& object); - - /** - To be called by any TkIdentifiable object when it is deleted, so the framework can stop tracking it. - */ - void onDestroy(TkIdentifiable& object); - - /** - Special onCreate method for joints, since they are not TkIdentifiable. - */ - void onCreate(TkJointImpl& joint); - - /** - Special onDestroy method for joints, since they are not TkIdentifiable. - */ - void onDestroy(TkJointImpl& joint); - - /** - Must be called whenever a TkIdentifiable object's ID is changed, so that the framework can associate the new ID with it. - */ - void onIDChange(TkIdentifiable& object, const NvBlastID& IDPrev, const NvBlastID& IDCurr); - - /** - Internal (non-virtual) method to find a TkIdentifiable object based upon its NvBlastID. - */ - TkIdentifiable* findObjectByIDInternal(const NvBlastID& id) const; - - // Access to singleton - - /** Retrieve the global singleton. */ - static TkFrameworkImpl* get(); - - /** Set the global singleton, if it's not already set, or set it to NULL. Returns true iff successful. */ - static bool set(TkFrameworkImpl* framework); - -private: - // Enums - enum { ClassID = NVBLAST_FOURCC('T', 'K', 'F', 'W') }; //!< TkFramework identifier token, used in serialization - - // Static data - static TkFrameworkImpl* s_framework; //!< Global (singleton) object pointer - - // Types - InlineArray<const TkTypeImpl*, TkTypeIndex::TypeCount>::type m_types; //!< TkIdentifiable static type data - HashMap<uint32_t, uint32_t>::type m_typeIDToIndex; //!< Map to type data keyed by ClassID - - // Objects and object names - HashMap<NvBlastID, TkIdentifiable*>::type m_IDToObject; //!< Map to all TkIdentifiable objects, keyed by NvBlastID - InlineArray<Array<TkIdentifiable*>::type, TkTypeIndex::TypeCount>::type m_objects; //!< Catalog of all TkIdentifiable objects, grouped by type. (Revisit implementation.) - - // Track external joints (to do: make this a pool) - HashSet<TkJointImpl*>::type m_joints; //!< All internal joints -}; - - -//////// TkFrameworkImpl inline methods //////// - -NV_INLINE TkIdentifiable* TkFrameworkImpl::findObjectByIDInternal(const NvBlastID& id) const -{ - const auto entry = m_IDToObject.find(id); - if (entry == nullptr) - { - return nullptr; - } - - return entry->second; -} - -} // namespace Blast -} // namespace Nv - - -#endif // ifndef NVBLASTTKFRAMEWORKIMPL_H +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#ifndef NVBLASTTKFRAMEWORKIMPL_H
+#define NVBLASTTKFRAMEWORKIMPL_H
+
+#include "NvBlastTkFramework.h"
+#include "NvBlastProfilerInternal.h"
+
+#include "NvBlastTkCommon.h"
+
+#include "NvBlastArray.h"
+#include "NvBlastHashMap.h"
+#include "NvBlastHashSet.h"
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+// Forward declarations
+class TkTypeImpl;
+class TkJointImpl;
+
+/**
+Implementation of TkFramework
+*/
+class TkFrameworkImpl : public TkFramework
+{
+public:
+ TkFrameworkImpl();
+ ~TkFrameworkImpl();
+
+ // Begin TkFramework
+ virtual void release() override;
+
+ virtual const TkType* getType(TkTypeIndex::Enum typeIndex) const override;
+
+ virtual TkIdentifiable* findObjectByID(const NvBlastID& id) const override;
+
+ virtual uint32_t getObjectCount(const TkType& type) const override;
+
+ virtual uint32_t getObjects(TkIdentifiable** buffer, uint32_t bufferSize, const TkType& type, uint32_t indexStart = 0) const override;
+
+ virtual bool reorderAssetDescChunks(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount, NvBlastBondDesc* bondDescs, uint32_t bondCount, uint32_t* chunkReorderMap = nullptr, bool keepBondNormalChunkOrder = false) const override;
+
+ virtual bool ensureAssetExactSupportCoverage(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount) const override;
+
+ virtual TkAsset* createAsset(const TkAssetDesc& desc) override;
+
+ virtual TkAsset* createAsset(const NvBlastAsset* assetLL, Nv::Blast::TkAssetJointDesc* jointDescs = nullptr, uint32_t jointDescCount = 0, bool ownsAsset = false) override;
+
+ virtual TkGroup* createGroup(const TkGroupDesc& desc) override;
+
+ virtual TkActor* createActor(const TkActorDesc& desc) override;
+
+ virtual TkJoint* createJoint(const TkJointDesc& desc) override;
+ // End TkFramework
+
+ // Public methods
+ /**
+ To be called by any TkIdentifiable object when it is created, so the framework can track it.
+ */
+ void onCreate(TkIdentifiable& object);
+
+ /**
+ To be called by any TkIdentifiable object when it is deleted, so the framework can stop tracking it.
+ */
+ void onDestroy(TkIdentifiable& object);
+
+ /**
+ Special onCreate method for joints, since they are not TkIdentifiable.
+ */
+ void onCreate(TkJointImpl& joint);
+
+ /**
+ Special onDestroy method for joints, since they are not TkIdentifiable.
+ */
+ void onDestroy(TkJointImpl& joint);
+
+ /**
+ Must be called whenever a TkIdentifiable object's ID is changed, so that the framework can associate the new ID with it.
+ */
+ void onIDChange(TkIdentifiable& object, const NvBlastID& IDPrev, const NvBlastID& IDCurr);
+
+ /**
+ Internal (non-virtual) method to find a TkIdentifiable object based upon its NvBlastID.
+ */
+ TkIdentifiable* findObjectByIDInternal(const NvBlastID& id) const;
+
+ // Access to singleton
+
+ /** Retrieve the global singleton. */
+ static TkFrameworkImpl* get();
+
+ /** Set the global singleton, if it's not already set, or set it to NULL. Returns true iff successful. */
+ static bool set(TkFrameworkImpl* framework);
+
+private:
+ // Enums
+ enum { ClassID = NVBLAST_FOURCC('T', 'K', 'F', 'W') }; //!< TkFramework identifier token, used in serialization
+
+ // Static data
+ static TkFrameworkImpl* s_framework; //!< Global (singleton) object pointer
+
+ // Types
+ InlineArray<const TkTypeImpl*, TkTypeIndex::TypeCount>::type m_types; //!< TkIdentifiable static type data
+ HashMap<uint32_t, uint32_t>::type m_typeIDToIndex; //!< Map to type data keyed by ClassID
+
+ // Objects and object names
+ HashMap<NvBlastID, TkIdentifiable*>::type m_IDToObject; //!< Map to all TkIdentifiable objects, keyed by NvBlastID
+ InlineArray<Array<TkIdentifiable*>::type, TkTypeIndex::TypeCount>::type m_objects; //!< Catalog of all TkIdentifiable objects, grouped by type. (Revisit implementation.)
+
+ // Track external joints (to do: make this a pool)
+ HashSet<TkJointImpl*>::type m_joints; //!< All internal joints
+};
+
+
+//////// TkFrameworkImpl inline methods ////////
+
+NV_INLINE TkIdentifiable* TkFrameworkImpl::findObjectByIDInternal(const NvBlastID& id) const
+{
+ const auto entry = m_IDToObject.find(id);
+ if (entry == nullptr)
+ {
+ return nullptr;
+ }
+
+ return entry->second;
+}
+
+} // namespace Blast
+} // namespace Nv
+
+
+#endif // ifndef NVBLASTTKFRAMEWORKIMPL_H
diff --git a/sdk/toolkit/source/NvBlastTkGUID.h b/sdk/toolkit/source/NvBlastTkGUID.h index 927e915..907a803 100644..100755 --- a/sdk/toolkit/source/NvBlastTkGUID.h +++ b/sdk/toolkit/source/NvBlastTkGUID.h @@ -1,148 +1,148 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#ifndef NVBLASTTKGUID_H -#define NVBLASTTKGUID_H - -#include "NvPreprocessor.h" - -#if NV_WINDOWS_FAMILY -#include <rpc.h> -#else -//#include <uuid/uuid.h> -#include "NvBlastTime.h" -#endif - -#include "PsHash.h" - -namespace Nv -{ -namespace Blast -{ - -#if NV_WINDOWS_FAMILY - -NV_INLINE NvBlastID TkGenerateGUID(void* ptr) -{ - NV_UNUSED(ptr); - - NV_COMPILE_TIME_ASSERT(sizeof(UUID) == sizeof(NvBlastID)); - - NvBlastID guid; - UuidCreate(reinterpret_cast<UUID*>(&guid)); - - return guid; -} - -#else - -NV_INLINE NvBlastID TkGenerateGUID(void* ptr) -{ -// NV_COMPILE_TIME_ASSERT(sizeof(uuid_t) == sizeof(NvBlastID)); - Time time; - - NvBlastID guid; - // uuid_generate_random(reinterpret_cast<uuid_t&>(guid)); - - *reinterpret_cast<uint64_t*>(guid.data) = reinterpret_cast<uintptr_t>(ptr); - *reinterpret_cast<int64_t*>(guid.data + 8) = time.getLastTickCount(); - - return guid; -} - -#endif - - -/** -Compares two NvBlastIDs. - -\param[in] id1 A pointer to the first id to compare. -\param[in] id2 A pointer to the second id to compare. - -\return true iff ids are equal. -*/ -NV_INLINE bool TkGUIDsEqual(const NvBlastID* id1, const NvBlastID* id2) -{ - return !memcmp(id1, id2, sizeof(NvBlastID)); -} - - -/** -Clears an NvBlastID (sets all of its fields to zero). - -\param[out] id A pointer to the ID to clear. -*/ -NV_INLINE void TkGUIDReset(NvBlastID* id) -{ - memset(id, 0, sizeof(NvBlastID)); -} - - -/** -Tests an NvBlastID to determine if it's zeroed. After calling TkGUIDReset -on an ID, passing it to this function will return a value of true. - -\param[in] id A pointer to the ID to test. -*/ -NV_INLINE bool TkGUIDIsZero(const NvBlastID* id) -{ - return *reinterpret_cast<const uint64_t*>(&id->data[0]) == 0 && *reinterpret_cast<const uint64_t*>(&id->data[8]) == 0; -} - -} // namespace Blast -} // namespace Nv - - -namespace physx -{ -namespace shdfnd -{ - -// hash specialization for NvBlastID -template <> -struct Hash<NvBlastID> -{ - uint32_t operator()(const NvBlastID& k) const - { - // "DJB" string hash - uint32_t h = 5381; - for (uint32_t i = 0; i < sizeof(k.data) / sizeof(k.data[0]); ++i) - h = ((h << 5) + h) ^ uint32_t(k.data[i]); - return h; - } - bool equal(const NvBlastID& k0, const NvBlastID& k1) const - { - return Nv::Blast::TkGUIDsEqual(&k0, &k1); - } -}; - -} // namespace shdfnd -} // namespace physx - - -#endif // #ifndef NVBLASTTKGUID_H +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#ifndef NVBLASTTKGUID_H
+#define NVBLASTTKGUID_H
+
+#include "NvPreprocessor.h"
+
+#if NV_WINDOWS_FAMILY
+#include <rpc.h>
+#else
+//#include <uuid/uuid.h>
+#include "NvBlastTime.h"
+#endif
+
+#include "PsHash.h"
+
+namespace Nv
+{
+namespace Blast
+{
+
+#if NV_WINDOWS_FAMILY
+
+NV_INLINE NvBlastID TkGenerateGUID(void* ptr)
+{
+ NV_UNUSED(ptr);
+
+ NV_COMPILE_TIME_ASSERT(sizeof(UUID) == sizeof(NvBlastID));
+
+ NvBlastID guid;
+ UuidCreate(reinterpret_cast<UUID*>(&guid));
+
+ return guid;
+}
+
+#else
+
+NV_INLINE NvBlastID TkGenerateGUID(void* ptr)
+{
+// NV_COMPILE_TIME_ASSERT(sizeof(uuid_t) == sizeof(NvBlastID));
+ Time time;
+
+ NvBlastID guid;
+ // uuid_generate_random(reinterpret_cast<uuid_t&>(guid));
+
+ *reinterpret_cast<uint64_t*>(guid.data) = reinterpret_cast<uintptr_t>(ptr);
+ *reinterpret_cast<int64_t*>(guid.data + 8) = time.getLastTickCount();
+
+ return guid;
+}
+
+#endif
+
+
+/**
+Compares two NvBlastIDs.
+
+\param[in] id1 A pointer to the first id to compare.
+\param[in] id2 A pointer to the second id to compare.
+
+\return true iff ids are equal.
+*/
+NV_INLINE bool TkGUIDsEqual(const NvBlastID* id1, const NvBlastID* id2)
+{
+ return !memcmp(id1, id2, sizeof(NvBlastID));
+}
+
+
+/**
+Clears an NvBlastID (sets all of its fields to zero).
+
+\param[out] id A pointer to the ID to clear.
+*/
+NV_INLINE void TkGUIDReset(NvBlastID* id)
+{
+ memset(id, 0, sizeof(NvBlastID));
+}
+
+
+/**
+Tests an NvBlastID to determine if it's zeroed. After calling TkGUIDReset
+on an ID, passing it to this function will return a value of true.
+
+\param[in] id A pointer to the ID to test.
+*/
+NV_INLINE bool TkGUIDIsZero(const NvBlastID* id)
+{
+ return *reinterpret_cast<const uint64_t*>(&id->data[0]) == 0 && *reinterpret_cast<const uint64_t*>(&id->data[8]) == 0;
+}
+
+} // namespace Blast
+} // namespace Nv
+
+
+namespace physx
+{
+namespace shdfnd
+{
+
+// hash specialization for NvBlastID
+template <>
+struct Hash<NvBlastID>
+{
+ uint32_t operator()(const NvBlastID& k) const
+ {
+ // "DJB" string hash
+ uint32_t h = 5381;
+ for (uint32_t i = 0; i < sizeof(k.data) / sizeof(k.data[0]); ++i)
+ h = ((h << 5) + h) ^ uint32_t(k.data[i]);
+ return h;
+ }
+ bool equal(const NvBlastID& k0, const NvBlastID& k1) const
+ {
+ return Nv::Blast::TkGUIDsEqual(&k0, &k1);
+ }
+};
+
+} // namespace shdfnd
+} // namespace physx
+
+
+#endif // #ifndef NVBLASTTKGUID_H
diff --git a/sdk/toolkit/source/NvBlastTkGroupImpl.cpp b/sdk/toolkit/source/NvBlastTkGroupImpl.cpp index 1769f33..bcb8463 100644..100755 --- a/sdk/toolkit/source/NvBlastTkGroupImpl.cpp +++ b/sdk/toolkit/source/NvBlastTkGroupImpl.cpp @@ -1,612 +1,612 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#include "NvPreprocessor.h" - -#include "NvBlastAssert.h" -#include "NvBlast.h" - -#include "NvBlastTkFrameworkImpl.h" -#include "NvBlastTkGroupImpl.h" -#include "NvBlastTkActorImpl.h" -#include "NvBlastTkFamilyImpl.h" -#include "NvBlastTkAssetImpl.h" -#include "NvBlastTkTaskImpl.h" - -#undef max -#undef min -#include <algorithm> - -using namespace physx; - - -namespace Nv -{ -namespace Blast -{ - -//////// Static data //////// - -NVBLASTTK_DEFINE_TYPE_IDENTIFIABLE(Group); - - -//////// Member functions //////// - -TkGroupImpl::TkGroupImpl() : m_actorCount(0), m_isProcessing(false) -{ -#if NV_PROFILE - memset(&m_stats, 0, sizeof(TkGroupStats)); -#endif -} - - -TkGroupImpl::~TkGroupImpl() -{ - NVBLAST_ASSERT(getActorCount() == 0); - NVBLAST_ASSERT(m_sharedMemory.size() == 0); -} - - -void TkGroupImpl::release() -{ - if (isProcessing()) - { - // abort all processing? - NVBLAST_LOG_ERROR("TkGroup::release: cannot release Group while processing."); - NVBLAST_ALWAYS_ASSERT_MESSAGE("TkGroup::release: cannot release Group while processing."); - return; - } - - for (auto it = m_sharedMemory.getIterator(); !it.done(); ++it) - { - TkFamilyImpl* family = it->first; - for (TkActorImpl& actor : family->getActorsInternal()) - { - if (actor.m_group == this) - { - removeActorInternal(actor); - } - } - SharedMemory* mem = it->second; - mem->release(); - NVBLAST_DELETE(mem, SharedMemory); - } - m_sharedMemory.clear(); - - m_bondTempDataBlock.release(); - m_chunkTempDataBlock.release(); - m_bondEventDataBlock.release(); - m_chunkEventDataBlock.release(); - m_splitScratchBlock.release(); - - NVBLAST_DELETE(this, TkGroupImpl); -} - - -void TkGroupImpl::addActorsInternal(TkActorImpl** actors, uint32_t numActors) -{ - for (uint32_t i = 0; i < numActors; i++) - { - addActorInternal(*actors[i]); - } -} - - -void TkGroupImpl::addActorInternal(TkActorImpl& tkActor) -{ - NVBLAST_ASSERT(tkActor.getGroup() == nullptr); - tkActor.m_group = this; - m_actorCount++; -} - - -bool TkGroupImpl::addActor(TkActor& actor) -{ - TkActorImpl& tkActor = static_cast<TkActorImpl&>(actor); - if (tkActor.getGroup() != nullptr) - { - NVBLAST_LOG_ERROR("TkGroup::addActor: actor already belongs to a Group. Remove from current group first."); - return false; - } - - if (isProcessing()) - { - NVBLAST_LOG_ERROR("TkGroup::addActor: cannot alter Group while processing."); - return false; - } - - // mark the actor that it now belongs to this group - addActorInternal(tkActor); - - // actors that were fractured already or have damage requested - // must be enqueued to be processed - if (tkActor.isPending()) - { - enqueue(&tkActor); - } - - TkFamilyImpl& family = tkActor.getFamilyImpl(); - SharedMemory* mem = m_sharedMemory[&family]; - if (mem == nullptr) - { - // the actor belongs to a family not involved in this group yet - // shared memory must be allocated and temporary buffers adjusted accordingly - - BLAST_PROFILE_ZONE_BEGIN("family memory"); - mem = NVBLAST_NEW(SharedMemory); - mem->allocate(family); - m_sharedMemory[&family] = mem; - BLAST_PROFILE_ZONE_END("family memory"); - - BLAST_PROFILE_ZONE_BEGIN("group memory"); - - const uint32_t workerCount = m_workers.size(); - - NvBlastLog theLog = logLL; - - // this group's tasks will use one temporary buffer each, which is of max size of, for all families involved - const size_t requiredScratch = NvBlastActorGetRequiredScratchForSplit(tkActor.getActorLL(), theLog); - if (static_cast<size_t>(m_splitScratchBlock.numElementsPerBlock()) < requiredScratch) - { - m_splitScratchBlock.release(); - m_splitScratchBlock.allocate(static_cast<uint32_t>(requiredScratch), workerCount); - } - - // generate and apply fracture may create an entry for each bond - const uint32_t bondCount = NvBlastAssetGetBondCount(tkActor.getAsset()->getAssetLL(), theLog); - if (m_bondTempDataBlock.numElementsPerBlock() < bondCount) - { - m_bondTempDataBlock.release(); - m_bondTempDataBlock.allocate(bondCount, workerCount); - m_bondEventDataBlock.release(); - m_bondEventDataBlock.allocate(bondCount, workerCount); - } - - // apply fracture may create an entry for each lower-support chunk - const uint32_t graphNodeCount = NvBlastAssetGetSupportGraph(tkActor.getAsset()->getAssetLL(), theLog).nodeCount; - const uint32_t subsupportChunkCount - = NvBlastAssetGetChunkCount(tkActor.getAsset()->getAssetLL(), theLog) - - NvBlastAssetGetFirstSubsupportChunkIndex(tkActor.getAsset()->getAssetLL(), theLog); - const uint32_t chunkCount = graphNodeCount + subsupportChunkCount; - if (m_chunkTempDataBlock.numElementsPerBlock() < chunkCount) - { - m_chunkTempDataBlock.release(); - m_chunkTempDataBlock.allocate(chunkCount, workerCount); - m_chunkEventDataBlock.release(); - m_chunkEventDataBlock.allocate(chunkCount, workerCount); - } - BLAST_PROFILE_ZONE_END("group memory"); - } - mem->addReference(); - - return true; -} - - -uint32_t TkGroupImpl::getActors(TkActor** buffer, uint32_t bufferSize, uint32_t indexStart /* = 0 */) const -{ - BLAST_PROFILE_SCOPE_L("TkGroup::getActors"); - - uint32_t actorCount = m_actorCount; - if (actorCount <= indexStart) - { - NVBLAST_LOG_WARNING("TkGroup::getActors: indexStart beyond end of actor list."); - return 0; - } - - actorCount -= indexStart; - if (actorCount > bufferSize) - { - actorCount = bufferSize; - } - - uint32_t index = 0; - bool done = false; - for (auto it = const_cast<TkGroupImpl*>(this)->m_sharedMemory.getIterator(); !it.done();++it) - { - TkFamilyImpl* fam = it->first; - for (TkActorImpl& actor : fam->getActorsInternal()) - { - if (actor.m_group == this) - { - NVBLAST_ASSERT(actor.isActive()); - - if (index >= indexStart) - { - *buffer++ = &actor; - } - - index++; - done = (index - indexStart) >= actorCount; - } - if (done) break; - } - if (done) break; - } - - return actorCount; -} - - -void TkGroupImpl::removeActorInternal(TkActorImpl& tkActor) -{ - NVBLAST_ASSERT(tkActor.m_group == this); - tkActor.m_group = nullptr; - m_actorCount--; -} - - -void TkGroupImpl::releaseSharedMemory(TkFamilyImpl* fam, SharedMemory* mem) -{ - NVBLAST_ASSERT(mem != nullptr && m_sharedMemory[fam] == mem); - mem->release(); - m_sharedMemory.erase(fam); - NVBLAST_DELETE(mem, SharedMemory); -} - - -bool TkGroupImpl::removeActor(TkActor& actor) -{ - TkActorImpl& tkActor = static_cast<TkActorImpl&>(actor); - - if (tkActor.getGroup() != this) - { - NVBLAST_LOG_ERROR("TkGroup::removeActor: actor does not belong to this Group."); - return false; - } - - if (isProcessing()) - { - NVBLAST_LOG_ERROR("TkGroup::removeActor: cannot alter Group while processing."); - return false; - } - - removeActorInternal(tkActor); - - // pending actors must be removed from the job queue as well - if(tkActor.isPending()) - { - uint32_t index = tkActor.m_groupJobIndex; - tkActor.m_groupJobIndex = invalidIndex<uint32_t>(); - m_jobs.replaceWithLast(index); - if (index < m_jobs.size()) - { - NVBLAST_ASSERT(m_jobs[index].m_tkActor->m_groupJobIndex == m_jobs.size()); - NVBLAST_ASSERT(m_jobs[index].m_tkActor->isPending()); - m_jobs[index].m_tkActor->m_groupJobIndex = index; - } - } - - // if the actor is the last of its family in this group - // the group-family memory can be released - TkFamilyImpl* family = &tkActor.getFamilyImpl(); - SharedMemory* mem = getSharedMemory(family); - if (mem->removeReference()) - { - releaseSharedMemory(family, mem); - } - - return true; -} - - -TkGroupImpl* TkGroupImpl::create(const TkGroupDesc& desc) -{ - TkGroupImpl* group = NVBLAST_NEW(TkGroupImpl); - - group->setWorkerCount(desc.workerCount); - - return group; -} - - -void TkGroupImpl::setWorkerCount(uint32_t workerCount) -{ - if (isProcessing()) - { - NVBLAST_LOG_WARNING("TkGroup::setWorkerCount: Group is still processing, call TkGroup::endProcess first."); - return; - } - - if (workerCount == 0) - { - NVBLAST_LOG_WARNING("TkGroup: attempting to create a Group with 0 workers. Forced to 1."); - workerCount = 1; - } - - if (workerCount != m_workers.size()) - { - m_workers.resize(workerCount); - - uint32_t workerId = 0; - for (auto& worker : m_workers) - { - worker.m_id = workerId++; - worker.m_group = this; - } - - const uint32_t bondCount = m_bondTempDataBlock.numElementsPerBlock(); - if (bondCount > 0) - { - m_bondTempDataBlock.release(); - m_bondTempDataBlock.allocate(bondCount, workerCount); - m_bondEventDataBlock.release(); - m_bondEventDataBlock.allocate(bondCount, workerCount); - } - const uint32_t chunkCount = m_chunkTempDataBlock.numElementsPerBlock(); - if (chunkCount > 0) - { - m_chunkTempDataBlock.release(); - m_chunkTempDataBlock.allocate(chunkCount, workerCount); - m_chunkEventDataBlock.release(); - m_chunkEventDataBlock.allocate(chunkCount, workerCount); - } - const uint32_t scratchSize = m_splitScratchBlock.numElementsPerBlock(); - if (scratchSize > 0) - { - m_splitScratchBlock.release(); - m_splitScratchBlock.allocate(scratchSize, workerCount); - } - } -} - - -NV_INLINE uint32_t TkGroupImpl::getWorkerCount() const -{ - return m_workers.size(); -} - - -uint32_t TkGroupImpl::startProcess() -{ - BLAST_PROFILE_SCOPE_L("TkGroup::startProcess"); - - if (!setProcessing(true)) - { - NVBLAST_LOG_WARNING("TkGroup::process: Group is still processing, call TkGroup::endProcess first."); - return 0; - } - - if (m_jobs.size() > 0) - { - BLAST_PROFILE_ZONE_BEGIN("task setup"); - - BLAST_PROFILE_ZONE_BEGIN("setup job queue"); - for (const auto& job : m_jobs) - { - const TkActorImpl* a = job.m_tkActor; - SharedMemory* mem = getSharedMemory(&a->getFamilyImpl()); - - const uint32_t damageCount = a->m_damageBuffer.size(); - - // applyFracture'd actor do not necessarily have damage queued - NVBLAST_ASSERT(damageCount > 0 || a->m_flags.isSet(TkActorFlag::DAMAGED)); - - // no reason to be here without these - NVBLAST_ASSERT(a->m_flags.isSet(TkActorFlag::PENDING)); - NVBLAST_ASSERT(a->m_group == this); - - // collect the amount of event payload memory to preallocate for TkWorkers - mem->m_eventsMemory += damageCount * (sizeof(TkFractureCommands) + sizeof(TkFractureEvents)) + sizeof(TkSplitEvent); - - // collect the amount of event entries to preallocate for TkWorkers - // (two TkFracture* events per damage plus one TkSplitEvent) - mem->m_eventsCount += 2 * damageCount + 1; - } - BLAST_PROFILE_ZONE_END("setup job queue"); - - BLAST_PROFILE_ZONE_BEGIN("memory protect"); - for (auto it = m_sharedMemory.getIterator(); !it.done(); ++it) - { - // preallocate the event memory for TkWorkers - SharedMemory* mem = it->second; - mem->m_events.reserveData(mem->m_eventsMemory); - mem->m_events.reserveEvents(mem->m_eventsCount); - - // these counters are not used anymore - // reset them immediately for next time - mem->m_eventsCount = 0; - mem->m_eventsMemory = 0; - - // switch to parallel mode - mem->m_events.protect(true); - } - BLAST_PROFILE_ZONE_END("memory protect"); - - BLAST_PROFILE_ZONE_END("task setup"); - - - for (auto&worker : m_workers) - { - worker.initialize(); - } - - return m_jobs.size(); - } - else - { - bool success = setProcessing(false); - NVBLAST_ASSERT(success); - NV_UNUSED(success); - return 0; - } -} - - -bool TkGroupImpl::endProcess() -{ - if (isProcessing()) - { - BLAST_PROFILE_SCOPE_L("TkGroupImpl::endProcess"); - - if (m_jobs.size() > 0) - { -#if NV_PROFILE - BLAST_PROFILE_ZONE_BEGIN("accumulate timers"); - NvBlastTimers accumulated; - NvBlastTimersReset(&accumulated); - uint32_t jobCount = 0; - int64_t workerTime = 0; - for (TkWorker& worker : m_workers) - { - accumulated += worker.m_stats.timers; - jobCount += worker.m_stats.processedActorsCount; - workerTime += worker.m_stats.workerTime; - } - m_stats.timers = accumulated; - m_stats.processedActorsCount = jobCount; - m_stats.workerTime = workerTime; - BLAST_PROFILE_ZONE_END("accumulate timers"); -#endif - - BLAST_PROFILE_ZONE_BEGIN("job update"); - for (auto& j : m_jobs) - { - if (j.m_newActorsCount) - { - TkFamilyImpl* fam = &j.m_tkActor->getFamilyImpl(); - SharedMemory* mem = getSharedMemory(fam); - - // as LL is implemented, where newActorsCount the parent is always deleted - removeActorInternal(*j.m_tkActor); - mem->removeReference(); - addActorsInternal(j.m_newActors, j.m_newActorsCount); - mem->addReference(j.m_newActorsCount); - - // Update joints - mem->m_events.protect(false); // allow allocations again - BLAST_PROFILE_ZONE_BEGIN("updateJoints"); - fam->updateJoints(j.m_tkActor, &mem->m_events); - BLAST_PROFILE_ZONE_END("updateJoints"); - } - - // virtually dequeue the actor - // the queue itself is cleared right after this loop - j.m_tkActor->m_flags.clear(TkActorFlag::PENDING); - j.m_tkActor->m_groupJobIndex = invalidIndex<uint32_t>(); - BLAST_PROFILE_ZONE_BEGIN("damageBuffer.clear"); - j.m_tkActor->m_damageBuffer.clear(); - BLAST_PROFILE_ZONE_END("damageBuffer.clear"); - } - m_jobs.clear(); - BLAST_PROFILE_ZONE_END("job update"); - - BLAST_PROFILE_ZONE_BEGIN("event dispatch"); - for (auto it = m_sharedMemory.getIterator(); !it.done(); ++it) - { - BLAST_PROFILE_SCOPE_L("event dispatch"); - TkFamilyImpl* family = it->first; - SharedMemory* mem = it->second; - - NVBLAST_ASSERT(family != nullptr); - NVBLAST_ASSERT(mem != nullptr && mem->isUsed()); - - // where no actor of a family has split, - // its group/family event queue has not been - // unprotected in the jobs loop above - mem->m_events.protect(false); - - family->getQueue().dispatch(mem->m_events); - - mem->m_events.reset(); - mem->reset(); - } - BLAST_PROFILE_ZONE_END("event dispatch"); - - BLAST_PROFILE_ZONE_BEGIN("event memory release"); - for (auto& worker : m_workers) - { - worker.m_bondBuffer.clear(); - worker.m_chunkBuffer.clear(); - } - BLAST_PROFILE_ZONE_END("event memory release"); - } - - bool success = setProcessing(false); - NVBLAST_ASSERT(success); - return success; - } - - return false; -} - - -bool TkGroupImpl::setProcessing(bool value) -{ - bool expected = !value; - return m_isProcessing.compare_exchange_strong(expected, value); -} - - -void TkGroupImpl::enqueue(TkActorImpl* tkActor) -{ - NVBLAST_ASSERT(tkActor->getGroupImpl() != nullptr); - NVBLAST_ASSERT(tkActor->getGroupImpl() == this); - NVBLAST_ASSERT(isInvalidIndex(tkActor->m_groupJobIndex)); - NVBLAST_ASSERT(isProcessing() == false); -#if NV_DEBUG - for (TkWorkerJob& j : m_jobs) - { - NVBLAST_ASSERT(j.m_tkActor != tkActor); - } -#endif - - tkActor->m_groupJobIndex = m_jobs.size(); - TkWorkerJob& j = m_jobs.insert(); - j.m_tkActor = tkActor; -} - - -TkGroupWorker* TkGroupImpl::acquireWorker() -{ - BLAST_PROFILE_SCOPE_L("TkGroupImpl::acquireWorker"); - std::unique_lock<std::mutex> lk(m_workerMtx); - for (auto& worker:m_workers) - { - if (!worker.m_isBusy) - { - worker.m_isBusy = true; - return &worker; - } - } - return nullptr; -} - - -void TkGroupImpl::returnWorker(TkGroupWorker* worker) -{ - BLAST_PROFILE_SCOPE_L("TkGroupImpl::returnWorker"); - std::unique_lock<std::mutex> lk(m_workerMtx); - auto w = static_cast<TkWorker*>(worker); - NVBLAST_CHECK_WARNING(w->m_group == this, "TkGroup::returnWorker worker does not belong to this group.", return); - w->m_isBusy = false; -} - - -} // namespace Blast -} // namespace Nv +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#include "NvPreprocessor.h"
+
+#include "NvBlastAssert.h"
+#include "NvBlast.h"
+
+#include "NvBlastTkFrameworkImpl.h"
+#include "NvBlastTkGroupImpl.h"
+#include "NvBlastTkActorImpl.h"
+#include "NvBlastTkFamilyImpl.h"
+#include "NvBlastTkAssetImpl.h"
+#include "NvBlastTkTaskImpl.h"
+
+#undef max
+#undef min
+#include <algorithm>
+
+using namespace physx;
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+//////// Static data ////////
+
+NVBLASTTK_DEFINE_TYPE_IDENTIFIABLE(Group);
+
+
+//////// Member functions ////////
+
+TkGroupImpl::TkGroupImpl() : m_actorCount(0), m_isProcessing(false)
+{
+#if NV_PROFILE
+ memset(&m_stats, 0, sizeof(TkGroupStats));
+#endif
+}
+
+
+TkGroupImpl::~TkGroupImpl()
+{
+ NVBLAST_ASSERT(getActorCount() == 0);
+ NVBLAST_ASSERT(m_sharedMemory.size() == 0);
+}
+
+
+void TkGroupImpl::release()
+{
+ if (isProcessing())
+ {
+ // abort all processing?
+ NVBLAST_LOG_ERROR("TkGroup::release: cannot release Group while processing.");
+ NVBLAST_ALWAYS_ASSERT_MESSAGE("TkGroup::release: cannot release Group while processing.");
+ return;
+ }
+
+ for (auto it = m_sharedMemory.getIterator(); !it.done(); ++it)
+ {
+ TkFamilyImpl* family = it->first;
+ for (TkActorImpl& actor : family->getActorsInternal())
+ {
+ if (actor.m_group == this)
+ {
+ removeActorInternal(actor);
+ }
+ }
+ SharedMemory* mem = it->second;
+ mem->release();
+ NVBLAST_DELETE(mem, SharedMemory);
+ }
+ m_sharedMemory.clear();
+
+ m_bondTempDataBlock.release();
+ m_chunkTempDataBlock.release();
+ m_bondEventDataBlock.release();
+ m_chunkEventDataBlock.release();
+ m_splitScratchBlock.release();
+
+ NVBLAST_DELETE(this, TkGroupImpl);
+}
+
+
+void TkGroupImpl::addActorsInternal(TkActorImpl** actors, uint32_t numActors)
+{
+ for (uint32_t i = 0; i < numActors; i++)
+ {
+ addActorInternal(*actors[i]);
+ }
+}
+
+
+void TkGroupImpl::addActorInternal(TkActorImpl& tkActor)
+{
+ NVBLAST_ASSERT(tkActor.getGroup() == nullptr);
+ tkActor.m_group = this;
+ m_actorCount++;
+}
+
+
+bool TkGroupImpl::addActor(TkActor& actor)
+{
+ TkActorImpl& tkActor = static_cast<TkActorImpl&>(actor);
+ if (tkActor.getGroup() != nullptr)
+ {
+ NVBLAST_LOG_ERROR("TkGroup::addActor: actor already belongs to a Group. Remove from current group first.");
+ return false;
+ }
+
+ if (isProcessing())
+ {
+ NVBLAST_LOG_ERROR("TkGroup::addActor: cannot alter Group while processing.");
+ return false;
+ }
+
+ // mark the actor that it now belongs to this group
+ addActorInternal(tkActor);
+
+ // actors that were fractured already or have damage requested
+ // must be enqueued to be processed
+ if (tkActor.isPending())
+ {
+ enqueue(&tkActor);
+ }
+
+ TkFamilyImpl& family = tkActor.getFamilyImpl();
+ SharedMemory* mem = m_sharedMemory[&family];
+ if (mem == nullptr)
+ {
+ // the actor belongs to a family not involved in this group yet
+ // shared memory must be allocated and temporary buffers adjusted accordingly
+
+ BLAST_PROFILE_ZONE_BEGIN("family memory");
+ mem = NVBLAST_NEW(SharedMemory);
+ mem->allocate(family);
+ m_sharedMemory[&family] = mem;
+ BLAST_PROFILE_ZONE_END("family memory");
+
+ BLAST_PROFILE_ZONE_BEGIN("group memory");
+
+ const uint32_t workerCount = m_workers.size();
+
+ NvBlastLog theLog = logLL;
+
+ // this group's tasks will use one temporary buffer each, which is of max size of, for all families involved
+ const size_t requiredScratch = NvBlastActorGetRequiredScratchForSplit(tkActor.getActorLL(), theLog);
+ if (static_cast<size_t>(m_splitScratchBlock.numElementsPerBlock()) < requiredScratch)
+ {
+ m_splitScratchBlock.release();
+ m_splitScratchBlock.allocate(static_cast<uint32_t>(requiredScratch), workerCount);
+ }
+
+ // generate and apply fracture may create an entry for each bond
+ const uint32_t bondCount = NvBlastAssetGetBondCount(tkActor.getAsset()->getAssetLL(), theLog);
+ if (m_bondTempDataBlock.numElementsPerBlock() < bondCount)
+ {
+ m_bondTempDataBlock.release();
+ m_bondTempDataBlock.allocate(bondCount, workerCount);
+ m_bondEventDataBlock.release();
+ m_bondEventDataBlock.allocate(bondCount, workerCount);
+ }
+
+ // apply fracture may create an entry for each lower-support chunk
+ const uint32_t graphNodeCount = NvBlastAssetGetSupportGraph(tkActor.getAsset()->getAssetLL(), theLog).nodeCount;
+ const uint32_t subsupportChunkCount
+ = NvBlastAssetGetChunkCount(tkActor.getAsset()->getAssetLL(), theLog)
+ - NvBlastAssetGetFirstSubsupportChunkIndex(tkActor.getAsset()->getAssetLL(), theLog);
+ const uint32_t chunkCount = graphNodeCount + subsupportChunkCount;
+ if (m_chunkTempDataBlock.numElementsPerBlock() < chunkCount)
+ {
+ m_chunkTempDataBlock.release();
+ m_chunkTempDataBlock.allocate(chunkCount, workerCount);
+ m_chunkEventDataBlock.release();
+ m_chunkEventDataBlock.allocate(chunkCount, workerCount);
+ }
+ BLAST_PROFILE_ZONE_END("group memory");
+ }
+ mem->addReference();
+
+ return true;
+}
+
+
+uint32_t TkGroupImpl::getActors(TkActor** buffer, uint32_t bufferSize, uint32_t indexStart /* = 0 */) const
+{
+ BLAST_PROFILE_SCOPE_L("TkGroup::getActors");
+
+ uint32_t actorCount = m_actorCount;
+ if (actorCount <= indexStart)
+ {
+ NVBLAST_LOG_WARNING("TkGroup::getActors: indexStart beyond end of actor list.");
+ return 0;
+ }
+
+ actorCount -= indexStart;
+ if (actorCount > bufferSize)
+ {
+ actorCount = bufferSize;
+ }
+
+ uint32_t index = 0;
+ bool done = false;
+ for (auto it = const_cast<TkGroupImpl*>(this)->m_sharedMemory.getIterator(); !it.done();++it)
+ {
+ TkFamilyImpl* fam = it->first;
+ for (TkActorImpl& actor : fam->getActorsInternal())
+ {
+ if (actor.m_group == this)
+ {
+ NVBLAST_ASSERT(actor.isActive());
+
+ if (index >= indexStart)
+ {
+ *buffer++ = &actor;
+ }
+
+ index++;
+ done = (index - indexStart) >= actorCount;
+ }
+ if (done) break;
+ }
+ if (done) break;
+ }
+
+ return actorCount;
+}
+
+
+void TkGroupImpl::removeActorInternal(TkActorImpl& tkActor)
+{
+ NVBLAST_ASSERT(tkActor.m_group == this);
+ tkActor.m_group = nullptr;
+ m_actorCount--;
+}
+
+
+void TkGroupImpl::releaseSharedMemory(TkFamilyImpl* fam, SharedMemory* mem)
+{
+ NVBLAST_ASSERT(mem != nullptr && m_sharedMemory[fam] == mem);
+ mem->release();
+ m_sharedMemory.erase(fam);
+ NVBLAST_DELETE(mem, SharedMemory);
+}
+
+
+bool TkGroupImpl::removeActor(TkActor& actor)
+{
+ TkActorImpl& tkActor = static_cast<TkActorImpl&>(actor);
+
+ if (tkActor.getGroup() != this)
+ {
+ NVBLAST_LOG_ERROR("TkGroup::removeActor: actor does not belong to this Group.");
+ return false;
+ }
+
+ if (isProcessing())
+ {
+ NVBLAST_LOG_ERROR("TkGroup::removeActor: cannot alter Group while processing.");
+ return false;
+ }
+
+ removeActorInternal(tkActor);
+
+ // pending actors must be removed from the job queue as well
+ if(tkActor.isPending())
+ {
+ uint32_t index = tkActor.m_groupJobIndex;
+ tkActor.m_groupJobIndex = invalidIndex<uint32_t>();
+ m_jobs.replaceWithLast(index);
+ if (index < m_jobs.size())
+ {
+ NVBLAST_ASSERT(m_jobs[index].m_tkActor->m_groupJobIndex == m_jobs.size());
+ NVBLAST_ASSERT(m_jobs[index].m_tkActor->isPending());
+ m_jobs[index].m_tkActor->m_groupJobIndex = index;
+ }
+ }
+
+ // if the actor is the last of its family in this group
+ // the group-family memory can be released
+ TkFamilyImpl* family = &tkActor.getFamilyImpl();
+ SharedMemory* mem = getSharedMemory(family);
+ if (mem->removeReference())
+ {
+ releaseSharedMemory(family, mem);
+ }
+
+ return true;
+}
+
+
+TkGroupImpl* TkGroupImpl::create(const TkGroupDesc& desc)
+{
+ TkGroupImpl* group = NVBLAST_NEW(TkGroupImpl);
+
+ group->setWorkerCount(desc.workerCount);
+
+ return group;
+}
+
+
+void TkGroupImpl::setWorkerCount(uint32_t workerCount)
+{
+ if (isProcessing())
+ {
+ NVBLAST_LOG_WARNING("TkGroup::setWorkerCount: Group is still processing, call TkGroup::endProcess first.");
+ return;
+ }
+
+ if (workerCount == 0)
+ {
+ NVBLAST_LOG_WARNING("TkGroup: attempting to create a Group with 0 workers. Forced to 1.");
+ workerCount = 1;
+ }
+
+ if (workerCount != m_workers.size())
+ {
+ m_workers.resize(workerCount);
+
+ uint32_t workerId = 0;
+ for (auto& worker : m_workers)
+ {
+ worker.m_id = workerId++;
+ worker.m_group = this;
+ }
+
+ const uint32_t bondCount = m_bondTempDataBlock.numElementsPerBlock();
+ if (bondCount > 0)
+ {
+ m_bondTempDataBlock.release();
+ m_bondTempDataBlock.allocate(bondCount, workerCount);
+ m_bondEventDataBlock.release();
+ m_bondEventDataBlock.allocate(bondCount, workerCount);
+ }
+ const uint32_t chunkCount = m_chunkTempDataBlock.numElementsPerBlock();
+ if (chunkCount > 0)
+ {
+ m_chunkTempDataBlock.release();
+ m_chunkTempDataBlock.allocate(chunkCount, workerCount);
+ m_chunkEventDataBlock.release();
+ m_chunkEventDataBlock.allocate(chunkCount, workerCount);
+ }
+ const uint32_t scratchSize = m_splitScratchBlock.numElementsPerBlock();
+ if (scratchSize > 0)
+ {
+ m_splitScratchBlock.release();
+ m_splitScratchBlock.allocate(scratchSize, workerCount);
+ }
+ }
+}
+
+
+NV_INLINE uint32_t TkGroupImpl::getWorkerCount() const
+{
+ return m_workers.size();
+}
+
+
+uint32_t TkGroupImpl::startProcess()
+{
+ BLAST_PROFILE_SCOPE_L("TkGroup::startProcess");
+
+ if (!setProcessing(true))
+ {
+ NVBLAST_LOG_WARNING("TkGroup::process: Group is still processing, call TkGroup::endProcess first.");
+ return 0;
+ }
+
+ if (m_jobs.size() > 0)
+ {
+ BLAST_PROFILE_ZONE_BEGIN("task setup");
+
+ BLAST_PROFILE_ZONE_BEGIN("setup job queue");
+ for (const auto& job : m_jobs)
+ {
+ const TkActorImpl* a = job.m_tkActor;
+ SharedMemory* mem = getSharedMemory(&a->getFamilyImpl());
+
+ const uint32_t damageCount = a->m_damageBuffer.size();
+
+ // applyFracture'd actor do not necessarily have damage queued
+ NVBLAST_ASSERT(damageCount > 0 || a->m_flags.isSet(TkActorFlag::DAMAGED));
+
+ // no reason to be here without these
+ NVBLAST_ASSERT(a->m_flags.isSet(TkActorFlag::PENDING));
+ NVBLAST_ASSERT(a->m_group == this);
+
+ // collect the amount of event payload memory to preallocate for TkWorkers
+ mem->m_eventsMemory += damageCount * (sizeof(TkFractureCommands) + sizeof(TkFractureEvents)) + sizeof(TkSplitEvent);
+
+ // collect the amount of event entries to preallocate for TkWorkers
+ // (two TkFracture* events per damage plus one TkSplitEvent)
+ mem->m_eventsCount += 2 * damageCount + 1;
+ }
+ BLAST_PROFILE_ZONE_END("setup job queue");
+
+ BLAST_PROFILE_ZONE_BEGIN("memory protect");
+ for (auto it = m_sharedMemory.getIterator(); !it.done(); ++it)
+ {
+ // preallocate the event memory for TkWorkers
+ SharedMemory* mem = it->second;
+ mem->m_events.reserveData(mem->m_eventsMemory);
+ mem->m_events.reserveEvents(mem->m_eventsCount);
+
+ // these counters are not used anymore
+ // reset them immediately for next time
+ mem->m_eventsCount = 0;
+ mem->m_eventsMemory = 0;
+
+ // switch to parallel mode
+ mem->m_events.protect(true);
+ }
+ BLAST_PROFILE_ZONE_END("memory protect");
+
+ BLAST_PROFILE_ZONE_END("task setup");
+
+
+ for (auto&worker : m_workers)
+ {
+ worker.initialize();
+ }
+
+ return m_jobs.size();
+ }
+ else
+ {
+ bool success = setProcessing(false);
+ NVBLAST_ASSERT(success);
+ NV_UNUSED(success);
+ return 0;
+ }
+}
+
+
+bool TkGroupImpl::endProcess()
+{
+ if (isProcessing())
+ {
+ BLAST_PROFILE_SCOPE_L("TkGroupImpl::endProcess");
+
+ if (m_jobs.size() > 0)
+ {
+#if NV_PROFILE
+ BLAST_PROFILE_ZONE_BEGIN("accumulate timers");
+ NvBlastTimers accumulated;
+ NvBlastTimersReset(&accumulated);
+ uint32_t jobCount = 0;
+ int64_t workerTime = 0;
+ for (TkWorker& worker : m_workers)
+ {
+ accumulated += worker.m_stats.timers;
+ jobCount += worker.m_stats.processedActorsCount;
+ workerTime += worker.m_stats.workerTime;
+ }
+ m_stats.timers = accumulated;
+ m_stats.processedActorsCount = jobCount;
+ m_stats.workerTime = workerTime;
+ BLAST_PROFILE_ZONE_END("accumulate timers");
+#endif
+
+ BLAST_PROFILE_ZONE_BEGIN("job update");
+ for (auto& j : m_jobs)
+ {
+ if (j.m_newActorsCount)
+ {
+ TkFamilyImpl* fam = &j.m_tkActor->getFamilyImpl();
+ SharedMemory* mem = getSharedMemory(fam);
+
+ // as LL is implemented, where newActorsCount the parent is always deleted
+ removeActorInternal(*j.m_tkActor);
+ mem->removeReference();
+ addActorsInternal(j.m_newActors, j.m_newActorsCount);
+ mem->addReference(j.m_newActorsCount);
+
+ // Update joints
+ mem->m_events.protect(false); // allow allocations again
+ BLAST_PROFILE_ZONE_BEGIN("updateJoints");
+ fam->updateJoints(j.m_tkActor, &mem->m_events);
+ BLAST_PROFILE_ZONE_END("updateJoints");
+ }
+
+ // virtually dequeue the actor
+ // the queue itself is cleared right after this loop
+ j.m_tkActor->m_flags.clear(TkActorFlag::PENDING);
+ j.m_tkActor->m_groupJobIndex = invalidIndex<uint32_t>();
+ BLAST_PROFILE_ZONE_BEGIN("damageBuffer.clear");
+ j.m_tkActor->m_damageBuffer.clear();
+ BLAST_PROFILE_ZONE_END("damageBuffer.clear");
+ }
+ m_jobs.clear();
+ BLAST_PROFILE_ZONE_END("job update");
+
+ BLAST_PROFILE_ZONE_BEGIN("event dispatch");
+ for (auto it = m_sharedMemory.getIterator(); !it.done(); ++it)
+ {
+ BLAST_PROFILE_SCOPE_L("event dispatch");
+ TkFamilyImpl* family = it->first;
+ SharedMemory* mem = it->second;
+
+ NVBLAST_ASSERT(family != nullptr);
+ NVBLAST_ASSERT(mem != nullptr && mem->isUsed());
+
+ // where no actor of a family has split,
+ // its group/family event queue has not been
+ // unprotected in the jobs loop above
+ mem->m_events.protect(false);
+
+ family->getQueue().dispatch(mem->m_events);
+
+ mem->m_events.reset();
+ mem->reset();
+ }
+ BLAST_PROFILE_ZONE_END("event dispatch");
+
+ BLAST_PROFILE_ZONE_BEGIN("event memory release");
+ for (auto& worker : m_workers)
+ {
+ worker.m_bondBuffer.clear();
+ worker.m_chunkBuffer.clear();
+ }
+ BLAST_PROFILE_ZONE_END("event memory release");
+ }
+
+ bool success = setProcessing(false);
+ NVBLAST_ASSERT(success);
+ return success;
+ }
+
+ return false;
+}
+
+
+bool TkGroupImpl::setProcessing(bool value)
+{
+ bool expected = !value;
+ return m_isProcessing.compare_exchange_strong(expected, value);
+}
+
+
+void TkGroupImpl::enqueue(TkActorImpl* tkActor)
+{
+ NVBLAST_ASSERT(tkActor->getGroupImpl() != nullptr);
+ NVBLAST_ASSERT(tkActor->getGroupImpl() == this);
+ NVBLAST_ASSERT(isInvalidIndex(tkActor->m_groupJobIndex));
+ NVBLAST_ASSERT(isProcessing() == false);
+#if NV_DEBUG
+ for (TkWorkerJob& j : m_jobs)
+ {
+ NVBLAST_ASSERT(j.m_tkActor != tkActor);
+ }
+#endif
+
+ tkActor->m_groupJobIndex = m_jobs.size();
+ TkWorkerJob& j = m_jobs.insert();
+ j.m_tkActor = tkActor;
+}
+
+
+TkGroupWorker* TkGroupImpl::acquireWorker()
+{
+ BLAST_PROFILE_SCOPE_L("TkGroupImpl::acquireWorker");
+ std::unique_lock<std::mutex> lk(m_workerMtx);
+ for (auto& worker:m_workers)
+ {
+ if (!worker.m_isBusy)
+ {
+ worker.m_isBusy = true;
+ return &worker;
+ }
+ }
+ return nullptr;
+}
+
+
+void TkGroupImpl::returnWorker(TkGroupWorker* worker)
+{
+ BLAST_PROFILE_SCOPE_L("TkGroupImpl::returnWorker");
+ std::unique_lock<std::mutex> lk(m_workerMtx);
+ auto w = static_cast<TkWorker*>(worker);
+ NVBLAST_CHECK_WARNING(w->m_group == this, "TkGroup::returnWorker worker does not belong to this group.", return);
+ w->m_isBusy = false;
+}
+
+
+} // namespace Blast
+} // namespace Nv
diff --git a/sdk/toolkit/source/NvBlastTkGroupImpl.h b/sdk/toolkit/source/NvBlastTkGroupImpl.h index be617c0..6807832 100644..100755 --- a/sdk/toolkit/source/NvBlastTkGroupImpl.h +++ b/sdk/toolkit/source/NvBlastTkGroupImpl.h @@ -1,194 +1,194 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#ifndef NVBLASTTKGROUPIMPL_H -#define NVBLASTTKGROUPIMPL_H - - -#include "NvBlastTkTaskImpl.h" -#include "NvBlastTkGroup.h" -#include "NvBlastTkTypeImpl.h" - - -namespace Nv -{ -namespace Blast -{ - -class TkActorImpl; -class TkFamilyImpl; - -NVBLASTTK_IMPL_DECLARE(Group) -{ - ~TkGroupImpl(); - -public: - TkGroupImpl(); - - NVBLASTTK_IMPL_DEFINE_IDENTIFIABLE('G', 'R', 'P', '\0'); - - static TkGroupImpl* create(const TkGroupDesc& desc); - - // Begin TkGroup - virtual bool addActor(TkActor& actor) override; - - virtual uint32_t getActorCount() const override; - - virtual uint32_t getActors(TkActor** buffer, uint32_t bufferSize, uint32_t indexStart = 0) const override; - - virtual uint32_t startProcess() override; - virtual bool endProcess() override; - - virtual void getStats(TkGroupStats& stats) const override; - - virtual void setWorkerCount(uint32_t workerCount) override; - virtual uint32_t getWorkerCount() const override; - - virtual TkGroupWorker* acquireWorker() override; - virtual void returnWorker(TkGroupWorker*) override; - // End TkGroup - - // TkGroupImpl API - - /** - Remove the actor from this group if the actor actually belongs to it and the group is not processing. - - \param[in] actor The TkActor to remove. - - \return true if removing succeeded, false otherwise - */ - bool removeActor(TkActor& actor); - - /** - Add the actor to this group's job queue. - It is the caller's responsibility to add an actor only once. This condition is checked in debug builds. - */ - void enqueue(TkActorImpl* tkActor); - - /** - Atomically check if this group is processing actors. @see setProcessing() - - \return true between startProcess() and endProcess() calls, false otherwise - */ - bool isProcessing() const; - -private: - /** - Atomically set the processing state. This function checks for the current state - before changing it. @see isProcessing() - - \param[in] value the value of the new state - - \return true if the new state could be set, false otherwise - */ - bool setProcessing(bool value); - - /** - Get the group-family shared memory for the specified family. To be used when the memory is expected to already exist. - */ - SharedMemory* getSharedMemory(TkFamilyImpl* family); - void releaseSharedMemory(TkFamilyImpl* fam, SharedMemory* mem); - - // functions to add/remove actors _without_ group-family memory management - void addActorInternal(TkActorImpl& tkActor); - void addActorsInternal(TkActorImpl** actors, uint32_t numActors); - void removeActorInternal(TkActorImpl& tkActor); - - - uint32_t m_actorCount; //!< number of actors in this group - - HashMap<TkFamilyImpl*, SharedMemory*>::type m_sharedMemory; //!< memory sharable by actors in the same family in this group - - // it is assumed no more than the asset's number of bond and chunks fracture commands are produced - SharedBlock<NvBlastChunkFractureData> m_chunkTempDataBlock; //!< chunk data for damage/fracture - SharedBlock<NvBlastBondFractureData> m_bondTempDataBlock; //!< bond data for damage/fracture - SharedBlock<NvBlastChunkFractureData> m_chunkEventDataBlock; //!< initial memory block for event data - SharedBlock<NvBlastBondFractureData> m_bondEventDataBlock; //!< initial memory block for event data - SharedBlock<char> m_splitScratchBlock; //!< split scratch memory - - std::atomic<bool> m_isProcessing; //!< true while workers are processing - - Array<TkWorker>::type m_workers; //!< this group's workers - - Array<TkWorkerJob>::type m_jobs; //!< this group's process jobs - -//#if NV_PROFILE - TkGroupStats m_stats; //!< accumulated group's worker stats -//#endif - - std::mutex m_workerMtx; - - friend class TkWorker; -}; - - -NV_INLINE bool TkGroupImpl::isProcessing() const -{ - return m_isProcessing.load(); -} - - -NV_INLINE void TkGroupImpl::getStats(TkGroupStats& stats) const -{ -#if NV_PROFILE - memcpy(&stats, &m_stats, sizeof(TkGroupStats)); -#else - NV_UNUSED(stats); -#endif -} - - -NV_INLINE uint32_t TkGroupImpl::getActorCount() const -{ - return m_actorCount; -} - - -NV_INLINE SharedMemory* TkGroupImpl::getSharedMemory(TkFamilyImpl* family) -{ - SharedMemory* mem = m_sharedMemory[family]; - NVBLAST_ASSERT(mem != nullptr); - return mem; -} - - -NV_FORCE_INLINE void operator +=(NvBlastTimers& lhs, const NvBlastTimers& rhs) -{ - lhs.material += rhs.material; - lhs.fracture += rhs.fracture; - lhs.island += rhs.fracture; - lhs.partition += rhs.partition; - lhs.visibility += rhs.visibility; -} - - -} // namespace Blast -} // namespace Nv - - -#endif // ifndef NVBLASTTKGROUPIMPL_H +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#ifndef NVBLASTTKGROUPIMPL_H
+#define NVBLASTTKGROUPIMPL_H
+
+
+#include "NvBlastTkTaskImpl.h"
+#include "NvBlastTkGroup.h"
+#include "NvBlastTkTypeImpl.h"
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+class TkActorImpl;
+class TkFamilyImpl;
+
+NVBLASTTK_IMPL_DECLARE(Group)
+{
+ ~TkGroupImpl();
+
+public:
+ TkGroupImpl();
+
+ NVBLASTTK_IMPL_DEFINE_IDENTIFIABLE('G', 'R', 'P', '\0');
+
+ static TkGroupImpl* create(const TkGroupDesc& desc);
+
+ // Begin TkGroup
+ virtual bool addActor(TkActor& actor) override;
+
+ virtual uint32_t getActorCount() const override;
+
+ virtual uint32_t getActors(TkActor** buffer, uint32_t bufferSize, uint32_t indexStart = 0) const override;
+
+ virtual uint32_t startProcess() override;
+ virtual bool endProcess() override;
+
+ virtual void getStats(TkGroupStats& stats) const override;
+
+ virtual void setWorkerCount(uint32_t workerCount) override;
+ virtual uint32_t getWorkerCount() const override;
+
+ virtual TkGroupWorker* acquireWorker() override;
+ virtual void returnWorker(TkGroupWorker*) override;
+ // End TkGroup
+
+ // TkGroupImpl API
+
+ /**
+ Remove the actor from this group if the actor actually belongs to it and the group is not processing.
+
+ \param[in] actor The TkActor to remove.
+
+ \return true if removing succeeded, false otherwise
+ */
+ bool removeActor(TkActor& actor);
+
+ /**
+ Add the actor to this group's job queue.
+ It is the caller's responsibility to add an actor only once. This condition is checked in debug builds.
+ */
+ void enqueue(TkActorImpl* tkActor);
+
+ /**
+ Atomically check if this group is processing actors. @see setProcessing()
+
+ \return true between startProcess() and endProcess() calls, false otherwise
+ */
+ bool isProcessing() const;
+
+private:
+ /**
+ Atomically set the processing state. This function checks for the current state
+ before changing it. @see isProcessing()
+
+ \param[in] value the value of the new state
+
+ \return true if the new state could be set, false otherwise
+ */
+ bool setProcessing(bool value);
+
+ /**
+ Get the group-family shared memory for the specified family. To be used when the memory is expected to already exist.
+ */
+ SharedMemory* getSharedMemory(TkFamilyImpl* family);
+ void releaseSharedMemory(TkFamilyImpl* fam, SharedMemory* mem);
+
+ // functions to add/remove actors _without_ group-family memory management
+ void addActorInternal(TkActorImpl& tkActor);
+ void addActorsInternal(TkActorImpl** actors, uint32_t numActors);
+ void removeActorInternal(TkActorImpl& tkActor);
+
+
+ uint32_t m_actorCount; //!< number of actors in this group
+
+ HashMap<TkFamilyImpl*, SharedMemory*>::type m_sharedMemory; //!< memory sharable by actors in the same family in this group
+
+ // it is assumed no more than the asset's number of bond and chunks fracture commands are produced
+ SharedBlock<NvBlastChunkFractureData> m_chunkTempDataBlock; //!< chunk data for damage/fracture
+ SharedBlock<NvBlastBondFractureData> m_bondTempDataBlock; //!< bond data for damage/fracture
+ SharedBlock<NvBlastChunkFractureData> m_chunkEventDataBlock; //!< initial memory block for event data
+ SharedBlock<NvBlastBondFractureData> m_bondEventDataBlock; //!< initial memory block for event data
+ SharedBlock<char> m_splitScratchBlock; //!< split scratch memory
+
+ std::atomic<bool> m_isProcessing; //!< true while workers are processing
+
+ Array<TkWorker>::type m_workers; //!< this group's workers
+
+ Array<TkWorkerJob>::type m_jobs; //!< this group's process jobs
+
+//#if NV_PROFILE
+ TkGroupStats m_stats; //!< accumulated group's worker stats
+//#endif
+
+ std::mutex m_workerMtx;
+
+ friend class TkWorker;
+};
+
+
+NV_INLINE bool TkGroupImpl::isProcessing() const
+{
+ return m_isProcessing.load();
+}
+
+
+NV_INLINE void TkGroupImpl::getStats(TkGroupStats& stats) const
+{
+#if NV_PROFILE
+ memcpy(&stats, &m_stats, sizeof(TkGroupStats));
+#else
+ NV_UNUSED(stats);
+#endif
+}
+
+
+NV_INLINE uint32_t TkGroupImpl::getActorCount() const
+{
+ return m_actorCount;
+}
+
+
+NV_INLINE SharedMemory* TkGroupImpl::getSharedMemory(TkFamilyImpl* family)
+{
+ SharedMemory* mem = m_sharedMemory[family];
+ NVBLAST_ASSERT(mem != nullptr);
+ return mem;
+}
+
+
+NV_FORCE_INLINE void operator +=(NvBlastTimers& lhs, const NvBlastTimers& rhs)
+{
+ lhs.material += rhs.material;
+ lhs.fracture += rhs.fracture;
+ lhs.island += rhs.fracture;
+ lhs.partition += rhs.partition;
+ lhs.visibility += rhs.visibility;
+}
+
+
+} // namespace Blast
+} // namespace Nv
+
+
+#endif // ifndef NVBLASTTKGROUPIMPL_H
diff --git a/sdk/toolkit/source/NvBlastTkJointImpl.cpp b/sdk/toolkit/source/NvBlastTkJointImpl.cpp index 18ee8d0..48c8370 100644..100755 --- a/sdk/toolkit/source/NvBlastTkJointImpl.cpp +++ b/sdk/toolkit/source/NvBlastTkJointImpl.cpp @@ -1,195 +1,195 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#include "NvBlastTkFrameworkImpl.h" -#include "NvBlastTkJointImpl.h" -#include "NvBlastTkActorImpl.h" -#include "NvBlastTkAssetImpl.h" -#include "NvBlastTkFamilyImpl.h" - - -namespace Nv -{ -namespace Blast -{ - -//////// Member functions //////// - -TkJointImpl::TkJointImpl(const TkJointDesc& desc, TkFamilyImpl* owner) : m_owner(owner) -{ - userData = nullptr; - - // Do not fire off a creation event. Creation events will only be fired when a family-internal joint is created. - NVBLAST_ASSERT(desc.families[0] != nullptr || desc.families[1] != nullptr); - NVBLAST_ASSERT(desc.families[0] == nullptr || desc.chunkIndices[0] < static_cast<TkFamilyImpl*>(desc.families[0])->getAssetImpl()->getChunkCount()); - NVBLAST_ASSERT(desc.attachPositions[0].isFinite()); - NVBLAST_ASSERT(desc.families[1] == nullptr || desc.chunkIndices[1] < static_cast<TkFamilyImpl*>(desc.families[1])->getAssetImpl()->getChunkCount()); - NVBLAST_ASSERT(desc.attachPositions[1].isFinite()); - - for (int i = 0; i < 2; ++i) - { - m_data.actors[i] = desc.families[i] != nullptr ? static_cast<TkFamilyImpl*>(desc.families[i])->getActorByChunk(desc.chunkIndices[i]) : nullptr; - m_data.chunkIndices[i] = desc.chunkIndices[i]; - m_data.attachPositions[i] = desc.attachPositions[i]; - m_links[i].m_joint = this; - } - - if (owner == nullptr) - { - TkFrameworkImpl::get()->onCreate(*this); - } -} - - -void TkJointImpl::release() -{ - removeReferencesInActors(); - - if (m_owner != nullptr) - { - // Internal joint - m_owner->releaseJoint(*this); - } - else - { - // External joint - removeReferencesInFamilies(); - TkFrameworkImpl::get()->onDestroy(*this); - NVBLAST_DELETE(this, TkJointImpl); - } -} - - -void TkJointImpl::setActors(TkActorImpl* actor0, TkActorImpl* actor1, TkEventQueue* alternateQueue) -{ - NVBLAST_ASSERT(m_data.actors[0] != nullptr || m_data.actors[1] != nullptr); - - const bool unreferenced = (actor0 == nullptr && m_data.actors[0] != nullptr) || (actor1 == nullptr && m_data.actors[1] != nullptr); - - removeReferencesInActors(); - - if (!unreferenced) - { - if (actor0 != nullptr) - { - actor0->addJoint(m_links[0]); - } - - if (actor1 != nullptr && actor1 != actor0) // If the actors are the same, we only need one joint reference - { - actor1->addJoint(m_links[1]); - } - } - - // We do _not_ return if m_data.m_actors[0] == actor0 && m_data.m_actors[1] == actor1 since - // this leads to a bug. This function will only be called when an actor is split. It is - // possible that the two TkActors in a joint are the same as before, but in this case one - // of the actors will be the split actor. Since will be represented by a different - // physical actor, this case still needs to be reported in an event. Returning when neither - // TkActor has changed will prevent that, and lead to unwanted joint disconnection. - - const uint32_t familyToUse = m_data.actors[0] != actor0 ? 0 : 1; - - TkEventQueue* q = alternateQueue == nullptr ? - &static_cast<TkActorImpl*>(m_data.actors[familyToUse])->getFamilyImpl().getQueue() - : alternateQueue; - - const bool jointWasInternal = m_data.actors[0] == m_data.actors[1]; - - if (unreferenced) - { - removeReferencesInFamilies(); - actor0 = actor1 = nullptr; // Make both new actors NULL - } - - if (!jointWasInternal || actor0 != actor1) - { - // The original actors were different, or they are now, signal a joint update - TkJointUpdateEvent* e = q->allocData<TkJointUpdateEvent>(); - e->joint = this; - e->subtype = unreferenced ? TkJointUpdateEvent::Unreferenced : (jointWasInternal ? TkJointUpdateEvent::External : TkJointUpdateEvent::Changed); - m_data.actors[0] = actor0; - m_data.actors[1] = actor1; - q->addEvent(e); - } - else - if (jointWasInternal) - { - // The joint was originally created within the same actor and now it remains within the same actor. - m_data.actors[0] = m_data.actors[1] = actor0; - } -} - - -const TkJointData TkJointImpl::getData() const -{ - return getDataInternal(); -} - - -void TkJointImpl::removeReferencesInActors() -{ - TkActorImpl* actor0 = static_cast<TkActorImpl*>(m_data.actors[0]); - TkActorImpl* actor1 = static_cast<TkActorImpl*>(m_data.actors[1]); - - if (actor0 != nullptr) - { - actor0->removeJoint(m_links[0]); - } - - if (actor1 != nullptr && actor1 != actor0) // If the actors are the same, we only had one joint reference - { - actor1->removeJoint(m_links[1]); - } -} - - -void TkJointImpl::removeReferencesInFamilies() -{ - if (m_owner != nullptr) - { - return; // Only concerned with external joints - } - - NVBLAST_ASSERT(m_data.actors[0] != m_data.actors[1] || m_data.actors[0] == nullptr); // This is enforced by the initial assumption in TkFrameworkImpl::createJoint. - - for (int i = 0; i < 2; ++i) - { - if (m_data.actors[i] != nullptr) - { - TkFamilyImpl& family = static_cast<TkActorImpl*>(m_data.actors[i])->getFamilyImpl(); - TkJointImpl* joint = nullptr; - const bool found = family.deleteExternalJointHandle(joint, getFamilyID(m_data.actors[i ^ 1]), m_data.chunkIndices[i], m_data.chunkIndices[i ^ 1]); - NVBLAST_ASSERT((!found && m_data.actors[i ^ 1] == nullptr) || joint == this); // Might not be found if the actors in a family are in the process of being deleted - NV_UNUSED(found); - } - } -} - -} // namespace Blast -} // namespace Nv +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#include "NvBlastTkFrameworkImpl.h"
+#include "NvBlastTkJointImpl.h"
+#include "NvBlastTkActorImpl.h"
+#include "NvBlastTkAssetImpl.h"
+#include "NvBlastTkFamilyImpl.h"
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+//////// Member functions ////////
+
+TkJointImpl::TkJointImpl(const TkJointDesc& desc, TkFamilyImpl* owner) : m_owner(owner)
+{
+ userData = nullptr;
+
+ // Do not fire off a creation event. Creation events will only be fired when a family-internal joint is created.
+ NVBLAST_ASSERT(desc.families[0] != nullptr || desc.families[1] != nullptr);
+ NVBLAST_ASSERT(desc.families[0] == nullptr || desc.chunkIndices[0] < static_cast<TkFamilyImpl*>(desc.families[0])->getAssetImpl()->getChunkCount());
+ NVBLAST_ASSERT(desc.attachPositions[0].isFinite());
+ NVBLAST_ASSERT(desc.families[1] == nullptr || desc.chunkIndices[1] < static_cast<TkFamilyImpl*>(desc.families[1])->getAssetImpl()->getChunkCount());
+ NVBLAST_ASSERT(desc.attachPositions[1].isFinite());
+
+ for (int i = 0; i < 2; ++i)
+ {
+ m_data.actors[i] = desc.families[i] != nullptr ? static_cast<TkFamilyImpl*>(desc.families[i])->getActorByChunk(desc.chunkIndices[i]) : nullptr;
+ m_data.chunkIndices[i] = desc.chunkIndices[i];
+ m_data.attachPositions[i] = desc.attachPositions[i];
+ m_links[i].m_joint = this;
+ }
+
+ if (owner == nullptr)
+ {
+ TkFrameworkImpl::get()->onCreate(*this);
+ }
+}
+
+
+void TkJointImpl::release()
+{
+ removeReferencesInActors();
+
+ if (m_owner != nullptr)
+ {
+ // Internal joint
+ m_owner->releaseJoint(*this);
+ }
+ else
+ {
+ // External joint
+ removeReferencesInFamilies();
+ TkFrameworkImpl::get()->onDestroy(*this);
+ NVBLAST_DELETE(this, TkJointImpl);
+ }
+}
+
+
+void TkJointImpl::setActors(TkActorImpl* actor0, TkActorImpl* actor1, TkEventQueue* alternateQueue)
+{
+ NVBLAST_ASSERT(m_data.actors[0] != nullptr || m_data.actors[1] != nullptr);
+
+ const bool unreferenced = (actor0 == nullptr && m_data.actors[0] != nullptr) || (actor1 == nullptr && m_data.actors[1] != nullptr);
+
+ removeReferencesInActors();
+
+ if (!unreferenced)
+ {
+ if (actor0 != nullptr)
+ {
+ actor0->addJoint(m_links[0]);
+ }
+
+ if (actor1 != nullptr && actor1 != actor0) // If the actors are the same, we only need one joint reference
+ {
+ actor1->addJoint(m_links[1]);
+ }
+ }
+
+ // We do _not_ return if m_data.m_actors[0] == actor0 && m_data.m_actors[1] == actor1 since
+ // this leads to a bug. This function will only be called when an actor is split. It is
+ // possible that the two TkActors in a joint are the same as before, but in this case one
+ // of the actors will be the split actor. Since will be represented by a different
+ // physical actor, this case still needs to be reported in an event. Returning when neither
+ // TkActor has changed will prevent that, and lead to unwanted joint disconnection.
+
+ const uint32_t familyToUse = m_data.actors[0] != actor0 ? 0 : 1;
+
+ TkEventQueue* q = alternateQueue == nullptr ?
+ &static_cast<TkActorImpl*>(m_data.actors[familyToUse])->getFamilyImpl().getQueue()
+ : alternateQueue;
+
+ const bool jointWasInternal = m_data.actors[0] == m_data.actors[1];
+
+ if (unreferenced)
+ {
+ removeReferencesInFamilies();
+ actor0 = actor1 = nullptr; // Make both new actors NULL
+ }
+
+ if (!jointWasInternal || actor0 != actor1)
+ {
+ // The original actors were different, or they are now, signal a joint update
+ TkJointUpdateEvent* e = q->allocData<TkJointUpdateEvent>();
+ e->joint = this;
+ e->subtype = unreferenced ? TkJointUpdateEvent::Unreferenced : (jointWasInternal ? TkJointUpdateEvent::External : TkJointUpdateEvent::Changed);
+ m_data.actors[0] = actor0;
+ m_data.actors[1] = actor1;
+ q->addEvent(e);
+ }
+ else
+ if (jointWasInternal)
+ {
+ // The joint was originally created within the same actor and now it remains within the same actor.
+ m_data.actors[0] = m_data.actors[1] = actor0;
+ }
+}
+
+
+const TkJointData TkJointImpl::getData() const
+{
+ return getDataInternal();
+}
+
+
+void TkJointImpl::removeReferencesInActors()
+{
+ TkActorImpl* actor0 = static_cast<TkActorImpl*>(m_data.actors[0]);
+ TkActorImpl* actor1 = static_cast<TkActorImpl*>(m_data.actors[1]);
+
+ if (actor0 != nullptr)
+ {
+ actor0->removeJoint(m_links[0]);
+ }
+
+ if (actor1 != nullptr && actor1 != actor0) // If the actors are the same, we only had one joint reference
+ {
+ actor1->removeJoint(m_links[1]);
+ }
+}
+
+
+void TkJointImpl::removeReferencesInFamilies()
+{
+ if (m_owner != nullptr)
+ {
+ return; // Only concerned with external joints
+ }
+
+ NVBLAST_ASSERT(m_data.actors[0] != m_data.actors[1] || m_data.actors[0] == nullptr); // This is enforced by the initial assumption in TkFrameworkImpl::createJoint.
+
+ for (int i = 0; i < 2; ++i)
+ {
+ if (m_data.actors[i] != nullptr)
+ {
+ TkFamilyImpl& family = static_cast<TkActorImpl*>(m_data.actors[i])->getFamilyImpl();
+ TkJointImpl* joint = nullptr;
+ const bool found = family.deleteExternalJointHandle(joint, getFamilyID(m_data.actors[i ^ 1]), m_data.chunkIndices[i], m_data.chunkIndices[i ^ 1]);
+ NVBLAST_ASSERT((!found && m_data.actors[i ^ 1] == nullptr) || joint == this); // Might not be found if the actors in a family are in the process of being deleted
+ NV_UNUSED(found);
+ }
+ }
+}
+
+} // namespace Blast
+} // namespace Nv
diff --git a/sdk/toolkit/source/NvBlastTkJointImpl.h b/sdk/toolkit/source/NvBlastTkJointImpl.h index 773481b..8be96cd 100644..100755 --- a/sdk/toolkit/source/NvBlastTkJointImpl.h +++ b/sdk/toolkit/source/NvBlastTkJointImpl.h @@ -1,164 +1,164 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#ifndef NVBLASTTKJOINTIMPL_H -#define NVBLASTTKJOINTIMPL_H - - -#include "NvBlastTkJoint.h" -#include "NvBlastTkCommon.h" -#include "NvBlastIndexFns.h" - -#include "NvBlastAssert.h" -#include "NvBlastDLink.h" - -#include <atomic> - - -namespace Nv -{ -namespace Blast -{ - -// Forward declarations -class TkActorImpl; -class TkJointImpl; -class TkFamilyImpl; -class TkEventQueue; - - -/** -Double-sided link (DLink) which holds a reference back to a joint which contains it. -*/ -struct TkJointLink : public DLink -{ - TkJointImpl* m_joint; //!< The joint containing this link. -}; - - -/** -Implementation of TkJoint. -*/ -class TkJointImpl : public TkJoint -{ -public: - /** Blank constructor only creates valid TkJointLinks (point back to this object) */ - TkJointImpl(); - - /** - This constructor sets all internal data. If the joint is defined in an asset, the family - instanced from that asset will own this joint, and the 'owner' parameter is that family. - Otherwise, in the case where a joint is created from TkFramwork::createJoint, the joint - is not owned by a family and 'owner' will be NULL. - */ - TkJointImpl(const TkJointDesc& desc, TkFamilyImpl* owner); - - // Begin TkObject - virtual void release() override; - // End TkObject - - // Begin TkJoint - virtual const TkJointData getData() const override; - // End TkJoint - - // Public API - - /** - Internal method to access a const reference to the joint data. - - \return a const reference to the joint data. - */ - const TkJointData& getDataInternal() const; - - /** - Internal method to access a non-const reference to the joint data. - - \return a non-const reference to the joint data. - */ - TkJointData& getDataWritable(); - - /** - Set the actors that this joint attaches to. When the actors are different from the joint's current actors, - an event will be generated on one of the actors' families event queues to signal the change. Alternatively, - if alternateQueue is not NULL then it will be used to hold the event. - - If a non-NULL attached actor becomes NULL, then this joint will detach its references to both actors (if - they exist) and send an event of subtype Unreferenced. This signals the user that the joint may be deleted. - - \param[in] actor0 The new TkActor to replace the first attached actor. - \param[in] actor1 The new TkActor to replace the second attached actor. - \param[in] alternateQueue If not NULL, this queue will be used to hold events generated by this function. - */ - void setActors(TkActorImpl* actor0, TkActorImpl* actor1, TkEventQueue* alternateQueue = nullptr); - - /** - Ensures that any attached actors no longer refer to this joint. - */ - void removeReferencesInActors(); - - /** - Ensures that any attached actors' families no longer refer to this joint. External joints (created using - TkFramework::createJoint) are referenced by the attached actors' families. - */ - void removeReferencesInFamilies(); - -private: - TkJointData m_data; //!< The data given to the user: attached actors, chunk indices, and actor-local attachment positions. - TkJointLink m_links[2]; //!< One link for each actor in m_data.m_actors. If m_data.m_actors[0] == m_data.m_actors[1], then only m_links[0] is used. - TkFamilyImpl* m_owner; //!< The owning family if this is an internal joint created during TkFramework::createActor() from a TkAssetDesc with joint flags. - - friend class TkFrameworkImpl; - friend class TkFamilyImpl; - friend class TkActorImpl; -}; - - -//////// TkJointImpl inline methods //////// - -NV_INLINE TkJointImpl::TkJointImpl() -{ - m_links[0].m_joint = m_links[1].m_joint = this; -} - - -NV_INLINE const TkJointData& TkJointImpl::getDataInternal() const -{ - return m_data; -} - - -NV_INLINE TkJointData& TkJointImpl::getDataWritable() -{ - return m_data; -} - -} // namespace Blast -} // namespace Nv - - -#endif // ifndef NVBLASTTKJOINTIMPL_H +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#ifndef NVBLASTTKJOINTIMPL_H
+#define NVBLASTTKJOINTIMPL_H
+
+
+#include "NvBlastTkJoint.h"
+#include "NvBlastTkCommon.h"
+#include "NvBlastIndexFns.h"
+
+#include "NvBlastAssert.h"
+#include "NvBlastDLink.h"
+
+#include <atomic>
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+// Forward declarations
+class TkActorImpl;
+class TkJointImpl;
+class TkFamilyImpl;
+class TkEventQueue;
+
+
+/**
+Double-sided link (DLink) which holds a reference back to a joint which contains it.
+*/
+struct TkJointLink : public DLink
+{
+ TkJointImpl* m_joint; //!< The joint containing this link.
+};
+
+
+/**
+Implementation of TkJoint.
+*/
+class TkJointImpl : public TkJoint
+{
+public:
+ /** Blank constructor only creates valid TkJointLinks (point back to this object) */
+ TkJointImpl();
+
+ /**
+ This constructor sets all internal data. If the joint is defined in an asset, the family
+ instanced from that asset will own this joint, and the 'owner' parameter is that family.
+ Otherwise, in the case where a joint is created from TkFramwork::createJoint, the joint
+ is not owned by a family and 'owner' will be NULL.
+ */
+ TkJointImpl(const TkJointDesc& desc, TkFamilyImpl* owner);
+
+ // Begin TkObject
+ virtual void release() override;
+ // End TkObject
+
+ // Begin TkJoint
+ virtual const TkJointData getData() const override;
+ // End TkJoint
+
+ // Public API
+
+ /**
+ Internal method to access a const reference to the joint data.
+
+ \return a const reference to the joint data.
+ */
+ const TkJointData& getDataInternal() const;
+
+ /**
+ Internal method to access a non-const reference to the joint data.
+
+ \return a non-const reference to the joint data.
+ */
+ TkJointData& getDataWritable();
+
+ /**
+ Set the actors that this joint attaches to. When the actors are different from the joint's current actors,
+ an event will be generated on one of the actors' families event queues to signal the change. Alternatively,
+ if alternateQueue is not NULL then it will be used to hold the event.
+
+ If a non-NULL attached actor becomes NULL, then this joint will detach its references to both actors (if
+ they exist) and send an event of subtype Unreferenced. This signals the user that the joint may be deleted.
+
+ \param[in] actor0 The new TkActor to replace the first attached actor.
+ \param[in] actor1 The new TkActor to replace the second attached actor.
+ \param[in] alternateQueue If not NULL, this queue will be used to hold events generated by this function.
+ */
+ void setActors(TkActorImpl* actor0, TkActorImpl* actor1, TkEventQueue* alternateQueue = nullptr);
+
+ /**
+ Ensures that any attached actors no longer refer to this joint.
+ */
+ void removeReferencesInActors();
+
+ /**
+ Ensures that any attached actors' families no longer refer to this joint. External joints (created using
+ TkFramework::createJoint) are referenced by the attached actors' families.
+ */
+ void removeReferencesInFamilies();
+
+private:
+ TkJointData m_data; //!< The data given to the user: attached actors, chunk indices, and actor-local attachment positions.
+ TkJointLink m_links[2]; //!< One link for each actor in m_data.m_actors. If m_data.m_actors[0] == m_data.m_actors[1], then only m_links[0] is used.
+ TkFamilyImpl* m_owner; //!< The owning family if this is an internal joint created during TkFramework::createActor() from a TkAssetDesc with joint flags.
+
+ friend class TkFrameworkImpl;
+ friend class TkFamilyImpl;
+ friend class TkActorImpl;
+};
+
+
+//////// TkJointImpl inline methods ////////
+
+NV_INLINE TkJointImpl::TkJointImpl()
+{
+ m_links[0].m_joint = m_links[1].m_joint = this;
+}
+
+
+NV_INLINE const TkJointData& TkJointImpl::getDataInternal() const
+{
+ return m_data;
+}
+
+
+NV_INLINE TkJointData& TkJointImpl::getDataWritable()
+{
+ return m_data;
+}
+
+} // namespace Blast
+} // namespace Nv
+
+
+#endif // ifndef NVBLASTTKJOINTIMPL_H
diff --git a/sdk/toolkit/source/NvBlastTkTaskImpl.cpp b/sdk/toolkit/source/NvBlastTkTaskImpl.cpp index 07bde19..63e6c2a 100644..100755 --- a/sdk/toolkit/source/NvBlastTkTaskImpl.cpp +++ b/sdk/toolkit/source/NvBlastTkTaskImpl.cpp @@ -1,271 +1,271 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#include "NvBlastTime.h" - -#include "NvBlastTkTaskImpl.h" -#include "NvBlastTkFamilyImpl.h" -#include "NvBlastTkAssetImpl.h" -#include "NvBlastTkGroupImpl.h" - - -using namespace Nv::Blast; - - -void SharedMemory::allocate(TkFamilyImpl& tkFamily) -{ - NVBLAST_ASSERT(m_refCount == 0); - const NvBlastAsset* assetLL = tkFamily.getAsset()->getAssetLL(); - - // at most leafChunkCount actors can be created within a family - // tasks will grab their portion out of these memory blocks - uint32_t leafChunkCount = NvBlastAssetGetLeafChunkCount(assetLL, logLL); - m_newActorBuffers.allocate(2 * leafChunkCount); // GWD-167 workaround (2*) - m_newTkActorBuffers.allocate(leafChunkCount); -} - - -/** -Creates a TkEvent::FractureCommand according to the input buffer for tkActor -into events queue using the LocalBuffers to store the actual event data. -*/ -NV_FORCE_INLINE void reportFractureCommands( - const NvBlastFractureBuffers& buffer, - LocalBuffer<NvBlastBondFractureData>& bondBuffer, LocalBuffer<NvBlastChunkFractureData>& chunkBuffer, - TkEventQueue& events, const TkActorImpl* tkActor) -{ - - NvBlastBondFractureData* bdata = nullptr; - if (buffer.bondFractureCount > 0) - { - bdata = bondBuffer.allocate(buffer.bondFractureCount); - memcpy(bdata, buffer.bondFractures, sizeof(NvBlastBondFractureData)*buffer.bondFractureCount); - } - - NvBlastChunkFractureData* cdata = nullptr; - if (buffer.chunkFractureCount > 0) - { - cdata = chunkBuffer.allocate(buffer.chunkFractureCount); - memcpy(cdata, buffer.chunkFractures, sizeof(NvBlastChunkFractureData)*buffer.chunkFractureCount); - } - - TkFractureCommands* fevt = events.allocData<TkFractureCommands>(); - fevt->tkActorData = *tkActor; - fevt->buffers = { buffer.bondFractureCount, buffer.chunkFractureCount, bdata, cdata }; - events.addEvent(fevt); -} - - -/** -Creates a TkEvent::FractureEvent according to the input buffer for tkActor -into events queue using the LocalBuffers to store the actual event data. -*/ -NV_FORCE_INLINE void reportFractureEvents( - const NvBlastFractureBuffers& buffer, - LocalBuffer<NvBlastBondFractureData>& bondBuffer, LocalBuffer<NvBlastChunkFractureData>& chunkBuffer, - TkEventQueue& events, const TkActorImpl* tkActor) -{ - uint32_t result[4] = { 0,0,0,0 }; - - NvBlastBondFractureData* bdata = nullptr; - if (buffer.bondFractureCount > 0) - { - bdata = bondBuffer.allocate(buffer.bondFractureCount); - for (uint32_t b = 0; b < buffer.bondFractureCount; ++b) - { - bdata[b] = buffer.bondFractures[b]; - result[buffer.bondFractures[b].health > 0 ? 0 : 1]++; - } - } - - NvBlastChunkFractureData* cdata = nullptr; - if (buffer.chunkFractureCount > 0) - { - cdata = chunkBuffer.allocate(buffer.chunkFractureCount); - for (uint32_t c = 0; c < buffer.chunkFractureCount; ++c) - { - cdata[c] = buffer.chunkFractures[c]; - result[buffer.chunkFractures[c].health > 0 ? 2 : 3]++; - } - } - - TkFractureEvents* fevt = events.allocData<TkFractureEvents>(); - fevt->tkActorData = *tkActor; - fevt->buffers = { buffer.bondFractureCount, buffer.chunkFractureCount, bdata, cdata }; - fevt->bondsDamaged = result[0]; - fevt->bondsBroken = result[1]; - fevt->chunksDamaged = result[2]; - fevt->chunksBroken = result[3]; - events.addEvent(fevt); -} - - -void TkWorker::initialize() -{ - // temporary memory used to generate and apply fractures - // it must fit for the largest family involved in the group that owns this worker - NvBlastBondFractureData* bondFractureData = m_group->m_bondTempDataBlock.getBlock(m_id); - uint32_t bondFractureCount = m_group->m_bondTempDataBlock.numElementsPerBlock(); - NvBlastChunkFractureData* chunkFractureData = m_group->m_chunkTempDataBlock.getBlock(m_id); - uint32_t chunkFractureCount = m_group->m_chunkTempDataBlock.numElementsPerBlock(); - m_tempBuffer = { bondFractureCount, chunkFractureCount, bondFractureData, chunkFractureData }; - - // temporary memory used to split the actor - // large enough for the largest family involved - m_splitScratch = m_group->m_splitScratchBlock.getBlock(m_id); - - // to avoid unnecessary allocations, preallocated memory exists to fit all chunks and bonds taking damage once - // where multiple damage occurs, more memory will be allocated on demand (this may thwart other threads doing the same) - m_bondBuffer.initialize(m_group->m_bondEventDataBlock.getBlock(m_id), m_group->m_bondEventDataBlock.numElementsPerBlock()); - m_chunkBuffer.initialize(m_group->m_chunkEventDataBlock.getBlock(m_id), m_group->m_chunkEventDataBlock.numElementsPerBlock()); - -#if NV_PROFILE - NvBlastTimersReset(&m_stats.timers); - m_stats.processedActorsCount = 0; -#endif -} - -void TkWorker::process(TkWorkerJob& j) -{ - NvBlastTimers* timers = nullptr; - - BLAST_PROFILE_SCOPE_M("TkActor"); - - TkActorImpl* tkActor = j.m_tkActor; - const uint32_t tkActorIndex = tkActor->getIndex(); - NvBlastActor* actorLL = tkActor->getActorLLInternal(); - TkFamilyImpl& family = tkActor->getFamilyImpl(); - SharedMemory* mem = m_group->getSharedMemory(&family); - TkEventQueue& events = mem->m_events; - - NVBLAST_ASSERT(tkActor->getGroupImpl() == m_group); - NVBLAST_ASSERT(tkActor->m_flags.isSet(TkActorFlag::PENDING)); - -#if NV_PROFILE - timers = &m_stats.timers; - *timers += tkActor->m_timers; - NvBlastTimersReset(&tkActor->m_timers); - m_stats.processedActorsCount++; -#endif - - // generate and apply fracture for all damage requested on this actor - // and queue events accordingly - for (const auto& damage : tkActor->m_damageBuffer) - { - NvBlastFractureBuffers commandBuffer = m_tempBuffer; - - BLAST_PROFILE_ZONE_BEGIN("Material"); - NvBlastActorGenerateFracture(&commandBuffer, actorLL, damage.program, damage.programParams, logLL, timers); - BLAST_PROFILE_ZONE_END("Material"); - - if (commandBuffer.chunkFractureCount > 0 || commandBuffer.bondFractureCount > 0) - { - BLAST_PROFILE_SCOPE_M("Fill Command Events"); - reportFractureCommands(commandBuffer, m_bondBuffer, m_chunkBuffer, events, tkActor); - } - - NvBlastFractureBuffers eventBuffer = m_tempBuffer; - - BLAST_PROFILE_ZONE_BEGIN("Fracture"); - NvBlastActorApplyFracture(&eventBuffer, actorLL, &commandBuffer, logLL, timers); - BLAST_PROFILE_ZONE_END("Fracture"); - - if (eventBuffer.chunkFractureCount > 0 || eventBuffer.bondFractureCount > 0) - { - BLAST_PROFILE_SCOPE_M("Fill Fracture Events"); - tkActor->m_flags |= (TkActorFlag::DAMAGED); - reportFractureEvents(eventBuffer, m_bondBuffer, m_chunkBuffer, events, tkActor); - } - } - - - // split the actor, which could have been damaged directly though the TkActor's fracture functions - // i.e. it did not have damage queued for the above loop - - NvBlastActorSplitEvent splitEvent = { nullptr, nullptr }; - if (tkActor->isDamaged()) - { - BLAST_PROFILE_ZONE_BEGIN("Split Memory"); - uint32_t maxActorCount = NvBlastActorGetMaxActorCountForSplit(actorLL, logLL); - splitEvent.newActors = mem->reserveNewActors(maxActorCount); - BLAST_PROFILE_ZONE_END("Split Memory"); - BLAST_PROFILE_ZONE_BEGIN("Split"); - j.m_newActorsCount = NvBlastActorSplit(&splitEvent, actorLL, maxActorCount, m_splitScratch, logLL, timers); - BLAST_PROFILE_ZONE_END("Split"); - - tkActor->m_flags.clear(TkActorFlag::DAMAGED); - } - else - { - j.m_newActorsCount = 0; - } - - - // update the TkActor according to the LL split results and queue events accordingly - if (j.m_newActorsCount > 0) - { - NVBLAST_ASSERT(splitEvent.deletedActor == tkActor->getActorLL()); - - BLAST_PROFILE_ZONE_BEGIN("memory new actors"); - - auto tkSplitEvent = events.allocData<TkSplitEvent>(); - - tkSplitEvent->children = mem->reserveNewTkActors(j.m_newActorsCount); - tkSplitEvent->numChildren = j.m_newActorsCount; - - tkSplitEvent->parentData.family = &family; - tkSplitEvent->parentData.userData = tkActor->userData; - tkSplitEvent->parentData.index = tkActorIndex; - family.removeActor(tkActor); - - BLAST_PROFILE_ZONE_END("memory new actors"); - - - BLAST_PROFILE_ZONE_BEGIN("create new actors"); - for (uint32_t i = 0; i < j.m_newActorsCount; ++i) - { - TkActorImpl* newActor = family.addActor(splitEvent.newActors[i]); - tkSplitEvent->children[i] = newActor; - } - j.m_newActors = reinterpret_cast<TkActorImpl**>(tkSplitEvent->children); - BLAST_PROFILE_ZONE_END("create new actors"); - - BLAST_PROFILE_ZONE_BEGIN("split event"); - events.addEvent(tkSplitEvent); - BLAST_PROFILE_ZONE_END("split event"); - } - - j.m_tkActor->m_flags.clear(TkActorFlag::PENDING); -} - - -void TkWorker::process(uint32_t jobID) -{ - TkWorkerJob& j = m_group->m_jobs[jobID]; - process(j); -} +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#include "NvBlastTime.h"
+
+#include "NvBlastTkTaskImpl.h"
+#include "NvBlastTkFamilyImpl.h"
+#include "NvBlastTkAssetImpl.h"
+#include "NvBlastTkGroupImpl.h"
+
+
+using namespace Nv::Blast;
+
+
+void SharedMemory::allocate(TkFamilyImpl& tkFamily)
+{
+ NVBLAST_ASSERT(m_refCount == 0);
+ const NvBlastAsset* assetLL = tkFamily.getAsset()->getAssetLL();
+
+ // at most leafChunkCount actors can be created within a family
+ // tasks will grab their portion out of these memory blocks
+ uint32_t leafChunkCount = NvBlastAssetGetLeafChunkCount(assetLL, logLL);
+ m_newActorBuffers.allocate(2 * leafChunkCount); // GWD-167 workaround (2*)
+ m_newTkActorBuffers.allocate(leafChunkCount);
+}
+
+
+/**
+Creates a TkEvent::FractureCommand according to the input buffer for tkActor
+into events queue using the LocalBuffers to store the actual event data.
+*/
+NV_FORCE_INLINE void reportFractureCommands(
+ const NvBlastFractureBuffers& buffer,
+ LocalBuffer<NvBlastBondFractureData>& bondBuffer, LocalBuffer<NvBlastChunkFractureData>& chunkBuffer,
+ TkEventQueue& events, const TkActorImpl* tkActor)
+{
+
+ NvBlastBondFractureData* bdata = nullptr;
+ if (buffer.bondFractureCount > 0)
+ {
+ bdata = bondBuffer.allocate(buffer.bondFractureCount);
+ memcpy(bdata, buffer.bondFractures, sizeof(NvBlastBondFractureData)*buffer.bondFractureCount);
+ }
+
+ NvBlastChunkFractureData* cdata = nullptr;
+ if (buffer.chunkFractureCount > 0)
+ {
+ cdata = chunkBuffer.allocate(buffer.chunkFractureCount);
+ memcpy(cdata, buffer.chunkFractures, sizeof(NvBlastChunkFractureData)*buffer.chunkFractureCount);
+ }
+
+ TkFractureCommands* fevt = events.allocData<TkFractureCommands>();
+ fevt->tkActorData = *tkActor;
+ fevt->buffers = { buffer.bondFractureCount, buffer.chunkFractureCount, bdata, cdata };
+ events.addEvent(fevt);
+}
+
+
+/**
+Creates a TkEvent::FractureEvent according to the input buffer for tkActor
+into events queue using the LocalBuffers to store the actual event data.
+*/
+NV_FORCE_INLINE void reportFractureEvents(
+ const NvBlastFractureBuffers& buffer,
+ LocalBuffer<NvBlastBondFractureData>& bondBuffer, LocalBuffer<NvBlastChunkFractureData>& chunkBuffer,
+ TkEventQueue& events, const TkActorImpl* tkActor)
+{
+ uint32_t result[4] = { 0,0,0,0 };
+
+ NvBlastBondFractureData* bdata = nullptr;
+ if (buffer.bondFractureCount > 0)
+ {
+ bdata = bondBuffer.allocate(buffer.bondFractureCount);
+ for (uint32_t b = 0; b < buffer.bondFractureCount; ++b)
+ {
+ bdata[b] = buffer.bondFractures[b];
+ result[buffer.bondFractures[b].health > 0 ? 0 : 1]++;
+ }
+ }
+
+ NvBlastChunkFractureData* cdata = nullptr;
+ if (buffer.chunkFractureCount > 0)
+ {
+ cdata = chunkBuffer.allocate(buffer.chunkFractureCount);
+ for (uint32_t c = 0; c < buffer.chunkFractureCount; ++c)
+ {
+ cdata[c] = buffer.chunkFractures[c];
+ result[buffer.chunkFractures[c].health > 0 ? 2 : 3]++;
+ }
+ }
+
+ TkFractureEvents* fevt = events.allocData<TkFractureEvents>();
+ fevt->tkActorData = *tkActor;
+ fevt->buffers = { buffer.bondFractureCount, buffer.chunkFractureCount, bdata, cdata };
+ fevt->bondsDamaged = result[0];
+ fevt->bondsBroken = result[1];
+ fevt->chunksDamaged = result[2];
+ fevt->chunksBroken = result[3];
+ events.addEvent(fevt);
+}
+
+
+void TkWorker::initialize()
+{
+ // temporary memory used to generate and apply fractures
+ // it must fit for the largest family involved in the group that owns this worker
+ NvBlastBondFractureData* bondFractureData = m_group->m_bondTempDataBlock.getBlock(m_id);
+ uint32_t bondFractureCount = m_group->m_bondTempDataBlock.numElementsPerBlock();
+ NvBlastChunkFractureData* chunkFractureData = m_group->m_chunkTempDataBlock.getBlock(m_id);
+ uint32_t chunkFractureCount = m_group->m_chunkTempDataBlock.numElementsPerBlock();
+ m_tempBuffer = { bondFractureCount, chunkFractureCount, bondFractureData, chunkFractureData };
+
+ // temporary memory used to split the actor
+ // large enough for the largest family involved
+ m_splitScratch = m_group->m_splitScratchBlock.getBlock(m_id);
+
+ // to avoid unnecessary allocations, preallocated memory exists to fit all chunks and bonds taking damage once
+ // where multiple damage occurs, more memory will be allocated on demand (this may thwart other threads doing the same)
+ m_bondBuffer.initialize(m_group->m_bondEventDataBlock.getBlock(m_id), m_group->m_bondEventDataBlock.numElementsPerBlock());
+ m_chunkBuffer.initialize(m_group->m_chunkEventDataBlock.getBlock(m_id), m_group->m_chunkEventDataBlock.numElementsPerBlock());
+
+#if NV_PROFILE
+ NvBlastTimersReset(&m_stats.timers);
+ m_stats.processedActorsCount = 0;
+#endif
+}
+
+void TkWorker::process(TkWorkerJob& j)
+{
+ NvBlastTimers* timers = nullptr;
+
+ BLAST_PROFILE_SCOPE_M("TkActor");
+
+ TkActorImpl* tkActor = j.m_tkActor;
+ const uint32_t tkActorIndex = tkActor->getIndex();
+ NvBlastActor* actorLL = tkActor->getActorLLInternal();
+ TkFamilyImpl& family = tkActor->getFamilyImpl();
+ SharedMemory* mem = m_group->getSharedMemory(&family);
+ TkEventQueue& events = mem->m_events;
+
+ NVBLAST_ASSERT(tkActor->getGroupImpl() == m_group);
+ NVBLAST_ASSERT(tkActor->m_flags.isSet(TkActorFlag::PENDING));
+
+#if NV_PROFILE
+ timers = &m_stats.timers;
+ *timers += tkActor->m_timers;
+ NvBlastTimersReset(&tkActor->m_timers);
+ m_stats.processedActorsCount++;
+#endif
+
+ // generate and apply fracture for all damage requested on this actor
+ // and queue events accordingly
+ for (const auto& damage : tkActor->m_damageBuffer)
+ {
+ NvBlastFractureBuffers commandBuffer = m_tempBuffer;
+
+ BLAST_PROFILE_ZONE_BEGIN("Material");
+ NvBlastActorGenerateFracture(&commandBuffer, actorLL, damage.program, damage.programParams, logLL, timers);
+ BLAST_PROFILE_ZONE_END("Material");
+
+ if (commandBuffer.chunkFractureCount > 0 || commandBuffer.bondFractureCount > 0)
+ {
+ BLAST_PROFILE_SCOPE_M("Fill Command Events");
+ reportFractureCommands(commandBuffer, m_bondBuffer, m_chunkBuffer, events, tkActor);
+ }
+
+ NvBlastFractureBuffers eventBuffer = m_tempBuffer;
+
+ BLAST_PROFILE_ZONE_BEGIN("Fracture");
+ NvBlastActorApplyFracture(&eventBuffer, actorLL, &commandBuffer, logLL, timers);
+ BLAST_PROFILE_ZONE_END("Fracture");
+
+ if (eventBuffer.chunkFractureCount > 0 || eventBuffer.bondFractureCount > 0)
+ {
+ BLAST_PROFILE_SCOPE_M("Fill Fracture Events");
+ tkActor->m_flags |= (TkActorFlag::DAMAGED);
+ reportFractureEvents(eventBuffer, m_bondBuffer, m_chunkBuffer, events, tkActor);
+ }
+ }
+
+
+ // split the actor, which could have been damaged directly though the TkActor's fracture functions
+ // i.e. it did not have damage queued for the above loop
+
+ NvBlastActorSplitEvent splitEvent = { nullptr, nullptr };
+ if (tkActor->isDamaged())
+ {
+ BLAST_PROFILE_ZONE_BEGIN("Split Memory");
+ uint32_t maxActorCount = NvBlastActorGetMaxActorCountForSplit(actorLL, logLL);
+ splitEvent.newActors = mem->reserveNewActors(maxActorCount);
+ BLAST_PROFILE_ZONE_END("Split Memory");
+ BLAST_PROFILE_ZONE_BEGIN("Split");
+ j.m_newActorsCount = NvBlastActorSplit(&splitEvent, actorLL, maxActorCount, m_splitScratch, logLL, timers);
+ BLAST_PROFILE_ZONE_END("Split");
+
+ tkActor->m_flags.clear(TkActorFlag::DAMAGED);
+ }
+ else
+ {
+ j.m_newActorsCount = 0;
+ }
+
+
+ // update the TkActor according to the LL split results and queue events accordingly
+ if (j.m_newActorsCount > 0)
+ {
+ NVBLAST_ASSERT(splitEvent.deletedActor == tkActor->getActorLL());
+
+ BLAST_PROFILE_ZONE_BEGIN("memory new actors");
+
+ auto tkSplitEvent = events.allocData<TkSplitEvent>();
+
+ tkSplitEvent->children = mem->reserveNewTkActors(j.m_newActorsCount);
+ tkSplitEvent->numChildren = j.m_newActorsCount;
+
+ tkSplitEvent->parentData.family = &family;
+ tkSplitEvent->parentData.userData = tkActor->userData;
+ tkSplitEvent->parentData.index = tkActorIndex;
+ family.removeActor(tkActor);
+
+ BLAST_PROFILE_ZONE_END("memory new actors");
+
+
+ BLAST_PROFILE_ZONE_BEGIN("create new actors");
+ for (uint32_t i = 0; i < j.m_newActorsCount; ++i)
+ {
+ TkActorImpl* newActor = family.addActor(splitEvent.newActors[i]);
+ tkSplitEvent->children[i] = newActor;
+ }
+ j.m_newActors = reinterpret_cast<TkActorImpl**>(tkSplitEvent->children);
+ BLAST_PROFILE_ZONE_END("create new actors");
+
+ BLAST_PROFILE_ZONE_BEGIN("split event");
+ events.addEvent(tkSplitEvent);
+ BLAST_PROFILE_ZONE_END("split event");
+ }
+
+ j.m_tkActor->m_flags.clear(TkActorFlag::PENDING);
+}
+
+
+void TkWorker::process(uint32_t jobID)
+{
+ TkWorkerJob& j = m_group->m_jobs[jobID];
+ process(j);
+}
diff --git a/sdk/toolkit/source/NvBlastTkTaskImpl.h b/sdk/toolkit/source/NvBlastTkTaskImpl.h index 1ab3ee0..a0aa11f 100644..100755 --- a/sdk/toolkit/source/NvBlastTkTaskImpl.h +++ b/sdk/toolkit/source/NvBlastTkTaskImpl.h @@ -1,373 +1,373 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#ifndef NVBLASTTKTASKIMPL_H -#define NVBLASTTKTASKIMPL_H - -#include "NvBlast.h" - -#include "NvBlastTkFrameworkImpl.h" -#include "NvBlastTkEventQueue.h" -#include "NvBlastArray.h" - -#include <atomic> -#include <mutex> -#include <condition_variable> - -#include "NvBlastAssert.h" - -#include "NvBlastTkGroup.h" // TkGroupStats - - -namespace Nv -{ -namespace Blast -{ - -class TkGroupImpl; -class TkActorImpl; -class TkFamilyImpl; - - -/** -Transient structure describing a job and its results. -*/ -struct TkWorkerJob -{ - TkActorImpl* m_tkActor; //!< the actor to process - TkActorImpl** m_newActors; //!< list of child actors created by splitting - uint32_t m_newActorsCount; //!< the number of child actors created -}; - - - - - -/** -A list of equally sized memory blocks sharable between tasks. -*/ -template<typename T> -class SharedBlock -{ -public: - - SharedBlock() : m_numElementsPerBlock(0), m_numBlocks(0), m_buffer(nullptr) {} - - /** - Allocates one large memory block of elementsPerBlock*numBlocks elements. - */ - void allocate(uint32_t elementsPerBlock, uint32_t numBlocks) - { - NVBLAST_ASSERT(elementsPerBlock > 0 && numBlocks > 0); - - m_buffer = reinterpret_cast<T*>(NVBLAST_ALLOC_NAMED(elementsPerBlock*numBlocks*sizeof(T), "SharedBlock")); - m_numElementsPerBlock = elementsPerBlock; - m_numBlocks = numBlocks; - } - - /** - Returns the pointer to the first element of a block of numElementsPerBlock() elements. - */ - T* getBlock(uint32_t id) - { - NVBLAST_ASSERT(id < m_numBlocks || 0 == m_numElementsPerBlock); - return &m_buffer[id*m_numElementsPerBlock]; - } - - /** - The number of elements available per block. - */ - uint32_t numElementsPerBlock() const - { - return m_numElementsPerBlock; - } - - /** - Frees the whole memory block. - */ - void release() - { - m_numBlocks = 0; - m_numElementsPerBlock = 0; - NVBLAST_FREE(m_buffer); - m_buffer = nullptr; - } - -private: - uint32_t m_numElementsPerBlock; //!< elements available in one block - uint32_t m_numBlocks; //!< number of virtual blocks available - T* m_buffer; //!< contiguous memory for all blocks -}; - - -/** -A preallocated, shared array from which can be allocated from in tasks. -Intended to be used when the maximum amount of data (e.g. for a family) -is known in advance. No further allocations take place on exhaustion. -Exhaustion asserts in debug builds and overflows otherwise. -*/ -template<typename T> -class SharedBuffer -{ -public: - SharedBuffer() : m_capacity(0), m_used(0), m_buffer(nullptr) {} - - /** - Atomically gets a pointer to the first element of an array of n elements. - */ - T* reserve(size_t n) - { - NVBLAST_ASSERT(m_used + n <= m_capacity); - size_t start = m_used.fetch_add(n); - return &m_buffer[start]; - } - - /** - Preallocates memory for capacity elements. - */ - void allocate(size_t capacity) - { - NVBLAST_ASSERT(m_buffer == nullptr); - m_buffer = reinterpret_cast<T*>(NVBLAST_ALLOC_NAMED(capacity*sizeof(T), "SplitMemory")); - m_capacity = capacity; - } - - /** - Preserves the memory allocated but resets to reserve from the beginning of the array. - */ - void reset() - { - m_used = 0; - } - - /** - Frees the preallocated array. - */ - void release() - { - NVBLAST_ASSERT(m_buffer != nullptr); - NVBLAST_FREE(m_buffer); - m_buffer = nullptr; - m_capacity = m_used = 0; - } - -private: - size_t m_capacity; //!< available elements in the buffer - std::atomic<size_t> m_used; //!< used elements in the buffer - T* m_buffer; //!< the memory containing T's -}; - - -/** -Allocates from a preallocated, externally owned memory block initialized with. -When blocks run out of space, new ones are allocated and owned by this class. -*/ -template<typename T> -class LocalBuffer -{ -public: - /** - Returns the pointer to the first element of an array of n elements. - Allocates a new block of memory when exhausted, its size being the larger of n and capacity set with initialize(). - */ - T* allocate(size_t n) - { - if (m_used + n > m_capacity) - { - allocateNewBlock(n > m_capacity ? n : m_capacity); - } - - size_t index = m_used; - m_used += n; - return &m_currentBlock[index]; - } - - /** - Release the additionally allocated memory blocks. - The externally owned memory block remains untouched. - */ - void clear() - { - for (void* block : m_memoryBlocks) - { - NVBLAST_FREE(block); - } - m_memoryBlocks.clear(); - } - - /** - Set the externally owned memory block to start allocating from, - with a size of capacity elements. - */ - void initialize(T* block, size_t capacity) - { - m_currentBlock = block; - m_capacity = capacity; - m_used = 0; - } - -private: - /** - Allocates space for capacity elements. - */ - void allocateNewBlock(size_t capacity) - { - BLAST_PROFILE_SCOPE_L("Local Buffer allocation"); - m_capacity = capacity; - m_currentBlock = static_cast<T*>(NVBLAST_ALLOC_NAMED(capacity*sizeof(T), "Blast LocalBuffer")); - m_memoryBlocks.pushBack(m_currentBlock); - m_used = 0; - } - - InlineArray<void*, 4>::type m_memoryBlocks; //!< storage for memory blocks - T* m_currentBlock; //!< memory block used to allocate from - size_t m_used; //!< elements used in current block - size_t m_capacity; //!< elements available in current block -}; - - -/** -Holds the memory used by TkWorker for each family in each group. -*/ -class SharedMemory -{ -public: - SharedMemory() : m_eventsMemory(0), m_eventsCount(0), m_refCount(0) {} - - /** - Reserves n entries from preallocated memory. - */ - NvBlastActor** reserveNewActors(size_t n) - { - return m_newActorBuffers.reserve(n); - } - - /** - Reserves n entries from preallocated memory. - */ - TkActor** reserveNewTkActors(size_t n) - { - return m_newTkActorBuffers.reserve(n); - } - - /** - Allocates buffers to hold - */ - void allocate(TkFamilyImpl&); - - /** - Resets the internal buffers to reserve from their beginning. - Preserves the allocated memory. - */ - void reset() - { - m_newActorBuffers.reset(); - m_newTkActorBuffers.reset(); - } - - /** - Increments the reference count. - */ - void addReference() { m_refCount++; } - - /** - Increments the reference count by n. - */ - void addReference(size_t n) { m_refCount += n; } - - /** - Decrements the reference count. - Returns true if the count reached zero. - */ - bool removeReference() - { - m_refCount--; - return !isUsed(); - } - - /** - Checks if the reference count is not zero. - */ - bool isUsed() - { - return m_refCount > 0; - } - - /** - Release the internal buffers' memory. - */ - void release() - { - m_newActorBuffers.release(); - m_newTkActorBuffers.release(); - } - - TkEventQueue m_events; //!< event queue shared across a group's actors of the same family - uint32_t m_eventsMemory; //!< expected memory size for event data - uint32_t m_eventsCount; //!< expected number of events - -private: - size_t m_refCount; //!< helper for usage and releasing memory - - SharedBuffer<NvBlastActor*> m_newActorBuffers; //!< memory for splitting - SharedBuffer<TkActor*> m_newTkActorBuffers; //!< memory for split events -}; - - -/** -Thread worker fracturing and splitting actors sequentially. -The list of actual jobs is provided by the group owning this worker. -*/ -class TkWorker final : public TkGroupWorker -{ -public: - TkWorker() : m_id(~(uint32_t)0), m_group(nullptr), m_isBusy(false) {} - - void process(uint32_t jobID); - void initialize(); - - void process(TkWorkerJob& job); - - uint32_t m_id; //!< this worker's id - TkGroupImpl* m_group; //!< the group owning this worker - - LocalBuffer<NvBlastChunkFractureData> m_chunkBuffer; //!< memory manager for chunk event data - LocalBuffer<NvBlastBondFractureData> m_bondBuffer; //!< memory manager for bonds event data - - void* m_splitScratch; - NvBlastFractureBuffers m_tempBuffer; - bool m_isBusy; - -#if NV_PROFILE - TkGroupStats m_stats; -#endif -}; -} -} - -#endif // NVBLASTTKTASKIMPL_H +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#ifndef NVBLASTTKTASKIMPL_H
+#define NVBLASTTKTASKIMPL_H
+
+#include "NvBlast.h"
+
+#include "NvBlastTkFrameworkImpl.h"
+#include "NvBlastTkEventQueue.h"
+#include "NvBlastArray.h"
+
+#include <atomic>
+#include <mutex>
+#include <condition_variable>
+
+#include "NvBlastAssert.h"
+
+#include "NvBlastTkGroup.h" // TkGroupStats
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+class TkGroupImpl;
+class TkActorImpl;
+class TkFamilyImpl;
+
+
+/**
+Transient structure describing a job and its results.
+*/
+struct TkWorkerJob
+{
+ TkActorImpl* m_tkActor; //!< the actor to process
+ TkActorImpl** m_newActors; //!< list of child actors created by splitting
+ uint32_t m_newActorsCount; //!< the number of child actors created
+};
+
+
+
+
+
+/**
+A list of equally sized memory blocks sharable between tasks.
+*/
+template<typename T>
+class SharedBlock
+{
+public:
+
+ SharedBlock() : m_numElementsPerBlock(0), m_numBlocks(0), m_buffer(nullptr) {}
+
+ /**
+ Allocates one large memory block of elementsPerBlock*numBlocks elements.
+ */
+ void allocate(uint32_t elementsPerBlock, uint32_t numBlocks)
+ {
+ NVBLAST_ASSERT(elementsPerBlock > 0 && numBlocks > 0);
+
+ m_buffer = reinterpret_cast<T*>(NVBLAST_ALLOC_NAMED(elementsPerBlock*numBlocks*sizeof(T), "SharedBlock"));
+ m_numElementsPerBlock = elementsPerBlock;
+ m_numBlocks = numBlocks;
+ }
+
+ /**
+ Returns the pointer to the first element of a block of numElementsPerBlock() elements.
+ */
+ T* getBlock(uint32_t id)
+ {
+ NVBLAST_ASSERT(id < m_numBlocks || 0 == m_numElementsPerBlock);
+ return &m_buffer[id*m_numElementsPerBlock];
+ }
+
+ /**
+ The number of elements available per block.
+ */
+ uint32_t numElementsPerBlock() const
+ {
+ return m_numElementsPerBlock;
+ }
+
+ /**
+ Frees the whole memory block.
+ */
+ void release()
+ {
+ m_numBlocks = 0;
+ m_numElementsPerBlock = 0;
+ NVBLAST_FREE(m_buffer);
+ m_buffer = nullptr;
+ }
+
+private:
+ uint32_t m_numElementsPerBlock; //!< elements available in one block
+ uint32_t m_numBlocks; //!< number of virtual blocks available
+ T* m_buffer; //!< contiguous memory for all blocks
+};
+
+
+/**
+A preallocated, shared array from which can be allocated from in tasks.
+Intended to be used when the maximum amount of data (e.g. for a family)
+is known in advance. No further allocations take place on exhaustion.
+Exhaustion asserts in debug builds and overflows otherwise.
+*/
+template<typename T>
+class SharedBuffer
+{
+public:
+ SharedBuffer() : m_capacity(0), m_used(0), m_buffer(nullptr) {}
+
+ /**
+ Atomically gets a pointer to the first element of an array of n elements.
+ */
+ T* reserve(size_t n)
+ {
+ NVBLAST_ASSERT(m_used + n <= m_capacity);
+ size_t start = m_used.fetch_add(n);
+ return &m_buffer[start];
+ }
+
+ /**
+ Preallocates memory for capacity elements.
+ */
+ void allocate(size_t capacity)
+ {
+ NVBLAST_ASSERT(m_buffer == nullptr);
+ m_buffer = reinterpret_cast<T*>(NVBLAST_ALLOC_NAMED(capacity*sizeof(T), "SplitMemory"));
+ m_capacity = capacity;
+ }
+
+ /**
+ Preserves the memory allocated but resets to reserve from the beginning of the array.
+ */
+ void reset()
+ {
+ m_used = 0;
+ }
+
+ /**
+ Frees the preallocated array.
+ */
+ void release()
+ {
+ NVBLAST_ASSERT(m_buffer != nullptr);
+ NVBLAST_FREE(m_buffer);
+ m_buffer = nullptr;
+ m_capacity = m_used = 0;
+ }
+
+private:
+ size_t m_capacity; //!< available elements in the buffer
+ std::atomic<size_t> m_used; //!< used elements in the buffer
+ T* m_buffer; //!< the memory containing T's
+};
+
+
+/**
+Allocates from a preallocated, externally owned memory block initialized with.
+When blocks run out of space, new ones are allocated and owned by this class.
+*/
+template<typename T>
+class LocalBuffer
+{
+public:
+ /**
+ Returns the pointer to the first element of an array of n elements.
+ Allocates a new block of memory when exhausted, its size being the larger of n and capacity set with initialize().
+ */
+ T* allocate(size_t n)
+ {
+ if (m_used + n > m_capacity)
+ {
+ allocateNewBlock(n > m_capacity ? n : m_capacity);
+ }
+
+ size_t index = m_used;
+ m_used += n;
+ return &m_currentBlock[index];
+ }
+
+ /**
+ Release the additionally allocated memory blocks.
+ The externally owned memory block remains untouched.
+ */
+ void clear()
+ {
+ for (void* block : m_memoryBlocks)
+ {
+ NVBLAST_FREE(block);
+ }
+ m_memoryBlocks.clear();
+ }
+
+ /**
+ Set the externally owned memory block to start allocating from,
+ with a size of capacity elements.
+ */
+ void initialize(T* block, size_t capacity)
+ {
+ m_currentBlock = block;
+ m_capacity = capacity;
+ m_used = 0;
+ }
+
+private:
+ /**
+ Allocates space for capacity elements.
+ */
+ void allocateNewBlock(size_t capacity)
+ {
+ BLAST_PROFILE_SCOPE_L("Local Buffer allocation");
+ m_capacity = capacity;
+ m_currentBlock = static_cast<T*>(NVBLAST_ALLOC_NAMED(capacity*sizeof(T), "Blast LocalBuffer"));
+ m_memoryBlocks.pushBack(m_currentBlock);
+ m_used = 0;
+ }
+
+ InlineArray<void*, 4>::type m_memoryBlocks; //!< storage for memory blocks
+ T* m_currentBlock; //!< memory block used to allocate from
+ size_t m_used; //!< elements used in current block
+ size_t m_capacity; //!< elements available in current block
+};
+
+
+/**
+Holds the memory used by TkWorker for each family in each group.
+*/
+class SharedMemory
+{
+public:
+ SharedMemory() : m_eventsMemory(0), m_eventsCount(0), m_refCount(0) {}
+
+ /**
+ Reserves n entries from preallocated memory.
+ */
+ NvBlastActor** reserveNewActors(size_t n)
+ {
+ return m_newActorBuffers.reserve(n);
+ }
+
+ /**
+ Reserves n entries from preallocated memory.
+ */
+ TkActor** reserveNewTkActors(size_t n)
+ {
+ return m_newTkActorBuffers.reserve(n);
+ }
+
+ /**
+ Allocates buffers to hold
+ */
+ void allocate(TkFamilyImpl&);
+
+ /**
+ Resets the internal buffers to reserve from their beginning.
+ Preserves the allocated memory.
+ */
+ void reset()
+ {
+ m_newActorBuffers.reset();
+ m_newTkActorBuffers.reset();
+ }
+
+ /**
+ Increments the reference count.
+ */
+ void addReference() { m_refCount++; }
+
+ /**
+ Increments the reference count by n.
+ */
+ void addReference(size_t n) { m_refCount += n; }
+
+ /**
+ Decrements the reference count.
+ Returns true if the count reached zero.
+ */
+ bool removeReference()
+ {
+ m_refCount--;
+ return !isUsed();
+ }
+
+ /**
+ Checks if the reference count is not zero.
+ */
+ bool isUsed()
+ {
+ return m_refCount > 0;
+ }
+
+ /**
+ Release the internal buffers' memory.
+ */
+ void release()
+ {
+ m_newActorBuffers.release();
+ m_newTkActorBuffers.release();
+ }
+
+ TkEventQueue m_events; //!< event queue shared across a group's actors of the same family
+ uint32_t m_eventsMemory; //!< expected memory size for event data
+ uint32_t m_eventsCount; //!< expected number of events
+
+private:
+ size_t m_refCount; //!< helper for usage and releasing memory
+
+ SharedBuffer<NvBlastActor*> m_newActorBuffers; //!< memory for splitting
+ SharedBuffer<TkActor*> m_newTkActorBuffers; //!< memory for split events
+};
+
+
+/**
+Thread worker fracturing and splitting actors sequentially.
+The list of actual jobs is provided by the group owning this worker.
+*/
+class TkWorker final : public TkGroupWorker
+{
+public:
+ TkWorker() : m_id(~(uint32_t)0), m_group(nullptr), m_isBusy(false) {}
+
+ void process(uint32_t jobID);
+ void initialize();
+
+ void process(TkWorkerJob& job);
+
+ uint32_t m_id; //!< this worker's id
+ TkGroupImpl* m_group; //!< the group owning this worker
+
+ LocalBuffer<NvBlastChunkFractureData> m_chunkBuffer; //!< memory manager for chunk event data
+ LocalBuffer<NvBlastBondFractureData> m_bondBuffer; //!< memory manager for bonds event data
+
+ void* m_splitScratch;
+ NvBlastFractureBuffers m_tempBuffer;
+ bool m_isBusy;
+
+#if NV_PROFILE
+ TkGroupStats m_stats;
+#endif
+};
+}
+}
+
+#endif // NVBLASTTKTASKIMPL_H
diff --git a/sdk/toolkit/source/NvBlastTkTypeImpl.h b/sdk/toolkit/source/NvBlastTkTypeImpl.h index 81ff5ef..9a5dc6e 100644..100755 --- a/sdk/toolkit/source/NvBlastTkTypeImpl.h +++ b/sdk/toolkit/source/NvBlastTkTypeImpl.h @@ -1,161 +1,161 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#ifndef NVBLASTTKTYPEIMPL_H -#define NVBLASTTKTYPEIMPL_H - - -#include "NvPreprocessor.h" - -#include "NvBlastTkType.h" - - -namespace Nv -{ -namespace Blast -{ - -/** -Implementation of TkType, storing class information for TkIdentifiable-derived classes. -*/ -class TkTypeImpl : public TkType -{ -public: - TkTypeImpl(const char* typeName, uint32_t typeID, uint32_t version); - - // Begin TkType - virtual const char* getName() const override { return getNameInternal(); } - - virtual uint32_t getVersion() const override { return getVersionInternal(); } - // End TkType - - // Public methods - - /** - Access to the class name. - - \return a C string pointer to the class name. - */ - const char* getNameInternal() const; - - /** - Access to the data format version for the class. - - \return the data format version. - */ - uint32_t getVersionInternal() const; - - /** - Access to a unique identifier for the class (set using the NVBLASTTK_IMPL_DEFINE_IDENTIFIABLE macro). - - \return the class's unique identifier. - */ - uint32_t getID() const; - - /** - Access to a runtime-unique small index for the class. - - \return the index for the class. - */ - uint32_t getIndex() const; - - /** - \return whether or not the index has been set (see setIndex) to a valid value. - */ - bool indexIsValid() const; - -private: - enum { InvalidIndex = 0xFFFFFFFF }; - - /** - Sets the type index. - - \param[in] index The index to set. - */ - void setIndex(uint32_t index); - - const char* m_name; //!< The name of the class, set by the constructor. - uint32_t m_ID; //!< The unique identifier for the class, set by the constructor. - uint32_t m_version; //!< The data format version for the class, set by the constructor. - uint32_t m_index; //!< The index set for this class, set using setIndex(). - - friend class TkFrameworkImpl; -}; - - -//////// TkTypeImpl inline methods //////// - -NV_INLINE TkTypeImpl::TkTypeImpl(const char* typeName, uint32_t typeID, uint32_t version) - : m_name(typeName) - , m_ID(typeID) - , m_version(version) - , m_index((uint32_t)InvalidIndex) -{ -} - - -NV_INLINE const char* TkTypeImpl::getNameInternal() const -{ - return m_name; -} - - -NV_INLINE uint32_t TkTypeImpl::getVersionInternal() const -{ - return m_version; -} - - -NV_INLINE uint32_t TkTypeImpl::getID() const -{ - return m_ID; -} - - -NV_INLINE uint32_t TkTypeImpl::getIndex() const -{ - return m_index; -} - - -NV_INLINE bool TkTypeImpl::indexIsValid() const -{ - return m_index != (uint32_t)InvalidIndex; -} - - -NV_INLINE void TkTypeImpl::setIndex(uint32_t index) -{ - m_index = index; -} - -} // namespace Blast -} // namespace Nv - - -#endif // ifndef NVBLASTTKTYPEIMPL_H +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#ifndef NVBLASTTKTYPEIMPL_H
+#define NVBLASTTKTYPEIMPL_H
+
+
+#include "NvPreprocessor.h"
+
+#include "NvBlastTkType.h"
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+/**
+Implementation of TkType, storing class information for TkIdentifiable-derived classes.
+*/
+class TkTypeImpl : public TkType
+{
+public:
+ TkTypeImpl(const char* typeName, uint32_t typeID, uint32_t version);
+
+ // Begin TkType
+ virtual const char* getName() const override { return getNameInternal(); }
+
+ virtual uint32_t getVersion() const override { return getVersionInternal(); }
+ // End TkType
+
+ // Public methods
+
+ /**
+ Access to the class name.
+
+ \return a C string pointer to the class name.
+ */
+ const char* getNameInternal() const;
+
+ /**
+ Access to the data format version for the class.
+
+ \return the data format version.
+ */
+ uint32_t getVersionInternal() const;
+
+ /**
+ Access to a unique identifier for the class (set using the NVBLASTTK_IMPL_DEFINE_IDENTIFIABLE macro).
+
+ \return the class's unique identifier.
+ */
+ uint32_t getID() const;
+
+ /**
+ Access to a runtime-unique small index for the class.
+
+ \return the index for the class.
+ */
+ uint32_t getIndex() const;
+
+ /**
+ \return whether or not the index has been set (see setIndex) to a valid value.
+ */
+ bool indexIsValid() const;
+
+private:
+ enum { InvalidIndex = 0xFFFFFFFF };
+
+ /**
+ Sets the type index.
+
+ \param[in] index The index to set.
+ */
+ void setIndex(uint32_t index);
+
+ const char* m_name; //!< The name of the class, set by the constructor.
+ uint32_t m_ID; //!< The unique identifier for the class, set by the constructor.
+ uint32_t m_version; //!< The data format version for the class, set by the constructor.
+ uint32_t m_index; //!< The index set for this class, set using setIndex().
+
+ friend class TkFrameworkImpl;
+};
+
+
+//////// TkTypeImpl inline methods ////////
+
+NV_INLINE TkTypeImpl::TkTypeImpl(const char* typeName, uint32_t typeID, uint32_t version)
+ : m_name(typeName)
+ , m_ID(typeID)
+ , m_version(version)
+ , m_index((uint32_t)InvalidIndex)
+{
+}
+
+
+NV_INLINE const char* TkTypeImpl::getNameInternal() const
+{
+ return m_name;
+}
+
+
+NV_INLINE uint32_t TkTypeImpl::getVersionInternal() const
+{
+ return m_version;
+}
+
+
+NV_INLINE uint32_t TkTypeImpl::getID() const
+{
+ return m_ID;
+}
+
+
+NV_INLINE uint32_t TkTypeImpl::getIndex() const
+{
+ return m_index;
+}
+
+
+NV_INLINE bool TkTypeImpl::indexIsValid() const
+{
+ return m_index != (uint32_t)InvalidIndex;
+}
+
+
+NV_INLINE void TkTypeImpl::setIndex(uint32_t index)
+{
+ m_index = index;
+}
+
+} // namespace Blast
+} // namespace Nv
+
+
+#endif // ifndef NVBLASTTKTYPEIMPL_H
|