diff options
| author | Bryan Galdrikian <[email protected]> | 2017-10-24 15:25:02 -0700 |
|---|---|---|
| committer | Bryan Galdrikian <[email protected]> | 2017-10-24 15:25:02 -0700 |
| commit | b0c11962f6012430da3bcaa2727288046b33d648 (patch) | |
| tree | cf13338fa4fd7072badf64f751f94abeeb437003 /samples/SampleBase | |
| parent | linux build fix - all configs (diff) | |
| download | blast-b0c11962f6012430da3bcaa2727288046b33d648.tar.xz blast-b0c11962f6012430da3bcaa2727288046b33d648.zip | |
Changes for 1.1.1
See README.md
Diffstat (limited to 'samples/SampleBase')
| -rw-r--r-- | samples/SampleBase/blast/BlastAsset.cpp | 13 | ||||
| -rw-r--r-- | samples/SampleBase/blast/BlastAsset.h | 16 | ||||
| -rw-r--r-- | samples/SampleBase/blast/BlastController.cpp | 53 | ||||
| -rw-r--r-- | samples/SampleBase/blast/BlastController.h | 89 | ||||
| -rw-r--r-- | samples/SampleBase/blast/BlastFamily.cpp | 43 | ||||
| -rw-r--r-- | samples/SampleBase/blast/BlastFamily.h | 12 | ||||
| -rw-r--r-- | samples/SampleBase/ui/DamageToolController.cpp | 131 | ||||
| -rw-r--r-- | samples/SampleBase/ui/DamageToolController.h | 14 |
8 files changed, 305 insertions, 66 deletions
diff --git a/samples/SampleBase/blast/BlastAsset.cpp b/samples/SampleBase/blast/BlastAsset.cpp index 3900e2c..3d536d6 100644 --- a/samples/SampleBase/blast/BlastAsset.cpp +++ b/samples/SampleBase/blast/BlastAsset.cpp @@ -29,14 +29,23 @@ #include "BlastAsset.h" #include "NvBlastExtPxAsset.h" #include "NvBlastTkAsset.h" +#include "NvBlastExtDamageShaders.h" #include <algorithm> BlastAsset::BlastAsset(Renderer& renderer) - : m_renderer(renderer), m_bondHealthMax(1.0f), m_supportChunkHealthMax(1.0f) + : m_renderer(renderer), m_bondHealthMax(1.0f), m_supportChunkHealthMax(1.0f), m_damageAccelerator(nullptr) { } +BlastAsset::~BlastAsset() +{ + if (m_damageAccelerator) + { + m_damageAccelerator->release(); + } +} + void BlastAsset::initialize() { // calc max healths @@ -68,6 +77,8 @@ void BlastAsset::initialize() { m_supportChunkHealthMax = actorDesc.uniformInitialLowerSupportChunkHealth; } + + m_damageAccelerator = NvBlastExtDamageAcceleratorCreate(m_pxAsset->getTkAsset().getAssetLL(), 3); } size_t BlastAsset::getBlastAssetSize() const diff --git a/samples/SampleBase/blast/BlastAsset.h b/samples/SampleBase/blast/BlastAsset.h index 7eafddf..d0a60fb 100644 --- a/samples/SampleBase/blast/BlastAsset.h +++ b/samples/SampleBase/blast/BlastAsset.h @@ -39,6 +39,7 @@ using namespace physx; class Renderer; class BlastFamily; class PhysXController; +class NvBlastExtDamageAccelerator; namespace Nv { @@ -62,7 +63,7 @@ public: //////// ctor //////// BlastAsset(Renderer& renderer); - virtual ~BlastAsset() {} + virtual ~BlastAsset(); //////// desc //////// @@ -85,7 +86,7 @@ public: //////// data getters //////// - const ExtPxAsset* getPxAsset() const + ExtPxAsset* getPxAsset() const { return m_pxAsset; } @@ -102,6 +103,10 @@ public: return m_bondHealthMax; } + NvBlastExtDamageAccelerator* getAccelerator() const + { + return m_damageAccelerator; + } protected: //////// internal operations //////// @@ -116,9 +121,10 @@ protected: //////// internal data //////// - ExtPxAsset* m_pxAsset; - float m_bondHealthMax; - float m_supportChunkHealthMax; + ExtPxAsset* m_pxAsset; + float m_bondHealthMax; + float m_supportChunkHealthMax; + NvBlastExtDamageAccelerator* m_damageAccelerator; }; diff --git a/samples/SampleBase/blast/BlastController.cpp b/samples/SampleBase/blast/BlastController.cpp index b74593d..2f79775 100644 --- a/samples/SampleBase/blast/BlastController.cpp +++ b/samples/SampleBase/blast/BlastController.cpp @@ -43,6 +43,7 @@ #include "NvBlastExtPxManager.h" #include "NvBlastExtPxFamily.h" #include "NvBlastExtPxActor.h" +#include "NvBlastExtPxAsset.h" #include "NvBlastExtSerialization.h" #include "NvBlastExtTkSerialization.h" #include "NvBlastExtPxSerialization.h" @@ -83,7 +84,7 @@ static physx::PxJoint* createPxJointCallback(ExtPxActor* actor0, const physx::Px BlastController::BlastController() : m_eventCallback(nullptr), debugRenderMode(BlastFamily::DEBUG_RENDER_DISABLED), m_impactDamageEnabled(true), m_impactDamageToStressEnabled(false), m_rigidBodyLimitEnabled(true), m_rigidBodyLimit(40000), m_blastAssetsSize(0), debugRenderScale(0.01f), -m_taskManager(nullptr), m_extGroupTaskManager(nullptr) +m_taskManager(nullptr), m_extGroupTaskManager(nullptr), m_damageDescBuffer(64 * 1024), m_damageParamsBuffer(1024) { m_impactDamageToStressFactor = 0.01f; m_draggingToStressFactor = 100.0f; @@ -175,6 +176,51 @@ void BlastController::notifyPhysXControllerRelease() } } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Deffered/Immediate damage +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void BlastController::deferDamage(ExtPxActor *actor, BlastFamily& family, const NvBlastDamageProgram& program, const void* damageDesc, uint32_t damageDescSize) +{ + const void* bufferedDamageDesc = m_damageDescBuffer.push(damageDesc, damageDescSize); + PX_ASSERT_WITH_MESSAGE(bufferedDamageDesc, "Damage desc buffer exhausted."); + + NvBlastExtProgramParams programParams = { bufferedDamageDesc, &family.getMaterial(), actor->getFamily().getPxAsset().getAccelerator() }; + + const void* bufferedProgramParams = m_damageParamsBuffer.push(&programParams, sizeof(NvBlastExtProgramParams)); + PX_ASSERT_WITH_MESSAGE(bufferedProgramParams, "Damage params buffer exhausted."); + + if (bufferedDamageDesc && bufferedProgramParams) + { + actor->getTkActor().damage(program, bufferedProgramParams); + } +} + +NvBlastFractureBuffers& BlastController::getFractureBuffers(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.data()); + m_fractureBuffers.bondFractures = reinterpret_cast<NvBlastBondFractureData*>(&m_fractureData.data()[m_fractureBuffers.chunkFractureCount * sizeof(NvBlastChunkFractureData)]); + return m_fractureBuffers; +} + +void BlastController::immediateDamage(ExtPxActor *actor, BlastFamily& family, const NvBlastDamageProgram& program, const void* damageDesc) +{ + NvBlastExtProgramParams programParams = { damageDesc, &family.getMaterial(), actor->getFamily().getPxAsset().getAccelerator() }; + + NvBlastFractureBuffers& fractureEvents = getFractureBuffers(actor); + actor->getTkActor().generateFracture(&fractureEvents, program, &programParams); + actor->getTkActor().applyFracture(nullptr, &fractureEvents); +} + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Impact damage /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -334,6 +380,9 @@ void BlastController::Animate(double dt) #endif + m_damageParamsBuffer.clear(); + m_damageDescBuffer.clear(); + PROFILER_END(); getPhysXController().simulationBegin(dt); @@ -437,7 +486,7 @@ void BlastController::recalculateAssetsSize() } } -bool BlastController::overlap(const PxGeometry& geometry, const PxTransform& pose, std::function<void(ExtPxActor*)> hitCall) +bool BlastController::overlap(const PxGeometry& geometry, const PxTransform& pose, std::function<void(ExtPxActor*, BlastFamily&)> hitCall) { PROFILER_SCOPED_FUNCTION(); diff --git a/samples/SampleBase/blast/BlastController.h b/samples/SampleBase/blast/BlastController.h index a019339..0de199c 100644 --- a/samples/SampleBase/blast/BlastController.h +++ b/samples/SampleBase/blast/BlastController.h @@ -88,10 +88,14 @@ public: //////// public API //////// - bool overlap(const PxGeometry& geometry, const PxTransform& pose, std::function<void(ExtPxActor*)> hitCall); + bool overlap(const PxGeometry& geometry, const PxTransform& pose, std::function<void(ExtPxActor*, BlastFamily&)> hitCall); bool stressDamage(ExtPxActor *actor, PxVec3 position, PxVec3 force); + void deferDamage(ExtPxActor *actor, BlastFamily& family, const NvBlastDamageProgram& program, const void* damageDesc, uint32_t damageDescSize); + void immediateDamage(ExtPxActor *actor, BlastFamily& family, const NvBlastDamageProgram& program, const void* damageDesc); + NvBlastFractureBuffers& getFractureBuffers(ExtPxActor* actor); + BlastFamilyPtr spawnFamily(BlastAsset* blastAsset, const BlastAsset::ActorDesc& desc); void removeFamily(BlastFamilyPtr actor); void removeAllFamilies(); @@ -229,37 +233,76 @@ private: } + //////// buffer for damage //////// + + class FixedBuffer + { + public: + FixedBuffer(const uint32_t size) + { + m_buffer.resize(size); + m_index = 0; + } + + void* push(const void* data, uint32_t size) + { + if (m_index + size > m_buffer.size()) + return nullptr; + + void* dst = &m_buffer[m_index]; + memcpy(dst, data, size); + m_index += size; + return dst; + } + + void clear() + { + m_index = 0; + } + + private: + std::vector<char> m_buffer; + uint32_t m_index; + }; + + //////// internal data //////// - PxTaskManager* m_taskManager; - TkFramework* m_tkFramework; - TkGroup* m_tkGroup; - ExtPxManager* m_extPxManager; - ExtImpactDamageManager* m_extImpactDamageManager; - ExtImpactSettings m_extImpactDamageManagerSettings; - EventCallback* m_eventCallback; - ExtStressSolverSettings m_extStressSolverSettings; - ExtGroupTaskManager* m_extGroupTaskManager; - ExtSerialization* m_extSerialization; + PxTaskManager* m_taskManager; + TkFramework* m_tkFramework; + TkGroup* m_tkGroup; + ExtPxManager* m_extPxManager; + ExtImpactDamageManager* m_extImpactDamageManager; + ExtImpactSettings m_extImpactDamageManagerSettings; + EventCallback* m_eventCallback; + ExtStressSolverSettings m_extStressSolverSettings; + ExtGroupTaskManager* m_extGroupTaskManager; + ExtSerialization* m_extSerialization; + + std::vector<BlastFamilyPtr> m_families; + DebugRenderBuffer m_debugRenderBuffer; + + FixedBuffer m_damageDescBuffer; + FixedBuffer m_damageParamsBuffer; - std::vector<BlastFamilyPtr> m_families; - DebugRenderBuffer m_debugRenderBuffer; + NvBlastFractureBuffers m_fractureBuffers; + std::vector<char> m_fractureData; - bool m_impactDamageEnabled; - bool m_impactDamageUpdatePending; - bool m_impactDamageToStressEnabled; + bool m_impactDamageEnabled; + bool m_impactDamageUpdatePending; + bool m_impactDamageToStressEnabled; - float m_impactDamageToStressFactor; - float m_draggingToStressFactor; + float m_impactDamageToStressFactor; + float m_draggingToStressFactor; - bool m_rigidBodyLimitEnabled; - uint32_t m_rigidBodyLimit; + bool m_rigidBodyLimitEnabled; + uint32_t m_rigidBodyLimit; - BlastReplay* m_replay; + BlastReplay* m_replay; - BlastTimers m_lastBlastTimers; + BlastTimers m_lastBlastTimers; - size_t m_blastAssetsSize; + size_t m_blastAssetsSize; }; diff --git a/samples/SampleBase/blast/BlastFamily.cpp b/samples/SampleBase/blast/BlastFamily.cpp index a966372..a9a9e6f 100644 --- a/samples/SampleBase/blast/BlastFamily.cpp +++ b/samples/SampleBase/blast/BlastFamily.cpp @@ -58,9 +58,11 @@ BlastFamily::BlastFamily(PhysXController& physXController, ExtPxManager& pxManag , m_totalVisibleChunkCount(0) , m_stressSolver(nullptr) , m_spawned(false) + , m_debugRenderDepth(-1) { m_settings.stressSolverEnabled = false; m_settings.stressDamageEnabled = false; + m_settings.damageAcceleratorEnabled = true; } BlastFamily::~BlastFamily() @@ -82,10 +84,13 @@ void BlastFamily::initialize(const BlastAsset::ActorDesc& desc) familyDesc.group = desc.group; familyDesc.pxAsset = m_blastAsset.getPxAsset(); m_pxFamily = m_pxManager.createFamily(familyDesc); + m_pxFamily->setMaterial(&m_settings.material); + m_tkFamily = &m_pxFamily->getTkFamily(); m_tkFamily->setID(desc.id); - m_tkFamily->setMaterial(&m_settings.material); + + refreshDamageAcceleratorSettings(); m_familySize = NvBlastFamilyGetSize(m_tkFamily->getFamilyLL(), nullptr); @@ -196,6 +201,16 @@ void BlastFamily::drawUI() ImGui::DragFloat("Min Damage Threshold", &m_settings.material.minDamageThreshold, 0.01f, 0.f, m_settings.material.maxDamageThreshold); ImGui::DragFloat("Max Damage Threshold", &m_settings.material.maxDamageThreshold, 0.01f, m_settings.material.minDamageThreshold, 1.f); + if (ImGui::Checkbox("AABB Tree (Damage Accelerator)", &m_settings.damageAcceleratorEnabled)) + { + refreshDamageAcceleratorSettings(); + } + if (m_settings.damageAcceleratorEnabled) + { + ImGui::DragInt("AABB Tree debug depth", &m_debugRenderDepth); + } + + ImGui::Spacing(); // Stress Solver Settings @@ -274,13 +289,19 @@ void BlastFamily::setSettings(const Settings& settings) m_settings = settings; refreshStressSolverSettings(); + refreshDamageAcceleratorSettings(); if (reloadStressSolverNeeded) { reloadStressSolver(); } - m_tkFamily->setMaterial(&m_settings.material); + m_pxFamily->setMaterial(&m_settings.material); +} + +void BlastFamily::refreshDamageAcceleratorSettings() +{ + m_pxFamily->getPxAsset().setAccelerator(m_settings.damageAcceleratorEnabled ? m_blastAsset.getAccelerator() : nullptr); } void BlastFamily::refreshStressSolverSettings() @@ -451,6 +472,20 @@ void BlastFamily::fillDebugRender(DebugRenderBuffer& debugRenderBuffer, DebugRen } } + // AABB tree + if (mode == DEBUG_RENDER_AABB_TREE_CENTROIDS || mode == DEBUG_RENDER_AABB_TREE_SEGMENTS) + { + if (m_settings.damageAcceleratorEnabled && m_blastAsset.getAccelerator() && nodeCount > graph.nodeCount / 2) + { + const auto buffer = m_blastAsset.getAccelerator()->fillDebugRender(m_debugRenderDepth, mode == DEBUG_RENDER_AABB_TREE_SEGMENTS); + if (buffer.lineCount) + { + const auto lines = reinterpret_cast<const PxDebugLine*>(buffer.lines); + debugRenderBuffer.m_lines.insert(debugRenderBuffer.m_lines.end(), lines, lines + buffer.lineCount); + } + } + } + // transform all added lines from local to global PxTransform localToGlobal = pxActor->getPhysXActor().getGlobalPose(); for (uint32_t i = lineStartIndex; i < debugRenderBuffer.m_lines.size(); i++) @@ -525,7 +560,7 @@ private: PxOverlapHit m_hitBuffer[1000]; }; -bool BlastFamily::overlap(const PxGeometry& geometry, const PxTransform& pose, std::function<void(ExtPxActor*)> hitCall) +bool BlastFamily::overlap(const PxGeometry& geometry, const PxTransform& pose, std::function<void(ExtPxActor*, BlastFamily&)> hitCall) { std::set<ExtPxActor*> actorsToDamage; #if 1 @@ -540,7 +575,7 @@ bool BlastFamily::overlap(const PxGeometry& geometry, const PxTransform& pose, s for (auto actor : actorsToDamage) { - hitCall(actor); + hitCall(actor, *this); } return !actorsToDamage.empty(); diff --git a/samples/SampleBase/blast/BlastFamily.h b/samples/SampleBase/blast/BlastFamily.h index 5a8000e..599e742 100644 --- a/samples/SampleBase/blast/BlastFamily.h +++ b/samples/SampleBase/blast/BlastFamily.h @@ -66,7 +66,7 @@ public: //////// public API //////// - bool overlap(const PxGeometry& geometry, const PxTransform& pose, std::function<void(ExtPxActor*)> hitCall); + bool overlap(const PxGeometry& geometry, const PxTransform& pose, std::function<void(ExtPxActor*, BlastFamily&)> hitCall); void updatePreSplit(float dt); void updateAfterSplit(float dt); @@ -82,6 +82,8 @@ public: DEBUG_RENDER_CENTROIDS, DEBUG_RENDER_HEALTH_GRAPH_CENTROIDS, DEBUG_RENDER_JOINTS, + DEBUG_RENDER_AABB_TREE_CENTROIDS, + DEBUG_RENDER_AABB_TREE_SEGMENTS, DEBUG_RENDER_STRESS_GRAPH, DEBUG_RENDER_STRESS_GRAPH_NODES_IMPULSES, DEBUG_RENDER_STRESS_GRAPH_BONDS_IMPULSES, @@ -100,6 +102,11 @@ public: return m_pxFamily; } + const NvBlastExtMaterial& getMaterial() const + { + return m_settings.material; + } + uint32_t getActorCount() const; uint32_t getTotalVisibleChunkCount() const @@ -120,6 +127,7 @@ public: void resetStress(); void refreshStressSolverSettings(); + void refreshDamageAcceleratorSettings(); void reloadStressSolver(); @@ -131,6 +139,7 @@ public: bool stressSolverEnabled; ExtStressSolverSettings stressSolverSettings; bool stressDamageEnabled; + bool damageAcceleratorEnabled; NvBlastExtMaterial material; }; @@ -216,6 +225,7 @@ private: double m_stressSolveTime; std::set<ExtPxActor*> m_actors; std::set<const ExtPxActor*> m_actorsToUpdateHealth; + int m_debugRenderDepth; }; diff --git a/samples/SampleBase/ui/DamageToolController.cpp b/samples/SampleBase/ui/DamageToolController.cpp index 2f8837c..8a0d1e7 100644 --- a/samples/SampleBase/ui/DamageToolController.cpp +++ b/samples/SampleBase/ui/DamageToolController.cpp @@ -39,6 +39,7 @@ #include "NvBlastTkFamily.h" #include "NvBlastExtDamageShaders.h" #include "NvBlastExtPxActor.h" +#include "NvBlastExtPxFamily.h" #include "PxRigidDynamic.h" #include "PxScene.h" @@ -68,12 +69,12 @@ DamageToolController::DamageToolController() // damage amount calc using NvBlastExtMaterial auto getDamageAmountFn = [](const float damage, ExtPxActor* actor) { - const void* material = actor->getTkActor().getFamily().getMaterial(); - return material ? reinterpret_cast<const NvBlastExtMaterial*>(material)->getNormalizedDamage(damage) : 0.f; + const NvBlastExtMaterial* material = actor->getFamily().getMaterial(); + return material ? material->getNormalizedDamage(damage) : 0.f; }; // Damage functions - auto radialDamageExecute = [&](const Damager* damager, ExtPxActor* actor, PxVec3 origin, PxVec3 position, PxVec3 normal) + auto radialDamageExecute = [&](const Damager* damager, ExtPxActor* actor, BlastFamily& family, const Damager::DamageData& data) { const float damage = getDamageAmountFn(m_damage, actor); if (damage > 0.f) @@ -81,58 +82,95 @@ DamageToolController::DamageToolController() NvBlastExtRadialDamageDesc desc = { damage, - { position.x, position.y, position.z }, + { data.hitPosition.x, data.hitPosition.y, data.hitPosition.z }, damager->radius, damager->radius * 1.6f }; - actor->getTkActor().damage(damager->program, &desc, sizeof(desc)); + getBlastController().deferDamage(actor, family, damager->program, &desc, sizeof(desc)); } }; - auto lineSegmentDamageExecute = [&](const Damager* damager, ExtPxActor* actor, PxVec3 origin, PxVec3 position, PxVec3 normal) + auto sliceDamageExecute = [&](const Damager* damager, ExtPxActor* actor, BlastFamily& family, const Damager::DamageData& data) { const float damage = getDamageAmountFn(m_damage, actor); if (damage > 0.f) { - PxVec3 dir = (position - origin).getNormalized(); - PxVec3 farEnd = origin + dir * 10000.0f; + PxVec3 farEnd = data.origin + data.weaponDir * 1000.0f; + PxVec3 farEndPrev = data.origin + data.previousWeaponDir * 1000.0f; - NvBlastExtSegmentRadialDamageDesc desc = + NvBlastExtTriangleIntersectionDamageDesc desc = { damage, - { origin.x, origin.y, origin.z }, + { data.origin.x, data.origin.y, data.origin.z }, { farEnd.x, farEnd.y, farEnd.z }, + { farEndPrev.x, farEndPrev.y, farEndPrev.z }, + }; + + getBlastController().deferDamage(actor, family, damager->program, &desc, sizeof(desc)); + } + }; + auto capsuleDamageExecute = [&](const Damager* damager, ExtPxActor* actor, BlastFamily& family, const Damager::DamageData& data) + { + const float damage = getDamageAmountFn(m_damage, actor); + if (damage > 0.f) + { + PxVec3 dir = (data.hitPosition - data.origin).getNormalized(); + PxVec3 farEnd = data.origin + dir * 10000.0f; + + NvBlastExtCapsuleRadialDamageDesc desc = + { + damage, + { data.origin.x, data.origin.y, data.origin.z }, + { farEnd.x, farEnd.y, farEnd.z }, + damager->radius, + damager->radius * 1.6f + }; + + getBlastController().deferDamage(actor, family, damager->program, &desc, sizeof(desc)); + } + }; + auto impulseSpreadDamageExecute = [&](const Damager* damager, ExtPxActor* actor, BlastFamily& family, const Damager::DamageData& data) + { + const float damage = m_damage; + if (damage > 0.f) + { + PxVec3 impactNormal = -data.hitNormal; + + NvBlastExtImpactSpreadDamageDesc desc = + { + damage, + { data.hitPosition.x, data.hitPosition.y, data.hitPosition.z }, damager->radius, damager->radius * 1.6f }; - actor->getTkActor().damage(damager->program, &desc, sizeof(desc)); + getBlastController().immediateDamage(actor, family, damager->program, &desc); } }; - auto shearDamageExecute = [&](const Damager* damager, ExtPxActor* actor, PxVec3 origin, PxVec3 position, PxVec3 normal) + auto shearDamageExecute = [&](const Damager* damager, ExtPxActor* actor, BlastFamily& family, const Damager::DamageData& data) { const float damage = getDamageAmountFn(m_damage, actor); if (damage > 0.f) { - PxVec3 impactNormal = -normal; + PxVec3 impactNormal = -data.hitNormal; NvBlastExtShearDamageDesc desc = { damage, { impactNormal.x, impactNormal.y, impactNormal.z }, - { position.x, position.y, position.z }, + { data.hitPosition.x, data.hitPosition.y, data.hitPosition.z }, damager->radius, damager->radius * 1.6f }; - actor->getTkActor().damage(damager->program, &desc, sizeof(desc)); + getBlastController().deferDamage(actor, family, damager->program, &desc, sizeof(desc)); } }; - auto stressDamageExecute = [&](const Damager* damager, ExtPxActor* actor, PxVec3 origin, PxVec3 position, PxVec3 normal) + auto stressDamageExecute = [&](const Damager* damager, ExtPxActor* actor, BlastFamily& family, const Damager::DamageData& data) { - PxVec3 force = -m_stressForceFactor * normal * actor->getPhysXActor().getMass(); + PxVec3 force = -m_stressForceFactor * data.hitNormal * actor->getPhysXActor().getMass(); - getBlastController().stressDamage(actor, position, force); + getBlastController().stressDamage(actor, data.hitPosition, force); }; // Damage Tools: @@ -157,11 +195,24 @@ DamageToolController::DamageToolController() { Damager dam; - dam.uiName = "Segment Damage (Falloff)"; - dam.program = NvBlastDamageProgram{ NvBlastExtSegmentFalloffGraphShader, NvBlastExtSegmentFalloffSubgraphShader }; + dam.uiName = "Slice Damage"; + dam.program = NvBlastDamageProgram{ NvBlastExtTriangleIntersectionGraphShader, NvBlastExtTriangleIntersectionSubgraphShader }; + dam.pointerType = Damager::PointerType::Line; + dam.pointerColor = DirectX::XMFLOAT4(0.1f, 1.0f, 0.1f, 0.4f); + dam.executeFunction = sliceDamageExecute; + dam.damageWhilePressed = true; + dam.radius = .2f; + dam.radiusLimit = .2f; + m_damagers.push_back(dam); + } + + { + Damager dam; + dam.uiName = "Capsule Damage (Falloff)"; + dam.program = NvBlastDamageProgram{ NvBlastExtCapsuleFalloffGraphShader, NvBlastExtCapsuleFalloffSubgraphShader }; dam.pointerType = Damager::PointerType::Line; dam.pointerColor = DirectX::XMFLOAT4(0.1f, 1.0f, 0.1f, 0.4f); - dam.executeFunction = lineSegmentDamageExecute; + dam.executeFunction = capsuleDamageExecute; dam.damageWhilePressed = true; dam.radius = .2f; dam.radiusLimit = 20.0f; @@ -170,8 +221,18 @@ DamageToolController::DamageToolController() { Damager dam; + dam.uiName = "Impact Spread Damage"; + dam.program = NvBlastDamageProgram { NvBlastExtImpactSpreadGraphShader, NvBlastExtImpactSpreadSubgraphShader }; + dam.pointerType = Damager::PointerType::Sphere; + dam.pointerColor = DirectX::XMFLOAT4(0.5f, 1.0f, 0.5f, 0.4f); + dam.executeFunction = impulseSpreadDamageExecute; + m_damagers.push_back(dam); + } + + { + Damager dam; dam.uiName = "Shear Damage"; - dam.program = NvBlastDamageProgram { NvBlastExtShearGraphShader, NvBlastExtShearSubgraphShader }; + dam.program = NvBlastDamageProgram{ NvBlastExtShearGraphShader, NvBlastExtShearSubgraphShader }; dam.pointerType = Damager::PointerType::Sphere; dam.pointerColor = DirectX::XMFLOAT4(0.5f, 1.0f, 0.5f, 0.4f); dam.executeFunction = shearDamageExecute; @@ -243,6 +304,8 @@ void DamageToolController::Animate(double dt) // damage mode if (m_damageMode) { + const Damager& damager = m_damagers[m_damagerIndex]; + // ray cast according to camera + mouse ray PxVec3 eyePos, pickDir; getPhysXController().getEyePoseAndPickDir(m_lastMousePos.x, m_lastMousePos.y, eyePos, pickDir); @@ -253,21 +316,24 @@ void DamageToolController::Animate(double dt) getPhysXController().getPhysXScene().raycast(eyePos, pickDir, PX_MAX_F32, hit1, PxHitFlag::ePOSITION | PxHitFlag::eNORMAL); hit = hit1.block; - if (hit.shape) + if (hit.shape || (m_prevWasHit && damager.pointerType == Damager::Line)) { PxMat44 cameraViewInv = XMMATRIXToPxMat44(getRenderer().getCamera().GetViewMatrix()).inverseRT(); PxVec3 weaponOrigin = eyePos + cameraViewInv.rotate(WEAPON_POSITION_IN_VIEW); + PxVec3 weaponDir = (hit.position - weaponOrigin).getNormalized(); // damage function - const Damager& damager = m_damagers[m_damagerIndex]; - auto damageFunction = [&](ExtPxActor* actor) + auto damageFunction = [&](ExtPxActor* actor, BlastFamily& family) { auto t0 = actor->getPhysXActor().getGlobalPose(); PxTransform t(t0.getInverse()); - PxVec3 localNormal = t.rotate(hit.normal); - PxVec3 localPosition = t.transform(hit.position); - PxVec3 localOrigin = t.transform(weaponOrigin); - damager.executeFunction(&damager, actor, localOrigin, localPosition, localNormal); + Damager::DamageData data; + data.hitNormal = t.rotate(hit.normal); + data.hitPosition = t.transform(hit.position); + data.origin = t.transform(weaponOrigin); + data.weaponDir = t.rotate(weaponDir); + data.previousWeaponDir = t.rotate(m_previousPickDir); + damager.executeFunction(&damager, actor, family, data); }; // should damage? @@ -324,6 +390,13 @@ void DamageToolController::Animate(double dt) { PX_ASSERT(false); } + + m_previousPickDir = weaponDir; + m_prevWasHit = true; + } + else + { + m_prevWasHit = false; } } } diff --git a/samples/SampleBase/ui/DamageToolController.h b/samples/SampleBase/ui/DamageToolController.h index ae14064..cf07a83 100644 --- a/samples/SampleBase/ui/DamageToolController.h +++ b/samples/SampleBase/ui/DamageToolController.h @@ -39,6 +39,7 @@ class Renderable; class RenderMaterial; +class BlastFamily; namespace Nv { @@ -122,7 +123,16 @@ private: Line }; - typedef std::function<void(const Damager* damager, Nv::Blast::ExtPxActor* actor, physx::PxVec3 origin, physx::PxVec3 position, physx::PxVec3 normal)> ExecuteFn; + struct DamageData + { + physx::PxVec3 origin; + physx::PxVec3 hitPosition; + physx::PxVec3 hitNormal; + physx::PxVec3 weaponDir; + physx::PxVec3 previousWeaponDir; + }; + + typedef std::function<void(const Damager* damager, Nv::Blast::ExtPxActor* actor, BlastFamily& family, const DamageData& damageData)> ExecuteFn; const char* uiName; NvBlastDamageProgram program; @@ -143,6 +153,8 @@ private: physx::PxVec2 m_lastMousePos; bool m_isMousePressed; uint32_t m_damageCountWhilePressed; + physx::PxVec3 m_previousPickDir; + bool m_prevWasHit; }; #endif
\ No newline at end of file |