aboutsummaryrefslogtreecommitdiff
path: root/sdk/lowlevel/source
diff options
context:
space:
mode:
authorAnton Novoselov <[email protected]>2017-08-01 12:53:38 +0300
committerAnton Novoselov <[email protected]>2017-08-01 12:53:38 +0300
commit236f03c0b9a4982328ed1201978f7f69d192d9b2 (patch)
treee486f2fa39dba203563895541e92c60ed3e25759 /sdk/lowlevel/source
parentAdded screens to welcome page (diff)
downloadblast-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')
-rw-r--r--sdk/lowlevel/source/NvBlastActor.cpp629
-rw-r--r--sdk/lowlevel/source/NvBlastActor.h198
-rw-r--r--sdk/lowlevel/source/NvBlastActorSerializationBlock.cpp109
-rw-r--r--sdk/lowlevel/source/NvBlastActorSerializationBlock.h36
-rw-r--r--sdk/lowlevel/source/NvBlastAsset.cpp236
-rw-r--r--sdk/lowlevel/source/NvBlastAsset.h36
-rw-r--r--sdk/lowlevel/source/NvBlastAssetHelper.cpp108
-rw-r--r--sdk/lowlevel/source/NvBlastChunkHierarchy.h36
-rw-r--r--sdk/lowlevel/source/NvBlastFamily.cpp535
-rw-r--r--sdk/lowlevel/source/NvBlastFamily.h216
-rw-r--r--sdk/lowlevel/source/NvBlastFamilyGraph.cpp36
-rw-r--r--sdk/lowlevel/source/NvBlastFamilyGraph.h37
-rw-r--r--sdk/lowlevel/source/NvBlastSupportGraph.h37
13 files changed, 1388 insertions, 861 deletions
diff --git a/sdk/lowlevel/source/NvBlastActor.cpp b/sdk/lowlevel/source/NvBlastActor.cpp
index b93c47a..afed7bb 100644
--- a/sdk/lowlevel/source/NvBlastActor.cpp
+++ b/sdk/lowlevel/source/NvBlastActor.cpp
@@ -1,12 +1,30 @@
-/*
-* 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 "NvBlastActor.h"
#include "NvBlastFamilyGraph.h"
@@ -24,29 +42,11 @@ namespace Nv
namespace Blast
{
-//////// Local helper functions ////////
-
-#if NVBLAST_CHECK_PARAMS
-/**
-Helper function to validate fracture buffer values being meaningful.
-*/
-static inline bool isValid(const NvBlastFractureBuffers* buffers)
-{
- if (buffers->chunkFractureCount != 0 && buffers->chunkFractures == nullptr)
- return false;
-
- if (buffers->bondFractureCount != 0 && buffers->bondFractures == nullptr)
- return false;
-
- return true;
-}
-#endif
-
//////// Actor static methods ////////
size_t Actor::createRequiredScratch(const NvBlastFamily* family)
{
-#if NVBLAST_CHECK_PARAMS
+#if NVBLASTLL_CHECK_PARAMS
if (family == nullptr || reinterpret_cast<const FamilyHeader*>(family)->m_asset == nullptr)
{
NVBLAST_ALWAYS_ASSERT();
@@ -61,22 +61,22 @@ size_t Actor::createRequiredScratch(const NvBlastFamily* family)
Actor* Actor::create(NvBlastFamily* family, const NvBlastActorDesc* desc, void* scratch, NvBlastLog logFn)
{
- NVBLAST_CHECK(family != nullptr, logFn, "Actor::create: NULL family pointer input.", return nullptr);
- NVBLAST_CHECK(reinterpret_cast<FamilyHeader*>(family)->m_asset != nullptr, logFn, "Actor::create: family has NULL asset.", return nullptr);
- NVBLAST_CHECK(reinterpret_cast<FamilyHeader*>(family)->m_asset->m_graph.m_nodeCount != 0, logFn, "Actor::create: family's asset has no support chunks.", return nullptr);
- NVBLAST_CHECK(desc != nullptr, logFn, "Actor::create: NULL desc pointer input.", return nullptr);
- NVBLAST_CHECK(scratch != nullptr, logFn, "Actor::create: NULL scratch input.", return nullptr);
+ NVBLASTLL_CHECK(family != nullptr, logFn, "Actor::create: NULL family pointer input.", return nullptr);
+ NVBLASTLL_CHECK(reinterpret_cast<FamilyHeader*>(family)->m_asset != nullptr, logFn, "Actor::create: family has NULL asset.", return nullptr);
+ NVBLASTLL_CHECK(reinterpret_cast<FamilyHeader*>(family)->m_asset->m_graph.m_nodeCount != 0, logFn, "Actor::create: family's asset has no support chunks.", return nullptr);
+ NVBLASTLL_CHECK(desc != nullptr, logFn, "Actor::create: NULL desc pointer input.", return nullptr);
+ NVBLASTLL_CHECK(scratch != nullptr, logFn, "Actor::create: NULL scratch input.", return nullptr);
FamilyHeader* header = reinterpret_cast<FamilyHeader*>(family);
if (header->m_actorCount > 0)
{
- NVBLAST_LOG_ERROR(logFn, "Actor::create: input family is not empty.");
+ NVBLASTLL_LOG_ERROR(logFn, "Actor::create: input family is not empty.");
return nullptr;
}
const Asset& solverAsset = *static_cast<const Asset*>(header->m_asset);
- const Nv::Blast::SupportGraph& graph = solverAsset.m_graph;
+ const SupportGraph& graph = solverAsset.m_graph;
// Lower support chunk healths - initialize
float* lowerSupportChunkHealths = header->getLowerSupportChunkHealths();
@@ -190,14 +190,14 @@ uint32_t Actor::damageBond(const NvBlastBondFractureData& cmd)
void Actor::generateFracture(NvBlastFractureBuffers* commandBuffers, const NvBlastDamageProgram& program, const NvBlastProgramParams* programParams,
NvBlastLog logFn, NvBlastTimers* timers) const
{
- NVBLAST_CHECK(commandBuffers != nullptr, logFn, "Actor::generateFracture: NULL commandBuffers pointer input.", return);
- NVBLAST_CHECK(isValid(commandBuffers), logFn, "NvBlastActorGenerateFracture: commandBuffers memory is NULL but size is > 0.",
+ NVBLASTLL_CHECK(commandBuffers != nullptr, logFn, "Actor::generateFracture: NULL commandBuffers pointer input.", return);
+ NVBLASTLL_CHECK(isValid(commandBuffers), logFn, "NvBlastActorGenerateFracture: commandBuffers memory is NULL but size is > 0.",
commandBuffers->bondFractureCount = 0; commandBuffers->chunkFractureCount = 0; return);
-#if NVBLAST_CHECK_PARAMS
+#if NVBLASTLL_CHECK_PARAMS
if (commandBuffers->bondFractureCount == 0 && commandBuffers->chunkFractureCount == 0)
{
- NVBLAST_LOG_WARNING(logFn, "NvBlastActorGenerateFracture: commandBuffers do not provide any space.");
+ NVBLASTLL_LOG_WARNING(logFn, "NvBlastActorGenerateFracture: commandBuffers do not provide any space.");
return;
}
#endif
@@ -221,7 +221,9 @@ void Actor::generateFracture(NvBlastFractureBuffers* commandBuffers, const NvBla
graph->getAdjacentNodeIndices(),
graph->getAdjacentBondIndices(),
getBonds(),
- getBondHealths()
+ getChunks(),
+ getBondHealths(),
+ getLowerSupportChunkHealths()
};
program.graphShaderFunction(commandBuffers, &shaderActor, programParams);
@@ -252,374 +254,6 @@ void Actor::generateFracture(NvBlastFractureBuffers* commandBuffers, const NvBla
}
-void Actor::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 Actor::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 Actor::fractureNoEvents(uint32_t chunkFractureCount, const NvBlastChunkFractureData* chunkFractures)
-{
- const Asset& asset = *getAsset();
- const SupportGraph& graph = *getGraph();
- const uint32_t* graphAdjacencyPartition = graph.getAdjacencyPartition();
- const uint32_t* graphAdjacentNodeIndices = graph.getAdjacentNodeIndices();
- float* bondHealths = getBondHealths();
- float* chunkHealths = getLowerSupportChunkHealths();
- float* subChunkHealths = getSubsupportChunkHealths();
- const NvBlastChunk* chunks = getChunks();
-
- for (uint32_t i = 0; i < chunkFractureCount; ++i)
- {
- const NvBlastChunkFractureData& command = chunkFractures[i];
- const uint32_t chunkIndex = command.chunkIndex;
- const uint32_t chunkHealthIndex = asset.getContiguousLowerSupportIndex(chunkIndex);
- NVBLAST_ASSERT(!isInvalidIndex(chunkHealthIndex));
- if (isInvalidIndex(chunkHealthIndex))
- {
- continue;
- }
- float& health = chunkHealths[chunkHealthIndex];
- if (health > 0.0f && command.health > 0.0f)
- {
- const uint32_t nodeIndex = asset.getChunkToGraphNodeMap()[chunkIndex];
- if (getGraphNodeCount() > 1 && !isInvalidIndex(nodeIndex))
- {
- for (uint32_t adjacentIndex = graphAdjacencyPartition[nodeIndex]; adjacentIndex < graphAdjacencyPartition[nodeIndex + 1]; adjacentIndex++)
- {
-
- const uint32_t bondIndex = graph.findBond(nodeIndex, graphAdjacentNodeIndices[adjacentIndex]);
- NVBLAST_ASSERT(!isInvalidIndex(bondIndex));
- if (bondHealths[bondIndex] > 0.0f)
- {
- bondHealths[bondIndex] = 0.0f;
- }
- }
- getFamilyGraph()->notifyNodeRemoved(getIndex(), nodeIndex, &graph);
- }
-
- health -= command.health;
-
- const float remainingDamage = -health;
-
- if (remainingDamage > 0.0f) // node chunk has been damaged beyond its health
- {
- uint32_t firstSubOffset = getFirstSubsupportChunkIndex();
- fractureSubSupportNoEvents(chunkIndex, firstSubOffset, remainingDamage, subChunkHealths, chunks);
- }
- }
- }
-}
-
-
-void Actor::fractureWithEvents(uint32_t chunkFractureCount, const NvBlastChunkFractureData* commands, NvBlastChunkFractureData* events, uint32_t eventsSize, uint32_t* count)
-{
- const Asset& asset = *getAsset();
- const SupportGraph& graph = *getGraph();
- const uint32_t* graphAdjacencyPartition = graph.getAdjacencyPartition();
- const uint32_t* graphAdjacentNodeIndices = graph.getAdjacentNodeIndices();
- float* bondHealths = getBondHealths();
- float* chunkHealths = getLowerSupportChunkHealths();
- float* subChunkHealths = getSubsupportChunkHealths();
- const NvBlastChunk* chunks = getChunks();
-
- for (uint32_t i = 0; i < chunkFractureCount; ++i)
- {
- const NvBlastChunkFractureData& command = commands[i];
- const uint32_t chunkIndex = command.chunkIndex;
- const uint32_t chunkHealthIndex = asset.getContiguousLowerSupportIndex(chunkIndex);
- NVBLAST_ASSERT(!isInvalidIndex(chunkHealthIndex));
- if (isInvalidIndex(chunkHealthIndex))
- {
- continue;
- }
- float& health = chunkHealths[chunkHealthIndex];
- if (health > 0.0f && command.health > 0.0f)
- {
- const uint32_t nodeIndex = asset.getChunkToGraphNodeMap()[chunkIndex];
- if (getGraphNodeCount() > 1 && !isInvalidIndex(nodeIndex))
- {
- for (uint32_t adjacentIndex = graphAdjacencyPartition[nodeIndex]; adjacentIndex < graphAdjacencyPartition[nodeIndex + 1]; adjacentIndex++)
- {
- const uint32_t bondIndex = graph.findBond(nodeIndex, graphAdjacentNodeIndices[adjacentIndex]);
- NVBLAST_ASSERT(!isInvalidIndex(bondIndex));
- if (bondHealths[bondIndex] > 0.0f)
- {
- bondHealths[bondIndex] = 0.0f;
- }
- }
- getFamilyGraph()->notifyNodeRemoved(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
- {
- uint32_t firstSubOffset = getFirstSubsupportChunkIndex();
- fractureSubSupport(chunkIndex, firstSubOffset, remainingDamage, subChunkHealths, chunks, events, count, eventsSize);
- }
- }
- }
-}
-
-
-void Actor::fractureInPlaceEvents(uint32_t chunkFractureCount, NvBlastChunkFractureData* inoutbuffer, uint32_t eventsSize, uint32_t* count)
-{
- const Asset& asset = *getAsset();
- const SupportGraph& graph = *getGraph();
- const uint32_t* graphAdjacencyPartition = graph.getAdjacencyPartition();
- const uint32_t* graphAdjacentNodeIndices = graph.getAdjacentNodeIndices();
- float* bondHealths = getBondHealths();
- float* chunkHealths = getLowerSupportChunkHealths();
- float* subChunkHealths = getSubsupportChunkHealths();
- const NvBlastChunk* chunks = 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 = asset.getContiguousLowerSupportIndex(chunkIndex);
- NVBLAST_ASSERT(!isInvalidIndex(chunkHealthIndex));
- if (isInvalidIndex(chunkHealthIndex))
- {
- continue;
- }
- float& health = chunkHealths[chunkHealthIndex];
- if (health > 0.0f && command.health > 0.0f)
- {
- const uint32_t nodeIndex = asset.getChunkToGraphNodeMap()[chunkIndex];
- if (getGraphNodeCount() > 1 && !isInvalidIndex(nodeIndex))
- {
- for (uint32_t adjacentIndex = graphAdjacencyPartition[nodeIndex]; adjacentIndex < graphAdjacencyPartition[nodeIndex + 1]; adjacentIndex++)
- {
- const uint32_t bondIndex = graph.findBond(nodeIndex, graphAdjacentNodeIndices[adjacentIndex]);
- NVBLAST_ASSERT(!isInvalidIndex(bondIndex));
- if (bondHealths[bondIndex] > 0.0f)
- {
- bondHealths[bondIndex] = 0.0f;
- }
- }
- getFamilyGraph()->notifyNodeRemoved(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
- {
- uint32_t firstSubOffset = getFirstSubsupportChunkIndex();
- fractureSubSupport(chunkIndex, firstSubOffset, remainingDamage, subChunkHealths, chunks, inoutbuffer, count, eventsSize);
- }
- }
-}
-
-
-void Actor::applyFracture(NvBlastFractureBuffers* eventBuffers, const NvBlastFractureBuffers* commands, NvBlastLog logFn, NvBlastTimers* timers)
-{
- NVBLAST_CHECK(commands != nullptr, logFn, "Actor::applyFracture: NULL commands pointer input.", return);
- NVBLAST_CHECK(isValid(commands), logFn, "Actor::applyFracture: commands memory is NULL but size is > 0.", return);
- NVBLAST_CHECK(eventBuffers == nullptr || isValid(eventBuffers), logFn, "NvBlastActorApplyFracture: eventBuffers memory is NULL but size is > 0.",
- eventBuffers->bondFractureCount = 0; eventBuffers->chunkFractureCount = 0; return);
-
-#if NVBLAST_CHECK_PARAMS
- if (eventBuffers != nullptr && eventBuffers->bondFractureCount == 0 && eventBuffers->chunkFractureCount == 0)
- {
- NVBLAST_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);
- }
- else if (eventBuffers->chunkFractures != commands->chunkFractures)
- {
- // immediate hierarchical fracture
- uint32_t count = 0;
- fractureWithEvents(commands->chunkFractureCount, commands->chunkFractures, eventBuffers->chunkFractures, eventBuffers->chunkFractureCount, &count);
-
- if (count > eventBuffers->chunkFractureCount)
- {
- NVBLAST_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);
-
- if (count > eventBuffers->chunkFractureCount)
- {
- NVBLAST_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 = getBonds();
- float* bondHealths = getBondHealths();
- for (uint32_t i = 0; i < commands->bondFractureCount; ++i)
- {
- const NvBlastBondFractureData& frac = commands->bondFractures[i];
-
- const uint32_t bondIndex = 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)
- {
- NVBLAST_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
-
-}
size_t Actor::splitRequiredScratch() const
@@ -630,9 +264,9 @@ size_t Actor::splitRequiredScratch() const
uint32_t Actor::split(NvBlastActorSplitEvent* result, uint32_t newActorsMaxCount, void* scratch, NvBlastLog logFn, NvBlastTimers* timers)
{
- NVBLAST_CHECK(result != nullptr, logFn, "Actor::split: NULL result pointer input.", return 0);
- NVBLAST_CHECK(newActorsMaxCount > 0 && result->newActors != nullptr, logFn, "NvBlastActorSplit: no space for results provided.", return 0);
- NVBLAST_CHECK(scratch != nullptr, logFn, "Actor::split: NULL scratch pointer input.", return 0);
+ NVBLASTLL_CHECK(result != nullptr, logFn, "Actor::split: NULL result pointer input.", return 0);
+ NVBLASTLL_CHECK(newActorsMaxCount > 0 && result->newActors != nullptr, logFn, "NvBlastActorSplit: no space for results provided.", return 0);
+ NVBLASTLL_CHECK(scratch != nullptr, logFn, "Actor::split: NULL scratch pointer input.", return 0);
#if NV_PROFILE
Time time;
@@ -708,10 +342,21 @@ uint32_t Actor::split(NvBlastActorSplitEvent* result, uint32_t newActorsMaxCount
#endif
// Recalculate visible chunk lists if the graph nodes have been redistributed
+ uint32_t actualActorsCount = 0;
for (uint32_t i = 0; i < actorsCount; ++i)
{
- newActors[i]->updateVisibleChunksFromGraphNodes();
+ newActors[actualActorsCount] = newActors[i];
+ newActors[actualActorsCount]->updateVisibleChunksFromGraphNodes();
+ if (newActors[actualActorsCount]->getVisibleChunkCount() > 0) // If we've split such that the world node is by itself, it will have no visible chunks
+ {
+ ++actualActorsCount;
+ }
+ else
+ {
+ getFamilyHeader()->returnActor(*newActors[actualActorsCount]);
+ }
}
+ actorsCount = actualActorsCount;
#if NV_PROFILE
if (timers != nullptr)
@@ -780,7 +425,7 @@ uint32_t Actor::partitionMultipleGraphNodes(Actor** newActors, uint32_t newActor
// Check for single subsupport chunk, no partitioning
if (m_graphNodeCount <= 1)
{
- NVBLAST_LOG_WARNING(logFn, "Nv::Blast::Actor::partitionMultipleGraphNodes: actor is a single lower-support chunk, and cannot be partitioned by this function.");
+ NVBLASTLL_LOG_WARNING(logFn, "Nv::Blast::Actor::partitionMultipleGraphNodes: actor is a single lower-support chunk, and cannot be partitioned by this function.");
return 0;
}
@@ -810,7 +455,11 @@ uint32_t Actor::partitionMultipleGraphNodes(Actor** newActors, uint32_t newActor
if (islandID == thisActorIndex)
{
- m_leafChunkCount += subtreeLeafChunkCounts[graphChunkIndices[graphNodeIndex]];
+ const uint32_t graphChunkIndex = graphChunkIndices[graphNodeIndex];
+ if (!isInvalidIndex(graphChunkIndex)) // Invalid if this is the world chunk
+ {
+ m_leafChunkCount += subtreeLeafChunkCounts[graphChunkIndex];
+ }
lastGraphNodeIndex = graphNodeIndex;
continue; // Leave the chunk in this actor
}
@@ -855,7 +504,11 @@ uint32_t Actor::partitionMultipleGraphNodes(Actor** newActors, uint32_t newActor
newActor->m_firstGraphNodeIndex = graphNodeIndex;
++newActor->m_graphNodeCount;
// Add to the actor's leaf chunk count
- newActor->m_leafChunkCount += subtreeLeafChunkCounts[graphChunkIndices[graphNodeIndex]];
+ const uint32_t graphChunkIndex = graphChunkIndices[graphNodeIndex];
+ if (!isInvalidIndex(graphChunkIndex)) // Invalid if this is the world chunk
+ {
+ newActor->m_leafChunkCount += subtreeLeafChunkCounts[graphChunkIndex];
+ }
}
if (m_graphNodeCount > 0)
@@ -878,7 +531,7 @@ uint32_t Actor::partitionMultipleGraphNodes(Actor** newActors, uint32_t newActor
if (overflow)
{
- NVBLAST_LOG_WARNING(logFn, "Nv::Blast::Actor::partitionMultipleGraphNodes: input newActors array could not hold all actors generated.");
+ NVBLASTLL_LOG_WARNING(logFn, "Nv::Blast::Actor::partitionMultipleGraphNodes: input newActors array could not hold all actors generated.");
}
return newActorCount;
@@ -892,7 +545,7 @@ uint32_t Actor::partitionSingleLowerSupportChunk(Actor** newActors, uint32_t new
// Ensure this is a single subsupport chunk, no partitioning
if (m_graphNodeCount > 1)
{
- NVBLAST_LOG_WARNING(logFn, "Nv::Blast::Actor::partitionSingleLowerSupportChunk: actor is not a single lower-support chunk, and cannot be partitioned by this function.");
+ NVBLASTLL_LOG_WARNING(logFn, "Nv::Blast::Actor::partitionSingleLowerSupportChunk: actor is not a single lower-support chunk, and cannot be partitioned by this function.");
return 0;
}
@@ -901,6 +554,12 @@ uint32_t Actor::partitionSingleLowerSupportChunk(Actor** newActors, uint32_t new
// The conditional (visible vs. support chunk) is needed because we allow single-child chunk chains
// This makes it possible that an actor with a single support chunk will have a different visible chunk (ancestor of the support chunk)
const uint32_t chunkIndex = m_graphNodeCount == 0 ? m_firstVisibleChunkIndex : getGraph()->getChunkIndices()[m_firstGraphNodeIndex];
+
+ if (isInvalidIndex(chunkIndex))
+ {
+ return 0; // This actor has no chunks; only a graph node representing the world
+ }
+
NVBLAST_ASSERT(isInvalidIndex(header->getVisibleChunkIndexLinks()[chunkIndex].m_adj[1]));
const NvBlastChunk& chunk = header->m_asset->getChunks()[chunkIndex];
@@ -909,7 +568,7 @@ uint32_t Actor::partitionSingleLowerSupportChunk(Actor** newActors, uint32_t new
// Warn if we cannot fit all child chunks in the output list
if (childCount > newActorsSize)
{
- NVBLAST_LOG_WARNING(logFn, "Nv::Blast::Actor::partitionSingleLowerSupportChunk: input newActors array will not hold all actors generated.");
+ NVBLASTLL_LOG_WARNING(logFn, "Nv::Blast::Actor::partitionSingleLowerSupportChunk: input newActors array will not hold all actors generated.");
childCount = newActorsSize;
}
@@ -959,7 +618,7 @@ void Actor::updateVisibleChunksFromGraphNodes()
Actor* actors = header->getActors();
IndexDLink<uint32_t>* visibleChunkIndexLinks = header->getVisibleChunkIndexLinks();
uint32_t* chunkActorIndices = header->getChunkActorIndices();
- const Nv::Blast::SupportGraph& graph = asset->m_graph;
+ const SupportGraph& graph = asset->m_graph;
const uint32_t* graphChunkIndices = graph.getChunkIndices();
const NvBlastChunk* chunks = asset->getChunks();
const uint32_t upperSupportChunkCount = asset->getUpperSupportChunkCount();
@@ -968,7 +627,11 @@ void Actor::updateVisibleChunksFromGraphNodes()
const uint32_t* graphNodeIndexLinks = header->getGraphNodeIndexLinks();
for (uint32_t graphNodeIndex = m_firstGraphNodeIndex; !isInvalidIndex(graphNodeIndex); graphNodeIndex = graphNodeIndexLinks[graphNodeIndex])
{
- updateVisibleChunksFromSupportChunk<Actor>(actors, visibleChunkIndexLinks, chunkActorIndices, thisActorIndex, graphChunkIndices[graphNodeIndex], chunks, upperSupportChunkCount);
+ const uint32_t supportChunkIndex = graphChunkIndices[graphNodeIndex];
+ if (!isInvalidIndex(supportChunkIndex)) // Invalid if this is the world chunk
+ {
+ updateVisibleChunksFromSupportChunk<Actor>(actors, visibleChunkIndexLinks, chunkActorIndices, thisActorIndex, graphChunkIndices[graphNodeIndex], chunks, upperSupportChunkCount);
+ }
}
}
@@ -983,9 +646,9 @@ extern "C"
NvBlastActor* NvBlastFamilyCreateFirstActor(NvBlastFamily* family, const NvBlastActorDesc* desc, void* scratch, NvBlastLog logFn)
{
- NVBLAST_CHECK(family != nullptr, logFn, "NvBlastFamilyCreateFirstActor: NULL family input.", return nullptr);
- NVBLAST_CHECK(desc != nullptr, logFn, "NvBlastFamilyCreateFirstActor: NULL desc input.", return nullptr);
- NVBLAST_CHECK(scratch != nullptr, logFn, "NvBlastFamilyCreateFirstActor: NULL scratch input.", return nullptr);
+ NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilyCreateFirstActor: NULL family input.", return nullptr);
+ NVBLASTLL_CHECK(desc != nullptr, logFn, "NvBlastFamilyCreateFirstActor: NULL desc input.", return nullptr);
+ NVBLASTLL_CHECK(scratch != nullptr, logFn, "NvBlastFamilyCreateFirstActor: NULL scratch input.", return nullptr);
return Nv::Blast::Actor::create(family, desc, scratch, logFn);
}
@@ -993,8 +656,8 @@ NvBlastActor* NvBlastFamilyCreateFirstActor(NvBlastFamily* family, const NvBlast
size_t NvBlastFamilyGetRequiredScratchForCreateFirstActor(const NvBlastFamily* family, NvBlastLog logFn)
{
- NVBLAST_CHECK(family != nullptr, logFn, "NvBlastFamilyGetRequiredScratchForCreateFirstActor: NULL family input.", return 0);
- NVBLAST_CHECK(reinterpret_cast<const Nv::Blast::FamilyHeader*>(family)->m_asset != nullptr,
+ NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilyGetRequiredScratchForCreateFirstActor: NULL family input.", return 0);
+ NVBLASTLL_CHECK(reinterpret_cast<const Nv::Blast::FamilyHeader*>(family)->m_asset != nullptr,
logFn, "NvBlastFamilyGetRequiredScratchForCreateFirstActor: family has NULL asset.", return 0);
return Nv::Blast::Actor::createRequiredScratch(family);
@@ -1003,13 +666,13 @@ size_t NvBlastFamilyGetRequiredScratchForCreateFirstActor(const NvBlastFamily* f
bool NvBlastActorDeactivate(NvBlastActor* actor, NvBlastLog logFn)
{
- NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorDeactivate: NULL actor input.", return false);
+ NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorDeactivate: NULL actor input.", return false);
Nv::Blast::Actor& a = *static_cast<Nv::Blast::Actor*>(actor);
if (!a.isActive())
{
- NVBLAST_LOG_WARNING(logFn, "NvBlastActorDeactivate: inactive actor input.");
+ NVBLASTLL_LOG_WARNING(logFn, "NvBlastActorDeactivate: inactive actor input.");
}
return a.release();
@@ -1018,13 +681,13 @@ bool NvBlastActorDeactivate(NvBlastActor* actor, NvBlastLog logFn)
uint32_t NvBlastActorGetVisibleChunkCount(const NvBlastActor* actor, NvBlastLog logFn)
{
- NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorGetVisibleChunkCount: NULL actor input.", return 0);
+ NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorGetVisibleChunkCount: NULL actor input.", return 0);
const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor);
if (!a.isActive())
{
- NVBLAST_LOG_ERROR(logFn, "NvBlastActorGetVisibleChunkCount: inactive actor input.");
+ NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGetVisibleChunkCount: inactive actor input.");
return 0;
}
@@ -1034,14 +697,14 @@ uint32_t NvBlastActorGetVisibleChunkCount(const NvBlastActor* actor, NvBlastLog
uint32_t NvBlastActorGetVisibleChunkIndices(uint32_t* visibleChunkIndices, uint32_t visibleChunkIndicesSize, const NvBlastActor* actor, NvBlastLog logFn)
{
- NVBLAST_CHECK(visibleChunkIndices != nullptr, logFn, "NvBlastActorGetVisibleChunkIndices: NULL visibleChunkIndices pointer input.", return 0);
- NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorGetVisibleChunkIndices: NULL actor pointer input.", return 0);
+ NVBLASTLL_CHECK(visibleChunkIndices != nullptr, logFn, "NvBlastActorGetVisibleChunkIndices: NULL visibleChunkIndices pointer input.", return 0);
+ NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorGetVisibleChunkIndices: NULL actor pointer input.", return 0);
const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor);
if (!a.isActive())
{
- NVBLAST_LOG_ERROR(logFn, "NvBlastActorGetVisibleChunkIndices: inactive actor pointer input.");
+ NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGetVisibleChunkIndices: inactive actor pointer input.");
return 0;
}
@@ -1058,13 +721,13 @@ uint32_t NvBlastActorGetVisibleChunkIndices(uint32_t* visibleChunkIndices, uint3
uint32_t NvBlastActorGetGraphNodeCount(const NvBlastActor* actor, NvBlastLog logFn)
{
- NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorGetGraphNodeCount: NULL actor pointer input.", return 0);
+ NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorGetGraphNodeCount: NULL actor pointer input.", return 0);
const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor);
if (!a.isActive())
{
- NVBLAST_LOG_ERROR(logFn, "NvBlastActorGetGraphNodeCount: inactive actor pointer input.");
+ NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGetGraphNodeCount: inactive actor pointer input.");
return 0;
}
@@ -1074,22 +737,27 @@ uint32_t NvBlastActorGetGraphNodeCount(const NvBlastActor* actor, NvBlastLog log
uint32_t NvBlastActorGetGraphNodeIndices(uint32_t* graphNodeIndices, uint32_t graphNodeIndicesSize, const NvBlastActor* actor, NvBlastLog logFn)
{
- NVBLAST_CHECK(graphNodeIndices != nullptr, logFn, "NvBlastActorGetGraphNodeIndices: NULL graphNodeIndices pointer input.", return 0);
- NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorGetGraphNodeIndices: NULL actor pointer input.", return 0);
+ NVBLASTLL_CHECK(graphNodeIndices != nullptr, logFn, "NvBlastActorGetGraphNodeIndices: NULL graphNodeIndices pointer input.", return 0);
+ NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorGetGraphNodeIndices: NULL actor pointer input.", return 0);
const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor);
if (!a.isActive())
{
- NVBLAST_LOG_ERROR(logFn, "NvBlastActorGetGraphNodeIndices: inactive actor pointer input.");
+ NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGetGraphNodeIndices: inactive actor pointer input.");
return 0;
}
// Iterate through graph node list and write to supplied array
+ const uint32_t* graphChunkIndices = a.getAsset()->m_graph.getChunkIndices();
uint32_t indexCount = 0;
for (Nv::Blast::Actor::GraphNodeIt i = a; indexCount < graphNodeIndicesSize && (bool)i; ++i)
{
- graphNodeIndices[indexCount++] = (uint32_t)i;
+ const uint32_t graphNodeIndex = (uint32_t)i;
+ if (!Nv::Blast::isInvalidIndex(graphChunkIndices[graphNodeIndex]))
+ {
+ graphNodeIndices[indexCount++] = graphNodeIndex;
+ }
}
return indexCount;
@@ -1098,13 +766,13 @@ uint32_t NvBlastActorGetGraphNodeIndices(uint32_t* graphNodeIndices, uint32_t gr
const float* NvBlastActorGetBondHealths(const NvBlastActor* actor, NvBlastLog logFn)
{
- NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorGetBondHealths: NULL actor pointer input.", return nullptr);
+ NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorGetBondHealths: NULL actor pointer input.", return nullptr);
const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor);
if (!a.isActive())
{
- NVBLAST_LOG_ERROR(logFn, "NvBlastActorGetBondHealths: inactive actor pointer input.");
+ NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGetBondHealths: inactive actor pointer input.");
return nullptr;
}
@@ -1114,13 +782,13 @@ const float* NvBlastActorGetBondHealths(const NvBlastActor* actor, NvBlastLog lo
NvBlastFamily* NvBlastActorGetFamily(const NvBlastActor* actor, NvBlastLog logFn)
{
- NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorGetFamily: NULL actor pointer input.", return nullptr);
+ NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorGetFamily: NULL actor pointer input.", return nullptr);
const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor);
if (!a.isActive())
{
- NVBLAST_LOG_ERROR(logFn, "NvBlastActorGetFamily: inactive actor pointer input.");
+ NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGetFamily: inactive actor pointer input.");
return nullptr;
}
@@ -1130,13 +798,13 @@ NvBlastFamily* NvBlastActorGetFamily(const NvBlastActor* actor, NvBlastLog logFn
uint32_t NvBlastActorGetIndex(const NvBlastActor* actor, NvBlastLog logFn)
{
- NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorGetIndex: NULL actor pointer input.", return Nv::Blast::invalidIndex<uint32_t>());
+ NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorGetIndex: NULL actor pointer input.", return Nv::Blast::invalidIndex<uint32_t>());
const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor);
if (!a.isActive())
{
- NVBLAST_LOG_ERROR(logFn, "NvBlastActorGetIndex: actor is not active.");
+ NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGetIndex: actor is not active.");
return Nv::Blast::invalidIndex<uint32_t>();
}
@@ -1154,14 +822,14 @@ void NvBlastActorGenerateFracture
NvBlastTimers* timers
)
{
- NVBLAST_CHECK(commandBuffers != nullptr, logFn, "NvBlastActorGenerateFracture: NULL commandBuffers pointer input.", return);
- NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorGenerateFracture: NULL actor pointer input.", return);
+ NVBLASTLL_CHECK(commandBuffers != nullptr, logFn, "NvBlastActorGenerateFracture: NULL commandBuffers pointer input.", return);
+ NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorGenerateFracture: NULL actor pointer input.", return);
const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor);
if (!a.isActive())
{
- NVBLAST_LOG_ERROR(logFn, "NvBlastActorGenerateFracture: actor is not active.");
+ NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGenerateFracture: actor is not active.");
commandBuffers->bondFractureCount = 0;
commandBuffers->chunkFractureCount = 0;
return;
@@ -1180,15 +848,15 @@ void NvBlastActorApplyFracture
NvBlastTimers* timers
)
{
- NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorApplyFracture: NULL actor pointer input.", return);
- NVBLAST_CHECK(commands != nullptr, logFn, "NvBlastActorApplyFracture: NULL commands pointer input.", return);
- NVBLAST_CHECK(Nv::Blast::isValid(commands), logFn, "NvBlastActorApplyFracture: commands memory is NULL but size is > 0.", return);
+ NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorApplyFracture: NULL actor pointer input.", return);
+ NVBLASTLL_CHECK(commands != nullptr, logFn, "NvBlastActorApplyFracture: NULL commands pointer input.", return);
+ NVBLASTLL_CHECK(Nv::Blast::isValid(commands), logFn, "NvBlastActorApplyFracture: commands memory is NULL but size is > 0.", return);
Nv::Blast::Actor& a = *static_cast<Nv::Blast::Actor*>(actor);
if (!a.isActive())
{
- NVBLAST_LOG_ERROR(logFn, "NvBlastActorApplyFracture: actor is not active.");
+ NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorApplyFracture: actor is not active.");
if (eventBuffers != nullptr)
{
eventBuffers->bondFractureCount = 0;
@@ -1197,19 +865,19 @@ void NvBlastActorApplyFracture
return;
}
- a.applyFracture(eventBuffers, commands, logFn, timers);
+ a.getFamilyHeader()->applyFracture(eventBuffers, commands, &a, logFn, timers);
}
size_t NvBlastActorGetRequiredScratchForSplit(const NvBlastActor* actor, NvBlastLog logFn)
{
- NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorGetRequiredScratchForSplit: NULL actor input.", return 0);
+ NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorGetRequiredScratchForSplit: NULL actor input.", return 0);
const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor);
if (!a.isActive())
{
- NVBLAST_LOG_ERROR(logFn, "NvBlastActorGetRequiredScratchForSplit: actor is not active.");
+ NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGetRequiredScratchForSplit: actor is not active.");
return 0;
}
@@ -1219,13 +887,13 @@ size_t NvBlastActorGetRequiredScratchForSplit(const NvBlastActor* actor, NvBlast
uint32_t NvBlastActorGetMaxActorCountForSplit(const NvBlastActor* actor, NvBlastLog logFn)
{
- NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorGetMaxActorCountForSplit: NULL actor input.", return 0);
+ NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorGetMaxActorCountForSplit: NULL actor input.", return 0);
const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor);
if (!a.isActive())
{
- NVBLAST_LOG_ERROR(logFn, "NvBlastActorGetMaxActorCountForSplit: actor is not active.");
+ NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGetMaxActorCountForSplit: actor is not active.");
return 0;
}
@@ -1243,16 +911,16 @@ uint32_t NvBlastActorSplit
NvBlastTimers* timers
)
{
- NVBLAST_CHECK(result != nullptr, logFn, "NvBlastActorSplit: NULL result pointer input.", return 0);
- NVBLAST_CHECK(newActorsMaxCount > 0 && result->newActors != nullptr, logFn, "NvBlastActorSplit: no space for results provided.", return 0);
- NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorSplit: NULL actor pointer input.", return 0);
- NVBLAST_CHECK(scratch != nullptr, logFn, "NvBlastActorSplit: NULL scratch pointer input.", return 0);
+ NVBLASTLL_CHECK(result != nullptr, logFn, "NvBlastActorSplit: NULL result pointer input.", return 0);
+ NVBLASTLL_CHECK(newActorsMaxCount > 0 && result->newActors != nullptr, logFn, "NvBlastActorSplit: no space for results provided.", return 0);
+ NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorSplit: NULL actor pointer input.", return 0);
+ NVBLASTLL_CHECK(scratch != nullptr, logFn, "NvBlastActorSplit: NULL scratch pointer input.", return 0);
Nv::Blast::Actor& a = *static_cast<Nv::Blast::Actor*>(actor);
if (!a.isActive())
{
- NVBLAST_LOG_ERROR(logFn, "NvBlastActorGetIndex: actor is not active.");
+ NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGetIndex: actor is not active.");
return 0;
}
@@ -1262,13 +930,13 @@ uint32_t NvBlastActorSplit
bool NvBlastActorCanFracture(const NvBlastActor* actor, NvBlastLog logFn)
{
- NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorCanFracture: NULL actor input.", return false);
+ NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorCanFracture: NULL actor input.", return false);
const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor);
if (!a.isActive())
{
- NVBLAST_LOG_ERROR(logFn, "NvBlastActorCanFracture: actor is not active.");
+ NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorCanFracture: actor is not active.");
return false;
}
@@ -1287,30 +955,25 @@ bool NvBlastActorCanFracture(const NvBlastActor* actor, NvBlastLog logFn)
}
-} // extern "C"
+bool NvBlastActorIsBoundToWorld(const NvBlastActor* actor, NvBlastLog logFn)
+{
+ NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorIsBoundToWorld: NULL actor input.", return false);
+ return static_cast<const Nv::Blast::Actor*>(actor)->isBoundToWorld();
+}
-// deprecated API, still used in tests
-uint32_t NvBlastActorClosestChunk(const float point[4], const NvBlastActor* actor, NvBlastLog logFn)
+
+bool NvBlastActorIsSplitRequired(const NvBlastActor* actor, NvBlastLog logFn)
{
- const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor);
+ NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorIsSplitRequired: NULL actor input.", return false);
- if (a.isSubSupportChunk())
+ const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor);
+ if (!a.isActive())
{
- NVBLAST_LOG_WARNING(logFn, "NvBlastActorClosestChunk: not a graph actor.");
- return Nv::Blast::invalidIndex<uint32_t>();
+ NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorIsSplitRequired: actor is not active.");
+ return false;
}
-
- uint32_t closestNode = Nv::Blast::findNodeByPositionLinked(
- point,
- a.getFirstGraphNodeIndex(),
- a.getFamilyHeader()->getGraphNodeIndexLinks(),
- a.getAsset()->m_graph.getAdjacencyPartition(),
- a.getAsset()->m_graph.getAdjacentNodeIndices(),
- a.getAsset()->m_graph.getAdjacentBondIndices(),
- a.getAsset()->getBonds(),
- a.getFamilyHeader()->getBondHealths()
- );
-
- return a.getAsset()->m_graph.getChunkIndices()[closestNode];
+ return a.isSplitRequired();
}
+
+} // extern "C"
diff --git a/sdk/lowlevel/source/NvBlastActor.h b/sdk/lowlevel/source/NvBlastActor.h
index 42879e7..7e30660 100644
--- a/sdk/lowlevel/source/NvBlastActor.h
+++ b/sdk/lowlevel/source/NvBlastActor.h
@@ -1,12 +1,30 @@
-/*
-* 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.
+
#ifndef NVBLASTACTOR_H
#define NVBLASTACTOR_H
@@ -16,6 +34,8 @@
#include "NvBlastDLink.h"
#include "NvBlastIteratorBase.h"
#include "NvBlastSupportGraph.h"
+#include "NvBlastFamilyGraph.h"
+#include "NvBlastPreprocessorInternal.h"
#include <cstring>
@@ -309,6 +329,11 @@ public:
//////// Damage and fracturing methods ////////
/**
+ See NvBlastActorGenerateFracture
+ */
+ void generateFracture(NvBlastFractureBuffers* commandBuffers, const NvBlastDamageProgram& program, const NvBlastProgramParams* programParams, NvBlastLog logFn, NvBlastTimers* timers) const;
+
+ /**
Damage bond between two chunks by health amount (instance graph also will be notified in case bond is broken after).
*/
uint32_t damageBond(uint32_t nodeIndex0, uint32_t nodeIndex1, float healthDamage);
@@ -324,73 +349,6 @@ public:
uint32_t damageBond(const NvBlastBondFractureData& cmd);
/**
- See NvBlastActorGenerateFracture
- */
- void generateFracture(NvBlastFractureBuffers* commandBuffers, const NvBlastDamageProgram& program, const NvBlastProgramParams* programParams, NvBlastLog logFn, NvBlastTimers* timers) const;
-
- /**
- Hierarchically distribute damage to child chunks.
-
- \param chunkIndex asset chunk index to hierarchically damage
- \param suboffset index of the first sub-support health
- \param healthDamage damage strength to apply
- \param chunkHealths instance chunk healths
- \param chunks asset chunk collection
- */
- void fractureSubSupportNoEvents(uint32_t chunkIndex, uint32_t suboffset, float healthDamage, float* chunkHealths, const NvBlastChunk* chunks);
-
- /**
- Hierarchically distribute damage to child chunks, recording a fracture event for each health damage applied.
-
- If outBuffer is too small, events are dropped but the chunks are still damaged.
-
- \param chunkIndex asset chunk index to hierarchically damage
- \param suboffset index of the first sub-support health
- \param healthDamage damage strength to apply
- \param chunkHealths instance chunk healths
- \param chunks asset chunk collection
- \param outBuffer target buffer for fracture events
- \param currentIndex current position in outBuffer - returns the number of damaged chunks
- \param maxCount capacity of outBuffer
- */
- void fractureSubSupport(uint32_t chunkIndex, uint32_t suboffset, float healthDamage, float* chunkHealths, const NvBlastChunk* chunks, NvBlastChunkFractureData* outBuffer, uint32_t* currentIndex, const uint32_t maxCount);
-
- /**
- Apply chunk fracture commands hierarchically.
-
- \param chunkFractureCount number of chunk fracture commands to apply
- \param chunkFractures array of chunk fracture commands
- */
- void fractureNoEvents(uint32_t chunkFractureCount, const NvBlastChunkFractureData* chunkFractures);
-
- /**
- Apply chunk fracture commands hierarchically, recording a fracture event for each health damage applied.
-
- If events array is too small, events are dropped but the chunks are still damaged.
-
- \param chunkFractureCount number of chunk fracture commands to apply
- \param commands array of chunk fracture commands
- \param events target buffer for fracture events
- \param eventsSize number of available entries in 'events'
- \param count returns the number of damaged chunks
- */
- void fractureWithEvents(uint32_t chunkFractureCount, const NvBlastChunkFractureData* commands, NvBlastChunkFractureData* events, uint32_t eventsSize, uint32_t* count);
-
- /**
- Apply chunk fracture commands hierarchically, recording a fracture event for each health damage applied.
-
- In-Place version: fracture commands are replaced by fracture events.
-
- If inoutbuffer array is too small, events are dropped but the chunks are still damaged.
-
- \param chunkFractureCount number of chunk fracture commands to apply
- \param inoutbuffer array of chunk fracture commands to be replaced by events
- \param eventsSize number of available entries in inoutbuffer
- \param count returns the number of damaged chunks
- */
- void fractureInPlaceEvents(uint32_t chunkFractureCount, NvBlastChunkFractureData* inoutbuffer, uint32_t eventsSize, uint32_t* count);
-
- /**
See NvBlastActorApplyFracture
*/
void applyFracture(NvBlastFractureBuffers* eventBuffers, const NvBlastFractureBuffers* commands, NvBlastLog logFn, NvBlastTimers* timers);
@@ -473,6 +431,16 @@ public:
*/
uint32_t partitionMultipleGraphNodes(Actor** newActors, uint32_t newActorsSize, NvBlastLog logFn);
+ /**
+ \return true iff this actor contains the "world" support graph node, created when a bond contains the invalidIndex<uint32_t>() value for one of their chunkIndices.
+ */
+ bool isBoundToWorld() const;
+
+ /**
+ \return true iff this actor was damaged and split() call is required.
+ */
+ bool isSplitRequired() const;
+
private:
//////// Data ////////
@@ -695,7 +663,7 @@ NV_INLINE bool Actor::release()
NV_INLINE uint32_t Actor::partition(Actor** newActors, uint32_t newActorsSize, NvBlastLog logFn)
{
- NVBLAST_CHECK(newActorsSize == 0 || newActors != nullptr, logFn, "Nv::Blast::Actor::partition: NULL newActors pointer array input with non-zero newActorCount.", return 0);
+ NVBLASTLL_CHECK(newActorsSize == 0 || newActors != nullptr, logFn, "Nv::Blast::Actor::partition: NULL newActors pointer array input with non-zero newActorCount.", return 0);
// Call one of two partition functions depending on the actor's support status
return m_graphNodeCount <= 1 ?
@@ -704,6 +672,58 @@ NV_INLINE uint32_t Actor::partition(Actor** newActors, uint32_t newActorsSize, N
}
+NV_INLINE bool Actor::isBoundToWorld() const
+{
+ const SupportGraph& graph = *getGraph();
+
+ if (graph.m_nodeCount == 0)
+ {
+ return false; // This shouldn't happen
+ }
+
+ const uint32_t lastGraphChunkIndex = graph.getChunkIndices()[graph.m_nodeCount - 1];
+
+ if (!isInvalidIndex(lastGraphChunkIndex))
+ {
+ return false; // There is no world node
+ }
+
+ return getFamilyGraph()->getIslandIds()[graph.m_nodeCount - 1] == getIndex();
+}
+
+
+NV_INLINE bool Actor::isSplitRequired() const
+{
+ NVBLAST_ASSERT(isActive());
+
+ if (getGraphNodeCount() <= 1)
+ {
+ uint32_t chunkHealthIndex = isSingleSupportChunk() ? getIndex() : getFirstVisibleChunkIndex() - getFirstSubsupportChunkIndex() + getGraph()->m_nodeCount;
+ float* chunkHealths = getLowerSupportChunkHealths();
+ if (chunkHealths[chunkHealthIndex] <= 0.0f)
+ {
+ const uint32_t chunkIndex = m_graphNodeCount == 0 ? m_firstVisibleChunkIndex : getGraph()->getChunkIndices()[m_firstGraphNodeIndex];
+ if (!isInvalidIndex(chunkIndex))
+ {
+ const NvBlastChunk& chunk = getChunks()[chunkIndex];
+ uint32_t childCount = chunk.childIndexStop - chunk.firstChildIndex;
+ return childCount > 0;
+ }
+ }
+ }
+ else
+ {
+ uint32_t* firstDirtyNodeIndices = getFamilyGraph()->getFirstDirtyNodeIndices();
+ if (!isInvalidIndex(firstDirtyNodeIndices[getIndex()]))
+ {
+ return true;
+ }
+
+ }
+ return false;
+}
+
+
//////// Actor::VisibleChunkIt inline methods ////////
NV_INLINE Actor::VisibleChunkIt::VisibleChunkIt(const Actor& actor) : DListIt<uint32_t>(actor.m_firstVisibleChunkIndex, actor.getFamilyHeader()->getVisibleChunkIndexLinks())
@@ -717,16 +737,28 @@ NV_INLINE Actor::GraphNodeIt::GraphNodeIt(const Actor& actor) : LListIt<uint32_t
{
}
-} // namespace Blast
-} // namespace Nv
+//////// Helper functions ////////
+#if NVBLASTLL_CHECK_PARAMS
/**
-Returns the closest chunk asset index for a supported actor.
-Helper functions still used in tests.
-Has become obsolete with introduction of chunkMap and its inverse.
+Helper function to validate fracture buffer values being meaningful.
*/
-uint32_t NvBlastActorClosestChunk(const float point[4], const NvBlastActor* actor, NvBlastLog logFn);
+static inline bool isValid(const NvBlastFractureBuffers* buffers)
+{
+ if (buffers->chunkFractureCount != 0 && buffers->chunkFractures == nullptr)
+ return false;
+
+ if (buffers->bondFractureCount != 0 && buffers->bondFractures == nullptr)
+ return false;
+
+ return true;
+}
+#endif
+
+
+} // namespace Blast
+} // namespace Nv
#endif // ifndef NVBLASTACTOR_H
diff --git a/sdk/lowlevel/source/NvBlastActorSerializationBlock.cpp b/sdk/lowlevel/source/NvBlastActorSerializationBlock.cpp
index e496a69..ca830a7 100644
--- a/sdk/lowlevel/source/NvBlastActorSerializationBlock.cpp
+++ b/sdk/lowlevel/source/NvBlastActorSerializationBlock.cpp
@@ -1,12 +1,29 @@
-/*
-* 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 "NvBlastActor.h"
@@ -25,18 +42,18 @@ namespace Blast
Actor* Actor::deserialize(NvBlastFamily* family, const void* buffer, NvBlastLog logFn)
{
- NVBLAST_CHECK(family != nullptr, logFn, "Actor::deserialize: NULL family pointer input.", return nullptr);
+ NVBLASTLL_CHECK(family != nullptr, logFn, "Actor::deserialize: NULL family pointer input.", return nullptr);
const ActorSerializationHeader* serHeader = reinterpret_cast<const ActorSerializationHeader*>(buffer);
if (serHeader->m_formatVersion != ActorSerializationFormat::Current)
{
- NVBLAST_LOG_ERROR(logFn, "Actor::deserialize: wrong data format. Serialization data must be converted to current version.");
+ NVBLASTLL_LOG_ERROR(logFn, "Actor::deserialize: wrong data format. Serialization data must be converted to current version.");
return nullptr;
}
FamilyHeader* header = reinterpret_cast<FamilyHeader*>(family);
const Asset* asset = header->m_asset;
- const Nv::Blast::SupportGraph& graph = asset->m_graph;
+ const SupportGraph& graph = asset->m_graph;
const uint32_t* graphChunkIndices = graph.getChunkIndices();
const uint32_t* graphAdjacencyPartition = graph.getAdjacencyPartition();
const uint32_t* graphAdjacentNodeIndices = graph.getAdjacentNodeIndices();
@@ -55,7 +72,7 @@ Actor* Actor::deserialize(NvBlastFamily* family, const void* buffer, NvBlastLog
if (actor == nullptr)
{
- NVBLAST_LOG_ERROR(logFn, "Actor::deserialize: invalid actor index in serialized data. Actor not created.");
+ NVBLASTLL_LOG_ERROR(logFn, "Actor::deserialize: invalid actor index in serialized data. Actor not created.");
return nullptr;
}
@@ -63,7 +80,7 @@ Actor* Actor::deserialize(NvBlastFamily* family, const void* buffer, NvBlastLog
uint32_t* chunkActorIndices = header->getChunkActorIndices();
FamilyGraph* familyGraph = header->getFamilyGraph();
-#if NVBLAST_CHECK_PARAMS
+#if NVBLASTLL_CHECK_PARAMS
{
const uint32_t* serVisibleChunkIndices = serHeader->getVisibleChunkIndices();
for (uint32_t i = 0; i < serHeader->m_visibleChunkCount; ++i)
@@ -71,7 +88,7 @@ Actor* Actor::deserialize(NvBlastFamily* family, const void* buffer, NvBlastLog
const uint32_t visibleChunkIndex = serVisibleChunkIndices[i];
if (!isInvalidIndex(chunkActorIndices[visibleChunkIndex]))
{
- NVBLAST_LOG_ERROR(logFn, "Actor::deserialize: visible chunk already has an actor in family. Actor not created.");
+ NVBLASTLL_LOG_ERROR(logFn, "Actor::deserialize: visible chunk already has an actor in family. Actor not created.");
header->returnActor(*actor);
return nullptr;
}
@@ -125,7 +142,7 @@ Actor* Actor::deserialize(NvBlastFamily* family, const void* buffer, NvBlastLog
{
uint32_t serLowerSupportChunkCount = 0;
float* graphNodeHealths = header->getLowerSupportChunkHealths();
- for (Nv::Blast::Actor::GraphNodeIt i = *actor; (bool)i; ++i)
+ for (Actor::GraphNodeIt i = *actor; (bool)i; ++i)
{
const uint32_t graphNodeIndex = (uint32_t)i;
graphNodeHealths[graphNodeIndex] = serLowerSupportChunkHealths[serLowerSupportChunkCount++];
@@ -152,7 +169,7 @@ Actor* Actor::deserialize(NvBlastFamily* family, const void* buffer, NvBlastLog
{
const float* serBondHealths = serHeader->getBondHealths();
float* bondHealths = header->getBondHealths();
- for (Nv::Blast::Actor::GraphNodeIt i = *actor; (bool)i; ++i)
+ for (Actor::GraphNodeIt i = *actor; (bool)i; ++i)
{
const uint32_t graphNodeIndex = (uint32_t)i;
for (uint32_t adjacentIndex = graphAdjacencyPartition[graphNodeIndex]; adjacentIndex < graphAdjacencyPartition[graphNodeIndex + 1]; ++adjacentIndex)
@@ -176,7 +193,7 @@ Actor* Actor::deserialize(NvBlastFamily* family, const void* buffer, NvBlastLog
{
const uint32_t* serFastRoute = serHeader->getFastRoute();
uint32_t* fastRoute = header->getFamilyGraph()->getFastRoute();
- for (Nv::Blast::Actor::GraphNodeIt i = *actor; (bool)i; ++i)
+ for (Actor::GraphNodeIt i = *actor; (bool)i; ++i)
{
fastRoute[(uint32_t)i] = *serFastRoute++;
}
@@ -186,7 +203,7 @@ Actor* Actor::deserialize(NvBlastFamily* family, const void* buffer, NvBlastLog
{
const uint32_t* serHopCounts = serHeader->getHopCounts();
uint32_t* hopCounts = header->getFamilyGraph()->getHopCounts();
- for (Nv::Blast::Actor::GraphNodeIt i = *actor; (bool)i; ++i)
+ for (Actor::GraphNodeIt i = *actor; (bool)i; ++i)
{
hopCounts[(uint32_t)i] = *serHopCounts++;
}
@@ -198,7 +215,7 @@ Actor* Actor::deserialize(NvBlastFamily* family, const void* buffer, NvBlastLog
uint32_t serBondIndex = 0;
const FixedBoolArray* serEdgeRemovedArray = serHeader->getEdgeRemovedArray();
FixedBoolArray* edgeRemovedArray = familyGraph->getIsEdgeRemoved();
- for (Nv::Blast::Actor::GraphNodeIt i = *actor; (bool)i; ++i)
+ for (Actor::GraphNodeIt i = *actor; (bool)i; ++i)
{
const uint32_t graphNodeIndex = (uint32_t)i;
for (uint32_t adjacentIndex = graphAdjacencyPartition[graphNodeIndex]; adjacentIndex < graphAdjacencyPartition[graphNodeIndex + 1]; ++adjacentIndex)
@@ -232,7 +249,7 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c
{
// Set up pointers and such
const Asset* asset = getAsset();
- const Nv::Blast::SupportGraph& graph = asset->m_graph;
+ const SupportGraph& graph = asset->m_graph;
const uint32_t* graphChunkIndices = graph.getChunkIndices();
const uint32_t* graphAdjacencyPartition = graph.getAdjacencyPartition();
const uint32_t* graphAdjacentNodeIndices = graph.getAdjacentNodeIndices();
@@ -247,7 +264,7 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c
const uint32_t* firstDirtyNodeIndices = header->getFamilyGraph()->getFirstDirtyNodeIndices();
if (!isInvalidIndex(firstDirtyNodeIndices[thisActorIndex]))
{
- NVBLAST_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: instance graph has dirty nodes. Call Nv::Blast::Actor::findIslands before serializing.");
+ NVBLASTLL_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: instance graph has dirty nodes. Call Nv::Blast::Actor::findIslands before serializing.");
return 0;
}
}
@@ -274,12 +291,12 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c
offset = align16(offset + m_visibleChunkCount*sizeof(uint32_t));
if (offset > bufferSize)
{
- NVBLAST_LOG_ERROR(logFn, "Nv::Blast::Actor::Actor::serialize: buffer size exceeded.");
+ NVBLASTLL_LOG_ERROR(logFn, "Nv::Blast::Actor::Actor::serialize: buffer size exceeded.");
return 0; // Buffer size insufficient
}
uint32_t* serVisibleChunkIndices = serHeader->getVisibleChunkIndices();
uint32_t serVisibleChunkCount = 0;
- for (Nv::Blast::Actor::VisibleChunkIt i = *this; (bool)i; ++i)
+ for (Actor::VisibleChunkIt i = *this; (bool)i; ++i)
{
NVBLAST_ASSERT(serVisibleChunkCount < m_visibleChunkCount);
serVisibleChunkIndices[serVisibleChunkCount++] = (uint32_t)i;
@@ -293,12 +310,12 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c
offset = align16(offset + m_graphNodeCount*sizeof(uint32_t));
if (offset > bufferSize)
{
- NVBLAST_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded.");
+ NVBLASTLL_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded.");
return 0; // Buffer size insufficient
}
uint32_t* serGraphNodeIndices = serHeader->getGraphNodeIndices();
uint32_t serGraphNodeCount = 0;
- for (Nv::Blast::Actor::GraphNodeIt i = *this; (bool)i; ++i)
+ for (Actor::GraphNodeIt i = *this; (bool)i; ++i)
{
NVBLAST_ASSERT(serGraphNodeCount < m_graphNodeCount);
serGraphNodeIndices[serGraphNodeCount++] = (uint32_t)i;
@@ -316,7 +333,7 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c
{
uint32_t serLowerSupportChunkCount = 0;
const float* graphNodeHealths = header->getLowerSupportChunkHealths();
- for (Nv::Blast::Actor::GraphNodeIt i = *this; (bool)i; ++i)
+ for (Actor::GraphNodeIt i = *this; (bool)i; ++i)
{
const uint32_t graphNodeIndex = (uint32_t)i;
serLowerSupportChunkHealths[serLowerSupportChunkCount++] = graphNodeHealths[graphNodeIndex];
@@ -329,7 +346,7 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c
{
if (offset >= bufferSize)
{
- NVBLAST_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded.");
+ NVBLASTLL_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded.");
return 0; // Buffer size insufficient
}
serLowerSupportChunkHealths[serLowerSupportChunkCount++] = subsupportHealths[(uint32_t)j - subsupportChunkCount];
@@ -343,7 +360,7 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c
NVBLAST_ASSERT(m_firstVisibleChunkIndex >= subsupportChunkCount);
if (offset >= bufferSize)
{
- NVBLAST_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded.");
+ NVBLASTLL_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded.");
return 0; // Buffer size insufficient
}
*serLowerSupportChunkHealths = subsupportHealths[m_firstVisibleChunkIndex - subsupportChunkCount];
@@ -358,7 +375,7 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c
serHeader->m_bondHealthsOffset = (uint32_t)offset;
float* serBondHealths = serHeader->getBondHealths();
const float* bondHealths = header->getBondHealths();
- for (Nv::Blast::Actor::GraphNodeIt i = *this; (bool)i; ++i)
+ for (Actor::GraphNodeIt i = *this; (bool)i; ++i)
{
const uint32_t graphNodeIndex = (uint32_t)i;
for (uint32_t adjacentIndex = graphAdjacencyPartition[graphNodeIndex]; adjacentIndex < graphAdjacencyPartition[graphNodeIndex + 1]; ++adjacentIndex)
@@ -372,7 +389,7 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c
{
if (offset >= bufferSize)
{
- NVBLAST_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded.");
+ NVBLASTLL_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded.");
return 0; // Buffer size insufficient
}
const uint32_t adjacentBondIndex = graphAdjacentBondIndices[adjacentIndex];
@@ -391,12 +408,12 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c
offset = align16(offset + m_graphNodeCount*sizeof(uint32_t));
if (offset > bufferSize)
{
- NVBLAST_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded.");
+ NVBLASTLL_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded.");
return 0; // Buffer size insufficient
}
uint32_t* serFastRoute = serHeader->getFastRoute();
const uint32_t* fastRoute = header->getFamilyGraph()->getFastRoute();
- for (Nv::Blast::Actor::GraphNodeIt i = *this; (bool)i; ++i)
+ for (Actor::GraphNodeIt i = *this; (bool)i; ++i)
{
*serFastRoute++ = fastRoute[(uint32_t)i];
}
@@ -408,12 +425,12 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c
offset = align16(offset + m_graphNodeCount*sizeof(uint32_t));
if (offset > bufferSize)
{
- NVBLAST_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded.");
+ NVBLASTLL_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded.");
return 0; // Buffer size insufficient
}
uint32_t* serHopCounts = serHeader->getHopCounts();
const uint32_t* hopCounts = header->getFamilyGraph()->getHopCounts();
- for (Nv::Blast::Actor::GraphNodeIt i = *this; (bool)i; ++i)
+ for (Actor::GraphNodeIt i = *this; (bool)i; ++i)
{
*serHopCounts++ = hopCounts[(uint32_t)i];
}
@@ -426,7 +443,7 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c
offset = align16(offset + FixedBoolArray::requiredMemorySize(serBondCount));
if (offset > bufferSize)
{
- NVBLAST_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded.");
+ NVBLASTLL_LOG_ERROR(logFn, "Nv::Blast::Actor::serialize: buffer size exceeded.");
return 0; // Buffer size insufficient
}
uint32_t serBondIndex = 0;
@@ -434,7 +451,7 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c
new (serEdgeRemovedArray)FixedBoolArray(serBondCount);
serEdgeRemovedArray->fill(); // Reset bits as we find bonds
const FixedBoolArray* edgeRemovedArray = header->getFamilyGraph()->getIsEdgeRemoved();
- for (Nv::Blast::Actor::GraphNodeIt i = *this; (bool)i; ++i)
+ for (Actor::GraphNodeIt i = *this; (bool)i; ++i)
{
const uint32_t graphNodeIndex = (uint32_t)i;
for (uint32_t adjacentIndex = graphAdjacencyPartition[graphNodeIndex]; adjacentIndex < graphAdjacencyPartition[graphNodeIndex + 1]; ++adjacentIndex)
@@ -468,7 +485,7 @@ uint32_t Actor::serialize(void* buffer, uint32_t bufferSize, NvBlastLog logFn) c
uint32_t Actor::serializationRequiredStorage(NvBlastLog logFn) const
{
const Asset* asset = getAsset();
- const Nv::Blast::SupportGraph& graph = asset->m_graph;
+ const SupportGraph& graph = asset->m_graph;
const uint32_t* graphChunkIndices = graph.getChunkIndices();
const uint32_t* graphAdjacencyPartition = graph.getAdjacencyPartition();
const uint32_t* graphAdjacentNodeIndices = graph.getAdjacentNodeIndices();
@@ -515,7 +532,7 @@ uint32_t Actor::serializationRequiredStorage(NvBlastLog logFn) const
if (dataSize > UINT32_MAX)
{
- NVBLAST_LOG_WARNING(logFn, "Nv::Blast::Actor::serializationRequiredStorage: Serialization block size exceeds 4GB. Returning 0.\n");
+ NVBLASTLL_LOG_WARNING(logFn, "Nv::Blast::Actor::serializationRequiredStorage: Serialization block size exceeds 4GB. Returning 0.\n");
return 0;
}
@@ -533,13 +550,13 @@ extern "C"
uint32_t NvBlastActorGetSerializationSize(const NvBlastActor* actor, NvBlastLog logFn)
{
- NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorGetSerializationSize: NULL actor pointer input.", return 0);
+ NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorGetSerializationSize: NULL actor pointer input.", return 0);
const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor);
if (!a.isActive())
{
- NVBLAST_LOG_ERROR(logFn, "NvBlastActorGetSerializationSize: inactive actor pointer input.");
+ NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorGetSerializationSize: inactive actor pointer input.");
return 0;
}
@@ -549,14 +566,14 @@ uint32_t NvBlastActorGetSerializationSize(const NvBlastActor* actor, NvBlastLog
uint32_t NvBlastActorSerialize(void* buffer, uint32_t bufferSize, const NvBlastActor* actor, NvBlastLog logFn)
{
- NVBLAST_CHECK(buffer != nullptr, logFn, "NvBlastActorSerialize: NULL buffer pointer input.", return 0);
- NVBLAST_CHECK(actor != nullptr, logFn, "NvBlastActorSerialize: NULL actor pointer input.", return 0);
+ NVBLASTLL_CHECK(buffer != nullptr, logFn, "NvBlastActorSerialize: NULL buffer pointer input.", return 0);
+ NVBLASTLL_CHECK(actor != nullptr, logFn, "NvBlastActorSerialize: NULL actor pointer input.", return 0);
const Nv::Blast::Actor& a = *static_cast<const Nv::Blast::Actor*>(actor);
if (!a.isActive())
{
- NVBLAST_LOG_ERROR(logFn, "NvBlastActorSerialize: inactive actor pointer input.");
+ NVBLASTLL_LOG_ERROR(logFn, "NvBlastActorSerialize: inactive actor pointer input.");
return 0;
}
@@ -566,8 +583,8 @@ uint32_t NvBlastActorSerialize(void* buffer, uint32_t bufferSize, const NvBlastA
NvBlastActor* NvBlastFamilyDeserializeActor(NvBlastFamily* family, const void* buffer, NvBlastLog logFn)
{
- NVBLAST_CHECK(family != nullptr, logFn, "NvBlastFamilyDeserializeActor: NULL family input. No actor deserialized.", return nullptr);
- NVBLAST_CHECK(buffer != nullptr, logFn, "NvBlastFamilyDeserializeActor: NULL buffer pointer input. No actor deserialized.", return nullptr);
+ NVBLASTLL_CHECK(family != nullptr, logFn, "NvBlastFamilyDeserializeActor: NULL family input. No actor deserialized.", return nullptr);
+ NVBLASTLL_CHECK(buffer != nullptr, logFn, "NvBlastFamilyDeserializeActor: NULL buffer pointer input. No actor deserialized.", return nullptr);
return Nv::Blast::Actor::deserialize(family, buffer, logFn);
}
diff --git a/sdk/lowlevel/source/NvBlastActorSerializationBlock.h b/sdk/lowlevel/source/NvBlastActorSerializationBlock.h
index 1388a74..95e9842 100644
--- a/sdk/lowlevel/source/NvBlastActorSerializationBlock.h
+++ b/sdk/lowlevel/source/NvBlastActorSerializationBlock.h
@@ -1,12 +1,30 @@
-/*
-* 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.
+
#ifndef NVBLASTACTORSERIALIZATIONBLOCK_H
#define NVBLASTACTORSERIALIZATIONBLOCK_H
diff --git a/sdk/lowlevel/source/NvBlastAsset.cpp b/sdk/lowlevel/source/NvBlastAsset.cpp
index 29fc6b0..354a3ac 100644
--- a/sdk/lowlevel/source/NvBlastAsset.cpp
+++ b/sdk/lowlevel/source/NvBlastAsset.cpp
@@ -1,12 +1,30 @@
-/*
-* 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 "NvBlastAssert.h"
#include "NvBlastAsset.h"
@@ -36,37 +54,37 @@ static bool solverAssetBuildValidateInput(void* mem, const NvBlastAssetDesc* des
{
if (mem == nullptr)
{
- NVBLAST_LOG_ERROR(logFn, "AssetBuildValidateInput: NULL mem pointer input.");
+ NVBLASTLL_LOG_ERROR(logFn, "AssetBuildValidateInput: NULL mem pointer input.");
return false;
}
if (desc == nullptr)
{
- NVBLAST_LOG_ERROR(logFn, "AssetBuildValidateInput: NULL desc pointer input.");
+ NVBLASTLL_LOG_ERROR(logFn, "AssetBuildValidateInput: NULL desc pointer input.");
return false;
}
if (desc->chunkCount == 0)
{
- NVBLAST_LOG_ERROR(logFn, "AssetBuildValidateInput: Zero chunk count not allowed.");
+ NVBLASTLL_LOG_ERROR(logFn, "AssetBuildValidateInput: Zero chunk count not allowed.");
return false;
}
if (desc->chunkDescs == nullptr)
{
- NVBLAST_LOG_ERROR(logFn, "AssetBuildValidateInput: NULL chunkDescs pointer input.");
+ NVBLASTLL_LOG_ERROR(logFn, "AssetBuildValidateInput: NULL chunkDescs pointer input.");
return false;
}
if (desc->bondCount != 0 && desc->bondDescs == nullptr)
{
- NVBLAST_LOG_ERROR(logFn, "AssetBuildValidateInput: bondCount non-zero but NULL bondDescs pointer input.");
+ NVBLASTLL_LOG_ERROR(logFn, "AssetBuildValidateInput: bondCount non-zero but NULL bondDescs pointer input.");
return false;
}
if (scratch == nullptr)
{
- NVBLAST_LOG_ERROR(logFn, "AssetBuildValidateInput: NULL scratch pointer input.");
+ NVBLASTLL_LOG_ERROR(logFn, "AssetBuildValidateInput: NULL scratch pointer input.");
return false;
}
@@ -111,7 +129,7 @@ Asset* initializeAsset(void* mem, NvBlastID id, uint32_t chunkCount, uint32_t gr
// 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::allocateAsset: Asset data size will exceed 4GB. Instance not created.\n");
+ NVBLASTLL_LOG_ERROR(logFn, "Nv::Blast::allocateAsset: Asset data size will exceed 4GB. Instance not created.\n");
return nullptr;
}
@@ -121,7 +139,7 @@ Asset* initializeAsset(void* mem, NvBlastID id, uint32_t chunkCount, uint32_t gr
// Fill in fields
const size_t graphOffset = NV_OFFSET_OF(Asset, m_graph);
asset->m_header.dataType = NvBlastDataBlock::AssetDataBlock;
- asset->m_header.formatVersion = NvBlastAssetDataFormat::Current;
+ asset->m_header.formatVersion = 0; // Not currently using this field
asset->m_header.size = (uint32_t)dataSize;
asset->m_header.reserved = 0;
asset->m_ID = id;
@@ -223,7 +241,7 @@ static bool testForValidTrees(uint32_t chunkCount, const NvBlastChunkDesc* chunk
// Ensure there are no loops
if (testForLoop(chunkDescs, i))
{
- NVBLAST_LOG_WARNING(logFn, "testForValidTrees: loop found. Asset will not be created.");
+ NVBLASTLL_LOG_WARNING(logFn, "testForValidTrees: loop found. Asset will not be created.");
return false;
}
}
@@ -255,7 +273,7 @@ class BondsOrdered
public:
bool operator () (const BondSortData& bond0, const BondSortData& bond1) const
{
- return (bond0.m_c0 != bond1.m_c0) ? (bond0.m_c0 < bond1.m_c0) : (bond0.m_c1 < bond1.m_c1);
+ return (bond0.m_c0 != bond1.m_c0) ? (bond0.m_c0 < bond1.m_c0) : (bond0.m_c1 != bond1.m_c1 ? bond0.m_c1 < bond1.m_c1 : bond0.m_b < bond1.m_b);
}
};
@@ -273,6 +291,19 @@ size_t Asset::getMemorySize(const NvBlastAssetDesc* desc)
graphNodeCount += (uint32_t)((desc->chunkDescs[i].flags & NvBlastChunkDesc::SupportFlag) != 0);
}
+ for (uint32_t i = 0; i < desc->bondCount; ++i)
+ {
+ const NvBlastBondDesc& bondDesc = desc->bondDescs[i];
+ const uint32_t chunkIndex0 = bondDesc.chunkIndices[0];
+ const uint32_t chunkIndex1 = bondDesc.chunkIndices[1];
+ if ((isInvalidIndex(chunkIndex0) && chunkIndex1 < desc->chunkCount) ||
+ (isInvalidIndex(chunkIndex1) && chunkIndex0 < desc->chunkCount))
+ {
+ ++graphNodeCount; // world node
+ break;
+ }
+ }
+
AssetDataOffsets offsets;
return createAssetDataOffsets(offsets, desc->chunkCount, graphNodeCount, desc->bondCount);
}
@@ -280,7 +311,7 @@ size_t Asset::getMemorySize(const NvBlastAssetDesc* desc)
size_t Asset::createRequiredScratch(const NvBlastAssetDesc* desc)
{
-#if NVBLAST_CHECK_PARAMS
+#if NVBLASTLL_CHECK_PARAMS
if (desc == nullptr)
{
NVBLAST_ALWAYS_ASSERT();
@@ -292,14 +323,14 @@ size_t Asset::createRequiredScratch(const NvBlastAssetDesc* desc)
return 16 +
align16(desc->chunkCount*sizeof(char)) +
align16(desc->chunkCount*sizeof(uint32_t)) +
- align16(2 * desc->bondCount*sizeof(Nv::Blast::BondSortData)) +
+ align16(2 * desc->bondCount*sizeof(BondSortData)) +
align16(desc->bondCount*sizeof(uint32_t));
}
Asset* Asset::create(void* mem, const NvBlastAssetDesc* desc, void* scratch, NvBlastLog logFn)
{
-#if NVBLAST_CHECK_PARAMS
+#if NVBLASTLL_CHECK_PARAMS
if (!solverAssetBuildValidateInput(mem, desc, scratch, logFn))
{
return nullptr;
@@ -308,7 +339,7 @@ Asset* Asset::create(void* mem, const NvBlastAssetDesc* desc, void* scratch, NvB
NV_UNUSED(solverAssetBuildValidateInput);
#endif
- NVBLAST_CHECK((reinterpret_cast<uintptr_t>(mem) & 0xF) == 0, logFn, "NvBlastCreateAsset: mem pointer not 16-byte aligned.", return nullptr);
+ NVBLASTLL_CHECK((reinterpret_cast<uintptr_t>(mem) & 0xF) == 0, logFn, "NvBlastCreateAsset: mem pointer not 16-byte aligned.", return nullptr);
// Make sure we have valid trees before proceeding
if (!testForValidTrees(desc->chunkCount, desc->chunkDescs, logFn))
@@ -319,20 +350,21 @@ Asset* Asset::create(void* mem, const NvBlastAssetDesc* desc, void* scratch, NvB
scratch = (void*)align16((size_t)scratch); // Bump to 16-byte alignment (see padding in NvBlastGetRequiredScratchForCreateAsset)
// reserve chunkAnnotation on scratch
- char* chunkAnnotation = reinterpret_cast<char*>(scratch); scratch = Nv::Blast::pointerOffset(scratch, align16(desc->chunkCount));
+ char* chunkAnnotation = reinterpret_cast<char*>(scratch); scratch = pointerOffset(scratch, align16(desc->chunkCount));
// test for coverage, chunkAnnotation will be filled there.
uint32_t leafChunkCount;
uint32_t supportChunkCount;
if (!ensureExactSupportCoverage(supportChunkCount, leafChunkCount, chunkAnnotation, desc->chunkCount, const_cast<NvBlastChunkDesc*>(desc->chunkDescs), true, logFn))
{
+ NVBLASTLL_LOG_ERROR(logFn, "NvBlastCreateAsset: support coverage is not exact. Asset will not be created. The Asset helper function NvBlastEnsureAssetExactSupportCoverage may be used to create exact coverage.");
return nullptr;
}
// test for valid chunk order
if (!testForValidChunkOrder(desc->chunkCount, desc->chunkDescs, chunkAnnotation, scratch))
{
- NVBLAST_LOG_ERROR(logFn, "NvBlastCreateAsset: chunks order is invalid. Asset will not be created. Use Asset helper functions such as NvBlastBuildAssetDescChunkReorderMap to fix descriptor order.");
+ NVBLASTLL_LOG_ERROR(logFn, "NvBlastCreateAsset: chunks order is invalid. Asset will not be created. Use Asset helper functions such as NvBlastBuildAssetDescChunkReorderMap to fix descriptor order.");
return nullptr;
}
@@ -348,7 +380,7 @@ Asset* Asset::create(void* mem, const NvBlastAssetDesc* desc, void* scratch, NvB
}
// Create map from global indices to graph node indices and initialize to invalid values
- uint32_t* graphNodeIndexMap = (uint32_t*)scratch; scratch = Nv::Blast::pointerOffset(scratch, align16(desc->chunkCount * sizeof(uint32_t)));
+ uint32_t* graphNodeIndexMap = (uint32_t*)scratch; scratch = pointerOffset(scratch, align16(desc->chunkCount * sizeof(uint32_t)));
memset(graphNodeIndexMap, 0xFF, desc->chunkCount*sizeof(uint32_t));
// Fill graphNodeIndexMap
@@ -363,7 +395,7 @@ Asset* Asset::create(void* mem, const NvBlastAssetDesc* desc, void* scratch, NvB
NVBLAST_ASSERT(graphNodeCount == supportChunkCount);
// Scratch array for bond sorting, of size 2*desc->bondCount
- Nv::Blast::BondSortData* bondSortArray = (Nv::Blast::BondSortData*)scratch; scratch = Nv::Blast::pointerOffset(scratch, align16(2 * desc->bondCount*sizeof(Nv::Blast::BondSortData)));
+ BondSortData* bondSortArray = (BondSortData*)scratch; scratch = pointerOffset(scratch, align16(2 * desc->bondCount*sizeof(BondSortData)));
// Bond remapping array of size desc->bondCount
uint32_t* bondMap = (uint32_t*)scratch;
@@ -380,33 +412,56 @@ Asset* Asset::create(void* mem, const NvBlastAssetDesc* desc, void* scratch, NvB
// Construct temp array of chunk index pairs and bond indices. This array is symmetrized to hold the reversed chunk indices as well.
uint32_t bondSortArraySize = 0;
- Nv::Blast::BondSortData* t = bondSortArray;
+ BondSortData* t = bondSortArray;
+ bool addWorldNode = false;
for (uint32_t i = 0; i < desc->bondCount; ++i)
{
const NvBlastBondDesc& bondDesc = desc->bondDescs[i];
const uint32_t chunkIndex0 = bondDesc.chunkIndices[0];
const uint32_t chunkIndex1 = bondDesc.chunkIndices[1];
- if (chunkIndex0 >= desc->chunkCount || chunkIndex1 >= desc->chunkCount || chunkIndex0 == chunkIndex1)
+ if ((chunkIndex0 >= desc->chunkCount && !isInvalidIndex(chunkIndex0)) ||
+ (chunkIndex1 >= desc->chunkCount && !isInvalidIndex(chunkIndex1)) ||
+ chunkIndex0 == chunkIndex1)
{
invalidFound = true;
continue;
}
- const uint32_t graphIndex0 = graphNodeIndexMap[chunkIndex0];
- const uint32_t graphIndex1 = graphNodeIndexMap[chunkIndex1];
- if (Nv::Blast::isInvalidIndex(graphIndex0) || Nv::Blast::isInvalidIndex(graphIndex1))
+ uint32_t graphIndex0;
+ if (!isInvalidIndex(chunkIndex0))
+ {
+ graphIndex0 = graphNodeIndexMap[chunkIndex0];
+ }
+ else
+ {
+ addWorldNode = true;
+ graphIndex0 = graphNodeCount; // Will set graphNodeCount = supportChunkCount + 1
+ }
+
+ uint32_t graphIndex1;
+ if (!isInvalidIndex(chunkIndex1))
+ {
+ graphIndex1 = graphNodeIndexMap[chunkIndex1];
+ }
+ else
+ {
+ addWorldNode = true;
+ graphIndex1 = graphNodeCount; // Will set graphNodeCount = supportChunkCount + 1
+ }
+
+ if (isInvalidIndex(graphIndex0) || isInvalidIndex(graphIndex1))
{
nonSupportFound = true;
continue;
}
- t[bondSortArraySize++] = Nv::Blast::BondSortData(graphIndex0, graphIndex1, i);
- t[bondSortArraySize++] = Nv::Blast::BondSortData(graphIndex1, graphIndex0, i);
+ t[bondSortArraySize++] = BondSortData(graphIndex0, graphIndex1, i);
+ t[bondSortArraySize++] = BondSortData(graphIndex1, graphIndex0, i);
}
// Sort the temp array
- std::sort(bondSortArray, bondSortArray + bondSortArraySize, Nv::Blast::BondsOrdered());
+ std::sort(bondSortArray, bondSortArray + bondSortArraySize, BondsOrdered());
uint32_t symmetrizedBondCount = 0;
for (uint32_t i = 0; i < bondSortArraySize; ++i)
@@ -426,48 +481,55 @@ Asset* Asset::create(void* mem, const NvBlastAssetDesc* desc, void* scratch, NvB
bondCount = symmetrizedBondCount / 2;
+ // World node references found in bonds; add a world node
+ if (addWorldNode)
+ {
+ ++graphNodeCount;
+ }
+
// Report warnings
if (invalidFound)
{
- NVBLAST_LOG_WARNING(logFn, "NvBlastCreateAsset: Invalid bonds found (non-existent or same chunks referenced) and removed from asset.");
+ NVBLASTLL_LOG_WARNING(logFn, "NvBlastCreateAsset: Invalid bonds found (non-existent or same chunks referenced) and removed from asset.");
}
if (duplicateFound)
{
- NVBLAST_LOG_WARNING(logFn, "NvBlastCreateAsset: Duplicate bonds found and removed from asset.");
+ NVBLASTLL_LOG_WARNING(logFn, "NvBlastCreateAsset: Duplicate bonds found and removed from asset.");
}
if (nonSupportFound)
{
- NVBLAST_LOG_WARNING(logFn, "NvBlastCreateAsset: Bonds referencing non-support chunks found and removed from asset.");
+ NVBLASTLL_LOG_WARNING(logFn, "NvBlastCreateAsset: Bonds referencing non-support chunks found and removed from asset.");
}
}
// Allocate memory for asset
NvBlastID id;
memset(&id, 0, sizeof(NvBlastID)); // To do - create an actual id
- Nv::Blast::Asset* asset = initializeAsset(mem, id, desc->chunkCount, supportChunkCount, leafChunkCount, firstSubsupportChunkIndex, bondCount, logFn);
+ Asset* asset = initializeAsset(mem, id, desc->chunkCount, graphNodeCount, leafChunkCount, firstSubsupportChunkIndex, bondCount, logFn);
// Asset data pointers
- Nv::Blast::SupportGraph& graph = asset->m_graph;
+ SupportGraph& graph = asset->m_graph;
NvBlastChunk* chunks = asset->getChunks();
NvBlastBond* bonds = asset->getBonds();
uint32_t* subtreeLeafChunkCounts = asset->getSubtreeLeafChunkCounts();
// Create chunks
uint32_t* graphChunkIndices = graph.getChunkIndices();
+ memset(graphChunkIndices, 0xFF, graphNodeCount * sizeof(uint32_t)); // Ensures unmapped node indices go to invalidIndex - this is important for the world node, if added
for (uint32_t i = 0; i < desc->chunkCount; ++i)
{
const NvBlastChunkDesc& chunkDesc = desc->chunkDescs[i];
- const uint32_t newChunkIndex = i;
- NvBlastChunk& assetChunk = chunks[newChunkIndex];
+ NvBlastChunk& assetChunk = chunks[i];
memcpy(assetChunk.centroid, chunkDesc.centroid, 3 * sizeof(float));
assetChunk.volume = chunkDesc.volume;
- assetChunk.parentChunkIndex = Nv::Blast::isInvalidIndex(chunkDesc.parentChunkIndex) ? chunkDesc.parentChunkIndex : chunkDesc.parentChunkIndex;
- assetChunk.firstChildIndex = Nv::Blast::invalidIndex<uint32_t>(); // Will be filled in below
+ assetChunk.parentChunkIndex = isInvalidIndex(chunkDesc.parentChunkIndex) ? chunkDesc.parentChunkIndex : chunkDesc.parentChunkIndex;
+ assetChunk.firstChildIndex = invalidIndex<uint32_t>(); // Will be filled in below
assetChunk.childIndexStop = assetChunk.firstChildIndex;
assetChunk.userData = chunkDesc.userData;
- if (!Nv::Blast::isInvalidIndex(graphNodeIndexMap[newChunkIndex]))
+ const uint32_t graphNodeIndex = graphNodeIndexMap[i];
+ if (!isInvalidIndex(graphNodeIndex))
{
- graphChunkIndices[graphNodeIndexMap[newChunkIndex]] = newChunkIndex;
+ graphChunkIndices[graphNodeIndex] = i;
}
}
@@ -478,7 +540,7 @@ Asset* Asset::create(void* mem, const NvBlastAssetDesc* desc, void* scratch, NvB
for (uint32_t i = 0; i < desc->chunkCount; ++i)
{
const uint32_t parentChunkIndex = chunks[i].parentChunkIndex;
- if (!Nv::Blast::isInvalidIndex(parentChunkIndex))
+ if (!isInvalidIndex(parentChunkIndex))
{
if (chunks[parentChunkIndex].childIndexStop == chunks[parentChunkIndex].firstChildIndex)
{
@@ -495,32 +557,22 @@ Asset* Asset::create(void* mem, const NvBlastAssetDesc* desc, void* scratch, NvB
if (bondCount > 0)
{
// Create the lookup table from the sorted array
- Nv::Blast::createIndexStartLookup<uint32_t>(graphAdjacencyPartition, 0, graphNodeCount - 1, &bondSortArray->m_c0, 2 * bondCount, sizeof(Nv::Blast::BondSortData));
+ createIndexStartLookup<uint32_t>(graphAdjacencyPartition, 0, graphNodeCount - 1, &bondSortArray->m_c0, 2 * bondCount, sizeof(BondSortData));
// Write the adjacent chunk and bond index data
uint32_t bondIndex = 0;
for (uint32_t i = 0; i < 2 * bondCount; ++i)
{
- const Nv::Blast::BondSortData& bondSortData = bondSortArray[i];
+ const BondSortData& bondSortData = bondSortArray[i];
graphAdjacentNodeIndices[i] = bondSortData.m_c1;
const uint32_t oldBondIndex = bondSortData.m_b;
const NvBlastBondDesc& bondDesc = desc->bondDescs[oldBondIndex];
- if (Nv::Blast::isInvalidIndex(bondMap[oldBondIndex]))
+ if (isInvalidIndex(bondMap[oldBondIndex]))
{
bonds[bondIndex] = bondDesc.bond;
- // Our convention is that the bond normal points away from the lower-indexed chunk, towards the higher-indexed chunk.
- // If our new (graph node) indexing would reverse this direction from the bond descriptor's indexing, we must flip the nomral.
- const bool nodeIndicesOrdered = bondSortData.m_c0 < bondSortData.m_c1;
- const bool descNodeIndicesOrdered = bondDesc.chunkIndices[0] < bondDesc.chunkIndices[1];
- if (descNodeIndicesOrdered && !nodeIndicesOrdered)
- {
- float* normal = bonds[bondIndex].normal;
- normal[0] = -normal[0];
- normal[1] = -normal[1];
- normal[2] = -normal[2];
- }
bondMap[oldBondIndex] = bondIndex++;
}
+ NVBLAST_ASSERT(bondMap[oldBondIndex] < bondCount);
graphAdjacentBondIndices[i] = bondMap[oldBondIndex];
}
}
@@ -535,7 +587,7 @@ Asset* Asset::create(void* mem, const NvBlastAssetDesc* desc, void* scratch, NvB
uint32_t* breadthFirstChunkIndices = graphNodeIndexMap; // Reusing graphNodeIndexMap ... graphNodeIndexMap may no longer be used
for (uint32_t startChunkIndex = 0; startChunkIndex < desc->chunkCount; ++startChunkIndex)
{
- if (!Nv::Blast::isInvalidIndex(chunks[startChunkIndex].parentChunkIndex))
+ if (!isInvalidIndex(chunks[startChunkIndex].parentChunkIndex))
{
break; // Only iterate through root chunks at this level
}
@@ -637,7 +689,7 @@ bool Asset::ensureExactSupportCoverage(uint32_t& supportChunkCount, uint32_t& le
if (redundantCoverage)
{
- NVBLAST_LOG_INFO(logFn, "NvBlastCreateAsset: some leaf-to-root chains had more than one support chunk. Some support chunks removed.");
+ NVBLASTLL_LOG_INFO(logFn, "NvBlastCreateAsset: some leaf-to-root chains had more than one support chunk. Some support chunks removed.");
}
if (insufficientCoverage)
@@ -698,7 +750,7 @@ bool Asset::ensureExactSupportCoverage(uint32_t& supportChunkCount, uint32_t& le
}
}
- NVBLAST_LOG_INFO(logFn, "NvBlastCreateAsset: some leaf-to-root chains had no support chunks. Support chunks added.");
+ NVBLASTLL_LOG_INFO(logFn, "NvBlastCreateAsset: some leaf-to-root chains had no support chunks. Support chunks added.");
}
// Apply changes and count the number of support chunks
@@ -731,12 +783,12 @@ bool Asset::testForValidChunkOrder(uint32_t chunkCount, const NvBlastChunkDesc*
const uint32_t parentChunkIndex = chunkDescs[i].parentChunkIndex;
if (parentChunkIndex != currentParentChunkIndex)
{
- if (!Nv::Blast::isInvalidIndex(currentParentChunkIndex))
+ if (!isInvalidIndex(currentParentChunkIndex))
{
chunkMarks[currentParentChunkIndex] = 1;
}
currentParentChunkIndex = parentChunkIndex;
- if (Nv::Blast::isInvalidIndex(currentParentChunkIndex))
+ if (isInvalidIndex(currentParentChunkIndex))
{
return false;
}
@@ -772,7 +824,7 @@ extern "C"
size_t NvBlastGetRequiredScratchForCreateAsset(const NvBlastAssetDesc* desc, NvBlastLog logFn)
{
- NVBLAST_CHECK(desc != nullptr, logFn, "NvBlastGetRequiredScratchForCreateAsset: NULL desc pointer input.", return 0);
+ NVBLASTLL_CHECK(desc != nullptr, logFn, "NvBlastGetRequiredScratchForCreateAsset: NULL desc pointer input.", return 0);
return Nv::Blast::Asset::createRequiredScratch(desc);
}
@@ -780,7 +832,7 @@ size_t NvBlastGetRequiredScratchForCreateAsset(const NvBlastAssetDesc* desc, NvB
size_t NvBlastGetAssetMemorySize(const NvBlastAssetDesc* desc, NvBlastLog logFn)
{
- NVBLAST_CHECK(desc != nullptr, logFn, "NvBlastGetAssetMemorySize: NULL desc input.", return 0);
+ NVBLASTLL_CHECK(desc != nullptr, logFn, "NvBlastGetAssetMemorySize: NULL desc input.", return 0);
return Nv::Blast::Asset::getMemorySize(desc);
}
@@ -794,7 +846,7 @@ NvBlastAsset* NvBlastCreateAsset(void* mem, const NvBlastAssetDesc* desc, void*
size_t NvBlastAssetGetFamilyMemorySize(const NvBlastAsset* asset, NvBlastLog logFn)
{
- NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetFamilyMemorySize: NULL asset pointer input.", return 0);
+ NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetFamilyMemorySize: NULL asset pointer input.", return 0);
return Nv::Blast::getFamilyMemorySize(reinterpret_cast<const Nv::Blast::Asset*>(asset));
}
@@ -802,7 +854,7 @@ size_t NvBlastAssetGetFamilyMemorySize(const NvBlastAsset* asset, NvBlastLog log
NvBlastID NvBlastAssetGetID(const NvBlastAsset* asset, NvBlastLog logFn)
{
- NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetID: NULL asset pointer input.", NvBlastID zero; memset(&zero, 0, sizeof(NvBlastID)); return zero);
+ NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetID: NULL asset pointer input.", NvBlastID zero; memset(&zero, 0, sizeof(NvBlastID)); return zero);
return ((Nv::Blast::Asset*)asset)->m_ID;
}
@@ -810,8 +862,8 @@ NvBlastID NvBlastAssetGetID(const NvBlastAsset* asset, NvBlastLog logFn)
bool NvBlastAssetSetID(NvBlastAsset* asset, const NvBlastID* id, NvBlastLog logFn)
{
- NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetSetID: NULL asset pointer input.", return false);
- NVBLAST_CHECK(id != nullptr, logFn, "NvBlastAssetSetID: NULL id pointer input.", return false);
+ NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetSetID: NULL asset pointer input.", return false);
+ NVBLASTLL_CHECK(id != nullptr, logFn, "NvBlastAssetSetID: NULL id pointer input.", return false);
((Nv::Blast::Asset*)asset)->m_ID = *id;
@@ -821,7 +873,7 @@ bool NvBlastAssetSetID(NvBlastAsset* asset, const NvBlastID* id, NvBlastLog logF
uint32_t NvBlastAssetGetFormatVersion(const NvBlastAsset* asset, NvBlastLog logFn)
{
- NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetFormatVersion: NULL asset input.", return UINT32_MAX);
+ NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetFormatVersion: NULL asset input.", return UINT32_MAX);
return ((Nv::Blast::Asset*)asset)->m_header.formatVersion;
}
@@ -829,7 +881,7 @@ uint32_t NvBlastAssetGetFormatVersion(const NvBlastAsset* asset, NvBlastLog logF
uint32_t NvBlastAssetGetSize(const NvBlastAsset* asset, NvBlastLog logFn)
{
- NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetSize: NULL asset input.", return 0);
+ NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetSize: NULL asset input.", return 0);
return ((Nv::Blast::Asset*)asset)->m_header.size;
}
@@ -837,15 +889,31 @@ uint32_t NvBlastAssetGetSize(const NvBlastAsset* asset, NvBlastLog logFn)
uint32_t NvBlastAssetGetChunkCount(const NvBlastAsset* asset, NvBlastLog logFn)
{
- NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetChunkCount: NULL asset input.", return 0);
+ NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetChunkCount: NULL asset input.", return 0);
return ((Nv::Blast::Asset*)asset)->m_chunkCount;
}
+uint32_t NvBlastAssetGetSupportChunkCount(const NvBlastAsset* asset, NvBlastLog logFn)
+{
+ NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetSupportChunkCount: NULL asset input.", return 0);
+
+ const Nv::Blast::Asset* a = reinterpret_cast<const Nv::Blast::Asset*>(asset);
+ const Nv::Blast::SupportGraph& graph = a->m_graph;
+
+ if (graph.m_nodeCount == 0)
+ {
+ return 0; // This shouldn't happen
+ }
+
+ return Nv::Blast::isInvalidIndex(graph.getChunkIndices()[graph.m_nodeCount - 1]) ? graph.m_nodeCount - 1 : graph.m_nodeCount;
+}
+
+
uint32_t NvBlastAssetGetLeafChunkCount(const NvBlastAsset* asset, NvBlastLog logFn)
{
- NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetLeafChunkCount: NULL asset input.", return 0);
+ NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetLeafChunkCount: NULL asset input.", return 0);
return ((Nv::Blast::Asset*)asset)->m_leafChunkCount;
}
@@ -853,7 +921,7 @@ uint32_t NvBlastAssetGetLeafChunkCount(const NvBlastAsset* asset, NvBlastLog log
uint32_t NvBlastAssetGetFirstSubsupportChunkIndex(const NvBlastAsset* asset, NvBlastLog logFn)
{
- NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetFirstSubsupportChunkIndex: NULL asset input.", return 0);
+ NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetFirstSubsupportChunkIndex: NULL asset input.", return 0);
return ((Nv::Blast::Asset*)asset)->m_firstSubsupportChunkIndex;
}
@@ -861,7 +929,7 @@ uint32_t NvBlastAssetGetFirstSubsupportChunkIndex(const NvBlastAsset* asset, NvB
uint32_t NvBlastAssetGetBondCount(const NvBlastAsset* asset, NvBlastLog logFn)
{
- NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetBondCount: NULL asset input.", return 0);
+ NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetBondCount: NULL asset input.", return 0);
return ((Nv::Blast::Asset*)asset)->m_bondCount;
}
@@ -869,7 +937,7 @@ uint32_t NvBlastAssetGetBondCount(const NvBlastAsset* asset, NvBlastLog logFn)
const NvBlastSupportGraph NvBlastAssetGetSupportGraph(const NvBlastAsset* asset, NvBlastLog logFn)
{
- NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetSupportGraph: NULL asset input.",
+ NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetSupportGraph: NULL asset input.",
NvBlastSupportGraph blank; blank.nodeCount = 0; blank.chunkIndices = blank.adjacencyPartition = blank.adjacentNodeIndices = blank.adjacentBondIndices = nullptr; return blank);
const Nv::Blast::SupportGraph& supportGraph = static_cast<const Nv::Blast::Asset*>(asset)->m_graph;
@@ -887,7 +955,7 @@ const NvBlastSupportGraph NvBlastAssetGetSupportGraph(const NvBlastAsset* asset,
const uint32_t* NvBlastAssetGetChunkToGraphNodeMap(const NvBlastAsset* asset, NvBlastLog logFn)
{
- NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetChunkToGraphNodeMap: NULL asset input.", return nullptr);
+ NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetChunkToGraphNodeMap: NULL asset input.", return nullptr);
return static_cast<const Nv::Blast::Asset*>(asset)->getChunkToGraphNodeMap();
}
@@ -895,7 +963,7 @@ const uint32_t* NvBlastAssetGetChunkToGraphNodeMap(const NvBlastAsset* asset, Nv
const NvBlastChunk* NvBlastAssetGetChunks(const NvBlastAsset* asset, NvBlastLog logFn)
{
- NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetChunks: NULL asset input.", return 0);
+ NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetChunks: NULL asset input.", return 0);
return ((Nv::Blast::Asset*)asset)->getChunks();
}
@@ -903,7 +971,7 @@ const NvBlastChunk* NvBlastAssetGetChunks(const NvBlastAsset* asset, NvBlastLog
const NvBlastBond* NvBlastAssetGetBonds(const NvBlastAsset* asset, NvBlastLog logFn)
{
- NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetBonds: NULL asset input.", return 0);
+ NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetBonds: NULL asset input.", return 0);
return ((Nv::Blast::Asset*)asset)->getBonds();
}
@@ -911,7 +979,7 @@ const NvBlastBond* NvBlastAssetGetBonds(const NvBlastAsset* asset, NvBlastLog lo
uint32_t NvBlastAssetGetActorSerializationSizeUpperBound(const NvBlastAsset* asset, NvBlastLog logFn)
{
- NVBLAST_CHECK(asset != nullptr, logFn, "NvBlastAssetGetActorSerializationSizeUpperBound: NULL asset input.", return 0);
+ NVBLASTLL_CHECK(asset != nullptr, logFn, "NvBlastAssetGetActorSerializationSizeUpperBound: NULL asset input.", return 0);
const Nv::Blast::Asset& solverAsset = *(const Nv::Blast::Asset*)asset;
const uint32_t graphNodeCount = solverAsset.m_graph.m_nodeCount;
@@ -921,7 +989,7 @@ uint32_t NvBlastAssetGetActorSerializationSizeUpperBound(const NvBlastAsset* ass
if (upperBound > UINT32_MAX)
{
- NVBLAST_LOG_WARNING(logFn, "NvBlastAssetGetActorSerializationSizeUpperBound: Serialization block size exceeds 4GB. Returning 0.\n");
+ NVBLASTLL_LOG_WARNING(logFn, "NvBlastAssetGetActorSerializationSizeUpperBound: Serialization block size exceeds 4GB. Returning 0.\n");
return 0;
}
diff --git a/sdk/lowlevel/source/NvBlastAsset.h b/sdk/lowlevel/source/NvBlastAsset.h
index 30e8161..65f8b43 100644
--- a/sdk/lowlevel/source/NvBlastAsset.h
+++ b/sdk/lowlevel/source/NvBlastAsset.h
@@ -1,12 +1,30 @@
-/*
-* 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.
+
#ifndef NVBLASTASSET_H
#define NVBLASTASSET_H
diff --git a/sdk/lowlevel/source/NvBlastAssetHelper.cpp b/sdk/lowlevel/source/NvBlastAssetHelper.cpp
index 0d6c5d2..cc3d643 100644
--- a/sdk/lowlevel/source/NvBlastAssetHelper.cpp
+++ b/sdk/lowlevel/source/NvBlastAssetHelper.cpp
@@ -1,17 +1,37 @@
-/*
-* 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 "NvBlastAsset.h"
#include "NvBlastIndexFns.h"
#include "NvBlastAssert.h"
#include "NvBlastMemory.h"
+#include "NvBlastMath.h"
+#include "NvBlastPreprocessorInternal.h"
#include <algorithm>
@@ -62,9 +82,9 @@ extern "C"
bool NvBlastBuildAssetDescChunkReorderMap(uint32_t* chunkReorderMap, const NvBlastChunkDesc* chunkDescs, uint32_t chunkCount, void* scratch, NvBlastLog logFn)
{
- NVBLAST_CHECK(chunkCount == 0 || chunkDescs != nullptr, logFn, "NvBlastBuildAssetDescChunkReorderMap: NULL chunkDescs input with non-zero chunkCount", return false);
- NVBLAST_CHECK(chunkReorderMap == nullptr || chunkCount != 0, logFn, "NvBlastBuildAssetDescChunkReorderMap: NULL chunkReorderMap input with non-zero chunkCount", return false);
- NVBLAST_CHECK(chunkCount == 0 || scratch != nullptr, logFn, "NvBlastBuildAssetDescChunkReorderMap: NULL scratch input with non-zero chunkCount", return false);
+ NVBLASTLL_CHECK(chunkCount == 0 || chunkDescs != nullptr, logFn, "NvBlastBuildAssetDescChunkReorderMap: NULL chunkDescs input with non-zero chunkCount", return false);
+ NVBLASTLL_CHECK(chunkReorderMap == nullptr || chunkCount != 0, logFn, "NvBlastBuildAssetDescChunkReorderMap: NULL chunkReorderMap input with non-zero chunkCount", return false);
+ NVBLASTLL_CHECK(chunkCount == 0 || scratch != nullptr, logFn, "NvBlastBuildAssetDescChunkReorderMap: NULL scratch input with non-zero chunkCount", return false);
uint32_t* chunkMap = static_cast<uint32_t*>(scratch); scratch = pointerOffset(scratch, chunkCount * sizeof(uint32_t));
char* chunkAnnotation = static_cast<char*>(scratch); scratch = pointerOffset(scratch, chunkCount * sizeof(char));
@@ -73,7 +93,7 @@ bool NvBlastBuildAssetDescChunkReorderMap(uint32_t* chunkReorderMap, const NvBla
uint32_t leafChunkCount;
if (!Asset::ensureExactSupportCoverage(supportChunkCount, leafChunkCount, chunkAnnotation, chunkCount, const_cast<NvBlastChunkDesc*>(chunkDescs), true, logFn))
{
- NVBLAST_LOG_ERROR(logFn, "NvBlastBuildAssetDescChunkReorderMap: chunk descriptors did not have exact coverage, map could not be built. Use NvBlastEnsureAssetExactSupportCoverage to fix descriptors.");
+ NVBLASTLL_LOG_ERROR(logFn, "NvBlastBuildAssetDescChunkReorderMap: chunk descriptors did not have exact coverage, map could not be built. Use NvBlastEnsureAssetExactSupportCoverage to fix descriptors.");
return false;
}
@@ -108,14 +128,15 @@ void NvBlastApplyAssetDescChunkReorderMap
NvBlastBondDesc* bondDescs,
uint32_t bondCount,
const uint32_t* chunkReorderMap,
+ bool keepBondNormalChunkOrder,
NvBlastLog logFn
)
{
- NVBLAST_CHECK(chunkCount == 0 || chunkDescs != nullptr, logFn, "NvBlastApplyAssetDescChunkReorderMap: NULL chunkDescs input with non-zero chunkCount", return);
- NVBLAST_CHECK(reorderedChunkDescs == nullptr || chunkCount != 0, logFn, "NvBlastApplyAssetDescChunkReorderMap: NULL reorderedChunkDescs input with non-zero chunkCount", return);
- NVBLAST_CHECK(chunkReorderMap == nullptr || chunkCount != 0, logFn, "NvBlastApplyAssetDescChunkReorderMap: NULL chunkReorderMap input with non-zero chunkCount", return);
- NVBLAST_CHECK(bondCount == 0 || bondDescs != nullptr, logFn, "NvBlastApplyAssetDescChunkReorderMap: NULL bondDescs input with non-zero bondCount", return);
- NVBLAST_CHECK(bondDescs == nullptr || chunkReorderMap != nullptr, logFn, "NvBlastApplyAssetDescChunkReorderMap: NULL bondDescs input with NULL chunkReorderMap", return);
+ NVBLASTLL_CHECK(chunkCount == 0 || chunkDescs != nullptr, logFn, "NvBlastApplyAssetDescChunkReorderMap: NULL chunkDescs input with non-zero chunkCount", return);
+ NVBLASTLL_CHECK(reorderedChunkDescs == nullptr || chunkCount != 0, logFn, "NvBlastApplyAssetDescChunkReorderMap: NULL reorderedChunkDescs input with non-zero chunkCount", return);
+ NVBLASTLL_CHECK(chunkReorderMap == nullptr || chunkCount != 0, logFn, "NvBlastApplyAssetDescChunkReorderMap: NULL chunkReorderMap input with non-zero chunkCount", return);
+ NVBLASTLL_CHECK(bondCount == 0 || bondDescs != nullptr, logFn, "NvBlastApplyAssetDescChunkReorderMap: NULL bondDescs input with non-zero bondCount", return);
+ NVBLASTLL_CHECK(bondDescs == nullptr || chunkReorderMap != nullptr, logFn, "NvBlastApplyAssetDescChunkReorderMap: NULL bondDescs input with NULL chunkReorderMap", return);
// Copy chunk descs
if (reorderedChunkDescs)
@@ -135,35 +156,58 @@ void NvBlastApplyAssetDescChunkReorderMap
{
for (uint32_t i = 0; i < bondCount; ++i)
{
- for (int j = 0; j < 2; ++j)
+ NvBlastBondDesc& bondDesc = bondDescs[i];
+ uint32_t& index0 = bondDesc.chunkIndices[0];
+ uint32_t& index1 = bondDesc.chunkIndices[1];
+ const uint32_t newIndex0 = index0 < chunkCount ? chunkReorderMap[index0] : index0;
+ const uint32_t newIndex1 = index1 < chunkCount ? chunkReorderMap[index1] : index1;
+ if (keepBondNormalChunkOrder && (index0 < index1) != (newIndex0 < newIndex1))
{
- uint32_t& index = bondDescs[i].chunkIndices[j];
- if (index < chunkCount)
- {
- index = chunkReorderMap[index];
- }
+ VecMath::mul(bondDesc.bond.normal, -1);
}
+ index0 = newIndex0;
+ index1 = newIndex1;
}
}
}
-void NvBlastApplyAssetDescChunkReorderMapInplace(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount, NvBlastBondDesc* bondDescs, uint32_t bondCount, const uint32_t* chunkReorderMap, void* scratch, NvBlastLog logFn)
+void NvBlastApplyAssetDescChunkReorderMapInPlace
+(
+ NvBlastChunkDesc* chunkDescs,
+ uint32_t chunkCount,
+ NvBlastBondDesc* bondDescs,
+ uint32_t bondCount,
+ const uint32_t* chunkReorderMap,
+ bool keepBondNormalChunkOrder,
+ void* scratch,
+ NvBlastLog logFn
+)
{
- NVBLAST_CHECK(chunkCount == 0 || chunkDescs != nullptr, logFn, "NvBlastApplyAssetDescChunkReorderMapInplace: NULL chunkDescs input with non-zero chunkCount", return);
- NVBLAST_CHECK(chunkCount == 0 || scratch != nullptr, logFn, "NvBlastApplyAssetDescChunkReorderMapInplace: NULL scratch input with non-zero chunkCount", return);
+ NVBLASTLL_CHECK(chunkCount == 0 || chunkDescs != nullptr, logFn, "NvBlastApplyAssetDescChunkReorderMapInPlace: NULL chunkDescs input with non-zero chunkCount", return);
+ NVBLASTLL_CHECK(chunkCount == 0 || scratch != nullptr, logFn, "NvBlastApplyAssetDescChunkReorderMapInPlace: NULL scratch input with non-zero chunkCount", return);
NvBlastChunkDesc* chunksTemp = static_cast<NvBlastChunkDesc*>(scratch);
memcpy(chunksTemp, chunkDescs, sizeof(NvBlastChunkDesc) * chunkCount);
- NvBlastApplyAssetDescChunkReorderMap(chunkDescs, chunksTemp, chunkCount, bondDescs, bondCount, chunkReorderMap, logFn);
+ NvBlastApplyAssetDescChunkReorderMap(chunkDescs, chunksTemp, chunkCount, bondDescs, bondCount, chunkReorderMap, keepBondNormalChunkOrder, logFn);
}
-bool NvBlastReorderAssetDescChunks(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount, NvBlastBondDesc* bondDescs, uint32_t bondCount, uint32_t* chunkReorderMap, void* scratch, NvBlastLog logFn)
+bool NvBlastReorderAssetDescChunks
+(
+ NvBlastChunkDesc* chunkDescs,
+ uint32_t chunkCount,
+ NvBlastBondDesc* bondDescs,
+ uint32_t bondCount,
+ uint32_t* chunkReorderMap,
+ bool keepBondNormalChunkOrder,
+ void* scratch,
+ NvBlastLog logFn
+)
{
if (!NvBlastBuildAssetDescChunkReorderMap(chunkReorderMap, chunkDescs, chunkCount, scratch, logFn))
{
- NvBlastApplyAssetDescChunkReorderMapInplace(chunkDescs, chunkCount, bondDescs, bondCount, chunkReorderMap, scratch, logFn);
+ NvBlastApplyAssetDescChunkReorderMapInPlace(chunkDescs, chunkCount, bondDescs, bondCount, chunkReorderMap, keepBondNormalChunkOrder, scratch, logFn);
return false;
}
return true;
@@ -172,8 +216,8 @@ bool NvBlastReorderAssetDescChunks(NvBlastChunkDesc* chunkDescs, uint32_t chunkC
bool NvBlastEnsureAssetExactSupportCoverage(NvBlastChunkDesc* chunkDescs, uint32_t chunkCount, void* scratch, NvBlastLog logFn)
{
- NVBLAST_CHECK(chunkCount == 0 || chunkDescs != nullptr, logFn, "NvBlastEnsureAssetExactSupportCoverage: NULL chunkDescs input with non-zero chunkCount", return false);
- NVBLAST_CHECK(chunkCount == 0 || scratch != nullptr, logFn, "NvBlastEnsureAssetExactSupportCoverage: NULL scratch input with non-zero chunkCount", return false);
+ NVBLASTLL_CHECK(chunkCount == 0 || chunkDescs != nullptr, logFn, "NvBlastEnsureAssetExactSupportCoverage: NULL chunkDescs input with non-zero chunkCount", return false);
+ NVBLASTLL_CHECK(chunkCount == 0 || scratch != nullptr, logFn, "NvBlastEnsureAssetExactSupportCoverage: NULL scratch input with non-zero chunkCount", return false);
uint32_t supportChunkCount;
uint32_t leafChunkCount;
diff --git a/sdk/lowlevel/source/NvBlastChunkHierarchy.h b/sdk/lowlevel/source/NvBlastChunkHierarchy.h
index e7e05c6..52380e8 100644
--- a/sdk/lowlevel/source/NvBlastChunkHierarchy.h
+++ b/sdk/lowlevel/source/NvBlastChunkHierarchy.h
@@ -1,12 +1,30 @@
-/*
-* 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.
+
#ifndef NVBLASTCHUNKHIERARCHY_H
#define NVBLASTCHUNKHIERARCHY_H
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();
}
diff --git a/sdk/lowlevel/source/NvBlastFamily.h b/sdk/lowlevel/source/NvBlastFamily.h
index d1cb069..99a7e98 100644
--- a/sdk/lowlevel/source/NvBlastFamily.h
+++ b/sdk/lowlevel/source/NvBlastFamily.h
@@ -1,18 +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.
+
#ifndef NVBLASTFAMILY_H
#define NVBLASTFAMILY_H
-#include "NvBlastPreprocessorInternal.h"
#include "NvBlastAsset.h"
#include "NvBlastPreprocessor.h"
#include "NvBlastDLink.h"
@@ -164,6 +181,139 @@ struct FamilyHeader : public NvBlastDataBlock
\return true iff the indexed actor is active.
*/
bool isActorActive(uint32_t index) const;
+
+ /**
+ Retrieve the actor from an index. If actor is inactive nullptr is returned.
+
+ \param[in] index The index of an actor.
+
+ \return A pointer to the indexed actor if the actor is active, nullptr otherwise.
+ */
+ Actor* getActorByIndex(uint32_t index) const;
+
+ /**
+ Retrieve the index of an actor associated with the given chunk.
+
+ \param[in] chunkIndex The index of chunk.
+
+ \return the index of associated actor in the FamilyHeader's getActors() array.
+ */
+ uint32_t getGetChunkActorIndex(uint32_t chunkIndex) const;
+
+ /**
+ Retrieve the index of an actor associated with the given node.
+
+ \param[in] nodeIndex The index of node.
+
+ \return the index of associated actor in the FamilyHeader's getActors() array.
+ */
+ uint32_t getGetNodeActorIndex(uint32_t nodeIndex) const;
+
+ /**
+ Retrieve an actor associated with the given chunk.
+
+ \param[in] chunkIndex The index of chunk.
+
+ \return A pointer to the actor if the actor is active, nullptr otherwise.
+ */
+ Actor* getGetChunkActor(uint32_t chunkIndex) const;
+
+ /**
+ Retrieve an actor associated with the given node.
+
+ \param[in] nodeIndex The index of node.
+
+ \return A pointer to the actor if the actor is active, nullptr otherwise.
+ */
+ Actor* getGetNodeActor(uint32_t nodeIndex) const;
+
+
+ //////// Fracturing methods ////////
+
+ /**
+ Hierarchically distribute damage to child chunks.
+
+ \param chunkIndex asset chunk index to hierarchically damage
+ \param suboffset index of the first sub-support health
+ \param healthDamage damage strength to apply
+ \param chunkHealths instance chunk healths
+ \param chunks asset chunk collection
+ */
+ void fractureSubSupportNoEvents(uint32_t chunkIndex, uint32_t suboffset, float healthDamage, float* chunkHealths, const NvBlastChunk* chunks);
+
+ /**
+ Hierarchically distribute damage to child chunks, recording a fracture event for each health damage applied.
+
+ If outBuffer is too small, events are dropped but the chunks are still damaged.
+
+ \param chunkIndex asset chunk index to hierarchically damage
+ \param suboffset index of the first sub-support health
+ \param healthDamage damage strength to apply
+ \param chunkHealths instance chunk healths
+ \param chunks asset chunk collection
+ \param outBuffer target buffer for fracture events
+ \param currentIndex current position in outBuffer - returns the number of damaged chunks
+ \param maxCount capacity of outBuffer
+ \param[in] filterActor pointer to the actor to filter commands that target other actors. May be NULL to apply all commands
+ \param[in] logFn User-supplied message function (see NvBlastLog definition). May be NULL.
+ */
+ void fractureSubSupport(uint32_t chunkIndex, uint32_t suboffset, float healthDamage, float* chunkHealths, const NvBlastChunk* chunks, NvBlastChunkFractureData* outBuffer, uint32_t* currentIndex, const uint32_t maxCount);
+
+ /**
+ Apply chunk fracture commands hierarchically.
+
+ \param chunkFractureCount number of chunk fracture commands to apply
+ \param chunkFractures array of chunk fracture commands
+ \param filterActor pointer to the actor to filter commands corresponding to other actors. May be NULL to apply all commands
+ \param[in] logFn User-supplied message function (see NvBlastLog definition). May be NULL.
+ */
+ void fractureNoEvents(uint32_t chunkFractureCount, const NvBlastChunkFractureData* chunkFractures, Actor* filterActor, NvBlastLog logFn);
+
+ /**
+ Apply chunk fracture commands hierarchically, recording a fracture event for each health damage applied.
+
+ If events array is too small, events are dropped but the chunks are still damaged.
+
+ \param chunkFractureCount number of chunk fracture commands to apply
+ \param commands array of chunk fracture commands
+ \param events target buffer for fracture events
+ \param eventsSize number of available entries in 'events'
+ \param count returns the number of damaged chunks
+ \param[in] filterActor pointer to the actor to filter commands that target other actors. May be NULL to apply all commands
+ \param[in] logFn User-supplied message function (see NvBlastLog definition). May be NULL.
+
+ */
+ void fractureWithEvents(uint32_t chunkFractureCount, const NvBlastChunkFractureData* commands, NvBlastChunkFractureData* events, uint32_t eventsSize, uint32_t* count, Actor* filterActor, NvBlastLog logFn);
+
+ /**
+ Apply chunk fracture commands hierarchically, recording a fracture event for each health damage applied.
+
+ In-Place version: fracture commands are replaced by fracture events.
+
+ If inoutbuffer array is too small, events are dropped but the chunks are still damaged.
+
+ \param chunkFractureCount number of chunk fracture commands to apply
+ \param inoutbuffer array of chunk fracture commands to be replaced by events
+ \param eventsSize number of available entries in inoutbuffer
+ \param count returns the number of damaged chunks
+ \param[in] filterActor pointer to the actor to filter commands that target other actors. May be NULL to apply all commands
+ \param[in] logFn User-supplied message function (see NvBlastLog definition). May be NULL.
+
+ */
+ void fractureInPlaceEvents(uint32_t chunkFractureCount, NvBlastChunkFractureData* inoutbuffer, uint32_t eventsSize, uint32_t* count, Actor* filterActor, NvBlastLog logFn);
+
+ /**
+ See NvBlastActorApplyFracture
+
+ \param[in,out] eventBuffers Target buffers to hold applied fracture events. May be NULL, in which case events are not reported.
+ To avoid data loss, provide an entry for every lower-support chunk and every bond in the original actor.
+ \param[in,out] actor The NvBlastActor to apply fracture to.
+ \param[in] commands The fracture commands to process.
+ \param[in] filterActor pointer to the actor to filter commands that target other actors. May be NULL to apply all commands
+ \param[in] logFn User-supplied message function (see NvBlastLog definition). May be NULL.
+ \param[in,out] timers If non-NULL this struct will be filled out with profiling information for the step, in profile build configurations.
+ */
+ void applyFracture(NvBlastFractureBuffers* eventBuffers, const NvBlastFractureBuffers* commands, Actor* filterActor, NvBlastLog logFn, NvBlastTimers* timers);
};
} // namespace Blast
@@ -221,6 +371,52 @@ NV_INLINE bool FamilyHeader::isActorActive(uint32_t index) const
}
+NV_INLINE Actor* FamilyHeader::getActorByIndex(uint32_t index) const
+{
+ NVBLAST_ASSERT(index < getActorBufferSize());
+ Actor& actor = getActors()[index];
+ return actor.isActive() ? &actor : nullptr;
+}
+
+
+NV_INLINE uint32_t FamilyHeader::getGetChunkActorIndex(uint32_t chunkIndex) const
+{
+ NVBLAST_ASSERT(m_asset);
+ NVBLAST_ASSERT(chunkIndex < m_asset->m_chunkCount);
+ if (chunkIndex < m_asset->getUpperSupportChunkCount())
+ {
+ return getChunkActorIndices()[chunkIndex];
+ }
+ else
+ {
+ return chunkIndex - (m_asset->getUpperSupportChunkCount() - m_asset->m_graph.m_nodeCount);
+ }
+}
+
+
+NV_INLINE uint32_t FamilyHeader::getGetNodeActorIndex(uint32_t nodeIndex) const
+{
+ NVBLAST_ASSERT(m_asset);
+ NVBLAST_ASSERT(nodeIndex < m_asset->m_graph.m_nodeCount);
+ const uint32_t chunkIndex = m_asset->m_graph.getChunkIndices()[nodeIndex];
+ return isInvalidIndex(chunkIndex) ? chunkIndex : getChunkActorIndices()[chunkIndex];
+}
+
+
+NV_INLINE Actor* FamilyHeader::getGetChunkActor(uint32_t chunkIndex) const
+{
+ uint32_t actorIndex = getGetChunkActorIndex(chunkIndex);
+ return !isInvalidIndex(actorIndex) ? getActorByIndex(actorIndex) : nullptr;
+}
+
+
+NV_INLINE Actor* FamilyHeader::getGetNodeActor(uint32_t nodeIndex) const
+{
+ uint32_t actorIndex = getGetNodeActorIndex(nodeIndex);
+ return !isInvalidIndex(actorIndex) ? getActorByIndex(actorIndex) : nullptr;
+}
+
+
//////// Global functions ////////
/**
diff --git a/sdk/lowlevel/source/NvBlastFamilyGraph.cpp b/sdk/lowlevel/source/NvBlastFamilyGraph.cpp
index 08ed83d..9379a32 100644
--- a/sdk/lowlevel/source/NvBlastFamilyGraph.cpp
+++ b/sdk/lowlevel/source/NvBlastFamilyGraph.cpp
@@ -1,12 +1,30 @@
-/*
-* 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 "NvBlastFamilyGraph.h"
diff --git a/sdk/lowlevel/source/NvBlastFamilyGraph.h b/sdk/lowlevel/source/NvBlastFamilyGraph.h
index 9fa331a..1242487 100644
--- a/sdk/lowlevel/source/NvBlastFamilyGraph.h
+++ b/sdk/lowlevel/source/NvBlastFamilyGraph.h
@@ -1,12 +1,30 @@
-/*
-* 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.
+
#ifndef NVBLASTFAMILYGRAPH_H
#define NVBLASTFAMILYGRAPH_H
@@ -18,7 +36,6 @@
#include "NvBlastFixedBoolArray.h"
#include "NvBlastMath.h"
#include "NvBlastFixedPriorityQueue.h"
-#include "NvBlastPreprocessorInternal.h"
#include "NvBlastMemory.h"
diff --git a/sdk/lowlevel/source/NvBlastSupportGraph.h b/sdk/lowlevel/source/NvBlastSupportGraph.h
index 9ee3fc9..b8c2368 100644
--- a/sdk/lowlevel/source/NvBlastSupportGraph.h
+++ b/sdk/lowlevel/source/NvBlastSupportGraph.h
@@ -1,19 +1,36 @@
-/*
-* 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.
+
#ifndef NVBLASTSUPPORTGRAPH_H
#define NVBLASTSUPPORTGRAPH_H
#include "NvBlastIndexFns.h"
-#include "NvBlastPreprocessorInternal.h"
#include "NvBlastMemory.h"
namespace Nv