diff options
Diffstat (limited to 'NvBlast/docs/_source/ext_physx.txt')
| -rw-r--r-- | NvBlast/docs/_source/ext_physx.txt | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/NvBlast/docs/_source/ext_physx.txt b/NvBlast/docs/_source/ext_physx.txt new file mode 100644 index 0000000..70a8e2e --- /dev/null +++ b/NvBlast/docs/_source/ext_physx.txt @@ -0,0 +1,244 @@ +/*! \page pageextphysx PhysX Extensions + +NvBlastExtPhysX contains extensions for easier use of Blast Toolkit with the PhysX SDK. +There are 3 of them: +- <b>ExtPxManager</b>: Manager to keep Blast Actors in sync with PhysX actors. +- <b>ExtImpactDamageManager</b>: Manager to collect and apply impact damage caused by collision in PhysX Scene. +- <b>ExtStressSolver</b>: Stress Solver to propagate stress through support graph and apply it as damage to Blast actors. + +This library also contains an extension for synchronizing Blast state: +- <b>ExtSync</b> - Utility for writing Blast state to a buffer, to be read by a client. This may be used for networking, for example. + + +<br> +\section ExtPxManager + +<b>Physics Manager</b> - is a reference implementation for keeping Blast Actors synced with PhysX actors. It's main job is to listen +for TkFamily events and update \a PxScene (by adding and removing PxActors) accordingly. + +In order to use it create ExtPxManager: + +\code +ExtPxManager* pxManager = ExtPxManager::create(m_physics, m_tkFramework); +\endcode + +For every \a TkAsset prepare \a ExtPxAsset. Which contains \a TkAsset + collection of physics geometry for every chunk. Every chunk can contain any number of subchunks. +Where each subchunk is basically PxConvexMeshGeometry with transform. Also every chunk can be marked as static (\a isStatic flag). +If actor contains at least one static chunks in it's support graph it makes an actor kinematic (static), otherwise it's dynamic. +Having zero subchunks makes chunk invisible in physics scene, it can be used for example to represent 'earth' as a special invisible static chunk and connect all near earth chunks to it. + + +To create a \a ExtPxFamily from an \a ExtPxAsset: + +\code +ExtPxFamilyDesc familyDesc; +familyDesc.pxAsset = pxAsset; +familyDesc.group = tkGroup; +familyDesc.actorDesc.initialBondHealths = nullptr; +familyDesc.actorDesc.initialSupportChunkHealths = nullptr; +familyDesc.actorDesc.uniformInitialBondHealth = BOND_HEALTH_MAX; +familyDesc.actorDesc.uniformInitialLowerSupportChunkHealth = 1.0f; +ExtPxFamily* family = pxManager->createFamily(desc); +\endcode + +You can subscribe to family events in order to sync graphics (or anything else) with physics: + +\code +family->subscribe(listener); +\endcode + +Listener will be notified with all physics actors added and removed. + +And finally spawn the family in some world position (the first actor/actors will be created and event will be fired to the listener): + +\code + +ExtPxSpawnSettings spawnSettings = { + &pxScene, + defaultPxMaterial, + RIGIDBODY_DENSITY +}; + +family->spawn(PxTransform(0, 0, 0), spawnSettings); +\endcode + +You can get families actor's either from listening to events or by calling getActors(). +Every \a ExtPxActor matches 1 <-> 1 with TkActor (which matches \a NvBlastActor accordingly). + +\code +ExtPxActor* actor = ....; +physx::PxRigidDynamic rigidDynamic = actor->getPxActor(); // +\endcode + +ExtPxActor remains internally unchanged through it's life time. +Use \a ExtPxActor \a getChunkIndices() and \a getPxActor() to update graphics representation. Sample code: + +\code + const uint32_t* chunkIndices; + size_t chunkIndexCount; + actor.getChunkIndices(chunkIndices, chunkIndexCount); + for (uint32_t i = 0; i < chunkIndexCount; i++) + { + uint32_t chunkIndex = chunkIndices[i]; + for (Renderable* r : m_chunks[chunkIndex].renderables) + { + r->setTransform(actor.getPxActor()->getGlobalPose() * pxAsset.chunks[chunkIndex].convexes[0].transform); + } + } +\endcode + +In order to use joints set joint create function with \a ExtPxManager::setCreateJointFunction(...). It will be called when new TkJoint's are +being created. All the joint updates and remove will be handled by manager internally. + +<br> +\section ExtImpactDamageManager + +<b>Impact Damage Manager</b> - is a reference implementation for fast and easy impact damage support. It's built on top of ExtPxManager. + +In order to use it create it: + +\code +ExtImpactDamageManager* impactManager = ExtImpactDamageManager::create(pxManager); +\endcode + +Call it's onContact method on every \a PxSimulationEventCallback \a onContact() + +\code + class EventCallback : public PxSimulationEventCallback + { + public: + EventCallback(ExtImpactDamageManager* manager) : m_manager(manager) {} + + virtual void onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, uint32_t nbPairs) + { + m_manager->onContact(pairHeader, pairs, nbPairs); + } + + private: + ExtImpactDamageManager* m_manager; + }; +\endcode + +Call \a applyDamage() when you want the buffered damage to be applied: + +\code +impactManager->applyDamage(); +\endcode + +Also important to enable contact notification with custom filter shader for PxScene. \a ImpactDamageManager has a reference filter shader +implementation which can be used for that: + +\code +PxSceneDesc sceneDesc; +sceneDesc.filterShader = ExtImpactDamageManager::FilterShader; +\endcode + +<br> +\section ExtStressSolver + +<b>Stress Solver</b> - is a reference implementation of stress propagation using Blast support graph. + +\subsection Features Features +- Supports both static and dynamic actors +- Propagates both linear and angular momentum +- Graph complexity selection (reduces support graph to smaller size trade off speed and quality) +- Apply stress damage on Blast Actor +- Debug Render + +\subsection Usage Usage + +In order to use it instance stress solver by providing \a ExtPxFamily: + +\code +ExtStressSolver* stressSolver = ExtStressSolver::create(family); +\endcode + +And then call update() every frame: + +\code +bool doDamage = true; // if you want to actually apply stress and damage actors +stressSolver->update(doDamage); +\endcode + +By default it will apply scene gravity on static actors and centrifugal force on dynamic actors. +Also applyImpulse(...) can be called for additional stress to apply: + +\code +stressSolver->applyImpulse(actor, position, force); +\endcode + +It fully utilizes the fact that it knows initial support graph structure and does maximum of processing +in \a create(...) method calls. After that all actors split calls are synced internally quite fast and only the actual +stress propagation takes most of computational time. +Computational time is linearly proprtional to \a bondIterationsPerFrame setting. To fine tune look for balance +between \a bondIterationsPerFrame and \a graphReductionLevel . The more bond iterations +are set the more precise computation will be. The smaller graph allows to make higher fidelity computations witihing +the same bond iterations per frame (same time spent), but actual cracks (damaged bonds) will be more sparsed as the result. + + +<br> +\section ExtSync + +<b>Synchronization Extension (NvBlastExtSync)</b> - is a reference implementation for synchronizing Blast state. + +The idea is that you can use it to write synchronization events to the buffer (on server for example) and then apply this buffer on +a client. TkFamily ID should be properly set for that. + +3 types of events are supported: + +- <b>ExtSyncEventType::Fracture</b>: Fracture event. Contains fracture commands information on particular TkFamily. Applied incrementally. Relatively small. +- <b>ExtSyncEventType::FamilySync</b>: Family sync event. Contains all necessary information to fully sync TkFamily state. +- <b>ExtSyncEventType::Physics</b>: Physics sync event. Contains all necessary information to fully sync ExtPxFamily state. + +In order to use it create ExtSync: + +\code +ExtSync* sync = ExtSync::create(); +\endcode + +Then let ExtSync insatnce listen to family fracture commands and write them to internal buffer: + +\code +TkFamily* family = ...; +family->addListener(*sync); + +// fracture family +// .... +\endcode + +You can fully record TkFamily state or ExtPxFamily state at any moment by calling: + +\code +sync->syncFamily(tkFamily); +// or +sync->syncFamily(pxFamily); +\endcode + +Now you can take sync buffer: + +\code +const ExtSyncEvent*const* buffer; +uint32_t size; +sync->acquireSyncBuffer(buffer, size); + +m_savedBuffer.resize(size); +for (uint32_t i = 0; i < size; ++i) +{ + m_savedBuffer[i] = buffer[i]->clone(); +} + +sync->releaseSyncBuffer(); +\endcode + +On the client you can then apply this buffer: + +\code +sync->applySyncBuffer(tkFramework, m_savedBuffer.data(), m_savedBuffer.size(), group, pxManager); +\endcode + +ExtPxManager is required only if sync buffer contains ExtSyncEventType::Physics events. + + +<br> + +*/ |