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/physx/source/physics/NvBlastExtPxStressSolverImpl.cpp | |
| parent | Added screens to welcome page (diff) | |
| download | blast-236f03c0b9a4982328ed1201978f7f69d192d9b2.tar.xz blast-236f03c0b9a4982328ed1201978f7f69d192d9b2.zip | |
Blast 1.1 release (windows / linux)
see docs/release_notes.txt for details
Diffstat (limited to 'sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.cpp')
| -rw-r--r-- | sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.cpp | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.cpp b/sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.cpp new file mode 100644 index 0000000..2b331d3 --- /dev/null +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.cpp @@ -0,0 +1,229 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2016-2017 NVIDIA Corporation. All rights reserved. + + +#include "NvBlastExtPxStressSolverImpl.h" +#include "NvBlastExtPxAsset.h" +#include "NvBlastExtPxFamily.h" +#include "NvBlastExtPxActor.h" +#include "NvBlastAssert.h" +#include "NvBlastIndexFns.h" + +#include "NvBlastTkAsset.h" +#include "NvBlastTkActor.h" +#include "NvBlastTkFamily.h" + +#include "PxScene.h" +#include "PxRigidDynamic.h" + +#define USE_PHYSX_NODE_INFO 1 + + +namespace Nv +{ +namespace Blast +{ + +using namespace physx; + + +ExtPxStressSolverImpl::ExtPxStressSolverImpl(ExtPxFamily& family, ExtStressSolverSettings settings) + : m_family(family) +{ + NvBlastFamily* familyLL = const_cast<NvBlastFamily*>(family.getTkFamily().getFamilyLL()); + NVBLAST_ASSERT(familyLL); + m_solver = ExtStressSolver::create(*familyLL, settings); + + const TkAsset* tkAsset = m_family.getTkFamily().getAsset(); + const ExtPxAsset& asset = m_family.getPxAsset(); + const ExtPxChunk* chunks = asset.getChunks(); + const ExtPxSubchunk* subChunks = asset.getSubchunks(); + const NvBlastSupportGraph graph = tkAsset->getGraph(); + const uint32_t chunkCount = tkAsset->getChunkCount(); + + TkActor* tkActor; + m_family.getTkFamily().getActors(&tkActor, 1); + const float* bondHealths = tkActor->getBondHealths(); + +#if USE_PHYSX_NODE_INFO + // traverse graph and fill node info, + // essentially it does the same as m_solver->setAllNodesInfoFromLL() but fills mass, volume, transform from physx + // and it also uses ExtPxChunk isStatic flag in addition to 'world' node in LL + for (uint32_t node0 = 0; node0 < graph.nodeCount; ++node0) + { + uint32_t chunkIndex0 = graph.chunkIndices[node0]; + const ExtPxChunk* chunk0 = chunkIndex0 < chunkCount ? &chunks[chunkIndex0] : nullptr; + bool isChunkStatic = true; + + if (chunk0) + { + isChunkStatic = chunk0->isStatic; + for (uint32_t adjacencyIndex = graph.adjacencyPartition[node0]; adjacencyIndex < graph.adjacencyPartition[node0 + 1]; adjacencyIndex++) + { + uint32_t bondIndex = graph.adjacentBondIndices[adjacencyIndex]; + if (bondHealths[bondIndex] <= 0.0f) + continue; + uint32_t node1 = graph.adjacentNodeIndices[adjacencyIndex]; + uint32_t chunkIndex1 = graph.chunkIndices[node1]; + if (chunkIndex1 < chunkCount) + { + const ExtPxChunk& chunk1 = chunks[chunkIndex1]; + + if (chunk1.subchunkCount == 0 || chunk1.isStatic) + { + isChunkStatic |= chunk1.isStatic; + continue; + } + } + else + { + isChunkStatic = true; + break; + } + } + } + + // fill node info + float mass; + float volume; + PxVec3 localPos; + if (chunk0 && chunk0->subchunkCount > 0) + { + const ExtPxSubchunk& subChunk = subChunks[chunk0->firstSubchunkIndex]; + PxVec3 localCenterOfMass; + PxMat33 intertia; + PxVec3 scale = subChunk.geometry.scale.scale; + subChunk.geometry.convexMesh->getMassInformation(mass, intertia, localCenterOfMass); + mass *= scale.x * scale.y * scale.z; + const PxTransform& chunk0LocalTransform = subChunk.transform; + localPos = chunk0LocalTransform.transform(localCenterOfMass); + volume = mass / 1.0f; // unit density + } + else + { + mass = 0.0f; + volume = 0.0f; + localPos = PxVec3(PxZero); + isChunkStatic = true; + } + m_solver->setNodeInfo(node0, mass, volume, localPos, isChunkStatic); + } +#else + m_solver->setAllNodesInfoFromLL(); +#endif + + // notify initial actor's created + InlineArray<ExtPxActor*, 4>::type actors;; + actors.resize(m_family.getActorCount()); + m_family.getActors(actors.begin(), actors.size()); + for (const auto actor : actors) + { + onActorCreated(m_family, *actor); + } + + m_family.subscribe(*this); +} + +ExtPxStressSolverImpl::~ExtPxStressSolverImpl() +{ + m_family.unsubscribe(*this); + m_solver->release(); +} + +ExtPxStressSolver* ExtPxStressSolver::create(ExtPxFamily& family, ExtStressSolverSettings settings) +{ + return NVBLAST_NEW(ExtPxStressSolverImpl) (family, settings); +} + +void ExtPxStressSolverImpl::release() +{ + NVBLAST_DELETE(this, ExtPxStressSolverImpl); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Update Wrapper +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void ExtPxStressSolverImpl::update(bool doDamage) +{ + for (auto it = m_actors.getIterator(); !it.done(); ++it) + { + const ExtPxActor* actor = *it; + + PxRigidDynamic& rigidDynamic = actor->getPhysXActor(); + const bool isStatic = rigidDynamic.getRigidBodyFlags() & PxRigidBodyFlag::eKINEMATIC; + if (isStatic) + { + PxVec3 gravity = rigidDynamic.getScene()->getGravity(); + PxVec3 localGravity = rigidDynamic.getGlobalPose().rotateInv(gravity); + + m_solver->addGravityForce(*actor->getTkActor().getActorLL(), localGravity); + } + else + { + PxVec3 localCenterMass = rigidDynamic.getCMassLocalPose().p; + PxVec3 localAngularVelocity = rigidDynamic.getGlobalPose().rotateInv(rigidDynamic.getAngularVelocity()); + m_solver->addAngularVelocity(*actor->getTkActor().getActorLL(), localCenterMass, localAngularVelocity); + } + } + + m_solver->update(); + + if (doDamage && m_solver->getOverstressedBondCount() > 0) + { + NvBlastFractureBuffers commands; + m_solver->generateFractureCommands(commands); + if (commands.bondFractureCount > 0) + { + m_family.getTkFamily().applyFracture(&commands); + } + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Actors +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void ExtPxStressSolverImpl::onActorCreated(ExtPxFamily& /*family*/, ExtPxActor& actor) +{ + if (m_solver->notifyActorCreated(*actor.getTkActor().getActorLL())) + { + m_actors.insert(&actor); + } +} + +void ExtPxStressSolverImpl::onActorDestroyed(ExtPxFamily& /*family*/, ExtPxActor& actor) +{ + m_solver->notifyActorDestroyed(*actor.getTkActor().getActorLL()); + m_actors.erase(&actor); +} + + +} // namespace Blast +} // namespace Nv |