Asset Utilities (NvBlastExtAssetUtils)
NvBlastExtAssetUtils provides simple utility functions for modifying NvBlastAsset objects. Three functions are provided, described in the following sections.
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 oldAsset,
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);
Memory for the new asset is allocated using the allocator available through NvBlastGlobals (Globals API (NvBlastGlobals)). Therefore the new asset may be freed using
NVBLAST_FREE(newAsset);
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:
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);
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:
NVBLAST_FREE(mergedDesc.chunkDescs);
NVBLAST_FREE(mergedDesc.bondDescs);
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.