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 /docs/_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 'docs/_source')
24 files changed, 2889 insertions, 2874 deletions
diff --git a/docs/_source/apex_importer.txt b/docs/_source/apex_importer.txt index f80eb57..fca0b67 100644..100755 --- a/docs/_source/apex_importer.txt +++ b/docs/_source/apex_importer.txt @@ -1,93 +1,93 @@ -/*! \page pageimporter ApexImporter - -ApexImporter is a tool for converting destructible assets from APEX Destruction format to Blast&tm; asset format. Whereas APEX Destruction only needs a -list of connected chunks, Blast&tm; has a Bond structure to describe chunk connections. Each Bond describes the interface between two chunks, and needs -the area, centroid, and average normal of this interface. ApexImporter computes this data automatically. Interface search can be done in several ways: -- <b>Exact mode</b>: Importer tries to find triangles from two chunks which lay in common surface. If such triangles are found, their intersections are considered as the interface. Such an interface may not exist. -- <b>Forced mode</b>: This mode is based on search for midplane between two chunks and intersecting them with offsetted midplane to find interface parameters. Creates bonds even if chunks have no common surface. - - -A bond is not created if the area of interface is zero. The interface centroid is computed as center of mass of all interface polygon points. The interface normal is computed as an average of normals of all planes comprising the interface surface. - -Note - for Blast&tm; to operate with satisfactory fracturing behavior, it does not require exact area, centroid, and normal values for Bonds. - -Along with creating a Blast&tm; asset (*.blast), ApexImporter creates an *.obj or *.fbx file with description of chunk render geometry. Optionally the *.fbx file can store the collision geometry. - -Blast&tm; asset data can be saved in different ways: - -1) LL-asset which is Low Level asset data (NvBlastAsset with --ll). - -2) Tk-asset which is Toolkit asset data (Nv::Blast::TkAsset with --tk). - -3) ExtPx-asset which incorporates Blast&tm; data and collision geometry for physics engine (Nv::Blast::ExtPxAsset with --px). Default mode. - -ExtPxAsset assets or *.fbx files that contain collision geometry and can be used in \ref pagesampleassetviewer. - -\verbatim -USAGE: - - ApexImporter [--nonskinned] [--fbxcollision] [--fbx] [--obj] - [--fbxascii] [--ll] [--tk] [--px] [-d] [-m <0 - - EXACT, 1 - FORCED, for detailed description see - docs.>] -n <output asset name> [-o <output - directory>] -f <infile> [--] [--version] [-h] - - -Where: - - --nonskinned - Output a non-skinned FBX file - - --fbxcollision - Append collision geometry to FBX file - - --fbx - Output a FBX mesh to the output directory - - --obj - Output a OBJ mesh to the output directory - - --fbxascii - Output FBX as an ascii file (defaults to binary output) - - --ll - Output LL Blast asset to the output directory - - --tk - Output TkAsset to the output directory - - --px - Output ExtPxAsset to the output directory - - -d, --debug - Print debug output - - -m <0 - EXACT, 1 - FORCED, for detailed description see docs.>, --mode - <0 - EXACT, 1 - FORCED, for detailed description see docs.> - Interface search mode - - -n <output asset name>, --outAssetName <output asset name> - (required) Output asset name - - -o <output directory>, --outputDir <output directory> - Output directory - - -f <infile>, --file <infile> - (required) File to load - - --, --ignore_rest - Ignores the rest of the labeled arguments following this flag. - - --version - Displays version information and exits. - - -h, --help - Displays usage information and exits. - -\endverbatim - -<br> -See \ref pagecopyrights for license information regarding third-party software used by ApexImporter. - -<br> -*/ +/*! \page pageimporter ApexImporter
+
+ApexImporter is a tool for converting destructible assets from APEX Destruction format to Blast&tm; asset format. Whereas APEX Destruction only needs a
+list of connected chunks, Blast&tm; has a Bond structure to describe chunk connections. Each Bond describes the interface between two chunks, and needs
+the area, centroid, and average normal of this interface. ApexImporter computes this data automatically. Interface search can be done in several ways:
+- <b>Exact mode</b>: Importer tries to find triangles from two chunks which lay in common surface. If such triangles are found, their intersections are considered as the interface. Such an interface may not exist.
+- <b>Forced mode</b>: This mode is based on search for midplane between two chunks and intersecting them with offsetted midplane to find interface parameters. Creates bonds even if chunks have no common surface.
+
+
+A bond is not created if the area of interface is zero. The interface centroid is computed as center of mass of all interface polygon points. The interface normal is computed as an average of normals of all planes comprising the interface surface.
+
+Note - for Blast&tm; to operate with satisfactory fracturing behavior, it does not require exact area, centroid, and normal values for Bonds.
+
+Along with creating a Blast&tm; asset (*.blast), ApexImporter creates an *.obj or *.fbx file with description of chunk render geometry. Optionally the *.fbx file can store the collision geometry.
+
+Blast&tm; asset data can be saved in different ways:
+
+1) LL-asset which is Low Level asset data (NvBlastAsset with --ll).
+
+2) Tk-asset which is Toolkit asset data (Nv::Blast::TkAsset with --tk).
+
+3) ExtPx-asset which incorporates Blast&tm; data and collision geometry for physics engine (Nv::Blast::ExtPxAsset with --px). Default mode.
+
+ExtPxAsset assets or *.fbx files that contain collision geometry and can be used in \ref pagesampleassetviewer.
+
+\verbatim
+USAGE:
+
+ ApexImporter [--nonskinned] [--fbxcollision] [--fbx] [--obj]
+ [--fbxascii] [--ll] [--tk] [--px] [-d] [-m <0 -
+ EXACT, 1 - FORCED, for detailed description see
+ docs.>] -n <output asset name> [-o <output
+ directory>] -f <infile> [--] [--version] [-h]
+
+
+Where:
+
+ --nonskinned
+ Output a non-skinned FBX file
+
+ --fbxcollision
+ Append collision geometry to FBX file
+
+ --fbx
+ Output a FBX mesh to the output directory
+
+ --obj
+ Output a OBJ mesh to the output directory
+
+ --fbxascii
+ Output FBX as an ascii file (defaults to binary output)
+
+ --ll
+ Output LL Blast asset to the output directory
+
+ --tk
+ Output TkAsset to the output directory
+
+ --px
+ Output ExtPxAsset to the output directory
+
+ -d, --debug
+ Print debug output
+
+ -m <0 - EXACT, 1 - FORCED, for detailed description see docs.>, --mode
+ <0 - EXACT, 1 - FORCED, for detailed description see docs.>
+ Interface search mode
+
+ -n <output asset name>, --outAssetName <output asset name>
+ (required) Output asset name
+
+ -o <output directory>, --outputDir <output directory>
+ Output directory
+
+ -f <infile>, --file <infile>
+ (required) File to load
+
+ --, --ignore_rest
+ Ignores the rest of the labeled arguments following this flag.
+
+ --version
+ Displays version information and exits.
+
+ -h, --help
+ Displays usage information and exits.
+
+\endverbatim
+
+<br>
+See \ref pagecopyrights for license information regarding third-party software used by ApexImporter.
+
+<br>
+*/
diff --git a/docs/_source/api_ext_users_guide.txt b/docs/_source/api_ext_users_guide.txt index e255e82..1aeaf18 100644..100755 --- a/docs/_source/api_ext_users_guide.txt +++ b/docs/_source/api_ext_users_guide.txt @@ -1,43 +1,43 @@ -/*! \page pageextapi Extensions (NvBlastExt) - -These are the current Blast&tm; extensions: -<br> -<br> -\subpage pageextshaders - Standard damage shaders (radial, shear, line segment) which can be used in NvBlast and NvBlastTk damage functions. -<br> -<br> -\subpage pageextstress - A toolkit for performing stress calculations on low-level Blast&tm; actors, using a minimal API to assign masses and apply forces. Does not use any external physics library. -<br> -<br> -\subpage pageextassetutils - NvBlastAsset utility functions. Add world bonds, merge assets, and transform geometric data. -<br> -<br> -\subpage pageextauthoring - Powerful tools for cleaning and fracturing meshes using voronoi, clustered voronoi, and slicing methods. -<br> -<br> -\subpage pageextimport - Functions to import data from external formats and convert to a Blast&tm; asset. Currently handles APEX NvDestructibleAsset data. -<br> -<br> -\subpage pageextexporter - Standard mesh and collision writer tools in fbx, obj, and json formats. -<br> -<br> -\subpage pageextserialization - Blast&tm; object serialization manager. With the ExtTkSerialization and ExtPxSerialization extensions, can serialize assets for low-level, Tk, and ExtPhysX libraries -using a variety of encodings. This extension comes with low-level serializers built-in. -<br> -<br> -\subpage pageexttkserialization - This module contains serializers for NvBlastTk objects. Use in conjunction with ExtSerialization. -<br> -<br> -\subpage pageextpxserialization - This module contains serializers for ExtPhysX objects. Use in conjunction with ExtSerialization. -<br> -<br> -\subpage pageextphysx - A reference implementation of a physics manager, using the PhysX&tm; SDK. Creates and manages actors and joints, and handles impact damage and uses the stress solver (ExtStress) to -handle stress calculations. -<br> -<br> -To use them, include the appropriate headers in include/extensions (each extension will describe which headers are necessary), -and link to the desired NvBlastExt*{config}{arch} library in the lib folder. Here, config is the usual DEBUG/CHECKED/PROFILE (or nothing for release), -and {arch} distinguishes achitecture, if needed (such as _x86 or _x64). -<br> -<br> -*/ +/*! \page pageextapi Extensions (NvBlastExt)
+
+These are the current Blast&tm; extensions:
+<br>
+<br>
+\subpage pageextshaders - Standard damage shaders (radial, shear, line segment) which can be used in NvBlast and NvBlastTk damage functions.
+<br>
+<br>
+\subpage pageextstress - A toolkit for performing stress calculations on low-level Blast&tm; actors, using a minimal API to assign masses and apply forces. Does not use any external physics library.
+<br>
+<br>
+\subpage pageextassetutils - NvBlastAsset utility functions. Add world bonds, merge assets, and transform geometric data.
+<br>
+<br>
+\subpage pageextauthoring - Powerful tools for cleaning and fracturing meshes using voronoi, clustered voronoi, and slicing methods.
+<br>
+<br>
+\subpage pageextimport - Functions to import data from external formats and convert to a Blast&tm; asset. Currently handles APEX NvDestructibleAsset data.
+<br>
+<br>
+\subpage pageextexporter - Standard mesh and collision writer tools in fbx, obj, and json formats.
+<br>
+<br>
+\subpage pageextserialization - Blast&tm; object serialization manager. With the ExtTkSerialization and ExtPxSerialization extensions, can serialize assets for low-level, Tk, and ExtPhysX libraries
+using a variety of encodings. This extension comes with low-level serializers built-in.
+<br>
+<br>
+\subpage pageexttkserialization - This module contains serializers for NvBlastTk objects. Use in conjunction with ExtSerialization.
+<br>
+<br>
+\subpage pageextpxserialization - This module contains serializers for ExtPhysX objects. Use in conjunction with ExtSerialization.
+<br>
+<br>
+\subpage pageextphysx - A reference implementation of a physics manager, using the PhysX&tm; SDK. Creates and manages actors and joints, and handles impact damage and uses the stress solver (ExtStress) to
+handle stress calculations.
+<br>
+<br>
+To use them, include the appropriate headers in include/extensions (each extension will describe which headers are necessary),
+and link to the desired NvBlastExt*{config}{arch} library in the lib folder. Here, config is the usual DEBUG/CHECKED/PROFILE (or nothing for release),
+and {arch} distinguishes achitecture, if needed (such as _x86 or _x64).
+<br>
+<br>
+*/
diff --git a/docs/_source/api_globals_users_guide.txt b/docs/_source/api_globals_users_guide.txt index 00b35ef..834c0a8 100644..100755 --- a/docs/_source/api_globals_users_guide.txt +++ b/docs/_source/api_globals_users_guide.txt @@ -1,100 +1,100 @@ -/*! \page pageglobalsapi Globals API (NvBlastGlobals) - -The NvBlastGlobals library is a utility library which is used by NvBlastTk (see \ref pagehlapi) and some extensions (see \ref pageextapi) and samples. - -It provides a global allocator, error callback, and profiler API. - -<br> -\section globalsallocator Allocator - -<b>Include NvBlastGlobals.h</b> -<br> - -A global allocator with interface - -\code -Nv::Blast::AllocatorCallback -\endcode - -may be set by the user with the function - -\code -NvBlastGlobalSetAllocatorCallback -\endcode - -and accessed using - -\code -NvBlastGlobalGetAllocatorCallback -\endcode - -An internal, default allocator is used if the user does not set their own, or if NULL is passed into NvBlastGlobalSetAllocatorCallback. - -This allocator is used by NvBlastTk, as well as any extension that allocates memory. In addition, utility macros are provided such as -<b>NVBLAST_ALLOC</b>, <b>NVBLAST_FREE</b>, <b>NVBLAST_NEW</b>, and <b>NVBLAST_DELETE</b>. - -<br> -\section globalserror Error Callback - -<b>Include NvBlastGlobals.h</b> - -A global error message callback with interface - -\code -Nv::Blast::ErrorCallback -\endcode - -may be set by the user with the function - -\code -NvBlastGlobalSetErrorCallback -\endcode - -and accessed using - -\code -NvBlastGlobalGetErrorCallback -\endcode - -An internal, default error callback is used if the user does not set their own, or if NULL is passed into NvBlastGlobalSetErrorCallback. - -This error callback is used by NvBlastTk, as well as many extensions. In addition, utility macros are provided such as -<b>NVBLAST_LOG_ERROR</b> and <b>NVBLAST_LOG_WARNING</b>. - -Finally, a function with signature given by NvBlastLog is provided which uses the global error callback, - -\code -Nv::Blast::logLL -\endcode - -This function may be passed into any NvBlast&tm; function's log parameter. - -<br> -\section globalsprofiler Profiler API - -<b>Include NvBlastProfiler.h</b> -<br> - -BlastTk contains many profiling zones which use the global profiler which can be accessed in this library. The user may implement -the interface - -\code -Nv::Blast::ProfilerCallback -\endcode - -and pass it to the globals library using - -\code -NvBlastProfilerSetCallback -\endcode - -A NULL pointer may be passed in, disabling profiling. Profiler features are only active in checked, debug and profile builds. - -The granularity of events reported can be selected with - -\code -NvBlastProfilerSetDetail -\endcode - -<br> -*/ +/*! \page pageglobalsapi Globals API (NvBlastGlobals)
+
+The NvBlastGlobals library is a utility library which is used by NvBlastTk (see \ref pagehlapi) and some extensions (see \ref pageextapi) and samples.
+
+It provides a global allocator, error callback, and profiler API.
+
+<br>
+\section globalsallocator Allocator
+
+<b>Include NvBlastGlobals.h</b>
+<br>
+
+A global allocator with interface
+
+\code
+Nv::Blast::AllocatorCallback
+\endcode
+
+may be set by the user with the function
+
+\code
+NvBlastGlobalSetAllocatorCallback
+\endcode
+
+and accessed using
+
+\code
+NvBlastGlobalGetAllocatorCallback
+\endcode
+
+An internal, default allocator is used if the user does not set their own, or if NULL is passed into NvBlastGlobalSetAllocatorCallback.
+
+This allocator is used by NvBlastTk, as well as any extension that allocates memory. In addition, utility macros are provided such as
+<b>NVBLAST_ALLOC</b>, <b>NVBLAST_FREE</b>, <b>NVBLAST_NEW</b>, and <b>NVBLAST_DELETE</b>.
+
+<br>
+\section globalserror Error Callback
+
+<b>Include NvBlastGlobals.h</b>
+
+A global error message callback with interface
+
+\code
+Nv::Blast::ErrorCallback
+\endcode
+
+may be set by the user with the function
+
+\code
+NvBlastGlobalSetErrorCallback
+\endcode
+
+and accessed using
+
+\code
+NvBlastGlobalGetErrorCallback
+\endcode
+
+An internal, default error callback is used if the user does not set their own, or if NULL is passed into NvBlastGlobalSetErrorCallback.
+
+This error callback is used by NvBlastTk, as well as many extensions. In addition, utility macros are provided such as
+<b>NVBLAST_LOG_ERROR</b> and <b>NVBLAST_LOG_WARNING</b>.
+
+Finally, a function with signature given by NvBlastLog is provided which uses the global error callback,
+
+\code
+Nv::Blast::logLL
+\endcode
+
+This function may be passed into any NvBlast&tm; function's log parameter.
+
+<br>
+\section globalsprofiler Profiler API
+
+<b>Include NvBlastProfiler.h</b>
+<br>
+
+BlastTk contains many profiling zones which use the global profiler which can be accessed in this library. The user may implement
+the interface
+
+\code
+Nv::Blast::ProfilerCallback
+\endcode
+
+and pass it to the globals library using
+
+\code
+NvBlastProfilerSetCallback
+\endcode
+
+A NULL pointer may be passed in, disabling profiling. Profiler features are only active in checked, debug and profile builds.
+
+The granularity of events reported can be selected with
+
+\code
+NvBlastProfilerSetDetail
+\endcode
+
+<br>
+*/
diff --git a/docs/_source/api_hl_users_guide.txt b/docs/_source/api_hl_users_guide.txt index ae8dd4a..34d843e 100644..100755 --- a/docs/_source/api_hl_users_guide.txt +++ b/docs/_source/api_hl_users_guide.txt @@ -1,705 +1,705 @@ -/*! \page pagehlapi High Level (Toolkit) API (NvBlastTk) - -<b>Table of Contents</b> - -\subpage tkintroduction - -\subpage tk_class_hierarchy - -\subpage tk_include_and_library - -\subpage framework_init - -\subpage tkasset_creation - -\subpage tkasset_instancing - -\subpage tkgroups - -\subpage damage_in_tk - -\subpage tkjoints - -\subpage tkevents - -\subpage tktypes - -<br> -\section tkintroduction Introduction to NvBlastTk - -The high-level API, NvBlastTk (Tk stands for "toolkit"), is intended to be a more powerful library and a much more convenient entry point -into the use of Blast&tm;. Like the low-level library, Tk is physics and graphics-agnostic. Whereas the low-level API is C-style, Tk uses -a C++ API. Everything in Tk is in the namespace: - -\code -Nv::Blast -\endcode - -(the only exceptions are global-scope functions to create and access a framework singleton, see below). -Every object in Tk is prefixed with 'Tk'. For example, the Tk framework interface is: - -\code -Nv::Blast::TkFramework -\endcode - -<b> -For the remainder of this page we will be in the Nv::Blast namespace, and will drop the explicit scope Nv::Blast:: from our names. -</b> -<br> -<br> - - -BlastTk adds: - -- An object class hierarchy (see \ref tk_class_hierarchy, below). -- A global framework, <b>TkFramework</b> (a singleton). This keeps track of <b>TkIdentifiable</b> objects and allows -the user to query them based upon either GUID or <b>TkIdentifiable</b> subclass type, and also provides a number of functions to create the various objects in BlastTk. -- Processing groups with a task interface (see <b>TkGroup</b>). -- Event dispatching for actor families (see <b>TkFamily</b>). -- Intra-actor and inter-actor joint management (see <b>TkJoint</b>). Note, these "joints" only hold descriptor data, since physical objects are not handled by BlastTk. - -<br> -\section tk_class_hierarchy NvBlastTk Class Hierarchy - -- There are two abstract interfaces, one of which deriving from the other: <b>TkObject <- TkIdentifiable</b>. - - Lightweight objects are derived from <b>TkObject</b>. - - Objects which use a GUID and class identification are derieved from <b>TkIdentifiable</b>. -- <b>TkAsset</b> derives from <b>TkIdentifiable</b>. This is mostly a wrapper for NvBlastAsset, however it also stores -extra data associated with the asset such as internal joint descriptors. -- <b>TkFamily</b> derives from <b>TkIdentifiable</b>. One of these objects is made when a <b>TkActor</b> is instanced -from a <b>TkAsset</b>. All actors that are created by splitting the family's original actor remain within the same family. Actor and joint -events are dispatched from the <b>TkFamily</b>. -- <b>TkGroup</b> derives from <b>TkIdentifiable</b>. Groups are processing units. The user may create as many groups as they please, and add -or remove actors as they please from groups. The group provides a worker (TkGroupWorker) interface which allows the user to process multiple -jobs in the group asynchoronously. These jobs, along with a call to TkGroup::endProcess(), perform the tasks of generating fracture commands, -applying fracture commands, and actor splitting at the low-level. The user is informed of splitting through listeners given to TkFamily objects. -- <b>TkActor</b> derives from <b>TkObject</b>. It is mostly a wrapper for NvBlastActor, but it also provides a number of damage functions -to the user. -- <b>TkJoint</b> derives from <b>TkObject</b>. <b>TkAsset</b> descriptors, cause internal <b>TkJoint</b> obejcts to be created within an actor -(joining chunks within the same actor). Alternatively, the TkFramework provides a function which allows the user to create an external joint -between any two different actors. As actors split, internal joints may become external. The user gets notification whenever joints become -external, or when actors joined by joints change or are deleted, through listeners attached to the associated TkFamily objects. - -<br> -\section tk_include_and_library Linking and Header Files - -To use the BlastTk library, the application need only inlclude the header NvBlastTk.h, found in the <b>include/toolkit</b> folder, and link -against the appropriate version of the NvBlastTk library. Depending on the platform and configuration, various suffixes will be added to the library -name. The general naming scheme is - -NvBlastTk(config)(arch).(ext) - -(config) is DEBUG, CHECKED, OR PROFILE for the corresponding configurations. For a release configuration there is no (config) suffix. - -(arch) is _x86 or _x64 for Windows 32- and 64-bit builds, respectively, and empty for non-Windows platforms. - -(ext) is .lib for static linking and .dll for dynamic linking on Windows. On XBoxOne it is .lib, and on PS4 it is .a. - - -<br> -\section framework_init Creating the TkFramework - -As a reminder, in this document we assume we are in the Nv::Blast namespace: - -\code -using namespace Nv::Blast; -\endcode - -In order to use NvBlastTk, one first has to create a TkFramework singleton. This simply requires a call -to the global function NvBlastTkFrameworkCreate: - -\code -TkFramework* framework = NvBlastTkFrameworkCreate(); -\endcode - -The framework may be accessed via: - -\code -TkFramework* framework = NvBlastTkFrameworkGet(); -\endcode - -In the sections that follow, it is assumed that a framework has been created, and we have a pointer to it named 'framework' within scope. - -Finally, to release the framework, use - -\code -framework->release(); -\endcode - -This will release all assets, families, actors, joints, and groups. - -<br> -\section tkasset_creation Creating a TkAsset - -The TkAsset object is a high-level wrapper for the low-level NvBlastAsset (see \ref assets). The descriptor used to create a TkAsset, a TkAssetDesc, is derived from -NvBlastAssetDesc. The base fields should be filled in as described in (\ref assets). The new field is an optional array of flags to be associated with each bond in -the base descriptor. Currently the only flag is "BondJointed," and if set will cause an "internal joint" to be created in actors (TkActor type) created from the asset. -See (\ref tkjoints) for more on joints in BlastTk. - -\code -TkAssetDesc desc; - -myFunctionToFillInLowLevelAssetFields(desc); // Fill in the low-level (NvBlastAssetDesc) fields as usual - -std::vector<uint8_t*> bondFlags(desc.bondCount, 0); // Clear all flags - -// Set BondJointed flags corresponding to joints selected by the user (assumes a myBondIsJointedFunction to make this selection) -for (uint32_t i = 0; i < desc.bondCount; ++i) -{ - if (myBondIsJointedFunction(i)) // User-authored - { - bondFlags[i] |= TkAssetDesc::BondJointed; - } -} - -TkAsset* asset = framework->createAsset(desc); // Create a new TkAsset -\endcode - -The createAsset function used above creates a low-level NvBlastAsset from the base fields of the descriptor, and then adds internal joint descriptors based -upon the bonds' centroids and attached chunks. An alternative method to create a TkAsset allows the user to pass in a pre-existing NvBlastAsset, and a list -of joint descriptors. If the TkAsset is to have no internal joints, then the joint descriptors are not necessary and with an NvBlastAsset -pointer <b>llAsset</b>, a TkAsset may be created simply by using - -\code -TkAsset* asset = framework->createAsset(llAsset); -\endcode - -By default, such a TkAsset will not "own" the llAsset. When the TkAsset is released, the llAsset memory will be untouched. You can pass ownership to the -TkAsset using all of the default parameters of the createAsset function: - -\code -TkAsset* asset = framework->createAsset(llAsset, nullptr, 0, true); -\endcode - -The last parameter sets ownership. N.B.: in order for the TkAsset to own the underlying llAsset, and therefore release it when the TkAsset is released, -the memory for the llAsset must be allocated using the allocator accessed through NvBlastGlobals (see \ref pageglobalsapi). - -If one wants to author internal joints in a TkAsset using this second createAsset method, one must pass in a valid array of joint descriptors of type -TkAssetJointDesc. Each joint descriptor takes two positions and two node indices. The positions are the joint's attachment positions in asset space, and -the nodes indices are those of the graph nodes that correspond to support chunks. These indices are not, in general, the same as the chunk indices. -An example of initialization of the joint descriptors is given below. - -\code -std::vector<TkAssetJointDesc> jointDescs(jointCount); // Assume jointCount = the number of joints to add -jointDescs[0].nodeIndices[0] = 0; // Attach node 0 to node 1 -jointDescs[0].nodeIndices[1] = 1; -jointDescs[0].attachPoistions[0] = physx::PxVec3( 1.0f, 2.0f, 3.0f ); // Attachment positions are often the same within an asset, but they don't have to be -jointDescs[0].attachPoistions[1] = physx::PxVec3( 1.0f, 2.0f, 3.0f ); -// ... etc. - -TkAsset* asset = framework->createAsset(llAsset, jointDescs.data(), jointDescs.size()); -\endcode - -The code above assumes you know the support graph nodes to which you'd like to attach joints. Often, the user only knows the corresponding chunk indices. -Fortunately it's easy to map chunk indices to graph node indices. In order to get the map, use the low-level function - -\code -const uint32_t map = NvBlastAssetGetChunkToGraphNodeMap(llAsset, logFn); -\endcode - -This map is an array with an entry for every chunk index. To get the graph node index for a chunk indexed <b>chunkIndex</b>, use - -\code -uint32_t nodeIndex = map[chunkIndex]; -\endcode - -If the chunk indexed by <b>chunkIndex</b> does <em>not</em> correspond to a support chunk, then the mapped value will be UINT32_MAX, the invalid index. -Otherwise, the mapped value will be a valid graph node index. - -Finally, to release a TkAsset, as with any TkObject-derived object, use the release() method: - -\code -asset->release(); -\endcode - -<br> -\section tkasset_instancing Instancing a TkAsset: Creation of a TkActor and a TkFamily - -Whereas with the Blast&tm; low-level (\ref pagellapi), one must explicitly create a family (NvBlastFamily) from an asset (NvBlastAsset) before creating -the first actor (NvBlastActor) in the family, NvBlastTk creates a TkFamily automatically when an unfractured TkActor is instanced from a TkAsset using -the framework's createActor function. This family is accessible through the actor and any actor that is created from splitting it. The family is -<em>not</em> released automatically when all actors within it have been released. The user must use the TkFamily's release() method (see TkObject base -API) to do so. (Or wait until the framework is released.) If a family is released that contains actors, the actors within will be released as well. - -The TkFamily has a special role in NvBlastTk, holding user-supplied event listeners (\ref TkEventListener). All <em>internal</em> actor creation and destruction -events are broadcast to listeners through split events (TkSplitEvent). These signal when a fracturing operation has destroyed an actor and created -child actors from it. TkActor creation or release that occurs from an explicit API call do not produce events. For example when creating a first unfractured -instance of an asset using createAsset, or when calling the release() method on a TkActor. TkJoint events are similarly broadcast to -receivers (TkJointEvent). These signal when the actors which are joined by the joints change, so that the user may update a corresponding physical joint. -They also signal when a joint no longer attaches actors and is therefore unreferenced. The user may invalidate or release the joint using the TkObject -release() method when this occurs (more on joint ownership in \ref tkjoints). - -To create an unfractured TkActor instance from a TkAsset, one first fills in a descriptor (\ref TkActorDesc) and passes it to the framework's createActor function. -As with the TkAssetDesc, the TkActorDesc is derived from its low-level counterpart, the NvBlastActorDesc. In addition the TkActorDesc holds a pointer to -the TkAsset being instanced. An example of TkActor creation is given below, given a TkAsset pointer <b>asset</b>. - -\code -TkActorDesc desc; // The TkActorDesc constructor sets sane default values for the base (NvBlastActorDesc) fields, giving uniform chunk and bond healths of 1.0. -desc.asset = asset; // This field of TkActorDesc must be set to a valid asset pointer. - -TkActor* actor = framework->createActor(desc); -\endcode - -The TkFamily created with the actor above may be accessed through the actor's getFamily field: - -\code -TkFamily& family = actor->getFamily(); -\endcode - -The returned value is a reference since a TkActor's family can never be NULL. Actors resulting from the split of a "parent" actor will always belong to the -parent's family. - -For most applications, the user will need to create a listener object to pass to every family created, in order to keep their physics and graphics representations -in sync with the splitting of the TkActor. For more on this, see \ref tkevents. - -<br> -\section tkgroups Groups - -One important feature of NvBlastTk is the ability to multitask damage processing. The mechanism by which the toolkit does this is the group object, TkGroup. -Groups are created at the request of the user; the user may create as many groups as he or she likes. Actors may be added or removed from groups in any way the -user wishes, with the only constraint being that a given actor may belong to no more than one group. A group is a processing object, much like a scene in a physics -simulation. Indeed, a natural pattern would be to associate one group per physics scene, and synchronize the group processing with scene simulation. Another -pattern would be to subdivide the world into neighborhoods, and associate each neighborhood with a group. A distributed game could take advantage of this structure -to similarly distribute computation. - -Group processing is performed by <em>workers</em>, which have a TkGroupWorker API exposed to the user. The number of workers may be set by the user, with the idea being -that this should correspond to the number of threads available for group processing. Processing starts with a call to TkGroup::startProcess(). This creates a number -of jobs which the user may assign to workers as they like, each worker potentially on its own thread. The jobs calculate the effects of all damage taken -by the group's actors. After all jobs have been run, the user must call TkGroup::endProcess(). This will result in all events being fired off to listeners associated -with families with actors in the group. - -A convenience function, TkGroup::process(), is provided which uses one worker to perform all jobs sequentially on the calling thread. This is useful shortcut to -get BlastTk up and running quickly. A multithreaded group processing implementation is given by Nv::Blast::ExtGroupTaskManager (in NvBlastExtPxTask.h). -This resides in \ref pageextphysx, because it uses physx::PxTask. - -Actors resulting from the split of a "parent" actor will be placed automatically into the group that the parent belonged to. This is similar to the assigment of -families from a split, except that unlike families, the user then has the option to move the new actors to other groups, or no group at all. - -Also similar to families, groups are not automatically released when the last actor is removed from it. Unlike families, when a group is released, the actors which -belong to the group are <em>not</em> released. They will, however, be removed from the group before the release is complete. - -A typical usage is outlined below. See \ref damage_in_tk for methods of applying damage to actors. - -\code -// Create actors from descriptors desc1, desc2, ... etc., and attach a listener to each new family created -TkActor* actor1 = framework->createActor(desc1); -actor1->getFamily().addListener(gMyReceiver); // gMyReceiver is a TkEventListener-derived object. More on events in a subsequent section. -TkActor* actor2 = framework->createActor(desc2); -actor2->getFamily().addListener(gMyReceiver); -TkActor* actor3 = framework->createActor(desc3); -actor3->getFamily().addListener(gMyReceiver); -// etc... - -// Let's create two groups. First, create a group descriptor. This may be used to create both groups. -TkGroupDesc groupDesc; -groupDesc.workerCount = 1; // this example processes groups on the calling thread only - -// Now create the groups -TkGroup* group1 = framework->createGroup(groupDesc); -TkGroup* group2 = framework->createGroup(groupDesc); - -// Add actor1 and actor2 to group1, and actor2 to group3... -group1->addActor(actor1); -group1->addActor(actor2); -group2->addActor(actor3); -// etc... - -// Now apply damage to all actors - *NOTE* damage is described in detail in the next section. -// For now we will just assume a "myDamageFunction" to apply the damage. -myDamageFunction(actor1); -myDamageFunction(actor2); -myDamageFunction(actor3); -// etc... - -// Calling the groups' process functions will (synchronously) run all jobs to process damage taken by the contained actors. -group1->process(); -group2->process(); - -// When the groups are no longer needed, they may be released with the usual release method. -group1->release(); -group2->release(); -\endcode - -<br> -<b>Multithreaded processing</b> - -When distributing the jobs as mentioned above, every job must be processed exactly once (over all user tasks). - -The number of jobs processed per worker can range from a single job (resulting in a user task per job) to all jobs (like Nv::Blast::TkGroup::process() does). - -At any point in time, no more than the set workerCount amount of workers may have been acquired. Return the worker at the end of each task. - -\code -Nv::Blast::TkGroupWorker* worker = group->acquireWorker(); -// process some jobs -group->returnWorker(worker); -\endcode - -<br> -\section damage_in_tk Applying Damage to Actors and Families - -Damage in NvBlastTk uses the same damage program scheme as the low-level SDK (see \ref splitting). One passes the program -(NvBlastDamageProgram), damage descriptor (program-dependent), and material (also program-dependent) to a TkActor::damage -function. Ultimately, the damage descriptor and material data are all parameters used by the damage program. The distinction -is that the damage descriptor should describe properties of the thing doing the damage, while the material should -describe properties of the actor (the thing being damaged). The interpretation of this data is entirely up to the program's -functions, however. - -For convenience, the user may set a default material in the actor's family. This assumes, of course, that the material parameters -for this default are compatible with the program being used to damage the family's actors. - -Examples of the three TkActor damage methods are given below. - -<br> -\subsection multiple_damage Multiple Damage Descriptors using NvBlastProgramParams - -<b>N.B. - with this method of damage, the lifetime of the NvBlastProgramParams <em>must</em> extend at -least until the TkGroup::endProcess call for the actor.</b> - -\code -NvBlastDamageProgram program = -{ - myGraphShaderFunction, // A function with the NvBlastGraphShaderFunction signature - mySubgraphShaderFunction // A function with the NvBlastSubgraphShaderFunction signature -}; - -// The example struct "RadialDamageDesc" is modeled after NvBlastExtRadialDamageDesc in the NvBlastExtShaders extension -RadialDamageDesc damageDescs[2]; - -damageDescs[0].compressive = 10.0f; -damageDescs[0].position[0] = 1.0f; -damageDescs[0].position[1] = 2.0f; -damageDescs[0].position[2] = 3.0f; -damageDescs[0].minRadius = 0.0f; -damageDescs[0].maxRadius = 1.0f; - -damageDescs[1].compressive = 100.0f; -damageDescs[1].position[0] = 3.0f; -damageDescs[1].position[1] = 4.0f; -damageDescs[1].position[2] = 5.0f; -damageDescs[1].minRadius = 0.0f; -damageDescs[1].maxRadius = 5.0f; - -// The example material "Material" is modeled after NvBlastExtMaterial in the NvBlastExtShaders extension -Material material; - -material.health = 10.0f; -material.minDamageThreshold = 0.1f; -material.maxDamageThreshold = 0.8f; - -// Set the damage params struct -NvBlastProgramParams params = { damageDescs, 2, &material }; - -// Apply damage -actor->damage(program, ¶ms); // params must be kept around until TkGroup::endProcess is called! -\endcode - -<br> -\subsection single_damage_desc_default_material Single Damage Descriptor with Default TkFamily Material - -This method of damage copies the damage descriptor into a buffer, so the user need <em>not</em> hold onto -a copy after the damage function call. Only one damage descriptor may be passed in at once. - -To use this method, the user must first set a default material in the actor's family. For example: - -\code -// The example material "Material" is modeled after NvBlastExtMaterial in the NvBlastExtShaders extension -Material material; - -material.health = 10.0f; -material.minDamageThreshold = 0.1f; -material.maxDamageThreshold = 0.8f; - -// Set the default material used by the material-less TkActor::damage call -actor->getFamily().setMaterial(&material); -\endcode - -<b>N.B. the lifetime of the material set <em>must</em> extend at least until the TkGroup::endProcess call for the actor.</b> - -Then to apply damage, use: - -\code -NvBlastDamageProgram program = -{ - myGraphShaderFunction, // A function with the NvBlastGraphShaderFunction signature - mySubgraphShaderFunction // A function with the NvBlastSubgraphShaderFunction signature -}; - -// The example struct "RadialDamageDesc" is modeled after NvBlastExtRadialDamageDesc in the NvBlastExtShaders extension -RadialDamageDesc damageDesc; - -damageDesc.compressive = 10.0f; -damageDesc.position[0] = 1.0f; -damageDesc.position[1] = 2.0f; -damageDesc.position[2] = 3.0f; -damageDesc.minRadius = 0.0f; -damageDesc.maxRadius = 1.0f; - -// Apply damage -actor->damage(program, &damageDesc, (uint32_t)sizeof(RadialDamageDesc)); -\endcode - -<br> -\subsection single_damage_desc_with_material Single Damage Descriptor with Specified Material - -This method is just like the one above, except that the user has the opportunity to override the material used during damage. - -<b>N.B. - the lifetime of the material passed in <em>must</em> extend at least until the TkGroup::endProcess call for the actor.</b> - -This call is just like the one above with an extra material parameter: - -\code -actor->damage(program, &damageDesc, (uint32_t)sizeof(RadialDamageDesc), &material); -\endcode - -<br> -\section tkjoints Joints - -Joints in NvBlastTk are abstract representations of physical joints. When joints become active, change the actors they join, -or become unreferenced (the actors they join disappear), the user will receive notification via a TkJointUpdateEvent -(see \ref tkevents). - -Joints may be defined as a part of a TkAsset, in which case they are consisdered "internal" joints. (See \ref tkasset_creation.) -Since the first instance of a TkAsset is a single TkActor, internal joints are defined between chunks within the same actor. -Therefore they are not active (there is no point in joining two locations in a single rigid body). Upon splitting into multiple -actors, however, an internal joint's chunks may now belong to two different TkActors. When this happens, the user will receive a -TkJointUpdateEvent of subtype TkJointUpdateEvent::External. The event contains a pointer to the TkJoint, and from that the user -has access to the information needed to create a physical joint between the rigid bodies that correspond to the joined TkActors. - -Joints may also be created externally at runtime, using the TkFramework::createJoint function. A joint created this way must -be between two different TkActors. Because of this, the joint is immediately considered active, and so no TkJointUpdateEvent -is generated from its creation. The user should create a physical joint to correspond to the joint returned by createJoint. -An externally created joint of this type has another distinguishing characteristic: it may join an actor to "the world," or -"Newtonial Reference Frame" (NRF). To do this, one TkFamily pointer in the joint descriptor is set to NULL. Examples are -given below. - -\code -TkJointDesc desc; -desc.families[0] = &actor0->getFamily(); // Assume we have a valid actor0 pointer -desc.chunkIndices[0] = 1; // This chunk *must* be a support chunk in the asset that created desc.families[0] -desc.attachPositions[0] = physx::PxVec3(1.0f, 2.0f; 3.0f); // The attach position is in asset space -desc.families[1] = &actor1->getFamily(); // Assume we have a valid actor1 pointer... note, actor0 and actor1 could have the same family -desc.chunkIndices[1] = 10; // This chunk *must* be a support chunk in the asset that created desc.families[1] -desc.attachPositions[1] = physx::PxVec3(4.0f, 5.0f; 6.0f); // The attach position is in asset space - -// Create the external joint from the descriptor, which joins actor0 and actor1 -TkJoint* joint = framework->createJoint(desc); - -// Now join actor0 to the NRF -// desc.families[0] already contains actor0's family -desc.chunkIndices[0] = 2; // Again, this chunk must be a support chunk in the asset that created desc.families[0] -desc.attachPositions[0] = physx::PxVec3(0.0f, 0.0f; 0.0f); // The attach position is in asset space -desc.families[1] = nullptr; // Setting the family to NULL designates the world (NRF) -// The value of desc.chunkIndices[1] is not used, since desc.families[1] is NULL -desc.attachPositions[1] = physx::PxVec3(0.0f, 0.0f, 10.0f); // Attach position in the world - -// Create the external joint which joins actor0 to the world -TkJoint* jointNRF = framework->createJoint(desc); -\endcode - -<br> -\subsection releasing_joints Releasing Joints - -TkJoints are not released by Blast&tm;, except when the TkFramework is released. Otherwise, the user is responsible for -releasing TkJoints after they become unreferenced. This is facilitated by the Unreferenced subtype of the TkJointUpdateEvent. After -receiving this event for joint, the user may choose to release, using the typical TkObject::release() method. - -\code -joint->release(); -\endcode - -Note, this method can be called <em>at any time</em>, even before the joint is unreferenced. When called, it will remove its -references to its attached actors first, causing the joint to then become unreferenced. For example, if the user wishes to break -a physical joint in their simulation, they can then release the corresponding TkJoint. - -It should be mentioned, however, that joints created with an asset are allocated differently from external joints created using -TkFramework::createJoint. Internal joints created from the joint descriptors in a TkAsset are <em>block allocated</em> with every -TkFamily that instances the asset. Calling the release() method on those joints will remove any remaining references to them -(as mentioned above), but will not perform any deallocation. Only when the TkFamily itself is released will the internal joint -memory for that family be released. <b>This is true even if the internal joints become "external" from actor splitting.</b> Joints -that <em>become</em> external are still associated with a single family and their memory still resides with that family. - -On the other hand, joints that start out life external by way of the TkFramework::createJoint function have a separate allocation, -and do not have memory tied to any TkFamily (even if both actors joined are in the same family). Releasing a family holding one -of the actors in such a "purely external" joint will trigger a TkJointUpdateEvent of subtype Unreferenced, however, signalling that -the joint is ready for user release. - -<br> -\section tkevents Events - -NvBlastTk uses events to communicate the results of actor splitting, joint updates from actor splitting, and fracture event buffers -that can be used to synchronize fracturing between multiple clients. - -Events are broadcast to listeners which implement the TkEventListener interface. Listeners are held by TkFamily objects. During -a TkGroup::endProcess call (see \ref tkgroups), relevant events are broadcast to the listeners in the families associated with the actors -in the group. - -A typical user's receiver implementation might take on the form shown below. - -\code -class MyActorAndJointListener : public TkEventListener -{ - // TkEventListener interface - void receive(const TkEvent* events, uint32_t eventCount) override - { - // Events are batched into an event buffer. Loop over all events: - for (uint32_t i = 0; i < eventCount; ++i) - { - const TkEvent& event = events[i]; - - // See TkEvent documentation for event types - switch (event.type) - { - case TkSplitEvent::EVENT_TYPE: // A TkActor has split into smaller actors - { - const TkSplitEvent* splitEvent = event.getPayload<TkSplitEvent>(); // Split event payload - - // The parent actor may no longer be valid. Instead, we receive the information it held - // which we need to update our app's representation (e.g. removal of the corresponding physics actor) - myRemoveActorFunction(splitEvent->parentData.family, splitEvent->parentData.index, splitEvent->parentData.userData); - - // The split event contains an array of "child" actors that came from the parent. These are valid - // TkActor pointers and may be used to create physics and graphics representations in our application - for (uint32_t j = 0; j < splitEvent->numChildren; ++j) - { - myCreateActorFunction(splitEvent->children[j]); - } - } - break; - - case TkJointUpdateEvent::EVENT_TYPE: - { - const TkJointUpdateEvent* jointEvent = event.getPayload<TkJointUpdateEvent>(); // Joint update event payload - - // Joint events have three subtypes, see which one we have - switch (jointEvent->subtype) - { - case TkJointUpdateEvent::External: - myCreateJointFunction(jointEvent->joint); // An internal joint has been "exposed" (now joins two different actors). Create a physics joint. - break; - case TkJointUpdateEvent::Changed: - myUpdatejointFunction(jointEvent->joint); // A joint's actors have changed, so we need to update its corresponding physics joint. - break; - case TkJointUpdateEvent::Unreferenced: - myDestroyJointFunction(jointEvent->joint); // This joint is no longer referenced, so we may delete the corresponding physics joint. - break; - } - } - - // Unhandled: - case TkFractureCommands::EVENT_TYPE: - case TkFractureEvents::EVENT_TYPE: - default: - break; - } - } - } -}; -\endcode - -Whenever a new TkActor is created by the user (via TkFramework::createActor, see \ref tkasset_instancing), its newly-made family should -be given whatever listeners the user wishes to attach. For example, - -\code -TkActor* actor = framework->createActor(actorDesc); - -actor->getFamily().addListener(myListener); // myListener is an object which implements TkEventListener (see MyActorAndJointListener above, for example) -\endcode - -Listeners may also be removed from families at any time. - -<br> -\section tktypes Object and Type Identification - -NvBlastTk objects that are derived from TkIdentifiable (TkAsset, TkFamily, and TkGroup) support an object and class (type) identification -system. The TkIdentifiable interfaces setID and getID allow the user to set and access an NvBlastID for each object. The NvBlastID -is a 128-bit identifier. TkIdentifiable objects are tracked by the TkFramework, which may be used to look up an object by its NvBlastID. - -Upon creation, TkIdentifiable objects are given a GUID, a unique NvBlastID. The user is welcome to change the object's guid at any time, with -the restriction that the GUID cannot be all zero bytes. - -With an object's GUID, one may look up the object using the TkFramework function findObjectByID: - -\code -TkIdentifiable* object = framework->findObjectByID(id); // id = an NvBlastID GUID -\endcode - -If the object is found, a non-NULL pointer will be returned. - -TkIdentifiable-derived classes also have a class identification system, the TkType interface. From an individual object one may use the -TkIdentifiable interface getType to access the class's TkType interface. Alternatively, one may use the TkFramework getType function -with TkTypeIndex::Enum argument. For example, to get the TkType interface for the TkAsset class, use - -\code -const TkType* assetType = framework->getType(TkTypeIndex::Asset); -\endcode - -The type interface may be used: - - - to access class-specific object lists in the framework, - - identify the class of a TkIdentifiable obtained through ID lookup or deserialization, or - - to obtain the class's name and format version number. - -For example, to access a list of all families: - -\code -// Get the TkFamily type interface -const TkType* familyType = framework->getType(TkTypeIndex::Family); - -// Get the family count to allocate a buffer -const uint32_t familyCount = framework->getObjectCount(familyType); -std::vector<TkIdentifiable*> families(familyCount); - -// Write the families to the buffer -const uint32_t familiesFound = framework->getObjects(families.data(), familyCount, familyType); -\endcode - -In the above code, the values of familyCount and familiesFound should be equal. An alternative usage of TkFramework::getObjects allows the -user to write to a (potentially) smaller buffer, iteratively. For example: - -\code -uint32_t familiesFound; -uint32_t totalFamilyCount = 0; -do -{ - // Write to a fixed-size buffer - TkIdentifiable* familyBuffer[16]; - familiesFound = framework->getObjects(familyBuffer, 16, familyType, totalFamilyCount); - totalFamilyCount += familiesFound; - - // Process the families found so far - myProcessFamiliesFunction(familyBuffer, familiesFound); -} while (familiesFound == 16); -\endcode - -To use the type interface to identify a class, perhaps after serialization or lookup by ID, one may do something like: - -\code -\\ Assume we have a TkIdentifiable pointer called "object" - -// Get the type interfaces of interest -const TkType* assetType = framework->getType(TkTypeIndex::Asset); -const TkType* familyType = framework->getType(TkTypeIndex::Family); - -if (object->getType() == *assetType) -{ - TkAsset* asset = static_cast<TkAsset*>(object); - - // Process the object as a TkAsset -} -if (object->getType() == *familyType) -else -{ - TkFamily* family = static_cast<TkFamily*>(object); - - // Process the object as a TkFamily -} -\endcode - -A TkIdentifiable-derived class may be queried for its name using the TkType interface, using TkType::getName(). -This function returns a const char pointer to a string. - -Finally, one may query the class for its current format version number using TkType::getVersion(). - -<br> -*/ +/*! \page pagehlapi High Level (Toolkit) API (NvBlastTk)
+
+<b>Table of Contents</b>
+
+\subpage tkintroduction
+
+\subpage tk_class_hierarchy
+
+\subpage tk_include_and_library
+
+\subpage framework_init
+
+\subpage tkasset_creation
+
+\subpage tkasset_instancing
+
+\subpage tkgroups
+
+\subpage damage_in_tk
+
+\subpage tkjoints
+
+\subpage tkevents
+
+\subpage tktypes
+
+<br>
+\section tkintroduction Introduction to NvBlastTk
+
+The high-level API, NvBlastTk (Tk stands for "toolkit"), is intended to be a more powerful library and a much more convenient entry point
+into the use of Blast&tm;. Like the low-level library, Tk is physics and graphics-agnostic. Whereas the low-level API is C-style, Tk uses
+a C++ API. Everything in Tk is in the namespace:
+
+\code
+Nv::Blast
+\endcode
+
+(the only exceptions are global-scope functions to create and access a framework singleton, see below).
+Every object in Tk is prefixed with 'Tk'. For example, the Tk framework interface is:
+
+\code
+Nv::Blast::TkFramework
+\endcode
+
+<b>
+For the remainder of this page we will be in the Nv::Blast namespace, and will drop the explicit scope Nv::Blast:: from our names.
+</b>
+<br>
+<br>
+
+
+BlastTk adds:
+
+- An object class hierarchy (see \ref tk_class_hierarchy, below).
+- A global framework, <b>TkFramework</b> (a singleton). This keeps track of <b>TkIdentifiable</b> objects and allows
+the user to query them based upon either GUID or <b>TkIdentifiable</b> subclass type, and also provides a number of functions to create the various objects in BlastTk.
+- Processing groups with a task interface (see <b>TkGroup</b>).
+- Event dispatching for actor families (see <b>TkFamily</b>).
+- Intra-actor and inter-actor joint management (see <b>TkJoint</b>). Note, these "joints" only hold descriptor data, since physical objects are not handled by BlastTk.
+
+<br>
+\section tk_class_hierarchy NvBlastTk Class Hierarchy
+
+- There are two abstract interfaces, one of which deriving from the other: <b>TkObject <- TkIdentifiable</b>.
+ - Lightweight objects are derived from <b>TkObject</b>.
+ - Objects which use a GUID and class identification are derieved from <b>TkIdentifiable</b>.
+- <b>TkAsset</b> derives from <b>TkIdentifiable</b>. This is mostly a wrapper for NvBlastAsset, however it also stores
+extra data associated with the asset such as internal joint descriptors.
+- <b>TkFamily</b> derives from <b>TkIdentifiable</b>. One of these objects is made when a <b>TkActor</b> is instanced
+from a <b>TkAsset</b>. All actors that are created by splitting the family's original actor remain within the same family. Actor and joint
+events are dispatched from the <b>TkFamily</b>.
+- <b>TkGroup</b> derives from <b>TkIdentifiable</b>. Groups are processing units. The user may create as many groups as they please, and add
+or remove actors as they please from groups. The group provides a worker (TkGroupWorker) interface which allows the user to process multiple
+jobs in the group asynchoronously. These jobs, along with a call to TkGroup::endProcess(), perform the tasks of generating fracture commands,
+applying fracture commands, and actor splitting at the low-level. The user is informed of splitting through listeners given to TkFamily objects.
+- <b>TkActor</b> derives from <b>TkObject</b>. It is mostly a wrapper for NvBlastActor, but it also provides a number of damage functions
+to the user.
+- <b>TkJoint</b> derives from <b>TkObject</b>. <b>TkAsset</b> descriptors, cause internal <b>TkJoint</b> obejcts to be created within an actor
+(joining chunks within the same actor). Alternatively, the TkFramework provides a function which allows the user to create an external joint
+between any two different actors. As actors split, internal joints may become external. The user gets notification whenever joints become
+external, or when actors joined by joints change or are deleted, through listeners attached to the associated TkFamily objects.
+
+<br>
+\section tk_include_and_library Linking and Header Files
+
+To use the BlastTk library, the application need only inlclude the header NvBlastTk.h, found in the <b>include/toolkit</b> folder, and link
+against the appropriate version of the NvBlastTk library. Depending on the platform and configuration, various suffixes will be added to the library
+name. The general naming scheme is
+
+NvBlastTk(config)(arch).(ext)
+
+(config) is DEBUG, CHECKED, OR PROFILE for the corresponding configurations. For a release configuration there is no (config) suffix.
+
+(arch) is _x86 or _x64 for Windows 32- and 64-bit builds, respectively, and empty for non-Windows platforms.
+
+(ext) is .lib for static linking and .dll for dynamic linking on Windows. On XBoxOne it is .lib, and on PS4 it is .a.
+
+
+<br>
+\section framework_init Creating the TkFramework
+
+As a reminder, in this document we assume we are in the Nv::Blast namespace:
+
+\code
+using namespace Nv::Blast;
+\endcode
+
+In order to use NvBlastTk, one first has to create a TkFramework singleton. This simply requires a call
+to the global function NvBlastTkFrameworkCreate:
+
+\code
+TkFramework* framework = NvBlastTkFrameworkCreate();
+\endcode
+
+The framework may be accessed via:
+
+\code
+TkFramework* framework = NvBlastTkFrameworkGet();
+\endcode
+
+In the sections that follow, it is assumed that a framework has been created, and we have a pointer to it named 'framework' within scope.
+
+Finally, to release the framework, use
+
+\code
+framework->release();
+\endcode
+
+This will release all assets, families, actors, joints, and groups.
+
+<br>
+\section tkasset_creation Creating a TkAsset
+
+The TkAsset object is a high-level wrapper for the low-level NvBlastAsset (see \ref assets). The descriptor used to create a TkAsset, a TkAssetDesc, is derived from
+NvBlastAssetDesc. The base fields should be filled in as described in (\ref assets). The new field is an optional array of flags to be associated with each bond in
+the base descriptor. Currently the only flag is "BondJointed," and if set will cause an "internal joint" to be created in actors (TkActor type) created from the asset.
+See (\ref tkjoints) for more on joints in BlastTk.
+
+\code
+TkAssetDesc desc;
+
+myFunctionToFillInLowLevelAssetFields(desc); // Fill in the low-level (NvBlastAssetDesc) fields as usual
+
+std::vector<uint8_t*> bondFlags(desc.bondCount, 0); // Clear all flags
+
+// Set BondJointed flags corresponding to joints selected by the user (assumes a myBondIsJointedFunction to make this selection)
+for (uint32_t i = 0; i < desc.bondCount; ++i)
+{
+ if (myBondIsJointedFunction(i)) // User-authored
+ {
+ bondFlags[i] |= TkAssetDesc::BondJointed;
+ }
+}
+
+TkAsset* asset = framework->createAsset(desc); // Create a new TkAsset
+\endcode
+
+The createAsset function used above creates a low-level NvBlastAsset from the base fields of the descriptor, and then adds internal joint descriptors based
+upon the bonds' centroids and attached chunks. An alternative method to create a TkAsset allows the user to pass in a pre-existing NvBlastAsset, and a list
+of joint descriptors. If the TkAsset is to have no internal joints, then the joint descriptors are not necessary and with an NvBlastAsset
+pointer <b>llAsset</b>, a TkAsset may be created simply by using
+
+\code
+TkAsset* asset = framework->createAsset(llAsset);
+\endcode
+
+By default, such a TkAsset will not "own" the llAsset. When the TkAsset is released, the llAsset memory will be untouched. You can pass ownership to the
+TkAsset using all of the default parameters of the createAsset function:
+
+\code
+TkAsset* asset = framework->createAsset(llAsset, nullptr, 0, true);
+\endcode
+
+The last parameter sets ownership. N.B.: in order for the TkAsset to own the underlying llAsset, and therefore release it when the TkAsset is released,
+the memory for the llAsset must be allocated using the allocator accessed through NvBlastGlobals (see \ref pageglobalsapi).
+
+If one wants to author internal joints in a TkAsset using this second createAsset method, one must pass in a valid array of joint descriptors of type
+TkAssetJointDesc. Each joint descriptor takes two positions and two node indices. The positions are the joint's attachment positions in asset space, and
+the nodes indices are those of the graph nodes that correspond to support chunks. These indices are not, in general, the same as the chunk indices.
+An example of initialization of the joint descriptors is given below.
+
+\code
+std::vector<TkAssetJointDesc> jointDescs(jointCount); // Assume jointCount = the number of joints to add
+jointDescs[0].nodeIndices[0] = 0; // Attach node 0 to node 1
+jointDescs[0].nodeIndices[1] = 1;
+jointDescs[0].attachPoistions[0] = physx::PxVec3( 1.0f, 2.0f, 3.0f ); // Attachment positions are often the same within an asset, but they don't have to be
+jointDescs[0].attachPoistions[1] = physx::PxVec3( 1.0f, 2.0f, 3.0f );
+// ... etc.
+
+TkAsset* asset = framework->createAsset(llAsset, jointDescs.data(), jointDescs.size());
+\endcode
+
+The code above assumes you know the support graph nodes to which you'd like to attach joints. Often, the user only knows the corresponding chunk indices.
+Fortunately it's easy to map chunk indices to graph node indices. In order to get the map, use the low-level function
+
+\code
+const uint32_t map = NvBlastAssetGetChunkToGraphNodeMap(llAsset, logFn);
+\endcode
+
+This map is an array with an entry for every chunk index. To get the graph node index for a chunk indexed <b>chunkIndex</b>, use
+
+\code
+uint32_t nodeIndex = map[chunkIndex];
+\endcode
+
+If the chunk indexed by <b>chunkIndex</b> does <em>not</em> correspond to a support chunk, then the mapped value will be UINT32_MAX, the invalid index.
+Otherwise, the mapped value will be a valid graph node index.
+
+Finally, to release a TkAsset, as with any TkObject-derived object, use the release() method:
+
+\code
+asset->release();
+\endcode
+
+<br>
+\section tkasset_instancing Instancing a TkAsset: Creation of a TkActor and a TkFamily
+
+Whereas with the Blast&tm; low-level (\ref pagellapi), one must explicitly create a family (NvBlastFamily) from an asset (NvBlastAsset) before creating
+the first actor (NvBlastActor) in the family, NvBlastTk creates a TkFamily automatically when an unfractured TkActor is instanced from a TkAsset using
+the framework's createActor function. This family is accessible through the actor and any actor that is created from splitting it. The family is
+<em>not</em> released automatically when all actors within it have been released. The user must use the TkFamily's release() method (see TkObject base
+API) to do so. (Or wait until the framework is released.) If a family is released that contains actors, the actors within will be released as well.
+
+The TkFamily has a special role in NvBlastTk, holding user-supplied event listeners (\ref TkEventListener). All <em>internal</em> actor creation and destruction
+events are broadcast to listeners through split events (TkSplitEvent). These signal when a fracturing operation has destroyed an actor and created
+child actors from it. TkActor creation or release that occurs from an explicit API call do not produce events. For example when creating a first unfractured
+instance of an asset using createAsset, or when calling the release() method on a TkActor. TkJoint events are similarly broadcast to
+receivers (TkJointEvent). These signal when the actors which are joined by the joints change, so that the user may update a corresponding physical joint.
+They also signal when a joint no longer attaches actors and is therefore unreferenced. The user may invalidate or release the joint using the TkObject
+release() method when this occurs (more on joint ownership in \ref tkjoints).
+
+To create an unfractured TkActor instance from a TkAsset, one first fills in a descriptor (\ref TkActorDesc) and passes it to the framework's createActor function.
+As with the TkAssetDesc, the TkActorDesc is derived from its low-level counterpart, the NvBlastActorDesc. In addition the TkActorDesc holds a pointer to
+the TkAsset being instanced. An example of TkActor creation is given below, given a TkAsset pointer <b>asset</b>.
+
+\code
+TkActorDesc desc; // The TkActorDesc constructor sets sane default values for the base (NvBlastActorDesc) fields, giving uniform chunk and bond healths of 1.0.
+desc.asset = asset; // This field of TkActorDesc must be set to a valid asset pointer.
+
+TkActor* actor = framework->createActor(desc);
+\endcode
+
+The TkFamily created with the actor above may be accessed through the actor's getFamily field:
+
+\code
+TkFamily& family = actor->getFamily();
+\endcode
+
+The returned value is a reference since a TkActor's family can never be NULL. Actors resulting from the split of a "parent" actor will always belong to the
+parent's family.
+
+For most applications, the user will need to create a listener object to pass to every family created, in order to keep their physics and graphics representations
+in sync with the splitting of the TkActor. For more on this, see \ref tkevents.
+
+<br>
+\section tkgroups Groups
+
+One important feature of NvBlastTk is the ability to multitask damage processing. The mechanism by which the toolkit does this is the group object, TkGroup.
+Groups are created at the request of the user; the user may create as many groups as he or she likes. Actors may be added or removed from groups in any way the
+user wishes, with the only constraint being that a given actor may belong to no more than one group. A group is a processing object, much like a scene in a physics
+simulation. Indeed, a natural pattern would be to associate one group per physics scene, and synchronize the group processing with scene simulation. Another
+pattern would be to subdivide the world into neighborhoods, and associate each neighborhood with a group. A distributed game could take advantage of this structure
+to similarly distribute computation.
+
+Group processing is performed by <em>workers</em>, which have a TkGroupWorker API exposed to the user. The number of workers may be set by the user, with the idea being
+that this should correspond to the number of threads available for group processing. Processing starts with a call to TkGroup::startProcess(). This creates a number
+of jobs which the user may assign to workers as they like, each worker potentially on its own thread. The jobs calculate the effects of all damage taken
+by the group's actors. After all jobs have been run, the user must call TkGroup::endProcess(). This will result in all events being fired off to listeners associated
+with families with actors in the group.
+
+A convenience function, TkGroup::process(), is provided which uses one worker to perform all jobs sequentially on the calling thread. This is useful shortcut to
+get BlastTk up and running quickly. A multithreaded group processing implementation is given by Nv::Blast::ExtGroupTaskManager (in NvBlastExtPxTask.h).
+This resides in \ref pageextphysx, because it uses physx::PxTask.
+
+Actors resulting from the split of a "parent" actor will be placed automatically into the group that the parent belonged to. This is similar to the assigment of
+families from a split, except that unlike families, the user then has the option to move the new actors to other groups, or no group at all.
+
+Also similar to families, groups are not automatically released when the last actor is removed from it. Unlike families, when a group is released, the actors which
+belong to the group are <em>not</em> released. They will, however, be removed from the group before the release is complete.
+
+A typical usage is outlined below. See \ref damage_in_tk for methods of applying damage to actors.
+
+\code
+// Create actors from descriptors desc1, desc2, ... etc., and attach a listener to each new family created
+TkActor* actor1 = framework->createActor(desc1);
+actor1->getFamily().addListener(gMyReceiver); // gMyReceiver is a TkEventListener-derived object. More on events in a subsequent section.
+TkActor* actor2 = framework->createActor(desc2);
+actor2->getFamily().addListener(gMyReceiver);
+TkActor* actor3 = framework->createActor(desc3);
+actor3->getFamily().addListener(gMyReceiver);
+// etc...
+
+// Let's create two groups. First, create a group descriptor. This may be used to create both groups.
+TkGroupDesc groupDesc;
+groupDesc.workerCount = 1; // this example processes groups on the calling thread only
+
+// Now create the groups
+TkGroup* group1 = framework->createGroup(groupDesc);
+TkGroup* group2 = framework->createGroup(groupDesc);
+
+// Add actor1 and actor2 to group1, and actor2 to group3...
+group1->addActor(actor1);
+group1->addActor(actor2);
+group2->addActor(actor3);
+// etc...
+
+// Now apply damage to all actors - *NOTE* damage is described in detail in the next section.
+// For now we will just assume a "myDamageFunction" to apply the damage.
+myDamageFunction(actor1);
+myDamageFunction(actor2);
+myDamageFunction(actor3);
+// etc...
+
+// Calling the groups' process functions will (synchronously) run all jobs to process damage taken by the contained actors.
+group1->process();
+group2->process();
+
+// When the groups are no longer needed, they may be released with the usual release method.
+group1->release();
+group2->release();
+\endcode
+
+<br>
+<b>Multithreaded processing</b>
+
+When distributing the jobs as mentioned above, every job must be processed exactly once (over all user tasks).
+
+The number of jobs processed per worker can range from a single job (resulting in a user task per job) to all jobs (like Nv::Blast::TkGroup::process() does).
+
+At any point in time, no more than the set workerCount amount of workers may have been acquired. Return the worker at the end of each task.
+
+\code
+Nv::Blast::TkGroupWorker* worker = group->acquireWorker();
+// process some jobs
+group->returnWorker(worker);
+\endcode
+
+<br>
+\section damage_in_tk Applying Damage to Actors and Families
+
+Damage in NvBlastTk uses the same damage program scheme as the low-level SDK (see \ref splitting). One passes the program
+(NvBlastDamageProgram), damage descriptor (program-dependent), and material (also program-dependent) to a TkActor::damage
+function. Ultimately, the damage descriptor and material data are all parameters used by the damage program. The distinction
+is that the damage descriptor should describe properties of the thing doing the damage, while the material should
+describe properties of the actor (the thing being damaged). The interpretation of this data is entirely up to the program's
+functions, however.
+
+For convenience, the user may set a default material in the actor's family. This assumes, of course, that the material parameters
+for this default are compatible with the program being used to damage the family's actors.
+
+Examples of the three TkActor damage methods are given below.
+
+<br>
+\subsection multiple_damage Multiple Damage Descriptors using NvBlastProgramParams
+
+<b>N.B. - with this method of damage, the lifetime of the NvBlastProgramParams <em>must</em> extend at
+least until the TkGroup::endProcess call for the actor.</b>
+
+\code
+NvBlastDamageProgram program =
+{
+ myGraphShaderFunction, // A function with the NvBlastGraphShaderFunction signature
+ mySubgraphShaderFunction // A function with the NvBlastSubgraphShaderFunction signature
+};
+
+// The example struct "RadialDamageDesc" is modeled after NvBlastExtRadialDamageDesc in the NvBlastExtShaders extension
+RadialDamageDesc damageDescs[2];
+
+damageDescs[0].compressive = 10.0f;
+damageDescs[0].position[0] = 1.0f;
+damageDescs[0].position[1] = 2.0f;
+damageDescs[0].position[2] = 3.0f;
+damageDescs[0].minRadius = 0.0f;
+damageDescs[0].maxRadius = 1.0f;
+
+damageDescs[1].compressive = 100.0f;
+damageDescs[1].position[0] = 3.0f;
+damageDescs[1].position[1] = 4.0f;
+damageDescs[1].position[2] = 5.0f;
+damageDescs[1].minRadius = 0.0f;
+damageDescs[1].maxRadius = 5.0f;
+
+// The example material "Material" is modeled after NvBlastExtMaterial in the NvBlastExtShaders extension
+Material material;
+
+material.health = 10.0f;
+material.minDamageThreshold = 0.1f;
+material.maxDamageThreshold = 0.8f;
+
+// Set the damage params struct
+NvBlastProgramParams params = { damageDescs, 2, &material };
+
+// Apply damage
+actor->damage(program, ¶ms); // params must be kept around until TkGroup::endProcess is called!
+\endcode
+
+<br>
+\subsection single_damage_desc_default_material Single Damage Descriptor with Default TkFamily Material
+
+This method of damage copies the damage descriptor into a buffer, so the user need <em>not</em> hold onto
+a copy after the damage function call. Only one damage descriptor may be passed in at once.
+
+To use this method, the user must first set a default material in the actor's family. For example:
+
+\code
+// The example material "Material" is modeled after NvBlastExtMaterial in the NvBlastExtShaders extension
+Material material;
+
+material.health = 10.0f;
+material.minDamageThreshold = 0.1f;
+material.maxDamageThreshold = 0.8f;
+
+// Set the default material used by the material-less TkActor::damage call
+actor->getFamily().setMaterial(&material);
+\endcode
+
+<b>N.B. the lifetime of the material set <em>must</em> extend at least until the TkGroup::endProcess call for the actor.</b>
+
+Then to apply damage, use:
+
+\code
+NvBlastDamageProgram program =
+{
+ myGraphShaderFunction, // A function with the NvBlastGraphShaderFunction signature
+ mySubgraphShaderFunction // A function with the NvBlastSubgraphShaderFunction signature
+};
+
+// The example struct "RadialDamageDesc" is modeled after NvBlastExtRadialDamageDesc in the NvBlastExtShaders extension
+RadialDamageDesc damageDesc;
+
+damageDesc.compressive = 10.0f;
+damageDesc.position[0] = 1.0f;
+damageDesc.position[1] = 2.0f;
+damageDesc.position[2] = 3.0f;
+damageDesc.minRadius = 0.0f;
+damageDesc.maxRadius = 1.0f;
+
+// Apply damage
+actor->damage(program, &damageDesc, (uint32_t)sizeof(RadialDamageDesc));
+\endcode
+
+<br>
+\subsection single_damage_desc_with_material Single Damage Descriptor with Specified Material
+
+This method is just like the one above, except that the user has the opportunity to override the material used during damage.
+
+<b>N.B. - the lifetime of the material passed in <em>must</em> extend at least until the TkGroup::endProcess call for the actor.</b>
+
+This call is just like the one above with an extra material parameter:
+
+\code
+actor->damage(program, &damageDesc, (uint32_t)sizeof(RadialDamageDesc), &material);
+\endcode
+
+<br>
+\section tkjoints Joints
+
+Joints in NvBlastTk are abstract representations of physical joints. When joints become active, change the actors they join,
+or become unreferenced (the actors they join disappear), the user will receive notification via a TkJointUpdateEvent
+(see \ref tkevents).
+
+Joints may be defined as a part of a TkAsset, in which case they are consisdered "internal" joints. (See \ref tkasset_creation.)
+Since the first instance of a TkAsset is a single TkActor, internal joints are defined between chunks within the same actor.
+Therefore they are not active (there is no point in joining two locations in a single rigid body). Upon splitting into multiple
+actors, however, an internal joint's chunks may now belong to two different TkActors. When this happens, the user will receive a
+TkJointUpdateEvent of subtype TkJointUpdateEvent::External. The event contains a pointer to the TkJoint, and from that the user
+has access to the information needed to create a physical joint between the rigid bodies that correspond to the joined TkActors.
+
+Joints may also be created externally at runtime, using the TkFramework::createJoint function. A joint created this way must
+be between two different TkActors. Because of this, the joint is immediately considered active, and so no TkJointUpdateEvent
+is generated from its creation. The user should create a physical joint to correspond to the joint returned by createJoint.
+An externally created joint of this type has another distinguishing characteristic: it may join an actor to "the world," or
+"Newtonial Reference Frame" (NRF). To do this, one TkFamily pointer in the joint descriptor is set to NULL. Examples are
+given below.
+
+\code
+TkJointDesc desc;
+desc.families[0] = &actor0->getFamily(); // Assume we have a valid actor0 pointer
+desc.chunkIndices[0] = 1; // This chunk *must* be a support chunk in the asset that created desc.families[0]
+desc.attachPositions[0] = physx::PxVec3(1.0f, 2.0f; 3.0f); // The attach position is in asset space
+desc.families[1] = &actor1->getFamily(); // Assume we have a valid actor1 pointer... note, actor0 and actor1 could have the same family
+desc.chunkIndices[1] = 10; // This chunk *must* be a support chunk in the asset that created desc.families[1]
+desc.attachPositions[1] = physx::PxVec3(4.0f, 5.0f; 6.0f); // The attach position is in asset space
+
+// Create the external joint from the descriptor, which joins actor0 and actor1
+TkJoint* joint = framework->createJoint(desc);
+
+// Now join actor0 to the NRF
+// desc.families[0] already contains actor0's family
+desc.chunkIndices[0] = 2; // Again, this chunk must be a support chunk in the asset that created desc.families[0]
+desc.attachPositions[0] = physx::PxVec3(0.0f, 0.0f; 0.0f); // The attach position is in asset space
+desc.families[1] = nullptr; // Setting the family to NULL designates the world (NRF)
+// The value of desc.chunkIndices[1] is not used, since desc.families[1] is NULL
+desc.attachPositions[1] = physx::PxVec3(0.0f, 0.0f, 10.0f); // Attach position in the world
+
+// Create the external joint which joins actor0 to the world
+TkJoint* jointNRF = framework->createJoint(desc);
+\endcode
+
+<br>
+\subsection releasing_joints Releasing Joints
+
+TkJoints are not released by Blast&tm;, except when the TkFramework is released. Otherwise, the user is responsible for
+releasing TkJoints after they become unreferenced. This is facilitated by the Unreferenced subtype of the TkJointUpdateEvent. After
+receiving this event for joint, the user may choose to release, using the typical TkObject::release() method.
+
+\code
+joint->release();
+\endcode
+
+Note, this method can be called <em>at any time</em>, even before the joint is unreferenced. When called, it will remove its
+references to its attached actors first, causing the joint to then become unreferenced. For example, if the user wishes to break
+a physical joint in their simulation, they can then release the corresponding TkJoint.
+
+It should be mentioned, however, that joints created with an asset are allocated differently from external joints created using
+TkFramework::createJoint. Internal joints created from the joint descriptors in a TkAsset are <em>block allocated</em> with every
+TkFamily that instances the asset. Calling the release() method on those joints will remove any remaining references to them
+(as mentioned above), but will not perform any deallocation. Only when the TkFamily itself is released will the internal joint
+memory for that family be released. <b>This is true even if the internal joints become "external" from actor splitting.</b> Joints
+that <em>become</em> external are still associated with a single family and their memory still resides with that family.
+
+On the other hand, joints that start out life external by way of the TkFramework::createJoint function have a separate allocation,
+and do not have memory tied to any TkFamily (even if both actors joined are in the same family). Releasing a family holding one
+of the actors in such a "purely external" joint will trigger a TkJointUpdateEvent of subtype Unreferenced, however, signalling that
+the joint is ready for user release.
+
+<br>
+\section tkevents Events
+
+NvBlastTk uses events to communicate the results of actor splitting, joint updates from actor splitting, and fracture event buffers
+that can be used to synchronize fracturing between multiple clients.
+
+Events are broadcast to listeners which implement the TkEventListener interface. Listeners are held by TkFamily objects. During
+a TkGroup::endProcess call (see \ref tkgroups), relevant events are broadcast to the listeners in the families associated with the actors
+in the group.
+
+A typical user's receiver implementation might take on the form shown below.
+
+\code
+class MyActorAndJointListener : public TkEventListener
+{
+ // TkEventListener interface
+ void receive(const TkEvent* events, uint32_t eventCount) override
+ {
+ // Events are batched into an event buffer. Loop over all events:
+ for (uint32_t i = 0; i < eventCount; ++i)
+ {
+ const TkEvent& event = events[i];
+
+ // See TkEvent documentation for event types
+ switch (event.type)
+ {
+ case TkSplitEvent::EVENT_TYPE: // A TkActor has split into smaller actors
+ {
+ const TkSplitEvent* splitEvent = event.getPayload<TkSplitEvent>(); // Split event payload
+
+ // The parent actor may no longer be valid. Instead, we receive the information it held
+ // which we need to update our app's representation (e.g. removal of the corresponding physics actor)
+ myRemoveActorFunction(splitEvent->parentData.family, splitEvent->parentData.index, splitEvent->parentData.userData);
+
+ // The split event contains an array of "child" actors that came from the parent. These are valid
+ // TkActor pointers and may be used to create physics and graphics representations in our application
+ for (uint32_t j = 0; j < splitEvent->numChildren; ++j)
+ {
+ myCreateActorFunction(splitEvent->children[j]);
+ }
+ }
+ break;
+
+ case TkJointUpdateEvent::EVENT_TYPE:
+ {
+ const TkJointUpdateEvent* jointEvent = event.getPayload<TkJointUpdateEvent>(); // Joint update event payload
+
+ // Joint events have three subtypes, see which one we have
+ switch (jointEvent->subtype)
+ {
+ case TkJointUpdateEvent::External:
+ myCreateJointFunction(jointEvent->joint); // An internal joint has been "exposed" (now joins two different actors). Create a physics joint.
+ break;
+ case TkJointUpdateEvent::Changed:
+ myUpdatejointFunction(jointEvent->joint); // A joint's actors have changed, so we need to update its corresponding physics joint.
+ break;
+ case TkJointUpdateEvent::Unreferenced:
+ myDestroyJointFunction(jointEvent->joint); // This joint is no longer referenced, so we may delete the corresponding physics joint.
+ break;
+ }
+ }
+
+ // Unhandled:
+ case TkFractureCommands::EVENT_TYPE:
+ case TkFractureEvents::EVENT_TYPE:
+ default:
+ break;
+ }
+ }
+ }
+};
+\endcode
+
+Whenever a new TkActor is created by the user (via TkFramework::createActor, see \ref tkasset_instancing), its newly-made family should
+be given whatever listeners the user wishes to attach. For example,
+
+\code
+TkActor* actor = framework->createActor(actorDesc);
+
+actor->getFamily().addListener(myListener); // myListener is an object which implements TkEventListener (see MyActorAndJointListener above, for example)
+\endcode
+
+Listeners may also be removed from families at any time.
+
+<br>
+\section tktypes Object and Type Identification
+
+NvBlastTk objects that are derived from TkIdentifiable (TkAsset, TkFamily, and TkGroup) support an object and class (type) identification
+system. The TkIdentifiable interfaces setID and getID allow the user to set and access an NvBlastID for each object. The NvBlastID
+is a 128-bit identifier. TkIdentifiable objects are tracked by the TkFramework, which may be used to look up an object by its NvBlastID.
+
+Upon creation, TkIdentifiable objects are given a GUID, a unique NvBlastID. The user is welcome to change the object's guid at any time, with
+the restriction that the GUID cannot be all zero bytes.
+
+With an object's GUID, one may look up the object using the TkFramework function findObjectByID:
+
+\code
+TkIdentifiable* object = framework->findObjectByID(id); // id = an NvBlastID GUID
+\endcode
+
+If the object is found, a non-NULL pointer will be returned.
+
+TkIdentifiable-derived classes also have a class identification system, the TkType interface. From an individual object one may use the
+TkIdentifiable interface getType to access the class's TkType interface. Alternatively, one may use the TkFramework getType function
+with TkTypeIndex::Enum argument. For example, to get the TkType interface for the TkAsset class, use
+
+\code
+const TkType* assetType = framework->getType(TkTypeIndex::Asset);
+\endcode
+
+The type interface may be used:
+
+ - to access class-specific object lists in the framework,
+ - identify the class of a TkIdentifiable obtained through ID lookup or deserialization, or
+ - to obtain the class's name and format version number.
+
+For example, to access a list of all families:
+
+\code
+// Get the TkFamily type interface
+const TkType* familyType = framework->getType(TkTypeIndex::Family);
+
+// Get the family count to allocate a buffer
+const uint32_t familyCount = framework->getObjectCount(familyType);
+std::vector<TkIdentifiable*> families(familyCount);
+
+// Write the families to the buffer
+const uint32_t familiesFound = framework->getObjects(families.data(), familyCount, familyType);
+\endcode
+
+In the above code, the values of familyCount and familiesFound should be equal. An alternative usage of TkFramework::getObjects allows the
+user to write to a (potentially) smaller buffer, iteratively. For example:
+
+\code
+uint32_t familiesFound;
+uint32_t totalFamilyCount = 0;
+do
+{
+ // Write to a fixed-size buffer
+ TkIdentifiable* familyBuffer[16];
+ familiesFound = framework->getObjects(familyBuffer, 16, familyType, totalFamilyCount);
+ totalFamilyCount += familiesFound;
+
+ // Process the families found so far
+ myProcessFamiliesFunction(familyBuffer, familiesFound);
+} while (familiesFound == 16);
+\endcode
+
+To use the type interface to identify a class, perhaps after serialization or lookup by ID, one may do something like:
+
+\code
+\\ Assume we have a TkIdentifiable pointer called "object"
+
+// Get the type interfaces of interest
+const TkType* assetType = framework->getType(TkTypeIndex::Asset);
+const TkType* familyType = framework->getType(TkTypeIndex::Family);
+
+if (object->getType() == *assetType)
+{
+ TkAsset* asset = static_cast<TkAsset*>(object);
+
+ // Process the object as a TkAsset
+}
+if (object->getType() == *familyType)
+else
+{
+ TkFamily* family = static_cast<TkFamily*>(object);
+
+ // Process the object as a TkFamily
+}
+\endcode
+
+A TkIdentifiable-derived class may be queried for its name using the TkType interface, using TkType::getName().
+This function returns a const char pointer to a string.
+
+Finally, one may query the class for its current format version number using TkType::getVersion().
+
+<br>
+*/
diff --git a/docs/_source/api_ll_users_guide.txt b/docs/_source/api_ll_users_guide.txt index 8d04ee8..4626f8f 100644..100755 --- a/docs/_source/api_ll_users_guide.txt +++ b/docs/_source/api_ll_users_guide.txt @@ -1,393 +1,393 @@ -/*! \page pagellapi Low Level API (NvBlast) - -<b>Table of Contents</b> - -\subpage llintroduction - -\subpage include_and_library - -\subpage assets - -\subpage actors_and_families - -\subpage splitting - -<br> -\section llintroduction Introduction - -The low-level API is the core of Blast&tm; destruction. It is designed to be a minimal API that allows an experienced user to incorporate destruction -into their application. Summarizing what the low-level API has, and <em>doesn't</em> have: - -- There is no physics representation. The low-level API is agnostic with respect to any physics engine, and furthermore does not have -any notion of collision geometry. The NvBlastActor is an abstraction which is intended to correspond to a rigid body. However -it is up to the user to implement that connection. The NvBlastActor references a list of visible chunk indices, which correspond to -NvBlastChunk data in the asset. The NvBlastChunk contains a userData field which can be used to associate collision -geometry with the actor based upon the visible chunks. The same is true for constraints created between actors. Bonds contain a -userData field that can be used to inform the user that actors should have joints created at a particular location, but it is up to the -user to create and manage physical joints between two actors. -- There is no graphics representation. Just as there is no notion of collision geometry, there is also no notion of graphics geometry. -The NvBlastChunk userData field (see the item above) can be used to associate graphics geometry with the actor based upon the visible chunks. -- There is no notion of threading. The API is a collection of free functions which the user may call from appropriate threads. -Blast&tm; guarantees that it is safe to operate on different actors from different threads. -- There is no global memory manager, message handler, etc. All low-level API functions take an optional message function pointer argument -in order to report warnings or errors. Memory is managed by the user, and functions that build objects require an appropriately-sized memory block -to be passed in. A corresponding utility function that calculates the memory requirements is always present alongside such functions. Temporary -storage needed by a function is always handled via user-supplied scratch space. For scratch, there is always a corresponding "RequiredScratch" -function or documentation which lets the user know how much scratch space is needed based upon the function arguments. -- Backwards-compatible, versioned, device-independent serialization is not handled by Blast&tm;. There <em>is</em> however a Blast&tm; extension -which does, see \ref pageextserialization. However, a simple form of serialization may be performed on assets and familes (see \ref pagedefinitions) -via simple memory copy. The data associated with these objects is available to the user, and may be copied and stored by the user. -Simply casting a pointer to such a block of memory to the correct object type will produce a usable object for Blast&tm;. (The only restriction is -that the block must be 16-byte aligned.) Families contain a number of actors and so this form of deserialization recreates all actors in the family. -This form of serialization may be used between two devices which have the same endianness, and contain Blast&tm; SDKs which use the same object format. -- Single-actor serialization and deserialization is, however, supported. This is not as light-weight as family serialization, but may be a better -serialization model for a particular application. To deserialize a single actor, one must have a family to hold the actor, created from the appropriate -asset. If none exists already, the user may create an empty family. After that, all actors that had been in that family may be deserialized -into it one-at-a-time, in any order. - -<br> -\section include_and_library Linking and Header Files - -To use the low-level Blast&tm; SDK, the application need only inlclude the header NvBlast.h, found in the top-level <b>include</b> folder, and link -against the appropriate version of the NvBlast library. Depending on the platform and configuration, various suffixes will be added to the library -name. The general naming scheme is - -NvBlast(config)(arch).(ext) - -(config) is DEBUG, CHECKED, OR PROFILE for the corresponding configurations. For a release configuration there is no (config) suffix. - -(arch) is _x86 or _x64 for Windows 32- and 64-bit builds, respectively, and empty for non-Windows platforms. - -(ext) is .lib for static linking and .dll for dynamic linking on Windows. On XBoxOne it is .lib, and on PS4 it is .a. - -<br> -\section assets Creating an Asset from a Descriptor (Authoring) - -The NvBlastAsset is an opaque type pointing to an object constructed by Blast&tm; in memory allocated by the user. -To create an asset from a descriptor, use the function \ref NvBlastCreateAsset. See the function documentation for a -description of its parameters. - -<b>N.B., there are strict rules for the ordering of chunks with an asset, and also conditions on the chunks marked as "support" -(using the NvBlastChunkDesc::SupportFlag). See the function documentation for these conditions. NvBlastCreateAsset does -<em>not</em> reorder chunks or modify support flags to meet these conditions. If the conditions are not met, NvBlastCreateAsset -fails and returns NULL. However, Blast&tm; provides helper functions to reorder chunk descriptors and modify the support flags -within those descriptors so that they are valid for asset creation. The helper functions return a mapping from the original -chunk ordering to the new chunk ordering, so that corresponding adjustments or mappings may be made for graphics and other data -the user associates with chunks.</b> - -Example code is given below. Throughout, we assume the user has defined a logging function called <B>logFn</B>, with the -signature of NvBlastLog. In all cases, the log function is optional, and NULL may be passed in its place. - -\code -// Create chunk descriptors -std::vector<NvBlastChunkDesc> chunkDescs; -chunkDescs.resize( chunkCount ); // chunkCount > 0 - -chunkDescs[0].parentChunkIndex = UINT32_MAX; // invalid index denotes a chunk hierarchy root -chunkDescs[0].centroid[0] = 0.0f; // centroid position in asset-local space -chunkDescs[0].centroid[1] = 0.0f; -chunkDescs[0].centroid[2] = 0.0f; -chunkDescs[0].volume = 1.0f; // Unit volume -chunkDescs[0].flags = NvBlastChunkDesc::NoFlags; -chunkDescs[0].userData = 0; // User-supplied ID. For example, this can be the index of the chunkDesc. - // The userData can be left undefined. - -chunkDescs[1].parentChunkIndex = 0; // child of chunk described by chunkDescs[0] -chunkDescs[1].centroid[0] = 2.0f; // centroid position in asset-local space -chunkDescs[1].centroid[1] = 4.0f; -chunkDescs[1].centroid[2] = 6.0f; -chunkDescs[1].volume = 1.0f; // Unit volume -chunkDescs[1].flags = NvBlastChunkDesc::SupportFlag; // This chunk should be represented in the support graph -chunkDescs[1].userData = 1; - -// ... etc. for all chunks - -// Create bond descriptors -std::vector<NvBlastBondDesc> bondDescs; -bondDescs.resize( bondCount ); // bondCount > 0 - -bondDescs[0].chunkIndices[0] = 1; // chunkIndices refer to chunk descriptor indices for support chunks -bondDescs[0].chunkIndices[1] = 2; -bondDescs[0].bond.normal[0] = 1.0f; // normal in the +x direction -bondDescs[0].bond.normal[1] = 0.0f; -bondDescs[0].bond.normal[2] = 0.0f; -bondDescs[0].bond.area = 1.0f; // unit area -bondDescs[0].bond.centroid[0] = 1.0f; // centroid position in asset-local space -bondDescs[0].bond.centroid[1] = 2.0f; -bondDescs[0].bond.centroid[2] = 3.0f; -bondDescs[0].userData = 0; // this can be used to tell the user more information about this - // bond for example to create a joint when this bond breaks - -bondDescs[1].chunkIndices[0] = 1; -bondDescs[1].chunkIndices[1] = ~0; // ~0 (UINT32_MAX) is the "invalid index." This creates a world bond -// ... etc. for bondDescs[1], all other fields are filled in as usual - -// ... etc. for all bonds - -// Set the fields of the descriptor -NvBlastAssetDesc assetDesc; -assetDesc.chunkCount = chunkCount; -assetDesc.chunkDescs = chunkDescs.data(); -assetDesc.bondCount = bondCount; -assetDesc.bondDescs = bondDescs.data(); - -// Now ensure the support coverage in the chunk descriptors is exact, and the chunks are correctly ordered -std::vector<char> scratch( chunkCount * sizeof(NvBlastChunkDesc) ); // This is enough scratch for both NvBlastEnsureAssetExactSupportCoverage and NvBlastReorderAssetDescChunks -NvBlastEnsureAssetExactSupportCoverage( chunkDescs.data(), chunkCount, scratch.data(), logFn ); -std::vector<uint32_t> map(chunkCount); // Will be filled with a map from the original chunk descriptor order to the new one -NvBlastReorderAssetDescChunks( chunkDescs.data(), chunkCount, bondDescs.data(), bondCount, map, true, scratch.data(), logFn ); - -// Create the asset -scratch.resize( NvBlastGetRequiredScratchForCreateAsset( &assetDesc ) ); // Provide scratch memory for asset creation -void* mem = malloc( NvBlastGetAssetMemorySize( &assetDesc ) ); // Allocate memory for the asset object -NvBlastAsset* asset = NvBlastCreateAsset( mem, &assetDesc, scratch.data(), logFn ); -\endcode - -<br> -It should be noted that the geometric information (centroid, volume, area, normal) in chunks and bonds is only used by damage -shader functions (see \ref pageextshaders). Depending on the shader, some, all, or none of the geometric information will be needed. -The user may write damage shader functions that interpret this data in any way they wish. - -<br> -\subsection asset_copying Cloning an Asset - -To clone an asset, one only needs to copy the memory associated with the NvBlastAsset. - -\code -uint32_t assetSize = NvBlastAssetGetSize( asset ); - -NvBlastAsset* newAsset = (NvBlastAsset*)malloc(assetSize); // NOTE: the memory buffer MUST be 16-byte aligned! -memcpy( newAsset, asset, assetSize ); // this data may be copied into a buffer, stored to a file, etc. -\endcode - -N.B. the comment after the malloc call above. NvBlastAsset memory <B>must</B> be 16-byte aligned. - -<br> -\subsection asset_releasing Releasing an Asset - -Blast&tm; low-level does no internal allocation; since the memory is allocated by the user, one simply has to free the memory they've -allocated. The asset pointer returned by NvBlastCreateAsset has the same numerical value as the mem block passed in (if the function -is successful, or NULL otherwise). So releasing an asset with memory allocated by <B>malloc</B> is simply done with a call to <B>free</B>: - -\code -free( asset ); -\endcode - -<br> -\section actors_and_families Creating Actors and Families - -Actors live within a family created from asset data. To create an actor, one must first create a family. This family is used by the initial actor created from -the asset, as well as all of the descendant actors created by recursively fracturing the initial actor. As with assets, family allocation is done by the user. - -To create a family, use: - -\code -// Allocate memory for the family object - this depends on the asset being represented by the family. -void* mem = malloc( NvBlastAssetGetFamilyMemorySize( asset, logFn ) ); - -NvBlastFamily* family = NvBlastAssetCreateFamily( mem, asset, logFn ); -\endcode - -When an actor is first created from an asset, it represents the root of the chunk hierarchy, that is the unfractured object. To create this actor, use: - -\code -// Set the fields of the descriptor -NvBlastActorDesc actorDesc; -actorDesc.asset = asset; // point to a valid asset -actorDesc.initialBondHealth = 1.0f; // this health value will be given to all bonds -actorDesc.initialChunkHealth = 1.0f; // this health value will be given to all lower-support chunks - -// Provide scratch memory -std::vector<char> scratch( NvBlastFamilyGetRequiredScratchForCreateFirstActor( &actorDesc ) ); - -// Create the first actor -NvBlastActor* actor = NvBlastFamilyCreateFirstActor( family, &actorDesc, scratch.data(), logFn ); // ready to be associated with physics and graphics by the user -\endcode - -<br> -\subsection actor_copying Copying Actors (Serialization and Deserialization) - -There are two ways to copy NvBlastActors: cloning an NvBlastFamily, and single-actor serialization. Cloning an NvBlastFamily is extremely fast as it only requires -a single memory copy. All actors in the family may be saved, loaded, or copied at once in this way. - -<br> -\subsection family_serialization Cloning a Family - -To clone a family, use the family pointer which may be retrieved -from any active actor in the family if needed, using the NvBlastActorGetFamily function: - -\code -const NvBlastFamily* family = NvBlastActorGetFamily( &actor, logFn ); -\endcode - -Then the size of the family may be obtained using: - -\code -size_t size = NvBlastFamilyGetSize( family, logFn ); -\endcode - -Now this memory may be copied, saved to disk, etc. To clone the family, for example, we can duplicate the memory: - -\code -std::vector<char> buffer( size ); -NvBlastFamily* family2 = reinterpret_cast<NvBlastFamily*>( buffer.data() ); -memcpy( family2, family, size ); -\endcode - -<B>N.B.</B> If this data has been serialized from an external source, the family will not contain a valid reference to its associated asset. -The user <em>must</em> set the family's asset. The family does however contain the asset's ID, to help the user match the correct asset -to the family. So one way of restoring the asset to the family follows: - -\code -const NvBlastGUID guid = NvBlastFamilyGetAssetID( family2, logFn ); -// ... here the user must retrieve the asset using the GUID or by some other means -NvBlastFamilySetAsset( family2, asset, logFn ); -\endcode - -The data in family2 will contain the same actors as the original family. To access them, use: - -\code -uint32_t actorCount = NvBlastFamilyGetActorCount( family2, logFn ); -std::vector<NvBlastActor*> actors( actorCount ); -uint32_t actorsWritten = NvBlastFamilyGetActors( actors.data(), actorCount, family2, logFn ); -\endcode - -In the code above, actorsWritten should equal actorCount. - -<br> -\subsection single_actor_serialization Single Actor Serialization - -To perform single-actor serialization, first find the buffer size required to store the serialization data: - -\code -size_t bufferSize = NvBlastActorGetSerializationSize( actor, logFn ); -\endcode - -If you want to use an upper bound which will be large enough for any actor in a family, you may use: - -\code -size_t bufferSize = NvBlastAssetGetActorSerializationSizeUpperBound( asset, logFn ); -\endcode - -Then create a buffer of that size and use NvBlastActorSerialize to write to the buffer: - -\code -std::vector<char> buffer( bufferSize ); -size_t bytesWritten = NvBlastActorSerialize( buffer, bufferSize, actor, logFn ); -\endcode - -To deserialize the buffer, an appropriate family must be created. It must not already hold a copy of the actor. It must be formed -using the correct asset (the one that originally created the actor): - -\code -void* mem = malloc( NvBlastAssetGetFamilyMemorySize( asset, logFn ) ); -NvBlastFamily* family = NvBlastAssetCreateFamily( mem, asset, logFn ); -\endcode - -Then deserialize into the family: - -\code -NvBlastActor* newActor = NvBlastFamilyDeserializeActor( family, buffer.data(), logFn ); -\endcode - -If newActor is not NULL, then the actor was successfully deserialized. - -<br> -\section actor_deactivating Deactivating an Actor - -Actors may not be released in the usual sense of deallocation. This is because actors' memory is stored as a block within the owning family. The -memory is only released when the family is released. However, one may deactivate an actor using NvBlastActorDeactivate. -This clears the actor's chunk lists and marks it as invalid, effectively disassociating it from the family. The user should consider this actor -to be destroyed. - -\code -bool success = NvBlastActorDeactivate( actor, logFn ); -\endcode - -<br> -\subsection family_releasing Releasing a family - -As mentioned above, releasing an actor does not actually do any deallocation; it simply invalidates the actor within its family. -To actually deallocate memory, you must deallocate the family. Note, this will invalidate all actors in the family. This is -a fast way to delete all actors that were created from repeated fracturing of a single instance. As with NvBlastAsset, memory is -allocated by the user, so to release a family with memory allocated by <B>malloc</B>, simply free that memory with <B>free</B>: - -\code -free( family ); -\endcode - -The family will <em>not</em> be automatically released when all actors within it are invalidated using NvBlastActorDeactivate. However, the user may query -the number of active actors in a family using - -\code -uint32_t actorCount = NvBlastFamilyGetActorCount( family, logFn ); -\endcode - - -<br> -\section splitting Damage and Fracturing - -Damaging and fracturing is a staged process. -In a first step, a \ref NvBlastDamageProgram creates lists of Bonds and Chunks to damage - so called Fracture Commands. -The lists are created from input specific to the NvBlastDamageProgram.<br> -NvBlastDamagePrograms are composed of a \ref NvBlastGraphShaderFunction and a -\ref NvBlastSubgraphShaderFunction operating on support graphs (support chunks and bonds) and disconnected subsupport chunks respectively. -An implementer can freely define the shader functions and parameters. -Different functions can have the effect of emulating different physical materials.<br> -Blast&tm; provides reference implementations of such functions in \ref pageextshaders, see also NvBlastExtDamageShaders.h. -The NvBlastDamageProgram is used through \ref NvBlastActorGenerateFracture that will provide the necessary internal data for the NvBlastActor being processed. -The shader functions see the internal data as \ref NvBlastGraphShaderActor and \ref NvBlastSubgraphShaderActor respectively. - -The second stage is carried out with \ref NvBlastActorApplyFracture. This function takes the previously generated Fracture Commands and applies them to the NvBlastActor. -The result of every applied command is reported as a respective Fracture Event if requested. - -Fracture Commands and Fracture Events both are represented by \ref NvBlastFractureBuffers. -The splitting of the actor into child actors is not done until the third stage, \ref NvBlastActorSplit, is called. -Fractures may be repeatedly applied to an actor before splitting. - -The \ref NvBlastActorGenerateFracture, \ref NvBlastActorApplyFracture and \ref NvBlastActorSplit functions are profiled in Profile configurations. -This is done through a pointer to a NvBlastTimers struct passed into the functions. -If this pointer is not NULL, then timing values will be accumulated in the referenced struct. - -The following example illustrates the process: - -\code -// Step one: Generate Fracture Commands - -// Damage programs (shader functions), material properties and damage description relate to each other. -// Together they define how actors will break by generating the desired set of Fracture Commands for Bonds and Chunks. -NvBlastDamageProgram damageProgram = { GraphShader, SubgraphShader }; -NvBlastProgramParams programParams = { damageDescs, damageDescCount, materialProperties }; - -// Generating the set of Fracture Commands does not modify the NvBlastActor. -NvBlastActorGenerateFracture( fractureCommands, actor, damageProgram, &programParams, logFn, &timers ); - - -// Step two: Apply Fracture Commands - -// Applying Fracture Commands does modify the state of the NvBlastActor. -// The Fracture Events report the resulting state of each Bond or Chunk involved. -// Chunks fractured hard enough will also fracture their children, creating Fracture Events for each. -NvBlastActorApplyFracture( fractureEvents, actor, fractureCommands, logFn, &timers ); - - -// Step three: Splitting - -// The Actor may be split into all its smallest pieces. -uint32_t maxNewActorCount = NvBlastActorGetMaxActorCountForSplit( actor, logFn ); -std::vector<NvBlastActor*> newActors( maxNewActorCount ); - -// Make this memory available to NvBlastSplitEvent. -NvBlastActorSplitEvent splitEvent; -splitEvent.newActors = newActors.data(); - -// Some temporary memory is necessary as well. -std::vector<char> scratch( NvBlastActorGetRequiredScratchForSplit( actor, logFn ) ); - -// New actors created are reported in splitEvent.newActors. -// If newActorCount != 0, then the old actor is deleted and is reported in splitEvent.deletedActor. -size_t newActorCount = NvBlastActorSplit( &splitEvent, actor, maxNewActorCount, scratch.data(), logFn, &timers ); -\endcode - -<br> -*/ +/*! \page pagellapi Low Level API (NvBlast)
+
+<b>Table of Contents</b>
+
+\subpage llintroduction
+
+\subpage include_and_library
+
+\subpage assets
+
+\subpage actors_and_families
+
+\subpage splitting
+
+<br>
+\section llintroduction Introduction
+
+The low-level API is the core of Blast&tm; destruction. It is designed to be a minimal API that allows an experienced user to incorporate destruction
+into their application. Summarizing what the low-level API has, and <em>doesn't</em> have:
+
+- There is no physics representation. The low-level API is agnostic with respect to any physics engine, and furthermore does not have
+any notion of collision geometry. The NvBlastActor is an abstraction which is intended to correspond to a rigid body. However
+it is up to the user to implement that connection. The NvBlastActor references a list of visible chunk indices, which correspond to
+NvBlastChunk data in the asset. The NvBlastChunk contains a userData field which can be used to associate collision
+geometry with the actor based upon the visible chunks. The same is true for constraints created between actors. Bonds contain a
+userData field that can be used to inform the user that actors should have joints created at a particular location, but it is up to the
+user to create and manage physical joints between two actors.
+- There is no graphics representation. Just as there is no notion of collision geometry, there is also no notion of graphics geometry.
+The NvBlastChunk userData field (see the item above) can be used to associate graphics geometry with the actor based upon the visible chunks.
+- There is no notion of threading. The API is a collection of free functions which the user may call from appropriate threads.
+Blast&tm; guarantees that it is safe to operate on different actors from different threads.
+- There is no global memory manager, message handler, etc. All low-level API functions take an optional message function pointer argument
+in order to report warnings or errors. Memory is managed by the user, and functions that build objects require an appropriately-sized memory block
+to be passed in. A corresponding utility function that calculates the memory requirements is always present alongside such functions. Temporary
+storage needed by a function is always handled via user-supplied scratch space. For scratch, there is always a corresponding "RequiredScratch"
+function or documentation which lets the user know how much scratch space is needed based upon the function arguments.
+- Backwards-compatible, versioned, device-independent serialization is not handled by Blast&tm;. There <em>is</em> however a Blast&tm; extension
+which does, see \ref pageextserialization. However, a simple form of serialization may be performed on assets and familes (see \ref pagedefinitions)
+via simple memory copy. The data associated with these objects is available to the user, and may be copied and stored by the user.
+Simply casting a pointer to such a block of memory to the correct object type will produce a usable object for Blast&tm;. (The only restriction is
+that the block must be 16-byte aligned.) Families contain a number of actors and so this form of deserialization recreates all actors in the family.
+This form of serialization may be used between two devices which have the same endianness, and contain Blast&tm; SDKs which use the same object format.
+- Single-actor serialization and deserialization is, however, supported. This is not as light-weight as family serialization, but may be a better
+serialization model for a particular application. To deserialize a single actor, one must have a family to hold the actor, created from the appropriate
+asset. If none exists already, the user may create an empty family. After that, all actors that had been in that family may be deserialized
+into it one-at-a-time, in any order.
+
+<br>
+\section include_and_library Linking and Header Files
+
+To use the low-level Blast&tm; SDK, the application need only inlclude the header NvBlast.h, found in the top-level <b>include</b> folder, and link
+against the appropriate version of the NvBlast library. Depending on the platform and configuration, various suffixes will be added to the library
+name. The general naming scheme is
+
+NvBlast(config)(arch).(ext)
+
+(config) is DEBUG, CHECKED, OR PROFILE for the corresponding configurations. For a release configuration there is no (config) suffix.
+
+(arch) is _x86 or _x64 for Windows 32- and 64-bit builds, respectively, and empty for non-Windows platforms.
+
+(ext) is .lib for static linking and .dll for dynamic linking on Windows. On XBoxOne it is .lib, and on PS4 it is .a.
+
+<br>
+\section assets Creating an Asset from a Descriptor (Authoring)
+
+The NvBlastAsset is an opaque type pointing to an object constructed by Blast&tm; in memory allocated by the user.
+To create an asset from a descriptor, use the function \ref NvBlastCreateAsset. See the function documentation for a
+description of its parameters.
+
+<b>N.B., there are strict rules for the ordering of chunks with an asset, and also conditions on the chunks marked as "support"
+(using the NvBlastChunkDesc::SupportFlag). See the function documentation for these conditions. NvBlastCreateAsset does
+<em>not</em> reorder chunks or modify support flags to meet these conditions. If the conditions are not met, NvBlastCreateAsset
+fails and returns NULL. However, Blast&tm; provides helper functions to reorder chunk descriptors and modify the support flags
+within those descriptors so that they are valid for asset creation. The helper functions return a mapping from the original
+chunk ordering to the new chunk ordering, so that corresponding adjustments or mappings may be made for graphics and other data
+the user associates with chunks.</b>
+
+Example code is given below. Throughout, we assume the user has defined a logging function called <B>logFn</B>, with the
+signature of NvBlastLog. In all cases, the log function is optional, and NULL may be passed in its place.
+
+\code
+// Create chunk descriptors
+std::vector<NvBlastChunkDesc> chunkDescs;
+chunkDescs.resize( chunkCount ); // chunkCount > 0
+
+chunkDescs[0].parentChunkIndex = UINT32_MAX; // invalid index denotes a chunk hierarchy root
+chunkDescs[0].centroid[0] = 0.0f; // centroid position in asset-local space
+chunkDescs[0].centroid[1] = 0.0f;
+chunkDescs[0].centroid[2] = 0.0f;
+chunkDescs[0].volume = 1.0f; // Unit volume
+chunkDescs[0].flags = NvBlastChunkDesc::NoFlags;
+chunkDescs[0].userData = 0; // User-supplied ID. For example, this can be the index of the chunkDesc.
+ // The userData can be left undefined.
+
+chunkDescs[1].parentChunkIndex = 0; // child of chunk described by chunkDescs[0]
+chunkDescs[1].centroid[0] = 2.0f; // centroid position in asset-local space
+chunkDescs[1].centroid[1] = 4.0f;
+chunkDescs[1].centroid[2] = 6.0f;
+chunkDescs[1].volume = 1.0f; // Unit volume
+chunkDescs[1].flags = NvBlastChunkDesc::SupportFlag; // This chunk should be represented in the support graph
+chunkDescs[1].userData = 1;
+
+// ... etc. for all chunks
+
+// Create bond descriptors
+std::vector<NvBlastBondDesc> bondDescs;
+bondDescs.resize( bondCount ); // bondCount > 0
+
+bondDescs[0].chunkIndices[0] = 1; // chunkIndices refer to chunk descriptor indices for support chunks
+bondDescs[0].chunkIndices[1] = 2;
+bondDescs[0].bond.normal[0] = 1.0f; // normal in the +x direction
+bondDescs[0].bond.normal[1] = 0.0f;
+bondDescs[0].bond.normal[2] = 0.0f;
+bondDescs[0].bond.area = 1.0f; // unit area
+bondDescs[0].bond.centroid[0] = 1.0f; // centroid position in asset-local space
+bondDescs[0].bond.centroid[1] = 2.0f;
+bondDescs[0].bond.centroid[2] = 3.0f;
+bondDescs[0].userData = 0; // this can be used to tell the user more information about this
+ // bond for example to create a joint when this bond breaks
+
+bondDescs[1].chunkIndices[0] = 1;
+bondDescs[1].chunkIndices[1] = ~0; // ~0 (UINT32_MAX) is the "invalid index." This creates a world bond
+// ... etc. for bondDescs[1], all other fields are filled in as usual
+
+// ... etc. for all bonds
+
+// Set the fields of the descriptor
+NvBlastAssetDesc assetDesc;
+assetDesc.chunkCount = chunkCount;
+assetDesc.chunkDescs = chunkDescs.data();
+assetDesc.bondCount = bondCount;
+assetDesc.bondDescs = bondDescs.data();
+
+// Now ensure the support coverage in the chunk descriptors is exact, and the chunks are correctly ordered
+std::vector<char> scratch( chunkCount * sizeof(NvBlastChunkDesc) ); // This is enough scratch for both NvBlastEnsureAssetExactSupportCoverage and NvBlastReorderAssetDescChunks
+NvBlastEnsureAssetExactSupportCoverage( chunkDescs.data(), chunkCount, scratch.data(), logFn );
+std::vector<uint32_t> map(chunkCount); // Will be filled with a map from the original chunk descriptor order to the new one
+NvBlastReorderAssetDescChunks( chunkDescs.data(), chunkCount, bondDescs.data(), bondCount, map, true, scratch.data(), logFn );
+
+// Create the asset
+scratch.resize( NvBlastGetRequiredScratchForCreateAsset( &assetDesc ) ); // Provide scratch memory for asset creation
+void* mem = malloc( NvBlastGetAssetMemorySize( &assetDesc ) ); // Allocate memory for the asset object
+NvBlastAsset* asset = NvBlastCreateAsset( mem, &assetDesc, scratch.data(), logFn );
+\endcode
+
+<br>
+It should be noted that the geometric information (centroid, volume, area, normal) in chunks and bonds is only used by damage
+shader functions (see \ref pageextshaders). Depending on the shader, some, all, or none of the geometric information will be needed.
+The user may write damage shader functions that interpret this data in any way they wish.
+
+<br>
+\subsection asset_copying Cloning an Asset
+
+To clone an asset, one only needs to copy the memory associated with the NvBlastAsset.
+
+\code
+uint32_t assetSize = NvBlastAssetGetSize( asset );
+
+NvBlastAsset* newAsset = (NvBlastAsset*)malloc(assetSize); // NOTE: the memory buffer MUST be 16-byte aligned!
+memcpy( newAsset, asset, assetSize ); // this data may be copied into a buffer, stored to a file, etc.
+\endcode
+
+N.B. the comment after the malloc call above. NvBlastAsset memory <B>must</B> be 16-byte aligned.
+
+<br>
+\subsection asset_releasing Releasing an Asset
+
+Blast&tm; low-level does no internal allocation; since the memory is allocated by the user, one simply has to free the memory they've
+allocated. The asset pointer returned by NvBlastCreateAsset has the same numerical value as the mem block passed in (if the function
+is successful, or NULL otherwise). So releasing an asset with memory allocated by <B>malloc</B> is simply done with a call to <B>free</B>:
+
+\code
+free( asset );
+\endcode
+
+<br>
+\section actors_and_families Creating Actors and Families
+
+Actors live within a family created from asset data. To create an actor, one must first create a family. This family is used by the initial actor created from
+the asset, as well as all of the descendant actors created by recursively fracturing the initial actor. As with assets, family allocation is done by the user.
+
+To create a family, use:
+
+\code
+// Allocate memory for the family object - this depends on the asset being represented by the family.
+void* mem = malloc( NvBlastAssetGetFamilyMemorySize( asset, logFn ) );
+
+NvBlastFamily* family = NvBlastAssetCreateFamily( mem, asset, logFn );
+\endcode
+
+When an actor is first created from an asset, it represents the root of the chunk hierarchy, that is the unfractured object. To create this actor, use:
+
+\code
+// Set the fields of the descriptor
+NvBlastActorDesc actorDesc;
+actorDesc.asset = asset; // point to a valid asset
+actorDesc.initialBondHealth = 1.0f; // this health value will be given to all bonds
+actorDesc.initialChunkHealth = 1.0f; // this health value will be given to all lower-support chunks
+
+// Provide scratch memory
+std::vector<char> scratch( NvBlastFamilyGetRequiredScratchForCreateFirstActor( &actorDesc ) );
+
+// Create the first actor
+NvBlastActor* actor = NvBlastFamilyCreateFirstActor( family, &actorDesc, scratch.data(), logFn ); // ready to be associated with physics and graphics by the user
+\endcode
+
+<br>
+\subsection actor_copying Copying Actors (Serialization and Deserialization)
+
+There are two ways to copy NvBlastActors: cloning an NvBlastFamily, and single-actor serialization. Cloning an NvBlastFamily is extremely fast as it only requires
+a single memory copy. All actors in the family may be saved, loaded, or copied at once in this way.
+
+<br>
+\subsection family_serialization Cloning a Family
+
+To clone a family, use the family pointer which may be retrieved
+from any active actor in the family if needed, using the NvBlastActorGetFamily function:
+
+\code
+const NvBlastFamily* family = NvBlastActorGetFamily( &actor, logFn );
+\endcode
+
+Then the size of the family may be obtained using:
+
+\code
+size_t size = NvBlastFamilyGetSize( family, logFn );
+\endcode
+
+Now this memory may be copied, saved to disk, etc. To clone the family, for example, we can duplicate the memory:
+
+\code
+std::vector<char> buffer( size );
+NvBlastFamily* family2 = reinterpret_cast<NvBlastFamily*>( buffer.data() );
+memcpy( family2, family, size );
+\endcode
+
+<B>N.B.</B> If this data has been serialized from an external source, the family will not contain a valid reference to its associated asset.
+The user <em>must</em> set the family's asset. The family does however contain the asset's ID, to help the user match the correct asset
+to the family. So one way of restoring the asset to the family follows:
+
+\code
+const NvBlastGUID guid = NvBlastFamilyGetAssetID( family2, logFn );
+// ... here the user must retrieve the asset using the GUID or by some other means
+NvBlastFamilySetAsset( family2, asset, logFn );
+\endcode
+
+The data in family2 will contain the same actors as the original family. To access them, use:
+
+\code
+uint32_t actorCount = NvBlastFamilyGetActorCount( family2, logFn );
+std::vector<NvBlastActor*> actors( actorCount );
+uint32_t actorsWritten = NvBlastFamilyGetActors( actors.data(), actorCount, family2, logFn );
+\endcode
+
+In the code above, actorsWritten should equal actorCount.
+
+<br>
+\subsection single_actor_serialization Single Actor Serialization
+
+To perform single-actor serialization, first find the buffer size required to store the serialization data:
+
+\code
+size_t bufferSize = NvBlastActorGetSerializationSize( actor, logFn );
+\endcode
+
+If you want to use an upper bound which will be large enough for any actor in a family, you may use:
+
+\code
+size_t bufferSize = NvBlastAssetGetActorSerializationSizeUpperBound( asset, logFn );
+\endcode
+
+Then create a buffer of that size and use NvBlastActorSerialize to write to the buffer:
+
+\code
+std::vector<char> buffer( bufferSize );
+size_t bytesWritten = NvBlastActorSerialize( buffer, bufferSize, actor, logFn );
+\endcode
+
+To deserialize the buffer, an appropriate family must be created. It must not already hold a copy of the actor. It must be formed
+using the correct asset (the one that originally created the actor):
+
+\code
+void* mem = malloc( NvBlastAssetGetFamilyMemorySize( asset, logFn ) );
+NvBlastFamily* family = NvBlastAssetCreateFamily( mem, asset, logFn );
+\endcode
+
+Then deserialize into the family:
+
+\code
+NvBlastActor* newActor = NvBlastFamilyDeserializeActor( family, buffer.data(), logFn );
+\endcode
+
+If newActor is not NULL, then the actor was successfully deserialized.
+
+<br>
+\section actor_deactivating Deactivating an Actor
+
+Actors may not be released in the usual sense of deallocation. This is because actors' memory is stored as a block within the owning family. The
+memory is only released when the family is released. However, one may deactivate an actor using NvBlastActorDeactivate.
+This clears the actor's chunk lists and marks it as invalid, effectively disassociating it from the family. The user should consider this actor
+to be destroyed.
+
+\code
+bool success = NvBlastActorDeactivate( actor, logFn );
+\endcode
+
+<br>
+\subsection family_releasing Releasing a family
+
+As mentioned above, releasing an actor does not actually do any deallocation; it simply invalidates the actor within its family.
+To actually deallocate memory, you must deallocate the family. Note, this will invalidate all actors in the family. This is
+a fast way to delete all actors that were created from repeated fracturing of a single instance. As with NvBlastAsset, memory is
+allocated by the user, so to release a family with memory allocated by <B>malloc</B>, simply free that memory with <B>free</B>:
+
+\code
+free( family );
+\endcode
+
+The family will <em>not</em> be automatically released when all actors within it are invalidated using NvBlastActorDeactivate. However, the user may query
+the number of active actors in a family using
+
+\code
+uint32_t actorCount = NvBlastFamilyGetActorCount( family, logFn );
+\endcode
+
+
+<br>
+\section splitting Damage and Fracturing
+
+Damaging and fracturing is a staged process.
+In a first step, a \ref NvBlastDamageProgram creates lists of Bonds and Chunks to damage - so called Fracture Commands.
+The lists are created from input specific to the NvBlastDamageProgram.<br>
+NvBlastDamagePrograms are composed of a \ref NvBlastGraphShaderFunction and a
+\ref NvBlastSubgraphShaderFunction operating on support graphs (support chunks and bonds) and disconnected subsupport chunks respectively.
+An implementer can freely define the shader functions and parameters.
+Different functions can have the effect of emulating different physical materials.<br>
+Blast&tm; provides reference implementations of such functions in \ref pageextshaders, see also NvBlastExtDamageShaders.h.
+The NvBlastDamageProgram is used through \ref NvBlastActorGenerateFracture that will provide the necessary internal data for the NvBlastActor being processed.
+The shader functions see the internal data as \ref NvBlastGraphShaderActor and \ref NvBlastSubgraphShaderActor respectively.
+
+The second stage is carried out with \ref NvBlastActorApplyFracture. This function takes the previously generated Fracture Commands and applies them to the NvBlastActor.
+The result of every applied command is reported as a respective Fracture Event if requested.
+
+Fracture Commands and Fracture Events both are represented by \ref NvBlastFractureBuffers.
+The splitting of the actor into child actors is not done until the third stage, \ref NvBlastActorSplit, is called.
+Fractures may be repeatedly applied to an actor before splitting.
+
+The \ref NvBlastActorGenerateFracture, \ref NvBlastActorApplyFracture and \ref NvBlastActorSplit functions are profiled in Profile configurations.
+This is done through a pointer to a NvBlastTimers struct passed into the functions.
+If this pointer is not NULL, then timing values will be accumulated in the referenced struct.
+
+The following example illustrates the process:
+
+\code
+// Step one: Generate Fracture Commands
+
+// Damage programs (shader functions), material properties and damage description relate to each other.
+// Together they define how actors will break by generating the desired set of Fracture Commands for Bonds and Chunks.
+NvBlastDamageProgram damageProgram = { GraphShader, SubgraphShader };
+NvBlastProgramParams programParams = { damageDescs, damageDescCount, materialProperties };
+
+// Generating the set of Fracture Commands does not modify the NvBlastActor.
+NvBlastActorGenerateFracture( fractureCommands, actor, damageProgram, &programParams, logFn, &timers );
+
+
+// Step two: Apply Fracture Commands
+
+// Applying Fracture Commands does modify the state of the NvBlastActor.
+// The Fracture Events report the resulting state of each Bond or Chunk involved.
+// Chunks fractured hard enough will also fracture their children, creating Fracture Events for each.
+NvBlastActorApplyFracture( fractureEvents, actor, fractureCommands, logFn, &timers );
+
+
+// Step three: Splitting
+
+// The Actor may be split into all its smallest pieces.
+uint32_t maxNewActorCount = NvBlastActorGetMaxActorCountForSplit( actor, logFn );
+std::vector<NvBlastActor*> newActors( maxNewActorCount );
+
+// Make this memory available to NvBlastSplitEvent.
+NvBlastActorSplitEvent splitEvent;
+splitEvent.newActors = newActors.data();
+
+// Some temporary memory is necessary as well.
+std::vector<char> scratch( NvBlastActorGetRequiredScratchForSplit( actor, logFn ) );
+
+// New actors created are reported in splitEvent.newActors.
+// If newActorCount != 0, then the old actor is deleted and is reported in splitEvent.deletedActor.
+size_t newActorCount = NvBlastActorSplit( &splitEvent, actor, maxNewActorCount, scratch.data(), logFn, &timers );
+\endcode
+
+<br>
+*/
diff --git a/docs/_source/api_users_guide.txt b/docs/_source/api_users_guide.txt index c3d2f83..fddbccb 100644..100755 --- a/docs/_source/api_users_guide.txt +++ b/docs/_source/api_users_guide.txt @@ -1,24 +1,24 @@ -/*! \page pageusersguide User's Guide - -Blast&tm; User's Guide - -\subpage pageintroduction - -\subpage pagellapi - -\subpage pageglobalsapi - -\subpage pagehlapi - -\subpage pageextapi - -\subpage pagetools - -\subpage pagesamples - -\subpage pagedefinitions - -\subpage pagecopyrights - -<br> -*/ +/*! \page pageusersguide User's Guide
+
+Blast&tm; User's Guide
+
+\subpage pageintroduction
+
+\subpage pagellapi
+
+\subpage pageglobalsapi
+
+\subpage pagehlapi
+
+\subpage pageextapi
+
+\subpage pagetools
+
+\subpage pagesamples
+
+\subpage pagedefinitions
+
+\subpage pagecopyrights
+
+<br>
+*/
diff --git a/docs/_source/authoring_tool.txt b/docs/_source/authoring_tool.txt index de780ff..cfa6145 100644..100755 --- a/docs/_source/authoring_tool.txt +++ b/docs/_source/authoring_tool.txt @@ -1,120 +1,122 @@ -/*! \page pageauthoring AuthoringTool - -The application <b>AuthoringTool</b> is a command-line asset authoring utility. It reads a file containing a single graphics mesh -(currently .fbx and .obj format are supported in this tool), and fractures it according to the parameters given in the command line. -The user can configure the output of the tool. It can save render mesh geometry to .fbx or .obj files. It also optionally could save -collision geometry in the same .fbx file. - -Additionally, the user can choose how Blast&tm; data should be saved (in .blast file): - - 1) LL-asset which is Low Level asset data (NvBlastAsset). Default mode. - - 2) Tk-asset which is Toolkit asset data (Nv::Blast::TkAsset). - - 3) ExtPx-asset which incorporates Blast&tm; data and collision geometry for physics engine (Nv::Blast::ExtPxAsset). - -.blast and .obj files may be consumed by the \ref pagesampleassetviewer. - - -\verbatim - - - -USAGE: - - AuthoringTool_x64.exe [--ovar <by default - 0.0>] [--avar <by default 0.0>] - [--slices <by default 1 1 1>] - [--radius <by default 1.0>] - [--clusters <by default 5>] - [--cells <by default 5>] [--mode <v - - voronoi, c - clustered voronoi, s - - slicing.>] [--nonskinned] - [--fbxcollision] [--fbx] [--obj] - [--fbxascii] [--tk] [--px] - [--clean] [--outputDir <by default - directory of the input file>] [--] - [--version] [-h] <infile> <output - asset name> - - -Where: - - --ovar <by default 0.0> - Slicing offset variation - - --avar <by default 0.0> - Slicing angle variation - - --slices <by default 1 1 1> - Number of slices per direction - - --radius <by default 1.0> - Clustered Voronoi cluster radius - - --clusters <by default 5> - Uniform Voronoi cluster count - - --cells <by default 5> - Voronoi cells count - - --mode <v - voronoi, c - clustered voronoi, s - slicing.> - Fracturing mode - - --nonskinned - Output a non-skinned FBX file - - --fbxcollision - Add collision geometry to FBX file - - --fbx - Output a FBX mesh to the output directory - - --obj - Output a OBJ mesh to the output directory - - --fbxascii - Output FBX as an ascii file (defaults to binary output) - - --tk - Output TkAsset to the .blast file in the output directory instead of - LL Blast asset (NvBlastAsset). - - --px - Output ExtPxAsset to the .blast file in the output directory instead - of LL Blast asset (NvBlastAsset). - - --clean - Try cleaning mesh before fracturing - - --outputDir <by default directory of the input file> - Output directory - - --, --ignore_rest - Ignores the rest of the labeled arguments following this flag. - - --version - Displays version information and exits. - - -h, --help - Displays usage information and exits. - - <infile> - (required) File to load - - <output asset name> - (required) Output asset name - - - Blast SDK: Authoring Tool - - - - -\endverbatim - -<br> -See \ref pagecopyrights for license information regarding third-party software used by ApexImporter. - -<br> -*/ +/*! \page pageauthoring AuthoringTool
+
+The application <b>AuthoringTool</b> is a command-line asset authoring utility. It reads a file containing a single graphics mesh
+(currently .fbx and .obj format are supported in this tool), and fractures it according to the parameters given in the command line.
+The user can configure the output of the tool. It can save render mesh geometry to .fbx or .obj files. It also optionally could save
+collision geometry in the same .fbx file.
+
+Additionally, the user can choose how Blast&tm; data should be saved (in .blast file):
+
+ 1) LL-asset which is Low Level asset data (NvBlastAsset). Default mode.
+
+ 2) Tk-asset which is Toolkit asset data (Nv::Blast::TkAsset).
+
+ 3) ExtPx-asset which incorporates Blast&tm; data and collision geometry for physics engine (Nv::Blast::ExtPxAsset).
+
+.blast and .obj files may be consumed by the \ref pagesampleassetviewer.
+
+This tool uses the Authoring Tools Extension (\ref pageextauthoring). Therefore the restrictions on the input mesh are those of the authoring tools, see \ref fracturemeshrestrictions.
+
+
+\verbatim
+
+
+
+USAGE:
+
+ AuthoringTool_x64.exe [--ovar <by default
+ 0.0>] [--avar <by default 0.0>]
+ [--slices <by default 1 1 1>]
+ [--radius <by default 1.0>]
+ [--clusters <by default 5>]
+ [--cells <by default 5>] [--mode <v
+ - voronoi, c - clustered voronoi, s
+ - slicing.>] [--nonskinned]
+ [--fbxcollision] [--fbx] [--obj]
+ [--fbxascii] [--tk] [--px]
+ [--clean] [--outputDir <by default
+ directory of the input file>] [--]
+ [--version] [-h] <infile> <output
+ asset name>
+
+
+Where:
+
+ --ovar <by default 0.0>
+ Slicing offset variation
+
+ --avar <by default 0.0>
+ Slicing angle variation
+
+ --slices <by default 1 1 1>
+ Number of slices per direction
+
+ --radius <by default 1.0>
+ Clustered Voronoi cluster radius
+
+ --clusters <by default 5>
+ Uniform Voronoi cluster count
+
+ --cells <by default 5>
+ Voronoi cells count
+
+ --mode <v - voronoi, c - clustered voronoi, s - slicing.>
+ Fracturing mode
+
+ --nonskinned
+ Output a non-skinned FBX file
+
+ --fbxcollision
+ Add collision geometry to FBX file
+
+ --fbx
+ Output a FBX mesh to the output directory
+
+ --obj
+ Output a OBJ mesh to the output directory
+
+ --fbxascii
+ Output FBX as an ascii file (defaults to binary output)
+
+ --tk
+ Output TkAsset to the .blast file in the output directory instead of
+ LL Blast asset (NvBlastAsset).
+
+ --px
+ Output ExtPxAsset to the .blast file in the output directory instead
+ of LL Blast asset (NvBlastAsset).
+
+ --clean
+ Try cleaning mesh before fracturing
+
+ --outputDir <by default directory of the input file>
+ Output directory
+
+ --, --ignore_rest
+ Ignores the rest of the labeled arguments following this flag.
+
+ --version
+ Displays version information and exits.
+
+ -h, --help
+ Displays usage information and exits.
+
+ <infile>
+ (required) File to load
+
+ <output asset name>
+ (required) Output asset name
+
+
+ Blast SDK: Authoring Tool
+
+
+
+
+\endverbatim
+
+<br>
+See \ref pagecopyrights for license information regarding third-party software used by ApexImporter.
+
+<br>
+*/
diff --git a/docs/_source/copyrights.txt b/docs/_source/copyrights.txt index e279469..207c26f 100644..100755 --- a/docs/_source/copyrights.txt +++ b/docs/_source/copyrights.txt @@ -1,100 +1,100 @@ -/*! \page pagecopyrights Copyrights - -\section tinyobjloader TinyObjLoader - -Blast&tm; \ref pagesamples and the tool \ref pageimporter use TinyObjLoader by Syoyo Fudita. This is licensed under the 2-clause BSD, given below. - -\verbatim -Copyright (c) 2012-2015, Syoyo Fujita -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -\endverbatim - -<br> -\section boost Boost - -Blast&tm; \ref pageextauthoring uses Boost (boost.org). This is licensed as follows. - -\verbatim -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. -\endverbatim - -<br> -\section vhacd V-HACD - -Blast&tm; \ref pageextauthoring uses V-HACD (by Khaled Mamou). This is licensed as follows. - -\verbatim -Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com) -All rights reserved. - - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, -this list of conditions and the following disclaimer in the documentation -and/or other materials provided with the distribution. - -3. The names of the contributors may not be used to endorse or promote -products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -\endverbatim - -<br> -*/ +/*! \page pagecopyrights Copyrights
+
+\section tinyobjloader TinyObjLoader
+
+Blast&tm; \ref pagesamples and the tool \ref pageimporter use TinyObjLoader by Syoyo Fudita. This is licensed under the 2-clause BSD, given below.
+
+\verbatim
+Copyright (c) 2012-2015, Syoyo Fujita
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\endverbatim
+
+<br>
+\section boost Boost
+
+Blast&tm; \ref pageextauthoring uses Boost (boost.org). This is licensed as follows.
+
+\verbatim
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+\endverbatim
+
+<br>
+\section vhacd V-HACD
+
+Blast&tm; \ref pageextauthoring uses V-HACD (by Khaled Mamou). This is licensed as follows.
+
+\verbatim
+Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
+All rights reserved.
+
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+
+3. The names of the contributors may not be used to endorse or promote
+products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+\endverbatim
+
+<br>
+*/
diff --git a/docs/_source/definitions.txt b/docs/_source/definitions.txt index d73c310..1ff2973 100644..100755 --- a/docs/_source/definitions.txt +++ b/docs/_source/definitions.txt @@ -1,14 +1,14 @@ -/*! \page pagedefinitions Definitions - -- <b>exact coverage</b>: the condition that a walk from any leaf chunk to its ancestor root chunk will always encounter exactly one support chunk -- <b>family</b>: the memory allocated when an asset is instanced into its initial set of actors, and all descendant actors formed from fracturing the initial set, recursively -- <b>root chunk</b>: a chunk with no parent -- <b>leaf chunk</b>: a chunk with no children -- <b>lower-support chunk</b>: a chunk that is either a support or subsupport chunk -- <b>subsupport chunk</b>: a chunk that is descended from a support chunk -- <b>supersupport chunk</b>: a chunk that is the ancestor of a support chunk -- <b>support chunk</b>: a chunk that is represented in the support graph -- <b>upper-support chunk</b>: a chunk that is either a support or supersupport chunk - -<br> -*/ +/*! \page pagedefinitions Definitions
+
+- <b>exact coverage</b>: the condition that a walk from any leaf chunk to its ancestor root chunk will always encounter exactly one support chunk
+- <b>family</b>: the memory allocated when an asset is instanced into its initial set of actors, and all descendant actors formed from fracturing the initial set, recursively
+- <b>root chunk</b>: a chunk with no parent
+- <b>leaf chunk</b>: a chunk with no children
+- <b>lower-support chunk</b>: a chunk that is either a support or subsupport chunk
+- <b>subsupport chunk</b>: a chunk that is descended from a support chunk
+- <b>supersupport chunk</b>: a chunk that is the ancestor of a support chunk
+- <b>support chunk</b>: a chunk that is represented in the support graph
+- <b>upper-support chunk</b>: a chunk that is either a support or supersupport chunk
+
+<br>
+*/
diff --git a/docs/_source/ext_assetutils.txt b/docs/_source/ext_assetutils.txt index 383f791..b0e7831 100644..100755 --- a/docs/_source/ext_assetutils.txt +++ b/docs/_source/ext_assetutils.txt @@ -1,94 +1,94 @@ -/*! \page pageextassetutils Asset Utilities (NvBlastExtAssetUtils) - -NvBlastExtAssetUtils provides simple utility functions for modifying NvBlastAsset objects. Three functions are provided, described in the following sections. - -<br> -\section addworldbonds Add World Bonds - -The function NvBlastExtAssetUtilsAddWorldBonds allows the user to create an asset from an existing asset, with the addition of new bonds that connect -support chunks to the world. (See the documentation for NvBlastBondDesc.) - -For example, given an asset called <em>oldAsset</em>, - -\code -const uint32_t worldBoundChunks[3] = { 1, 2, 3 }; // Chunks to bind to the world. These must be support chunks. -const NvcVec3 bondDirections[3] = { { -1, 0, 1 }, { 0, 0, -1}, { 1, 0, 0 } }; // Normal directions for the new bonds. - -// Create a new asset -NvBlastAsset* newAsset = NvBlastExtAssetUtilsAddWorldBonds(oldAsset, worldBoundChunks, 3, bondDirections, NULL); -\endcode - -Memory for the new asset is allocated using the allocator available through NvBlastGlobals (\ref pageglobalsapi). Therefore the new asset may be freed using - -\code -NVBLAST_FREE(newAsset); -\endcode - -<br> -\section mergeassets Merge Assets - -The NvBlastExtAssetUtilsMergeAssets function will combine any number of assets, generating an asset descriptor which may be passed to NvBlastCreateAsset. This -is done in order to allow the user to make adjustments to the descriptor before creating the merged asset. - -The geometric data in each asset to be merged may be transformed so that the assets will have desired relative poses. In addition, the user may describe new -bonds, in order to join support chunks of two different assets and create a larger support graph which spans the entire combined asset. The reference frame for -the new bonds' geometric data is that of the new asset. - -For example, if one wants to merge two wall assets together, with a relative translation between them of 10 units in the x-direction, the code might look something like this: - -\code -const NvBlastAsset* components[2] = { asset0, asset1 }; // asset0 and asset1 are already created -const NvcVec3 translations[2] = { { -5, 0, 0 }, { 5, 0, 0 } }; // Translate asset0 -5 in x, and asset1 +5 in x - -// New bonds: -const uint32_t newBondCount = ... // Some number of new bonds -const NvBlastExtAssetUtilsBondDesc newBondDescs[newBondCount]; -newBondDesc[0].bond.normal.x = 1; // Normal in the +x direction, pointing from asset0 to asset1 -newBondDesc[0].bond.normal.y = 0; -newBondDesc[0].bond.normal.z = 0; -newBondDesc[0].bond.area = 1; -newBondDesc[0].bond.centroid.x = 0; -newBondDesc[0].bond.centroid.y = 0; -newBondDesc[0].bond.centroid.z = 2.5; // Position is in the middle, off the ground -newBondDesc[0].bond.userData = 0; -newBondDesc[0].chunkIndices[0] = 5; // Connect from chunk[5] in components[componentIndices[0]] -newBondDesc[0].chunkIndices[1] = 13; // .. to chunk[13] in components[componentIndices[1]] -newBondDesc[0].componentIndices[0] = 0; // Connect asset in components[0] -newBondDesc[0].componentIndices[1] = 1; // .. to the asset in components[1] - -// Create merged asset descriptor -NvBlastAssetDesc mergedDesc = NvBlastExtAssetUtilsMergeAssets(components, NULL, translations, 2, newBondDescs, newBondCount); -\endcode - -Note, we passed in NULL for the list of relative rotations, meaning no asset will be rotated. - -Also note, the new bond descriptors can just as well apply to a single asset (by setting both component indices to the same index), allowing the user to create additional bonds within -a single asset if desired. - -The chunk and bond arrays referenced by the returned NvBlastAssetDesc are allocated using the NvBlastGlobals allocator, and it is up to the user to free this memory when it is no -longer needed: - -\code -NVBLAST_FREE(mergedDesc.chunkDescs); -NVBLAST_FREE(mergedDesc.bondDescs); -\endcode - -<br> -\section transforminplace Transform In-Place - -The NvBlastExtAssetTransformInPlace function will apply an affine transformation (given by scaling, rotation, translation components) to the geometric data within an asset. - -To use this function, simply pass in an NvcVec3 pointer to represent scale (which may be non-uniform), an NvcQuat pointer to represent rotation, and an NvcVec3 pointer to -represent translation. Any of these pointers may be NULL, in which case that transform component is implicitly considered to be the identity. This transforms: - -- Chunk centroids -- Chunk volumes -- Bond normals -- Bond areas -- Bond centroids - -The transformation of position vectors is done in the following order: scale, followed by rotation, followed by translation. - -The transformation of normal vectors uses the cofactors of the scale matrix (diagonals given by {scale.y*scale.z, scale.z*scale.x, scale.x*scale.y}), followed by rotation. -<br> -*/ +/*! \page pageextassetutils Asset Utilities (NvBlastExtAssetUtils)
+
+NvBlastExtAssetUtils provides simple utility functions for modifying NvBlastAsset objects. Three functions are provided, described in the following sections.
+
+<br>
+\section addworldbonds Add World Bonds
+
+The function NvBlastExtAssetUtilsAddWorldBonds allows the user to create an asset from an existing asset, with the addition of new bonds that connect
+support chunks to the world. (See the documentation for NvBlastBondDesc.)
+
+For example, given an asset called <em>oldAsset</em>,
+
+\code
+const uint32_t worldBoundChunks[3] = { 1, 2, 3 }; // Chunks to bind to the world. These must be support chunks.
+const NvcVec3 bondDirections[3] = { { -1, 0, 1 }, { 0, 0, -1}, { 1, 0, 0 } }; // Normal directions for the new bonds.
+
+// Create a new asset
+NvBlastAsset* newAsset = NvBlastExtAssetUtilsAddWorldBonds(oldAsset, worldBoundChunks, 3, bondDirections, NULL);
+\endcode
+
+Memory for the new asset is allocated using the allocator available through NvBlastGlobals (\ref pageglobalsapi). Therefore the new asset may be freed using
+
+\code
+NVBLAST_FREE(newAsset);
+\endcode
+
+<br>
+\section mergeassets Merge Assets
+
+The NvBlastExtAssetUtilsMergeAssets function will combine any number of assets, generating an asset descriptor which may be passed to NvBlastCreateAsset. This
+is done in order to allow the user to make adjustments to the descriptor before creating the merged asset.
+
+The geometric data in each asset to be merged may be transformed so that the assets will have desired relative poses. In addition, the user may describe new
+bonds, in order to join support chunks of two different assets and create a larger support graph which spans the entire combined asset. The reference frame for
+the new bonds' geometric data is that of the new asset.
+
+For example, if one wants to merge two wall assets together, with a relative translation between them of 10 units in the x-direction, the code might look something like this:
+
+\code
+const NvBlastAsset* components[2] = { asset0, asset1 }; // asset0 and asset1 are already created
+const NvcVec3 translations[2] = { { -5, 0, 0 }, { 5, 0, 0 } }; // Translate asset0 -5 in x, and asset1 +5 in x
+
+// New bonds:
+const uint32_t newBondCount = ... // Some number of new bonds
+const NvBlastExtAssetUtilsBondDesc newBondDescs[newBondCount];
+newBondDesc[0].bond.normal.x = 1; // Normal in the +x direction, pointing from asset0 to asset1
+newBondDesc[0].bond.normal.y = 0;
+newBondDesc[0].bond.normal.z = 0;
+newBondDesc[0].bond.area = 1;
+newBondDesc[0].bond.centroid.x = 0;
+newBondDesc[0].bond.centroid.y = 0;
+newBondDesc[0].bond.centroid.z = 2.5; // Position is in the middle, off the ground
+newBondDesc[0].bond.userData = 0;
+newBondDesc[0].chunkIndices[0] = 5; // Connect from chunk[5] in components[componentIndices[0]]
+newBondDesc[0].chunkIndices[1] = 13; // .. to chunk[13] in components[componentIndices[1]]
+newBondDesc[0].componentIndices[0] = 0; // Connect asset in components[0]
+newBondDesc[0].componentIndices[1] = 1; // .. to the asset in components[1]
+
+// Create merged asset descriptor
+NvBlastAssetDesc mergedDesc = NvBlastExtAssetUtilsMergeAssets(components, NULL, translations, 2, newBondDescs, newBondCount);
+\endcode
+
+Note, we passed in NULL for the list of relative rotations, meaning no asset will be rotated.
+
+Also note, the new bond descriptors can just as well apply to a single asset (by setting both component indices to the same index), allowing the user to create additional bonds within
+a single asset if desired.
+
+The chunk and bond arrays referenced by the returned NvBlastAssetDesc are allocated using the NvBlastGlobals allocator, and it is up to the user to free this memory when it is no
+longer needed:
+
+\code
+NVBLAST_FREE(mergedDesc.chunkDescs);
+NVBLAST_FREE(mergedDesc.bondDescs);
+\endcode
+
+<br>
+\section transforminplace Transform In-Place
+
+The NvBlastExtAssetTransformInPlace function will apply an affine transformation (given by scaling, rotation, translation components) to the geometric data within an asset.
+
+To use this function, simply pass in an NvcVec3 pointer to represent scale (which may be non-uniform), an NvcQuat pointer to represent rotation, and an NvcVec3 pointer to
+represent translation. Any of these pointers may be NULL, in which case that transform component is implicitly considered to be the identity. This transforms:
+
+- Chunk centroids
+- Chunk volumes
+- Bond normals
+- Bond areas
+- Bond centroids
+
+The transformation of position vectors is done in the following order: scale, followed by rotation, followed by translation.
+
+The transformation of normal vectors uses the cofactors of the scale matrix (diagonals given by {scale.y*scale.z, scale.z*scale.x, scale.x*scale.y}), followed by rotation.
+<br>
+*/
diff --git a/docs/_source/ext_authoring.txt b/docs/_source/ext_authoring.txt index cc058d4..2105eaf 100644..100755 --- a/docs/_source/ext_authoring.txt +++ b/docs/_source/ext_authoring.txt @@ -1,71 +1,84 @@ -/*! \page pageextauthoring Asset Authoring (NvBlastExtAuthoring) - -The Authoring extension provides tools for creation of a Blast&tm; asset from a provided mesh. - -There are four tools for creation of Blast&tm; assets. - - -<br> -\section fracturetool FractureTool - -Nv::Blast::FractureTool (see NvBlastExtAuthoringFractureTool.h) is used to fracture an input mesh. It supports Voronoi fracturing and also simple slicing. Internal surfaces of output chunks can be tesselated and noise can be applied to them. The slicing method supports slicing with a noisy slicing surface, which allows the creation of a jagged slicing line. Noisy slicing is switched on by setting a non-zero noise amplitude in slicing parameters (Nv::Blast::SlicingConfiguration). - - -FractureTool supports two types of output: - -1) Array of triangles - the tool fills provided array with triangles of chunk, ID of chunk should be provided. - -2) Buffered output - the tool fills provided array with vertices, and another array of arrays with indices. Indices form triplets of vertices of triangle. - -<br> -\section convexmeshbuilder ConvexMeshBuilder - -Nv::Blast::ConvexMeshBuilder is a tool for creation of collision geometry for physics engine. It recieves mesh vertices, and returns the convex hull of those vertices. If creation of a convex hull fails, the -tool creates collision geometry as a bounding box of provided vertices. - -The tool provides a method to trim convex hulls against each other. It can be used along with noisy slicing to avoid "explosive" behavior due to penetration of neighboring collision hulls into each other. -As a drawback, penetration of render meshes into each other is possible due to trimmed collision geometry. - -<br> -\section bondgenerator BondGenerator - -Nv::Blast::BlastBondGenerator is a tool for creation of Blast&tm; Bond descriptors from provided geometry data. -It has separate a method which is optimized for working FractureTool. -\code -int32_t Nv::Blast::BlastBondGenerator::buildDescFromInternalFracture(FractureTool* tool, const std::vector<bool>& chunkIsSupport, std::vector<NvBlastBondDesc>& resultBondDescs, std::vector<NvBlastChunkDesc>& resultChunkDescriptors); -\endcode - -Other methods can work with prefractured meshes created in Third party tools, and can be used for converting prefractured models to Blast&tm; assets. - -Nv::Blast::BlastBondGenerator supports two modes of NvBlastBond data generation: - -1) Exact - in this mode exact common surface between chunks is found and considered as interface between them. Exact normal, area and centroid are computed. - -2) Average - this mode uses approximations of the interface, and can be used for gathering NvBlastBond data for assets, where chunks penetrate each other, e.g. chunks with noise. - -<br> -\section meshcleaner MeshCleaner - -Nv::Blast::MeshCleaner can be used to remove self intersections and open edges in the interior of a mesh, making it more likely to fracture well. - -To use it, create a MeshCleaner using - -\code -Nv::Blast::MeshCleaner* cleaner = NvBlastExtAuthoringCreateMeshCleaner(); -\endcode - -Given an Nv::Blast::Mesh called "mesh", simply call - -\code -Nv::Blast::Mesh* newMesh = cleaner->cleanMesh(mesh); -\endcode - -If successful, newMesh will be a valid pointer to the cleaned mesh. Otherwise, newMesh will be NULL. - -When done, release using -\code -cleaner->release(); -\endcode - -<br> -*/ +/*! \page pageextauthoring Asset Authoring (NvBlastExtAuthoring)
+
+The Authoring extension provides tools for creation of a Blast&tm; asset from a provided mesh.
+
+There are four tools for creation of Blast&tm; assets.
+
+
+<br>
+\section fracturetool FractureTool
+
+Nv::Blast::FractureTool (see NvBlastExtAuthoringFractureTool.h) is used to fracture an input mesh. It supports Voronoi fracturing, slicing, and "cutout" fracture (slicing based upon an image). Internal surfaces of output chunks can be tesselated and noise can be applied to them. The slicing method supports slicing with a noisy slicing surface, which allows the creation of a jagged slicing line. Noisy slicing is switched on by setting a non-zero noise amplitude in slicing parameters (Nv::Blast::SlicingConfiguration).
+
+FractureTool supports two types of output:
+
+1) Array of triangles - the tool fills provided array with triangles of chunk, ID of chunk should be provided.
+
+2) Buffered output - the tool fills provided array with vertices, and another array of arrays with indices. Indices form triplets of vertices of triangle.
+
+<br>
+\section fracturemeshrestrictions Mesh Restrictions
+
+At the core of the fracturing tools is a geometric boolean algorithm based upon the paper, <b><em>A topologically robust algorithm for Boolean operations on polyhedral shapes using approximate arithmetic</em></b> by Smith and Dodgson, Computer-Aided Design 39 (2007) 149�163, Elsevier.
+The constraints for a valid input mesh are given in the paper. Practically, the restrictions may be summarized as follows.
+
+Input meshes
+- must be closed with CCW-oriented surfaces,
+- must not have self-intersection,
+- must not have T-junctions,
+- <em>may</em> have multiple disconnected components.
+
+Failure to meet the constraints (first three items) above will lead to unpredictable fracturing results.
+
+<br>
+\section convexmeshbuilder ConvexMeshBuilder
+
+Nv::Blast::ConvexMeshBuilder is a tool for creation of collision geometry for physics engine. It recieves mesh vertices, and returns the convex hull of those vertices. If creation of a convex hull fails, the
+tool creates collision geometry as a bounding box of provided vertices.
+
+The tool provides a method to trim convex hulls against each other. It can be used along with noisy slicing to avoid "explosive" behavior due to penetration of neighboring collision hulls into each other.
+As a drawback, penetration of render meshes into each other is possible due to trimmed collision geometry.
+
+<br>
+\section bondgenerator BondGenerator
+
+Nv::Blast::BlastBondGenerator is a tool for creation of Blast&tm; Bond descriptors from provided geometry data.
+It has separate a method which is optimized for working FractureTool.
+\code
+int32_t Nv::Blast::BlastBondGenerator::buildDescFromInternalFracture(FractureTool* tool, const std::vector<bool>& chunkIsSupport, std::vector<NvBlastBondDesc>& resultBondDescs, std::vector<NvBlastChunkDesc>& resultChunkDescriptors);
+\endcode
+
+Other methods can work with prefractured meshes created in Third party tools, and can be used for converting prefractured models to Blast&tm; assets.
+
+Nv::Blast::BlastBondGenerator supports two modes of NvBlastBond data generation:
+
+1) Exact - in this mode exact common surface between chunks is found and considered as interface between them. Exact normal, area and centroid are computed.
+
+2) Average - this mode uses approximations of the interface, and can be used for gathering NvBlastBond data for assets, where chunks penetrate each other, e.g. chunks with noise.
+
+<br>
+\section meshcleaner MeshCleaner
+
+Nv::Blast::MeshCleaner can be used to remove self intersections and open edges in the interior of a mesh, making it more likely to fracture well.
+
+To use it, create a MeshCleaner using
+
+\code
+Nv::Blast::MeshCleaner* cleaner = NvBlastExtAuthoringCreateMeshCleaner();
+\endcode
+
+Given an Nv::Blast::Mesh called "mesh", simply call
+
+\code
+Nv::Blast::Mesh* newMesh = cleaner->cleanMesh(mesh);
+\endcode
+
+If successful, newMesh will be a valid pointer to the cleaned mesh. Otherwise, newMesh will be NULL.
+
+When done, release using
+\code
+cleaner->release();
+\endcode
+
+<br>
+*/
diff --git a/docs/_source/ext_exporter.txt b/docs/_source/ext_exporter.txt index d5dcfdf..ec1c34a 100644..100755 --- a/docs/_source/ext_exporter.txt +++ b/docs/_source/ext_exporter.txt @@ -1,35 +1,35 @@ -/*! \page pageextexporter Exporter (NvBlastExtExporter) - -This extension provides both reader and writer tools for FBX and OBJ mesh formats. The file writers (IMeshFileWriter writer) use -NvBlastMesh data to create a mesh hierarchy in the output file format that matches the Blast&tm; chunk hierarchy. The FBX writer -is also capable of embedding collision data within the mesh. This data is stored in a second layer in the FBX scene, with node -names that match the graphics mesh node names. - -From NvBlastExtExporter.h: - -\code -/** - Creates an instance of IMeshFileReader for reading obj file. -*/ -NVBLAST_API Nv::Blast::IMeshFileReader* NvBlastExtExporterCreateObjFileReader(); - -/** - Creates an instance of IFbxFileReader for reading fbx file. -*/ -NVBLAST_API Nv::Blast::IFbxFileReader* NvBlastExtExporterCreateFbxFileReader(); - -/** - Creates an instance of IMeshFileWriter for writing obj file. -*/ -NVBLAST_API Nv::Blast::IMeshFileWriter* NvBlastExtExporterCreateObjFileWriter(); - -/** - Creates an instance of IMeshFileWriter for writing fbx file. - - \param[in] outputFBXAscii If true writes fbx in ascii format otherwise write in binary. -*/ -NVBLAST_API Nv::Blast::IMeshFileWriter* NvBlastExtExporterCreateFbxFileWriter(bool outputFBXAscii = false); -\endcode - -<br> -*/ +/*! \page pageextexporter Exporter (NvBlastExtExporter)
+
+This extension provides both reader and writer tools for FBX and OBJ mesh formats. The file writers (IMeshFileWriter writer) use
+NvBlastMesh data to create a mesh hierarchy in the output file format that matches the Blast&tm; chunk hierarchy. The FBX writer
+is also capable of embedding collision data within the mesh. This data is stored in a second layer in the FBX scene, with node
+names that match the graphics mesh node names.
+
+From NvBlastExtExporter.h:
+
+\code
+/**
+ Creates an instance of IMeshFileReader for reading obj file.
+*/
+NVBLAST_API Nv::Blast::IMeshFileReader* NvBlastExtExporterCreateObjFileReader();
+
+/**
+ Creates an instance of IFbxFileReader for reading fbx file.
+*/
+NVBLAST_API Nv::Blast::IFbxFileReader* NvBlastExtExporterCreateFbxFileReader();
+
+/**
+ Creates an instance of IMeshFileWriter for writing obj file.
+*/
+NVBLAST_API Nv::Blast::IMeshFileWriter* NvBlastExtExporterCreateObjFileWriter();
+
+/**
+ Creates an instance of IMeshFileWriter for writing fbx file.
+
+ \param[in] outputFBXAscii If true writes fbx in ascii format otherwise write in binary.
+*/
+NVBLAST_API Nv::Blast::IMeshFileWriter* NvBlastExtExporterCreateFbxFileWriter(bool outputFBXAscii = false);
+\endcode
+
+<br>
+*/
diff --git a/docs/_source/ext_import.txt b/docs/_source/ext_import.txt index db5ff10..6916b83 100644..100755 --- a/docs/_source/ext_import.txt +++ b/docs/_source/ext_import.txt @@ -1,24 +1,24 @@ -/*! \page pageextimport Importer (NvBlastExtImport) - -This extension provides tools to import data from external formats and convert to a Blast&tm; asset. - -Currently the only external data format handled is NvApexDestructibleAsset, handled by Nv::Blast::ApexImporter::ApexImportTool. - -This tool supports two bond generation modes and can be configured by providing: -\code -struct ApexImporterConfig -{ - enum InterfaceSearchMode { EXACT, FORCED, MODE_COUNT }; - InterfaceSearchMode infSearchMode; -} -\endcode - -1) EXACT - Importer tries to find triangles from two chunks which lay in common surface. If such triangles are found, their intersections are considered as the interface. - -2) FORCED - Bond creation is forced no matter how far chunks are from each other. Interface parameters are approximated. - -Nv::Blast::ApexImporter::ApexImportTool can be initialized by providing ApexSDK and ModuleDestructible, or they can be created internally. - -If ApexSDK and ModuleDestructible were provided, they are not freed when Nv::Blast::ApexImporter::~ApexImportTool() is called. -<br> -*/ +/*! \page pageextimport Importer (NvBlastExtImport)
+
+This extension provides tools to import data from external formats and convert to a Blast&tm; asset.
+
+Currently the only external data format handled is NvApexDestructibleAsset, handled by Nv::Blast::ApexImporter::ApexImportTool.
+
+This tool supports two bond generation modes and can be configured by providing:
+\code
+struct ApexImporterConfig
+{
+ enum InterfaceSearchMode { EXACT, FORCED, MODE_COUNT };
+ InterfaceSearchMode infSearchMode;
+}
+\endcode
+
+1) EXACT - Importer tries to find triangles from two chunks which lay in common surface. If such triangles are found, their intersections are considered as the interface.
+
+2) FORCED - Bond creation is forced no matter how far chunks are from each other. Interface parameters are approximated.
+
+Nv::Blast::ApexImporter::ApexImportTool can be initialized by providing ApexSDK and ModuleDestructible, or they can be created internally.
+
+If ApexSDK and ModuleDestructible were provided, they are not freed when Nv::Blast::ApexImporter::~ApexImportTool() is called.
+<br>
+*/
diff --git a/docs/_source/ext_physx.txt b/docs/_source/ext_physx.txt index 7a3627c..bad3f86 100644..100755 --- a/docs/_source/ext_physx.txt +++ b/docs/_source/ext_physx.txt @@ -1,316 +1,316 @@ -/*! \page pageextphysx PhysX&tm; Extensions (NvBlastExtPhysX) - -NvBlastExtPhysX contains classes for easier use of Blast&tm; Toolkit with the PhysX&tm; SDK. -There are three of them: -- \ref ExtPxManager - Manager to keep Blast&tm; actors in sync with PhysX&tm; actors. -- \ref ExtImpactDamageManager - Manager to collect and apply impact damage caused by collision in PhysX&tm; scene. -- \ref ExtPxStressSolver - Stress Solver to propagate stress through support graph and apply it as damage to Blast&tm; actors. - -This library also contains an extension for synchronizing Blast&tm; state: -- \ref ExtSync - Utility for writing Blast&tm; state to a buffer, to be read by a client. This may be used for networking, for example. - -It also provides classes for utilizing PhysX&tm; SDK Foundation capabilities: -- \ref ExtGroupTaskManager - Multithreaded TkGroup processing using PxTask. -- \ref ExtCustomProfiler - Serves Blast&tm; profiling zones to PxFoundation profiler (e.g. PVD) and platform specific profilers. - -<br> -\section ExtPxManager - -<b>Physics Manager</b> - is a reference implementation for keeping Blast&tm; actors synced with PhysX&tm; actors. Its main job is to listen -for TkFamily events and update \a PxScene (by adding and removing PxActors) accordingly. - -In order to use it, create an ExtPxManager. If we have a physx::PxPhysics object m_physics and a TkFramework m_tkFramework, use - -\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 a PxConvexMeshGeometry with transform. Also every chunk can be marked as static (\a isStatic flag). -If an actor contains at least one static chunk in its support graph, it makes that actor kinematic (static). Otherwise the actor is dynamic. -Having zero subchunks makes the chunk invisible in the 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 an \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 - -The 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 an event will be fired to the listener): - -\code - -ExtPxSpawnSettings spawnSettings = { - &pxScene, - defaultPxMaterial, - RIGIDBODY_DENSITY -}; - -family->spawn(PxTransform(0, 0, 0), PxVec3(1, 1, 1), spawnSettings); -\endcode - -You can get a family's actors either from listening to events or by calling \a getActors(). -Every \a ExtPxActor matches 1 <-> 1 with TkActor (which matches \a NvBlastActor accordingly). - -\code -ExtPxActor* actor = ....; -physx::PxRigidDynamic rigidDynamic = actor->getPxActor(); -\endcode - -An ExtPxActor remains internally unchanged throughout its lifetime. -Use \a ExtPxActor \a getChunkIndices() and \a getPxActor() to update your 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 a joint creation function with \a ExtPxManager::setCreateJointFunction(...). It will be called when new TkJoints are -being created. All the joint updates and removals will be handled by the manager internally. - -<br> -\section ExtImpactDamageManager - -<b>Impact Damage Manager</b> - is a reference implementation for fast and easy impact damage support. It is built on top of ExtPxManager. - -In order to use it, create it as follows: - -\code -ExtImpactDamageManager* impactManager = ExtImpactDamageManager::create(pxManager); -\endcode - -Call its 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 - -<b>N.B.</b> for impact damage to work, you must enable contact notification with custom filter shader for PxScene. \a ExtImpactDamageManager has a reference filter shader implementation which can be used for that: - -\code -PxSceneDesc sceneDesc; -sceneDesc.filterShader = ExtImpactDamageManager::FilterShader; -\endcode - -<br> -\section ExtPxStressSolver - -<b>Stress Solver</b> - this wrapper class uses \ref pageextstress to apply stress calculations to an ExtPxFamily. See \ref pageextstress for -the details of the underlying stress solver. - -\subsection pxstresssolverusage Usage - -In order to use it, instance an ExtPxStressSolver by providing \a ExtPxFamily: - -\code -ExtPxStressSolver* stressSolver = ExtPxStressSolver::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. - -The underlying ExtStressSolver can be accessed using \a ExtPxStressSolver::getSolver(). For example, to apply impulse to a particular actor, \a applyImpulse(...) can be called for additional stress to apply: - -\code -stressSolver->getSolver().addForce(actor, position, impulse); -\endcode - -Finally, the stress solver (and its underlying ExtStressSolver) may be released using - -\code -stressSolver->release(); -\endcode - -<br> -\section ExtSync - -<b>Synchronization Extension (NvBlastExtSync)</b> - is a reference implementation for synchronizing Blast&tm; 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 instance 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> - -\section ExtGroupTaskManager -This class provides a basic implementation for multithreaded TkGroup processing using PxTask and a PxTaskManager from PxFoundation. - -In the simplest use case, all worker threads provided by PxTaskManager are used to process the group. - -\code -// creating ExtGroupTaskManager from existing taskManager and tkGroup -ExtGroupTaskManager* gtm = ExtGroupTaskManager::create(*taskManager, tkGroup); - -while (running) -{ - // ... add TkActors to TkGroup and damage ... - - // start processing on all worker threads provided - gtm->process(); - - // ... do something else ... - - // wait for the group processing to finish - gtm->wait(); -} - -// after use, release the ExtGroupTaskManager -gtm->release(); -\endcode - -<br> - -Groups can be processed concurrently as well as follows. - -\code -// creating ExtGroupTaskManager from existing taskManager and groups - -ExtGroupTaskManager* gtm0 = ExtGroupTaskManager::create(*taskManager, tkGroup0); -ExtGroupTaskManager* gtm1 = ExtGroupTaskManager::create(*taskManager, tkGroup1); -\endcode - -TkActors are added to TkGroups and damaged as usual. - -The PxTaskManager used in this example provides four worker threads of which each ExtGroupTaskManager uses two for its group. - -\code -uint32_t started = 0; -if (gtm0->process(2) > 0) { started++; } -if (gtm1->process(2) > 0) { started++; } -\endcode - -Note that ExtGroupTaskManager::wait() never returns true if no processing has started, as reported by ExtGroupTaskManager::process(). -The illustrative busy loop is not recomended for actual use. - -\code -uint32_t completed = 0; -while (completed < started) -{ - if (gtm0->wait(false)) { completed++; } - if (gtm1->wait(false)) { completed++; } -} -\endcode - -<br> - -\section ExtCustomProfiler -This Nv::Blast::ProfileCallback implementation forwards Blast&tm; profile events to the PxProfilerCallback attached to PxFoundation, typically a PhysX&tm; Visual Debugger (PVD) instance. -To use it, simply attach one to Blast&tm;. - -\code -static Nv::Blast::ExtCustomProfiler gBlastProfiler; -NvBlastProfilerSetCallback(&gBlastProfiler); -\endcode - -For convenience, it also provides sending profile events to platform specific profilers. These are disabled by default. - -\code -gBlastProfiler.setPlatformEnabled(true); -\endcode - -<br> - -*/ +/*! \page pageextphysx PhysX&tm; Extensions (NvBlastExtPhysX)
+
+NvBlastExtPhysX contains classes for easier use of Blast&tm; Toolkit with the PhysX&tm; SDK.
+There are three of them:
+- \ref ExtPxManager - Manager to keep Blast&tm; actors in sync with PhysX&tm; actors.
+- \ref ExtImpactDamageManager - Manager to collect and apply impact damage caused by collision in PhysX&tm; scene.
+- \ref ExtPxStressSolver - Stress Solver to propagate stress through support graph and apply it as damage to Blast&tm; actors.
+
+This library also contains an extension for synchronizing Blast&tm; state:
+- \ref ExtSync - Utility for writing Blast&tm; state to a buffer, to be read by a client. This may be used for networking, for example.
+
+It also provides classes for utilizing PhysX&tm; SDK Foundation capabilities:
+- \ref ExtGroupTaskManager - Multithreaded TkGroup processing using PxTask.
+- \ref ExtCustomProfiler - Serves Blast&tm; profiling zones to PxFoundation profiler (e.g. PVD) and platform specific profilers.
+
+<br>
+\section ExtPxManager
+
+<b>Physics Manager</b> - is a reference implementation for keeping Blast&tm; actors synced with PhysX&tm; actors. Its main job is to listen
+for TkFamily events and update \a PxScene (by adding and removing PxActors) accordingly.
+
+In order to use it, create an ExtPxManager. If we have a physx::PxPhysics object m_physics and a TkFramework m_tkFramework, use
+
+\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 a PxConvexMeshGeometry with transform. Also every chunk can be marked as static (\a isStatic flag).
+If an actor contains at least one static chunk in its support graph, it makes that actor kinematic (static). Otherwise the actor is dynamic.
+Having zero subchunks makes the chunk invisible in the 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 an \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
+
+The 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 an event will be fired to the listener):
+
+\code
+
+ExtPxSpawnSettings spawnSettings = {
+ &pxScene,
+ defaultPxMaterial,
+ RIGIDBODY_DENSITY
+};
+
+family->spawn(PxTransform(0, 0, 0), PxVec3(1, 1, 1), spawnSettings);
+\endcode
+
+You can get a family's actors either from listening to events or by calling \a getActors().
+Every \a ExtPxActor matches 1 <-> 1 with TkActor (which matches \a NvBlastActor accordingly).
+
+\code
+ExtPxActor* actor = ....;
+physx::PxRigidDynamic rigidDynamic = actor->getPxActor();
+\endcode
+
+An ExtPxActor remains internally unchanged throughout its lifetime.
+Use \a ExtPxActor \a getChunkIndices() and \a getPxActor() to update your 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 a joint creation function with \a ExtPxManager::setCreateJointFunction(...). It will be called when new TkJoints are
+being created. All the joint updates and removals will be handled by the manager internally.
+
+<br>
+\section ExtImpactDamageManager
+
+<b>Impact Damage Manager</b> - is a reference implementation for fast and easy impact damage support. It is built on top of ExtPxManager.
+
+In order to use it, create it as follows:
+
+\code
+ExtImpactDamageManager* impactManager = ExtImpactDamageManager::create(pxManager);
+\endcode
+
+Call its 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
+
+<b>N.B.</b> for impact damage to work, you must enable contact notification with custom filter shader for PxScene. \a ExtImpactDamageManager has a reference filter shader implementation which can be used for that:
+
+\code
+PxSceneDesc sceneDesc;
+sceneDesc.filterShader = ExtImpactDamageManager::FilterShader;
+\endcode
+
+<br>
+\section ExtPxStressSolver
+
+<b>Stress Solver</b> - this wrapper class uses \ref pageextstress to apply stress calculations to an ExtPxFamily. See \ref pageextstress for
+the details of the underlying stress solver.
+
+\subsection pxstresssolverusage Usage
+
+In order to use it, instance an ExtPxStressSolver by providing \a ExtPxFamily:
+
+\code
+ExtPxStressSolver* stressSolver = ExtPxStressSolver::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.
+
+The underlying ExtStressSolver can be accessed using \a ExtPxStressSolver::getSolver(). For example, to apply impulse to a particular actor, \a applyImpulse(...) can be called for additional stress to apply:
+
+\code
+stressSolver->getSolver().addForce(actor, position, impulse);
+\endcode
+
+Finally, the stress solver (and its underlying ExtStressSolver) may be released using
+
+\code
+stressSolver->release();
+\endcode
+
+<br>
+\section ExtSync
+
+<b>Synchronization Extension (NvBlastExtSync)</b> - is a reference implementation for synchronizing Blast&tm; 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 instance 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>
+
+\section ExtGroupTaskManager
+This class provides a basic implementation for multithreaded TkGroup processing using PxTask and a PxTaskManager from PxFoundation.
+
+In the simplest use case, all worker threads provided by PxTaskManager are used to process the group.
+
+\code
+// creating ExtGroupTaskManager from existing taskManager and tkGroup
+ExtGroupTaskManager* gtm = ExtGroupTaskManager::create(*taskManager, tkGroup);
+
+while (running)
+{
+ // ... add TkActors to TkGroup and damage ...
+
+ // start processing on all worker threads provided
+ gtm->process();
+
+ // ... do something else ...
+
+ // wait for the group processing to finish
+ gtm->wait();
+}
+
+// after use, release the ExtGroupTaskManager
+gtm->release();
+\endcode
+
+<br>
+
+Groups can be processed concurrently as well as follows.
+
+\code
+// creating ExtGroupTaskManager from existing taskManager and groups
+
+ExtGroupTaskManager* gtm0 = ExtGroupTaskManager::create(*taskManager, tkGroup0);
+ExtGroupTaskManager* gtm1 = ExtGroupTaskManager::create(*taskManager, tkGroup1);
+\endcode
+
+TkActors are added to TkGroups and damaged as usual.
+
+The PxTaskManager used in this example provides four worker threads of which each ExtGroupTaskManager uses two for its group.
+
+\code
+uint32_t started = 0;
+if (gtm0->process(2) > 0) { started++; }
+if (gtm1->process(2) > 0) { started++; }
+\endcode
+
+Note that ExtGroupTaskManager::wait() never returns true if no processing has started, as reported by ExtGroupTaskManager::process().
+The illustrative busy loop is not recomended for actual use.
+
+\code
+uint32_t completed = 0;
+while (completed < started)
+{
+ if (gtm0->wait(false)) { completed++; }
+ if (gtm1->wait(false)) { completed++; }
+}
+\endcode
+
+<br>
+
+\section ExtCustomProfiler
+This Nv::Blast::ProfileCallback implementation forwards Blast&tm; profile events to the PxProfilerCallback attached to PxFoundation, typically a PhysX&tm; Visual Debugger (PVD) instance.
+To use it, simply attach one to Blast&tm;.
+
+\code
+static Nv::Blast::ExtCustomProfiler gBlastProfiler;
+NvBlastProfilerSetCallback(&gBlastProfiler);
+\endcode
+
+For convenience, it also provides sending profile events to platform specific profilers. These are disabled by default.
+
+\code
+gBlastProfiler.setPlatformEnabled(true);
+\endcode
+
+<br>
+
+*/
diff --git a/docs/_source/ext_pxserialization.txt b/docs/_source/ext_pxserialization.txt index a8f4ea0..5638ee2 100644..100755 --- a/docs/_source/ext_pxserialization.txt +++ b/docs/_source/ext_pxserialization.txt @@ -1,48 +1,48 @@ -/*! \page pageextpxserialization ExtPhysX Serialization (NvBlastExtPxSerialization) - -This extension contains serializers which can be loaded into the ExtSerialization manager defined in \ref pageextserialization. - -To use this extension, you must also load the ExtSerialization extension and create a serialization manager as described in \ref pageextserialization. - -We repeat this here (again, assuming we are in the Nv::Blast namespace): - -\code -ExtSerialization* ser = NvBlastExtSerializationCreate(); -\endcode - -Then, call the function NvBlastExtPxSerializerLoadSet, declared in <b>NvBlastExtPxSerialization.h</b>, passing in your TkFramework (required by ExtPhysX), along with -your physx::PxPhysics and physx::PxCooking pointers: - -\code -TkFramework* framework = ... // We must have created a TkFramework -physx::PxPhysics* physics = ... // and PxPhysics -physx::PxCooking* cooking = ... // and PxCooking - -NvBlastExtPxSerializerLoadSet(*framework, *physics, *cooking *ser); -\endcode - -Now your serialization manager will have the serializers provided by this extension. Currently only ExtPxAsset serializers exist, with object type ID -given by - -<br> -<b>ExtPxObjectTypeID::Asset</b> -<br> - -As with low-level assets, you can serialize using the serialization manager directly: - -\code -const ExtPxAsset* asset = ... // Given pointer to an Nv::Blast::ExtPxAsset - -void* buffer; -uint64_t size = ser->serializeIntoBuffer(buffer, asset, ExtPxObjectTypeID::Asset); -\endcode - -or use the wrapper function defined in <b>NvBlastExtPxSerialization.h</b>: - -\code -void* buffer; -uint64_t size = NvBlastExtSerializationSerializeExtPxAssetIntoBuffer(buffer, *ser, asset); -\endcode - -<br> -*/ +/*! \page pageextpxserialization ExtPhysX Serialization (NvBlastExtPxSerialization)
+
+This extension contains serializers which can be loaded into the ExtSerialization manager defined in \ref pageextserialization.
+
+To use this extension, you must also load the ExtSerialization extension and create a serialization manager as described in \ref pageextserialization.
+
+We repeat this here (again, assuming we are in the Nv::Blast namespace):
+
+\code
+ExtSerialization* ser = NvBlastExtSerializationCreate();
+\endcode
+
+Then, call the function NvBlastExtPxSerializerLoadSet, declared in <b>NvBlastExtPxSerialization.h</b>, passing in your TkFramework (required by ExtPhysX), along with
+your physx::PxPhysics and physx::PxCooking pointers:
+
+\code
+TkFramework* framework = ... // We must have created a TkFramework
+physx::PxPhysics* physics = ... // and PxPhysics
+physx::PxCooking* cooking = ... // and PxCooking
+
+NvBlastExtPxSerializerLoadSet(*framework, *physics, *cooking *ser);
+\endcode
+
+Now your serialization manager will have the serializers provided by this extension. Currently only ExtPxAsset serializers exist, with object type ID
+given by
+
+<br>
+<b>ExtPxObjectTypeID::Asset</b>
+<br>
+
+As with low-level assets, you can serialize using the serialization manager directly:
+
+\code
+const ExtPxAsset* asset = ... // Given pointer to an Nv::Blast::ExtPxAsset
+
+void* buffer;
+uint64_t size = ser->serializeIntoBuffer(buffer, asset, ExtPxObjectTypeID::Asset);
+\endcode
+
+or use the wrapper function defined in <b>NvBlastExtPxSerialization.h</b>:
+
+\code
+void* buffer;
+uint64_t size = NvBlastExtSerializationSerializeExtPxAssetIntoBuffer(buffer, *ser, asset);
+\endcode
+
+<br>
+*/
diff --git a/docs/_source/ext_serialization.txt b/docs/_source/ext_serialization.txt index b6b8ef0..4cc8bda 100644..100755 --- a/docs/_source/ext_serialization.txt +++ b/docs/_source/ext_serialization.txt @@ -1,193 +1,193 @@ -/*! \page pageextserialization Serialization (NvBlastExtSerialization) - -\section serialization_intro Introduction - -This extension defines the Nv::Blast::ExtSerialization class, a modular serialization manager which can be extended to handle data types from different Blast&tm; modules -(such as low-level, Tk, and ExtPhysX). - -An ExtSerialization manager is created using the global function NvBlastExtSerializationCreate: - -(From now on we'll assume we are using the Nv::Blast namespace.) - -\code -ExtSerialization* ser = NvBlastExtSerializationCreate(); -\endcode - -ExtSerialization is capable of loading sets of serializers for different data types and encodings. The NvBlastExtSerialization extension comes with a set of low-level data serializers, -with types enumerated in the header <b>NvBlastExtLlSerialization.h</b>. - -<b>The low-level serializers are automatically loaded into an ExtSerialization when it is created.</b> - -To load serializers for Tk and ExtPhysX assets, you must also load the extensions \ref pageexttkserialization and \ref pageextpxserialization, respectively. See the documentation for -those modules. - -Each serializer is capable of reading (and writing, if it is not read-only) a single data type in a single encoding (format). Some serializers are read-only, in order to read legacy -formats. - -The encodings available are enumerated in ExtSerialization::EncodingID. They are currently: - -- CapnProtoBinary - Uses Cap'n Proto's binary serialization format -- Raw - For low-level NvBlastAsset and NvBlastFamily types, this is simply a memory copy. For Tk and ExtPx assets, this is the deprecated serialization format from Blast&tm; 1.0. - -<br> -\section serialization_ser Serialization (writing) - -To serialize an object, the serialization manager's write encoding ID must be set to the desired value. By default it is set to EncodingID::CapnProtoBinary, as this is the only -encoding which supports writing for all object types (at the present time). When other encodings become available, use ExtSerialization::setSerializationEncoding to set the write -encoding to the desired type. - -Each serialization module defines the object types it can serialize. ExtSerialization defines the low-level types in <b>NvBlastExtLlSerialization.h</b>: - -- LlObjectTypeID::Asset - An NvBlastAsset -- LlObjectTypeID::Family - An NvBlastFamily - -To serialize an object, for example an NvBlastAsset, use ExtSerialization::serializeIntoBuffer as follows: - -\code -const NvBlastAsset* asset = ... // Given pointer to an NvBlastAsset - -void* buffer; -uint64_t size = ser->serializeIntoBuffer(buffer, asset, LlObjectTypeID::Asset); -\endcode - -If successful, the data is written into a buffer allocated using the NvBlastGlobals allocator, written to the "buffer" parameter, and the size of the buffer -written is the return value of the function. If the function returns 0, then serialization was unsuccessful. Notice that the second function parameter is actually a void*, -so it requires the last parameter to tell it what object it is serializing. A utility wrapper function is given in <b>NvBlastExtLlSerialization.h</b> which performs the -same operation with an NvBlastAsset, so one could equivalently use - -\code -void* buffer; -uint64_t size = NvBlastExtSerializationSerializeAssetIntoBuffer(buffer, *ser, asset); -\endcode - -A corresponding function also exists for NvBlastFamily, as well as other data types supported by other serialization extensions. - -This buffer may be written to disk, memory, networked, etc. Since the memory for the buffer is allocated using the allocator -in NvBlastGlobals, it may be freed using the same allocator: - -\code -NVBLAST_FREE(buffer) -\endcode - -<br> -\subsection bufferproviders Using a Buffer Provider - -If you wish to provide the serialization buffer by some means other than the NvBlastGlobals allocator, you may set a "buffer provider" -in the serialization manager. A buffer provider is simply a callback that requests a buffer from the user of the necessary size. -The user implements the interface ExtSerialization::BufferProvider, and passes a pointer to an instance of one to the serialization -manager using ExtSerialization::setBufferProvider. - -For example: - -\code -std::vector<char> growableBuffer; - -class MyBufferProvider : public Nv::Blast::ExtSerialization::BufferProvider -{ -public: - MyBufferProvider(std::vector<char>& growableBuffer) : m_growableBuffer(growableBuffer) {} - - virtual void* requestBuffer(size_t size) override - { - if (m_growableBuffer.size() < size) - { - m_growableBuffer.resize(size); - } - return m_growableBuffer.data(); - } - -private: - std::vector<char>& m_growableBuffer; -} myBufferProvider(growableBuffer); - -ser->setBufferProvider(&myBufferProvider); -\endcode - -Passing NULL to setBufferProvider returns the serialization to its default behavior of using the NvBlastGlobals allocator. - -<br> -\section serialization_deser Deserialization (reading) - -To deserialize an object, use the ExtSerialization::deserializeFromBuffer method. If you know the type of object in the buffer, -you may directly cast the returned pointer to one of that type. For example, if the buffer contains an NvBlastAsset, use: - -\code -const void* buffer = ... // A given buffer, may be read from disk, memory, etc. -const uint64_t size = ... // The buffer's size in bytes - -NvBlastAsset* asset = static_cast<NvBlastAsset*>(ser->deserializeFromBuffer(buffer, size)); -\endcode - -This returns a valid pointer if deserialization was successful, or NULL otherwise. If no serializer is loaded which can handle -the object type in the stream in its given encoding, it will fail and return NULL. - -Again, the memory for the asset is allocated using NvBlastGlobals, so that the asset may be released using - -\code -NVBLAST_FREE(asset); -\endcode - -<br> -\section detecting_object_type Detecting the Object Type in a Buffer - -If you don't know the object type in the buffer, you may use the last (optional) argument in deserializeFromBuffer to return the type: - -\code -uint32_t objTypeID; -void* obj = ser->deserializeFromBuffer(buffer, size, &objTypeID); - -NVBLAST_CHECK_ERROR(obj != nullptr, "Object could not be read from buffer.", return); - -switch (objTypeID) -{ -case LlObjectTypeID::Asset: - handleAssetLoad(static_cast<NvBlastAsset*>(obj)); - break; -case LlObjectTypeID::Family: - handleFamilyLoad(static_cast<NvBlastFamily*>(obj)); - break; -default: - NVBLAST_LOG_ERROR("Unknown object type "); -} -\endcode - -<br> -\subsection peeking_and_skipping Peeking at and Skipping Buffer Data - -If a buffer contains multiple objects, you may peek at the buffer to get object information including object type, encoding, and data size, and skip to -the next object in the buffer (whether or not you have chosen to read the current object). For example: - -\code -const void* buffer = ... // The input buffer -uint64_t size = ... // The input buffer size - -while (size) -{ - uint64_t objTypeID; - if (!ser->peekHeader(&objTypeID, NULL, NULL, buffer, size)) // Only reading the object type ID; may pass in NULL for the other header value pointers - { - break; // Read error, stop - } - - if (objectShouldBeLoaded(objTypeID)) // Some function to determine whether or not we want this object - { - void* obj = ser->deserializeFromBuffer(buffer, size); - // Handle loaded object ... - } - - // Jump to next object: - buffer = ser->skipObject(size, buffer); // Updates size as well -} -\endcode - -<br> -\section serialization_term Cleaning Up - -When finished with the serialization manager, it may be released using its release() method: - -\code -ser->release(); -\endcode - -<br> -*/ +/*! \page pageextserialization Serialization (NvBlastExtSerialization)
+
+\section serialization_intro Introduction
+
+This extension defines the Nv::Blast::ExtSerialization class, a modular serialization manager which can be extended to handle data types from different Blast&tm; modules
+(such as low-level, Tk, and ExtPhysX).
+
+An ExtSerialization manager is created using the global function NvBlastExtSerializationCreate:
+
+(From now on we'll assume we are using the Nv::Blast namespace.)
+
+\code
+ExtSerialization* ser = NvBlastExtSerializationCreate();
+\endcode
+
+ExtSerialization is capable of loading sets of serializers for different data types and encodings. The NvBlastExtSerialization extension comes with a set of low-level data serializers,
+with types enumerated in the header <b>NvBlastExtLlSerialization.h</b>.
+
+<b>The low-level serializers are automatically loaded into an ExtSerialization when it is created.</b>
+
+To load serializers for Tk and ExtPhysX assets, you must also load the extensions \ref pageexttkserialization and \ref pageextpxserialization, respectively. See the documentation for
+those modules.
+
+Each serializer is capable of reading (and writing, if it is not read-only) a single data type in a single encoding (format). Some serializers are read-only, in order to read legacy
+formats.
+
+The encodings available are enumerated in ExtSerialization::EncodingID. They are currently:
+
+- CapnProtoBinary - Uses Cap'n Proto's binary serialization format
+- Raw - For low-level NvBlastAsset and NvBlastFamily types, this is simply a memory copy. For Tk and ExtPx assets, this is the deprecated serialization format from Blast&tm; 1.0.
+
+<br>
+\section serialization_ser Serialization (writing)
+
+To serialize an object, the serialization manager's write encoding ID must be set to the desired value. By default it is set to EncodingID::CapnProtoBinary, as this is the only
+encoding which supports writing for all object types (at the present time). When other encodings become available, use ExtSerialization::setSerializationEncoding to set the write
+encoding to the desired type.
+
+Each serialization module defines the object types it can serialize. ExtSerialization defines the low-level types in <b>NvBlastExtLlSerialization.h</b>:
+
+- LlObjectTypeID::Asset - An NvBlastAsset
+- LlObjectTypeID::Family - An NvBlastFamily
+
+To serialize an object, for example an NvBlastAsset, use ExtSerialization::serializeIntoBuffer as follows:
+
+\code
+const NvBlastAsset* asset = ... // Given pointer to an NvBlastAsset
+
+void* buffer;
+uint64_t size = ser->serializeIntoBuffer(buffer, asset, LlObjectTypeID::Asset);
+\endcode
+
+If successful, the data is written into a buffer allocated using the NvBlastGlobals allocator, written to the "buffer" parameter, and the size of the buffer
+written is the return value of the function. If the function returns 0, then serialization was unsuccessful. Notice that the second function parameter is actually a void*,
+so it requires the last parameter to tell it what object it is serializing. A utility wrapper function is given in <b>NvBlastExtLlSerialization.h</b> which performs the
+same operation with an NvBlastAsset, so one could equivalently use
+
+\code
+void* buffer;
+uint64_t size = NvBlastExtSerializationSerializeAssetIntoBuffer(buffer, *ser, asset);
+\endcode
+
+A corresponding function also exists for NvBlastFamily, as well as other data types supported by other serialization extensions.
+
+This buffer may be written to disk, memory, networked, etc. Since the memory for the buffer is allocated using the allocator
+in NvBlastGlobals, it may be freed using the same allocator:
+
+\code
+NVBLAST_FREE(buffer)
+\endcode
+
+<br>
+\subsection bufferproviders Using a Buffer Provider
+
+If you wish to provide the serialization buffer by some means other than the NvBlastGlobals allocator, you may set a "buffer provider"
+in the serialization manager. A buffer provider is simply a callback that requests a buffer from the user of the necessary size.
+The user implements the interface ExtSerialization::BufferProvider, and passes a pointer to an instance of one to the serialization
+manager using ExtSerialization::setBufferProvider.
+
+For example:
+
+\code
+std::vector<char> growableBuffer;
+
+class MyBufferProvider : public Nv::Blast::ExtSerialization::BufferProvider
+{
+public:
+ MyBufferProvider(std::vector<char>& growableBuffer) : m_growableBuffer(growableBuffer) {}
+
+ virtual void* requestBuffer(size_t size) override
+ {
+ if (m_growableBuffer.size() < size)
+ {
+ m_growableBuffer.resize(size);
+ }
+ return m_growableBuffer.data();
+ }
+
+private:
+ std::vector<char>& m_growableBuffer;
+} myBufferProvider(growableBuffer);
+
+ser->setBufferProvider(&myBufferProvider);
+\endcode
+
+Passing NULL to setBufferProvider returns the serialization to its default behavior of using the NvBlastGlobals allocator.
+
+<br>
+\section serialization_deser Deserialization (reading)
+
+To deserialize an object, use the ExtSerialization::deserializeFromBuffer method. If you know the type of object in the buffer,
+you may directly cast the returned pointer to one of that type. For example, if the buffer contains an NvBlastAsset, use:
+
+\code
+const void* buffer = ... // A given buffer, may be read from disk, memory, etc.
+const uint64_t size = ... // The buffer's size in bytes
+
+NvBlastAsset* asset = static_cast<NvBlastAsset*>(ser->deserializeFromBuffer(buffer, size));
+\endcode
+
+This returns a valid pointer if deserialization was successful, or NULL otherwise. If no serializer is loaded which can handle
+the object type in the stream in its given encoding, it will fail and return NULL.
+
+Again, the memory for the asset is allocated using NvBlastGlobals, so that the asset may be released using
+
+\code
+NVBLAST_FREE(asset);
+\endcode
+
+<br>
+\section detecting_object_type Detecting the Object Type in a Buffer
+
+If you don't know the object type in the buffer, you may use the last (optional) argument in deserializeFromBuffer to return the type:
+
+\code
+uint32_t objTypeID;
+void* obj = ser->deserializeFromBuffer(buffer, size, &objTypeID);
+
+NVBLAST_CHECK_ERROR(obj != nullptr, "Object could not be read from buffer.", return);
+
+switch (objTypeID)
+{
+case LlObjectTypeID::Asset:
+ handleAssetLoad(static_cast<NvBlastAsset*>(obj));
+ break;
+case LlObjectTypeID::Family:
+ handleFamilyLoad(static_cast<NvBlastFamily*>(obj));
+ break;
+default:
+ NVBLAST_LOG_ERROR("Unknown object type ");
+}
+\endcode
+
+<br>
+\subsection peeking_and_skipping Peeking at and Skipping Buffer Data
+
+If a buffer contains multiple objects, you may peek at the buffer to get object information including object type, encoding, and data size, and skip to
+the next object in the buffer (whether or not you have chosen to read the current object). For example:
+
+\code
+const void* buffer = ... // The input buffer
+uint64_t size = ... // The input buffer size
+
+while (size)
+{
+ uint64_t objTypeID;
+ if (!ser->peekHeader(&objTypeID, NULL, NULL, buffer, size)) // Only reading the object type ID; may pass in NULL for the other header value pointers
+ {
+ break; // Read error, stop
+ }
+
+ if (objectShouldBeLoaded(objTypeID)) // Some function to determine whether or not we want this object
+ {
+ void* obj = ser->deserializeFromBuffer(buffer, size);
+ // Handle loaded object ...
+ }
+
+ // Jump to next object:
+ buffer = ser->skipObject(size, buffer); // Updates size as well
+}
+\endcode
+
+<br>
+\section serialization_term Cleaning Up
+
+When finished with the serialization manager, it may be released using its release() method:
+
+\code
+ser->release();
+\endcode
+
+<br>
+*/
diff --git a/docs/_source/ext_shaders.txt b/docs/_source/ext_shaders.txt index 3bfb37d..52aaa36 100644..100755 --- a/docs/_source/ext_shaders.txt +++ b/docs/_source/ext_shaders.txt @@ -1,46 +1,46 @@ -/*! \page pageextshaders Damage Shaders (NvBlastExtShaders) - -The Blast&tm; damage shader extension provides basic implementations of programs generating fracture commands, the first step in breaking a Blast&tm; Actor, see \ref splitting. -These programs come as two shader functions (callbacks): one for Actors with a support graph, and one for Actors with just one chunk, respectively. -The NvBlastDamageProgram containing both shaders can be used for low-level directly (NvBlastActorGenerateFracture) or for TkActor's damage and fracture functions. - -For example, one may construct a damage program using the "shear" damage shaders declared in NvBlastExtDamageShaders.h: - -\code - NvBlastDamageProgram damageProgram = { NvBlastExtShearGraphShader, NvBlastExtShearSubgraphShader }; -\endcode - -The appropriate shader ("graph" or "subgraph") will be called for an Actor being processed, along with the Actor's necessary geometry and program parameters. -The parameters (NvBlastProgramParams) are set to contain - -1. Material, something that describes an Actor properties (e.g. mass, stiffness, fragility) which are not expected to be changed often. - -2. Damage description, something that describes a particular damage event (e.g. position, radius and force of explosion). - -For example: - -\code - NvBlastExtMaterial material = { health, minDamageThreshold, maxDamageThreshold }; - NvBlastExtRadialDamageDesc damageDesc = { compressive, posX, posY, posZ, minR, maxR }; -\endcode - -When used with TkActor::damage() functions, TkActor will cache the necessary data for deferred processing through TkGroup. This includes accumulating damage requests for -the same material and program parameter combination. A default material can be set for a TkFamily that all its Actors uses. - -A Tk layer example follows. - -\code - tkGroup->addActor(*tkActor); - tkActor->damage(damageProgram, damageDesc0, sizeof(NvBlastExtRadialDamageDesc), &material); - tkActor->damage(damageProgram, damageDesc1, sizeof(NvBlastExtRadialDamageDesc), &material); - tkGroup->process(); -\endcode - -In contrast, the user is responsible for providing all the damage descriptions persisting through the low-level NvBlastActorGenerateFracture call when not using the Tk layer: - -\code - NvBlastProgramParams programParams = { damageDescs, 2, &material }; - NvBlastActorGenerateFracture(commandBuffers, actor, damageProgram, &programParams, nullptr, nullptr); -\endcode - -*/ +/*! \page pageextshaders Damage Shaders (NvBlastExtShaders)
+
+The Blast&tm; damage shader extension provides basic implementations of programs generating fracture commands, the first step in breaking a Blast&tm; Actor, see \ref splitting.
+These programs come as two shader functions (callbacks): one for Actors with a support graph, and one for Actors with just one chunk, respectively.
+The NvBlastDamageProgram containing both shaders can be used for low-level directly (NvBlastActorGenerateFracture) or for TkActor's damage and fracture functions.
+
+For example, one may construct a damage program using the "shear" damage shaders declared in NvBlastExtDamageShaders.h:
+
+\code
+ NvBlastDamageProgram damageProgram = { NvBlastExtShearGraphShader, NvBlastExtShearSubgraphShader };
+\endcode
+
+The appropriate shader ("graph" or "subgraph") will be called for an Actor being processed, along with the Actor's necessary geometry and program parameters.
+The parameters (NvBlastProgramParams) are set to contain
+
+1. Material, something that describes an Actor properties (e.g. mass, stiffness, fragility) which are not expected to be changed often.
+
+2. Damage description, something that describes a particular damage event (e.g. position, radius and force of explosion).
+
+For example:
+
+\code
+ NvBlastExtMaterial material = { health, minDamageThreshold, maxDamageThreshold };
+ NvBlastExtRadialDamageDesc damageDesc = { compressive, posX, posY, posZ, minR, maxR };
+\endcode
+
+When used with TkActor::damage() functions, TkActor will cache the necessary data for deferred processing through TkGroup. This includes accumulating damage requests for
+the same material and program parameter combination. A default material can be set for a TkFamily that all its Actors uses.
+
+A Tk layer example follows.
+
+\code
+ tkGroup->addActor(*tkActor);
+ tkActor->damage(damageProgram, damageDesc0, sizeof(NvBlastExtRadialDamageDesc), &material);
+ tkActor->damage(damageProgram, damageDesc1, sizeof(NvBlastExtRadialDamageDesc), &material);
+ tkGroup->process();
+\endcode
+
+In contrast, the user is responsible for providing all the damage descriptions persisting through the low-level NvBlastActorGenerateFracture call when not using the Tk layer:
+
+\code
+ NvBlastProgramParams programParams = { damageDescs, 2, &material };
+ NvBlastActorGenerateFracture(commandBuffers, actor, damageProgram, &programParams, nullptr, nullptr);
+\endcode
+
+*/
diff --git a/docs/_source/ext_stress.txt b/docs/_source/ext_stress.txt index 341fc12..834ee64 100644..100755 --- a/docs/_source/ext_stress.txt +++ b/docs/_source/ext_stress.txt @@ -1,115 +1,115 @@ -/*! \page pageextstress Stress Solver Extension (NvBlastExtStress) - - -The Blast&tm; stress solver extension provides an implementation of a quite fast and easy to use stress solver which works directly with the bond graph. It simulates more -complex damage model on support graph by allowing to apply forces on nodes of the support graph (on chunks). The most common usage is just applying gravity force on a static construction -so that it will fall apart at some point when the carcass cannot hold anymore. Dynamic actors are also supported, you could for example add centrifugal force so that rotating an object fast enough will break bonds. - -It also can be used as another way to apply impact damage, which can give the visually pleasant result of an actor breaking in a weak place instead of the place of contact. - -<br> -\section stresssolverfeatures Features - -- Requires only core \a NvBlast -- Supports both static and dynamic actors -- Propagates both linear and angular momentum -- Graph complexity selection (reduces support graph to smaller size to trade-off speed for quality) -- Apply stress damage on Blast&tm; actor -- Debug Render - -<br> -\section stresssolvertuning Settings Tuning - -Computational time is linearly proportional to the \a bondIterationsPerFrame setting. To fine tune, look for balance between \a bondIterationsPerFrame and \a graphReductionLevel . The more bond iterations -are set, the more precise the computation will be. The smaller graph allows to make higher fidelity computations within the same bond iterations per frame (same time spent), but actual cracks (damaged bonds) will be more sparse as the result. - -Debug render can help a lot for tuning, consider using \a stressSolver->fillDebugRender(...) for that. - -<br> -\section stresssolverusage Usage - -In order to use the stress solver, create an instance with \a ExtStressSolver::create(...). - -\code -ExtStressSolver* stressSolver = ExtStressSolver::create(family, settings); -\endcode - -\a ExtStressSolverSettings are passed in create function, but also can be changed at any time with \a stressSolver->setSettings(...). - -It fully utilizes the fact that it knows the initial support graph structure and does a maximum of processing -in the \a create(...) method call. After that, all actor split calls are synchronized internally and efficiently so only the actual stress propagation takes most of computational time. - -You need to provide physics specific information (mass, volume, position, static) for every node in support graph since Blast&tm; itself is physics agnostic. There are two ways to do it. One way is to call \a stressSolver->setNodeInfo(...) for every graph node. The other way is to call stressSolver->setAllNodesInfoFromLL() once: all the data will be populated using NvBlastAsset chunk's data, in particular \a volume and \a centroid. All nodes connected to 'world' chunk are marked as static. - -\code -stressSolver->setAllNodesInfoFromLL(); -\endcode - -Stress solver needs to keep track for actor create/destroy events in order to update its internal stress graph accordingly. So you need to call \a stressSolver->notifyActorCreated(actor) and \a stressSolver->notifyActorDestroyed(actor) every time an actor is created or destroyed, including the initial actor the family had when the stress solver was created. There is no need to track actors which contain only one or less graph nodes. In that case \a notifyActorCreated(actor) returns 'false' as a hint. It means that the stress solver will ignore them, as for those actors applying forces does not make any sense. - -A typical update loop looks like this: - --# If split happened, call relevant stressSolver->notifyActorCreated(actor) and stressSolver->notifyActorDestroyed(actor) --# Apply all forces, use \a stressSolver->addForce(...), stressSolver->addGravityForce(...), \a stressSolver->addAngularVelocity(...) --# Call \a stressSolver->update(). This is where all expensive computation takes place. --# If \a stressSolver->getOverstressedBondCount() > 0, use one of \a stressSolver->generateFractureCommands() methods to get bond fracture commands and apply them on actors. - -Example code from ExtPxStressSolverImpl: - -\code -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); -} - -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); - } - } -} -\endcode - -Have a look at \a ExtPxStressSolver implementation code, which is basically a high level wrapper on \a NvBlastExtStress to couple it with PhysX&tm; and \a NvBlastExtPx extension (see \ref extpxstresssolver). - -<br> - -*/ +/*! \page pageextstress Stress Solver (NvBlastExtStress)
+
+
+The Blast&tm; stress solver extension provides an implementation of a quite fast and easy to use stress solver which works directly with the bond graph. It simulates more
+complex damage model on support graph by allowing to apply forces on nodes of the support graph (on chunks). The most common usage is just applying gravity force on a static construction
+so that it will fall apart at some point when the carcass cannot hold anymore. Dynamic actors are also supported, you could for example add centrifugal force so that rotating an object fast enough will break bonds.
+
+It also can be used as another way to apply impact damage, which can give the visually pleasant result of an actor breaking in a weak place instead of the place of contact.
+
+<br>
+\section stresssolverfeatures Features
+
+- Requires only core \a NvBlast
+- Supports both static and dynamic actors
+- Propagates both linear and angular momentum
+- Graph complexity selection (reduces support graph to smaller size to trade-off speed for quality)
+- Apply stress damage on Blast&tm; actor
+- Debug Render
+
+<br>
+\section stresssolvertuning Settings Tuning
+
+Computational time is linearly proportional to the \a bondIterationsPerFrame setting. To fine tune, look for balance between \a bondIterationsPerFrame and \a graphReductionLevel . The more bond iterations
+are set, the more precise the computation will be. The smaller graph allows to make higher fidelity computations within the same bond iterations per frame (same time spent), but actual cracks (damaged bonds) will be more sparse as the result.
+
+Debug render can help a lot for tuning, consider using \a stressSolver->fillDebugRender(...) for that.
+
+<br>
+\section stresssolverusage Usage
+
+In order to use the stress solver, create an instance with \a ExtStressSolver::create(...).
+
+\code
+ExtStressSolver* stressSolver = ExtStressSolver::create(family, settings);
+\endcode
+
+\a ExtStressSolverSettings are passed in create function, but also can be changed at any time with \a stressSolver->setSettings(...).
+
+It fully utilizes the fact that it knows the initial support graph structure and does a maximum of processing
+in the \a create(...) method call. After that, all actor split calls are synchronized internally and efficiently so only the actual stress propagation takes most of computational time.
+
+You need to provide physics specific information (mass, volume, position, static) for every node in support graph since Blast&tm; itself is physics agnostic. There are two ways to do it. One way is to call \a stressSolver->setNodeInfo(...) for every graph node. The other way is to call stressSolver->setAllNodesInfoFromLL() once: all the data will be populated using NvBlastAsset chunk's data, in particular \a volume and \a centroid. All nodes connected to 'world' chunk are marked as static.
+
+\code
+stressSolver->setAllNodesInfoFromLL();
+\endcode
+
+Stress solver needs to keep track for actor create/destroy events in order to update its internal stress graph accordingly. So you need to call \a stressSolver->notifyActorCreated(actor) and \a stressSolver->notifyActorDestroyed(actor) every time an actor is created or destroyed, including the initial actor the family had when the stress solver was created. There is no need to track actors which contain only one or less graph nodes. In that case \a notifyActorCreated(actor) returns 'false' as a hint. It means that the stress solver will ignore them, as for those actors applying forces does not make any sense.
+
+A typical update loop looks like this:
+
+-# If split happened, call relevant stressSolver->notifyActorCreated(actor) and stressSolver->notifyActorDestroyed(actor)
+-# Apply all forces, use \a stressSolver->addForce(...), stressSolver->addGravityForce(...), \a stressSolver->addAngularVelocity(...)
+-# Call \a stressSolver->update(). This is where all expensive computation takes place.
+-# If \a stressSolver->getOverstressedBondCount() > 0, use one of \a stressSolver->generateFractureCommands() methods to get bond fracture commands and apply them on actors.
+
+Example code from ExtPxStressSolverImpl:
+
+\code
+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);
+}
+
+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);
+ }
+ }
+}
+\endcode
+
+Have a look at \a ExtPxStressSolver implementation code, which is basically a high level wrapper on \a NvBlastExtStress to couple it with PhysX&tm; and \a NvBlastExtPx extension (see \ref extpxstresssolver).
+
+<br>
+
+*/
diff --git a/docs/_source/ext_tkserialization.txt b/docs/_source/ext_tkserialization.txt index 6dbd4f5..a1c9f22 100644..100755 --- a/docs/_source/ext_tkserialization.txt +++ b/docs/_source/ext_tkserialization.txt @@ -1,45 +1,45 @@ -/*! \page pageexttkserialization BlastTk Serialization (NvBlastExtTkSerialization) - -This extension contains serializers which can be loaded into the ExtSerialization manager defined in \ref pageextserialization. - -To use this extension, you must also load the ExtSerialization extension and create a serialization manager as described in \ref pageextserialization. - -We repeat this here (again, assuming we are in the Nv::Blast namespace): - -\code -ExtSerialization* ser = NvBlastExtSerializationCreate(); -\endcode - -Then, call the function NvBlastExtTkSerializerLoadSet, declared in <b>NvBlastExtTkSerialization.h</b>, passing in your TkFramework: - -\code -TkFramework* framework = ... // We must have created a TkFramework - -NvBlastExtTkSerializerLoadSet(*framework, *ser); -\endcode - -Now your serialization manager will have the serializers provided by this extension. Currently only TkAsset serializers exist, with object type ID -given by - -<br> -<b>TkObjectTypeID::Asset</b> -<br> - -As with low-level assets, you can serialize using the serialization manager directly: - -\code -const TkAsset* asset = ... // Given pointer to an Nv::Blast::TkAsset - -void* buffer; -uint64_t size = ser->serializeIntoBuffer(buffer, asset, TkObjectTypeID::Asset); -\endcode - -or use the wrapper function defined in <b>NvBlastExtTkSerialization.h</b>: - -\code -void* buffer; -uint64_t size = NvBlastExtSerializationSerializeTkAssetIntoBuffer(buffer, *ser, asset); -\endcode - -<br> -*/ +/*! \page pageexttkserialization BlastTk Serialization (NvBlastExtTkSerialization)
+
+This extension contains serializers which can be loaded into the ExtSerialization manager defined in \ref pageextserialization.
+
+To use this extension, you must also load the ExtSerialization extension and create a serialization manager as described in \ref pageextserialization.
+
+We repeat this here (again, assuming we are in the Nv::Blast namespace):
+
+\code
+ExtSerialization* ser = NvBlastExtSerializationCreate();
+\endcode
+
+Then, call the function NvBlastExtTkSerializerLoadSet, declared in <b>NvBlastExtTkSerialization.h</b>, passing in your TkFramework:
+
+\code
+TkFramework* framework = ... // We must have created a TkFramework
+
+NvBlastExtTkSerializerLoadSet(*framework, *ser);
+\endcode
+
+Now your serialization manager will have the serializers provided by this extension. Currently only TkAsset serializers exist, with object type ID
+given by
+
+<br>
+<b>TkObjectTypeID::Asset</b>
+<br>
+
+As with low-level assets, you can serialize using the serialization manager directly:
+
+\code
+const TkAsset* asset = ... // Given pointer to an Nv::Blast::TkAsset
+
+void* buffer;
+uint64_t size = ser->serializeIntoBuffer(buffer, asset, TkObjectTypeID::Asset);
+\endcode
+
+or use the wrapper function defined in <b>NvBlastExtTkSerialization.h</b>:
+
+\code
+void* buffer;
+uint64_t size = NvBlastExtSerializationSerializeTkAssetIntoBuffer(buffer, *ser, asset);
+\endcode
+
+<br>
+*/
diff --git a/docs/_source/introduction.txt b/docs/_source/introduction.txt index 402deeb..d7b79f6 100644..100755 --- a/docs/_source/introduction.txt +++ b/docs/_source/introduction.txt @@ -1,79 +1,79 @@ -/*! \page pageintroduction Introduction - -Blast&tm; is an NVIDIA GameWorks&tm; destruction library. It consists of a \ref pagellapi, a \ref pagehlapi (Blast&tm; Toolkit -or BlastTk), and \ref pageextapi (Blast&tm; Extensions or BlastExt). This layered API is designed to allow short ramp-up time for -first usage (through the Ext and Tk APIs) while also allowing for customization and optimization by experienced users through the -low-level API. - -This library is intended to replace APEX Destruction. It is being developed with years of user feedback and experience, with the -goal of addressing shortcomings in performance, stability, and customizability of the APEX Destruction module. - -\section asset_structure Asset Structure - -Blast&tm; is currently designed to support rigid body, pre-fractured destruction. Future versions may support runtime fracturing -or deformation. - -The static data associated with a destructible is stored in an \{\em asset\}. Assets are instanced into actors, which may -be damaged and fractured. When fractured, actors are broken into pieces called \{\em chunks\}. Connected groups of chunks -belong to new actors. The grouping of chunks into actors is determined by the support graph in the asset. - -Chunks are defined hierarchically, so that when a chunk is fractured its child chunks are created. The user may tag any -chunk in this hierarchy as a \{\em support\} chunk. This is covered in more detail in the \ref support_model section. The user -also supplies a description of the connections between support chunks. A \{\em bond\} represents the surface joining neighboring -chunks. A bond is represented by a surface centroid, an average surface normal, and the surface area. These quantities don't -need to be exact for Blast&tm; to operate effectively. - -Multiple chunk hierarchies may exist in a single asset. The <em>root chunks</em> (see \ref pagedefinitions) will be visible when the -asset is initially instanced. Subsequent fracturing has the effect of breaking the root chunks into their hierarchical descendants. - -\section support_model Support Model - -Blast&tm; requires that support chunks form an <em>exact cover</em> (see the definition of exact coverage in \ref pagedefinitions). -The geometric interpretation of exact coverage is that the support chunks fill the space of the root (unfractured) chunk, without -any volume being covered by more than one chunk. A helper function is provided to modify a set of chunk descriptors so that they -have exact coverage. This function fills in missing coverage by assigning support to chunks at the highest place possible (closest -to root) in the hierarchy, and redundant support is removed: if a chunk and one of its descendant chunks are both marked as support, -the function will remove support from the descendant chunk. - -Support chunks that are joined by bonds will be grouped together in the same actor when fracturing occurs. Bonds may be defined -between any two support chunks, or between a support chunk and "the world." There is no corresponding "world chunk," but the bond -represents a connection between the chunk and its external environment. All chunks with a support graph connected to the world -will be put into the same actor. An expected use case is to make this actor static (or kinematic). Actors may be queried to -determine if they are "world-bound." - -In order to take advantage of the chunk hieararchy to reduce the number of chunks which represent an actor physically and -graphically, Blast&tm; calculates a list of <em>visible chunks</em> from the support chunks in an actor. These may be the support -chunks, or they may be ancestors of support chunks if all descendant support chunks are in the actor. - -Support chunks do not have to be leaves in the chunk hierarchy, nor do they have to be at the same depth in the hierarchy. Children -of support chunks will always be the sole chunk in their actor, since there are no bonds defined between them. If an actor consists -of a <em>subsupport chunk</em> (see \ref pagedefinitions), the visible chunk is the same chunk. The same is true if an actor consists -of a <em>single</em> support chunk. - -\section damage_model Damage Model - -Damage is defined as loss of an actor's material integrity. This is modeled by a simple health value associated with the bonds and -chunks in the support graph. The user applies damage to an actor at a given location, with a maximum effect radius. The resulting -loss of bond and chunk health is determined by a user-defined <em>material function</em>. In this way the user can customize the -effect of damage based upon the bonds' properties such as normal and area, as well as distance from impact location. - -Damage is applied during the processing of a damage event buffer. After all damage events are processed, bonds with non-positive -healths are considered to be broken. Blast&tm; performs island detection on the support graph to find all groups of support chunks -that are connected by unbroken bonds, and any new islands found result in new actors. - -If an actor is composed of a single support or subsupport chunk with subsupport descendants, then there is no bond structure to model -damage. Instead, such a chunk is considered to have its own health value, which may be decreased by damage. When such a lower-support -(see \ref pagedefinitions) chunk's health is non-positive, its associated actor is deleted and replaced by actors that represent its child -chunks, if any. - -The effect of damage on leaf chunks depends upon which API is used. The low-level API does not delete leaf chunks. It is up to the -user to delete them, and manage their physical and graphical representation outside of Blast&tm; if so desired. - -\section backwards_compatibility Backwards Compatibility - -The Blast&tm; SDK provides the \ref pageimporter tool to allow APEX Destructible assets to be reused. A Blast&tm; asset requires more information -in its support graph than an APEX Destuctible asset does. Whereas the latter only contains a list of chunk neighbors, the bonds used by Blast&tm; -include a small amount of geometric information, as described in \ref asset_structure. - -<br> -*/ +/*! \page pageintroduction Introduction
+
+Blast&tm; is an NVIDIA GameWorks&tm; destruction library. It consists of a \ref pagellapi, a \ref pagehlapi (Blast&tm; Toolkit
+or BlastTk), and \ref pageextapi (Blast&tm; Extensions or BlastExt). This layered API is designed to allow short ramp-up time for
+first usage (through the Ext and Tk APIs) while also allowing for customization and optimization by experienced users through the
+low-level API.
+
+This library is intended to replace APEX Destruction. It is being developed with years of user feedback and experience, with the
+goal of addressing shortcomings in performance, stability, and customizability of the APEX Destruction module.
+
+\section asset_structure Asset Structure
+
+Blast&tm; is currently designed to support rigid body, pre-fractured destruction. Future versions may support runtime fracturing
+or deformation.
+
+The static data associated with a destructible is stored in an \{\em asset\}. Assets are instanced into actors, which may
+be damaged and fractured. When fractured, actors are broken into pieces called \{\em chunks\}. Connected groups of chunks
+belong to new actors. The grouping of chunks into actors is determined by the support graph in the asset.
+
+Chunks are defined hierarchically, so that when a chunk is fractured its child chunks are created. The user may tag any
+chunk in this hierarchy as a \{\em support\} chunk. This is covered in more detail in the \ref support_model section. The user
+also supplies a description of the connections between support chunks. A \{\em bond\} represents the surface joining neighboring
+chunks. A bond is represented by a surface centroid, an average surface normal, and the surface area. These quantities don't
+need to be exact for Blast&tm; to operate effectively.
+
+Multiple chunk hierarchies may exist in a single asset. The <em>root chunks</em> (see \ref pagedefinitions) will be visible when the
+asset is initially instanced. Subsequent fracturing has the effect of breaking the root chunks into their hierarchical descendants.
+
+\section support_model Support Model
+
+Blast&tm; requires that support chunks form an <em>exact cover</em> (see the definition of exact coverage in \ref pagedefinitions).
+The geometric interpretation of exact coverage is that the support chunks fill the space of the root (unfractured) chunk, without
+any volume being covered by more than one chunk. A helper function is provided to modify a set of chunk descriptors so that they
+have exact coverage. This function fills in missing coverage by assigning support to chunks at the highest place possible (closest
+to root) in the hierarchy, and redundant support is removed: if a chunk and one of its descendant chunks are both marked as support,
+the function will remove support from the descendant chunk.
+
+Support chunks that are joined by bonds will be grouped together in the same actor when fracturing occurs. Bonds may be defined
+between any two support chunks, or between a support chunk and "the world." There is no corresponding "world chunk," but the bond
+represents a connection between the chunk and its external environment. All chunks with a support graph connected to the world
+will be put into the same actor. An expected use case is to make this actor static (or kinematic). Actors may be queried to
+determine if they are "world-bound."
+
+In order to take advantage of the chunk hieararchy to reduce the number of chunks which represent an actor physically and
+graphically, Blast&tm; calculates a list of <em>visible chunks</em> from the support chunks in an actor. These may be the support
+chunks, or they may be ancestors of support chunks if all descendant support chunks are in the actor.
+
+Support chunks do not have to be leaves in the chunk hierarchy, nor do they have to be at the same depth in the hierarchy. Children
+of support chunks will always be the sole chunk in their actor, since there are no bonds defined between them. If an actor consists
+of a <em>subsupport chunk</em> (see \ref pagedefinitions), the visible chunk is the same chunk. The same is true if an actor consists
+of a <em>single</em> support chunk.
+
+\section damage_model Damage Model
+
+Damage is defined as loss of an actor's material integrity. This is modeled by a simple health value associated with the bonds and
+chunks in the support graph. The user applies damage to an actor at a given location, with a maximum effect radius. The resulting
+loss of bond and chunk health is determined by a user-defined <em>material function</em>. In this way the user can customize the
+effect of damage based upon the bonds' properties such as normal and area, as well as distance from impact location.
+
+Damage is applied during the processing of a damage event buffer. After all damage events are processed, bonds with non-positive
+healths are considered to be broken. Blast&tm; performs island detection on the support graph to find all groups of support chunks
+that are connected by unbroken bonds, and any new islands found result in new actors.
+
+If an actor is composed of a single support or subsupport chunk with subsupport descendants, then there is no bond structure to model
+damage. Instead, such a chunk is considered to have its own health value, which may be decreased by damage. When such a lower-support
+(see \ref pagedefinitions) chunk's health is non-positive, its associated actor is deleted and replaced by actors that represent its child
+chunks, if any.
+
+The effect of damage on leaf chunks depends upon which API is used. The low-level API does not delete leaf chunks. It is up to the
+user to delete them, and manage their physical and graphical representation outside of Blast&tm; if so desired.
+
+\section backwards_compatibility Backwards Compatibility
+
+The Blast&tm; SDK provides the \ref pageimporter tool to allow APEX Destructible assets to be reused. A Blast&tm; asset requires more information
+in its support graph than an APEX Destuctible asset does. Whereas the latter only contains a list of chunk neighbors, the bonds used by Blast&tm;
+include a small amount of geometric information, as described in \ref asset_structure.
+
+<br>
+*/
diff --git a/docs/_source/legacy_converter.txt b/docs/_source/legacy_converter.txt index ff7048b..d5479b3 100644..100755 --- a/docs/_source/legacy_converter.txt +++ b/docs/_source/legacy_converter.txt @@ -1,28 +1,28 @@ -/*! \page pageconverter LegacyConverter - -\verbatim - -USAGE: - - LegacyConverter <infile> [-t <type>] [-o <outfile>] [-e <encoding>] - -Where: - - <infile> (required) Input legacy format file. - - -t <type> - (optional) The file format of <infile>. Must be one of: {llasset, tkasset, bpxa, pllasset, ptkasset, pbpxa} (case insensitive). - If not given, the file extension of <infile> is used. - - -outfile <outfile> - (optional) Filename (including path) of the output converted file. - If not given, the filename <infile> is used, with extension (if it has one) changed to .blast. - - -e <encoding> - (optional) Encoding to use for output file. Must be one of: {cpnb, raw} (case insensitive). - If not given, cpnb (Cap'n Proto binary) is used. - -\endverbatim - -<br> -*/ +/*! \page pageconverter LegacyConverter
+
+\verbatim
+
+USAGE:
+
+ LegacyConverter <infile> [-t <type>] [-o <outfile>] [-e <encoding>]
+
+Where:
+
+ <infile> (required) Input legacy format file.
+
+ -t <type>
+ (optional) The file format of <infile>. Must be one of: {llasset, tkasset, bpxa, pllasset, ptkasset, pbpxa} (case insensitive).
+ If not given, the file extension of <infile> is used.
+
+ -outfile <outfile>
+ (optional) Filename (including path) of the output converted file.
+ If not given, the filename <infile> is used, with extension (if it has one) changed to .blast.
+
+ -e <encoding>
+ (optional) Encoding to use for output file. Must be one of: {cpnb, raw} (case insensitive).
+ If not given, cpnb (Cap'n Proto binary) is used.
+
+\endverbatim
+
+<br>
+*/
diff --git a/docs/_source/sample_asset_viewer.txt b/docs/_source/sample_asset_viewer.txt index e1bcaf2..05632ef 100644..100755 --- a/docs/_source/sample_asset_viewer.txt +++ b/docs/_source/sample_asset_viewer.txt @@ -1,160 +1,160 @@ -/*! \page pagesampleassetviewer SampleAssetViewer - -The windows-specific <b>bin</b> subfolders contain the application SampleAssetViewer.exe. - -This application can load model file sets that are generated by the \ref pageimporter or \ref pageauthoring tools. A valid file set for this sample is one of the following: - --# An ExtPxAsset file and a graphics file: - - .blast file: contains the Nv::Blast::ExtPxAsset which stores collision hulls in addition to Blast data. Here you must use the --px option in when exporting from \ref pageimporter or \ref pageauthoring. - - .obj or .fbx file: stores the graphics data. --# An NvBlastAsset or TkAsset file, and a graphics + collision file: - - .blast file: contains an NvBlastAsset or Nv::Blast::TkAsset (use the --ll or --tk option, respectively, when exporting from \ref pageimporter or \ref pageauthoring). - - .fbx file: stores the graphics data along with embedded collision data. Here you must use the --fbxcollision option when exporting from \ref pageimporter or \ref pageauthoring to embed collision information. - -\section assetviewer_file_load Loading a Destructible Model - -To load a specific file set, make sure the all files in the file set (described above) have the same name (except for extension). Then use the commandline options - -\verbatim --t PATHNAME -n ASSETNAME -p "X Y Z" -r "AX AY AZ ANGLE" -\endverbatim - -Here, PATHNAME is the path to the directory containing the {.blast, .obj} or {.blast, .fbx} file set (described above). ASSETNAME is the common name of those files. -(X, Y, Z) is the translation to give to the actor that is created. (AX, AY, AZ, ANGLE) is the rotation axis and angle (in degrees) to apply to the actor. - -\section assetviewer_multifile_load Loading Multiple Destructible Models - -To load multiple destructible models, use a config file. The viewer reads .xml config files, which you can select using the command line argument - -\verbatim --x FILENAME -\endverbatim - -Running the application with no commandline arguments, the viewer will load <b>samples/resources/configs/assets.xml</b> by default. This file references -the models in the subdirectories of <b>samples/resources/models</b>. - -\section using_assetviewer Using SampleAssetViewer - -Upon startup, the viewer will instance its first asset in its assets list. Using the default assets.xml, this is a brick wall. - -The menu is displayed using an overlay on the left side of the screen. It is divided into many submenus, which are described below. - -In any scene, you may press <b>'F'</b> to fire a box into the scene in the direction the camera is pointing. - -You may also press <b>SPACE</b> to toggle between damage and drag mode. (The mode is shown at the top of the screen.) In drag mode, dynamic objects can be manipulated by -placing the mouse cursor over them, and using <b>Left Mouse / Drag</b> to pull on the object. In damage mode, <b>left-clicking</b> a destructible actor will apply damage to it. - -You may select between three different damage tools using the <b>1, 2, and 3</b> keys. Each will color the damage sphere (shown at the mouse hit location) a different color: - -- (1) White - falloff damage. Damage is applied everywhere within the sphere. -- (2) Blue - cutter damage. Damage is applied only near the surface of the sphere. -- (3) Green - hierarchical damage. Damage is passed down the chunk hierarchy with every damage application, sometimes leading to smaller chunks from an initial damage application. - -You may change the size of the damage sphere using the center mouse wheel, or the \ref viewer_damage_tool menu (see below). - -Right mouse button-drag to rotate the camera, and move using W, S, A, and D for forward, back, left, and right, respectively. Q and E move the camera down and up, relative to the current orientation. - -Pressing 'R' will reset the scene. Pressing 'P' toggles physical simulation. - -\section viewermenuitems Menu Items - -\subsection viewer_scene Scene - -Here you can select which assets to add to the scene, set the material damage properties, and enable a stress solver. - -In Replace mode (the default, set by radio button), selecting assets in the Assets list will remove all destructible actors from the scene and insert the selected one. -In Append mode (the other radio button), selecting a new asset will insert its actor into the scene while keeping the others as well. - -You may also select actors in the Scene Actors list, and remove (or reload) the actor using the buttons below the list. Reloading an actor will restore it to its -unfractured state. - -Note, in addition to destructible actors, the Scene Actors list shows the boxes that were fired into the scene using the 'F' key. Holding down the 'F' key "charges" -the throw, increasing the cube's speed the longer you hold down the key. You may remove the cubes using the scene controls. All cubes will be removed when the scene -is reset. - -The Blast Material properties are used by the various damage tools available. - -- Health = the value which damage must exceed to break a bond or chunk -- Min Damage Threshold = a fraction of Health, below which damage has no effect -- Max Damage Threshold = a fraction of Health, equal to the maximum damage that can be applied per damage event - -A stress solver may be enabled by selcting the Stress Solver Enabled checkbox. When enabled, you will be presented with several options. -NOTE: you must then select the Stress Damage Enabled checkbox in order to allow stress to do damage to the actors in the scene.<br> -Bond Iterations Per Frame - is max amount of bonds allowed to be processed in one frame. The higher this value, the better quality of stress solver, but the time taken by it is increased linearly. 9You can -check this timing in \a Stats submenu.) Using this value stress solver takes a fixed amount of CPU time on assets of any size. So the more complex an asset is (the more bonds it has) the less total iterations (on all bonds) are made.<br> -Use graph reduction level param to simplify stress graph for large assets. You can look at stress graph by using the \a Debug Render submenu. -Stress linear and angular factors are corresponded to the amount of damage to be applied on bonds from linear and angular momentum of stress on every bond. - -Replay control section allows to control recording and replaying Blast&tm; events. It demonstrates the usage of \ref ExtSync extension. You may start/stop recording of Blast&tm; events (damage, split). -If you toggle to sync initial actors, once recording starts, the full Blast&tm; state is saved. - -\subsection viewer_blast Blast - -Here you may disable or enable impact damage, using the Impact Damage checkbox (on by default). - -The Fragility setting is a multiplier that turns impact forces into damage amounts. - -You can toggle to pass impact damage to stress solver instead of just applying it with simple damage shader. Impact impulse will be passed to stress graph and damage will be applied -according to stress solver settings mentioned above. - -When dragging static actors (with mouse dragging tool) stress impulse is also applied on stress graph. Use Dragging To Stress Factor to tune the amount. - -You can limit rigid body count with next setting, all the actors created above this count will be ignored. - -\subsection viewer_damage_tool Damage Tool - -Here you may set the effect of the damage caused by the damage tool (left mouse click) - -- Compressive Damage = the amount of damage that will be applied to bonds using the normal component -- Explosive Impulse = the radial impulse given to the fractured pieces -- Damage Radius = the size of the damage tool (also settable using the mouse wheel) -- Damage Profile = the damage function to use (equivalent to pressing the '1', '2', or '3' keys, see the section \ref using_assetviewer) - -\subsection viewer_stats Stats - -Here you will find various timers, counts, and sizes. A running graph shows the frame time in ms. - -The "Last X" times shown at the end of this list record the time spent during the last damage or split calls. These are broken down -into sections, each contributing to the parent time. "Child" function times are denoted by indentation. - -\subsection viewer_application Application - -Here you may pause the physics simulation (the same as pressing 'P') and reload shaders. - -\subsection viewer_debugrender Debug Render - -Here you may select wireframe rendering, which is useful for the various debug render options given. - -You may select the debug render options from the Blast Debug Render Mode dropdown. Note: pressing 'I' will cycle through this menu: - -- Disabled = no debug rendering -- Health Graph = draws bonds with color based upon bond health. Green = full health, red = low health. -- Centroids = draws a line segment starting at each bond centroid, pointing in the direction of the bond normal. Also draws a square -centered at the bond centroid, with the area of the bond. -- Health Graph + Centroids = the two options above, combined. -- Stress Graph = draws bonds with color based upon stress values. Green = low stress, red = high stress. -- Stress Graph + Nodes Impulse = same as Stress Graph plus a line segment indicating the impulse applied to each graph node. The length of the segment is scaled by the Blast Debug Render Scale control. -The green segments show the linear impulse, the red segments the rotational impulse. -- Stress Graph + Bonds Impulse = same as Stress Graph plus a line segment indicating the impulse applied to each bond. The length of the segment is scaled by the Blast Debug Render Scale control. -The green segments show the linear impulse, the red segments the rotational impulse. - -\subsection viewer_physx PhysX - -This menu controls PhysX&tm; simulation parameters. Here you may choose to use fixed time steps (off by default), and set the time step (if Use Fixed Timestep is checked) with the Fixed Timestep control. - -If a suitable GPU is available, GPU Physics may be enabled using the Use GPU Physics control. - -\subsection viewer_renderer Renderer - -Here you may change the lighting, shadow, and ambient occlusion (HBAO) options. - -\subsection viewer_hints_help Hints / Help - -Gives selected keyboard shortcuts. - - -<br> -See \ref pagecopyrights for license information regarding third-party software used by the samples. - -<br> -*/ +/*! \page pagesampleassetviewer SampleAssetViewer
+
+The windows-specific <b>bin</b> subfolders contain the application SampleAssetViewer.exe.
+
+This application can load model file sets that are generated by the \ref pageimporter or \ref pageauthoring tools. A valid file set for this sample is one of the following:
+
+-# An ExtPxAsset file and a graphics file:
+ - .blast file: contains the Nv::Blast::ExtPxAsset which stores collision hulls in addition to Blast data. Here you must use the --px option in when exporting from \ref pageimporter or \ref pageauthoring.
+ - .obj or .fbx file: stores the graphics data.
+-# An NvBlastAsset or TkAsset file, and a graphics + collision file:
+ - .blast file: contains an NvBlastAsset or Nv::Blast::TkAsset (use the --ll or --tk option, respectively, when exporting from \ref pageimporter or \ref pageauthoring).
+ - .fbx file: stores the graphics data along with embedded collision data. Here you must use the --fbxcollision option when exporting from \ref pageimporter or \ref pageauthoring to embed collision information.
+
+\section assetviewer_file_load Loading a Destructible Model
+
+To load a specific file set, make sure the all files in the file set (described above) have the same name (except for extension). Then use the commandline options
+
+\verbatim
+-t PATHNAME -n ASSETNAME -p "X Y Z" -r "AX AY AZ ANGLE"
+\endverbatim
+
+Here, PATHNAME is the path to the directory containing the {.blast, .obj} or {.blast, .fbx} file set (described above). ASSETNAME is the common name of those files.
+(X, Y, Z) is the translation to give to the actor that is created. (AX, AY, AZ, ANGLE) is the rotation axis and angle (in degrees) to apply to the actor.
+
+\section assetviewer_multifile_load Loading Multiple Destructible Models
+
+To load multiple destructible models, use a config file. The viewer reads .xml config files, which you can select using the command line argument
+
+\verbatim
+-x FILENAME
+\endverbatim
+
+Running the application with no commandline arguments, the viewer will load <b>samples/resources/configs/assets.xml</b> by default. This file references
+the models in the subdirectories of <b>samples/resources/models</b>.
+
+\section using_assetviewer Using SampleAssetViewer
+
+Upon startup, the viewer will instance its first asset in its assets list. Using the default assets.xml, this is a brick wall.
+
+The menu is displayed using an overlay on the left side of the screen. It is divided into many submenus, which are described below.
+
+In any scene, you may press <b>'F'</b> to fire a box into the scene in the direction the camera is pointing.
+
+You may also press <b>SPACE</b> to toggle between damage and drag mode. (The mode is shown at the top of the screen.) In drag mode, dynamic objects can be manipulated by
+placing the mouse cursor over them, and using <b>Left Mouse / Drag</b> to pull on the object. In damage mode, <b>left-clicking</b> a destructible actor will apply damage to it.
+
+You may select between three different damage tools using the <b>1, 2, and 3</b> keys. Each will color the damage sphere (shown at the mouse hit location) a different color:
+
+- (1) White - falloff damage. Damage is applied everywhere within the sphere.
+- (2) Blue - cutter damage. Damage is applied only near the surface of the sphere.
+- (3) Green - hierarchical damage. Damage is passed down the chunk hierarchy with every damage application, sometimes leading to smaller chunks from an initial damage application.
+
+You may change the size of the damage sphere using the center mouse wheel, or the \ref viewer_damage_tool menu (see below).
+
+Right mouse button-drag to rotate the camera, and move using W, S, A, and D for forward, back, left, and right, respectively. Q and E move the camera down and up, relative to the current orientation.
+
+Pressing 'R' will reset the scene. Pressing 'P' toggles physical simulation.
+
+\section viewermenuitems Menu Items
+
+\subsection viewer_scene Scene
+
+Here you can select which assets to add to the scene, set the material damage properties, and enable a stress solver.
+
+In Replace mode (the default, set by radio button), selecting assets in the Assets list will remove all destructible actors from the scene and insert the selected one.
+In Append mode (the other radio button), selecting a new asset will insert its actor into the scene while keeping the others as well.
+
+You may also select actors in the Scene Actors list, and remove (or reload) the actor using the buttons below the list. Reloading an actor will restore it to its
+unfractured state.
+
+Note, in addition to destructible actors, the Scene Actors list shows the boxes that were fired into the scene using the 'F' key. Holding down the 'F' key "charges"
+the throw, increasing the cube's speed the longer you hold down the key. You may remove the cubes using the scene controls. All cubes will be removed when the scene
+is reset.
+
+The Blast Material properties are used by the various damage tools available.
+
+- Health = the value which damage must exceed to break a bond or chunk
+- Min Damage Threshold = a fraction of Health, below which damage has no effect
+- Max Damage Threshold = a fraction of Health, equal to the maximum damage that can be applied per damage event
+
+A stress solver may be enabled by selcting the Stress Solver Enabled checkbox. When enabled, you will be presented with several options.
+NOTE: you must then select the Stress Damage Enabled checkbox in order to allow stress to do damage to the actors in the scene.<br>
+Bond Iterations Per Frame - is max amount of bonds allowed to be processed in one frame. The higher this value, the better quality of stress solver, but the time taken by it is increased linearly. 9You can
+check this timing in \a Stats submenu.) Using this value stress solver takes a fixed amount of CPU time on assets of any size. So the more complex an asset is (the more bonds it has) the less total iterations (on all bonds) are made.<br>
+Use graph reduction level param to simplify stress graph for large assets. You can look at stress graph by using the \a Debug Render submenu.
+Stress linear and angular factors are corresponded to the amount of damage to be applied on bonds from linear and angular momentum of stress on every bond.
+
+Replay control section allows to control recording and replaying Blast&tm; events. It demonstrates the usage of \ref ExtSync extension. You may start/stop recording of Blast&tm; events (damage, split).
+If you toggle to sync initial actors, once recording starts, the full Blast&tm; state is saved.
+
+\subsection viewer_blast Blast
+
+Here you may disable or enable impact damage, using the Impact Damage checkbox (on by default).
+
+The Fragility setting is a multiplier that turns impact forces into damage amounts.
+
+You can toggle to pass impact damage to stress solver instead of just applying it with simple damage shader. Impact impulse will be passed to stress graph and damage will be applied
+according to stress solver settings mentioned above.
+
+When dragging static actors (with mouse dragging tool) stress impulse is also applied on stress graph. Use Dragging To Stress Factor to tune the amount.
+
+You can limit rigid body count with next setting, all the actors created above this count will be ignored.
+
+\subsection viewer_damage_tool Damage Tool
+
+Here you may set the effect of the damage caused by the damage tool (left mouse click)
+
+- Compressive Damage = the amount of damage that will be applied to bonds using the normal component
+- Explosive Impulse = the radial impulse given to the fractured pieces
+- Damage Radius = the size of the damage tool (also settable using the mouse wheel)
+- Damage Profile = the damage function to use (equivalent to pressing the '1', '2', or '3' keys, see the section \ref using_assetviewer)
+
+\subsection viewer_stats Stats
+
+Here you will find various timers, counts, and sizes. A running graph shows the frame time in ms.
+
+The "Last X" times shown at the end of this list record the time spent during the last damage or split calls. These are broken down
+into sections, each contributing to the parent time. "Child" function times are denoted by indentation.
+
+\subsection viewer_application Application
+
+Here you may pause the physics simulation (the same as pressing 'P') and reload shaders.
+
+\subsection viewer_debugrender Debug Render
+
+Here you may select wireframe rendering, which is useful for the various debug render options given.
+
+You may select the debug render options from the Blast Debug Render Mode dropdown. Note: pressing 'I' will cycle through this menu:
+
+- Disabled = no debug rendering
+- Health Graph = draws bonds with color based upon bond health. Green = full health, red = low health.
+- Centroids = draws a line segment starting at each bond centroid, pointing in the direction of the bond normal. Also draws a square
+centered at the bond centroid, with the area of the bond.
+- Health Graph + Centroids = the two options above, combined.
+- Stress Graph = draws bonds with color based upon stress values. Green = low stress, red = high stress.
+- Stress Graph + Nodes Impulse = same as Stress Graph plus a line segment indicating the impulse applied to each graph node. The length of the segment is scaled by the Blast Debug Render Scale control.
+The green segments show the linear impulse, the red segments the rotational impulse.
+- Stress Graph + Bonds Impulse = same as Stress Graph plus a line segment indicating the impulse applied to each bond. The length of the segment is scaled by the Blast Debug Render Scale control.
+The green segments show the linear impulse, the red segments the rotational impulse.
+
+\subsection viewer_physx PhysX
+
+This menu controls PhysX&tm; simulation parameters. Here you may choose to use fixed time steps (off by default), and set the time step (if Use Fixed Timestep is checked) with the Fixed Timestep control.
+
+If a suitable GPU is available, GPU Physics may be enabled using the Use GPU Physics control.
+
+\subsection viewer_renderer Renderer
+
+Here you may change the lighting, shadow, and ambient occlusion (HBAO) options.
+
+\subsection viewer_hints_help Hints / Help
+
+Gives selected keyboard shortcuts.
+
+
+<br>
+See \ref pagecopyrights for license information regarding third-party software used by the samples.
+
+<br>
+*/
diff --git a/docs/_source/samples.txt b/docs/_source/samples.txt index 56180e9..a7f0ef3 100644..100755 --- a/docs/_source/samples.txt +++ b/docs/_source/samples.txt @@ -1,8 +1,8 @@ -/*! \page pagesamples Samples - -The samples folder contains: - -\subpage pagesampleassetviewer - -<br> -*/ +/*! \page pagesamples Samples
+
+The samples folder contains:
+
+\subpage pagesampleassetviewer
+
+<br>
+*/
diff --git a/docs/_source/tools.txt b/docs/_source/tools.txt index ecded90..21d83ee 100644..100755 --- a/docs/_source/tools.txt +++ b/docs/_source/tools.txt @@ -1,20 +1,20 @@ -/*! \page pagetools Tools - - -<br> -See \ref pagecopyrights for license information regarding third-party software used by the tools. - -<br> -\subpage pageimporter - Import Apex assets into Blast&tm; format. - - -<br> -\subpage pageauthoring - Command line authoring tool. - - -<br> -\subpage pageconverter - Convert serialized data from legacy formats (.llasset, .tkasset, .bpxa, .pllasset, .ptkasset, .pbpxa) to the current unified (.blast) format. - - -<br> -*/ +/*! \page pagetools Tools
+
+
+<br>
+See \ref pagecopyrights for license information regarding third-party software used by the tools.
+
+<br>
+\subpage pageimporter - Import Apex assets into Blast&tm; format.
+
+
+<br>
+\subpage pageauthoring - Command line authoring tool.
+
+
+<br>
+\subpage pageconverter - Convert serialized data from legacy formats (.llasset, .tkasset, .bpxa, .pllasset, .ptkasset, .pbpxa) to the current unified (.blast) format.
+
+
+<br>
+*/
|