aboutsummaryrefslogtreecommitdiff
path: root/APEX_1.4/module/destructible/include/DestructibleAssetImpl.h
diff options
context:
space:
mode:
authorgit perforce import user <a@b>2016-10-25 12:29:14 -0600
committerSheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees>2016-10-25 18:56:37 -0500
commit3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch)
treefa6485c169e50d7415a651bf838f5bcd0fd3bfbd /APEX_1.4/module/destructible/include/DestructibleAssetImpl.h
downloadphysx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz
physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip
Initial commit:
PhysX 3.4.0 Update @ 21294896 APEX 1.4.0 Update @ 21275617 [CL 21300167]
Diffstat (limited to 'APEX_1.4/module/destructible/include/DestructibleAssetImpl.h')
-rw-r--r--APEX_1.4/module/destructible/include/DestructibleAssetImpl.h916
1 files changed, 916 insertions, 0 deletions
diff --git a/APEX_1.4/module/destructible/include/DestructibleAssetImpl.h b/APEX_1.4/module/destructible/include/DestructibleAssetImpl.h
new file mode 100644
index 00000000..28267af4
--- /dev/null
+++ b/APEX_1.4/module/destructible/include/DestructibleAssetImpl.h
@@ -0,0 +1,916 @@
+/*
+ * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+ *
+ * NVIDIA CORPORATION and its licensors retain all intellectual property
+ * and proprietary rights in and to this software, related documentation
+ * and any modifications thereto. Any use, reproduction, disclosure or
+ * distribution of this software and related documentation without an express
+ * license agreement from NVIDIA CORPORATION is strictly prohibited.
+ */
+
+
+#ifndef DESTRUCTIBLE_ASSET_IMPL_H
+#define DESTRUCTIBLE_ASSET_IMPL_H
+
+#include "Apex.h"
+#include "PsArray.h"
+#include "ApexSDKHelpers.h"
+#include "DestructibleAsset.h"
+#include "ApexSharedUtils.h"
+#include "ApexAssetTracker.h"
+#include "DestructibleActorParam.h"
+#include "ApexUsingNamespace.h"
+#include "DestructibleAssetParameters.h"
+#include "MeshCookedCollisionStreamsAtScale.h"
+#include "MeshCookedCollisionStream.h"
+#include "DestructibleAssetCollisionDataSet.h"
+#include "CachedOverlaps.h"
+
+#include "PxConvexMesh.h"
+
+#include "authoring/Fracturing.h"
+
+#include "ApexActor.h"
+
+namespace nvidia
+{
+namespace apex
+{
+class DestructiblePreview;
+}
+namespace destructible
+{
+class ModuleDestructibleImpl;
+
+
+/**
+ Descriptor used to create a Destructible actor.
+*/
+class DestructibleActorDesc : public ApexDesc
+{
+public:
+
+ /**
+ \brief Constructor sets to default.
+ */
+ PX_INLINE DestructibleActorDesc() : ApexDesc()
+ {
+ setToDefault();
+ }
+
+ /**
+ \brief Resets descriptor to default settings.
+ */
+ PX_INLINE void setToDefault()
+ {
+ ApexDesc::setToDefault();
+
+ physX3Template = NULL;
+ crumbleEmitterName = NULL;
+ dustEmitterName = NULL;
+ globalPose = PxMat44(PxIdentity);
+ scale = PxVec3(1.0f);
+ dynamic = false;
+ supportDepth = 0;
+ formExtendedStructures = false;
+ useAssetDefinedSupport = false;
+ useWorldSupport = false;
+ overrideSkinnedMaterials = NULL;
+ overrideSkinnedMaterialCount = 0;
+ overrideStaticMaterials = NULL;
+ overrideStaticMaterialCount = 0;
+ renderStaticChunksSeparately = true;
+ destructibleParameters.setToDefault();
+ }
+
+ /**
+ Returns true iff an object can be created using this descriptor.
+ */
+ PX_INLINE bool isValid() const
+ {
+ const float det = (globalPose.column0.getXYZ().cross(globalPose.column1.getXYZ())).dot(globalPose.column2.getXYZ());
+ if (!PxEquals(det, 1.0f, 0.001f))
+ {
+ APEX_DEBUG_WARNING("Mirror transformations are not allowed in the DestructibleActor descriptor.");
+ return false;
+ }
+
+ if (scale.x <= 0 || scale.y <= 0 || scale.z <= 0)
+ {
+ APEX_DEBUG_WARNING("Negative scales are not allowed in the DestructibleActor descriptor.");
+ return false;
+ }
+
+ if (physX3Template && !physX3Template->isValid() )
+ {
+ APEX_DEBUG_WARNING("Invalid physx3 descriptor template in the DestructibleActor descriptor.");
+ return false;
+ }
+
+ if (overrideSkinnedMaterialCount > 0 && overrideSkinnedMaterials == NULL)
+ {
+ APEX_DEBUG_WARNING("overrideSkinnedMaterials is NULL, but overrideSkinnedMaterialCount > 0.");
+ return false;
+ }
+
+ if (overrideStaticMaterialCount > 0 && overrideStaticMaterials == NULL)
+ {
+ APEX_DEBUG_WARNING("overrideStaticMaterials is NULL, but overrideStaticMaterialCount > 0.");
+ return false;
+ }
+
+ // Note - Not checking shapeDescTemplate, since meshData is not supplied
+
+ return ApexDesc::isValid();
+ }
+
+ PhysX3DescTemplateImpl* physX3Template;
+
+ /**
+ The name of the MeshParticleSystem to use for crumbling. This overrides the crumble system defined
+ in the DestructibleAsset if specified.
+ */
+ const char* crumbleEmitterName;
+
+ /**
+ The name of the MeshParticleSystem to use for fracture-line dust. This overrides the dust system defined
+ in the DestructibleAsset if specified.
+ */
+ const char* dustEmitterName;
+
+ /**
+ Initial global pose of undamaged destructible
+ */
+ PxMat44 globalPose;
+
+ /**
+ 3D scale
+ */
+ PxVec3 scale;
+
+ /**
+ Whether or not the destructible starts life as a dynamic actor
+ */
+ bool dynamic;
+
+ /**
+ The chunk hierarchy depth at which to create a support graph. Higher depth levels give more detailed support,
+ but will give a higher computational load. Chunks below the support depth will never be supported.
+ */
+ uint32_t supportDepth;
+
+ /**
+ If set, and the destructible is initially static, it will become part of an extended support
+ structure if it is in contact with another static destructible that also has this flag set.
+ */
+ bool formExtendedStructures;
+
+ /**
+ If set, then chunks which are tagged as "support" chunks (via DestructibleChunkDesc::isSupportChunk)
+ will have environmental support in static destructibles.
+
+ Note: if both ASSET_DEFINED_SUPPORT and WORLD_SUPPORT are set, then chunks must be tagged as
+ "support" chunks AND overlap the PxScene's static geometry in order to be environmentally supported.
+ */
+ bool useAssetDefinedSupport;
+
+ /**
+ If set, then chunks which overlap the PxScene's static geometry will have environmental support in
+ static destructibles.
+
+ Note: if both ASSET_DEFINED_SUPPORT and WORLD_SUPPORT are set, then chunks must be tagged as
+ "support" chunks AND overlap the PxScene's static geometry in order to be environmentally supported.
+ */
+ bool useWorldSupport;
+
+ /*
+ If true, static chunks will be renderered separately from dynamic chunks, as a single mesh (not using skinning).
+ This parameter is ignored if the 'dynamic' parameter is true.
+ Default value = false.
+ */
+ bool renderStaticChunksSeparately;
+
+ /**
+ Per-actor material names for the skinned mesh
+ */
+ const char** overrideSkinnedMaterials;
+
+ /**
+ Size of overrideSkinnedMaterials array
+ */
+ uint32_t overrideSkinnedMaterialCount;
+
+ /**
+ Per-actor material names for the static mesh
+ */
+ const char** overrideStaticMaterials;
+
+ /**
+ Size of overrideStaticMaterials array
+ */
+ uint32_t overrideStaticMaterialCount;
+
+ /**
+ Initial destructible parameters. These may be changed at runtime.
+ */
+ DestructibleParameters destructibleParameters;
+};
+
+
+/**
+ Set of sets of convex meshes [scale#][part#]
+*/
+class DestructibleConvexMeshContainer
+{
+public:
+ struct ConvexMeshSet : public UserAllocated
+ {
+ ConvexMeshSet() : mReferenceCount(0) {}
+
+ physx::Array<PxConvexMesh*> mSet;
+ uint32_t mReferenceCount;
+ };
+
+ ~DestructibleConvexMeshContainer() { reset(); }
+
+ uint32_t size() const
+ {
+ return mConvexMeshSets.size();
+ }
+
+ physx::Array<PxConvexMesh*>& operator [] (uint32_t i) const
+ {
+ return mConvexMeshSets[i]->mSet;
+ }
+
+ uint32_t getReferenceCount(uint32_t i) const
+ {
+ return mConvexMeshSets[i]->mReferenceCount;
+ }
+ void incReferenceCount(uint32_t i)
+ {
+ ++mConvexMeshSets[i]->mReferenceCount;
+ }
+ bool decReferenceCount(uint32_t i)
+ {
+ if (mConvexMeshSets[i]->mReferenceCount == 0)
+ return false;
+ --mConvexMeshSets[i]->mReferenceCount;
+ return true;
+ }
+
+ void resize(uint32_t newSize)
+ {
+ const uint32_t oldSize = size();
+ mConvexMeshSets.resize(newSize);
+ for (uint32_t i = oldSize; i < newSize; ++i)
+ {
+ mConvexMeshSets[i] = PX_NEW(ConvexMeshSet);
+ }
+ }
+
+ void reset(bool force = true)
+ {
+ for (uint32_t i = mConvexMeshSets.size(); i--;)
+ {
+ ConvexMeshSet* meshSet = mConvexMeshSets[i];
+ if (meshSet != NULL)
+ {
+ if (force)
+ {
+ PX_DELETE(meshSet);
+ mConvexMeshSets[i] = NULL;
+ }
+ else
+ {
+ if (meshSet->mReferenceCount == 0)
+ {
+ // Release the PhysX convex mesh pointers
+ for (uint32_t j=0; j<meshSet->mSet.size(); j++)
+ {
+ PxConvexMesh* convexMesh = meshSet->mSet[j];
+ if (convexMesh == NULL)
+ {
+ continue;
+ }
+ convexMesh->release();
+ }
+
+ meshSet->mSet.resize(0);
+ PX_DELETE(meshSet);
+ mConvexMeshSets.replaceWithLast(i);
+ }
+ }
+ }
+ }
+ if (force)
+ {
+ mConvexMeshSets.reset();
+ }
+ }
+
+private:
+ physx::Array<ConvexMeshSet*> mConvexMeshSets;
+};
+
+
+/**
+ Destructible asset collision data. Caches collision data for a DestructibleAsset at
+ various scales.
+*/
+
+#define kDefaultDestructibleAssetCollisionScaleTolerance (0.0001f)
+
+class DestructibleAssetCollision : public ApexResource
+{
+public:
+
+ struct Version
+ {
+ enum Enum
+ {
+ First = 0,
+ // New versions must be put here. There is no need to explicitly number them. The
+ // numbers above were put there to conform to the old DestructionToolStreamVersion enum.
+
+ Count,
+ Current = Count - 1
+ };
+ };
+
+ DestructibleAssetCollision();
+ DestructibleAssetCollision(NvParameterized::Interface* params);
+ ~DestructibleAssetCollision();
+
+ void setDestructibleAssetToCook(class DestructibleAssetImpl* asset);
+
+ bool addScale(const PxVec3& scale);
+
+ bool cookAll();
+
+ bool cookScale(const PxVec3& scale);
+
+ void resize(uint32_t hullCount);
+
+ const char* getAssetName() const
+ {
+ return mParams->assetName;
+ }
+ DestructibleAssetImpl* getAsset() { return mAsset; }
+ PxConvexMesh* getConvexMesh(uint32_t hullIndex, const PxVec3& scale);
+
+ PxFileBuf& deserialize(PxFileBuf& stream, const char* assetName);
+ PxFileBuf& serialize(PxFileBuf& stream) const;
+
+ bool platformAndVersionMatch() const;
+ void setPlatformAndVersion();
+
+ uint32_t memorySize() const;
+
+ MeshCookedCollisionStreamsAtScale* getCollisionAtScale(const PxVec3& scale);
+
+ physx::Array<PxConvexMesh*>* getConvexMeshesAtScale(const PxVec3& scale);
+
+ void clearUnreferencedSets();
+ // Spit out warnings to the error stream for any referenced sets
+ void reportReferencedSets();
+ bool incReferenceCount(int scaleIndex);
+ bool decReferenceCount(int scaleIndex);
+
+ void merge(DestructibleAssetCollision& collisionSet);
+
+ int32_t getScaleIndex(const PxVec3& scale, float tolerance) const;
+
+private:
+ DestructibleAssetCollisionDataSet* mParams;
+ bool mOwnsParams;
+
+ class DestructibleAssetImpl* mAsset;
+ DestructibleConvexMeshContainer mConvexMeshContainer;
+};
+
+#define OFFSET_FN(_classname, _membername) static uint32_t _membername##Offset() { return PX_OFFSET_OF(_classname, _membername); }
+
+class DestructibleAssetImpl : public ApexResource
+{
+public:
+
+ enum
+ {
+ InvalidChunkIndex = 0xFFFF
+ };
+
+ enum ChunkFlags
+ {
+ SupportChunk = (1 << 0),
+ UnfracturableChunk = (1 << 1),
+ DescendantUnfractureable = (1 << 2),
+ UndamageableChunk = (1 << 3),
+ UncrumbleableChunk = (1 << 4),
+#if APEX_RUNTIME_FRACTURE
+ RuntimeFracturableChunk = (1 << 5),
+#endif
+
+ Instanced = (1 << 8),
+ };
+
+ struct ChunkInstanceBufferDataElement
+ {
+ PxVec3 translation;
+ PxMat33 scaledRotation;
+ PxVec2 uvOffset;
+ PxVec3 localOffset;
+
+ OFFSET_FN(ChunkInstanceBufferDataElement, translation)
+ OFFSET_FN(ChunkInstanceBufferDataElement, scaledRotation)
+ OFFSET_FN(ChunkInstanceBufferDataElement, uvOffset)
+ OFFSET_FN(ChunkInstanceBufferDataElement, localOffset)
+ };
+
+ struct ScatterInstanceBufferDataElement
+ {
+ PxVec3 translation;
+ PxMat33 scaledRotation;
+ float alpha;
+
+ OFFSET_FN(ScatterInstanceBufferDataElement, translation)
+ OFFSET_FN(ScatterInstanceBufferDataElement, scaledRotation)
+ OFFSET_FN(ScatterInstanceBufferDataElement, alpha)
+ };
+
+ struct ScatterMeshInstanceInfo
+ {
+ ScatterMeshInstanceInfo()
+ : m_actor(NULL)
+ , m_instanceBuffer(NULL)
+ , m_IBSize(0)
+ {}
+
+ ~ScatterMeshInstanceInfo();
+
+ RenderMeshActor* m_actor;
+ UserRenderInstanceBuffer* m_instanceBuffer;
+ uint32_t m_IBSize;
+ physx::Array<ScatterInstanceBufferDataElement> m_instanceBufferData;
+ };
+
+ DestructibleAssetImpl(ModuleDestructibleImpl* module, DestructibleAsset* api, const char* name);
+ DestructibleAssetImpl(ModuleDestructibleImpl* module, DestructibleAsset* api, NvParameterized::Interface* params, const char* name);
+ ~DestructibleAssetImpl();
+
+ const NvParameterized::Interface* getAssetNvParameterized() const
+ {
+ return mParams;
+ }
+
+ DestructibleActor* createDestructibleActorFromDeserializedState(NvParameterized::Interface* params, Scene&);
+ DestructibleActor* createDestructibleActor(const NvParameterized::Interface& params, Scene&);
+ void releaseDestructibleActor(DestructibleActor& actor);
+
+ RenderMeshAsset* getRenderMeshAsset() const
+ {
+ return renderMeshAsset;
+ }
+ bool setRenderMeshAsset(RenderMeshAsset* newRenderMeshAsset);
+
+ bool setScatterMeshAssets(RenderMeshAsset** scatterMeshAssetArray, uint32_t scatterMeshAssetArraySize);
+
+ void createScatterMeshInstanceInfo();
+
+ UserRenderInstanceBufferDesc getScatterMeshInstanceBufferDesc();
+
+ uint32_t getScatterMeshAssetCount() const
+ {
+ return scatterMeshAssets.size();
+ }
+
+ virtual RenderMeshAsset* const * getScatterMeshAssets() const
+ {
+ return scatterMeshAssets.size() > 0 ? &scatterMeshAssets[0] : NULL;
+ }
+
+ RenderMeshAsset* getRuntimeRenderMeshAsset() const
+ {
+ return runtimeRenderMeshAsset;
+ }
+
+ uint32_t getInstancedChunkMeshCount() const
+ {
+ return m_instancedChunkMeshCount;
+ }
+
+ uint32_t getChunkCount() const
+ {
+ return (uint32_t)mParams->chunks.arraySizes[0];
+ }
+ uint32_t getDepthCount() const
+ {
+ return mParams->depthCount;
+ }
+ bool getScatterMeshAlwaysDrawFlag() const
+ {
+ return mParams->destructibleParameters.alwaysDrawScatterMesh;
+ }
+ uint32_t getChunkChildCount(uint32_t chunkIndex) const
+ {
+ if (chunkIndex >= (uint32_t)mParams->chunks.arraySizes[0])
+ {
+ return 0;
+ }
+ return (uint32_t)mParams->chunks.buf[chunkIndex].numChildren;
+ }
+ uint16_t getChunkDepth(uint32_t chunkIndex) const
+ {
+ if (chunkIndex >= (uint32_t)mParams->chunks.arraySizes[0])
+ {
+ return 0;
+ }
+ return mParams->chunks.buf[chunkIndex].depth;
+ }
+ int32_t getChunkChild(uint32_t chunkIndex, uint32_t childIndex) const
+ {
+ if (childIndex >= getChunkChildCount(chunkIndex))
+ {
+ return -1;
+ }
+ return int32_t(mParams->chunks.buf[chunkIndex].firstChildIndex + childIndex);
+ }
+ PxBounds3 getBounds() const
+ {
+ return mParams->bounds;
+ }
+ DestructibleParameters getParameters() const;
+ DestructibleInitParameters getInitParameters() const;
+ const char* getCrumbleEmitterName() const;
+ const char* getDustEmitterName() const;
+ const char* getFracturePatternName() const;
+ float getFractureImpulseScale() const
+ {
+ return mParams->destructibleParameters.fractureImpulseScale;
+ }
+ float getImpactVelocityThreshold() const
+ {
+ return mParams->destructibleParameters.impactVelocityThreshold;
+ }
+ void getStats(DestructibleAssetStats& stats) const;
+ void cacheChunkOverlapsUpToDepth(int32_t depth = -1);
+ float getNeighborPadding() const
+ {
+ return mParams->neighborPadding;
+ }
+
+ uint16_t getChunkParentIndex(uint32_t chunkIndex) const
+ {
+ PX_ASSERT(chunkIndex < (uint16_t)mParams->chunks.arraySizes[0]);
+ return mParams->chunks.buf[chunkIndex].parentIndex;
+ }
+
+ PxVec3 getChunkPositionOffset(uint32_t chunkIndex) const
+ {
+ PX_ASSERT(chunkIndex < (uint16_t)mParams->chunks.arraySizes[0]);
+ DestructibleAssetParametersNS::Chunk_Type& sourceChunk = mParams->chunks.buf[chunkIndex];
+ return (sourceChunk.flags & DestructibleAssetImpl::Instanced) == 0 ? PxVec3(0.0f) : mParams->chunkInstanceInfo.buf[sourceChunk.meshPartIndex].chunkPositionOffset;
+ }
+
+ PxVec2 getChunkUVOffset(uint32_t chunkIndex) const
+ {
+ PX_ASSERT(chunkIndex < (uint16_t)mParams->chunks.arraySizes[0]);
+ DestructibleAssetParametersNS::Chunk_Type& sourceChunk = mParams->chunks.buf[chunkIndex];
+ return (sourceChunk.flags & DestructibleAssetImpl::Instanced) == 0 ? PxVec2(0.0f) : mParams->chunkInstanceInfo.buf[sourceChunk.meshPartIndex].chunkUVOffset;
+ }
+
+ uint32_t getChunkFlags(uint32_t chunkIndex) const
+ {
+ PX_ASSERT(chunkIndex < (uint16_t)mParams->chunks.arraySizes[0]);
+ DestructibleAssetParametersNS::Chunk_Type& sourceChunk = mParams->chunks.buf[chunkIndex];
+ uint32_t flags = 0;
+ if (sourceChunk.flags & DestructibleAssetImpl::SupportChunk)
+ {
+ flags |= DestructibleAsset::ChunkEnvironmentallySupported;
+ }
+ if (sourceChunk.flags & DestructibleAssetImpl::UnfracturableChunk)
+ {
+ flags |= DestructibleAsset::ChunkAndDescendentsDoNotFracture;
+ }
+ if (sourceChunk.flags & DestructibleAssetImpl::UndamageableChunk)
+ {
+ flags |= DestructibleAsset::ChunkDoesNotFracture;
+ }
+ if (sourceChunk.flags & DestructibleAssetImpl::UncrumbleableChunk)
+ {
+ flags |= DestructibleAsset::ChunkDoesNotCrumble;
+ }
+ if (sourceChunk.flags & DestructibleAssetImpl::Instanced)
+ {
+ flags |= DestructibleAsset::ChunkIsInstanced;
+ }
+#if APEX_RUNTIME_FRACTURE
+ if (sourceChunk.flags & DestructibleAssetImpl::RuntimeFracturableChunk)
+ {
+ flags |= DestructibleAsset::ChunkRuntimeFracture;
+ }
+#endif
+ return flags;
+ }
+
+ uint32_t getPartIndex(uint32_t chunkIndex) const
+ {
+ PX_ASSERT(chunkIndex < (uint16_t)mParams->chunks.arraySizes[0]);
+ DestructibleAssetParametersNS::Chunk_Type& sourceChunk = mParams->chunks.buf[chunkIndex];
+ return (sourceChunk.flags & DestructibleAssetImpl::Instanced) == 0 ? sourceChunk.meshPartIndex : mParams->chunkInstanceInfo.buf[sourceChunk.meshPartIndex].partIndex;
+ }
+
+ uint32_t getChunkHullIndexStart(uint32_t chunkIndex) const
+ {
+ return mParams->chunkConvexHullStartIndices.buf[getPartIndex(chunkIndex)];
+ }
+
+ uint32_t getChunkHullIndexStop(uint32_t chunkIndex) const
+ {
+ return mParams->chunkConvexHullStartIndices.buf[getPartIndex(chunkIndex)+1];
+ }
+
+ uint32_t getChunkHullCount(uint32_t chunkIndex) const
+ {
+ const uint32_t partIndex = getPartIndex(chunkIndex);
+ return mParams->chunkConvexHullStartIndices.buf[partIndex+1] - mParams->chunkConvexHullStartIndices.buf[partIndex];
+ }
+
+ uint32_t getPartHullIndexStart(uint32_t partIndex) const
+ {
+ return mParams->chunkConvexHullStartIndices.buf[partIndex];
+ }
+
+ uint32_t getPartHullIndexStop(uint32_t partIndex) const
+ {
+ return mParams->chunkConvexHullStartIndices.buf[partIndex+1];
+ }
+
+ NvParameterized::Interface** getConvexHullParameters(uint32_t hullIndex) const
+ {
+ return mParams->chunkConvexHulls.buf + hullIndex;
+ }
+
+ PxBounds3 getChunkActorLocalBounds(uint32_t chunkIndex) const
+ {
+ const uint32_t partIndex = getPartIndex(chunkIndex);
+ PxBounds3 bounds = renderMeshAsset->getBounds(partIndex);
+ const PxVec3 offset = getChunkPositionOffset(chunkIndex);
+ bounds.minimum += offset;
+ bounds.maximum += offset;
+ return bounds;
+ }
+
+ const PxBounds3& getChunkShapeLocalBounds(uint32_t chunkIndex) const
+ {
+ const uint32_t partIndex = getPartIndex(chunkIndex);
+ return renderMeshAsset->getBounds(partIndex);
+ }
+
+ void applyTransformation(const PxMat44& transformation, float scale);
+ void applyTransformation(const PxMat44& transformation);
+ bool setPlatformMaxDepth(PlatformTag platform, uint32_t maxDepth);
+ bool removePlatformMaxDepth(PlatformTag platform);
+
+ CachedOverlapsNS::IntPair_DynamicArray1D_Type* getOverlapsAtDepth(uint32_t depth, bool create = true) const;
+
+ void clearChunkOverlaps(int32_t depth = -1, bool keepCachedFlag = false);
+ void addChunkOverlaps(IntPair* supportGraphEdges, uint32_t numSupportGraphEdges);
+ void removeChunkOverlaps(IntPair* supportGraphEdges, uint32_t numSupportGraphEdges, bool keepCachedFlagIfEmpty);
+
+ void traceSurfaceBoundary(physx::Array<PxVec3>& outPoints, uint16_t chunkIndex, const PxTransform& localToWorldRT, const PxVec3& scale,
+ float spacing, float jitter, float surfaceDistance, uint32_t maxPoints);
+
+ AuthObjTypeID getObjTypeID() const
+ {
+ return mAssetTypeID;
+ }
+ const char* getObjTypeName() const
+ {
+ return getClassName();
+ }
+ const char* getName() const
+ {
+ return mName.c_str();
+ }
+
+ void prepareForNewInstance();
+
+ void resetInstanceData();
+
+ // DestructibleAssetAuthoring methods
+ virtual bool prepareForPlatform(nvidia::apex::PlatformTag platform) const;
+
+ void setFractureImpulseScale(float scale)
+ {
+ mParams->destructibleParameters.fractureImpulseScale = scale;
+ }
+ void setImpactVelocityThreshold(float threshold)
+ {
+ mParams->destructibleParameters.impactVelocityThreshold = threshold;
+ }
+ void setChunkOverlapsCacheDepth(int32_t depth = -1);
+ void setParameters(const DestructibleParameters&);
+ void setInitParameters(const DestructibleInitParameters&);
+ void setCrumbleEmitterName(const char*);
+ void setDustEmitterName(const char*);
+ void setFracturePatternName(const char*);
+ void setNeighborPadding(float neighborPadding)
+ {
+ mParams->neighborPadding = neighborPadding;
+ }
+
+ uint32_t forceLoadAssets();
+ void initializeAssetNameTable();
+
+ void cleanup();
+ ModuleDestructibleImpl* getOwner()
+ {
+ return module;
+ }
+ DestructibleAsset* getAsset()
+ {
+ return mNxAssetApi;
+ }
+
+ static AuthObjTypeID getAssetTypeID()
+ {
+ return mAssetTypeID;
+ }
+
+ virtual NvParameterized::Interface* getDefaultActorDesc();
+ virtual NvParameterized::Interface* getDefaultAssetPreviewDesc();
+ virtual Actor* createApexActor(const NvParameterized::Interface& params, Scene& apexScene);
+
+ virtual AssetPreview* createApexAssetPreview(const ::NvParameterized::Interface& /*params*/, AssetPreviewScene* /*previewScene*/);
+
+ virtual bool isValidForActorCreation(const ::NvParameterized::Interface& /*parms*/, Scene& /*apexScene*/) const;
+
+ uint32_t getActorTransformCount() const
+ {
+ return (uint32_t)mParams->actorTransforms.arraySizes[0];
+ }
+
+ const PxMat44* getActorTransforms() const
+ {
+ return mParams->actorTransforms.buf;
+ }
+
+ void appendActorTransforms(const PxMat44* transforms, uint32_t transformCount);
+
+ void clearActorTransforms();
+
+ bool rebuildCollisionGeometry(uint32_t partIndex, const DestructibleGeometryDesc& geometryDesc);
+
+
+ NvParameterized::Interface* acquireNvParameterizedInterface(void)
+ {
+ NvParameterized::Interface* ret = mParams;
+
+ // don't set mParams to NULL here, because it's read during the asset release
+ mOwnsParams = false;
+
+ return ret;
+ }
+
+protected:
+
+ void init();
+
+ void calculateChunkDepthStarts();
+ void calculateChunkOverlaps(physx::Array<IntPair>& overlaps, uint32_t depth) const;
+
+ void reduceAccordingToLOD();
+
+ void updateChunkInstanceRenderResources(bool rewriteBuffers, void* userRenderData);
+
+ static bool chunksInProximity(const DestructibleAssetImpl& asset0, uint16_t chunkIndex0, const PxTransform& tm0, const PxVec3& scale0,
+ const DestructibleAssetImpl& asset1, uint16_t chunkIndex1, const PxTransform& tm1, const PxVec3& scale1,
+ float padding);
+
+ bool chunkAndSphereInProximity(uint16_t chunkIndex, const PxTransform& chunkTM, const PxVec3& chunkScale,
+ const PxVec3& sphereWorldCenter, float sphereRadius, float padding, float* distance);
+
+ static DestructibleParameters getParameters(const DestructibleAssetParametersNS::DestructibleParameters_Type&,
+ const DestructibleAssetParametersNS::DestructibleDepthParameters_DynamicArray1D_Type*);
+ static void setParameters(const DestructibleParameters&, DestructibleAssetParametersNS::DestructibleParameters_Type&);
+
+ static AuthObjTypeID mAssetTypeID;
+ static const char* getClassName()
+ {
+ return DESTRUCTIBLE_AUTHORING_TYPE_NAME;
+ }
+ ApexSimpleString mName;
+
+ DestructibleAsset* mNxAssetApi;
+ ModuleDestructibleImpl* module;
+
+ DestructibleAssetParameters* mParams;
+ bool mOwnsParams;
+
+ // Has a parameterized internal representation
+ Array<ConvexHullImpl> chunkConvexHulls;
+
+ // Runtime / derived
+ int32_t chunkOverlapCacheDepth;
+ Array<ResID> mStaticMaterialIDs;
+
+ ApexAssetTracker mCrumbleAssetTracker;
+ ApexAssetTracker mDustAssetTracker;
+
+ RenderMeshAsset* renderMeshAsset;
+ RenderMeshAsset* runtimeRenderMeshAsset;
+
+ physx::Array<PxConvexMesh*>* mCollisionMeshes;
+
+ uint32_t mRuntimeCookedConvexCount;
+
+ Array<RenderMeshAsset*> scatterMeshAssets;
+
+ // Instanced chunks
+ uint16_t m_instancedChunkMeshCount;
+ physx::Array<RenderMeshActor*> m_instancedChunkRenderMeshActors; // One per render mesh actor per instanced chunk
+ physx::Array<uint16_t> m_instancedChunkActorVisiblePart;
+ physx::Array<uint16_t> m_instancedChunkActorMap; // from instanced chunk instanceInfo index to actor index
+ physx::Array<UserRenderInstanceBuffer*> m_chunkInstanceBuffers;
+ physx::Array< physx::Array< ChunkInstanceBufferDataElement > > m_chunkInstanceBufferData;
+
+ // Scatter meshes
+ physx::Array<ScatterMeshInstanceInfo> m_scatterMeshInstanceInfo; // One per scatter mesh asset
+
+ uint32_t m_currentInstanceBufferActorAllowance;
+ bool m_needsInstanceBufferDataResize;
+ bool m_needsInstanceBufferResize;
+ nvidia::Mutex m_chunkInstanceBufferDataLock;
+
+ bool m_needsScatterMeshInstanceInfoCreation;
+
+ int32_t m_instancingRepresentativeActorIndex; // -1 => means it's not set
+
+ ResourceList m_destructibleList;
+ ResourceList m_previewList;
+
+ friend class DestructibleStructure;
+ friend class DestructiblePreviewImpl;
+ friend class DestructibleActorImpl;
+ friend class DestructibleActorJointImpl;
+ friend class DestructibleScene;
+ friend class ModuleDestructibleImpl;
+ friend class DestructibleAssetCollision;
+ friend class DestructibleModuleCachedData;
+ friend class ApexDamageEventReportDataImpl;
+ friend class DestructibleRenderableImpl;
+
+ NvParameterized::Interface* mApexDestructibleActorParams;
+
+private:
+ struct PlatformKeyValuePair
+ {
+ PlatformKeyValuePair(nvidia::apex::PlatformTag k, uint32_t v): key(k), val(v) {}
+ ~PlatformKeyValuePair() {}
+ nvidia::apex::PlatformTag key;
+ uint32_t val;
+ private:
+ PlatformKeyValuePair();
+ };
+ Array<PlatformKeyValuePair> m_platformFractureDepthMap;
+ bool setDepthCount(uint32_t targetDepthCount) const;
+};
+
+#ifndef WITHOUT_APEX_AUTHORING
+
+void gatherPartMesh(physx::Array<PxVec3>& vertices, physx::Array<uint32_t>& indices, const RenderMeshAsset* renderMeshAsset, uint32_t partIndex);
+
+class DestructibleAssetAuthoringImpl : public DestructibleAssetImpl
+{
+public:
+
+ ExplicitHierarchicalMeshImpl hMesh;
+ ExplicitHierarchicalMeshImpl hMeshCore;
+ CutoutSetImpl cutoutSet;
+ IntersectMesh intersectMesh;
+
+ DestructibleAssetAuthoringImpl(ModuleDestructibleImpl* module, DestructibleAsset* api, const char* name) :
+ DestructibleAssetImpl(module, api, name) {}
+
+ DestructibleAssetAuthoringImpl(ModuleDestructibleImpl* module, DestructibleAsset* api, NvParameterized::Interface* params, const char* name) :
+ DestructibleAssetImpl(module, api, params, name) {}
+
+ void setToolString(const char* toolString);
+
+ void cookChunks(const DestructibleAssetCookingDesc&, bool cacheOverlaps, uint32_t* chunkIndexMapUser2Apex, uint32_t* chunkIndexMapApex2User, uint32_t chunkIndexMapCount);
+
+ void trimCollisionGeometry(const uint32_t* partIndices, uint32_t partIndexCount, float maxTrimFraction = 0.2f);
+
+ void serializeFractureToolState(PxFileBuf& stream, nvidia::ExplicitHierarchicalMesh::Embedding& embedding) const;
+ void deserializeFractureToolState(PxFileBuf& stream, nvidia::ExplicitHierarchicalMesh::Embedding& embedding);
+
+private:
+ void trimCollisionGeometryInternal(const uint32_t* chunkIndices, uint32_t chunkIndexCount, const physx::Array<IntPair>& parentDepthOverlaps, uint32_t depth, float maxTrimFraction);
+};
+#endif
+
+}
+} // end namespace nvidia
+
+#endif // DESTRUCTIBLE_ASSET_IMPL_H