diff options
| author | Bryan Galdrikian <[email protected]> | 2018-05-31 11:36:08 -0700 |
|---|---|---|
| committer | Bryan Galdrikian <[email protected]> | 2018-05-31 11:36:08 -0700 |
| commit | 7115f60b91b5717d90f643fd692010905c7004db (patch) | |
| tree | effd68c6978751c517d54c2f2bb5bb6e7dc93e18 /sdk/extensions/physx/source | |
| parent | Updating BlastTool zip (diff) | |
| download | blast-1.1.3_rc1.tar.xz blast-1.1.3_rc1.zip | |
Blast 1.1.3. See docs/release_notes.txt.v1.1.3_rc1
Diffstat (limited to 'sdk/extensions/physx/source')
14 files changed, 3041 insertions, 3041 deletions
diff --git a/sdk/extensions/physx/source/physics/NvBlastExtImpactDamageManager.cpp b/sdk/extensions/physx/source/physics/NvBlastExtImpactDamageManager.cpp index 205c77e..7f86021 100644..100755 --- a/sdk/extensions/physx/source/physics/NvBlastExtImpactDamageManager.cpp +++ b/sdk/extensions/physx/source/physics/NvBlastExtImpactDamageManager.cpp @@ -1,489 +1,489 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#include "NvBlastExtImpactDamageManager.h" -#include "NvBlastExtPxManager.h" -#include "NvBlastExtPxFamily.h" -#include "NvBlastExtPxActor.h" -#include "NvBlastExtPxAsset.h" -#include "NvBlastExtPxListener.h" - -#include "NvBlastAssert.h" - -#include "NvBlastExtDamageShaders.h" -#include "NvBlastArray.h" - -#include "PxRigidDynamic.h" -#include "PxSimulationEventCallback.h" -#include "PxRigidBodyExt.h" - -#include "NvBlastTkFramework.h" -#include "NvBlastTkActor.h" -#include "NvBlastTkFamily.h" -#include "NvBlastTkAsset.h" - - -namespace Nv -{ -namespace Blast -{ - -using namespace physx; - -const float MIN_IMPACT_VELOCITY_SQUARED = 1.0f; - - -class ExtImpactDamageManagerImpl final : public ExtImpactDamageManager -{ -public: - ExtImpactDamageManagerImpl(ExtPxManager* pxManager, ExtImpactSettings settings) - : m_pxManager(pxManager), m_settings(settings), m_listener(this), m_usePxUserData(m_pxManager->isPxUserDataUsed()) - { - NVBLAST_ASSERT_WITH_MESSAGE(pxManager != nullptr, "ExtImpactDamageManager creation: input ExtPxManager is nullptr."); - m_pxManager->subscribe(m_listener); - - m_impactDamageBuffer.reserve(32); - } - - ~ExtImpactDamageManagerImpl() - { - m_pxManager->unsubscribe(m_listener); - } - - virtual void release() override - { - NVBLAST_DELETE(this, ExtImpactDamageManagerImpl); - } - - - //////// interface //////// - - virtual void setSettings(const ExtImpactSettings& settings) override - { - m_settings = settings; - } - - virtual void onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, uint32_t nbPairs) override; - - virtual void applyDamage() override; - - - //////// public methods //////// - - void queueImpactDamage(ExtPxActor* actor, PxVec3 force, PxVec3 position, PxShape* shape) - { - ImpactDamageData data = { actor, force, position, shape }; - m_impactDamageBuffer.pushBack(data); - } - - -private: - //////// physics manager listener //////// - - class PxManagerListener : public ExtPxListener - { - public: - PxManagerListener(ExtImpactDamageManagerImpl* manager) : m_manager(manager) {} - - virtual void onActorCreated(ExtPxFamily&, ExtPxActor&) override {} - virtual void onActorDestroyed(ExtPxFamily& family, ExtPxActor& actor) override - { - NV_UNUSED(family); - - // filter out actor from queued buffer - auto& buffer = m_manager->m_impactDamageBuffer; - for (int32_t i = 0; i < (int32_t)buffer.size(); ++i) - { - if (buffer[i].actor == &actor) - { - buffer.replaceWithLast(i); - i--; - } - } - } - private: - ExtImpactDamageManagerImpl* m_manager; - }; - - - //////// private methods //////// - - void ensureBuffersSize(ExtPxActor* actor); - void damageActor(ExtPxActor* actor, PxShape* shape, PxVec3 position, PxVec3 force); - - - //////// data //////// - - ExtPxManager* m_pxManager; - ExtImpactSettings m_settings; - PxManagerListener m_listener; - Array<PxContactPairPoint>::type m_pairPointBuffer; - bool m_usePxUserData; - - struct ImpactDamageData - { - ExtPxActor* actor; - PxVec3 force; - PxVec3 position; - PxShape* shape; - }; - - Array<ImpactDamageData>::type m_impactDamageBuffer; - - NvBlastFractureBuffers m_fractureBuffers; - Array<uint8_t>::type m_fractureData; -}; - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// ExtImpactDamageManagerImpl -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -ExtImpactDamageManager* ExtImpactDamageManager::create(ExtPxManager* pxManager, ExtImpactSettings settings) -{ - return NVBLAST_NEW(ExtImpactDamageManagerImpl) (pxManager, settings); -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// onContact callback call -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void ExtImpactDamageManagerImpl::onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, uint32_t nbPairs) -{ - if (pairHeader.flags & physx::PxContactPairHeaderFlag::eREMOVED_ACTOR_0 || - pairHeader.flags & physx::PxContactPairHeaderFlag::eREMOVED_ACTOR_1 || - pairHeader.actors[0] == nullptr || - pairHeader.actors[1] == nullptr) - { - return; - } - - PxRigidActor* rigidActor0 = pairHeader.actors[0]; - PxRigidActor* rigidActor1 = pairHeader.actors[1]; - - ExtPxActor* actors[2]; - - if (m_usePxUserData) - { - actors[0] = (ExtPxActor*)rigidActor0->userData; - actors[1] = (ExtPxActor*)rigidActor1->userData; - } - else - { - PxRigidDynamic* rigidDynamic0 = rigidActor0->is<PxRigidDynamic>(); - PxRigidDynamic* rigidDynamic1 = rigidActor1->is<PxRigidDynamic>(); - actors[0] = rigidDynamic0 ? m_pxManager->getActorFromPhysXActor(*rigidDynamic0) : nullptr; - actors[1] = rigidDynamic1 ? m_pxManager->getActorFromPhysXActor(*rigidDynamic1) : nullptr; - } - - - // check one of them is blast actor - if (actors[0] == nullptr && actors[1] == nullptr) - { - return; - } - - // self-collision check - if (actors[0] != nullptr && actors[1] != nullptr) - { - if (&actors[0]->getFamily() == &actors[1]->getFamily() && !m_settings.isSelfCollissionEnabled) - return; - } - - for (uint32_t pairIdx = 0; pairIdx < nbPairs; pairIdx++) - { - const PxContactPair& currentPair = pairs[pairIdx]; - - if (currentPair.flags & physx::PxContactPairFlag::eREMOVED_SHAPE_0 || - currentPair.flags & physx::PxContactPairFlag::eREMOVED_SHAPE_1 || - currentPair.shapes[0] == nullptr || - currentPair.shapes[1] == nullptr) - { - continue; - } - - float masses[2] = { 0, 0 }; - { - for (int i = 0; i < 2; ++i) - { - PxRigidDynamic* rigidDynamic = pairHeader.actors[i]->is<physx::PxRigidDynamic>(); - if (rigidDynamic) - { - if (!(rigidDynamic->getRigidBodyFlags() & physx::PxRigidBodyFlag::eKINEMATIC)) - { - masses[i] = rigidDynamic->getMass(); - } - } - } - }; - - float reducedMass; - if (masses[0] == 0.0f) - { - reducedMass = masses[1]; - } - else if (masses[1] == 0.0f) - { - reducedMass = masses[0]; - } - else - { - reducedMass = masses[0] * masses[1] / (masses[0] + masses[1]); - } - - - PxVec3 destructibleForces[2] = { PxVec3(0.0f), PxVec3(0.0f) }; - PxVec3 avgContactPosition = PxVec3(0.0f); - PxVec3 avgContactNormal = PxVec3(0.0f); - uint32_t numContacts = 0; - - m_pairPointBuffer.resize(currentPair.contactCount); - uint32_t numContactsInStream = currentPair.contactCount > 0 ? currentPair.extractContacts(m_pairPointBuffer.begin(), currentPair.contactCount) : 0; - - for (uint32_t contactIdx = 0; contactIdx < numContactsInStream; contactIdx++) - { - PxContactPairPoint& currentPoint = m_pairPointBuffer[contactIdx]; - - const PxVec3& patchNormal = currentPoint.normal; - const PxVec3& position = currentPoint.position; - PxVec3 velocities[2] = { PxVec3(0.0f), PxVec3(0.0f) }; - for (int i = 0; i < 2; ++i) - { - PxRigidBody* rigidBody = pairHeader.actors[i]->is<physx::PxRigidBody>(); - if (rigidBody) - { - velocities[i] = physx::PxRigidBodyExt::getVelocityAtPos(*rigidBody, position); - } - } - - const PxVec3 velocityDelta = velocities[0] - velocities[1]; - if (velocityDelta.magnitudeSquared() >= MIN_IMPACT_VELOCITY_SQUARED || reducedMass == 0.0f) // If reduced mass == 0, this is kineamtic vs. kinematic. Generate damage. - { - for (int i = 0; i < 2; ++i) - { - if (actors[i]) - { - // this is not really physically correct, but at least its deterministic... - destructibleForces[i] += (patchNormal * patchNormal.dot(velocityDelta)) * reducedMass * (i ? 1.0f : -1.0f); - } - } - avgContactPosition += position; - avgContactNormal += patchNormal; - numContacts++; - } - } - - if (numContacts) - { - avgContactPosition /= (float)numContacts; - avgContactNormal.normalize(); - for (uint32_t i = 0; i < 2; i++) - { - const PxVec3 force = destructibleForces[i] / (float)numContacts; - ExtPxActor* actor = actors[i]; - if (actor != nullptr) - { - if (!force.isZero()) - { - queueImpactDamage(actor, force, avgContactPosition, currentPair.shapes[i]); - } - else if (reducedMass == 0.0f) // Handle kinematic vs. kinematic - { - // holy molly - } - } - } - } - } -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// ExtImpactDamageManager damage processing -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void ExtImpactDamageManagerImpl::applyDamage() -{ - const auto damageFn = m_settings.damageFunction; - const auto damageFnData = m_settings.damageFunctionData; - - for (const ImpactDamageData& data : m_impactDamageBuffer) - { - PxTransform t(data.actor->getPhysXActor().getGlobalPose().getInverse()); - PxVec3 force = t.rotate(data.force); - PxVec3 position = t.transform(data.position); - - if (!damageFn || !damageFn(damageFnData, data.actor, data.shape, position, force)) - { - damageActor(data.actor, data.shape, position, force); - } - } - m_impactDamageBuffer.clear(); -} - -void ExtImpactDamageManagerImpl::ensureBuffersSize(ExtPxActor* actor) -{ - const TkAsset* tkAsset = actor->getTkActor().getAsset(); - const uint32_t chunkCount = tkAsset->getChunkCount(); - const uint32_t bondCount = tkAsset->getBondCount(); - - m_fractureBuffers.bondFractureCount = bondCount; - m_fractureBuffers.chunkFractureCount = chunkCount; - m_fractureData.resize((uint32_t)(m_fractureBuffers.bondFractureCount*sizeof(NvBlastBondFractureData) + m_fractureBuffers.chunkFractureCount*sizeof(NvBlastChunkFractureData))); // chunk count + bond count - m_fractureBuffers.chunkFractures = reinterpret_cast<NvBlastChunkFractureData*>(m_fractureData.begin()); - m_fractureBuffers.bondFractures = reinterpret_cast<NvBlastBondFractureData*>(&m_fractureData.begin()[m_fractureBuffers.chunkFractureCount*sizeof(NvBlastChunkFractureData)]); -} - -void ExtImpactDamageManagerImpl::damageActor(ExtPxActor* actor, PxShape* /*shape*/, PxVec3 position, PxVec3 force) -{ - ensureBuffersSize(actor); - - const float damage = m_settings.hardness > 0.f ? force.magnitude() / m_settings.hardness : 0.f; - - const NvBlastExtMaterial* material = actor->getFamily().getMaterial(); - if (!material) - { - return; - } - - float normalizedDamage = material->getNormalizedDamage(damage); - if (normalizedDamage == 0.f || normalizedDamage < m_settings.damageThresholdMin) - { - return; - } - normalizedDamage = PxClamp<float>(normalizedDamage, 0, m_settings.damageThresholdMax); - - const PxVec3 normal = force.getNormalized(); - const float minDistance = m_settings.damageRadiusMax * normalizedDamage; - const float maxDistance = minDistance * PxClamp<float>(m_settings.damageFalloffRadiusFactor, 1, 32); - - NvBlastExtProgramParams programParams(nullptr); - programParams.material = material; - programParams.accelerator = actor->getFamily().getPxAsset().getAccelerator(); - NvBlastDamageProgram program; - - if (m_settings.shearDamage) - { - NvBlastExtShearDamageDesc desc = { - normalizedDamage, - { normal[0], normal[1], normal[2] }, - { position[0], position[1], position[2] }, - minDistance, - maxDistance - }; - - programParams.damageDesc = &desc; - - program.graphShaderFunction = NvBlastExtShearGraphShader; - program.subgraphShaderFunction = NvBlastExtShearSubgraphShader; - - NvBlastFractureBuffers fractureEvents = m_fractureBuffers; - actor->getTkActor().generateFracture(&fractureEvents, program, &programParams); - actor->getTkActor().applyFracture(nullptr, &fractureEvents); - } - else - { - NvBlastExtImpactSpreadDamageDesc desc = { - normalizedDamage, - { position[0], position[1], position[2] }, - minDistance, - maxDistance - }; - - programParams.damageDesc = &desc; - - program.graphShaderFunction = NvBlastExtImpactSpreadGraphShader; - program.subgraphShaderFunction = NvBlastExtImpactSpreadSubgraphShader; - - NvBlastFractureBuffers fractureEvents = m_fractureBuffers; - actor->getTkActor().generateFracture(&fractureEvents, program, &programParams); - actor->getTkActor().applyFracture(nullptr, &fractureEvents); - } -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Filter Shader -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -PxFilterFlags ExtImpactDamageManager::FilterShader( - PxFilterObjectAttributes attributes0, - PxFilterData filterData0, - PxFilterObjectAttributes attributes1, - PxFilterData filterData1, - PxPairFlags& pairFlags, - const void* constantBlock, - uint32_t constantBlockSize) -{ - PX_UNUSED(constantBlock); - PX_UNUSED(constantBlockSize); - // let triggers through - if (PxFilterObjectIsTrigger(attributes0) || PxFilterObjectIsTrigger(attributes1)) - { - pairFlags = PxPairFlag::eTRIGGER_DEFAULT; - return PxFilterFlags(); - } - - if ((PxFilterObjectIsKinematic(attributes0) || PxFilterObjectIsKinematic(attributes1)) && - (PxGetFilterObjectType(attributes0) == PxFilterObjectType::eRIGID_STATIC || PxGetFilterObjectType(attributes1) == PxFilterObjectType::eRIGID_STATIC)) - { - return PxFilterFlag::eSUPPRESS; - } - - // use a group-based mechanism if the first two filter data words are not 0 - uint32_t f0 = filterData0.word0 | filterData0.word1; - uint32_t f1 = filterData1.word0 | filterData1.word1; - if (f0 && f1 && !(filterData0.word0&filterData1.word1 || filterData1.word0&filterData0.word1)) - return PxFilterFlag::eSUPPRESS; - - // determine if we should suppress notification - const bool suppressNotify = ((filterData0.word3 | filterData1.word3) & ExtPxManager::LEAF_CHUNK) != 0; - - pairFlags = PxPairFlag::eCONTACT_DEFAULT; - if (!suppressNotify) - { - pairFlags = pairFlags - | PxPairFlag::eNOTIFY_CONTACT_POINTS - | PxPairFlag::eNOTIFY_THRESHOLD_FORCE_PERSISTS - | PxPairFlag::eNOTIFY_THRESHOLD_FORCE_FOUND - | PxPairFlag::eNOTIFY_TOUCH_FOUND - | PxPairFlag::eNOTIFY_TOUCH_PERSISTS; - } - - // eSOLVE_CONTACT is invalid with kinematic pairs - if (PxFilterObjectIsKinematic(attributes0) && PxFilterObjectIsKinematic(attributes1)) - { - pairFlags &= ~PxPairFlag::eSOLVE_CONTACT; - } - - return PxFilterFlags(); -} - -} // namespace Blast -} // namespace Nv +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#include "NvBlastExtImpactDamageManager.h"
+#include "NvBlastExtPxManager.h"
+#include "NvBlastExtPxFamily.h"
+#include "NvBlastExtPxActor.h"
+#include "NvBlastExtPxAsset.h"
+#include "NvBlastExtPxListener.h"
+
+#include "NvBlastAssert.h"
+
+#include "NvBlastExtDamageShaders.h"
+#include "NvBlastArray.h"
+
+#include "PxRigidDynamic.h"
+#include "PxSimulationEventCallback.h"
+#include "PxRigidBodyExt.h"
+
+#include "NvBlastTkFramework.h"
+#include "NvBlastTkActor.h"
+#include "NvBlastTkFamily.h"
+#include "NvBlastTkAsset.h"
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+using namespace physx;
+
+const float MIN_IMPACT_VELOCITY_SQUARED = 1.0f;
+
+
+class ExtImpactDamageManagerImpl final : public ExtImpactDamageManager
+{
+public:
+ ExtImpactDamageManagerImpl(ExtPxManager* pxManager, ExtImpactSettings settings)
+ : m_pxManager(pxManager), m_settings(settings), m_listener(this), m_usePxUserData(m_pxManager->isPxUserDataUsed())
+ {
+ NVBLAST_ASSERT_WITH_MESSAGE(pxManager != nullptr, "ExtImpactDamageManager creation: input ExtPxManager is nullptr.");
+ m_pxManager->subscribe(m_listener);
+
+ m_impactDamageBuffer.reserve(32);
+ }
+
+ ~ExtImpactDamageManagerImpl()
+ {
+ m_pxManager->unsubscribe(m_listener);
+ }
+
+ virtual void release() override
+ {
+ NVBLAST_DELETE(this, ExtImpactDamageManagerImpl);
+ }
+
+
+ //////// interface ////////
+
+ virtual void setSettings(const ExtImpactSettings& settings) override
+ {
+ m_settings = settings;
+ }
+
+ virtual void onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, uint32_t nbPairs) override;
+
+ virtual void applyDamage() override;
+
+
+ //////// public methods ////////
+
+ void queueImpactDamage(ExtPxActor* actor, PxVec3 force, PxVec3 position, PxShape* shape)
+ {
+ ImpactDamageData data = { actor, force, position, shape };
+ m_impactDamageBuffer.pushBack(data);
+ }
+
+
+private:
+ //////// physics manager listener ////////
+
+ class PxManagerListener : public ExtPxListener
+ {
+ public:
+ PxManagerListener(ExtImpactDamageManagerImpl* manager) : m_manager(manager) {}
+
+ virtual void onActorCreated(ExtPxFamily&, ExtPxActor&) override {}
+ virtual void onActorDestroyed(ExtPxFamily& family, ExtPxActor& actor) override
+ {
+ NV_UNUSED(family);
+
+ // filter out actor from queued buffer
+ auto& buffer = m_manager->m_impactDamageBuffer;
+ for (int32_t i = 0; i < (int32_t)buffer.size(); ++i)
+ {
+ if (buffer[i].actor == &actor)
+ {
+ buffer.replaceWithLast(i);
+ i--;
+ }
+ }
+ }
+ private:
+ ExtImpactDamageManagerImpl* m_manager;
+ };
+
+
+ //////// private methods ////////
+
+ void ensureBuffersSize(ExtPxActor* actor);
+ void damageActor(ExtPxActor* actor, PxShape* shape, PxVec3 position, PxVec3 force);
+
+
+ //////// data ////////
+
+ ExtPxManager* m_pxManager;
+ ExtImpactSettings m_settings;
+ PxManagerListener m_listener;
+ Array<PxContactPairPoint>::type m_pairPointBuffer;
+ bool m_usePxUserData;
+
+ struct ImpactDamageData
+ {
+ ExtPxActor* actor;
+ PxVec3 force;
+ PxVec3 position;
+ PxShape* shape;
+ };
+
+ Array<ImpactDamageData>::type m_impactDamageBuffer;
+
+ NvBlastFractureBuffers m_fractureBuffers;
+ Array<uint8_t>::type m_fractureData;
+};
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// ExtImpactDamageManagerImpl
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ExtImpactDamageManager* ExtImpactDamageManager::create(ExtPxManager* pxManager, ExtImpactSettings settings)
+{
+ return NVBLAST_NEW(ExtImpactDamageManagerImpl) (pxManager, settings);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// onContact callback call
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void ExtImpactDamageManagerImpl::onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, uint32_t nbPairs)
+{
+ if (pairHeader.flags & physx::PxContactPairHeaderFlag::eREMOVED_ACTOR_0 ||
+ pairHeader.flags & physx::PxContactPairHeaderFlag::eREMOVED_ACTOR_1 ||
+ pairHeader.actors[0] == nullptr ||
+ pairHeader.actors[1] == nullptr)
+ {
+ return;
+ }
+
+ PxRigidActor* rigidActor0 = pairHeader.actors[0];
+ PxRigidActor* rigidActor1 = pairHeader.actors[1];
+
+ ExtPxActor* actors[2];
+
+ if (m_usePxUserData)
+ {
+ actors[0] = (ExtPxActor*)rigidActor0->userData;
+ actors[1] = (ExtPxActor*)rigidActor1->userData;
+ }
+ else
+ {
+ PxRigidDynamic* rigidDynamic0 = rigidActor0->is<PxRigidDynamic>();
+ PxRigidDynamic* rigidDynamic1 = rigidActor1->is<PxRigidDynamic>();
+ actors[0] = rigidDynamic0 ? m_pxManager->getActorFromPhysXActor(*rigidDynamic0) : nullptr;
+ actors[1] = rigidDynamic1 ? m_pxManager->getActorFromPhysXActor(*rigidDynamic1) : nullptr;
+ }
+
+
+ // check one of them is blast actor
+ if (actors[0] == nullptr && actors[1] == nullptr)
+ {
+ return;
+ }
+
+ // self-collision check
+ if (actors[0] != nullptr && actors[1] != nullptr)
+ {
+ if (&actors[0]->getFamily() == &actors[1]->getFamily() && !m_settings.isSelfCollissionEnabled)
+ return;
+ }
+
+ for (uint32_t pairIdx = 0; pairIdx < nbPairs; pairIdx++)
+ {
+ const PxContactPair& currentPair = pairs[pairIdx];
+
+ if (currentPair.flags & physx::PxContactPairFlag::eREMOVED_SHAPE_0 ||
+ currentPair.flags & physx::PxContactPairFlag::eREMOVED_SHAPE_1 ||
+ currentPair.shapes[0] == nullptr ||
+ currentPair.shapes[1] == nullptr)
+ {
+ continue;
+ }
+
+ float masses[2] = { 0, 0 };
+ {
+ for (int i = 0; i < 2; ++i)
+ {
+ PxRigidDynamic* rigidDynamic = pairHeader.actors[i]->is<physx::PxRigidDynamic>();
+ if (rigidDynamic)
+ {
+ if (!(rigidDynamic->getRigidBodyFlags() & physx::PxRigidBodyFlag::eKINEMATIC))
+ {
+ masses[i] = rigidDynamic->getMass();
+ }
+ }
+ }
+ };
+
+ float reducedMass;
+ if (masses[0] == 0.0f)
+ {
+ reducedMass = masses[1];
+ }
+ else if (masses[1] == 0.0f)
+ {
+ reducedMass = masses[0];
+ }
+ else
+ {
+ reducedMass = masses[0] * masses[1] / (masses[0] + masses[1]);
+ }
+
+
+ PxVec3 destructibleForces[2] = { PxVec3(0.0f), PxVec3(0.0f) };
+ PxVec3 avgContactPosition = PxVec3(0.0f);
+ PxVec3 avgContactNormal = PxVec3(0.0f);
+ uint32_t numContacts = 0;
+
+ m_pairPointBuffer.resize(currentPair.contactCount);
+ uint32_t numContactsInStream = currentPair.contactCount > 0 ? currentPair.extractContacts(m_pairPointBuffer.begin(), currentPair.contactCount) : 0;
+
+ for (uint32_t contactIdx = 0; contactIdx < numContactsInStream; contactIdx++)
+ {
+ PxContactPairPoint& currentPoint = m_pairPointBuffer[contactIdx];
+
+ const PxVec3& patchNormal = currentPoint.normal;
+ const PxVec3& position = currentPoint.position;
+ PxVec3 velocities[2] = { PxVec3(0.0f), PxVec3(0.0f) };
+ for (int i = 0; i < 2; ++i)
+ {
+ PxRigidBody* rigidBody = pairHeader.actors[i]->is<physx::PxRigidBody>();
+ if (rigidBody)
+ {
+ velocities[i] = physx::PxRigidBodyExt::getVelocityAtPos(*rigidBody, position);
+ }
+ }
+
+ const PxVec3 velocityDelta = velocities[0] - velocities[1];
+ if (velocityDelta.magnitudeSquared() >= MIN_IMPACT_VELOCITY_SQUARED || reducedMass == 0.0f) // If reduced mass == 0, this is kineamtic vs. kinematic. Generate damage.
+ {
+ for (int i = 0; i < 2; ++i)
+ {
+ if (actors[i])
+ {
+ // this is not really physically correct, but at least its deterministic...
+ destructibleForces[i] += (patchNormal * patchNormal.dot(velocityDelta)) * reducedMass * (i ? 1.0f : -1.0f);
+ }
+ }
+ avgContactPosition += position;
+ avgContactNormal += patchNormal;
+ numContacts++;
+ }
+ }
+
+ if (numContacts)
+ {
+ avgContactPosition /= (float)numContacts;
+ avgContactNormal.normalize();
+ for (uint32_t i = 0; i < 2; i++)
+ {
+ const PxVec3 force = destructibleForces[i] / (float)numContacts;
+ ExtPxActor* actor = actors[i];
+ if (actor != nullptr)
+ {
+ if (!force.isZero())
+ {
+ queueImpactDamage(actor, force, avgContactPosition, currentPair.shapes[i]);
+ }
+ else if (reducedMass == 0.0f) // Handle kinematic vs. kinematic
+ {
+ // holy molly
+ }
+ }
+ }
+ }
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// ExtImpactDamageManager damage processing
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void ExtImpactDamageManagerImpl::applyDamage()
+{
+ const auto damageFn = m_settings.damageFunction;
+ const auto damageFnData = m_settings.damageFunctionData;
+
+ for (const ImpactDamageData& data : m_impactDamageBuffer)
+ {
+ PxTransform t(data.actor->getPhysXActor().getGlobalPose().getInverse());
+ PxVec3 force = t.rotate(data.force);
+ PxVec3 position = t.transform(data.position);
+
+ if (!damageFn || !damageFn(damageFnData, data.actor, data.shape, position, force))
+ {
+ damageActor(data.actor, data.shape, position, force);
+ }
+ }
+ m_impactDamageBuffer.clear();
+}
+
+void ExtImpactDamageManagerImpl::ensureBuffersSize(ExtPxActor* actor)
+{
+ const TkAsset* tkAsset = actor->getTkActor().getAsset();
+ const uint32_t chunkCount = tkAsset->getChunkCount();
+ const uint32_t bondCount = tkAsset->getBondCount();
+
+ m_fractureBuffers.bondFractureCount = bondCount;
+ m_fractureBuffers.chunkFractureCount = chunkCount;
+ m_fractureData.resize((uint32_t)(m_fractureBuffers.bondFractureCount*sizeof(NvBlastBondFractureData) + m_fractureBuffers.chunkFractureCount*sizeof(NvBlastChunkFractureData))); // chunk count + bond count
+ m_fractureBuffers.chunkFractures = reinterpret_cast<NvBlastChunkFractureData*>(m_fractureData.begin());
+ m_fractureBuffers.bondFractures = reinterpret_cast<NvBlastBondFractureData*>(&m_fractureData.begin()[m_fractureBuffers.chunkFractureCount*sizeof(NvBlastChunkFractureData)]);
+}
+
+void ExtImpactDamageManagerImpl::damageActor(ExtPxActor* actor, PxShape* /*shape*/, PxVec3 position, PxVec3 force)
+{
+ ensureBuffersSize(actor);
+
+ const float damage = m_settings.hardness > 0.f ? force.magnitude() / m_settings.hardness : 0.f;
+
+ const NvBlastExtMaterial* material = actor->getFamily().getMaterial();
+ if (!material)
+ {
+ return;
+ }
+
+ float normalizedDamage = material->getNormalizedDamage(damage);
+ if (normalizedDamage == 0.f || normalizedDamage < m_settings.damageThresholdMin)
+ {
+ return;
+ }
+ normalizedDamage = PxClamp<float>(normalizedDamage, 0, m_settings.damageThresholdMax);
+
+ const PxVec3 normal = force.getNormalized();
+ const float minDistance = m_settings.damageRadiusMax * normalizedDamage;
+ const float maxDistance = minDistance * PxClamp<float>(m_settings.damageFalloffRadiusFactor, 1, 32);
+
+ NvBlastExtProgramParams programParams(nullptr);
+ programParams.material = material;
+ programParams.accelerator = actor->getFamily().getPxAsset().getAccelerator();
+ NvBlastDamageProgram program;
+
+ if (m_settings.shearDamage)
+ {
+ NvBlastExtShearDamageDesc desc = {
+ normalizedDamage,
+ { normal[0], normal[1], normal[2] },
+ { position[0], position[1], position[2] },
+ minDistance,
+ maxDistance
+ };
+
+ programParams.damageDesc = &desc;
+
+ program.graphShaderFunction = NvBlastExtShearGraphShader;
+ program.subgraphShaderFunction = NvBlastExtShearSubgraphShader;
+
+ NvBlastFractureBuffers fractureEvents = m_fractureBuffers;
+ actor->getTkActor().generateFracture(&fractureEvents, program, &programParams);
+ actor->getTkActor().applyFracture(nullptr, &fractureEvents);
+ }
+ else
+ {
+ NvBlastExtImpactSpreadDamageDesc desc = {
+ normalizedDamage,
+ { position[0], position[1], position[2] },
+ minDistance,
+ maxDistance
+ };
+
+ programParams.damageDesc = &desc;
+
+ program.graphShaderFunction = NvBlastExtImpactSpreadGraphShader;
+ program.subgraphShaderFunction = NvBlastExtImpactSpreadSubgraphShader;
+
+ NvBlastFractureBuffers fractureEvents = m_fractureBuffers;
+ actor->getTkActor().generateFracture(&fractureEvents, program, &programParams);
+ actor->getTkActor().applyFracture(nullptr, &fractureEvents);
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Filter Shader
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+PxFilterFlags ExtImpactDamageManager::FilterShader(
+ PxFilterObjectAttributes attributes0,
+ PxFilterData filterData0,
+ PxFilterObjectAttributes attributes1,
+ PxFilterData filterData1,
+ PxPairFlags& pairFlags,
+ const void* constantBlock,
+ uint32_t constantBlockSize)
+{
+ PX_UNUSED(constantBlock);
+ PX_UNUSED(constantBlockSize);
+ // let triggers through
+ if (PxFilterObjectIsTrigger(attributes0) || PxFilterObjectIsTrigger(attributes1))
+ {
+ pairFlags = PxPairFlag::eTRIGGER_DEFAULT;
+ return PxFilterFlags();
+ }
+
+ if ((PxFilterObjectIsKinematic(attributes0) || PxFilterObjectIsKinematic(attributes1)) &&
+ (PxGetFilterObjectType(attributes0) == PxFilterObjectType::eRIGID_STATIC || PxGetFilterObjectType(attributes1) == PxFilterObjectType::eRIGID_STATIC))
+ {
+ return PxFilterFlag::eSUPPRESS;
+ }
+
+ // use a group-based mechanism if the first two filter data words are not 0
+ uint32_t f0 = filterData0.word0 | filterData0.word1;
+ uint32_t f1 = filterData1.word0 | filterData1.word1;
+ if (f0 && f1 && !(filterData0.word0&filterData1.word1 || filterData1.word0&filterData0.word1))
+ return PxFilterFlag::eSUPPRESS;
+
+ // determine if we should suppress notification
+ const bool suppressNotify = ((filterData0.word3 | filterData1.word3) & ExtPxManager::LEAF_CHUNK) != 0;
+
+ pairFlags = PxPairFlag::eCONTACT_DEFAULT;
+ if (!suppressNotify)
+ {
+ pairFlags = pairFlags
+ | PxPairFlag::eNOTIFY_CONTACT_POINTS
+ | PxPairFlag::eNOTIFY_THRESHOLD_FORCE_PERSISTS
+ | PxPairFlag::eNOTIFY_THRESHOLD_FORCE_FOUND
+ | PxPairFlag::eNOTIFY_TOUCH_FOUND
+ | PxPairFlag::eNOTIFY_TOUCH_PERSISTS;
+ }
+
+ // eSOLVE_CONTACT is invalid with kinematic pairs
+ if (PxFilterObjectIsKinematic(attributes0) && PxFilterObjectIsKinematic(attributes1))
+ {
+ pairFlags &= ~PxPairFlag::eSOLVE_CONTACT;
+ }
+
+ return PxFilterFlags();
+}
+
+} // namespace Blast
+} // namespace Nv
diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxActorImpl.cpp b/sdk/extensions/physx/source/physics/NvBlastExtPxActorImpl.cpp index 3a07b0d..dbe8d47 100644..100755 --- a/sdk/extensions/physx/source/physics/NvBlastExtPxActorImpl.cpp +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxActorImpl.cpp @@ -1,203 +1,203 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#include "NvBlastExtPxActorImpl.h" -#include "NvBlastExtPxAsset.h" -#include "NvBlastExtPxManagerImpl.h" -#include "NvBlastExtPxFamilyImpl.h" - -#include "PxRigidDynamic.h" -#include "PxPhysics.h" - -#include "NvBlastAssert.h" - -#include "NvBlastTkActor.h" -#include "NvBlastTkAsset.h" - -#include "PxRigidBodyExt.h" - - -namespace Nv -{ -namespace Blast -{ - - -ExtPxActorImpl::ExtPxActorImpl(ExtPxFamilyImpl* family, TkActor* tkActor, const PxActorCreateInfo& pxActorInfo) - : m_family(family), m_tkActor(tkActor) -{ - const ExtPxChunk* pxChunks = m_family->m_pxAsset.getChunks(); - const ExtPxSubchunk* pxSubchunks = m_family->m_pxAsset.getSubchunks(); - const NvBlastChunk* chunks = m_tkActor->getAsset()->getChunks(); - uint32_t nodeCount = m_tkActor->getGraphNodeCount(); - - PxFilterData simulationFilterData; // Default constructor = {0,0,0,0} - - // get visible chunk indices list - { - auto& chunkIndices = m_family->m_indicesScratch; - chunkIndices.resize(m_tkActor->getVisibleChunkCount()); - m_tkActor->getVisibleChunkIndices(chunkIndices.begin(), static_cast<uint32_t>(chunkIndices.size())); - - // fill visible chunk indices list with mapped to our asset indices - m_chunkIndices.reserve(chunkIndices.size()); - for (const uint32_t chunkIndex : chunkIndices) - { - const ExtPxChunk& chunk = pxChunks[chunkIndex]; - if (chunk.subchunkCount == 0) - continue; - m_chunkIndices.pushBack(chunkIndex); - } - - // Single lower-support chunk actors might be leaf actors, check for this and disable contact callbacks if so - if (nodeCount <= 1) - { - NVBLAST_ASSERT(chunkIndices.size() == 1); - if (chunkIndices.size() > 0) - { - const NvBlastChunk& chunk = chunks[chunkIndices[0]]; - if (chunk.firstChildIndex == chunk.childIndexStop) - { - simulationFilterData.word3 = ExtPxManager::LEAF_CHUNK; // mark as leaf chunk if chunk has no children - } - } - } - } - - // create rigidDynamic and setup - PxPhysics& physics = m_family->m_manager.m_physics; - m_rigidDynamic = physics.createRigidDynamic(pxActorInfo.m_transform); - if (m_family->m_pxActorDescTemplate != nullptr) - { - m_rigidDynamic->setActorFlags(static_cast<physx::PxActorFlags>(m_family->m_pxActorDescTemplate->flags)); - } - - // fill rigidDynamic with shapes - PxMaterial* material = m_family->m_spawnSettings.material; - for (uint32_t i = 0; i < m_chunkIndices.size(); ++i) - { - uint32_t chunkID = m_chunkIndices[i]; - const ExtPxChunk& chunk = pxChunks[chunkID]; - for (uint32_t c = 0; c < chunk.subchunkCount; c++) - { - const uint32_t subchunkIndex = chunk.firstSubchunkIndex + c; - auto& subchunk = pxSubchunks[subchunkIndex]; - PxShape* shape = physics.createShape(subchunk.geometry, *material); - shape->setLocalPose(subchunk.transform); - - const ExtPxShapeDescTemplate* pxShapeDesc = m_family->m_pxShapeDescTemplate; - if (pxShapeDesc != nullptr) - { - shape->setFlags(static_cast<PxShapeFlags>(pxShapeDesc->flags)); - shape->setSimulationFilterData(pxShapeDesc->simulationFilterData); - shape->setQueryFilterData(pxShapeDesc->queryFilterData); - shape->setContactOffset(pxShapeDesc->contactOffset); - shape->setRestOffset(pxShapeDesc->restOffset); - } - else - { - shape->setSimulationFilterData(simulationFilterData); - } - - m_rigidDynamic->attachShape(*shape); - - NVBLAST_ASSERT_WITH_MESSAGE(m_family->m_subchunkShapes[subchunkIndex] == nullptr, "Chunk has some shapes(live)."); - m_family->m_subchunkShapes[subchunkIndex] = shape; - } - } - - // search for static chunk in actor's graph (make actor static if it contains static chunk) - bool staticFound = m_tkActor->isBoundToWorld(); - if (nodeCount > 0) - { - auto& graphNodeIndices = m_family->m_indicesScratch; - graphNodeIndices.resize(nodeCount); - m_tkActor->getGraphNodeIndices(graphNodeIndices.begin(), static_cast<uint32_t>(graphNodeIndices.size())); - const NvBlastSupportGraph graph = m_tkActor->getAsset()->getGraph(); - - for (uint32_t i = 0; !staticFound && i < graphNodeIndices.size(); ++i) - { - const uint32_t chunkIndex = graph.chunkIndices[graphNodeIndices[i]]; - const ExtPxChunk& chunk = pxChunks[chunkIndex]; - staticFound = chunk.isStatic; - } - } - m_rigidDynamic->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, staticFound); - - // store pointer to actor in px userData - m_family->m_manager.registerActor(m_rigidDynamic, this); - - // store pointer to actor in blast userData - m_tkActor->userData = this; - - // update mass properties - PxRigidBodyExt::updateMassAndInertia(*m_rigidDynamic, m_family->m_spawnSettings.density); - - // set initial velocities - if (!(m_rigidDynamic->getRigidBodyFlags() & PxRigidBodyFlag::eKINEMATIC)) - { - const PxVec3 COM = m_rigidDynamic->getGlobalPose().transform(m_rigidDynamic->getCMassLocalPose().p); - const PxVec3 linearVelocity = pxActorInfo.m_parentLinearVelocity + pxActorInfo.m_parentAngularVelocity.cross(COM - pxActorInfo.m_parentCOM); - const PxVec3 angularVelocity = pxActorInfo.m_parentAngularVelocity; - m_rigidDynamic->setLinearVelocity(linearVelocity); - m_rigidDynamic->setAngularVelocity(angularVelocity); - } -} - -void ExtPxActorImpl::release() -{ - if (m_rigidDynamic != nullptr) - { - m_family->m_manager.unregisterActor(m_rigidDynamic); - m_rigidDynamic->release(); - m_rigidDynamic = nullptr; - } - - const ExtPxChunk* pxChunks = m_family->m_pxAsset.getChunks(); - for (uint32_t chunkID : m_chunkIndices) - { - const ExtPxChunk& chunk = pxChunks[chunkID]; - for (uint32_t c = 0; c < chunk.subchunkCount; c++) - { - const uint32_t subchunkIndex = chunk.firstSubchunkIndex + c; - m_family->m_subchunkShapes[subchunkIndex] = nullptr; - } - } - m_chunkIndices.clear(); - - m_tkActor->userData = nullptr; -} - -ExtPxFamily& ExtPxActorImpl::getFamily() const -{ - return *m_family; -} - - -} // namespace Blast -} // namespace Nv +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#include "NvBlastExtPxActorImpl.h"
+#include "NvBlastExtPxAsset.h"
+#include "NvBlastExtPxManagerImpl.h"
+#include "NvBlastExtPxFamilyImpl.h"
+
+#include "PxRigidDynamic.h"
+#include "PxPhysics.h"
+
+#include "NvBlastAssert.h"
+
+#include "NvBlastTkActor.h"
+#include "NvBlastTkAsset.h"
+
+#include "PxRigidBodyExt.h"
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+
+ExtPxActorImpl::ExtPxActorImpl(ExtPxFamilyImpl* family, TkActor* tkActor, const PxActorCreateInfo& pxActorInfo)
+ : m_family(family), m_tkActor(tkActor)
+{
+ const ExtPxChunk* pxChunks = m_family->m_pxAsset.getChunks();
+ const ExtPxSubchunk* pxSubchunks = m_family->m_pxAsset.getSubchunks();
+ const NvBlastChunk* chunks = m_tkActor->getAsset()->getChunks();
+ uint32_t nodeCount = m_tkActor->getGraphNodeCount();
+
+ PxFilterData simulationFilterData; // Default constructor = {0,0,0,0}
+
+ // get visible chunk indices list
+ {
+ auto& chunkIndices = m_family->m_indicesScratch;
+ chunkIndices.resize(m_tkActor->getVisibleChunkCount());
+ m_tkActor->getVisibleChunkIndices(chunkIndices.begin(), static_cast<uint32_t>(chunkIndices.size()));
+
+ // fill visible chunk indices list with mapped to our asset indices
+ m_chunkIndices.reserve(chunkIndices.size());
+ for (const uint32_t chunkIndex : chunkIndices)
+ {
+ const ExtPxChunk& chunk = pxChunks[chunkIndex];
+ if (chunk.subchunkCount == 0)
+ continue;
+ m_chunkIndices.pushBack(chunkIndex);
+ }
+
+ // Single lower-support chunk actors might be leaf actors, check for this and disable contact callbacks if so
+ if (nodeCount <= 1)
+ {
+ NVBLAST_ASSERT(chunkIndices.size() == 1);
+ if (chunkIndices.size() > 0)
+ {
+ const NvBlastChunk& chunk = chunks[chunkIndices[0]];
+ if (chunk.firstChildIndex == chunk.childIndexStop)
+ {
+ simulationFilterData.word3 = ExtPxManager::LEAF_CHUNK; // mark as leaf chunk if chunk has no children
+ }
+ }
+ }
+ }
+
+ // create rigidDynamic and setup
+ PxPhysics& physics = m_family->m_manager.m_physics;
+ m_rigidDynamic = physics.createRigidDynamic(pxActorInfo.m_transform);
+ if (m_family->m_pxActorDescTemplate != nullptr)
+ {
+ m_rigidDynamic->setActorFlags(static_cast<physx::PxActorFlags>(m_family->m_pxActorDescTemplate->flags));
+ }
+
+ // fill rigidDynamic with shapes
+ PxMaterial* material = m_family->m_spawnSettings.material;
+ for (uint32_t i = 0; i < m_chunkIndices.size(); ++i)
+ {
+ uint32_t chunkID = m_chunkIndices[i];
+ const ExtPxChunk& chunk = pxChunks[chunkID];
+ for (uint32_t c = 0; c < chunk.subchunkCount; c++)
+ {
+ const uint32_t subchunkIndex = chunk.firstSubchunkIndex + c;
+ auto& subchunk = pxSubchunks[subchunkIndex];
+ PxShape* shape = physics.createShape(subchunk.geometry, *material);
+ shape->setLocalPose(subchunk.transform);
+
+ const ExtPxShapeDescTemplate* pxShapeDesc = m_family->m_pxShapeDescTemplate;
+ if (pxShapeDesc != nullptr)
+ {
+ shape->setFlags(static_cast<PxShapeFlags>(pxShapeDesc->flags));
+ shape->setSimulationFilterData(pxShapeDesc->simulationFilterData);
+ shape->setQueryFilterData(pxShapeDesc->queryFilterData);
+ shape->setContactOffset(pxShapeDesc->contactOffset);
+ shape->setRestOffset(pxShapeDesc->restOffset);
+ }
+ else
+ {
+ shape->setSimulationFilterData(simulationFilterData);
+ }
+
+ m_rigidDynamic->attachShape(*shape);
+
+ NVBLAST_ASSERT_WITH_MESSAGE(m_family->m_subchunkShapes[subchunkIndex] == nullptr, "Chunk has some shapes(live).");
+ m_family->m_subchunkShapes[subchunkIndex] = shape;
+ }
+ }
+
+ // search for static chunk in actor's graph (make actor static if it contains static chunk)
+ bool staticFound = m_tkActor->isBoundToWorld();
+ if (nodeCount > 0)
+ {
+ auto& graphNodeIndices = m_family->m_indicesScratch;
+ graphNodeIndices.resize(nodeCount);
+ m_tkActor->getGraphNodeIndices(graphNodeIndices.begin(), static_cast<uint32_t>(graphNodeIndices.size()));
+ const NvBlastSupportGraph graph = m_tkActor->getAsset()->getGraph();
+
+ for (uint32_t i = 0; !staticFound && i < graphNodeIndices.size(); ++i)
+ {
+ const uint32_t chunkIndex = graph.chunkIndices[graphNodeIndices[i]];
+ const ExtPxChunk& chunk = pxChunks[chunkIndex];
+ staticFound = chunk.isStatic;
+ }
+ }
+ m_rigidDynamic->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, staticFound);
+
+ // store pointer to actor in px userData
+ m_family->m_manager.registerActor(m_rigidDynamic, this);
+
+ // store pointer to actor in blast userData
+ m_tkActor->userData = this;
+
+ // update mass properties
+ PxRigidBodyExt::updateMassAndInertia(*m_rigidDynamic, m_family->m_spawnSettings.density);
+
+ // set initial velocities
+ if (!(m_rigidDynamic->getRigidBodyFlags() & PxRigidBodyFlag::eKINEMATIC))
+ {
+ const PxVec3 COM = m_rigidDynamic->getGlobalPose().transform(m_rigidDynamic->getCMassLocalPose().p);
+ const PxVec3 linearVelocity = pxActorInfo.m_parentLinearVelocity + pxActorInfo.m_parentAngularVelocity.cross(COM - pxActorInfo.m_parentCOM);
+ const PxVec3 angularVelocity = pxActorInfo.m_parentAngularVelocity;
+ m_rigidDynamic->setLinearVelocity(linearVelocity);
+ m_rigidDynamic->setAngularVelocity(angularVelocity);
+ }
+}
+
+void ExtPxActorImpl::release()
+{
+ if (m_rigidDynamic != nullptr)
+ {
+ m_family->m_manager.unregisterActor(m_rigidDynamic);
+ m_rigidDynamic->release();
+ m_rigidDynamic = nullptr;
+ }
+
+ const ExtPxChunk* pxChunks = m_family->m_pxAsset.getChunks();
+ for (uint32_t chunkID : m_chunkIndices)
+ {
+ const ExtPxChunk& chunk = pxChunks[chunkID];
+ for (uint32_t c = 0; c < chunk.subchunkCount; c++)
+ {
+ const uint32_t subchunkIndex = chunk.firstSubchunkIndex + c;
+ m_family->m_subchunkShapes[subchunkIndex] = nullptr;
+ }
+ }
+ m_chunkIndices.clear();
+
+ m_tkActor->userData = nullptr;
+}
+
+ExtPxFamily& ExtPxActorImpl::getFamily() const
+{
+ return *m_family;
+}
+
+
+} // namespace Blast
+} // namespace Nv
diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxActorImpl.h b/sdk/extensions/physx/source/physics/NvBlastExtPxActorImpl.h index 3c8fde2..0fc8f6c 100644..100755 --- a/sdk/extensions/physx/source/physics/NvBlastExtPxActorImpl.h +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxActorImpl.h @@ -1,113 +1,113 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#ifndef NVBLASTEXTPXACTORIMPL_H -#define NVBLASTEXTPXACTORIMPL_H - -#include "NvBlastExtPxActor.h" -#include "NvBlastArray.h" -#include "PxTransform.h" - - -using namespace physx; - -namespace Nv -{ -namespace Blast -{ - - -// Forward declarations -class ExtPxFamilyImpl; - -struct PxActorCreateInfo -{ - PxTransform m_transform; - PxVec3 m_scale; - PxVec3 m_parentLinearVelocity; - PxVec3 m_parentAngularVelocity; - PxVec3 m_parentCOM; -}; - - -class ExtPxActorImpl final : public ExtPxActor -{ -public: - //////// ctor //////// - - ExtPxActorImpl(ExtPxFamilyImpl* family, TkActor* tkActor, const PxActorCreateInfo& pxActorInfo); - - ~ExtPxActorImpl() - { - release(); - } - - void release(); - - - //////// interface //////// - - virtual uint32_t getChunkCount() const override - { - return static_cast<uint32_t>(m_chunkIndices.size()); - } - - virtual const uint32_t* getChunkIndices() const override - { - return m_chunkIndices.begin(); - } - - virtual PxRigidDynamic& getPhysXActor() const override - { - return *m_rigidDynamic; - } - - virtual TkActor& getTkActor() const override - { - return *m_tkActor; - } - - virtual ExtPxFamily& getFamily() const override; - - -private: - //////// data //////// - - ExtPxFamilyImpl* m_family; - TkActor* m_tkActor; - PxRigidDynamic* m_rigidDynamic; - InlineArray<uint32_t, 4>::type m_chunkIndices; -}; - - - -} // namespace Blast -} // namespace Nv - - -#endif // ifndef NVBLASTEXTPXACTORIMPL_H +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#ifndef NVBLASTEXTPXACTORIMPL_H
+#define NVBLASTEXTPXACTORIMPL_H
+
+#include "NvBlastExtPxActor.h"
+#include "NvBlastArray.h"
+#include "PxTransform.h"
+
+
+using namespace physx;
+
+namespace Nv
+{
+namespace Blast
+{
+
+
+// Forward declarations
+class ExtPxFamilyImpl;
+
+struct PxActorCreateInfo
+{
+ PxTransform m_transform;
+ PxVec3 m_scale;
+ PxVec3 m_parentLinearVelocity;
+ PxVec3 m_parentAngularVelocity;
+ PxVec3 m_parentCOM;
+};
+
+
+class ExtPxActorImpl final : public ExtPxActor
+{
+public:
+ //////// ctor ////////
+
+ ExtPxActorImpl(ExtPxFamilyImpl* family, TkActor* tkActor, const PxActorCreateInfo& pxActorInfo);
+
+ ~ExtPxActorImpl()
+ {
+ release();
+ }
+
+ void release();
+
+
+ //////// interface ////////
+
+ virtual uint32_t getChunkCount() const override
+ {
+ return static_cast<uint32_t>(m_chunkIndices.size());
+ }
+
+ virtual const uint32_t* getChunkIndices() const override
+ {
+ return m_chunkIndices.begin();
+ }
+
+ virtual PxRigidDynamic& getPhysXActor() const override
+ {
+ return *m_rigidDynamic;
+ }
+
+ virtual TkActor& getTkActor() const override
+ {
+ return *m_tkActor;
+ }
+
+ virtual ExtPxFamily& getFamily() const override;
+
+
+private:
+ //////// data ////////
+
+ ExtPxFamilyImpl* m_family;
+ TkActor* m_tkActor;
+ PxRigidDynamic* m_rigidDynamic;
+ InlineArray<uint32_t, 4>::type m_chunkIndices;
+};
+
+
+
+} // namespace Blast
+} // namespace Nv
+
+
+#endif // ifndef NVBLASTEXTPXACTORIMPL_H
diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxAssetImpl.cpp b/sdk/extensions/physx/source/physics/NvBlastExtPxAssetImpl.cpp index f079afd..2bc1b63 100644..100755 --- a/sdk/extensions/physx/source/physics/NvBlastExtPxAssetImpl.cpp +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxAssetImpl.cpp @@ -1,270 +1,270 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#include "NvBlastExtPxAssetImpl.h" -#include "NvBlastHashMap.h" - -#include "NvBlastAssert.h" -#include "NvBlastIndexFns.h" - -#include "NvBlastTkAsset.h" - -#include "PxIO.h" -#include "PxPhysics.h" -#include "PxFileBuf.h" -#include "cooking/PxCooking.h" - -#include <algorithm> - -namespace Nv -{ -namespace Blast -{ - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// ExtPxAssetImpl Implementation -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -ExtPxAssetImpl::ExtPxAssetImpl(const ExtPxAssetDesc& desc, TkFramework& framework) - : m_accelerator(nullptr) -#if !defined(NV_VC) || NV_VC >= 14 - , m_defaultActorDesc { 1.0f, nullptr, 1.0f, nullptr } -{ -#else -{ - m_defaultActorDesc.uniformInitialBondHealth = m_defaultActorDesc.uniformInitialLowerSupportChunkHealth = 1.0f; - m_defaultActorDesc.initialBondHealths = m_defaultActorDesc.initialSupportChunkHealths = nullptr; -#endif - m_tkAsset = framework.createAsset(desc); - fillPhysicsChunks(desc.pxChunks, desc.chunkCount); -} - -ExtPxAssetImpl::ExtPxAssetImpl(const TkAssetDesc& desc, ExtPxChunk* pxChunks, ExtPxSubchunk* pxSubchunks, TkFramework& framework) - : m_accelerator(nullptr) -#if !defined(NV_VC) || NV_VC >= 14 - , m_defaultActorDesc{ 1.0f, nullptr, 1.0f, nullptr } -{ -#else -{ - m_defaultActorDesc.uniformInitialBondHealth = m_defaultActorDesc.uniformInitialLowerSupportChunkHealth = 1.0f; - m_defaultActorDesc.initialBondHealths = m_defaultActorDesc.initialSupportChunkHealths = nullptr; -#endif - m_tkAsset = framework.createAsset(desc); - fillPhysicsChunks(pxChunks, pxSubchunks, desc.chunkCount); -} - -ExtPxAssetImpl::ExtPxAssetImpl(TkAsset* asset, ExtPxAssetDesc::ChunkDesc* chunks, uint32_t chunkCount) - : m_tkAsset(asset) - , m_accelerator(nullptr) -#if !defined(NV_VC) || NV_VC >= 14 - , m_defaultActorDesc{ 1.0f, nullptr, 1.0f, nullptr } -{ -#else -{ - m_defaultActorDesc.uniformInitialBondHealth = m_defaultActorDesc.uniformInitialLowerSupportChunkHealth = 1.0f; - m_defaultActorDesc.initialBondHealths = m_defaultActorDesc.initialSupportChunkHealths = nullptr; -#endif - m_tkAsset = asset; - fillPhysicsChunks(chunks, chunkCount); -} - - -ExtPxAssetImpl::ExtPxAssetImpl(TkAsset* asset) - : m_tkAsset(asset) - , m_accelerator(nullptr) -#if !defined(NV_VC) || NV_VC >= 14 - , m_defaultActorDesc { 1.0f, nullptr, 1.0f, nullptr } -{ -#else -{ - m_defaultActorDesc.uniformInitialBondHealth = m_defaultActorDesc.uniformInitialLowerSupportChunkHealth = 1.0f; - m_defaultActorDesc.initialBondHealths = m_defaultActorDesc.initialSupportChunkHealths = nullptr; -#endif -} - -ExtPxAssetImpl::~ExtPxAssetImpl() -{ - if (m_tkAsset) - { - m_tkAsset->release(); - } -} - -void ExtPxAssetImpl::release() -{ - NVBLAST_DELETE(this, ExtPxAssetImpl); -} - -void ExtPxAssetImpl::fillPhysicsChunks(ExtPxChunk* pxChunks, ExtPxSubchunk* pxSuchunks, uint32_t chunkCount) -{ - // count subchunks and reserve memory - uint32_t subchunkCount = 0; - for (uint32_t i = 0; i < chunkCount; ++i) - { - const auto& chunk = pxChunks[i]; - subchunkCount += static_cast<uint32_t>(chunk.subchunkCount); - } - m_subchunks.resize(subchunkCount); - m_chunks.resize(chunkCount); - memcpy(&m_subchunks.front(), pxSuchunks, sizeof(ExtPxSubchunk) * subchunkCount); - memcpy(&m_chunks.front(), pxChunks, sizeof(ExtPxChunk) * chunkCount); -} - -void ExtPxAssetImpl::fillPhysicsChunks(ExtPxAssetDesc::ChunkDesc* pxChunks, uint32_t chunkCount) -{ - // count subchunks and reserve memory - uint32_t subchunkCount = 0; - for (uint32_t i = 0; i < chunkCount; ++i) - { - const auto& chunk = pxChunks[i]; - subchunkCount += static_cast<uint32_t>(chunk.subchunkCount); - } - m_subchunks.reserve(subchunkCount); - - // fill chunks and subchunks - m_chunks.resize(chunkCount); - for (uint32_t i = 0; i < chunkCount; ++i) - { - const auto& chunk = pxChunks[i]; - m_chunks[i].isStatic = chunk.isStatic; - m_chunks[i].firstSubchunkIndex = m_subchunks.size(); - m_chunks[i].subchunkCount = chunk.subchunkCount; - for (uint32_t k = 0; k < chunk.subchunkCount; ++k) - { - ExtPxSubchunk subchunk = - { - chunk.subchunks[k].transform, - chunk.subchunks[k].geometry - }; - m_subchunks.pushBack(subchunk); - } - } -} - - -NV_INLINE bool serializeConvexMesh(const PxConvexMesh& convexMesh, PxCooking& cooking, Array<uint32_t>::type& indicesScratch, - Array<PxHullPolygon>::type hullPolygonsScratch, PxOutputStream& stream) -{ - PxConvexMeshDesc desc; - desc.points.data = convexMesh.getVertices(); - desc.points.count = convexMesh.getNbVertices(); - desc.points.stride = sizeof(PxVec3); - - hullPolygonsScratch.resize(convexMesh.getNbPolygons()); - - uint32_t indexCount = 0; - for (uint32_t i = 0; i < convexMesh.getNbPolygons(); i++) - { - PxHullPolygon polygon; - convexMesh.getPolygonData(i, polygon); - if (polygon.mNbVerts) - { - indexCount = std::max<uint32_t>(indexCount, polygon.mIndexBase + polygon.mNbVerts); - } - } - indicesScratch.resize(indexCount); - - for (uint32_t i = 0; i < convexMesh.getNbPolygons(); i++) - { - PxHullPolygon polygon; - convexMesh.getPolygonData(i, polygon); - for (uint32_t j = 0; j < polygon.mNbVerts; j++) - { - indicesScratch[polygon.mIndexBase + j] = convexMesh.getIndexBuffer()[polygon.mIndexBase + j]; - } - - hullPolygonsScratch[i] = polygon; - } - - desc.indices.count = indexCount; - desc.indices.data = indicesScratch.begin(); - desc.indices.stride = sizeof(uint32_t); - - desc.polygons.count = convexMesh.getNbPolygons(); - desc.polygons.data = hullPolygonsScratch.begin(); - desc.polygons.stride = sizeof(PxHullPolygon); - - return cooking.cookConvexMesh(desc, stream); -} - - -void ExtPxAssetImpl::setUniformHealth(bool enabled) -{ - if (m_bondHealths.empty() != enabled) - { - if (enabled) - { - m_bondHealths.resizeUninitialized(0); - m_supportChunkHealths.resizeUninitialized(0); - } - else - { - m_bondHealths.resize(m_tkAsset->getBondCount()); - m_supportChunkHealths.resize(m_tkAsset->getGraph().nodeCount); - } - } - - m_defaultActorDesc.initialBondHealths = enabled ? nullptr : m_bondHealths.begin(); - m_defaultActorDesc.initialSupportChunkHealths = enabled ? nullptr : m_supportChunkHealths.begin(); -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// ExtPxAsset Static -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -ExtPxAsset* ExtPxAsset::create(const ExtPxAssetDesc& desc, TkFramework& framework) -{ - ExtPxAssetImpl* asset = NVBLAST_NEW(ExtPxAssetImpl)(desc, framework); - return asset; -} - -ExtPxAsset* ExtPxAsset::create(const TkAssetDesc& desc, ExtPxChunk* pxChunks, ExtPxSubchunk* pxSubchunks, TkFramework& framework) -{ - ExtPxAssetImpl* asset = NVBLAST_NEW(ExtPxAssetImpl)(desc, pxChunks, pxSubchunks, framework); - return asset; -} - -Nv::Blast::ExtPxAsset* ExtPxAsset::create(TkAsset* tkAsset) -{ - ExtPxAssetImpl* asset = NVBLAST_NEW(ExtPxAssetImpl)(tkAsset); - - // Don't populate the chunks or subchunks! - - return asset; -} - -Nv::Blast::ExtPxAsset* ExtPxAsset::create(TkAsset* tkAsset, ExtPxAssetDesc::ChunkDesc* chunks, uint32_t chunkCount) -{ - ExtPxAssetImpl* asset = NVBLAST_NEW(ExtPxAssetImpl)(tkAsset, chunks, chunkCount); - return asset; -} - -} // namespace Blast -} // namespace Nv +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#include "NvBlastExtPxAssetImpl.h"
+#include "NvBlastHashMap.h"
+
+#include "NvBlastAssert.h"
+#include "NvBlastIndexFns.h"
+
+#include "NvBlastTkAsset.h"
+
+#include "PxIO.h"
+#include "PxPhysics.h"
+#include "PxFileBuf.h"
+#include "cooking/PxCooking.h"
+
+#include <algorithm>
+
+namespace Nv
+{
+namespace Blast
+{
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// ExtPxAssetImpl Implementation
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ExtPxAssetImpl::ExtPxAssetImpl(const ExtPxAssetDesc& desc, TkFramework& framework)
+ : m_accelerator(nullptr)
+#if !defined(NV_VC) || NV_VC >= 14
+ , m_defaultActorDesc { 1.0f, nullptr, 1.0f, nullptr }
+{
+#else
+{
+ m_defaultActorDesc.uniformInitialBondHealth = m_defaultActorDesc.uniformInitialLowerSupportChunkHealth = 1.0f;
+ m_defaultActorDesc.initialBondHealths = m_defaultActorDesc.initialSupportChunkHealths = nullptr;
+#endif
+ m_tkAsset = framework.createAsset(desc);
+ fillPhysicsChunks(desc.pxChunks, desc.chunkCount);
+}
+
+ExtPxAssetImpl::ExtPxAssetImpl(const TkAssetDesc& desc, ExtPxChunk* pxChunks, ExtPxSubchunk* pxSubchunks, TkFramework& framework)
+ : m_accelerator(nullptr)
+#if !defined(NV_VC) || NV_VC >= 14
+ , m_defaultActorDesc{ 1.0f, nullptr, 1.0f, nullptr }
+{
+#else
+{
+ m_defaultActorDesc.uniformInitialBondHealth = m_defaultActorDesc.uniformInitialLowerSupportChunkHealth = 1.0f;
+ m_defaultActorDesc.initialBondHealths = m_defaultActorDesc.initialSupportChunkHealths = nullptr;
+#endif
+ m_tkAsset = framework.createAsset(desc);
+ fillPhysicsChunks(pxChunks, pxSubchunks, desc.chunkCount);
+}
+
+ExtPxAssetImpl::ExtPxAssetImpl(TkAsset* asset, ExtPxAssetDesc::ChunkDesc* chunks, uint32_t chunkCount)
+ : m_tkAsset(asset)
+ , m_accelerator(nullptr)
+#if !defined(NV_VC) || NV_VC >= 14
+ , m_defaultActorDesc{ 1.0f, nullptr, 1.0f, nullptr }
+{
+#else
+{
+ m_defaultActorDesc.uniformInitialBondHealth = m_defaultActorDesc.uniformInitialLowerSupportChunkHealth = 1.0f;
+ m_defaultActorDesc.initialBondHealths = m_defaultActorDesc.initialSupportChunkHealths = nullptr;
+#endif
+ m_tkAsset = asset;
+ fillPhysicsChunks(chunks, chunkCount);
+}
+
+
+ExtPxAssetImpl::ExtPxAssetImpl(TkAsset* asset)
+ : m_tkAsset(asset)
+ , m_accelerator(nullptr)
+#if !defined(NV_VC) || NV_VC >= 14
+ , m_defaultActorDesc { 1.0f, nullptr, 1.0f, nullptr }
+{
+#else
+{
+ m_defaultActorDesc.uniformInitialBondHealth = m_defaultActorDesc.uniformInitialLowerSupportChunkHealth = 1.0f;
+ m_defaultActorDesc.initialBondHealths = m_defaultActorDesc.initialSupportChunkHealths = nullptr;
+#endif
+}
+
+ExtPxAssetImpl::~ExtPxAssetImpl()
+{
+ if (m_tkAsset)
+ {
+ m_tkAsset->release();
+ }
+}
+
+void ExtPxAssetImpl::release()
+{
+ NVBLAST_DELETE(this, ExtPxAssetImpl);
+}
+
+void ExtPxAssetImpl::fillPhysicsChunks(ExtPxChunk* pxChunks, ExtPxSubchunk* pxSuchunks, uint32_t chunkCount)
+{
+ // count subchunks and reserve memory
+ uint32_t subchunkCount = 0;
+ for (uint32_t i = 0; i < chunkCount; ++i)
+ {
+ const auto& chunk = pxChunks[i];
+ subchunkCount += static_cast<uint32_t>(chunk.subchunkCount);
+ }
+ m_subchunks.resize(subchunkCount);
+ m_chunks.resize(chunkCount);
+ memcpy(&m_subchunks.front(), pxSuchunks, sizeof(ExtPxSubchunk) * subchunkCount);
+ memcpy(&m_chunks.front(), pxChunks, sizeof(ExtPxChunk) * chunkCount);
+}
+
+void ExtPxAssetImpl::fillPhysicsChunks(ExtPxAssetDesc::ChunkDesc* pxChunks, uint32_t chunkCount)
+{
+ // count subchunks and reserve memory
+ uint32_t subchunkCount = 0;
+ for (uint32_t i = 0; i < chunkCount; ++i)
+ {
+ const auto& chunk = pxChunks[i];
+ subchunkCount += static_cast<uint32_t>(chunk.subchunkCount);
+ }
+ m_subchunks.reserve(subchunkCount);
+
+ // fill chunks and subchunks
+ m_chunks.resize(chunkCount);
+ for (uint32_t i = 0; i < chunkCount; ++i)
+ {
+ const auto& chunk = pxChunks[i];
+ m_chunks[i].isStatic = chunk.isStatic;
+ m_chunks[i].firstSubchunkIndex = m_subchunks.size();
+ m_chunks[i].subchunkCount = chunk.subchunkCount;
+ for (uint32_t k = 0; k < chunk.subchunkCount; ++k)
+ {
+ ExtPxSubchunk subchunk =
+ {
+ chunk.subchunks[k].transform,
+ chunk.subchunks[k].geometry
+ };
+ m_subchunks.pushBack(subchunk);
+ }
+ }
+}
+
+
+NV_INLINE bool serializeConvexMesh(const PxConvexMesh& convexMesh, PxCooking& cooking, Array<uint32_t>::type& indicesScratch,
+ Array<PxHullPolygon>::type hullPolygonsScratch, PxOutputStream& stream)
+{
+ PxConvexMeshDesc desc;
+ desc.points.data = convexMesh.getVertices();
+ desc.points.count = convexMesh.getNbVertices();
+ desc.points.stride = sizeof(PxVec3);
+
+ hullPolygonsScratch.resize(convexMesh.getNbPolygons());
+
+ uint32_t indexCount = 0;
+ for (uint32_t i = 0; i < convexMesh.getNbPolygons(); i++)
+ {
+ PxHullPolygon polygon;
+ convexMesh.getPolygonData(i, polygon);
+ if (polygon.mNbVerts)
+ {
+ indexCount = std::max<uint32_t>(indexCount, polygon.mIndexBase + polygon.mNbVerts);
+ }
+ }
+ indicesScratch.resize(indexCount);
+
+ for (uint32_t i = 0; i < convexMesh.getNbPolygons(); i++)
+ {
+ PxHullPolygon polygon;
+ convexMesh.getPolygonData(i, polygon);
+ for (uint32_t j = 0; j < polygon.mNbVerts; j++)
+ {
+ indicesScratch[polygon.mIndexBase + j] = convexMesh.getIndexBuffer()[polygon.mIndexBase + j];
+ }
+
+ hullPolygonsScratch[i] = polygon;
+ }
+
+ desc.indices.count = indexCount;
+ desc.indices.data = indicesScratch.begin();
+ desc.indices.stride = sizeof(uint32_t);
+
+ desc.polygons.count = convexMesh.getNbPolygons();
+ desc.polygons.data = hullPolygonsScratch.begin();
+ desc.polygons.stride = sizeof(PxHullPolygon);
+
+ return cooking.cookConvexMesh(desc, stream);
+}
+
+
+void ExtPxAssetImpl::setUniformHealth(bool enabled)
+{
+ if (m_bondHealths.empty() != enabled)
+ {
+ if (enabled)
+ {
+ m_bondHealths.resizeUninitialized(0);
+ m_supportChunkHealths.resizeUninitialized(0);
+ }
+ else
+ {
+ m_bondHealths.resize(m_tkAsset->getBondCount());
+ m_supportChunkHealths.resize(m_tkAsset->getGraph().nodeCount);
+ }
+ }
+
+ m_defaultActorDesc.initialBondHealths = enabled ? nullptr : m_bondHealths.begin();
+ m_defaultActorDesc.initialSupportChunkHealths = enabled ? nullptr : m_supportChunkHealths.begin();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// ExtPxAsset Static
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ExtPxAsset* ExtPxAsset::create(const ExtPxAssetDesc& desc, TkFramework& framework)
+{
+ ExtPxAssetImpl* asset = NVBLAST_NEW(ExtPxAssetImpl)(desc, framework);
+ return asset;
+}
+
+ExtPxAsset* ExtPxAsset::create(const TkAssetDesc& desc, ExtPxChunk* pxChunks, ExtPxSubchunk* pxSubchunks, TkFramework& framework)
+{
+ ExtPxAssetImpl* asset = NVBLAST_NEW(ExtPxAssetImpl)(desc, pxChunks, pxSubchunks, framework);
+ return asset;
+}
+
+Nv::Blast::ExtPxAsset* ExtPxAsset::create(TkAsset* tkAsset)
+{
+ ExtPxAssetImpl* asset = NVBLAST_NEW(ExtPxAssetImpl)(tkAsset);
+
+ // Don't populate the chunks or subchunks!
+
+ return asset;
+}
+
+Nv::Blast::ExtPxAsset* ExtPxAsset::create(TkAsset* tkAsset, ExtPxAssetDesc::ChunkDesc* chunks, uint32_t chunkCount)
+{
+ ExtPxAssetImpl* asset = NVBLAST_NEW(ExtPxAssetImpl)(tkAsset, chunks, chunkCount);
+ return asset;
+}
+
+} // namespace Blast
+} // namespace Nv
diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxAssetImpl.h b/sdk/extensions/physx/source/physics/NvBlastExtPxAssetImpl.h index 96e2ed4..12770d0 100644..100755 --- a/sdk/extensions/physx/source/physics/NvBlastExtPxAssetImpl.h +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxAssetImpl.h @@ -1,163 +1,163 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#ifndef NVBLASTEXTPXASSETIMPL_H -#define NVBLASTEXTPXASSETIMPL_H - -#include "NvBlastExtPxAsset.h" -#include "NvBlastArray.h" - - -namespace Nv -{ -namespace Blast -{ - - -using namespace physx; -using namespace general_PxIOStream2; - - -// Macro to load a uint32_t (or larger) with four characters (move it in some shared header if it's used anywhere else in Ext) -#define NVBLASTEXT_FOURCC(_a, _b, _c, _d) ( (uint32_t)(_a) | (uint32_t)(_b)<<8 | (uint32_t)(_c)<<16 | (uint32_t)(_d)<<24 ) - - -class ExtPxAssetImpl final : public ExtPxAsset -{ - NV_NOCOPY(ExtPxAssetImpl) - -public: - friend class ExtPxAsset; - - //////// ctor //////// - - ExtPxAssetImpl(const ExtPxAssetDesc& desc, TkFramework& framework); - ExtPxAssetImpl(const TkAssetDesc& desc, ExtPxChunk* pxChunks, ExtPxSubchunk* pxSubchunks, TkFramework& framework); - ExtPxAssetImpl(TkAsset* asset, ExtPxAssetDesc::ChunkDesc* chunks, uint32_t chunkCount); - ExtPxAssetImpl(TkAsset* asset); - - ~ExtPxAssetImpl(); - - - //////// interface //////// - - virtual void release() override; - - virtual const TkAsset& getTkAsset() const override - { - return *m_tkAsset; - } - - virtual uint32_t getChunkCount() const override - { - return m_chunks.size(); - } - - virtual const ExtPxChunk* getChunks() const override - { - return m_chunks.begin(); - } - - virtual uint32_t getSubchunkCount() const override - { - return m_subchunks.size(); - } - - virtual const ExtPxSubchunk* getSubchunks() const override - { - return m_subchunks.begin(); - } - - virtual NvBlastActorDesc& getDefaultActorDesc() override - { - return m_defaultActorDesc; - } - - virtual const NvBlastActorDesc& getDefaultActorDesc() const override - { - return m_defaultActorDesc; - } - - virtual void setUniformHealth(bool enabled) override; - - virtual void setAccelerator(NvBlastExtDamageAccelerator* accelerator) override - { - m_accelerator = accelerator; - } - - virtual NvBlastExtDamageAccelerator* getAccelerator() const override - { - return m_accelerator; - } - - - //////// internal public methods //////// - - /* - Get the underlying array for the chunks. Used for serialization. - */ - Array<ExtPxChunk>::type& getChunksArray() { return m_chunks; } - - /* - Get the underlying array for the subchunks. Used for serialization. - */ - Array<ExtPxSubchunk>::type& getSubchunksArray() { return m_subchunks; } - - /* - Get the underlying array for the bond healths. Used for serialization. - */ - Array<float>::type& getBondHealthsArray() { return m_bondHealths; } - - /* - Get the underlying array for the support chunk healths. Used for serialization. - */ - Array<float>::type& getSupportChunkHealthsArray() { return m_supportChunkHealths; } - -private: - - //////// initialization ///////// - void fillPhysicsChunks(ExtPxChunk* pxChunks, ExtPxSubchunk* pxSuchunk, uint32_t chunkCount); - void fillPhysicsChunks(ExtPxAssetDesc::ChunkDesc* desc, uint32_t count); - - - //////// data //////// - - TkAsset* m_tkAsset; - Array<ExtPxChunk>::type m_chunks; - Array<ExtPxSubchunk>::type m_subchunks; - Array<float>::type m_bondHealths; - Array<float>::type m_supportChunkHealths; - NvBlastExtDamageAccelerator* m_accelerator; - NvBlastActorDesc m_defaultActorDesc; -}; - -} // namespace Blast -} // namespace Nv - - -#endif // ifndef NVBLASTEXTPXASSETIMPL_H +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#ifndef NVBLASTEXTPXASSETIMPL_H
+#define NVBLASTEXTPXASSETIMPL_H
+
+#include "NvBlastExtPxAsset.h"
+#include "NvBlastArray.h"
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+
+using namespace physx;
+using namespace general_PxIOStream2;
+
+
+// Macro to load a uint32_t (or larger) with four characters (move it in some shared header if it's used anywhere else in Ext)
+#define NVBLASTEXT_FOURCC(_a, _b, _c, _d) ( (uint32_t)(_a) | (uint32_t)(_b)<<8 | (uint32_t)(_c)<<16 | (uint32_t)(_d)<<24 )
+
+
+class ExtPxAssetImpl final : public ExtPxAsset
+{
+ NV_NOCOPY(ExtPxAssetImpl)
+
+public:
+ friend class ExtPxAsset;
+
+ //////// ctor ////////
+
+ ExtPxAssetImpl(const ExtPxAssetDesc& desc, TkFramework& framework);
+ ExtPxAssetImpl(const TkAssetDesc& desc, ExtPxChunk* pxChunks, ExtPxSubchunk* pxSubchunks, TkFramework& framework);
+ ExtPxAssetImpl(TkAsset* asset, ExtPxAssetDesc::ChunkDesc* chunks, uint32_t chunkCount);
+ ExtPxAssetImpl(TkAsset* asset);
+
+ ~ExtPxAssetImpl();
+
+
+ //////// interface ////////
+
+ virtual void release() override;
+
+ virtual const TkAsset& getTkAsset() const override
+ {
+ return *m_tkAsset;
+ }
+
+ virtual uint32_t getChunkCount() const override
+ {
+ return m_chunks.size();
+ }
+
+ virtual const ExtPxChunk* getChunks() const override
+ {
+ return m_chunks.begin();
+ }
+
+ virtual uint32_t getSubchunkCount() const override
+ {
+ return m_subchunks.size();
+ }
+
+ virtual const ExtPxSubchunk* getSubchunks() const override
+ {
+ return m_subchunks.begin();
+ }
+
+ virtual NvBlastActorDesc& getDefaultActorDesc() override
+ {
+ return m_defaultActorDesc;
+ }
+
+ virtual const NvBlastActorDesc& getDefaultActorDesc() const override
+ {
+ return m_defaultActorDesc;
+ }
+
+ virtual void setUniformHealth(bool enabled) override;
+
+ virtual void setAccelerator(NvBlastExtDamageAccelerator* accelerator) override
+ {
+ m_accelerator = accelerator;
+ }
+
+ virtual NvBlastExtDamageAccelerator* getAccelerator() const override
+ {
+ return m_accelerator;
+ }
+
+
+ //////// internal public methods ////////
+
+ /*
+ Get the underlying array for the chunks. Used for serialization.
+ */
+ Array<ExtPxChunk>::type& getChunksArray() { return m_chunks; }
+
+ /*
+ Get the underlying array for the subchunks. Used for serialization.
+ */
+ Array<ExtPxSubchunk>::type& getSubchunksArray() { return m_subchunks; }
+
+ /*
+ Get the underlying array for the bond healths. Used for serialization.
+ */
+ Array<float>::type& getBondHealthsArray() { return m_bondHealths; }
+
+ /*
+ Get the underlying array for the support chunk healths. Used for serialization.
+ */
+ Array<float>::type& getSupportChunkHealthsArray() { return m_supportChunkHealths; }
+
+private:
+
+ //////// initialization /////////
+ void fillPhysicsChunks(ExtPxChunk* pxChunks, ExtPxSubchunk* pxSuchunk, uint32_t chunkCount);
+ void fillPhysicsChunks(ExtPxAssetDesc::ChunkDesc* desc, uint32_t count);
+
+
+ //////// data ////////
+
+ TkAsset* m_tkAsset;
+ Array<ExtPxChunk>::type m_chunks;
+ Array<ExtPxSubchunk>::type m_subchunks;
+ Array<float>::type m_bondHealths;
+ Array<float>::type m_supportChunkHealths;
+ NvBlastExtDamageAccelerator* m_accelerator;
+ NvBlastActorDesc m_defaultActorDesc;
+};
+
+} // namespace Blast
+} // namespace Nv
+
+
+#endif // ifndef NVBLASTEXTPXASSETIMPL_H
diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxFamilyImpl.cpp b/sdk/extensions/physx/source/physics/NvBlastExtPxFamilyImpl.cpp index 027e67e..7bf5ede 100644..100755 --- a/sdk/extensions/physx/source/physics/NvBlastExtPxFamilyImpl.cpp +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxFamilyImpl.cpp @@ -1,320 +1,320 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#include "NvBlastExtPxFamilyImpl.h" -#include "NvBlastExtPxActorImpl.h" -#include "NvBlastExtPxAssetImpl.h" -#include "NvBlastExtPxListener.h" -#include "NvBlastExtPxManagerImpl.h" - -#include "NvBlastTkFamily.h" -#include "NvBlastTkActor.h" -#include "NvBlastTkJoint.h" - -#include "NvBlastAssert.h" - -#include "PxRigidDynamic.h" -#include "PxScene.h" - -#include <algorithm> - - -namespace Nv -{ -namespace Blast -{ - - -ExtPxFamilyImpl::ExtPxFamilyImpl(ExtPxManagerImpl& manager, TkFamily& tkFamily, ExtPxAsset& pxAsset) - : m_manager(manager) - , m_tkFamily(tkFamily) - , m_pxAsset(pxAsset) - , m_pxShapeDescTemplate(nullptr) - , m_pxActorDescTemplate(nullptr) - , m_material(nullptr) - , m_isSpawned(false) -{ - m_subchunkShapes.resize(static_cast<uint32_t>(m_pxAsset.getSubchunkCount())); - - userData = nullptr; - - m_manager.registerFamily(*this); -} - -ExtPxFamilyImpl::~ExtPxFamilyImpl() -{ - m_manager.unregisterFamily(*this); - - if (m_isSpawned) - { - m_tkFamily.removeListener(*this); - - auto& actors = m_actorsBuffer; - actors.resize(m_actors.size()); - uint32_t i = 0; - for (auto it = m_actors.getIterator(); !it.done(); ++it) - { - actors[i++] = *it; - } - destroyActors(actors.begin(), actors.size()); - } - - m_tkFamily.release(); -} - -void ExtPxFamilyImpl::release() -{ - NVBLAST_DELETE(this, ExtPxFamilyImpl); -} - -bool ExtPxFamilyImpl::spawn(const physx::PxTransform& pose, const physx::PxVec3& scale, const ExtPxSpawnSettings& settings) -{ - NVBLAST_CHECK_ERROR(!m_isSpawned, "Family spawn: family already spawned. Was spawn() called twice?", return false); - NVBLAST_CHECK_ERROR(settings.scene != nullptr, "Family creation: desc.scene is nullptr", return false); - NVBLAST_CHECK_ERROR(settings.material != nullptr, "Family creation: desc.material is nullptr", return false); - - m_initialTransform = pose; - m_spawnSettings = settings; - - // get current tkActors (usually it's only 1, but it can be already in split state) - const uint32_t actorCount = (uint32_t)m_tkFamily.getActorCount(); - m_newActorsBuffer.resize(actorCount); - m_tkFamily.getActors(m_newActorsBuffer.begin(), actorCount); - - // calc max split count - uint32_t splitMaxActorCount = 0; - for (TkActor* actor : m_newActorsBuffer) - { - splitMaxActorCount = std::max<uint32_t>(splitMaxActorCount, actor->getSplitMaxActorCount()); - } - - // preallocate memory - m_newActorsBuffer.resize(splitMaxActorCount); - m_newActorCreateInfo.resize(splitMaxActorCount); - m_physXActorsBuffer.resize(splitMaxActorCount); - m_physXActorsBuffer.resize(splitMaxActorCount); - m_indicesScratch.reserve(splitMaxActorCount); - - // fill initial actor create info - for (uint32_t i = 0; i < actorCount; ++i) - { - PxActorCreateInfo& pxActorInfo = m_newActorCreateInfo[i]; - pxActorInfo.m_parentAngularVelocity = PxVec3(PxZero); - pxActorInfo.m_parentLinearVelocity = PxVec3(PxZero); - pxActorInfo.m_transform = pose; - pxActorInfo.m_scale = scale; - } - - // create first actors in family - createActors(m_newActorsBuffer.begin(), m_newActorCreateInfo.begin(), actorCount); - - // listen family for new actors - m_tkFamily.addListener(*this); - - m_isSpawned = true; - - return true; -} - -bool ExtPxFamilyImpl::despawn() -{ - NVBLAST_CHECK_ERROR(m_spawnSettings.scene != nullptr, "Family despawn: desc.scene is nullptr", return false); - - auto& actors = m_actorsBuffer; - actors.resize(m_actors.size()); - uint32_t i = 0; - for (auto it = m_actors.getIterator(); !it.done(); ++it) - { - actors[i++] = *it; - } - destroyActors(actors.begin(), actors.size()); - - return true; -} - -void ExtPxFamilyImpl::receive(const TkEvent* events, uint32_t eventCount) -{ - auto& actorsToDelete = m_actorsBuffer; - actorsToDelete.clear(); - uint32_t totalNewActorsCount = 0; - - for (uint32_t i = 0; i < eventCount; ++i) - { - const TkEvent& e = events[i]; - if (e.type == TkEvent::Split) - { - const TkSplitEvent* splitEvent = e.getPayload<TkSplitEvent>(); - - uint32_t newActorsCount = splitEvent->numChildren; - - ExtPxActorImpl* parentActor = nullptr; - PxRigidDynamic* parentPxActor = nullptr; - if (splitEvent->parentData.userData) - { - parentActor = reinterpret_cast<ExtPxActorImpl*>(splitEvent->parentData.userData); - parentPxActor = &parentActor->getPhysXActor(); - } - - for (uint32_t j = totalNewActorsCount; j < totalNewActorsCount + newActorsCount; ++j) - { - const PxTransform parentTransform = parentPxActor ? parentPxActor->getGlobalPose() : m_initialTransform; - m_newActorCreateInfo[j].m_transform = parentTransform; - m_newActorCreateInfo[j].m_parentCOM = parentTransform.transform(parentPxActor ? parentPxActor->getCMassLocalPose().p : PxVec3(PxZero)); - - //TODO: Get the current scale of the actor! - m_newActorCreateInfo[j].m_scale = m_initialScale; - - m_newActorCreateInfo[j].m_parentLinearVelocity = parentPxActor ? parentPxActor->getLinearVelocity() : PxVec3(PxZero); - m_newActorCreateInfo[j].m_parentAngularVelocity = parentPxActor ? parentPxActor->getAngularVelocity() : PxVec3(PxZero); - - m_newActorsBuffer[j] = splitEvent->children[j - totalNewActorsCount]; - } - - totalNewActorsCount += newActorsCount; - - if (parentActor) - { - actorsToDelete.pushBack(parentActor); - } - } - } - - destroyActors(actorsToDelete.begin(), actorsToDelete.size()); - if (totalNewActorsCount > 0) - { - uint32_t cappedNewActorsCount = totalNewActorsCount; - const uint32_t actorCountLimit = m_manager.getActorCountLimit(); - const uint32_t totalActorCount = m_manager.getPxActorCount(); - if (actorCountLimit > 0 && cappedNewActorsCount + totalActorCount > actorCountLimit) - { - cappedNewActorsCount = actorCountLimit > totalActorCount ? actorCountLimit - totalActorCount : 0; - } - createActors(m_newActorsBuffer.begin(), m_newActorCreateInfo.begin(), cappedNewActorsCount); - m_culledActors.reserve(m_culledActors.size() + totalNewActorsCount - cappedNewActorsCount); - for (uint32_t i = cappedNewActorsCount; i < totalNewActorsCount; ++i) - { - m_culledActors.pushBack(m_newActorsBuffer[i]); - } - totalNewActorsCount = cappedNewActorsCount; // In case it's used below - } - - for (uint32_t i = 0; i < eventCount; ++i) - { - const TkEvent& e = events[i]; - if (e.type == TkEvent::JointUpdate) - { - const TkJointUpdateEvent* jointEvent = e.getPayload<TkJointUpdateEvent>(); - NVBLAST_ASSERT(jointEvent->joint); - TkJoint& joint = *jointEvent->joint; - - switch (jointEvent->subtype) - { - case TkJointUpdateEvent::External: - m_manager.createJoint(joint); - break; - case TkJointUpdateEvent::Changed: - m_manager.updateJoint(joint); - break; - case TkJointUpdateEvent::Unreferenced: - m_manager.destroyJoint(joint); - joint.release(); - break; - } - } - } -} - -void ExtPxFamilyImpl::createActors(TkActor** tkActors, const PxActorCreateInfo* pxActorInfos, uint32_t count) -{ - auto actorsToAdd = m_physXActorsBuffer.begin(); - for (uint32_t i = 0; i < count; ++i) - { - ExtPxActorImpl* actor = NVBLAST_NEW(ExtPxActorImpl)(this, tkActors[i], pxActorInfos[i]); - m_actors.insert(actor); - actorsToAdd[i] = &actor->getPhysXActor(); - dispatchActorCreated(*actor); - - // Handle incomplete joints - auto e = m_manager.m_incompleteJointMultiMap.find(tkActors[i]); - if (e != nullptr) - { - Array<TkJoint*>::type joints = e->second; // Copying the array - m_manager.m_incompleteJointMultiMap.erase(tkActors[i]); - for (uint32_t j = 0; j < joints.size(); ++j) - { - m_manager.updateJoint(*joints[j]); - } - } - } - m_spawnSettings.scene->addActors(actorsToAdd, static_cast<uint32_t>(count)); -} - -void ExtPxFamilyImpl::destroyActors(ExtPxActor** actors, uint32_t count) -{ - auto pxActorsToRemove = m_physXActorsBuffer.begin(); - for (uint32_t i = 0; i < count; ++i) - { - pxActorsToRemove[i] = &actors[i]->getPhysXActor(); - } - m_spawnSettings.scene->removeActors(pxActorsToRemove, static_cast<uint32_t>(count)); - - for (uint32_t i = 0; i < count; ++i) - { - ExtPxActorImpl* actor = (ExtPxActorImpl*)actors[i]; - m_actors.erase(actor); - dispatchActorDestroyed(*actor); - NVBLAST_DELETE(actor, ExtPxActorImpl); - } -} - -void ExtPxFamilyImpl::dispatchActorCreated(ExtPxActor& actor) -{ - for (ExtPxListener* listener : m_listeners) - listener->onActorCreated(*this, actor); - m_manager.dispatchActorCreated(*this, actor); -} - -void ExtPxFamilyImpl::dispatchActorDestroyed(ExtPxActor& actor) -{ - for (ExtPxListener* listener : m_listeners) - listener->onActorDestroyed(*this, actor); - m_manager.dispatchActorDestroyed(*this, actor); -} - -void ExtPxFamilyImpl::postSplitUpdate() -{ - for (auto actor : m_culledActors) - { - actor->release(); - } - m_culledActors.resize(0); -} - - -} // namespace Blast -} // namespace Nv +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#include "NvBlastExtPxFamilyImpl.h"
+#include "NvBlastExtPxActorImpl.h"
+#include "NvBlastExtPxAssetImpl.h"
+#include "NvBlastExtPxListener.h"
+#include "NvBlastExtPxManagerImpl.h"
+
+#include "NvBlastTkFamily.h"
+#include "NvBlastTkActor.h"
+#include "NvBlastTkJoint.h"
+
+#include "NvBlastAssert.h"
+
+#include "PxRigidDynamic.h"
+#include "PxScene.h"
+
+#include <algorithm>
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+
+ExtPxFamilyImpl::ExtPxFamilyImpl(ExtPxManagerImpl& manager, TkFamily& tkFamily, ExtPxAsset& pxAsset)
+ : m_manager(manager)
+ , m_tkFamily(tkFamily)
+ , m_pxAsset(pxAsset)
+ , m_pxShapeDescTemplate(nullptr)
+ , m_pxActorDescTemplate(nullptr)
+ , m_material(nullptr)
+ , m_isSpawned(false)
+{
+ m_subchunkShapes.resize(static_cast<uint32_t>(m_pxAsset.getSubchunkCount()));
+
+ userData = nullptr;
+
+ m_manager.registerFamily(*this);
+}
+
+ExtPxFamilyImpl::~ExtPxFamilyImpl()
+{
+ m_manager.unregisterFamily(*this);
+
+ if (m_isSpawned)
+ {
+ m_tkFamily.removeListener(*this);
+
+ auto& actors = m_actorsBuffer;
+ actors.resize(m_actors.size());
+ uint32_t i = 0;
+ for (auto it = m_actors.getIterator(); !it.done(); ++it)
+ {
+ actors[i++] = *it;
+ }
+ destroyActors(actors.begin(), actors.size());
+ }
+
+ m_tkFamily.release();
+}
+
+void ExtPxFamilyImpl::release()
+{
+ NVBLAST_DELETE(this, ExtPxFamilyImpl);
+}
+
+bool ExtPxFamilyImpl::spawn(const physx::PxTransform& pose, const physx::PxVec3& scale, const ExtPxSpawnSettings& settings)
+{
+ NVBLAST_CHECK_ERROR(!m_isSpawned, "Family spawn: family already spawned. Was spawn() called twice?", return false);
+ NVBLAST_CHECK_ERROR(settings.scene != nullptr, "Family creation: desc.scene is nullptr", return false);
+ NVBLAST_CHECK_ERROR(settings.material != nullptr, "Family creation: desc.material is nullptr", return false);
+
+ m_initialTransform = pose;
+ m_spawnSettings = settings;
+
+ // get current tkActors (usually it's only 1, but it can be already in split state)
+ const uint32_t actorCount = (uint32_t)m_tkFamily.getActorCount();
+ m_newActorsBuffer.resize(actorCount);
+ m_tkFamily.getActors(m_newActorsBuffer.begin(), actorCount);
+
+ // calc max split count
+ uint32_t splitMaxActorCount = 0;
+ for (TkActor* actor : m_newActorsBuffer)
+ {
+ splitMaxActorCount = std::max<uint32_t>(splitMaxActorCount, actor->getSplitMaxActorCount());
+ }
+
+ // preallocate memory
+ m_newActorsBuffer.resize(splitMaxActorCount);
+ m_newActorCreateInfo.resize(splitMaxActorCount);
+ m_physXActorsBuffer.resize(splitMaxActorCount);
+ m_physXActorsBuffer.resize(splitMaxActorCount);
+ m_indicesScratch.reserve(splitMaxActorCount);
+
+ // fill initial actor create info
+ for (uint32_t i = 0; i < actorCount; ++i)
+ {
+ PxActorCreateInfo& pxActorInfo = m_newActorCreateInfo[i];
+ pxActorInfo.m_parentAngularVelocity = PxVec3(PxZero);
+ pxActorInfo.m_parentLinearVelocity = PxVec3(PxZero);
+ pxActorInfo.m_transform = pose;
+ pxActorInfo.m_scale = scale;
+ }
+
+ // create first actors in family
+ createActors(m_newActorsBuffer.begin(), m_newActorCreateInfo.begin(), actorCount);
+
+ // listen family for new actors
+ m_tkFamily.addListener(*this);
+
+ m_isSpawned = true;
+
+ return true;
+}
+
+bool ExtPxFamilyImpl::despawn()
+{
+ NVBLAST_CHECK_ERROR(m_spawnSettings.scene != nullptr, "Family despawn: desc.scene is nullptr", return false);
+
+ auto& actors = m_actorsBuffer;
+ actors.resize(m_actors.size());
+ uint32_t i = 0;
+ for (auto it = m_actors.getIterator(); !it.done(); ++it)
+ {
+ actors[i++] = *it;
+ }
+ destroyActors(actors.begin(), actors.size());
+
+ return true;
+}
+
+void ExtPxFamilyImpl::receive(const TkEvent* events, uint32_t eventCount)
+{
+ auto& actorsToDelete = m_actorsBuffer;
+ actorsToDelete.clear();
+ uint32_t totalNewActorsCount = 0;
+
+ for (uint32_t i = 0; i < eventCount; ++i)
+ {
+ const TkEvent& e = events[i];
+ if (e.type == TkEvent::Split)
+ {
+ const TkSplitEvent* splitEvent = e.getPayload<TkSplitEvent>();
+
+ uint32_t newActorsCount = splitEvent->numChildren;
+
+ ExtPxActorImpl* parentActor = nullptr;
+ PxRigidDynamic* parentPxActor = nullptr;
+ if (splitEvent->parentData.userData)
+ {
+ parentActor = reinterpret_cast<ExtPxActorImpl*>(splitEvent->parentData.userData);
+ parentPxActor = &parentActor->getPhysXActor();
+ }
+
+ for (uint32_t j = totalNewActorsCount; j < totalNewActorsCount + newActorsCount; ++j)
+ {
+ const PxTransform parentTransform = parentPxActor ? parentPxActor->getGlobalPose() : m_initialTransform;
+ m_newActorCreateInfo[j].m_transform = parentTransform;
+ m_newActorCreateInfo[j].m_parentCOM = parentTransform.transform(parentPxActor ? parentPxActor->getCMassLocalPose().p : PxVec3(PxZero));
+
+ //TODO: Get the current scale of the actor!
+ m_newActorCreateInfo[j].m_scale = m_initialScale;
+
+ m_newActorCreateInfo[j].m_parentLinearVelocity = parentPxActor ? parentPxActor->getLinearVelocity() : PxVec3(PxZero);
+ m_newActorCreateInfo[j].m_parentAngularVelocity = parentPxActor ? parentPxActor->getAngularVelocity() : PxVec3(PxZero);
+
+ m_newActorsBuffer[j] = splitEvent->children[j - totalNewActorsCount];
+ }
+
+ totalNewActorsCount += newActorsCount;
+
+ if (parentActor)
+ {
+ actorsToDelete.pushBack(parentActor);
+ }
+ }
+ }
+
+ destroyActors(actorsToDelete.begin(), actorsToDelete.size());
+ if (totalNewActorsCount > 0)
+ {
+ uint32_t cappedNewActorsCount = totalNewActorsCount;
+ const uint32_t actorCountLimit = m_manager.getActorCountLimit();
+ const uint32_t totalActorCount = m_manager.getPxActorCount();
+ if (actorCountLimit > 0 && cappedNewActorsCount + totalActorCount > actorCountLimit)
+ {
+ cappedNewActorsCount = actorCountLimit > totalActorCount ? actorCountLimit - totalActorCount : 0;
+ }
+ createActors(m_newActorsBuffer.begin(), m_newActorCreateInfo.begin(), cappedNewActorsCount);
+ m_culledActors.reserve(m_culledActors.size() + totalNewActorsCount - cappedNewActorsCount);
+ for (uint32_t i = cappedNewActorsCount; i < totalNewActorsCount; ++i)
+ {
+ m_culledActors.pushBack(m_newActorsBuffer[i]);
+ }
+ totalNewActorsCount = cappedNewActorsCount; // In case it's used below
+ }
+
+ for (uint32_t i = 0; i < eventCount; ++i)
+ {
+ const TkEvent& e = events[i];
+ if (e.type == TkEvent::JointUpdate)
+ {
+ const TkJointUpdateEvent* jointEvent = e.getPayload<TkJointUpdateEvent>();
+ NVBLAST_ASSERT(jointEvent->joint);
+ TkJoint& joint = *jointEvent->joint;
+
+ switch (jointEvent->subtype)
+ {
+ case TkJointUpdateEvent::External:
+ m_manager.createJoint(joint);
+ break;
+ case TkJointUpdateEvent::Changed:
+ m_manager.updateJoint(joint);
+ break;
+ case TkJointUpdateEvent::Unreferenced:
+ m_manager.destroyJoint(joint);
+ joint.release();
+ break;
+ }
+ }
+ }
+}
+
+void ExtPxFamilyImpl::createActors(TkActor** tkActors, const PxActorCreateInfo* pxActorInfos, uint32_t count)
+{
+ auto actorsToAdd = m_physXActorsBuffer.begin();
+ for (uint32_t i = 0; i < count; ++i)
+ {
+ ExtPxActorImpl* actor = NVBLAST_NEW(ExtPxActorImpl)(this, tkActors[i], pxActorInfos[i]);
+ m_actors.insert(actor);
+ actorsToAdd[i] = &actor->getPhysXActor();
+ dispatchActorCreated(*actor);
+
+ // Handle incomplete joints
+ auto e = m_manager.m_incompleteJointMultiMap.find(tkActors[i]);
+ if (e != nullptr)
+ {
+ Array<TkJoint*>::type joints = e->second; // Copying the array
+ m_manager.m_incompleteJointMultiMap.erase(tkActors[i]);
+ for (uint32_t j = 0; j < joints.size(); ++j)
+ {
+ m_manager.updateJoint(*joints[j]);
+ }
+ }
+ }
+ m_spawnSettings.scene->addActors(actorsToAdd, static_cast<uint32_t>(count));
+}
+
+void ExtPxFamilyImpl::destroyActors(ExtPxActor** actors, uint32_t count)
+{
+ auto pxActorsToRemove = m_physXActorsBuffer.begin();
+ for (uint32_t i = 0; i < count; ++i)
+ {
+ pxActorsToRemove[i] = &actors[i]->getPhysXActor();
+ }
+ m_spawnSettings.scene->removeActors(pxActorsToRemove, static_cast<uint32_t>(count));
+
+ for (uint32_t i = 0; i < count; ++i)
+ {
+ ExtPxActorImpl* actor = (ExtPxActorImpl*)actors[i];
+ m_actors.erase(actor);
+ dispatchActorDestroyed(*actor);
+ NVBLAST_DELETE(actor, ExtPxActorImpl);
+ }
+}
+
+void ExtPxFamilyImpl::dispatchActorCreated(ExtPxActor& actor)
+{
+ for (ExtPxListener* listener : m_listeners)
+ listener->onActorCreated(*this, actor);
+ m_manager.dispatchActorCreated(*this, actor);
+}
+
+void ExtPxFamilyImpl::dispatchActorDestroyed(ExtPxActor& actor)
+{
+ for (ExtPxListener* listener : m_listeners)
+ listener->onActorDestroyed(*this, actor);
+ m_manager.dispatchActorDestroyed(*this, actor);
+}
+
+void ExtPxFamilyImpl::postSplitUpdate()
+{
+ for (auto actor : m_culledActors)
+ {
+ actor->release();
+ }
+ m_culledActors.resize(0);
+}
+
+
+} // namespace Blast
+} // namespace Nv
diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxFamilyImpl.h b/sdk/extensions/physx/source/physics/NvBlastExtPxFamilyImpl.h index f839b65..ae4ea40 100644..100755 --- a/sdk/extensions/physx/source/physics/NvBlastExtPxFamilyImpl.h +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxFamilyImpl.h @@ -1,197 +1,197 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#ifndef NVBLASTEXTPXFAMILYIMPL_H -#define NVBLASTEXTPXFAMILYIMPL_H - -#include "NvBlastExtPxFamily.h" -#include "NvBlastArray.h" -#include "NvBlastHashSet.h" -#include "PxTransform.h" -#include "NvBlastTkEvent.h" - - -using namespace physx; - - -namespace Nv -{ -namespace Blast -{ - -// Forward declarations -class ExtPxManagerImpl; -class ExtPxActorImpl; -struct PxActorCreateInfo; - - -class ExtPxFamilyImpl final : public ExtPxFamily, TkEventListener -{ - NV_NOCOPY(ExtPxFamilyImpl) - -public: - friend ExtPxActorImpl; - friend ExtPxManagerImpl; - - //////// ctor //////// - - ExtPxFamilyImpl(ExtPxManagerImpl& manager, TkFamily& tkFamily, ExtPxAsset& pxAsset); - ~ExtPxFamilyImpl(); - - virtual void release() override; - - - //////// ExtPxFamily interface //////// - -// virtual bool spawn(const PxTransform& pose, const ExtPxSpawnSettings& settings) override; - virtual bool spawn(const physx::PxTransform& pose, const physx::PxVec3& scale, const ExtPxSpawnSettings& settings) override; - virtual bool despawn() override; - - - virtual uint32_t getActorCount() const override - { - return m_actors.size(); - } - - virtual uint32_t getActors(ExtPxActor** buffer, uint32_t bufferSize) const override - { - uint32_t index = 0; - for (auto it = const_cast<ExtPxFamilyImpl*>(this)->m_actors.getIterator(); !it.done() && index < bufferSize; ++it) - { - buffer[index++] = *it; - } - return index; - } - - virtual TkFamily& getTkFamily() const override - { - return m_tkFamily; - } - - virtual const physx::PxShape* const* getSubchunkShapes() const override - { - return m_subchunkShapes.begin(); - } - - virtual ExtPxAsset& getPxAsset() const override - { - return m_pxAsset; - } - - virtual void setMaterial(PxMaterial& material) override - { - m_spawnSettings.material = &material; - } - - virtual void setPxShapeDescTemplate(const ExtPxShapeDescTemplate* pxShapeDesc) override - { - m_pxShapeDescTemplate = pxShapeDesc; - } - - virtual const ExtPxShapeDescTemplate* getPxShapeDescTemplate() const override - { - return m_pxShapeDescTemplate; - } - - virtual void setPxActorDesc(const ExtPxActorDescTemplate* pxActorDesc) override - { - m_pxActorDescTemplate = pxActorDesc; - } - - virtual const ExtPxActorDescTemplate* getPxActorDesc() const override - { - return m_pxActorDescTemplate; - } - - virtual const NvBlastExtMaterial* getMaterial() const override - { - return m_material; - } - - virtual void setMaterial(const NvBlastExtMaterial* material) override - { - m_material = material; - } - - virtual void subscribe(ExtPxListener& listener) override - { - m_listeners.pushBack(&listener); - } - - virtual void unsubscribe(ExtPxListener& listener) override - { - m_listeners.findAndReplaceWithLast(&listener); - } - - virtual void postSplitUpdate() override; - - //////// TkEventListener interface //////// - - virtual void receive(const TkEvent* events, uint32_t eventCount) override; - - - //////// events dispatch //////// - - void dispatchActorCreated(ExtPxActor& actor); - void dispatchActorDestroyed(ExtPxActor& actor); - - -private: - //////// private methods //////// - - void createActors(TkActor** tkActors, const PxActorCreateInfo* pxActorInfos, uint32_t count); - void destroyActors(ExtPxActor** actors, uint32_t count); - - //////// data //////// - - ExtPxManagerImpl& m_manager; - TkFamily& m_tkFamily; - ExtPxAsset& m_pxAsset; - ExtPxSpawnSettings m_spawnSettings; - const ExtPxShapeDescTemplate* m_pxShapeDescTemplate; - const ExtPxActorDescTemplate* m_pxActorDescTemplate; - const NvBlastExtMaterial* m_material; - bool m_isSpawned; - PxTransform m_initialTransform; - PxVec3 m_initialScale; - HashSet<ExtPxActor*>::type m_actors; - Array<TkActor*>::type m_culledActors; - InlineArray<ExtPxListener*, 4>::type m_listeners; - Array<PxShape*>::type m_subchunkShapes; - Array<TkActor*>::type m_newActorsBuffer; - Array<PxActorCreateInfo>::type m_newActorCreateInfo; - Array<PxActor*>::type m_physXActorsBuffer; - Array<ExtPxActor*>::type m_actorsBuffer; - Array<uint32_t>::type m_indicesScratch; -}; - -} // namespace Blast -} // namespace Nv - - -#endif // ifndef NVBLASTEXTPXFAMILYIMPL_H +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#ifndef NVBLASTEXTPXFAMILYIMPL_H
+#define NVBLASTEXTPXFAMILYIMPL_H
+
+#include "NvBlastExtPxFamily.h"
+#include "NvBlastArray.h"
+#include "NvBlastHashSet.h"
+#include "PxTransform.h"
+#include "NvBlastTkEvent.h"
+
+
+using namespace physx;
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+// Forward declarations
+class ExtPxManagerImpl;
+class ExtPxActorImpl;
+struct PxActorCreateInfo;
+
+
+class ExtPxFamilyImpl final : public ExtPxFamily, TkEventListener
+{
+ NV_NOCOPY(ExtPxFamilyImpl)
+
+public:
+ friend ExtPxActorImpl;
+ friend ExtPxManagerImpl;
+
+ //////// ctor ////////
+
+ ExtPxFamilyImpl(ExtPxManagerImpl& manager, TkFamily& tkFamily, ExtPxAsset& pxAsset);
+ ~ExtPxFamilyImpl();
+
+ virtual void release() override;
+
+
+ //////// ExtPxFamily interface ////////
+
+// virtual bool spawn(const PxTransform& pose, const ExtPxSpawnSettings& settings) override;
+ virtual bool spawn(const physx::PxTransform& pose, const physx::PxVec3& scale, const ExtPxSpawnSettings& settings) override;
+ virtual bool despawn() override;
+
+
+ virtual uint32_t getActorCount() const override
+ {
+ return m_actors.size();
+ }
+
+ virtual uint32_t getActors(ExtPxActor** buffer, uint32_t bufferSize) const override
+ {
+ uint32_t index = 0;
+ for (auto it = const_cast<ExtPxFamilyImpl*>(this)->m_actors.getIterator(); !it.done() && index < bufferSize; ++it)
+ {
+ buffer[index++] = *it;
+ }
+ return index;
+ }
+
+ virtual TkFamily& getTkFamily() const override
+ {
+ return m_tkFamily;
+ }
+
+ virtual const physx::PxShape* const* getSubchunkShapes() const override
+ {
+ return m_subchunkShapes.begin();
+ }
+
+ virtual ExtPxAsset& getPxAsset() const override
+ {
+ return m_pxAsset;
+ }
+
+ virtual void setMaterial(PxMaterial& material) override
+ {
+ m_spawnSettings.material = &material;
+ }
+
+ virtual void setPxShapeDescTemplate(const ExtPxShapeDescTemplate* pxShapeDesc) override
+ {
+ m_pxShapeDescTemplate = pxShapeDesc;
+ }
+
+ virtual const ExtPxShapeDescTemplate* getPxShapeDescTemplate() const override
+ {
+ return m_pxShapeDescTemplate;
+ }
+
+ virtual void setPxActorDesc(const ExtPxActorDescTemplate* pxActorDesc) override
+ {
+ m_pxActorDescTemplate = pxActorDesc;
+ }
+
+ virtual const ExtPxActorDescTemplate* getPxActorDesc() const override
+ {
+ return m_pxActorDescTemplate;
+ }
+
+ virtual const NvBlastExtMaterial* getMaterial() const override
+ {
+ return m_material;
+ }
+
+ virtual void setMaterial(const NvBlastExtMaterial* material) override
+ {
+ m_material = material;
+ }
+
+ virtual void subscribe(ExtPxListener& listener) override
+ {
+ m_listeners.pushBack(&listener);
+ }
+
+ virtual void unsubscribe(ExtPxListener& listener) override
+ {
+ m_listeners.findAndReplaceWithLast(&listener);
+ }
+
+ virtual void postSplitUpdate() override;
+
+ //////// TkEventListener interface ////////
+
+ virtual void receive(const TkEvent* events, uint32_t eventCount) override;
+
+
+ //////// events dispatch ////////
+
+ void dispatchActorCreated(ExtPxActor& actor);
+ void dispatchActorDestroyed(ExtPxActor& actor);
+
+
+private:
+ //////// private methods ////////
+
+ void createActors(TkActor** tkActors, const PxActorCreateInfo* pxActorInfos, uint32_t count);
+ void destroyActors(ExtPxActor** actors, uint32_t count);
+
+ //////// data ////////
+
+ ExtPxManagerImpl& m_manager;
+ TkFamily& m_tkFamily;
+ ExtPxAsset& m_pxAsset;
+ ExtPxSpawnSettings m_spawnSettings;
+ const ExtPxShapeDescTemplate* m_pxShapeDescTemplate;
+ const ExtPxActorDescTemplate* m_pxActorDescTemplate;
+ const NvBlastExtMaterial* m_material;
+ bool m_isSpawned;
+ PxTransform m_initialTransform;
+ PxVec3 m_initialScale;
+ HashSet<ExtPxActor*>::type m_actors;
+ Array<TkActor*>::type m_culledActors;
+ InlineArray<ExtPxListener*, 4>::type m_listeners;
+ Array<PxShape*>::type m_subchunkShapes;
+ Array<TkActor*>::type m_newActorsBuffer;
+ Array<PxActorCreateInfo>::type m_newActorCreateInfo;
+ Array<PxActor*>::type m_physXActorsBuffer;
+ Array<ExtPxActor*>::type m_actorsBuffer;
+ Array<uint32_t>::type m_indicesScratch;
+};
+
+} // namespace Blast
+} // namespace Nv
+
+
+#endif // ifndef NVBLASTEXTPXFAMILYIMPL_H
diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxManagerImpl.cpp b/sdk/extensions/physx/source/physics/NvBlastExtPxManagerImpl.cpp index 1ac0aec..018ff74 100644..100755 --- a/sdk/extensions/physx/source/physics/NvBlastExtPxManagerImpl.cpp +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxManagerImpl.cpp @@ -1,171 +1,171 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#include "NvBlastExtPxManagerImpl.h" -#include "NvBlastExtPxAssetImpl.h" -#include "NvBlastExtPxActorImpl.h" -#include "NvBlastExtPxFamilyImpl.h" - -#include "NvBlastAssert.h" - -#include "NvBlastTkActor.h" -#include "NvBlastTkFamily.h" -#include "NvBlastTkGroup.h" -#include "NvBlastTkJoint.h" - -#include "PxRigidDynamic.h" -#include "PxJoint.h" - - -namespace Nv -{ -namespace Blast -{ - - -ExtPxManager* ExtPxManager::create(PxPhysics& physics, TkFramework& framework, ExtPxCreateJointFunction createFn, bool useUserData) -{ - return NVBLAST_NEW(ExtPxManagerImpl)(physics, framework, createFn, useUserData); -} - -void ExtPxManagerImpl::release() -{ - NVBLAST_DELETE(this, ExtPxManagerImpl); -} - -ExtPxFamily* ExtPxManagerImpl::createFamily(const ExtPxFamilyDesc& desc) -{ - NVBLAST_CHECK_ERROR(desc.pxAsset != nullptr, "Family creation: pxAsset is nullptr.", return nullptr); - - // prepare TkActorDesc (take NvBlastActorDesc from ExtPxFamilyDesc if it's not null, otherwise take from PxAsset) - TkActorDesc tkActorDesc; - const NvBlastActorDesc& actorDesc = desc.actorDesc ? *desc.actorDesc : desc.pxAsset->getDefaultActorDesc(); - (&tkActorDesc)->NvBlastActorDesc::operator=(actorDesc); - tkActorDesc.asset = &desc.pxAsset->getTkAsset(); - - // create tk actor - TkActor* actor = m_framework.createActor(tkActorDesc); - NVBLAST_CHECK_ERROR(actor != nullptr, "Family creation: tk actor creation failed.", return nullptr); - - // create px family - ExtPxFamilyImpl* family = NVBLAST_NEW(ExtPxFamilyImpl)(*this, actor->getFamily(), *desc.pxAsset); - - if (desc.group) - { - desc.group->addActor(*actor); - } - - return family; -} - -bool ExtPxManagerImpl::createJoint(TkJoint& joint) -{ - if (!joint.userData && m_createJointFn) - { - const TkJointData data = joint.getData(); - ExtPxActorImpl* pxActor0 = data.actors[0] != nullptr ? reinterpret_cast<ExtPxActorImpl*>(data.actors[0]->userData) : nullptr; - ExtPxActorImpl* pxActor1 = data.actors[1] != nullptr ? reinterpret_cast<ExtPxActorImpl*>(data.actors[1]->userData) : nullptr; - if (!pxActor0 && !pxActor1) - { - for (int i = 0; i < 2; ++i) - { - if (data.actors[i] != nullptr) - { - m_incompleteJointMultiMap[data.actors[i]].pushBack(&joint); - } - } - return false; - } - PxTransform lf0(data.attachPositions[0]); - PxTransform lf1(data.attachPositions[1]); - PxJoint* pxJoint = m_createJointFn(pxActor0, lf0, pxActor1, lf1, m_physics, joint); - if (pxJoint) - { - joint.userData = pxJoint; - return true; - } - } - return false; -} - -void ExtPxManagerImpl::updateJoint(TkJoint& joint) -{ - const TkJointData& data = joint.getData(); - if (joint.userData) - { - ExtPxActorImpl* pxActors[2]; - for (int i = 0; i < 2; ++i) - { - if (data.actors[i] != nullptr) - { - pxActors[i] = reinterpret_cast<ExtPxActorImpl*>(data.actors[i]->userData); - if (pxActors[i] == nullptr) - { - Array<TkJoint*>::type& joints = m_incompleteJointMultiMap[data.actors[i]]; - NVBLAST_ASSERT(joints.find(&joint) == joints.end()); - joints.pushBack(&joint); - return; // Wait until the TkActor is received to create this joint - } - } - else - { - pxActors[i] = nullptr; - } - } - NVBLAST_ASSERT(pxActors[0] || pxActors[1]); - PxJoint* pxJoint = reinterpret_cast<PxJoint*>(joint.userData); - pxJoint->setActors(pxActors[0] ? &pxActors[0]->getPhysXActor() : nullptr, pxActors[1] ? &pxActors[1]->getPhysXActor() : nullptr); - } - else - { - ExtPxActorImpl* pxActor0 = data.actors[0] != nullptr ? reinterpret_cast<ExtPxActorImpl*>(data.actors[0]->userData) : nullptr; - ExtPxActorImpl* pxActor1 = data.actors[1] != nullptr ? reinterpret_cast<ExtPxActorImpl*>(data.actors[1]->userData) : nullptr; - PxTransform lf0(data.attachPositions[0]); - PxTransform lf1(data.attachPositions[1]); - PxJoint* pxJoint = m_createJointFn(pxActor0, lf0, pxActor1, lf1, m_physics, joint); - if (pxJoint) - { - joint.userData = pxJoint; - } - } -} - -void ExtPxManagerImpl::destroyJoint(TkJoint& joint) -{ - if (joint.userData) - { - PxJoint* pxJoint = reinterpret_cast<PxJoint*>(joint.userData); - pxJoint->release(); - joint.userData = nullptr; - } -} - - - -} // namespace Blast -} // namespace Nv +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#include "NvBlastExtPxManagerImpl.h"
+#include "NvBlastExtPxAssetImpl.h"
+#include "NvBlastExtPxActorImpl.h"
+#include "NvBlastExtPxFamilyImpl.h"
+
+#include "NvBlastAssert.h"
+
+#include "NvBlastTkActor.h"
+#include "NvBlastTkFamily.h"
+#include "NvBlastTkGroup.h"
+#include "NvBlastTkJoint.h"
+
+#include "PxRigidDynamic.h"
+#include "PxJoint.h"
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+
+ExtPxManager* ExtPxManager::create(PxPhysics& physics, TkFramework& framework, ExtPxCreateJointFunction createFn, bool useUserData)
+{
+ return NVBLAST_NEW(ExtPxManagerImpl)(physics, framework, createFn, useUserData);
+}
+
+void ExtPxManagerImpl::release()
+{
+ NVBLAST_DELETE(this, ExtPxManagerImpl);
+}
+
+ExtPxFamily* ExtPxManagerImpl::createFamily(const ExtPxFamilyDesc& desc)
+{
+ NVBLAST_CHECK_ERROR(desc.pxAsset != nullptr, "Family creation: pxAsset is nullptr.", return nullptr);
+
+ // prepare TkActorDesc (take NvBlastActorDesc from ExtPxFamilyDesc if it's not null, otherwise take from PxAsset)
+ TkActorDesc tkActorDesc;
+ const NvBlastActorDesc& actorDesc = desc.actorDesc ? *desc.actorDesc : desc.pxAsset->getDefaultActorDesc();
+ (&tkActorDesc)->NvBlastActorDesc::operator=(actorDesc);
+ tkActorDesc.asset = &desc.pxAsset->getTkAsset();
+
+ // create tk actor
+ TkActor* actor = m_framework.createActor(tkActorDesc);
+ NVBLAST_CHECK_ERROR(actor != nullptr, "Family creation: tk actor creation failed.", return nullptr);
+
+ // create px family
+ ExtPxFamilyImpl* family = NVBLAST_NEW(ExtPxFamilyImpl)(*this, actor->getFamily(), *desc.pxAsset);
+
+ if (desc.group)
+ {
+ desc.group->addActor(*actor);
+ }
+
+ return family;
+}
+
+bool ExtPxManagerImpl::createJoint(TkJoint& joint)
+{
+ if (!joint.userData && m_createJointFn)
+ {
+ const TkJointData data = joint.getData();
+ ExtPxActorImpl* pxActor0 = data.actors[0] != nullptr ? reinterpret_cast<ExtPxActorImpl*>(data.actors[0]->userData) : nullptr;
+ ExtPxActorImpl* pxActor1 = data.actors[1] != nullptr ? reinterpret_cast<ExtPxActorImpl*>(data.actors[1]->userData) : nullptr;
+ if (!pxActor0 && !pxActor1)
+ {
+ for (int i = 0; i < 2; ++i)
+ {
+ if (data.actors[i] != nullptr)
+ {
+ m_incompleteJointMultiMap[data.actors[i]].pushBack(&joint);
+ }
+ }
+ return false;
+ }
+ PxTransform lf0(data.attachPositions[0]);
+ PxTransform lf1(data.attachPositions[1]);
+ PxJoint* pxJoint = m_createJointFn(pxActor0, lf0, pxActor1, lf1, m_physics, joint);
+ if (pxJoint)
+ {
+ joint.userData = pxJoint;
+ return true;
+ }
+ }
+ return false;
+}
+
+void ExtPxManagerImpl::updateJoint(TkJoint& joint)
+{
+ const TkJointData& data = joint.getData();
+ if (joint.userData)
+ {
+ ExtPxActorImpl* pxActors[2];
+ for (int i = 0; i < 2; ++i)
+ {
+ if (data.actors[i] != nullptr)
+ {
+ pxActors[i] = reinterpret_cast<ExtPxActorImpl*>(data.actors[i]->userData);
+ if (pxActors[i] == nullptr)
+ {
+ Array<TkJoint*>::type& joints = m_incompleteJointMultiMap[data.actors[i]];
+ NVBLAST_ASSERT(joints.find(&joint) == joints.end());
+ joints.pushBack(&joint);
+ return; // Wait until the TkActor is received to create this joint
+ }
+ }
+ else
+ {
+ pxActors[i] = nullptr;
+ }
+ }
+ NVBLAST_ASSERT(pxActors[0] || pxActors[1]);
+ PxJoint* pxJoint = reinterpret_cast<PxJoint*>(joint.userData);
+ pxJoint->setActors(pxActors[0] ? &pxActors[0]->getPhysXActor() : nullptr, pxActors[1] ? &pxActors[1]->getPhysXActor() : nullptr);
+ }
+ else
+ {
+ ExtPxActorImpl* pxActor0 = data.actors[0] != nullptr ? reinterpret_cast<ExtPxActorImpl*>(data.actors[0]->userData) : nullptr;
+ ExtPxActorImpl* pxActor1 = data.actors[1] != nullptr ? reinterpret_cast<ExtPxActorImpl*>(data.actors[1]->userData) : nullptr;
+ PxTransform lf0(data.attachPositions[0]);
+ PxTransform lf1(data.attachPositions[1]);
+ PxJoint* pxJoint = m_createJointFn(pxActor0, lf0, pxActor1, lf1, m_physics, joint);
+ if (pxJoint)
+ {
+ joint.userData = pxJoint;
+ }
+ }
+}
+
+void ExtPxManagerImpl::destroyJoint(TkJoint& joint)
+{
+ if (joint.userData)
+ {
+ PxJoint* pxJoint = reinterpret_cast<PxJoint*>(joint.userData);
+ pxJoint->release();
+ joint.userData = nullptr;
+ }
+}
+
+
+
+} // namespace Blast
+} // namespace Nv
diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxManagerImpl.h b/sdk/extensions/physx/source/physics/NvBlastExtPxManagerImpl.h index 168ac3c..aeed587 100644..100755 --- a/sdk/extensions/physx/source/physics/NvBlastExtPxManagerImpl.h +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxManagerImpl.h @@ -1,220 +1,220 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#ifndef NVBLASTEXTPXMANAGERIMPL_H -#define NVBLASTEXTPXMANAGERIMPL_H - -#include "NvBlastExtPxManager.h" -#include "NvBlastArray.h" -#include "NvBlastHashMap.h" -#include "NvBlastExtPxListener.h" -#include "NvBlastExtPxFamily.h" - -#include "PxRigidDynamic.h" - - -using namespace physx; - - -namespace Nv -{ -namespace Blast -{ - -// Forward declarations -class TkActor; - -class ExtPxManagerImpl final : public ExtPxManager -{ - NV_NOCOPY(ExtPxManagerImpl) - -public: - friend class ExtPxActorImpl; - friend class ExtPxFamilyImpl; - - ExtPxManagerImpl(PxPhysics& physics, TkFramework&framework, ExtPxCreateJointFunction createFn, bool usePxUserData) - : m_physics(physics), m_framework(framework), m_createJointFn(createFn), m_usePxUserData(usePxUserData), m_actorCountLimit(0) - { - } - - ~ExtPxManagerImpl() - { - } - - virtual void release() override; - - - //////// interface //////// - - virtual ExtPxFamily* createFamily(const ExtPxFamilyDesc& desc) override; - - virtual bool createJoint(TkJoint& joint) override; - - virtual void destroyJoint(TkJoint& joint) override; - - virtual void setCreateJointFunction(ExtPxCreateJointFunction createFn) override - { - m_createJointFn = createFn; - } - - virtual uint32_t getFamilyCount() const override - { - return m_tkFamiliesMap.size(); - } - - virtual uint32_t getFamilies(ExtPxFamily** buffer, uint32_t bufferSize) const override - { - uint32_t index = 0; - for (auto it = const_cast<ExtPxManagerImpl*>(this)->m_tkFamiliesMap.getIterator(); !it.done() && index < bufferSize; ++it) - { - buffer[index++] = it->second; - } - return index; - } - - virtual ExtPxFamily* getFamilyFromTkFamily(TkFamily& family) const override - { - auto entry = m_tkFamiliesMap.find(&family); - return entry != nullptr ? entry->second : nullptr; - } - - virtual ExtPxActor* getActorFromPhysXActor(const PxRigidDynamic& pxActor) const override - { - auto it = m_physXActorsMap.find(&pxActor); - return it != nullptr ? it->second : nullptr; - } - - virtual PxPhysics& getPhysics() const override - { - return m_physics; - } - - virtual TkFramework& getFramework() const override - { - return m_framework; - } - - virtual bool isPxUserDataUsed() const override - { - return m_usePxUserData; - } - - virtual void subscribe(ExtPxListener& listener) override - { - m_listeners.pushBack(&listener); - } - - virtual void unsubscribe(ExtPxListener& listener) override - { - m_listeners.findAndReplaceWithLast(&listener); - } - - virtual void setActorCountLimit(uint32_t limit) override - { - m_actorCountLimit = limit; - } - - virtual uint32_t getActorCountLimit() override - { - return m_actorCountLimit; - } - - virtual uint32_t getPxActorCount() const override - { - return m_physXActorsMap.size(); - } - - - //////// internal public methods //////// - - void registerActor(PxRigidDynamic* pxActor, ExtPxActor* actor) - { - if (m_usePxUserData) - { - pxActor->userData = actor; - } - m_physXActorsMap[pxActor] = actor; - } - - void unregisterActor(PxRigidDynamic* pxActor) - { - if (m_usePxUserData) - { - pxActor->userData = nullptr; - } - m_physXActorsMap.erase(pxActor); - } - - void registerFamily(ExtPxFamily& family) - { - m_tkFamiliesMap[&family.getTkFamily()] = &family; - } - - void unregisterFamily(ExtPxFamily& family) - { - m_tkFamiliesMap.erase(&family.getTkFamily()); - } - - void updateJoint(TkJoint& joint); - - - //////// events dispatch //////// - - void dispatchActorCreated(ExtPxFamily& family, ExtPxActor& actor) - { - for (ExtPxListener* listener : m_listeners) - listener->onActorCreated(family, actor); - } - - void dispatchActorDestroyed(ExtPxFamily& family, ExtPxActor&actor) - { - for (ExtPxListener* listener : m_listeners) - listener->onActorDestroyed(family, actor); - } - - -private: - - //////// data //////// - - PxPhysics& m_physics; - TkFramework& m_framework; - ExtPxCreateJointFunction m_createJointFn; - bool m_usePxUserData; - InlineArray<ExtPxListener*, 8>::type m_listeners; - HashMap<const PxRigidDynamic*, ExtPxActor*>::type m_physXActorsMap; - HashMap<TkFamily*, ExtPxFamily*>::type m_tkFamiliesMap; - HashMap<TkActor*, Array<TkJoint*>::type >::type m_incompleteJointMultiMap; - uint32_t m_actorCountLimit; -}; - -} // namespace Blast -} // namespace Nv - - -#endif // ifndef NVBLASTEXTPXMANAGERIMPL_H +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#ifndef NVBLASTEXTPXMANAGERIMPL_H
+#define NVBLASTEXTPXMANAGERIMPL_H
+
+#include "NvBlastExtPxManager.h"
+#include "NvBlastArray.h"
+#include "NvBlastHashMap.h"
+#include "NvBlastExtPxListener.h"
+#include "NvBlastExtPxFamily.h"
+
+#include "PxRigidDynamic.h"
+
+
+using namespace physx;
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+// Forward declarations
+class TkActor;
+
+class ExtPxManagerImpl final : public ExtPxManager
+{
+ NV_NOCOPY(ExtPxManagerImpl)
+
+public:
+ friend class ExtPxActorImpl;
+ friend class ExtPxFamilyImpl;
+
+ ExtPxManagerImpl(PxPhysics& physics, TkFramework&framework, ExtPxCreateJointFunction createFn, bool usePxUserData)
+ : m_physics(physics), m_framework(framework), m_createJointFn(createFn), m_usePxUserData(usePxUserData), m_actorCountLimit(0)
+ {
+ }
+
+ ~ExtPxManagerImpl()
+ {
+ }
+
+ virtual void release() override;
+
+
+ //////// interface ////////
+
+ virtual ExtPxFamily* createFamily(const ExtPxFamilyDesc& desc) override;
+
+ virtual bool createJoint(TkJoint& joint) override;
+
+ virtual void destroyJoint(TkJoint& joint) override;
+
+ virtual void setCreateJointFunction(ExtPxCreateJointFunction createFn) override
+ {
+ m_createJointFn = createFn;
+ }
+
+ virtual uint32_t getFamilyCount() const override
+ {
+ return m_tkFamiliesMap.size();
+ }
+
+ virtual uint32_t getFamilies(ExtPxFamily** buffer, uint32_t bufferSize) const override
+ {
+ uint32_t index = 0;
+ for (auto it = const_cast<ExtPxManagerImpl*>(this)->m_tkFamiliesMap.getIterator(); !it.done() && index < bufferSize; ++it)
+ {
+ buffer[index++] = it->second;
+ }
+ return index;
+ }
+
+ virtual ExtPxFamily* getFamilyFromTkFamily(TkFamily& family) const override
+ {
+ auto entry = m_tkFamiliesMap.find(&family);
+ return entry != nullptr ? entry->second : nullptr;
+ }
+
+ virtual ExtPxActor* getActorFromPhysXActor(const PxRigidDynamic& pxActor) const override
+ {
+ auto it = m_physXActorsMap.find(&pxActor);
+ return it != nullptr ? it->second : nullptr;
+ }
+
+ virtual PxPhysics& getPhysics() const override
+ {
+ return m_physics;
+ }
+
+ virtual TkFramework& getFramework() const override
+ {
+ return m_framework;
+ }
+
+ virtual bool isPxUserDataUsed() const override
+ {
+ return m_usePxUserData;
+ }
+
+ virtual void subscribe(ExtPxListener& listener) override
+ {
+ m_listeners.pushBack(&listener);
+ }
+
+ virtual void unsubscribe(ExtPxListener& listener) override
+ {
+ m_listeners.findAndReplaceWithLast(&listener);
+ }
+
+ virtual void setActorCountLimit(uint32_t limit) override
+ {
+ m_actorCountLimit = limit;
+ }
+
+ virtual uint32_t getActorCountLimit() override
+ {
+ return m_actorCountLimit;
+ }
+
+ virtual uint32_t getPxActorCount() const override
+ {
+ return m_physXActorsMap.size();
+ }
+
+
+ //////// internal public methods ////////
+
+ void registerActor(PxRigidDynamic* pxActor, ExtPxActor* actor)
+ {
+ if (m_usePxUserData)
+ {
+ pxActor->userData = actor;
+ }
+ m_physXActorsMap[pxActor] = actor;
+ }
+
+ void unregisterActor(PxRigidDynamic* pxActor)
+ {
+ if (m_usePxUserData)
+ {
+ pxActor->userData = nullptr;
+ }
+ m_physXActorsMap.erase(pxActor);
+ }
+
+ void registerFamily(ExtPxFamily& family)
+ {
+ m_tkFamiliesMap[&family.getTkFamily()] = &family;
+ }
+
+ void unregisterFamily(ExtPxFamily& family)
+ {
+ m_tkFamiliesMap.erase(&family.getTkFamily());
+ }
+
+ void updateJoint(TkJoint& joint);
+
+
+ //////// events dispatch ////////
+
+ void dispatchActorCreated(ExtPxFamily& family, ExtPxActor& actor)
+ {
+ for (ExtPxListener* listener : m_listeners)
+ listener->onActorCreated(family, actor);
+ }
+
+ void dispatchActorDestroyed(ExtPxFamily& family, ExtPxActor&actor)
+ {
+ for (ExtPxListener* listener : m_listeners)
+ listener->onActorDestroyed(family, actor);
+ }
+
+
+private:
+
+ //////// data ////////
+
+ PxPhysics& m_physics;
+ TkFramework& m_framework;
+ ExtPxCreateJointFunction m_createJointFn;
+ bool m_usePxUserData;
+ InlineArray<ExtPxListener*, 8>::type m_listeners;
+ HashMap<const PxRigidDynamic*, ExtPxActor*>::type m_physXActorsMap;
+ HashMap<TkFamily*, ExtPxFamily*>::type m_tkFamiliesMap;
+ HashMap<TkActor*, Array<TkJoint*>::type >::type m_incompleteJointMultiMap;
+ uint32_t m_actorCountLimit;
+};
+
+} // namespace Blast
+} // namespace Nv
+
+
+#endif // ifndef NVBLASTEXTPXMANAGERIMPL_H
diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.cpp b/sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.cpp index 19ffb93..b18df25 100644..100755 --- a/sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.cpp +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.cpp @@ -1,229 +1,229 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#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 +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#include "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
diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.h b/sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.h index cd6cab6..7277dbc 100644..100755 --- a/sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.h +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxStressSolverImpl.h @@ -1,86 +1,86 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#ifndef NVBLASTEXTPXSTRESSSOLVERIMPL_H -#define NVBLASTEXTPXSTRESSSOLVERIMPL_H - -#include "NvBlastExtPxStressSolver.h" -#include "NvBlastExtPxListener.h" -#include "NvBlastArray.h" -#include "NvBlastHashSet.h" - -namespace Nv -{ -namespace Blast -{ - - -class ExtPxStressSolverImpl final : public ExtPxStressSolver, ExtPxListener -{ - NV_NOCOPY(ExtPxStressSolverImpl) - -public: - ExtPxStressSolverImpl(ExtPxFamily& family, ExtStressSolverSettings settings); - - - //////// ExtPxStressSolver interface //////// - - virtual void release() override; - - virtual ExtStressSolver& getSolver() const override - { - return *m_solver; - } - - virtual void update(bool doDamage) override; - - - //////// ExtPxListener interface //////// - - virtual void onActorCreated(ExtPxFamily& family, ExtPxActor& actor) final; - - virtual void onActorDestroyed(ExtPxFamily& family, ExtPxActor& actor) final; - - -private: - ~ExtPxStressSolverImpl(); - - - //////// data //////// - - ExtPxFamily& m_family; - ExtStressSolver* m_solver; - HashSet<ExtPxActor*>::type m_actors; -}; - - -} // namespace Blast -} // namespace Nv - - -#endif // ifndef NVBLASTEXTPXSTRESSSOLVERIMPL_H +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#ifndef NVBLASTEXTPXSTRESSSOLVERIMPL_H
+#define NVBLASTEXTPXSTRESSSOLVERIMPL_H
+
+#include "NvBlastExtPxStressSolver.h"
+#include "NvBlastExtPxListener.h"
+#include "NvBlastArray.h"
+#include "NvBlastHashSet.h"
+
+namespace Nv
+{
+namespace Blast
+{
+
+
+class ExtPxStressSolverImpl final : public ExtPxStressSolver, ExtPxListener
+{
+ NV_NOCOPY(ExtPxStressSolverImpl)
+
+public:
+ ExtPxStressSolverImpl(ExtPxFamily& family, ExtStressSolverSettings settings);
+
+
+ //////// ExtPxStressSolver interface ////////
+
+ virtual void release() override;
+
+ virtual ExtStressSolver& getSolver() const override
+ {
+ return *m_solver;
+ }
+
+ virtual void update(bool doDamage) override;
+
+
+ //////// ExtPxListener interface ////////
+
+ virtual void onActorCreated(ExtPxFamily& family, ExtPxActor& actor) final;
+
+ virtual void onActorDestroyed(ExtPxFamily& family, ExtPxActor& actor) final;
+
+
+private:
+ ~ExtPxStressSolverImpl();
+
+
+ //////// data ////////
+
+ ExtPxFamily& m_family;
+ ExtStressSolver* m_solver;
+ HashSet<ExtPxActor*>::type m_actors;
+};
+
+
+} // namespace Blast
+} // namespace Nv
+
+
+#endif // ifndef NVBLASTEXTPXSTRESSSOLVERIMPL_H
diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxTaskImpl.cpp b/sdk/extensions/physx/source/physics/NvBlastExtPxTaskImpl.cpp index eac8d45..56a78c7 100644..100755 --- a/sdk/extensions/physx/source/physics/NvBlastExtPxTaskImpl.cpp +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxTaskImpl.cpp @@ -1,120 +1,120 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#include "NvBlastGlobals.h" -#include "NvBlastExtPxTaskImpl.h" - -#include "NvBlastTkGroup.h" - -using namespace Nv::Blast; - - -uint32_t ExtGroupTaskManagerImpl::process(uint32_t workerCount) -{ - NVBLAST_CHECK_WARNING(m_group != nullptr, "ExtGroupTaskManager::process cannot process, no group set.", return 0); - NVBLAST_CHECK_WARNING(m_sync.isDone(), "ExtGroupTaskManager::process group is already being processed.", return 0); - - // at least one task must start, even when dispatcher has none specified - uint32_t dispatcherThreads = m_taskManager.getCpuDispatcher()->getWorkerCount(); - dispatcherThreads = dispatcherThreads > 0 ? dispatcherThreads : 1; - - // not expecting an arbitrary amount of tasks - uint32_t availableTasks = TASKS_MAX_COUNT; - - // use workerCount tasks, unless dispatcher has less threads or less tasks are available - uint32_t requestedTasks = workerCount > 0 ? workerCount : dispatcherThreads; - requestedTasks = requestedTasks > dispatcherThreads ? dispatcherThreads : requestedTasks; - requestedTasks = requestedTasks > availableTasks ? availableTasks : requestedTasks; - - // ensure the group has enough memory allocated for concurrent processing - m_group->setWorkerCount(requestedTasks); - - // check if there is work to do - uint32_t jobCount = m_group->startProcess(); - - if (jobCount) - { - // don't start more tasks than jobs are available - requestedTasks = requestedTasks > jobCount ? jobCount : requestedTasks; - - // common counter for all tasks - m_counter.reset(jobCount); - - // set to busy state - m_sync.setCount(requestedTasks); - - // set up tasks - for (uint32_t i = 0; i < requestedTasks; i++) - { - m_tasks[i].setup(m_group, &m_counter, &m_sync); - m_tasks[i].setContinuation(m_taskManager, nullptr); - m_tasks[i].removeReference(); - } - - return requestedTasks; - } - - // there was no work to be done - return 0; -} - - -bool ExtGroupTaskManagerImpl::wait(bool block) -{ - if (block && !m_sync.isDone()) - { - m_sync.wait(); - } - if (m_sync.isDone()) - { - return m_group->endProcess(); - } - return false; -} - - -void ExtGroupTaskManagerImpl::setGroup(TkGroup* group) -{ - NVBLAST_CHECK_WARNING(m_sync.isDone(), "ExtGroupTaskManager::setGroup trying to change group while processing.", return); - - m_group = group; -} - - -ExtGroupTaskManager* ExtGroupTaskManager::create(physx::PxTaskManager& taskManager, TkGroup* group) -{ - return NVBLAST_NEW(ExtGroupTaskManagerImpl) (taskManager, group); -} - - -void ExtGroupTaskManagerImpl::release() -{ - NVBLAST_CHECK_WARNING(m_sync.isDone(), "ExtGroupTaskManager::release group is still being processed.", return); - - NVBLAST_DELETE(this, ExtGroupTaskManagerImpl); -} +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#include "NvBlastGlobals.h"
+#include "NvBlastExtPxTaskImpl.h"
+
+#include "NvBlastTkGroup.h"
+
+using namespace Nv::Blast;
+
+
+uint32_t ExtGroupTaskManagerImpl::process(uint32_t workerCount)
+{
+ NVBLAST_CHECK_WARNING(m_group != nullptr, "ExtGroupTaskManager::process cannot process, no group set.", return 0);
+ NVBLAST_CHECK_WARNING(m_sync.isDone(), "ExtGroupTaskManager::process group is already being processed.", return 0);
+
+ // at least one task must start, even when dispatcher has none specified
+ uint32_t dispatcherThreads = m_taskManager.getCpuDispatcher()->getWorkerCount();
+ dispatcherThreads = dispatcherThreads > 0 ? dispatcherThreads : 1;
+
+ // not expecting an arbitrary amount of tasks
+ uint32_t availableTasks = TASKS_MAX_COUNT;
+
+ // use workerCount tasks, unless dispatcher has less threads or less tasks are available
+ uint32_t requestedTasks = workerCount > 0 ? workerCount : dispatcherThreads;
+ requestedTasks = requestedTasks > dispatcherThreads ? dispatcherThreads : requestedTasks;
+ requestedTasks = requestedTasks > availableTasks ? availableTasks : requestedTasks;
+
+ // ensure the group has enough memory allocated for concurrent processing
+ m_group->setWorkerCount(requestedTasks);
+
+ // check if there is work to do
+ uint32_t jobCount = m_group->startProcess();
+
+ if (jobCount)
+ {
+ // don't start more tasks than jobs are available
+ requestedTasks = requestedTasks > jobCount ? jobCount : requestedTasks;
+
+ // common counter for all tasks
+ m_counter.reset(jobCount);
+
+ // set to busy state
+ m_sync.setCount(requestedTasks);
+
+ // set up tasks
+ for (uint32_t i = 0; i < requestedTasks; i++)
+ {
+ m_tasks[i].setup(m_group, &m_counter, &m_sync);
+ m_tasks[i].setContinuation(m_taskManager, nullptr);
+ m_tasks[i].removeReference();
+ }
+
+ return requestedTasks;
+ }
+
+ // there was no work to be done
+ return 0;
+}
+
+
+bool ExtGroupTaskManagerImpl::wait(bool block)
+{
+ if (block && !m_sync.isDone())
+ {
+ m_sync.wait();
+ }
+ if (m_sync.isDone())
+ {
+ return m_group->endProcess();
+ }
+ return false;
+}
+
+
+void ExtGroupTaskManagerImpl::setGroup(TkGroup* group)
+{
+ NVBLAST_CHECK_WARNING(m_sync.isDone(), "ExtGroupTaskManager::setGroup trying to change group while processing.", return);
+
+ m_group = group;
+}
+
+
+ExtGroupTaskManager* ExtGroupTaskManager::create(physx::PxTaskManager& taskManager, TkGroup* group)
+{
+ return NVBLAST_NEW(ExtGroupTaskManagerImpl) (taskManager, group);
+}
+
+
+void ExtGroupTaskManagerImpl::release()
+{
+ NVBLAST_CHECK_WARNING(m_sync.isDone(), "ExtGroupTaskManager::release group is still being processed.", return);
+
+ NVBLAST_DELETE(this, ExtGroupTaskManagerImpl);
+}
diff --git a/sdk/extensions/physx/source/physics/NvBlastExtPxTaskImpl.h b/sdk/extensions/physx/source/physics/NvBlastExtPxTaskImpl.h index 0fd9779..6388584 100644..100755 --- a/sdk/extensions/physx/source/physics/NvBlastExtPxTaskImpl.h +++ b/sdk/extensions/physx/source/physics/NvBlastExtPxTaskImpl.h @@ -1,209 +1,209 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#ifndef NVBLASTEXTPXTASKIMPL_H -#define NVBLASTEXTPXTASKIMPL_H - -#include "NvBlastExtPxTask.h" -#include "PxTask.h" -#include "NvBlastTkGroup.h" - -#include <atomic> -#include <mutex> -#include <condition_variable> - -namespace Nv -{ -namespace Blast -{ - -/** -Counting synchronization object for waiting on TkWorkers to finish. -*/ -class ExtTaskSync -{ -public: - /** - Initializes with an expected number of notifications. - */ - ExtTaskSync(uint32_t count) : m_count(count) {} - - /** - Blocks until the expected number of notifications happened. - */ - void wait() - { - std::unique_lock<std::mutex> lk(m_mutex); - m_cv.wait(lk, [&] { return m_count == 0; }); - } - - /** - Decrement the wait() count by one. - */ - void notify() - { - //PERF_SCOPE_H("TaskSync::notify"); - std::unique_lock<std::mutex> lk(m_mutex); - if (m_count > 0) - { - m_count--; - } - if (m_count == 0) - { - lk.unlock(); - m_cv.notify_one(); - } - } - - /** - Peek if notifications are pending. - */ - bool isDone() - { - std::unique_lock<std::mutex> lk(m_mutex); - return m_count == 0; - } - - /** - Sets the expected number of notifications for wait() to unblock. - */ - void setCount(uint32_t count) - { - m_count = count; - } - -private: - std::mutex m_mutex; - std::condition_variable m_cv; - uint32_t m_count; -}; - - -/** -Common job counter for all tasks. -*/ -class ExtAtomicCounter -{ -public: - ExtAtomicCounter() : m_current(0), m_maxCount(0) {} - - bool isValid(uint32_t val) - { - return val < m_maxCount; - } - - uint32_t next() - { - return m_current.fetch_add(1); - } - - void reset(uint32_t maxCount) - { - m_maxCount = maxCount; - m_current = 0; - } -private: - std::atomic<uint32_t> m_current; - uint32_t m_maxCount; -}; - - -/** -A task running one group job after the other until done. Synchronizes atomically with its siblings. -*/ -class ExtGroupWorkerTask : public physx::PxLightCpuTask -{ -public: - ExtGroupWorkerTask() : PxLightCpuTask(), m_group(nullptr), m_counter(nullptr), m_sync(nullptr) - { - } - - void setup(TkGroup* group, ExtAtomicCounter* counter, ExtTaskSync* sync) - { - m_group = group; - m_counter = counter; - m_sync = sync; - } - - virtual void run() override - { - Nv::Blast::TkGroupWorker* worker = m_group->acquireWorker(); - uint32_t jobID = m_counter->next(); - while (m_counter->isValid(jobID)) - { - worker->process(jobID); - jobID = m_counter->next(); - } - m_group->returnWorker(worker); - } - - virtual void release() override - { - PxLightCpuTask::release(); - - // release the sync last - m_sync->notify(); - } - - virtual const char* getName() const override { return "BlastGroupWorkerTask"; } - -private: - TkGroup* m_group; - ExtAtomicCounter* m_counter; - ExtTaskSync* m_sync; -}; - - -/** -Implements ExtGroupTaskManager -*/ -class ExtGroupTaskManagerImpl : public ExtGroupTaskManager -{ -public: - ExtGroupTaskManagerImpl(physx::PxTaskManager& taskManager, TkGroup* group) - : m_taskManager(taskManager), m_sync(0), m_group(group) {} - - // ExtGroupTaskManager API - virtual void setGroup(TkGroup*) override; - virtual uint32_t process(uint32_t) override; - virtual void release() override; - virtual bool wait(bool block) override; - -private: - static const uint32_t TASKS_MAX_COUNT = 16; - physx::PxTaskManager& m_taskManager; - ExtAtomicCounter m_counter; - ExtGroupWorkerTask m_tasks[TASKS_MAX_COUNT]; - ExtTaskSync m_sync; - TkGroup* m_group; -}; - -} // namespace Blast -} // namespace Nv - -#endif // NVBLASTEXTPXTASKIMPL_H +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#ifndef NVBLASTEXTPXTASKIMPL_H
+#define NVBLASTEXTPXTASKIMPL_H
+
+#include "NvBlastExtPxTask.h"
+#include "PxTask.h"
+#include "NvBlastTkGroup.h"
+
+#include <atomic>
+#include <mutex>
+#include <condition_variable>
+
+namespace Nv
+{
+namespace Blast
+{
+
+/**
+Counting synchronization object for waiting on TkWorkers to finish.
+*/
+class ExtTaskSync
+{
+public:
+ /**
+ Initializes with an expected number of notifications.
+ */
+ ExtTaskSync(uint32_t count) : m_count(count) {}
+
+ /**
+ Blocks until the expected number of notifications happened.
+ */
+ void wait()
+ {
+ std::unique_lock<std::mutex> lk(m_mutex);
+ m_cv.wait(lk, [&] { return m_count == 0; });
+ }
+
+ /**
+ Decrement the wait() count by one.
+ */
+ void notify()
+ {
+ //PERF_SCOPE_H("TaskSync::notify");
+ std::unique_lock<std::mutex> lk(m_mutex);
+ if (m_count > 0)
+ {
+ m_count--;
+ }
+ if (m_count == 0)
+ {
+ lk.unlock();
+ m_cv.notify_one();
+ }
+ }
+
+ /**
+ Peek if notifications are pending.
+ */
+ bool isDone()
+ {
+ std::unique_lock<std::mutex> lk(m_mutex);
+ return m_count == 0;
+ }
+
+ /**
+ Sets the expected number of notifications for wait() to unblock.
+ */
+ void setCount(uint32_t count)
+ {
+ m_count = count;
+ }
+
+private:
+ std::mutex m_mutex;
+ std::condition_variable m_cv;
+ uint32_t m_count;
+};
+
+
+/**
+Common job counter for all tasks.
+*/
+class ExtAtomicCounter
+{
+public:
+ ExtAtomicCounter() : m_current(0), m_maxCount(0) {}
+
+ bool isValid(uint32_t val)
+ {
+ return val < m_maxCount;
+ }
+
+ uint32_t next()
+ {
+ return m_current.fetch_add(1);
+ }
+
+ void reset(uint32_t maxCount)
+ {
+ m_maxCount = maxCount;
+ m_current = 0;
+ }
+private:
+ std::atomic<uint32_t> m_current;
+ uint32_t m_maxCount;
+};
+
+
+/**
+A task running one group job after the other until done. Synchronizes atomically with its siblings.
+*/
+class ExtGroupWorkerTask : public physx::PxLightCpuTask
+{
+public:
+ ExtGroupWorkerTask() : PxLightCpuTask(), m_group(nullptr), m_counter(nullptr), m_sync(nullptr)
+ {
+ }
+
+ void setup(TkGroup* group, ExtAtomicCounter* counter, ExtTaskSync* sync)
+ {
+ m_group = group;
+ m_counter = counter;
+ m_sync = sync;
+ }
+
+ virtual void run() override
+ {
+ Nv::Blast::TkGroupWorker* worker = m_group->acquireWorker();
+ uint32_t jobID = m_counter->next();
+ while (m_counter->isValid(jobID))
+ {
+ worker->process(jobID);
+ jobID = m_counter->next();
+ }
+ m_group->returnWorker(worker);
+ }
+
+ virtual void release() override
+ {
+ PxLightCpuTask::release();
+
+ // release the sync last
+ m_sync->notify();
+ }
+
+ virtual const char* getName() const override { return "BlastGroupWorkerTask"; }
+
+private:
+ TkGroup* m_group;
+ ExtAtomicCounter* m_counter;
+ ExtTaskSync* m_sync;
+};
+
+
+/**
+Implements ExtGroupTaskManager
+*/
+class ExtGroupTaskManagerImpl : public ExtGroupTaskManager
+{
+public:
+ ExtGroupTaskManagerImpl(physx::PxTaskManager& taskManager, TkGroup* group)
+ : m_taskManager(taskManager), m_sync(0), m_group(group) {}
+
+ // ExtGroupTaskManager API
+ virtual void setGroup(TkGroup*) override;
+ virtual uint32_t process(uint32_t) override;
+ virtual void release() override;
+ virtual bool wait(bool block) override;
+
+private:
+ static const uint32_t TASKS_MAX_COUNT = 16;
+ physx::PxTaskManager& m_taskManager;
+ ExtAtomicCounter m_counter;
+ ExtGroupWorkerTask m_tasks[TASKS_MAX_COUNT];
+ ExtTaskSync m_sync;
+ TkGroup* m_group;
+};
+
+} // namespace Blast
+} // namespace Nv
+
+#endif // NVBLASTEXTPXTASKIMPL_H
diff --git a/sdk/extensions/physx/source/sync/NvBlastExtSync.cpp b/sdk/extensions/physx/source/sync/NvBlastExtSync.cpp index 3d768a6..7d5ed3e 100644..100755 --- a/sdk/extensions/physx/source/sync/NvBlastExtSync.cpp +++ b/sdk/extensions/physx/source/sync/NvBlastExtSync.cpp @@ -1,251 +1,251 @@ -// This code contains NVIDIA Confidential Information and is disclosed to you -// under a form of NVIDIA software license agreement provided separately to you. -// -// Notice -// NVIDIA Corporation and its licensors retain all intellectual property and -// proprietary rights in and to this software and related documentation and -// any modifications thereto. Any use, reproduction, disclosure, or -// distribution of this software and related documentation without an express -// license agreement from NVIDIA Corporation is strictly prohibited. -// -// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES -// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO -// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, -// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Information and code furnished is believed to be accurate and reliable. -// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such -// information or for any infringement of patents or other rights of third parties that may -// result from its use. No license is granted by implication or otherwise under any patent -// or patent rights of NVIDIA Corporation. Details are subject to change without notice. -// This code supersedes and replaces all information previously supplied. -// NVIDIA Corporation products are not authorized for use as critical -// components in life support devices or systems without express written approval of -// NVIDIA Corporation. -// -// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved. - - -#include "NvBlastExtSync.h" -#include "NvBlastAssert.h" -#include "NvBlast.h" -#include "NvBlastExtPxManager.h" -#include "NvBlastExtPxFamily.h" -#include "NvBlastExtPxActor.h" -#include "PxRigidDynamic.h" - -#include <chrono> -using namespace std::chrono; - -namespace Nv -{ -namespace Blast -{ - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// ExtSyncImpl Definition -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -class ExtSyncImpl : public ExtSync -{ - NV_NOCOPY(ExtSyncImpl) - -public: - //////// ctor //////// - - ExtSyncImpl(); - - virtual ~ExtSyncImpl(); - - - //////// TkEventListener interface //////// - - virtual void receive(const TkEvent* events, uint32_t eventCount) override; - - - //////// ExtSync interface //////// - - virtual void release() override; - - virtual void syncFamily(const TkFamily& family) override; - virtual void syncFamily(const ExtPxFamily& family) override; - - virtual uint32_t getSyncBufferSize() const override; - virtual void acquireSyncBuffer(const ExtSyncEvent*const*& buffer, uint32_t& size) const override; - virtual void releaseSyncBuffer() override; - - virtual void applySyncBuffer(TkFramework& framework, const ExtSyncEvent** buffer, uint32_t size, TkGroup* groupForNewActors, ExtPxManager* manager) override; - - -private: - //////// data //////// - - std::vector<ExtSyncEvent*> m_syncEvents; -}; - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// ExtSyncEvent Implementation -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void ExtSyncEvent::release() -{ - NVBLAST_DELETE(this, ExtSyncEvent); -} - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// ExtSyncImpl Implementation -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -ExtSync* ExtSync::create() -{ - return NVBLAST_NEW(ExtSyncImpl) (); -} - -void ExtSyncImpl::release() -{ - NVBLAST_DELETE(this, ExtSyncImpl); -} - -ExtSyncImpl::ExtSyncImpl() -{ -} - -ExtSyncImpl::~ExtSyncImpl() -{ - releaseSyncBuffer(); -} - -void ExtSyncImpl::receive(const TkEvent* events, uint32_t eventCount) -{ - for (uint32_t i = 0; i < eventCount; ++i) - { - const TkEvent& tkEvent = events[i]; - if (tkEvent.type == TkEvent::FractureCommand) - { - const TkFractureCommands* fracEvent = tkEvent.getPayload<TkFractureCommands>(); - ExtSyncEventFracture* e = NVBLAST_NEW(ExtSyncEventFracture) (); - e->timestamp = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count(); - e->familyID = fracEvent->tkActorData.family->getID(); - e->bondFractures.resize(fracEvent->buffers.bondFractureCount); - e->chunkFractures.resize(fracEvent->buffers.chunkFractureCount); - memcpy(e->bondFractures.data(), fracEvent->buffers.bondFractures, e->bondFractures.size() * sizeof(NvBlastBondFractureData)); - memcpy(e->chunkFractures.data(), fracEvent->buffers.chunkFractures, e->chunkFractures.size() * sizeof(NvBlastChunkFractureData)); - m_syncEvents.push_back(e); - } - } -} - -void ExtSyncImpl::syncFamily(const TkFamily& family) -{ - ExtSyncEventFamilySync* e = NVBLAST_NEW(ExtSyncEventFamilySync) (); - e->timestamp = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count(); - e->familyID = family.getID(); - const NvBlastFamily* familyLL = family.getFamilyLL(); - const uint32_t size = NvBlastFamilyGetSize(familyLL, logLL); - e->family = std::vector<char>((char*)familyLL, (char*)familyLL + size); - m_syncEvents.push_back(e); -} - -void ExtSyncImpl::syncFamily(const ExtPxFamily& family) -{ - const TkFamily& tkFamily = family.getTkFamily(); - - syncFamily(tkFamily); - - ExtSyncEventPhysicsSync* e = NVBLAST_NEW(ExtSyncEventPhysicsSync) (); - e->timestamp = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count(); - e->familyID = tkFamily.getID(); - std::vector<ExtPxActor*> actors(family.getActorCount()); - family.getActors(actors.data(), static_cast<uint32_t>(actors.size())); - e->data.reserve(actors.size()); - for (ExtPxActor* actor : actors) - { - ExtSyncEventPhysicsSync::ActorData data; - data.transform = actor->getPhysXActor().getGlobalPose(); - data.actorIndex = actor->getTkActor().getIndex(); - e->data.push_back(data); - } - - m_syncEvents.push_back(e); -} - -uint32_t ExtSyncImpl::getSyncBufferSize() const -{ - return static_cast<uint32_t>(m_syncEvents.size()); -} - -void ExtSyncImpl::acquireSyncBuffer(const ExtSyncEvent* const*& buffer, uint32_t& size) const -{ - buffer = m_syncEvents.data(); - size = static_cast<uint32_t>(m_syncEvents.size()); -} - -void ExtSyncImpl::releaseSyncBuffer() -{ - for (uint32_t i = 0; i < m_syncEvents.size(); ++i) - { - NVBLAST_DELETE(m_syncEvents[i], ExtSyncEvent); - } - m_syncEvents.clear(); -} - -void ExtSyncImpl::applySyncBuffer(TkFramework& framework, const ExtSyncEvent** buffer, uint32_t size, TkGroup* groupForNewActors, ExtPxManager* manager) -{ - const TkType* familyType = framework.getType(TkTypeIndex::Family); - NVBLAST_ASSERT(familyType); - - for (uint32_t i = 0; i < size; ++i) - { - const ExtSyncEvent* e = buffer[i]; - const NvBlastID& id = e->familyID; - TkIdentifiable* object = framework.findObjectByID(id); - if (object && object->getType() == *familyType) - { - TkFamily* family = static_cast<TkFamily*>(object); - - if (e->type == ExtSyncEventFracture::EVENT_TYPE) - { - const ExtSyncEventFracture* fractureEvent = e->getEvent<ExtSyncEventFracture>(); - const NvBlastFractureBuffers commands = - { - static_cast<uint32_t>(fractureEvent->bondFractures.size()), - static_cast<uint32_t>(fractureEvent->chunkFractures.size()), - const_cast<NvBlastBondFractureData*>(fractureEvent->bondFractures.data()), - const_cast<NvBlastChunkFractureData*>(fractureEvent->chunkFractures.data()) - }; - family->applyFracture(&commands); - } - else if (e->type == ExtSyncEventFamilySync::EVENT_TYPE) - { - const ExtSyncEventFamilySync* familyEvent = e->getEvent<ExtSyncEventFamilySync>(); - family->reinitialize((NvBlastFamily*)familyEvent->family.data(), groupForNewActors); - } - else if (e->type == ExtSyncEventPhysicsSync::EVENT_TYPE && manager) - { - const ExtSyncEventPhysicsSync* physicsEvent = e->getEvent<ExtSyncEventPhysicsSync>(); - ExtPxFamily* pxFamily = manager->getFamilyFromTkFamily(*family); - if (pxFamily) - { - std::vector<ExtPxActor*> actors(pxFamily->getActorCount()); - pxFamily->getActors(actors.data(), static_cast<uint32_t>(actors.size())); - - for (auto data : physicsEvent->data) - { - for (ExtPxActor* physicsaActor : actors) - { - if (data.actorIndex == physicsaActor->getTkActor().getIndex()) - { - physicsaActor->getPhysXActor().setGlobalPose(data.transform); - } - } - } - } - } - } - } -} - -} // namespace Blast -} // namespace Nv +// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#include "NvBlastExtSync.h"
+#include "NvBlastAssert.h"
+#include "NvBlast.h"
+#include "NvBlastExtPxManager.h"
+#include "NvBlastExtPxFamily.h"
+#include "NvBlastExtPxActor.h"
+#include "PxRigidDynamic.h"
+
+#include <chrono>
+using namespace std::chrono;
+
+namespace Nv
+{
+namespace Blast
+{
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// ExtSyncImpl Definition
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class ExtSyncImpl : public ExtSync
+{
+ NV_NOCOPY(ExtSyncImpl)
+
+public:
+ //////// ctor ////////
+
+ ExtSyncImpl();
+
+ virtual ~ExtSyncImpl();
+
+
+ //////// TkEventListener interface ////////
+
+ virtual void receive(const TkEvent* events, uint32_t eventCount) override;
+
+
+ //////// ExtSync interface ////////
+
+ virtual void release() override;
+
+ virtual void syncFamily(const TkFamily& family) override;
+ virtual void syncFamily(const ExtPxFamily& family) override;
+
+ virtual uint32_t getSyncBufferSize() const override;
+ virtual void acquireSyncBuffer(const ExtSyncEvent*const*& buffer, uint32_t& size) const override;
+ virtual void releaseSyncBuffer() override;
+
+ virtual void applySyncBuffer(TkFramework& framework, const ExtSyncEvent** buffer, uint32_t size, TkGroup* groupForNewActors, ExtPxManager* manager) override;
+
+
+private:
+ //////// data ////////
+
+ std::vector<ExtSyncEvent*> m_syncEvents;
+};
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// ExtSyncEvent Implementation
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void ExtSyncEvent::release()
+{
+ NVBLAST_DELETE(this, ExtSyncEvent);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// ExtSyncImpl Implementation
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ExtSync* ExtSync::create()
+{
+ return NVBLAST_NEW(ExtSyncImpl) ();
+}
+
+void ExtSyncImpl::release()
+{
+ NVBLAST_DELETE(this, ExtSyncImpl);
+}
+
+ExtSyncImpl::ExtSyncImpl()
+{
+}
+
+ExtSyncImpl::~ExtSyncImpl()
+{
+ releaseSyncBuffer();
+}
+
+void ExtSyncImpl::receive(const TkEvent* events, uint32_t eventCount)
+{
+ for (uint32_t i = 0; i < eventCount; ++i)
+ {
+ const TkEvent& tkEvent = events[i];
+ if (tkEvent.type == TkEvent::FractureCommand)
+ {
+ const TkFractureCommands* fracEvent = tkEvent.getPayload<TkFractureCommands>();
+ ExtSyncEventFracture* e = NVBLAST_NEW(ExtSyncEventFracture) ();
+ e->timestamp = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
+ e->familyID = fracEvent->tkActorData.family->getID();
+ e->bondFractures.resize(fracEvent->buffers.bondFractureCount);
+ e->chunkFractures.resize(fracEvent->buffers.chunkFractureCount);
+ memcpy(e->bondFractures.data(), fracEvent->buffers.bondFractures, e->bondFractures.size() * sizeof(NvBlastBondFractureData));
+ memcpy(e->chunkFractures.data(), fracEvent->buffers.chunkFractures, e->chunkFractures.size() * sizeof(NvBlastChunkFractureData));
+ m_syncEvents.push_back(e);
+ }
+ }
+}
+
+void ExtSyncImpl::syncFamily(const TkFamily& family)
+{
+ ExtSyncEventFamilySync* e = NVBLAST_NEW(ExtSyncEventFamilySync) ();
+ e->timestamp = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
+ e->familyID = family.getID();
+ const NvBlastFamily* familyLL = family.getFamilyLL();
+ const uint32_t size = NvBlastFamilyGetSize(familyLL, logLL);
+ e->family = std::vector<char>((char*)familyLL, (char*)familyLL + size);
+ m_syncEvents.push_back(e);
+}
+
+void ExtSyncImpl::syncFamily(const ExtPxFamily& family)
+{
+ const TkFamily& tkFamily = family.getTkFamily();
+
+ syncFamily(tkFamily);
+
+ ExtSyncEventPhysicsSync* e = NVBLAST_NEW(ExtSyncEventPhysicsSync) ();
+ e->timestamp = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
+ e->familyID = tkFamily.getID();
+ std::vector<ExtPxActor*> actors(family.getActorCount());
+ family.getActors(actors.data(), static_cast<uint32_t>(actors.size()));
+ e->data.reserve(actors.size());
+ for (ExtPxActor* actor : actors)
+ {
+ ExtSyncEventPhysicsSync::ActorData data;
+ data.transform = actor->getPhysXActor().getGlobalPose();
+ data.actorIndex = actor->getTkActor().getIndex();
+ e->data.push_back(data);
+ }
+
+ m_syncEvents.push_back(e);
+}
+
+uint32_t ExtSyncImpl::getSyncBufferSize() const
+{
+ return static_cast<uint32_t>(m_syncEvents.size());
+}
+
+void ExtSyncImpl::acquireSyncBuffer(const ExtSyncEvent* const*& buffer, uint32_t& size) const
+{
+ buffer = m_syncEvents.data();
+ size = static_cast<uint32_t>(m_syncEvents.size());
+}
+
+void ExtSyncImpl::releaseSyncBuffer()
+{
+ for (uint32_t i = 0; i < m_syncEvents.size(); ++i)
+ {
+ NVBLAST_DELETE(m_syncEvents[i], ExtSyncEvent);
+ }
+ m_syncEvents.clear();
+}
+
+void ExtSyncImpl::applySyncBuffer(TkFramework& framework, const ExtSyncEvent** buffer, uint32_t size, TkGroup* groupForNewActors, ExtPxManager* manager)
+{
+ const TkType* familyType = framework.getType(TkTypeIndex::Family);
+ NVBLAST_ASSERT(familyType);
+
+ for (uint32_t i = 0; i < size; ++i)
+ {
+ const ExtSyncEvent* e = buffer[i];
+ const NvBlastID& id = e->familyID;
+ TkIdentifiable* object = framework.findObjectByID(id);
+ if (object && object->getType() == *familyType)
+ {
+ TkFamily* family = static_cast<TkFamily*>(object);
+
+ if (e->type == ExtSyncEventFracture::EVENT_TYPE)
+ {
+ const ExtSyncEventFracture* fractureEvent = e->getEvent<ExtSyncEventFracture>();
+ const NvBlastFractureBuffers commands =
+ {
+ static_cast<uint32_t>(fractureEvent->bondFractures.size()),
+ static_cast<uint32_t>(fractureEvent->chunkFractures.size()),
+ const_cast<NvBlastBondFractureData*>(fractureEvent->bondFractures.data()),
+ const_cast<NvBlastChunkFractureData*>(fractureEvent->chunkFractures.data())
+ };
+ family->applyFracture(&commands);
+ }
+ else if (e->type == ExtSyncEventFamilySync::EVENT_TYPE)
+ {
+ const ExtSyncEventFamilySync* familyEvent = e->getEvent<ExtSyncEventFamilySync>();
+ family->reinitialize((NvBlastFamily*)familyEvent->family.data(), groupForNewActors);
+ }
+ else if (e->type == ExtSyncEventPhysicsSync::EVENT_TYPE && manager)
+ {
+ const ExtSyncEventPhysicsSync* physicsEvent = e->getEvent<ExtSyncEventPhysicsSync>();
+ ExtPxFamily* pxFamily = manager->getFamilyFromTkFamily(*family);
+ if (pxFamily)
+ {
+ std::vector<ExtPxActor*> actors(pxFamily->getActorCount());
+ pxFamily->getActors(actors.data(), static_cast<uint32_t>(actors.size()));
+
+ for (auto data : physicsEvent->data)
+ {
+ for (ExtPxActor* physicsaActor : actors)
+ {
+ if (data.actorIndex == physicsaActor->getTkActor().getIndex())
+ {
+ physicsaActor->getPhysXActor().setGlobalPose(data.transform);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+} // namespace Blast
+} // namespace Nv
|