diff options
| author | Anton Novoselov <[email protected]> | 2017-08-01 12:53:38 +0300 |
|---|---|---|
| committer | Anton Novoselov <[email protected]> | 2017-08-01 12:53:38 +0300 |
| commit | 236f03c0b9a4982328ed1201978f7f69d192d9b2 (patch) | |
| tree | e486f2fa39dba203563895541e92c60ed3e25759 /sdk/extensions/stress/include | |
| parent | Added screens to welcome page (diff) | |
| download | blast-236f03c0b9a4982328ed1201978f7f69d192d9b2.tar.xz blast-236f03c0b9a4982328ed1201978f7f69d192d9b2.zip | |
Blast 1.1 release (windows / linux)
see docs/release_notes.txt for details
Diffstat (limited to 'sdk/extensions/stress/include')
| -rw-r--r-- | sdk/extensions/stress/include/NvBlastExtStressSolver.h | 410 |
1 files changed, 410 insertions, 0 deletions
diff --git a/sdk/extensions/stress/include/NvBlastExtStressSolver.h b/sdk/extensions/stress/include/NvBlastExtStressSolver.h new file mode 100644 index 0000000..471c35e --- /dev/null +++ b/sdk/extensions/stress/include/NvBlastExtStressSolver.h @@ -0,0 +1,410 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2016-2017 NVIDIA Corporation. All rights reserved. + + +#ifndef NVBLASTEXTSTRESSSOLVER_H +#define NVBLASTEXTSTRESSSOLVER_H + +#include "NvBlastTypes.h" +#include "PxVec3.h" +#include <vector> + + +namespace Nv +{ +namespace Blast +{ + + +/** +Stress Solver Settings + +Stress on every bond is calculated as +stress = (bond.linearStress * stressLinearFactor + bond.angularStress * stressAngularFactor) / hardness; +where: +bond.linearStress = the linear stress force on particular bond +bond.angularStress = the angular stress force on particular bond +stressLinearFactor, stressAngularFactor, hardness = multiplier parameters set by this struct + +Support graph reduction: +graphReductionLevel is the number of node merge passes. The resulting graph will be +roughly 2^graphReductionLevel times smaller than the original. +*/ +struct ExtStressSolverSettings +{ + float hardness; //!< hardness of bond's material + float stressLinearFactor; //!< linear stress on bond multiplier + float stressAngularFactor; //!< angular stress on bond multiplier + uint32_t bondIterationsPerFrame; //!< number of bond iterations to perform per frame, @see getIterationsPerFrame() below + uint32_t graphReductionLevel; //!< graph reduction level + + ExtStressSolverSettings() : + hardness(1000.0f), + stressLinearFactor(0.25f), + stressAngularFactor(0.75f), + bondIterationsPerFrame(18000), + graphReductionLevel(3) + {} +}; + + +/** +Parameter to addForce() calls, determines the exact operation that is carried out. + +@see ExtStressSolver.addForce() +*/ +struct ExtForceMode +{ + enum Enum + { + IMPULSE, //!< parameter has unit of mass * distance /time + VELOCITY, //!< parameter has unit of distance / time, i.e. the effect is mass independent: a velocity change. + }; +}; + + +/** +Stress Solver. + +Uses NvBlastFamily, allocates and prepares its graph once when it's created. Then it's being quickly updated on every +actor split. +It uses NvBlastAsset support graph, you can apply forces on nodes and stress on bonds will be calculated as the result. +When stress on bond exceeds it's health bond is considered broken (overstressed). +Basic usage: +1. Create it with create function once for family +2. Fill node info for every node in support graph or use setAllNodesInfoFromLL() function. +3. Use notifyActorCreated / notifyActorDestroyed whenever actors are created and destroyed in family. +4. Every frame: Apply forces (there are different functions for it see @addForce) +5. Every frame: Call update() for actual solver to process. +6. If getOverstressedBondCount() > 0 use generateFractureCommands() functions to get FractureCommands with bonds fractured +*/ +class NV_DLL_EXPORT ExtStressSolver +{ +public: + //////// creation //////// + + /** + Create a new ExtStressSolver. + + \param[in] family The ExtPxFamily instance to calculate stress on. + \param[in] settings The settings to be set on ExtStressSolver. + + \return the new ExtStressSolver if successful, NULL otherwise. + */ + static ExtStressSolver* create(NvBlastFamily& family, ExtStressSolverSettings settings = ExtStressSolverSettings()); + + + //////// interface //////// + + /** + Release this stress solver. + */ + virtual void release() = 0; + + /** + Set node info. + + All the required info per node for stress solver is set with this function. Call it for every node in graph or use setAllNodesInfoFromLL(). + + \param[in] graphNodeIndex Index of the node in support graph. see NvBlastSupportGraph. + \param[in] mass Node mass. For static node it is irrelevant. + \param[in] volume Node volume. For static node it is irrelevant. + \param[in] localPosition Node local position. + \param[in] isStatic Is node static. + */ + virtual void setNodeInfo(uint32_t graphNodeIndex, float mass, float volume, physx::PxVec3 localPosition, bool isStatic) = 0; + + /** + Set all nodes info using low level NvBlastAsset data. + Uses NvBlastChunk's centroid and volume. + Uses 'world' node to mark nodes as static. + + \param[in] density Density. Used to convert volume to mass. + */ + virtual void setAllNodesInfoFromLL(float density = 1.0f) = 0; + + /** + Set stress solver settings. + Changing graph reduction level will lead to graph being rebuilt (which is fast, but still not recommended). + All other settings are applied instantly and can be changed every frame. + + \param[in] settings The settings to be set on ExtStressSolver. + */ + virtual void setSettings(const ExtStressSolverSettings& settings) = 0; + + /** + Get stress solver settings. + + \return the pointer to stress solver settings currently set. + */ + virtual const ExtStressSolverSettings& getSettings() const = 0; + + /** + Notify stress solver on newly created actor. + + Call this function for all initial actors present in family and later upon every actor split. + + \param[in] actor The actor created. + + \return true if actor will take part in stress solver process. false if actor doesn't contain any bonds. + */ + virtual bool notifyActorCreated(const NvBlastActor& actor) = 0; + + /** + Notify stress solver on destroyed actor. + + Call this function when actor is destroyed (split futher) or deactivated. + + \param[in] actor The actor destroyed. + */ + virtual void notifyActorDestroyed(const NvBlastActor& actor) = 0; + + /** + Apply external impulse on particular actor of family. This function will find nearest actor's graph node to apply impulse on. + + \param[in] actor The actor to apply impulse on. + \param[in] localPosition Local position in actor's coordinates to apply impulse on. + \param[in] localForce Force to apply in local actor's coordinates. + \param[in] mode The mode to use when applying the force/impulse(see #ExtForceMode) + + \return true iff node was found and force applied. + */ + virtual bool addForce(const NvBlastActor& actor, physx::PxVec3 localPosition, physx::PxVec3 localForce, ExtForceMode::Enum mode = ExtForceMode::IMPULSE) = 0; + + /** + Apply external impulse on particular node. + + \param[in] graphNodeIndex The graph node index to apply impulse on. See #NvBlastSupportGraph. + \param[in] localForce Force to apply in local actor's coordinates. + \param[in] mode The mode to use when applying the force/impulse(see #ExtForceMode) + */ + virtual void addForce(uint32_t graphNodeIndex, physx::PxVec3 localForce, ExtForceMode::Enum mode = ExtForceMode::IMPULSE) = 0; + + /** + Apply external gravity on particular actor of family. This function applies gravity on every node withing actor, so it makes sense only for static actors. + + \param[in] actor The actor to apply impulse on. + \param[in] localGravity Gravity to apply in local actor's coordinates. ExtForceMode::VELOCITY is used. + + \return true iff force was applied on at least one node. + */ + virtual bool addGravityForce(const NvBlastActor& actor, physx::PxVec3 localGravity) = 0; + + /** + Apply centrifugal force produced by actor's angular movement. + + \param[in] actor The actor to apply impulse on. + \param[in] localCenterMass Actor's local center of mass. + \param[in] localAngularVelocity Local angular velocity of an actor. + + \return true iff force was applied on at least one node. + */ + virtual bool addAngularVelocity(const NvBlastActor& actor, physx::PxVec3 localCenterMass, physx::PxVec3 localAngularVelocity) = 0; + + /** + Update stress solver. + + Actual performance heavy stress calculation happens there. Call it after all relevant forces were applied, usually every frame. + */ + virtual void update() = 0; + + /** + Get overstressed/broken bonds count. + + This count is updated after every update() call. Number of overstressed bond directly hints if any bond fracture is recommended by stress solver. + + \return the overstressed bonds count. + */ + virtual uint32_t getOverstressedBondCount() const = 0; + + /** + Generate fracture commands for particular actor. + + Calling this function if getOverstressedBondCount() == 0 or actor has no bond doesn't make sense, bondFractureCount will be '0'. + Filled fracture commands buffer can be passed directly to NvBlastActorApplyFracture. + + IMPORTANT: NvBlastFractureBuffers::bondFractures will point to internal stress solver memory which will be valid till next call + of any of generateFractureCommands() functions or stress solver release() call. + + \param[in] actor The actor to fill fracture commands for. + \param[in] commands Pointer to command buffer to fill. + */ + virtual void generateFractureCommands(const NvBlastActor& actor, NvBlastFractureBuffers& commands) = 0; + + /** + Generate fracture commands for whole family. A bit faster way to get all fractured bonds then calling generateFractureCommands() for every actor. + + Calling this function if getOverstressedBondCount() == 0 or actor has no bond doesn't make sense, bondFractureCount will be '0'. + + IMPORTANT: NvBlastFractureBuffers::bondFractures will point to internal stress solver memory which will be valid till next call + of any of generateFractureCommands() functions or stress solver release() call. + + \param[in] commands Pointer to command buffer to fill. + */ + virtual void generateFractureCommands(NvBlastFractureBuffers& commands) = 0; + + /** + Generate fracture commands for every actor in family. + + Actors and commands buffer must be passed in order to be filled. It's recommended for bufferSize to be the count of actor with more then one bond in family. + + Calling this function if getOverstressedBondCount() == 0 or actor has no bond doesn't make sense, '0' will be returned. + + IMPORTANT: NvBlastFractureBuffers::bondFractures will point to internal stress solver memory which will be valid till next call + of any of generateFractureCommands() functions or stress solver release() call. + + \param[out] buffer A user-supplied array of NvBlastActor pointers to fill. + \param[out] commandsBuffer A user-supplied array of NvBlastFractureBuffers to fill. + \param[in] bufferSize The number of elements available to write into buffer. + + \return the number of actors and command buffers written to the buffer. + */ + virtual uint32_t generateFractureCommandsPerActor(const NvBlastActor** actorBuffer, NvBlastFractureBuffers* commandsBuffer, uint32_t bufferSize) = 0; + + /** + Reset stress solver. + + Stress solver uses warm start internally, calling this function will flush all previous data calculated and also zeros frame count. + This function is to be used for debug purposes. + */ + virtual void reset() = 0; + + /** + Get stress solver linear error. + + \return the total linear error of stress calculation. + */ + virtual float getStressErrorLinear() const = 0; + + /** + Get stress solver angular error. + + \return the total angular error of stress calculation. + */ + virtual float getStressErrorAngular() const = 0; + + /** + Get stress solver total frames count (update() calls) since it was created (or reset). + + \return the frames count. + */ + virtual uint32_t getFrameCount() const = 0; + + /** + Get stress solver bonds count, after graph reduction was applied. + + \return the bonds count. + */ + virtual uint32_t getBondCount() const = 0; + + + /** + Debug Render Mode + */ + enum DebugRenderMode + { + STRESS_GRAPH = 0, //!< render only stress graph + STRESS_GRAPH_NODES_IMPULSES = 1, //!< render stress graph + nodes impulses after solving stress + STRESS_GRAPH_BONDS_IMPULSES = 2 //!< render stress graph + bonds impulses after solving stress + }; + + /** + Used to store a single line and colour for debug rendering. + */ + struct DebugLine + { + DebugLine(const physx::PxVec3& p0, const physx::PxVec3& p1, const uint32_t& c) + : pos0(p0), color0(c), pos1(p1), color1(c) {} + + physx::PxVec3 pos0; + uint32_t color0; + physx::PxVec3 pos1; + uint32_t color1; + }; + + /** + Debug Buffer + */ + struct DebugBuffer + { + const DebugLine* lines; + uint32_t lineCount; + }; + + /** + Fill debug render for passed array of support graph nodes. + + NOTE: Returned DebugBuffer points into internal memory which is valid till next fillDebugRender() call. + + \param[in] nodes Node indices of support graph to debug render for. + \param[in] nodeCount Node indices count. + \param[in] mode Debug render mode. + \param[in] scale Scale to be applied on impulses. + + \return debug buffer with array of lines + */ + virtual const DebugBuffer fillDebugRender(const uint32_t* nodes, uint32_t nodeCount, DebugRenderMode mode, float scale = 1.0f) = 0; + + + //////// helpers //////// + + /** + Get solver iteration per frame (update() call) for particular settings and bondCount. + + Helper method to know how many solver iterations are made per frame. + This function made so transparent to make it clear how ExtStressSolverSettings::bondIterationsPerFrame is used. + + \param[in] settings Debug render mode. + \param[in] bondCount Scale to be applied on impulses. + + \return the iterations per frame count. + */ + static uint32_t getIterationsPerFrame(const ExtStressSolverSettings& settings, uint32_t bondCount) + { + uint32_t perFrame = settings.bondIterationsPerFrame / (bondCount + 1); + return perFrame > 0 ? perFrame : 1; + } + + /** + Get iteration per frame (update() call). + + Helper method to know how many solver iterations are made per frame. + + \return the iterations per frame count. + */ + uint32_t getIterationsPerFrame() const + { + return getIterationsPerFrame(getSettings(), getBondCount()); + } + +}; + +} // namespace Blast +} // namespace Nv + + +#endif // ifndef NVBLASTEXTSTRESSSOLVER_H |