diff options
| author | Anton Novoselov <[email protected]> | 2017-08-01 12:53:38 +0300 |
|---|---|---|
| committer | Anton Novoselov <[email protected]> | 2017-08-01 12:53:38 +0300 |
| commit | 236f03c0b9a4982328ed1201978f7f69d192d9b2 (patch) | |
| tree | e486f2fa39dba203563895541e92c60ed3e25759 /sdk/lowlevel/source/NvBlastFamily.cpp | |
| parent | Added screens to welcome page (diff) | |
| download | blast-236f03c0b9a4982328ed1201978f7f69d192d9b2.tar.xz blast-236f03c0b9a4982328ed1201978f7f69d192d9b2.zip | |
Blast 1.1 release (windows / linux)
see docs/release_notes.txt for details
Diffstat (limited to 'sdk/lowlevel/source/NvBlastFamily.cpp')
| -rw-r--r-- | sdk/lowlevel/source/NvBlastFamily.cpp | 535 |
1 files changed, 468 insertions, 67 deletions
diff --git a/sdk/lowlevel/source/NvBlastFamily.cpp b/sdk/lowlevel/source/NvBlastFamily.cpp index 1f517b1..b0888c6 100644 --- a/sdk/lowlevel/source/NvBlastFamily.cpp +++ b/sdk/lowlevel/source/NvBlastFamily.cpp @@ -1,17 +1,35 @@ -/* -* Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. -* -* NVIDIA CORPORATION and its licensors retain all intellectual property -* and proprietary rights in and to this software, 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. -*/ +// 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-2017 NVIDIA Corporation. All rights reserved. #include "NvBlastFamily.h" #include "NvBlastFamilyGraph.h" #include "NvBlastIndexFns.h" +#include "NvBlastTime.h" #include <new> @@ -36,7 +54,7 @@ struct FamilyDataOffsets static size_t createFamilyDataOffsets(FamilyDataOffsets& offsets, const Asset* asset) { - const Nv::Blast::SupportGraph& graph = asset->m_graph; + const SupportGraph& graph = asset->m_graph; NvBlastCreateOffsetStart(sizeof(FamilyHeader)); NvBlastCreateOffsetAlign16(offsets.m_actors, asset->getLowerSupportChunkCount() * sizeof(Actor)); @@ -52,7 +70,7 @@ static size_t createFamilyDataOffsets(FamilyDataOffsets& offsets, const Asset* a size_t getFamilyMemorySize(const Asset* asset) { -#if NVBLAST_CHECK_PARAMS +#if NVBLASTLL_CHECK_PARAMS if (asset == nullptr) { NVBLAST_ALWAYS_ASSERT(); @@ -67,20 +85,20 @@ size_t getFamilyMemorySize(const Asset* asset) NvBlastFamily* createFamily(void* mem, const NvBlastAsset* asset, NvBlastLog logFn) { - NVBLAST_CHECK(mem != nullptr, logFn, "createFamily: NULL mem pointer input.", return nullptr); - NVBLAST_CHECK(asset != nullptr, logFn, "createFamily: NULL asset pointer input.", return nullptr); + NVBLASTLL_CHECK(mem != nullptr, logFn, "createFamily: NULL mem pointer input.", return nullptr); + NVBLASTLL_CHECK(asset != nullptr, logFn, "createFamily: NULL asset pointer input.", return nullptr); - NVBLAST_CHECK((reinterpret_cast<uintptr_t>(mem) & 0xF) == 0, logFn, "createFamily: mem pointer not 16-byte aligned.", return nullptr); + NVBLASTLL_CHECK((reinterpret_cast<uintptr_t>(mem) & 0xF) == 0, logFn, "createFamily: mem pointer not 16-byte aligned.", return nullptr); const Asset& solverAsset = *static_cast<const Asset*>(asset); if (solverAsset.m_chunkCount == 0) { - NVBLAST_LOG_ERROR(logFn, "createFamily: Asset has no chunks. Family not created.\n"); + NVBLASTLL_LOG_ERROR(logFn, "createFamily: Asset has no chunks. Family not created.\n"); return nullptr; } - const Nv::Blast::SupportGraph& graph = solverAsset.m_graph; + const SupportGraph& graph = solverAsset.m_graph; const uint32_t bondCount = solverAsset.getBondCount(); @@ -97,7 +115,7 @@ NvBlastFamily* createFamily(void* mem, const NvBlastAsset* asset, NvBlastLog log // Restricting our data size to < 4GB so that we may use uint32_t offsets if (dataSize > (size_t)UINT32_MAX) { - NVBLAST_LOG_ERROR(logFn, "Nv::Blast::Actor::instanceAllocate: Instance data block size will exceed 4GB. Instance not created.\n"); + NVBLASTLL_LOG_ERROR(logFn, "Nv::Blast::Actor::instanceAllocate: Instance data block size will exceed 4GB. Instance not created.\n"); return nullptr; } @@ -107,7 +125,7 @@ NvBlastFamily* createFamily(void* mem, const NvBlastAsset* asset, NvBlastLog log // Fill in family header FamilyHeader* header = (FamilyHeader*)family; header->dataType = NvBlastDataBlock::FamilyDataBlock; - header->formatVersion = NvBlastFamilyDataFormat::Current; + header->formatVersion = 0; // Not currently using this field header->size = (uint32_t)dataSize; header->m_assetID = solverAsset.m_ID; header->m_actorCount = 0; @@ -150,6 +168,417 @@ NvBlastFamily* createFamily(void* mem, const NvBlastAsset* asset, NvBlastLog log return family; } + +//////// Family member methods //////// + +void FamilyHeader::fractureSubSupportNoEvents(uint32_t chunkIndex, uint32_t suboffset, float healthDamage, float* chunkHealths, const NvBlastChunk* chunks) +{ + const NvBlastChunk& chunk = chunks[chunkIndex]; + uint32_t numChildren = chunk.childIndexStop - chunk.firstChildIndex; + + if (numChildren > 0) + { + healthDamage /= numChildren; + for (uint32_t childIndex = chunk.firstChildIndex; childIndex < chunk.childIndexStop; childIndex++) + { + float& health = chunkHealths[childIndex - suboffset]; + if (health > 0.0f) + { + float remainingDamage = healthDamage - health; + health -= healthDamage; + + NVBLAST_ASSERT(chunks[childIndex].parentChunkIndex == chunkIndex); + + if (health <= 0.0f && remainingDamage > 0.0f) + { + fractureSubSupportNoEvents(childIndex, suboffset, remainingDamage, chunkHealths, chunks); + } + } + } + } +} + + +void FamilyHeader::fractureSubSupport(uint32_t chunkIndex, uint32_t suboffset, float healthDamage, float* chunkHealths, const NvBlastChunk* chunks, NvBlastChunkFractureData* outBuffer, uint32_t* currentIndex, const uint32_t maxCount) +{ + const NvBlastChunk& chunk = chunks[chunkIndex]; + uint32_t numChildren = chunk.childIndexStop - chunk.firstChildIndex; + + if (numChildren > 0) + { + healthDamage /= numChildren; + for (uint32_t childIndex = chunk.firstChildIndex; childIndex < chunk.childIndexStop; childIndex++) + { + float& health = chunkHealths[childIndex - suboffset]; + if (health > 0.0f) + { + float remainingDamage = healthDamage - health; + health -= healthDamage; + + NVBLAST_ASSERT(chunks[childIndex].parentChunkIndex == chunkIndex); + + if (*currentIndex < maxCount) + { + NvBlastChunkFractureData& event = outBuffer[*currentIndex]; + event.userdata = chunks[childIndex].userData; + event.chunkIndex = childIndex; + event.health = health; + } + (*currentIndex)++; + + if (health <= 0.0f && remainingDamage > 0.0f) + { + fractureSubSupport(childIndex, suboffset, remainingDamage, chunkHealths, chunks, outBuffer, currentIndex, maxCount); + } + } + } + } + +} + + +void FamilyHeader::fractureNoEvents(uint32_t chunkFractureCount, const NvBlastChunkFractureData* chunkFractures, Actor* filterActor, NvBlastLog logFn) +{ + const SupportGraph& graph = m_asset->m_graph; + const uint32_t* graphAdjacencyPartition = graph.getAdjacencyPartition(); + const uint32_t* adjacentBondIndices = graph.getAdjacentBondIndices(); + float* bondHealths = getBondHealths(); + float* chunkHealths = getLowerSupportChunkHealths(); + float* subChunkHealths = getSubsupportChunkHealths(); + const NvBlastChunk* chunks = m_asset->getChunks(); + + for (uint32_t i = 0; i < chunkFractureCount; ++i) + { + const NvBlastChunkFractureData& command = chunkFractures[i]; + const uint32_t chunkIndex = command.chunkIndex; + const uint32_t chunkHealthIndex = m_asset->getContiguousLowerSupportIndex(chunkIndex); + NVBLAST_ASSERT(!isInvalidIndex(chunkHealthIndex)); + if (isInvalidIndex(chunkHealthIndex)) + { + continue; + } + float& health = chunkHealths[chunkHealthIndex]; + if (health > 0.0f && command.health > 0.0f) + { + Actor* actor = getGetChunkActor(chunkIndex); + if (filterActor && filterActor != actor) + { + NVBLASTLL_LOG_WARNING(logFn, "NvBlastActorApplyFracture: chunk fracture command corresponds to other actor, command is ignored."); + } + else if (actor) + { + const uint32_t nodeIndex = m_asset->getChunkToGraphNodeMap()[chunkIndex]; + if (actor->getGraphNodeCount() > 1 && !isInvalidIndex(nodeIndex)) + { + for (uint32_t adjacentIndex = graphAdjacencyPartition[nodeIndex]; adjacentIndex < graphAdjacencyPartition[nodeIndex + 1]; adjacentIndex++) + { + const uint32_t bondIndex = adjacentBondIndices[adjacentIndex]; + NVBLAST_ASSERT(!isInvalidIndex(bondIndex)); + if (bondHealths[bondIndex] > 0.0f) + { + bondHealths[bondIndex] = 0.0f; + } + } + getFamilyGraph()->notifyNodeRemoved(actor->getIndex(), nodeIndex, &graph); + } + + health -= command.health; + + const float remainingDamage = -health; + + if (remainingDamage > 0.0f) // node chunk has been damaged beyond its health + { + fractureSubSupportNoEvents(chunkIndex, m_asset->m_firstSubsupportChunkIndex, remainingDamage, subChunkHealths, chunks); + } + } + } + } +} + + +void FamilyHeader::fractureWithEvents(uint32_t chunkFractureCount, const NvBlastChunkFractureData* commands, NvBlastChunkFractureData* events, uint32_t eventsSize, uint32_t* count, Actor* filterActor, NvBlastLog logFn) +{ + const SupportGraph& graph = m_asset->m_graph; + const uint32_t* graphAdjacencyPartition = graph.getAdjacencyPartition(); + const uint32_t* adjacentBondIndices = graph.getAdjacentBondIndices(); + float* bondHealths = getBondHealths(); + float* chunkHealths = getLowerSupportChunkHealths(); + float* subChunkHealths = getSubsupportChunkHealths(); + const NvBlastChunk* chunks = m_asset->getChunks(); + + for (uint32_t i = 0; i < chunkFractureCount; ++i) + { + const NvBlastChunkFractureData& command = commands[i]; + const uint32_t chunkIndex = command.chunkIndex; + const uint32_t chunkHealthIndex = m_asset->getContiguousLowerSupportIndex(chunkIndex); + NVBLAST_ASSERT(!isInvalidIndex(chunkHealthIndex)); + if (isInvalidIndex(chunkHealthIndex)) + { + continue; + } + float& health = chunkHealths[chunkHealthIndex]; + if (health > 0.0f && command.health > 0.0f) + { + Actor* actor = getGetChunkActor(chunkIndex); + if (filterActor && filterActor != actor) + { + NVBLASTLL_LOG_WARNING(logFn, "NvBlastActorApplyFracture: chunk fracture command corresponds to other actor, command is ignored."); + } + else if (actor) + { + const uint32_t nodeIndex = m_asset->getChunkToGraphNodeMap()[chunkIndex]; + if (actor->getGraphNodeCount() > 1 && !isInvalidIndex(nodeIndex)) + { + for (uint32_t adjacentIndex = graphAdjacencyPartition[nodeIndex]; adjacentIndex < graphAdjacencyPartition[nodeIndex + 1]; adjacentIndex++) + { + const uint32_t bondIndex = adjacentBondIndices[adjacentIndex]; + NVBLAST_ASSERT(!isInvalidIndex(bondIndex)); + if (bondHealths[bondIndex] > 0.0f) + { + bondHealths[bondIndex] = 0.0f; + } + } + getFamilyGraph()->notifyNodeRemoved(actor->getIndex(), nodeIndex, &graph); + } + + health -= command.health; + + if (*count < eventsSize) + { + NvBlastChunkFractureData& outEvent = events[*count]; + outEvent.userdata = chunks[chunkIndex].userData; + outEvent.chunkIndex = chunkIndex; + outEvent.health = health; + } + (*count)++; + + const float remainingDamage = -health; + + if (remainingDamage > 0.0f) // node chunk has been damaged beyond its health + { + fractureSubSupport(chunkIndex, m_asset->m_firstSubsupportChunkIndex, remainingDamage, subChunkHealths, chunks, events, count, eventsSize); + } + } + } + } +} + + +void FamilyHeader::fractureInPlaceEvents(uint32_t chunkFractureCount, NvBlastChunkFractureData* inoutbuffer, uint32_t eventsSize, uint32_t* count, Actor* filterActor, NvBlastLog logFn) +{ + const SupportGraph& graph = m_asset->m_graph; + const uint32_t* graphAdjacencyPartition = graph.getAdjacencyPartition(); + const uint32_t* adjacentBondIndices = graph.getAdjacentBondIndices(); + float* bondHealths = getBondHealths(); + float* chunkHealths = getLowerSupportChunkHealths(); + float* subChunkHealths = getSubsupportChunkHealths(); + const NvBlastChunk* chunks = m_asset->getChunks(); + + // + // First level Chunk Fractures + // + + for (uint32_t i = 0; i < chunkFractureCount; ++i) + { + const NvBlastChunkFractureData& command = inoutbuffer[i]; + const uint32_t chunkIndex = command.chunkIndex; + const uint32_t chunkHealthIndex = m_asset->getContiguousLowerSupportIndex(chunkIndex); + NVBLAST_ASSERT(!isInvalidIndex(chunkHealthIndex)); + if (isInvalidIndex(chunkHealthIndex)) + { + continue; + } + float& health = chunkHealths[chunkHealthIndex]; + if (health > 0.0f && command.health > 0.0f) + { + Actor* actor = getGetChunkActor(chunkIndex); + if (filterActor && filterActor != actor) + { + NVBLASTLL_LOG_WARNING(logFn, "NvBlastActorApplyFracture: chunk fracture command corresponds to other actor, command is ignored."); + } + else if (actor) + { + const uint32_t nodeIndex = m_asset->getChunkToGraphNodeMap()[chunkIndex]; + if (actor->getGraphNodeCount() > 1 && !isInvalidIndex(nodeIndex)) + { + for (uint32_t adjacentIndex = graphAdjacencyPartition[nodeIndex]; adjacentIndex < graphAdjacencyPartition[nodeIndex + 1]; adjacentIndex++) + { + const uint32_t bondIndex = adjacentBondIndices[adjacentIndex]; + NVBLAST_ASSERT(!isInvalidIndex(bondIndex)); + if (bondHealths[bondIndex] > 0.0f) + { + bondHealths[bondIndex] = 0.0f; + } + } + getFamilyGraph()->notifyNodeRemoved(actor->getIndex(), nodeIndex, &graph); + } + + health -= command.health; + + NvBlastChunkFractureData& outEvent = inoutbuffer[(*count)++]; + outEvent.userdata = chunks[chunkIndex].userData; + outEvent.chunkIndex = chunkIndex; + outEvent.health = health; + } + } + } + + // + // Hierarchical Chunk Fractures + // + + uint32_t commandedChunkFractures = *count; + + for (uint32_t i = 0; i < commandedChunkFractures; ++i) + { + NvBlastChunkFractureData& event = inoutbuffer[i]; + const uint32_t chunkIndex = event.chunkIndex; + + const float remainingDamage = -event.health; + if (remainingDamage > 0.0f) // node chunk has been damaged beyond its health + { + fractureSubSupport(chunkIndex, m_asset->m_firstSubsupportChunkIndex, remainingDamage, subChunkHealths, chunks, inoutbuffer, count, eventsSize); + } + } +} + + +void FamilyHeader::applyFracture(NvBlastFractureBuffers* eventBuffers, const NvBlastFractureBuffers* commands, Actor* filterActor, NvBlastLog logFn, NvBlastTimers* timers) +{ + NVBLASTLL_CHECK(commands != nullptr, logFn, "NvBlastActorApplyFracture: NULL commands pointer input.", return); + NVBLASTLL_CHECK(isValid(commands), logFn, "NvBlastActorApplyFracture: commands memory is NULL but size is > 0.", return); + NVBLASTLL_CHECK(eventBuffers == nullptr || isValid(eventBuffers), logFn, "NvBlastActorApplyFracture: eventBuffers memory is NULL but size is > 0.", + eventBuffers->bondFractureCount = 0; eventBuffers->chunkFractureCount = 0; return); + +#if NVBLASTLL_CHECK_PARAMS + if (eventBuffers != nullptr && eventBuffers->bondFractureCount == 0 && eventBuffers->chunkFractureCount == 0) + { + NVBLASTLL_LOG_WARNING(logFn, "NvBlastActorApplyFracture: eventBuffers do not provide any space."); + return; + } +#endif + +#if NV_PROFILE + Time time; +#else + NV_UNUSED(timers); +#endif + + // + // Chunk Fracture + // + + if (eventBuffers == nullptr || eventBuffers->chunkFractures == nullptr) + { + // immediate hierarchical fracture + fractureNoEvents(commands->chunkFractureCount, commands->chunkFractures, filterActor, logFn); + } + else if (eventBuffers->chunkFractures != commands->chunkFractures) + { + // immediate hierarchical fracture + uint32_t count = 0; + fractureWithEvents(commands->chunkFractureCount, commands->chunkFractures, eventBuffers->chunkFractures, eventBuffers->chunkFractureCount, &count, filterActor, logFn); + + if (count > eventBuffers->chunkFractureCount) + { + NVBLASTLL_LOG_WARNING(logFn, "NvBlastActorApplyFracture: eventBuffers too small. Chunk events were lost."); + } + else + { + eventBuffers->chunkFractureCount = count; + } + } + else if (eventBuffers->chunkFractures == commands->chunkFractures) + { + // compacting first + uint32_t count = 0; + fractureInPlaceEvents(commands->chunkFractureCount, commands->chunkFractures, eventBuffers->chunkFractureCount, &count, filterActor, logFn); + + if (count > eventBuffers->chunkFractureCount) + { + NVBLASTLL_LOG_WARNING(logFn, "NvBlastActorApplyFracture: eventBuffers too small. Chunk events were lost."); + } + else + { + eventBuffers->chunkFractureCount = count; + } + } + + // + // Bond Fracture + // + + uint32_t outCount = 0; + const uint32_t eventBufferSize = eventBuffers ? eventBuffers->bondFractureCount : 0; + + NvBlastBond* bonds = m_asset->getBonds(); + float* bondHealths = getBondHealths(); + const uint32_t* graphChunkIndices = m_asset->m_graph.getChunkIndices(); + for (uint32_t i = 0; i < commands->bondFractureCount; ++i) + { + const NvBlastBondFractureData& frac = commands->bondFractures[i]; + NVBLAST_ASSERT(frac.nodeIndex0 < m_asset->m_graph.m_nodeCount); + NVBLAST_ASSERT(frac.nodeIndex1 < m_asset->m_graph.m_nodeCount); + uint32_t chunkIndex0 = graphChunkIndices[frac.nodeIndex0]; + uint32_t chunkIndex1 = graphChunkIndices[frac.nodeIndex1]; + NVBLAST_ASSERT(!isInvalidIndex(chunkIndex0) || !isInvalidIndex(chunkIndex1)); + Actor* actor0 = !isInvalidIndex(chunkIndex0) ? getGetChunkActor(chunkIndex0) : nullptr; + Actor* actor1 = !isInvalidIndex(chunkIndex1) ? getGetChunkActor(chunkIndex1) : nullptr; + NVBLAST_ASSERT(actor0 != nullptr || actor1 != nullptr); + // If actors are not nullptr and different then bond is already broken + // One of actor can be nullptr which probably means it's 'world' node. + if (actor0 == actor1 || actor0 == nullptr || actor1 == nullptr) + { + Actor* actor = actor0 ? actor0 : actor1; + NVBLAST_ASSERT_WITH_MESSAGE(actor, "NvBlastActorApplyFracture: all actors in bond fracture command are nullptr, command will be safely ignored, but investigation is recommended."); + if (filterActor && filterActor != actor) + { + NVBLASTLL_LOG_WARNING(logFn, "NvBlastActorApplyFracture: bond fracture command corresponds to other actor, command is ignored."); + } + else if (actor) + { + const uint32_t bondIndex = actor->damageBond(frac.nodeIndex0, frac.nodeIndex1, frac.health); + if (!isInvalidIndex(bondIndex)) + { + if (eventBuffers && eventBuffers->bondFractures) + { + if (outCount < eventBufferSize) + { + NvBlastBondFractureData& outEvent = eventBuffers->bondFractures[outCount]; + outEvent.userdata = bonds[bondIndex].userData; + outEvent.nodeIndex0 = frac.nodeIndex0; + outEvent.nodeIndex1 = frac.nodeIndex1; + outEvent.health = bondHealths[bondIndex]; + } + } + outCount++; + } + } + } + } + + if (eventBuffers && eventBuffers->bondFractures) + { + if (outCount > eventBufferSize) + { + NVBLASTLL_LOG_WARNING(logFn, "NvBlastActorApplyFracture: eventBuffers too small. Bond events were lost."); + } + else + { + eventBuffers->bondFractureCount = outCount; + } + } + +#if NV_PROFILE + if (timers != nullptr) + { + timers->fracture += time.getElapsedTicks(); + } +#endif + +} + + } // namespace Blast } // namespace Nv @@ -167,22 +596,29 @@ NvBlastFamily* NvBlastAssetCreateFamily(void* mem, const NvBlastAsset* asset, Nv uint32_t NvBlastFamilyGetFormatVersion(const NvBlastFamily* family, NvBlastLog logFn) { - NVBLAST_CHECK(family != nullptr, logFn, "NvBlastFamilyGetFormatVersion: NULL family pointer input.", return UINT32_MAX); + NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilyGetFormatVersion: NULL family pointer input.", return UINT32_MAX); return reinterpret_cast<const Nv::Blast::FamilyHeader*>(family)->formatVersion; } +const NvBlastAsset* NvBlastFamilyGetAsset(const NvBlastFamily* family, NvBlastLog logFn) +{ + NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilyGetAssetID: NULL family pointer input.", return nullptr); + return reinterpret_cast<const Nv::Blast::FamilyHeader*>(family)->m_asset; +} + + void NvBlastFamilySetAsset(NvBlastFamily* family, const NvBlastAsset* asset, NvBlastLog logFn) { - NVBLAST_CHECK(family != nullptr, logFn, "NvBlastFamilySetAsset: NULL family pointer input.", return); - NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastFamilySetAsset: NULL asset pointer input.", return); + NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilySetAsset: NULL family pointer input.", return); + NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastFamilySetAsset: NULL asset pointer input.", return); Nv::Blast::FamilyHeader* header = reinterpret_cast<Nv::Blast::FamilyHeader*>(family); const Nv::Blast::Asset* solverAsset = reinterpret_cast<const Nv::Blast::Asset*>(asset); if (memcmp(&header->m_assetID, &solverAsset->m_ID, sizeof(NvBlastID))) { - NVBLAST_LOG_ERROR(logFn, "NvBlastFamilySetAsset: wrong asset. Passed asset ID doesn't match family asset ID."); + NVBLASTLL_LOG_ERROR(logFn, "NvBlastFamilySetAsset: wrong asset. Passed asset ID doesn't match family asset ID."); return; } @@ -192,47 +628,35 @@ void NvBlastFamilySetAsset(NvBlastFamily* family, const NvBlastAsset* asset, NvB uint32_t NvBlastFamilyGetSize(const NvBlastFamily* family, NvBlastLog logFn) { - NVBLAST_CHECK(family != nullptr, logFn, "NvBlastFamilyGetSize: NULL family pointer input.", return 0); + NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilyGetSize: NULL family pointer input.", return 0); return reinterpret_cast<const Nv::Blast::FamilyHeader*>(family)->size; } NvBlastID NvBlastFamilyGetAssetID(const NvBlastFamily* family, NvBlastLog logFn) { - NVBLAST_CHECK(family != nullptr, logFn, "NvBlastFamilyGetAssetID: NULL family pointer input.", return NvBlastID()); + NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilyGetAssetID: NULL family pointer input.", return NvBlastID()); return reinterpret_cast<const Nv::Blast::FamilyHeader*>(family)->m_assetID; } uint32_t NvBlastFamilyGetActorCount(const NvBlastFamily* family, NvBlastLog logFn) { - NVBLAST_CHECK(family != nullptr, logFn, "NvBlastFamilyGetActorCount: NULL family pointer input.", return 0); + NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilyGetActorCount: NULL family pointer input.", return 0); const Nv::Blast::FamilyHeader* header = reinterpret_cast<const Nv::Blast::FamilyHeader*>(family); - if (header->formatVersion != NvBlastFamilyDataFormat::Current) - { - NVBLAST_LOG_ERROR(logFn, "NvBlastFamilyGetActorCount: wrong family format. Family must be converted to current version."); - return 0; - } - return header->m_actorCount; } uint32_t NvBlastFamilyGetActors(NvBlastActor** actors, uint32_t actorsSize, const NvBlastFamily* family, NvBlastLog logFn) { - NVBLAST_CHECK(actors != nullptr, logFn, "NvBlastFamilyGetActors: NULL actors pointer input.", return 0); - NVBLAST_CHECK(family != nullptr, logFn, "NvBlastFamilyGetActors: NULL family pointer input.", return 0); + NVBLASTLL_CHECK(actors != nullptr, logFn, "NvBlastFamilyGetActors: NULL actors pointer input.", return 0); + NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilyGetActors: NULL family pointer input.", return 0); const Nv::Blast::FamilyHeader* header = reinterpret_cast<const Nv::Blast::FamilyHeader*>(family); - if (header->formatVersion != NvBlastFamilyDataFormat::Current) - { - NVBLAST_LOG_ERROR(logFn, "NvBlastFamilyGetActors: wrong family format. Family must be converted to current version."); - return 0; - } - // Iterate through active actors and write to supplied array const uint32_t familyActorCount = header->getActorBufferSize(); Nv::Blast::Actor* familyActor = header->getActors(); @@ -251,43 +675,20 @@ uint32_t NvBlastFamilyGetActors(NvBlastActor** actors, uint32_t actorsSize, cons NvBlastActor* NvBlastFamilyGetChunkActor(const NvBlastFamily* family, uint32_t chunkIndex, NvBlastLog logFn) { - NVBLAST_CHECK(family != nullptr, logFn, "NvBlastFamilyGetChunkActor: NULL family pointer input.", return nullptr); + NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilyGetChunkActor: NULL family pointer input.", return nullptr); const Nv::Blast::FamilyHeader* header = reinterpret_cast<const Nv::Blast::FamilyHeader*>(family); - NVBLAST_CHECK(header->m_asset != nullptr, logFn, "NvBlastFamilyGetChunkActor: NvBlastFamily has null asset set.", return nullptr); - - const Nv::Blast::Asset& solverAsset = *static_cast<const Nv::Blast::Asset*>(header->m_asset); - NVBLAST_CHECK(chunkIndex < solverAsset.m_chunkCount, logFn, "NvBlastFamilyGetChunkActor: bad value of chunkIndex for the given family's asset.", return nullptr); - - // get actorIndex from chunkIndex - uint32_t actorIndex; - if (chunkIndex < solverAsset.getUpperSupportChunkCount()) - { - actorIndex = header->getChunkActorIndices()[chunkIndex]; - } - else - { - actorIndex = chunkIndex - (solverAsset.getUpperSupportChunkCount() - solverAsset.m_graph.m_nodeCount); - } + NVBLASTLL_CHECK(header->m_asset != nullptr, logFn, "NvBlastFamilyGetChunkActor: NvBlastFamily has null asset set.", return nullptr); + NVBLASTLL_CHECK(chunkIndex < header->m_asset->m_chunkCount, logFn, "NvBlastFamilyGetChunkActor: bad value of chunkIndex for the given family's asset.", return nullptr); - // get actor from actorIndex - if (!Nv::Blast::isInvalidIndex(actorIndex)) - { - NVBLAST_ASSERT(actorIndex < header->getActorBufferSize()); - Nv::Blast::Actor* actor = &header->getActors()[actorIndex]; - if (actor->isActive()) - { - return actor; - } - } - return nullptr; + return header->getGetChunkActor(chunkIndex); } uint32_t NvBlastFamilyGetMaxActorCount(const NvBlastFamily* family, NvBlastLog logFn) { - NVBLAST_CHECK(family != nullptr, logFn, "NvBlastFamilyGetMaxActorCount: NULL family pointer input.", return 0); + NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilyGetMaxActorCount: NULL family pointer input.", return 0); const Nv::Blast::FamilyHeader* header = reinterpret_cast<const Nv::Blast::FamilyHeader*>(family); return header->getActorBufferSize(); } |