diff options
| author | Anton Novoselov <[email protected]> | 2017-08-01 12:53:38 +0300 |
|---|---|---|
| committer | Anton Novoselov <[email protected]> | 2017-08-01 12:53:38 +0300 |
| commit | 236f03c0b9a4982328ed1201978f7f69d192d9b2 (patch) | |
| tree | e486f2fa39dba203563895541e92c60ed3e25759 /sdk/extensions/shaders | |
| parent | Added screens to welcome page (diff) | |
| download | blast-236f03c0b9a4982328ed1201978f7f69d192d9b2.tar.xz blast-236f03c0b9a4982328ed1201978f7f69d192d9b2.zip | |
Blast 1.1 release (windows / linux)
see docs/release_notes.txt for details
Diffstat (limited to 'sdk/extensions/shaders')
4 files changed, 457 insertions, 373 deletions
diff --git a/sdk/extensions/shaders/include/NvBlastExtDamageShaders.h b/sdk/extensions/shaders/include/NvBlastExtDamageShaders.h index 385bf52..8daf9cf 100644 --- a/sdk/extensions/shaders/include/NvBlastExtDamageShaders.h +++ b/sdk/extensions/shaders/include/NvBlastExtDamageShaders.h @@ -1,18 +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 NVBLASTEXTDAMAGESHADERS_H #define NVBLASTEXTDAMAGESHADERS_H #include "NvBlastTypes.h" -#include "NvBlastPreprocessor.h" + /** A few example damage shader implementations. @@ -24,22 +42,39 @@ A few example damage shader implementations. /////////////////////////////////////////////////////////////////////////////// /** -Specific parameters for the material functions here present. +Example of simple material. It is passed into damage shader, thus it is not used +currently in any of them. The user can use it to filter and normalize before applying. Material function implementers may choose their own set. */ struct NvBlastExtMaterial { - float singleChunkThreshold; //!< subsupport chunks only take damage surpassing this value - float graphChunkThreshold; //!< support chunks only take damage surpassing this value - float bondTangentialThreshold; //!< bond only take damage surpassing this value - float bondNormalThreshold; //!< currently unused - forward damage propagation - float damageAttenuation; //!< factor of damage attenuation while forwarding + NvBlastExtMaterial() : health(100.f), minDamageThreshold(0.0f), maxDamageThreshold(1.0f) {} + + float health; //!< health + float minDamageThreshold; //!< min damage fraction threshold to be applied. Range [0, 1]. For example 0.1 filters all damage below 10% of health. + float maxDamageThreshold; //!< max damage fraction threshold to be applied. Range [0, 1]. For example 0.8 won't allow more then 80% of health damage to be applied. + + /** + Helper to normalize damage. + + Pass damage defined in health, damage in range [0, 1] is returned, where 0 basically + indicates that the threshold wasn't reached and there is no point in applying it. + + \param[in] damageInHealth Damage defined in terms of health amount to be reduced. + + \return normalized damage + */ + float getNormalizedDamage(float damageInHealth) const + { + const float damage = health > 0.f ? damageInHealth / health : 1.0f; + return damage > minDamageThreshold ? (damage < maxDamageThreshold ? damage : maxDamageThreshold) : 0.f; + } }; /////////////////////////////////////////////////////////////////////////////// -// Radial Damage +// Point Radial Damage /////////////////////////////////////////////////////////////////////////////// /** @@ -47,7 +82,7 @@ Radial Damage Desc */ struct NvBlastExtRadialDamageDesc { - float compressive; //!< compressive (radial) damage component + float damage; //!< normalized damage amount, range: [0, 1] (maximum health value to be reduced) float position[3]; //!< origin of damage action float minRadius; //!< inner radius of damage action float maxRadius; //!< outer radius of damage action @@ -85,6 +120,36 @@ NVBLAST_API bool NvBlastExtDamageActorRadialFalloff(NvBlastActor* actor, NvBlast /////////////////////////////////////////////////////////////////////////////// +// Segment Radial Damage +/////////////////////////////////////////////////////////////////////////////// + +/** +Segment Radial Damage Desc +*/ +struct NvBlastExtSegmentRadialDamageDesc +{ + float damage; //!< normalized damage amount, range: [0, 1] (maximum health value to be reduced) + float position0[3]; //!< damage segment point A position + float position1[3]; //!< damage segment point B position + float minRadius; //!< inner radius of damage action + float maxRadius; //!< outer radius of damage action +}; + +/** +Segment Radial Falloff damage for both graph and subgraph shaders. + +For every bond/chunk damage is calculated from the distance to line segment AB described in NvBlastExtSegmentRadialDamageDesc. +If distance is smaller then minRadius, full compressive amount of damage is applied. From minRadius to maxRaidus it linearly falls off to zero. + +NOTE: The signature of shader functions are equal to NvBlastGraphShaderFunction and NvBlastSubgraphShaderFunction respectively. +They are not expected to be called directly. +@see NvBlastGraphShaderFunction, NvBlastSubgraphShaderFunction +*/ +NVBLAST_API void NvBlastExtSegmentFalloffGraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastGraphShaderActor* actor, const NvBlastProgramParams* params); +NVBLAST_API void NvBlastExtSegmentFalloffSubgraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastSubgraphShaderActor* actor, const NvBlastProgramParams* params); + + +/////////////////////////////////////////////////////////////////////////////// // Shear Damage /////////////////////////////////////////////////////////////////////////////// @@ -93,8 +158,13 @@ Shear Damage Desc */ struct NvBlastExtShearDamageDesc { - float shear[3]; //!< directional damage component + float damage; //!< normalized damage amount, range: [0, 1] (maximum health value to be reduced) + + float normal[3]; //!< directional damage component float position[3]; //!< origin of damage action + + float minRadius; //!< inner radius of damage action + float maxRadius; //!< outer radius of damage action }; /** diff --git a/sdk/extensions/shaders/source/NvBlastExtDamageShaders.cpp b/sdk/extensions/shaders/source/NvBlastExtDamageShaders.cpp new file mode 100644 index 0000000..8027447 --- /dev/null +++ b/sdk/extensions/shaders/source/NvBlastExtDamageShaders.cpp @@ -0,0 +1,368 @@ +// 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 "NvBlastExtDamageShaders.h" +#include "NvBlastIndexFns.h" +#include "NvBlastMath.h" +#include "NvBlastGeometry.h" +#include "NvBlastAssert.h" +#include "NvBlast.h" +#include <cmath> // for abs() on linux + +using namespace Nv::Blast; +using namespace Nv::Blast::VecMath; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Profiles +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +typedef float(*ProfileFunction)(float, float, float, float); + +float falloffProfile(float min, float max, float x, float f = 1.0f) +{ + if (x > max) return 0.0f; + if (x < min) return f; + + float y = 1.0f - (x - min) / (max - min); + return y * f; +} + +float cutterProfile(float min, float max, float x, float f = 1.0f) +{ + if (x > max || x < min) return 0.0f; + + return f; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Damage Functions +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +typedef float(*DamageFunction)(const float pos[3], const void* damageDescBuffer, uint32_t damageIndex); + +template <ProfileFunction profileFn, typename DescT = NvBlastExtRadialDamageDesc> +float pointDistanceDamage(const float pos[3], const void* damageDescBuffer, uint32_t damageIndex) +{ + const DescT* damageData = reinterpret_cast<const DescT*>(damageDescBuffer); + const DescT& desc = damageData[damageIndex]; + + float relativePosition[3]; + sub(desc.position, pos, relativePosition); + const float distance = sqrtf(dot(relativePosition, relativePosition)); + const float damage = profileFn(desc.minRadius, desc.maxRadius, distance, desc.damage); + return damage; +} + + +// Distance from point 'p' to line segment '(a, b)' +float distanceToSegment(const float p[3], const float a[3], const float b[3]) +{ + float v[3]; + sub(b, a, v); + + float w[3]; + sub(p, a, w); + + const float c1 = dot(v, w); + if (c1 <= 0) + return length(w); + + const float c2 = dot(v, v); + if (c2 < c1) + return dist(p, b); + + const float t = c1 / c2; + mul(v, t); + return dist(v, w); +} + +template <ProfileFunction profileFn> +float segmentDistanceDamage(const float pos[3], const void* damageDescBuffer, uint32_t damageIndex) +{ + const NvBlastExtSegmentRadialDamageDesc* damageData = reinterpret_cast<const NvBlastExtSegmentRadialDamageDesc*>(damageDescBuffer); + const NvBlastExtSegmentRadialDamageDesc& desc = damageData[damageIndex]; + + const float distance = distanceToSegment(pos, desc.position0, desc.position1); + const float damage = profileFn(desc.minRadius, desc.maxRadius, distance, desc.damage); + return damage; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Radial Graph Shader Template +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +template <DamageFunction damageFn> +void RadialProfileGraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastGraphShaderActor* actor, const NvBlastProgramParams* params) +{ + const uint32_t* graphNodeIndexLinks = actor->graphNodeIndexLinks; + const uint32_t firstGraphNodeIndex = actor->firstGraphNodeIndex; + const uint32_t* adjacencyPartition = actor->adjacencyPartition; + const uint32_t* adjacentNodeIndices = actor->adjacentNodeIndices; + const uint32_t* adjacentBondIndices = actor->adjacentBondIndices; + const NvBlastBond* assetBonds = actor->assetBonds; + const float* familyBondHealths = actor->familyBondHealths; + + const uint32_t damageCount = params->damageDescCount; + + uint32_t outCount = 0; + + uint32_t currentNodeIndex = firstGraphNodeIndex; + while (!Nv::Blast::isInvalidIndex(currentNodeIndex)) + { + for (uint32_t adj = adjacencyPartition[currentNodeIndex]; adj < adjacencyPartition[currentNodeIndex + 1]; adj++) + { + uint32_t adjacentNodeIndex = adjacentNodeIndices[adj]; + if (currentNodeIndex < adjacentNodeIndex) + { + uint32_t bondIndex = adjacentBondIndices[adj]; + + // skip bonds that are already broken or were visited already + // TODO: investigate why testing against health > -1.0f seems slower + // could reuse the island edge bitmap instead + if ((familyBondHealths[bondIndex] > 0.0f)) + { + + const NvBlastBond& bond = assetBonds[bondIndex]; + + float totalBondDamage = 0.0f; + + for (uint32_t damageIndex = 0; damageIndex < damageCount; damageIndex++) + { + totalBondDamage += damageFn(bond.centroid, params->damageDescBuffer, damageIndex); + } + + if (totalBondDamage > 0.0f) + { + NvBlastBondFractureData& outCommand = commandBuffers->bondFractures[outCount++]; + outCommand.nodeIndex0 = currentNodeIndex; + outCommand.nodeIndex1 = adjacentNodeIndex; + outCommand.health = totalBondDamage; + } + } + } + } + currentNodeIndex = graphNodeIndexLinks[currentNodeIndex]; + } + + commandBuffers->bondFractureCount = outCount; + commandBuffers->chunkFractureCount = 0; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Radial Single Shader Template +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +template <DamageFunction damageFn> +void RadialProfileSubgraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastSubgraphShaderActor* actor, const NvBlastProgramParams* params) +{ + uint32_t chunkFractureCount = 0; + uint32_t chunkFractureCountMax = commandBuffers->chunkFractureCount; + const uint32_t chunkIndex = actor->chunkIndex; + const NvBlastChunk* assetChunks = actor->assetChunks; + const NvBlastChunk& chunk = assetChunks[chunkIndex]; + + float totalDamage = 0.0f; + for (uint32_t damageIndex = 0; damageIndex < params->damageDescCount; ++damageIndex) + { + totalDamage += damageFn(chunk.centroid, params->damageDescBuffer, damageIndex); + } + + if (totalDamage > 0.0f && chunkFractureCount < chunkFractureCountMax) + { + NvBlastChunkFractureData& frac = commandBuffers->chunkFractures[chunkFractureCount++]; + frac.chunkIndex = chunkIndex; + frac.health = totalDamage; + } + + commandBuffers->bondFractureCount = 0; + commandBuffers->chunkFractureCount = chunkFractureCount; +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Radial Shaders Instantiation +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void NvBlastExtFalloffGraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastGraphShaderActor* actor, const NvBlastProgramParams* params) +{ + RadialProfileGraphShader<pointDistanceDamage<falloffProfile>>(commandBuffers, actor, params); +} + +void NvBlastExtFalloffSubgraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastSubgraphShaderActor* actor, const NvBlastProgramParams* params) +{ + RadialProfileSubgraphShader<pointDistanceDamage<falloffProfile>>(commandBuffers, actor, params); +} + +void NvBlastExtCutterGraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastGraphShaderActor* actor, const NvBlastProgramParams* params) +{ + RadialProfileGraphShader<pointDistanceDamage<cutterProfile>>(commandBuffers, actor, params); +} + +void NvBlastExtCutterSubgraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastSubgraphShaderActor* actor, const NvBlastProgramParams* params) +{ + RadialProfileSubgraphShader<pointDistanceDamage<cutterProfile>>(commandBuffers, actor, params); +} + +void NvBlastExtSegmentFalloffGraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastGraphShaderActor* actor, const NvBlastProgramParams* params) +{ + RadialProfileGraphShader<segmentDistanceDamage<falloffProfile>>(commandBuffers, actor, params); +} + +void NvBlastExtSegmentFalloffSubgraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastSubgraphShaderActor* actor, const NvBlastProgramParams* params) +{ + RadialProfileSubgraphShader<segmentDistanceDamage<falloffProfile>>(commandBuffers, actor, params); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Shear Shader +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void NvBlastExtShearGraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastGraphShaderActor* actor, const NvBlastProgramParams* params) +{ + uint32_t chunkFractureCount = 0; + uint32_t chunkFractureCountMax = commandBuffers->chunkFractureCount; + uint32_t bondFractureCount = 0; + uint32_t bondFractureCountMax = commandBuffers->bondFractureCount; + + for (uint32_t i = 0; i < params->damageDescCount; ++i) + { + const NvBlastExtShearDamageDesc& desc = reinterpret_cast<const NvBlastExtShearDamageDesc*>(params->damageDescBuffer)[i]; + const uint32_t* graphNodeIndexLinks = actor->graphNodeIndexLinks; + const uint32_t firstGraphNodeIndex = actor->firstGraphNodeIndex; + const uint32_t* chunkIndices = actor->chunkIndices; + const uint32_t* adjacencyPartition = actor->adjacencyPartition; + const uint32_t* adjacentNodeIndices = actor->adjacentNodeIndices; + const uint32_t* adjacentBondIndices = actor->adjacentBondIndices; + const NvBlastBond* assetBonds = actor->assetBonds; + const NvBlastChunk* assetChunks = actor->assetChunks; + const float* familyBondHealths = actor->familyBondHealths; + const float* supportChunkHealths = actor->supportChunkHealths; + + uint32_t closestNode = findClosestNode(desc.position + , firstGraphNodeIndex, graphNodeIndexLinks + , adjacencyPartition, adjacentNodeIndices, adjacentBondIndices + , assetBonds, familyBondHealths + , assetChunks, supportChunkHealths, chunkIndices); + + uint32_t nodeIndex = closestNode; + float maxDist = 0.0f; + uint32_t nextNode = invalidIndex<uint32_t>(); + + if (chunkFractureCount < chunkFractureCountMax) + { + const uint32_t chunkIndex = chunkIndices[nodeIndex]; + const NvBlastChunk& chunk = assetChunks[chunkIndex]; + NvBlastChunkFractureData& frac = commandBuffers->chunkFractures[chunkFractureCount++]; + frac.chunkIndex = chunkIndex; + frac.health = pointDistanceDamage<falloffProfile, NvBlastExtShearDamageDesc>(chunk.centroid, params->damageDescBuffer, i); + } + + do { + const uint32_t startIndex = adjacencyPartition[nodeIndex]; + const uint32_t stopIndex = adjacencyPartition[nodeIndex + 1]; + + + for (uint32_t adjacentNodeIndex = startIndex; adjacentNodeIndex < stopIndex; adjacentNodeIndex++) + { + const uint32_t neighbourIndex = adjacentNodeIndices[adjacentNodeIndex]; + const uint32_t bondIndex = adjacentBondIndices[adjacentNodeIndex]; + const NvBlastBond& bond = assetBonds[bondIndex]; + + if (!(familyBondHealths[bondIndex] > 0.0f)) + continue; + + float shear = 1 * std::abs(1 - std::abs(VecMath::dot(desc.normal, bond.normal))); + + float d[3]; VecMath::sub(bond.centroid, desc.position, d); + float ahead = VecMath::dot(d, desc.normal); + if (ahead > maxDist) + { + maxDist = ahead; + nextNode = neighbourIndex; + } + + const float damage = pointDistanceDamage<falloffProfile, NvBlastExtShearDamageDesc>(bond.centroid, params->damageDescBuffer, i); + if (damage > 0.0f && bondFractureCount < bondFractureCountMax) + { + NvBlastBondFractureData& frac = commandBuffers->bondFractures[bondFractureCount++]; + frac.userdata = bond.userData; + frac.nodeIndex0 = nodeIndex; + frac.nodeIndex1 = neighbourIndex; + frac.health = shear * damage; + } + } + + if (nodeIndex == nextNode) + break; + + nodeIndex = nextNode; + } while (!isInvalidIndex(nextNode)); + } + + commandBuffers->bondFractureCount = bondFractureCount; + commandBuffers->chunkFractureCount = chunkFractureCount; +} + +void NvBlastExtShearSubgraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastSubgraphShaderActor* actor, const NvBlastProgramParams* params) +{ + RadialProfileSubgraphShader<pointDistanceDamage<falloffProfile, NvBlastExtShearDamageDesc>>(commandBuffers, actor, params); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Helper Functions +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +bool NvBlastExtDamageActorRadialFalloff(NvBlastActor* actor, NvBlastFractureBuffers* buffers, const NvBlastExtRadialDamageDesc* damageDescBuffer, uint32_t damageDescCount, const NvBlastExtMaterial* material, NvBlastLog logFn, NvBlastTimers* timers) +{ + NvBlastDamageProgram program = + { + NvBlastExtFalloffGraphShader, + NvBlastExtFalloffSubgraphShader + }; + + NvBlastProgramParams params = + { + damageDescBuffer, + damageDescCount, + material + }; + + NvBlastActorGenerateFracture(buffers, actor, program, ¶ms, logFn, timers); + if (buffers->bondFractureCount > 0 || buffers->chunkFractureCount > 0) + { + NvBlastActorApplyFracture(nullptr, actor, buffers, logFn, timers); + return true; + } + + return false; +}
\ No newline at end of file diff --git a/sdk/extensions/shaders/source/NvBlastExtRadialShaders.cpp b/sdk/extensions/shaders/source/NvBlastExtRadialShaders.cpp deleted file mode 100644 index 00d1010..0000000 --- a/sdk/extensions/shaders/source/NvBlastExtRadialShaders.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* -* 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. -*/ - -#include "NvBlastExtDamageShaders.h" -#include "NvBlastIndexFns.h" -#include "NvBlastMath.h" -#include "NvBlastGeometry.h" -#include "NvBlastAssert.h" -#include "NvBlast.h" -#include "stdlib.h" // for abs() on linux - -using namespace Nv::Blast; -using namespace Nv::Blast::VecMath; - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Profiles -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -typedef float(*ProfileFunction)(float, float, float, float); - -float falloffProfile(float min, float max, float x, float f = 1.0f) -{ - if (x > max) return 0.0f; - if (x < min) return f; - - float y = 1.0f - (x - min) / (max - min); - return y * f; -} - -float cutterProfile(float min, float max, float x, float f = 1.0f) -{ - if (x > max || x < min) return 0.0f; - - return f; -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Radial Graph Shader Template -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -template <ProfileFunction profile> -void RadialProfileGraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastGraphShaderActor* actor, const NvBlastProgramParams* params) -{ - const uint32_t* graphNodeIndexLinks = actor->graphNodeIndexLinks; - const uint32_t firstGraphNodeIndex = actor->firstGraphNodeIndex; - const uint32_t* adjacencyPartition = actor->adjacencyPartition; - const uint32_t* adjacentNodeIndices = actor->adjacentNodeIndices; - const uint32_t* adjacentBondIndices = actor->adjacentBondIndices; - const NvBlastBond* assetBonds = actor->assetBonds; - const float* familyBondHealths = actor->familyBondHealths; - - const NvBlastExtRadialDamageDesc* damageData = reinterpret_cast<const NvBlastExtRadialDamageDesc*>(params->damageDescBuffer); - const uint32_t damageCount = params->damageDescCount; - - uint32_t outCount = 0; - - uint32_t currentNodeIndex = firstGraphNodeIndex; - while (!Nv::Blast::isInvalidIndex(currentNodeIndex)) - { - for (uint32_t adj = adjacencyPartition[currentNodeIndex]; adj < adjacencyPartition[currentNodeIndex + 1]; adj++) - { - uint32_t adjacentNodeIndex = adjacentNodeIndices[adj]; - if (currentNodeIndex < adjacentNodeIndex) - { - uint32_t bondIndex = adjacentBondIndices[adj]; - - // skip bonds that are already broken or were visited already - // TODO: investigate why testing against health > -1.0f seems slower - // could reuse the island edge bitmap instead - if ((familyBondHealths[bondIndex] > 0.0f)) - { - - const NvBlastBond& bond = assetBonds[bondIndex]; - - float totalBondDamage = 0.0f; - - for (uint32_t damageIndex = 0; damageIndex < damageCount; damageIndex++) - { - const NvBlastExtRadialDamageDesc& damage = damageData[damageIndex]; - - float relativePosition[3]; - sub(damage.position, bond.centroid, relativePosition); - float distance = sqrtf(dot(relativePosition, relativePosition)); - - float dir[3]; - normal(relativePosition, dir); - - totalBondDamage += profile(damage.minRadius, damage.maxRadius, distance, damage.compressive); - } - - if (totalBondDamage > 0.0f) - { - NvBlastBondFractureData& outCommand = commandBuffers->bondFractures[outCount++]; - outCommand.nodeIndex0 = currentNodeIndex; - outCommand.nodeIndex1 = adjacentNodeIndex; - outCommand.health = totalBondDamage; - } - } - } - } - currentNodeIndex = graphNodeIndexLinks[currentNodeIndex]; - } - - commandBuffers->bondFractureCount = outCount; - commandBuffers->chunkFractureCount = 0; -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Radial Single Shader Template -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -template <ProfileFunction profile> -void RadialProfileSubgraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastSubgraphShaderActor* actor, const NvBlastProgramParams* params) -{ - uint32_t chunkFractureCount = 0; - const uint32_t chunkIndex = actor->chunkIndex; - const NvBlastChunk* assetChunks = actor->assetChunks; - const NvBlastChunk& chunk = assetChunks[chunkIndex]; - - float totalDamage = 0.0f; - for (uint32_t i = 0; i < params->damageDescCount; ++i) - { - const NvBlastExtRadialDamageDesc& damage = reinterpret_cast<const NvBlastExtRadialDamageDesc*>(params->damageDescBuffer)[i]; - - float relativePosition[3]; - sub(damage.position, chunk.centroid, relativePosition); - float distance = sqrtf(dot(relativePosition, relativePosition)); - - totalDamage += profile(damage.minRadius, damage.maxRadius, distance, damage.compressive); - } - - if (totalDamage > 0.0f) - { - NvBlastChunkFractureData& frac = commandBuffers->chunkFractures[chunkFractureCount++]; - frac.chunkIndex = chunkIndex; - frac.health = totalDamage; - } - - commandBuffers->bondFractureCount = 0; - commandBuffers->chunkFractureCount = chunkFractureCount; -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Shader Instantiation -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void NvBlastExtFalloffGraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastGraphShaderActor* actor, const NvBlastProgramParams* params) -{ - RadialProfileGraphShader<falloffProfile>(commandBuffers, actor, params); -} - -void NvBlastExtFalloffSubgraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastSubgraphShaderActor* actor, const NvBlastProgramParams* params) -{ - RadialProfileSubgraphShader<falloffProfile>(commandBuffers, actor, params); -} - -void NvBlastExtCutterGraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastGraphShaderActor* actor, const NvBlastProgramParams* params) -{ - RadialProfileGraphShader<cutterProfile>(commandBuffers, actor, params); -} - -void NvBlastExtCutterSubgraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastSubgraphShaderActor* actor, const NvBlastProgramParams* params) -{ - RadialProfileSubgraphShader<cutterProfile>(commandBuffers, actor, params); -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Helper Functions -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -bool NvBlastExtDamageActorRadialFalloff(NvBlastActor* actor, NvBlastFractureBuffers* buffers, const NvBlastExtRadialDamageDesc* damageDescBuffer, uint32_t damageDescCount, const NvBlastExtMaterial* material, NvBlastLog logFn, NvBlastTimers* timers) -{ - NvBlastDamageProgram program = - { - NvBlastExtFalloffGraphShader, - NvBlastExtFalloffSubgraphShader - }; - - NvBlastProgramParams params = - { - damageDescBuffer, - damageDescCount, - material - }; - - NvBlastActorGenerateFracture(buffers, actor, program, ¶ms, logFn, timers); - if (buffers->bondFractureCount > 0 || buffers->chunkFractureCount > 0) - { - NvBlastActorApplyFracture(nullptr, actor, buffers, logFn, timers); - return true; - } - - return false; -}
\ No newline at end of file diff --git a/sdk/extensions/shaders/source/NvBlastExtShearShaders.cpp b/sdk/extensions/shaders/source/NvBlastExtShearShaders.cpp deleted file mode 100644 index 26707e1..0000000 --- a/sdk/extensions/shaders/source/NvBlastExtShearShaders.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* -* 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. -*/ - -#include "NvBlastExtDamageShaders.h" -#include "NvBlastIndexFns.h" -#include "NvBlastMath.h" -#include "NvBlastGeometry.h" -#include "NvBlastAssert.h" -#include "stdlib.h" // for abs() on linux - -using namespace Nv::Blast; -using namespace Nv::Blast::VecMath; - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Graph Shader -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void NvBlastExtShearGraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastGraphShaderActor* actor, const NvBlastProgramParams* params) -{ - const NvBlastExtMaterial* materialProperties = reinterpret_cast<const NvBlastExtMaterial*>(params->material); - const float graphChunkThreshold = materialProperties->graphChunkThreshold; - const float bondTangentialThreshold = materialProperties->bondTangentialThreshold; - const float damageAttenuation = 1.0f - materialProperties->damageAttenuation; - - uint32_t chunkFractureCount = 0; - uint32_t chunkFractureCountMax = commandBuffers->chunkFractureCount; - uint32_t bondFractureCount = 0; - uint32_t bondFractureCountMax = commandBuffers->bondFractureCount; - - for (uint32_t i = 0; i < params->damageDescCount; ++i) - { - const NvBlastExtShearDamageDesc& damage = reinterpret_cast<const NvBlastExtShearDamageDesc*>(params->damageDescBuffer)[i]; - - const uint32_t* graphNodeIndexLinks = actor->graphNodeIndexLinks; - const uint32_t firstGraphNodeIndex = actor->firstGraphNodeIndex; - const uint32_t* chunkIndices = actor->chunkIndices; - const uint32_t* adjacencyPartition = actor->adjacencyPartition; - const uint32_t* adjacentNodeIndices = actor->adjacentNodeIndices; - const uint32_t* adjacentBondIndices = actor->adjacentBondIndices; - const NvBlastBond* assetBonds = actor->assetBonds; - const float* familyBondHealths = actor->familyBondHealths; - - uint32_t closestNode = findNodeByPositionLinked(damage.position, firstGraphNodeIndex, graphNodeIndexLinks, adjacencyPartition, adjacentNodeIndices, adjacentBondIndices, assetBonds, familyBondHealths); - NVBLAST_ASSERT(!isInvalidIndex(closestNode)); - - float damageDir[3]; - float damageMag = VecMath::normal(damage.shear, damageDir); - - uint32_t nodeIndex = closestNode; - float maxDist = 0.0f; - uint32_t nextNode = invalidIndex<uint32_t>(); - - if (damageMag > graphChunkThreshold && chunkFractureCount < chunkFractureCountMax) - { - NvBlastChunkFractureData& frac = commandBuffers->chunkFractures[chunkFractureCount++]; - frac.chunkIndex = chunkIndices[nodeIndex]; - frac.health = damageMag * 2; - } - - do { - const uint32_t startIndex = adjacencyPartition[nodeIndex]; - const uint32_t stopIndex = adjacencyPartition[nodeIndex + 1]; - - - for (uint32_t adjacentNodeIndex = startIndex; adjacentNodeIndex < stopIndex; adjacentNodeIndex++) - { - const uint32_t neighbourIndex = adjacentNodeIndices[adjacentNodeIndex]; - const uint32_t bondIndex = adjacentBondIndices[adjacentNodeIndex]; - const NvBlastBond& bond = assetBonds[bondIndex]; - - if (!(familyBondHealths[bondIndex] > 0.0f)) - continue; - - float shear = 1 * abs(1 - abs(VecMath::dot(damage.shear, bond.normal))); - - float d[3]; VecMath::sub(bond.centroid, damage.position, d); - float ahead = VecMath::dot(d, damage.shear); - if (ahead > maxDist) - { - maxDist = ahead; - nextNode = neighbourIndex; - } - - if (shear > bondTangentialThreshold && bondFractureCount < bondFractureCountMax) - { - NvBlastBondFractureData& frac = commandBuffers->bondFractures[bondFractureCount++]; - frac.userdata = bond.userData; - frac.nodeIndex0 = nodeIndex; - frac.nodeIndex1 = neighbourIndex; - frac.health = shear; - } - } - - if (nodeIndex == nextNode) - break; - - nodeIndex = nextNode; - - damageMag *= damageAttenuation; - } while (!isInvalidIndex(nextNode)); - } - - commandBuffers->bondFractureCount = bondFractureCount; - commandBuffers->chunkFractureCount = chunkFractureCount; -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Single Shader -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void NvBlastExtShearSubgraphShader(NvBlastFractureBuffers* commandBuffers, const NvBlastSubgraphShaderActor* actor, const NvBlastProgramParams* params) -{ - const NvBlastExtMaterial* materialProperties = reinterpret_cast<const NvBlastExtMaterial*>(params->material); - - uint32_t chunkFractureCount = 0; - - float totalDamage = 0.0f; - for (uint32_t i = 0; i < params->damageDescCount; ++i) - { - const NvBlastExtShearDamageDesc& damage = reinterpret_cast<const NvBlastExtShearDamageDesc*>(params->damageDescBuffer)[i]; - - float damageDir[3]; - float damageMag = VecMath::normal(damage.shear, damageDir); - - if (damageMag > materialProperties->singleChunkThreshold) - { - totalDamage += damageMag * 2; - } - } - - if (totalDamage > 0.0f) - { - NvBlastChunkFractureData& frac = commandBuffers->chunkFractures[chunkFractureCount++]; - frac.chunkIndex = actor->chunkIndex; - frac.health = totalDamage; - } - - commandBuffers->bondFractureCount = 0; - commandBuffers->chunkFractureCount = chunkFractureCount; -} |