aboutsummaryrefslogtreecommitdiff
path: root/APEX_1.4/module/destructible/src/DestructiblePreviewImpl.cpp
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/src/DestructiblePreviewImpl.cpp
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/src/DestructiblePreviewImpl.cpp')
-rw-r--r--APEX_1.4/module/destructible/src/DestructiblePreviewImpl.cpp394
1 files changed, 394 insertions, 0 deletions
diff --git a/APEX_1.4/module/destructible/src/DestructiblePreviewImpl.cpp b/APEX_1.4/module/destructible/src/DestructiblePreviewImpl.cpp
new file mode 100644
index 00000000..4b633c91
--- /dev/null
+++ b/APEX_1.4/module/destructible/src/DestructiblePreviewImpl.cpp
@@ -0,0 +1,394 @@
+/*
+ * 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.
+ */
+
+
+#include "ApexDefs.h"
+#include "Apex.h"
+#include "ModuleDestructibleImpl.h"
+#include "DestructiblePreviewImpl.h"
+#include "DestructibleAssetImpl.h"
+#include "DestructiblePreviewParam.h"
+#include "RenderMeshAssetIntl.h"
+
+namespace nvidia
+{
+namespace destructible
+{
+
+DestructiblePreviewImpl::DestructiblePreviewImpl(DestructiblePreview* _api, DestructibleAssetImpl& _asset, const NvParameterized::Interface* params) :
+ ApexPreview(),
+ m_asset(&_asset),
+ m_api(_api),
+ m_instancedChunkCount(0)
+{
+ for (int meshN = 0; meshN < DestructibleActorMeshType::Count; ++meshN)
+ {
+ m_renderMeshActors[meshN] = NULL;
+ }
+
+ const DestructiblePreviewParam* destructiblePreviewParams = DYNAMIC_CAST(const DestructiblePreviewParam*)(params);
+
+ PX_ALLOCA(skinnedMaterialNames, const char*, destructiblePreviewParams->overrideSkinnedMaterialNames.arraySizes[0] > 0 ? destructiblePreviewParams->overrideSkinnedMaterialNames.arraySizes[0] : 1);
+ for (int i = 0; i < destructiblePreviewParams->overrideSkinnedMaterialNames.arraySizes[0]; ++i)
+ {
+ skinnedMaterialNames[i] = destructiblePreviewParams->overrideSkinnedMaterialNames.buf[i].buf;
+ }
+
+ PX_ASSERT(m_asset->getRenderMeshAsset());
+ RenderMeshActorDesc renderableMeshDesc;
+ renderableMeshDesc.visible = false;
+ renderableMeshDesc.indexBufferHint = RenderBufferHint::DYNAMIC;
+ renderableMeshDesc.keepVisibleBonesPacked = true;
+ renderableMeshDesc.overrideMaterials = destructiblePreviewParams->overrideSkinnedMaterialNames.arraySizes[0] > 0 ? (const char**)skinnedMaterialNames : NULL;
+ renderableMeshDesc.overrideMaterialCount = (uint32_t)destructiblePreviewParams->overrideSkinnedMaterialNames.arraySizes[0];
+ m_renderMeshActors[DestructibleActorMeshType::Skinned] = m_asset->getRenderMeshAsset()->createActor(renderableMeshDesc);
+ const uint32_t numParts = m_asset->getRenderMeshAsset()->getPartCount();
+ for (uint32_t i = 0; i < numParts; ++i)
+ {
+ m_renderMeshActors[DestructibleActorMeshType::Skinned]->setVisibility(false, (uint16_t)i);
+ }
+ m_renderMeshActors[DestructibleActorMeshType::Skinned]->updateBounds();
+
+ m_drawUnexpandedChunksStatically = destructiblePreviewParams->renderUnexplodedChunksStatically;
+
+ if (m_drawUnexpandedChunksStatically)
+ {
+ PX_ALLOCA(staticMaterialNames, const char*, destructiblePreviewParams->overrideStaticMaterialNames.arraySizes[0] > 0 ? destructiblePreviewParams->overrideStaticMaterialNames.arraySizes[0] : 1);
+ for (int i = 0; i < destructiblePreviewParams->overrideStaticMaterialNames.arraySizes[0]; ++i)
+ {
+ staticMaterialNames[i] = destructiblePreviewParams->overrideStaticMaterialNames.buf[i].buf;
+ }
+
+ // Create static render mesh
+ renderableMeshDesc.renderWithoutSkinning = true;
+ renderableMeshDesc.overrideMaterials = destructiblePreviewParams->overrideStaticMaterialNames.arraySizes[0] > 0 ? (const char**)staticMaterialNames : NULL;
+ renderableMeshDesc.overrideMaterialCount = (uint32_t)destructiblePreviewParams->overrideStaticMaterialNames.arraySizes[0];
+ m_renderMeshActors[DestructibleActorMeshType::Static] = m_asset->getRenderMeshAsset()->createActor(renderableMeshDesc);
+ for (uint32_t i = 0; i < numParts; ++i)
+ {
+ m_renderMeshActors[DestructibleActorMeshType::Static]->setVisibility(false, (uint16_t)i);
+ }
+ m_renderMeshActors[DestructibleActorMeshType::Static]->updateBounds();
+ }
+
+ // Instanced actors
+ physx::Array<uint16_t> tempPartToActorMap;
+ tempPartToActorMap.resize((uint32_t)m_asset->mParams->chunks.arraySizes[0], 0xFFFF);
+
+ m_instancedChunkActorMap.resize((uint32_t)m_asset->mParams->chunkInstanceInfo.arraySizes[0]);
+ for (int32_t i = 0; i < m_asset->mParams->chunkInstanceInfo.arraySizes[0]; ++i)
+ {
+ uint16_t partIndex = m_asset->mParams->chunkInstanceInfo.buf[i].partIndex;
+ if (tempPartToActorMap[partIndex] == 0xFFFF)
+ {
+ tempPartToActorMap[partIndex] = m_instancedChunkCount++;
+ }
+ m_instancedChunkActorMap[(uint32_t)i] = tempPartToActorMap[partIndex];
+ }
+
+ m_instancedActorVisiblePart.resize(m_instancedChunkCount);
+ for (int32_t i = 0; i < m_asset->mParams->chunks.arraySizes[0]; ++i)
+ {
+ DestructibleAssetParametersNS::Chunk_Type& chunk = m_asset->mParams->chunks.buf[i];
+ if ((chunk.flags & DestructibleAssetImpl::Instanced) != 0)
+ {
+ uint16_t partIndex = m_asset->mParams->chunkInstanceInfo.buf[chunk.meshPartIndex].partIndex;
+ m_instancedActorVisiblePart[m_instancedChunkActorMap[chunk.meshPartIndex]] = partIndex;
+ }
+ }
+
+ setChunkVisibility(0, true);
+
+ m_chunkDepth = destructiblePreviewParams->chunkDepth;
+ m_explodeAmount = destructiblePreviewParams->explodeAmount;
+ setPose(destructiblePreviewParams->globalPose);
+ m_userData = reinterpret_cast<void*>(destructiblePreviewParams->userData);
+}
+
+DestructiblePreviewImpl::~DestructiblePreviewImpl()
+{
+}
+
+// called at the end of 'setPose' which allows for any module specific updates.
+void DestructiblePreviewImpl::setPose(const PxMat44& pose)
+{
+ ApexPreview::setPose(pose);
+ setExplodeView(m_chunkDepth, m_explodeAmount);
+}
+
+void DestructiblePreviewImpl::setExplodeView(uint32_t depth, float explode)
+{
+ m_chunkDepth = PxClamp(depth, (uint32_t)0, m_asset->getDepthCount() - 1);
+ const float newExplodeAmount = PxMax(explode, 0.0f);
+
+ if (m_drawUnexpandedChunksStatically)
+ {
+ // Using a static mesh for unexploded chunks
+ if (m_explodeAmount == 0.0f && newExplodeAmount != 0.0f)
+ {
+ // Going from unexploded to exploded. Need to make the static mesh invisible.
+ if (m_renderMeshActors[DestructibleActorMeshType::Static] != NULL)
+ {
+ for (uint32_t i = 0; i < m_asset->getChunkCount(); ++i)
+ {
+ m_renderMeshActors[DestructibleActorMeshType::Static]->setVisibility(false, (uint16_t)i);
+ }
+ }
+ }
+ else if (m_explodeAmount != 0.0f && newExplodeAmount == 0.0f)
+ {
+ // Going from exploded to unexploded. Need to make the skinned mesh invisible.
+ if (m_renderMeshActors[DestructibleActorMeshType::Skinned] != NULL)
+ {
+ for (uint32_t i = 0; i < m_asset->getChunkCount(); ++i)
+ {
+ m_renderMeshActors[DestructibleActorMeshType::Skinned]->setVisibility(false, (uint16_t)i);
+ }
+ }
+ }
+ }
+
+ m_explodeAmount = newExplodeAmount;
+
+ for (uint32_t i = 0; i < m_instancedChunkRenderMeshActors.size(); ++i)
+ {
+ PX_ASSERT(i < m_chunkInstanceBufferData.size());
+ m_chunkInstanceBufferData[i].resize(0);
+ }
+
+ if (m_asset->getRenderMeshAsset() != NULL)
+ {
+ PxBounds3 bounds = m_asset->getRenderMeshAsset()->getBounds();
+ PxVec3 c = bounds.getCenter();
+
+ for (uint16_t i = 0; i < (uint16_t)m_asset->getChunkCount(); ++i)
+ {
+ setChunkVisibility(i, m_asset->mParams->chunks.buf[i].depth == m_chunkDepth);
+ }
+
+ DestructibleAssetParametersNS::Chunk_Type* sourceChunks = m_asset->mParams->chunks.buf;
+
+ mRenderBounds.setEmpty();
+
+ // Iterate over all visible chunks
+ const uint16_t* indexPtr = mVisibleChunks.usedIndices();
+ const uint16_t* indexPtrStop = indexPtr + mVisibleChunks.usedCount();
+ DestructibleAssetParametersNS::InstanceInfo_Type* instanceDataArray = m_asset->mParams->chunkInstanceInfo.buf;
+ while (indexPtr < indexPtrStop)
+ {
+ const uint16_t index = *indexPtr++;
+ if (index < m_asset->getChunkCount())
+ {
+ DestructibleAssetParametersNS::Chunk_Type& sourceChunk = sourceChunks[index];
+ PxMat44 pose = mPose;
+ if ((sourceChunk.flags & DestructibleAssetImpl::Instanced) == 0)
+ {
+ // Not instanced - only need to set skinned tms from chunks
+ if (!m_drawUnexpandedChunksStatically || m_explodeAmount != 0.0f)
+ {
+ PxBounds3 partBounds = m_asset->getRenderMeshAsset()->getBounds(sourceChunk.meshPartIndex);
+ PxVec3 partC = partBounds.getCenter();
+ pose.setPosition(pose.getPosition() + m_explodeAmount*pose.rotate(partC-c));
+ m_renderMeshActors[DestructibleActorMeshType::Skinned]->setTM(pose, sourceChunk.meshPartIndex);
+ }
+ }
+ else
+ {
+ // Instanced
+ PX_ASSERT(sourceChunk.meshPartIndex < m_asset->mParams->chunkInstanceInfo.arraySizes[0]);
+ DestructibleAssetImpl::ChunkInstanceBufferDataElement instanceDataElement;
+ DestructibleAssetParametersNS::InstanceInfo_Type& instanceData = instanceDataArray[sourceChunk.meshPartIndex];
+ const uint16_t instancedActorIndex = m_instancedChunkActorMap[sourceChunk.meshPartIndex];
+ physx::Array<DestructibleAssetImpl::ChunkInstanceBufferDataElement>& instanceBufferData = m_chunkInstanceBufferData[instancedActorIndex];
+ instanceDataElement.scaledRotation = PxMat33(pose.getBasis(0), pose.getBasis(1), pose.getBasis(2));
+ const PxVec3 globalOffset = instanceDataElement.scaledRotation*instanceData.chunkPositionOffset;
+ PxBounds3 partBounds = m_asset->getRenderMeshAsset()->getBounds(instanceData.partIndex);
+ partBounds.minimum += globalOffset;
+ partBounds.maximum += globalOffset;
+ PxVec3 partC = partBounds.getCenter();
+ instanceDataElement.translation = pose.getPosition() + globalOffset + m_explodeAmount*pose.rotate(partC-c);
+ instanceDataElement.uvOffset = instanceData.chunkUVOffset;
+ instanceDataElement.localOffset = instanceData.chunkPositionOffset;
+ instanceBufferData.pushBack(instanceDataElement);
+ // Transform bounds
+ PxVec3 center, extents;
+ center = partBounds.getCenter();
+ extents = partBounds.getExtents();
+ center = instanceDataElement.scaledRotation.transform(center) + instanceDataElement.translation;
+ extents = PxVec3(PxAbs(instanceDataElement.scaledRotation(0, 0) * extents.x) + PxAbs(instanceDataElement.scaledRotation(0, 1) * extents.y) + PxAbs(instanceDataElement.scaledRotation(0, 2) * extents.z),
+ PxAbs(instanceDataElement.scaledRotation(1, 0) * extents.x) + PxAbs(instanceDataElement.scaledRotation(1, 1) * extents.y) + PxAbs(instanceDataElement.scaledRotation(1, 2) * extents.z),
+ PxAbs(instanceDataElement.scaledRotation(2, 0) * extents.x) + PxAbs(instanceDataElement.scaledRotation(2, 1) * extents.y) + PxAbs(instanceDataElement.scaledRotation(2, 2) * extents.z));
+ mRenderBounds.include(PxBounds3::centerExtents(center, extents));
+ }
+ }
+ }
+
+ m_renderMeshActors[DestructibleActorMeshType::Skinned]->updateBounds();
+ mRenderBounds.include(m_renderMeshActors[DestructibleActorMeshType::Skinned]->getBounds());
+
+ // If a static mesh exists, set its (single) tm from the destructible's tm
+ if (m_renderMeshActors[DestructibleActorMeshType::Static] != NULL)
+ {
+ m_renderMeshActors[DestructibleActorMeshType::Static]->syncVisibility();
+ m_renderMeshActors[DestructibleActorMeshType::Static]->setTM(mPose);
+ m_renderMeshActors[DestructibleActorMeshType::Static]->updateBounds();
+ mRenderBounds.include(m_renderMeshActors[DestructibleActorMeshType::Static]->getBounds());
+ }
+ }
+}
+
+void DestructiblePreviewImpl::updateRenderResources(bool rewriteBuffers, void* userRenderData)
+{
+ for (uint32_t i = 0; i < DestructibleActorMeshType::Count; ++i)
+ {
+ if (m_renderMeshActors[i] != NULL)
+ {
+ RenderMeshActorIntl* renderMeshActor = (RenderMeshActorIntl*)m_renderMeshActors[i];
+ renderMeshActor->updateRenderResources((i == DestructibleActorMeshType::Skinned), rewriteBuffers, userRenderData);
+ }
+ }
+
+ setInstancedChunkCount(m_instancedChunkCount);
+
+ for (uint32_t i = 0; i < m_instancedChunkRenderMeshActors.size(); ++i)
+ {
+ PX_ASSERT(i < m_chunkInstanceBufferData.size());
+ RenderMeshActorIntl* renderMeshActor = (RenderMeshActorIntl*)m_instancedChunkRenderMeshActors[i];
+ if (renderMeshActor != NULL)
+ {
+ physx::Array<DestructibleAssetImpl::ChunkInstanceBufferDataElement>& instanceBufferData = m_chunkInstanceBufferData[i];
+ const uint32_t instanceBufferSize = instanceBufferData.size();
+ if (instanceBufferSize > 0)
+ {
+ m_chunkInstanceBuffers[i]->writeBuffer(&instanceBufferData[0], 0, instanceBufferSize);
+ }
+ renderMeshActor->setInstanceBufferRange(0, instanceBufferSize);
+ renderMeshActor->updateRenderResources(false, rewriteBuffers, userRenderData);
+ }
+ }
+}
+
+void DestructiblePreviewImpl::dispatchRenderResources(UserRenderer& renderer)
+{
+ for (uint32_t i = 0; i < DestructibleActorMeshType::Count; ++i)
+ {
+ if (m_renderMeshActors[i] != NULL)
+ {
+ m_renderMeshActors[i]->dispatchRenderResources(renderer);
+ }
+ }
+
+ for (uint32_t i = 0; i < m_instancedChunkRenderMeshActors.size(); ++i)
+ {
+ PX_ASSERT(i < m_chunkInstanceBufferData.size());
+ if (m_instancedChunkRenderMeshActors[i] != NULL)
+ {
+ if (m_chunkInstanceBufferData[i].size() > 0)
+ {
+ m_instancedChunkRenderMeshActors[i]->dispatchRenderResources(renderer);
+ }
+ }
+ }
+}
+
+void DestructiblePreviewImpl::release()
+{
+ if (mInRelease)
+ {
+ return;
+ }
+ mInRelease = true;
+ destroy();
+}
+
+void DestructiblePreviewImpl::destroy()
+{
+ ApexPreview::destroy();
+
+ for (uint32_t i = 0; i < DestructibleActorMeshType::Count; ++i)
+ {
+ if (m_renderMeshActors[i] != NULL)
+ {
+ m_renderMeshActors[i]->release();
+ }
+ }
+
+ setInstancedChunkCount(0);
+}
+
+void DestructiblePreviewImpl::setInstancedChunkCount(uint32_t count)
+{
+ UserRenderResourceManager* rrm = GetInternalApexSDK()->getUserRenderResourceManager();
+
+ const uint32_t oldCount = m_instancedChunkRenderMeshActors.size();
+ for (uint32_t i = count; i < oldCount; ++i)
+ {
+ if (m_instancedChunkRenderMeshActors[i] != NULL)
+ {
+ m_instancedChunkRenderMeshActors[i]->release();
+ m_instancedChunkRenderMeshActors[i] = NULL;
+ }
+ if (m_chunkInstanceBuffers[i] != NULL)
+ {
+ rrm->releaseInstanceBuffer(*m_chunkInstanceBuffers[i]);
+ m_chunkInstanceBuffers[i] = NULL;
+ }
+ }
+ m_instancedChunkRenderMeshActors.resize(count);
+ m_chunkInstanceBuffers.resize(count);
+ m_chunkInstanceBufferData.resize(count);
+ for (uint32_t index = oldCount; index < count; ++index)
+ {
+ m_instancedChunkRenderMeshActors[index] = NULL;
+ m_chunkInstanceBuffers[index] = NULL;
+ m_chunkInstanceBufferData[index].reset();
+
+ // Find out how many potential instances there are
+ uint32_t maxInstanceCount = 0;
+ for (int32_t i = 0; i < m_asset->mParams->chunkInstanceInfo.arraySizes[0]; ++i)
+ {
+ if (m_asset->mParams->chunkInstanceInfo.buf[i].partIndex == m_instancedActorVisiblePart[index])
+ {
+ ++maxInstanceCount;
+ }
+ }
+
+ // Create instance buffer
+ UserRenderInstanceBufferDesc instanceBufferDesc;
+ instanceBufferDesc.maxInstances = maxInstanceCount;
+ instanceBufferDesc.hint = RenderBufferHint::DYNAMIC;
+ instanceBufferDesc.semanticOffsets[RenderInstanceLayoutElement::POSITION_FLOAT3] = DestructibleAssetImpl::ChunkInstanceBufferDataElement::translationOffset();
+ instanceBufferDesc.semanticOffsets[RenderInstanceLayoutElement::ROTATION_SCALE_FLOAT3x3] = DestructibleAssetImpl::ChunkInstanceBufferDataElement::scaledRotationOffset();
+ instanceBufferDesc.semanticOffsets[RenderInstanceLayoutElement::UV_OFFSET_FLOAT2] = DestructibleAssetImpl::ChunkInstanceBufferDataElement::uvOffsetOffset();
+ instanceBufferDesc.semanticOffsets[RenderInstanceLayoutElement::LOCAL_OFFSET_FLOAT3] = DestructibleAssetImpl::ChunkInstanceBufferDataElement::localOffsetOffset();
+ instanceBufferDesc.stride = sizeof(DestructibleAssetImpl::ChunkInstanceBufferDataElement);
+ m_chunkInstanceBuffers[index] = rrm->createInstanceBuffer(instanceBufferDesc);
+
+ // Instance buffer data
+ m_chunkInstanceBufferData[index].reserve(maxInstanceCount);
+ m_chunkInstanceBufferData[index].resize(0);
+
+ // Create actor
+ if (m_asset->renderMeshAsset != NULL)
+ {
+ RenderMeshActorDesc renderableMeshDesc;
+ renderableMeshDesc.maxInstanceCount = maxInstanceCount;
+ renderableMeshDesc.renderWithoutSkinning = true;
+ renderableMeshDesc.visible = false;
+ m_instancedChunkRenderMeshActors[index] = m_asset->renderMeshAsset->createActor(renderableMeshDesc);
+ m_instancedChunkRenderMeshActors[index]->setInstanceBuffer(m_chunkInstanceBuffers[index]);
+ m_instancedChunkRenderMeshActors[index]->setVisibility(true, m_instancedActorVisiblePart[index]);
+ }
+ }
+}
+
+}
+} // end namespace nvidia
+