diff options
| author | git perforce import user <a@b> | 2016-10-25 12:29:14 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees> | 2016-10-25 18:56:37 -0500 |
| commit | 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch) | |
| tree | fa6485c169e50d7415a651bf838f5bcd0fd3bfbd /APEX_1.4/module/destructible/fracture/Renderable.cpp | |
| download | physx-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/fracture/Renderable.cpp')
| -rw-r--r-- | APEX_1.4/module/destructible/fracture/Renderable.cpp | 467 |
1 files changed, 467 insertions, 0 deletions
diff --git a/APEX_1.4/module/destructible/fracture/Renderable.cpp b/APEX_1.4/module/destructible/fracture/Renderable.cpp new file mode 100644 index 00000000..5e8ba01b --- /dev/null +++ b/APEX_1.4/module/destructible/fracture/Renderable.cpp @@ -0,0 +1,467 @@ +/* + * 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 "RTdef.h" +#if RT_COMPILE +#include "DestructibleActorImpl.h" + +#include "Actor.h" +#include "Compound.h" +#include "Convex.h" + +#include "../fracture/Renderable.h" + +namespace nvidia +{ +namespace fracture +{ + +Renderable::Renderable(): + mVertexBuffer(NULL), + mIndexBuffer(NULL), + mBoneBuffer(NULL), + mVertexBufferSize(0), + mIndexBufferSize(0), + mBoneBufferSize(0), + mVertexBufferSizeLast(0), + mIndexBufferSizeLast(0), + mBoneBufferSizeLast(0), + mFullBufferDirty(true), + valid(false) +{ + +} + +Renderable::~Renderable() +{ + UserRenderResourceManager* rrm = GetInternalApexSDK()->getUserRenderResourceManager(); + if (mVertexBuffer != NULL ) + { + rrm->releaseVertexBuffer(*mVertexBuffer); + } + if (mIndexBuffer != NULL ) + { + rrm->releaseIndexBuffer(*mIndexBuffer); + } + if (mBoneBuffer != NULL) + { + rrm->releaseBoneBuffer(*mBoneBuffer); + } + for (uint32_t k = 0; k < mConvexGroups.size(); k++) + { + ConvexGroup& g = mConvexGroups[k]; + for (uint32_t j = 0; j < g.mSubMeshes.size(); j++) + { + SubMesh& s = g.mSubMeshes[j]; + if(s.renderResource != NULL) + { + rrm->releaseResource(*s.renderResource); + s.renderResource = NULL; + } + } + } +} + +void Renderable::updateRenderResources(bool rewriteBuffers, void* userRenderData) +{ + UserRenderResourceManager* rrm = GetInternalApexSDK()->getUserRenderResourceManager(); + ResourceProviderIntl* nrp = GetInternalApexSDK()->getInternalResourceProvider(); + + PX_ASSERT(rrm != NULL && nrp != NULL); + if (rrm == NULL || nrp == NULL || mConvexGroups.empty()) + { + valid = false; + return; + } + + if (rewriteBuffers) + { + mFullBufferDirty = true; + } + + // Resize buffers if necessary: TODO: intelligently oversize + // vertex buffer + if (mVertexBufferSize > mVertexBufferSizeLast) + { + if (mVertexBuffer != NULL ) + { + rrm->releaseVertexBuffer(*mVertexBuffer); + } + { + UserRenderVertexBufferDesc desc; + desc.uvOrigin = nvidia::apex::TextureUVOrigin::ORIGIN_BOTTOM_LEFT; + desc.hint = RenderBufferHint::DYNAMIC; + desc.maxVerts = mVertexBufferSize; + desc.buffersRequest[RenderVertexSemantic::POSITION] = RenderDataFormat::FLOAT3; + desc.buffersRequest[RenderVertexSemantic::NORMAL] = RenderDataFormat::FLOAT3; + desc.buffersRequest[RenderVertexSemantic::TEXCOORD0] = RenderDataFormat::FLOAT2; + desc.buffersRequest[RenderVertexSemantic::BONE_INDEX] = RenderDataFormat::USHORT1; + mVertexBuffer = rrm->createVertexBuffer(desc); + PX_ASSERT(mVertexBuffer); + } + mFullBufferDirty = true; + } + // index buffer + if (mIndexBufferSize > mIndexBufferSizeLast) + { + if (mIndexBuffer != NULL ) + { + rrm->releaseIndexBuffer(*mIndexBuffer); + } + UserRenderIndexBufferDesc desc; + desc.hint = RenderBufferHint::DYNAMIC; + desc.maxIndices = mIndexBufferSize; + desc.format = RenderDataFormat::UINT1; + mIndexBuffer = rrm->createIndexBuffer(desc); + PX_ASSERT(mIndexBuffer); + mFullBufferDirty = true; + } + // bone buffer + if (mBoneBufferSize > mBoneBufferSizeLast) + { + if (mBoneBuffer != NULL) + { + rrm->releaseBoneBuffer(*mBoneBuffer); + } + UserRenderBoneBufferDesc desc; + desc.hint = RenderBufferHint::DYNAMIC; + desc.maxBones = mBoneBufferSize; + desc.buffersRequest[RenderBoneSemantic::POSE] = RenderDataFormat::FLOAT3x4; + mBoneBuffer = rrm->createBoneBuffer(desc); + PX_ASSERT(mBoneBuffer); + mFullBufferDirty = true; + } + // Fill buffers + if (mFullBufferDirty) + { + uint32_t vertexIdx = 0; + uint32_t indexIdx = 0; + uint32_t boneIdx = 0; + for (uint32_t k = 0; k < mConvexGroups.size(); k++) + { + ConvexGroup& g = mConvexGroups[k]; + for (uint32_t j = 0; j < g.mSubMeshes.size(); j++) + { + SubMesh& s = g.mSubMeshes[j]; + if(s.renderResource != NULL) + { + rrm->releaseResource(*s.renderResource); + s.renderResource = NULL; + } + UserRenderResourceDesc desc; + desc.primitives = RenderPrimitiveType::TRIANGLES; + // configure vertices + desc.vertexBuffers = &mVertexBuffer; + desc.numVertexBuffers = 1; + desc.numVerts = g.mVertexCache.size(); + desc.firstVertex = vertexIdx; + // configure indices; + desc.indexBuffer = mIndexBuffer; + desc.firstIndex = indexIdx; + desc.numIndices = s.mIndexCache.size(); + // configure bones; + desc.boneBuffer = mBoneBuffer; + desc.numBones = g.mBoneCache.size(); + desc.firstBone = boneIdx; + // configure other info + desc.material = nrp->getResource(mMaterialInfo[j].mMaterialID); + desc.submeshIndex = j; + desc.userRenderData = userRenderData; + // create + s.renderResource = rrm->createResource(desc); + PX_ASSERT(s.renderResource); + // copy indices into buffer + PX_ASSERT(indexIdx+s.mIndexCache.size() <= mIndexBufferSize); + mIndexBuffer->writeBuffer(s.mIndexCache.begin(),sizeof(*s.mIndexCache.begin()),indexIdx,s.mIndexCache.size()); + indexIdx += s.mIndexCache.size(); + } + // copy vertices and bones + { + RenderVertexBufferData data; + data.setSemanticData(RenderVertexSemantic::POSITION, g.mVertexCache.begin(), sizeof(*g.mVertexCache.begin()), RenderDataFormat::FLOAT3); + data.setSemanticData(RenderVertexSemantic::NORMAL, g.mNormalCache.begin(), sizeof(*g.mNormalCache.begin()), RenderDataFormat::FLOAT3); + data.setSemanticData(RenderVertexSemantic::TEXCOORD0, g.mTexcoordCache.begin(), sizeof(*g.mTexcoordCache.begin()), RenderDataFormat::FLOAT2); + data.setSemanticData(RenderVertexSemantic::BONE_INDEX,g.mBoneIndexCache.begin(),sizeof(*g.mBoneIndexCache.begin()),RenderDataFormat::USHORT1); + PX_ASSERT(vertexIdx + g.mVertexCache.size() <= mVertexBufferSize); + mVertexBuffer->writeBuffer(data,vertexIdx,g.mVertexCache.size()); + } + { + RenderBoneBufferData data; + data.setSemanticData(RenderBoneSemantic::POSE,g.mBoneCache.begin(),sizeof(*g.mBoneCache.begin()),RenderDataFormat::FLOAT4x4); + PX_ASSERT(boneIdx + g.mBoneCache.size() <= mBoneBufferSize); + mBoneBuffer->writeBuffer(data,boneIdx,g.mBoneCache.size()); + } + vertexIdx += g.mVertexCache.size(); + boneIdx += g.mBoneCache.size(); + } + mFullBufferDirty = false; + } + else // Bones only + { + uint32_t boneIdx = 0; + for (uint32_t k = 0; k < mConvexGroups.size(); k++) + { + ConvexGroup& g = mConvexGroups[k]; + { + RenderBoneBufferData data; + data.setSemanticData(RenderBoneSemantic::POSE,g.mBoneCache.begin(),sizeof(*g.mBoneCache.begin()),RenderDataFormat::FLOAT4x4); + mBoneBuffer->writeBuffer(data,boneIdx,g.mBoneCache.size()); + } + boneIdx += g.mBoneCache.size(); + } + } + mVertexBufferSizeLast = mVertexBufferSize; + mIndexBufferSizeLast = mIndexBufferSize; + mBoneBufferSizeLast = mBoneBufferSize; + valid = true; +} + +void Renderable::dispatchRenderResources(UserRenderer& api) +{ + if (!valid) + { + return; + } + RenderContext ctx; + ctx.local2world = PxMat44(PxIdentity); + ctx.world2local = PxMat44(PxIdentity); + for (uint32_t k = 0; k < mConvexGroups.size(); k++) + { + ConvexGroup& g = mConvexGroups[k]; + for (uint32_t j = 0; j < g.mSubMeshes.size(); j++) + { + SubMesh& s = g.mSubMeshes[j]; + if(s.renderResource && !s.mIndexCache.empty()) + { + ctx.renderResource = s.renderResource; + api.renderResource(ctx); + } + } + } +} + +// -----------------------Cache Update----------------------------------- +void Renderable::updateRenderCacheFull(Actor* actor) +{ + mVertexBufferSize = 0; + mIndexBufferSize = 0; + mBoneBufferSize = 0; + // Resize SubMeshes if necessary + const uint32_t numSubMeshes = actor->mActor->getRenderSubmeshCount(); + if( numSubMeshes == 0 ) + { + return; + } + if( numSubMeshes != mMaterialInfo.size() ) + { + mMaterialInfo.resize(numSubMeshes); + } + // grab material information + if (ResourceProviderIntl* nrp = GetInternalApexSDK()->getInternalResourceProvider()) + { + if (UserRenderResourceManager* rrm = GetInternalApexSDK()->getUserRenderResourceManager()) + { + ResID materialNS = GetInternalApexSDK()->getMaterialNameSpace(); + for(uint32_t i = 0; i < numSubMeshes; i++) + { + if(mMaterialInfo[i].mMaxBones == 0) + { + mMaterialInfo[i].mMaterialID = nrp->createResource(materialNS,actor->mActor->getDestructibleAsset()->getRenderMeshAsset()->getMaterialName(i),false); + mMaterialInfo[i].mMaxBones = rrm->getMaxBonesForMaterial(nrp->getResource(mMaterialInfo[i].mMaterialID)); + } + } + } + } + // Find bone limit + uint32_t maxBones = mMaterialInfo[0].mMaxBones; + for (uint32_t i = 1; i < mMaterialInfo.size(); i++) + { + if (mMaterialInfo[i].mMaxBones < maxBones) + { + maxBones = mMaterialInfo[i].mMaxBones; + } + } + //maxBones = 1; // TEMPORARY: FIXES TEXTURE MAPPING PROBLEM + //maxBones = rand(1,maxBones-1); + // Count Convexes + uint32_t numConvexes = 0; + const Array<base::Compound*>& compounds = actor->getCompounds(); + for (uint32_t k = 0; k < compounds.size(); k++) + { + const Array<base::Convex*>& convexes = compounds[k]->getConvexes(); + numConvexes += convexes.size(); + } + mBoneBufferSize += numConvexes; + + //maxBones is 0 when VTF rendering method is used for destructible(only) + if(maxBones == 0) + maxBones = mBoneBufferSize; + + // Create more groups if necessary + uint32_t numGroups = numConvexes/maxBones + ((numConvexes%maxBones)?1:0); + if (numGroups != mConvexGroups.size()) + { + mConvexGroups.resize(numGroups); + } + // Resize convex caches and subMeshes if necessary + for (uint32_t k = 0; k < mConvexGroups.size(); k++) + { + ConvexGroup& g = mConvexGroups[k]; + g.mConvexCache.clear(); + if( g.mConvexCache.capacity() <= maxBones ) + { + g.mConvexCache.reserve(maxBones); + } + if( g.mSubMeshes.size() != mMaterialInfo.size()) + { + g.mSubMeshes.resize(mMaterialInfo.size()); + } + } + // Populate convex cache + { + uint32_t idx = 0; + const Array<base::Compound*>& compounds = actor->getCompounds(); + for (uint32_t k = 0; k < compounds.size(); k++) + { + const Array<base::Convex*>& convexes = compounds[k]->getConvexes(); + for (uint32_t j = 0; j < convexes.size(); j++) + { + mConvexGroups[idx/maxBones].mConvexCache.pushBack((Convex*)convexes[j]); + idx++; + } + } + } + // Fill other caches + for (uint32_t k = 0; k < mConvexGroups.size(); k++) + { + ConvexGroup& g = mConvexGroups[k]; + // Calculate number of vertices + uint32_t numVertices = 0; + for (uint32_t j = 0; j < g.mConvexCache.size(); j++) + { + numVertices += g.mConvexCache[j]->getVisVertices().size(); + } + mVertexBufferSize += numVertices; + // Resize if necessary + g.mVertexCache.clear(); + g.mNormalCache.clear(); + g.mTexcoordCache.clear(); + g.mBoneIndexCache.clear(); + if (numVertices >= g.mVertexCache.capacity()) + { + g.mVertexCache.reserve(numVertices); + g.mNormalCache.reserve(numVertices); + g.mBoneIndexCache.reserve(numVertices); + g.mTexcoordCache.reserve(numVertices); + } + g.mBoneCache.clear(); + if (maxBones >= g.mBoneCache.capacity()) + { + g.mBoneCache.reserve(maxBones); + } + // Calculate index buffer sizes + for (uint32_t i = 0; i < g.mSubMeshes.size(); i++) + { + uint32_t numIndices = 0; + for (uint32_t j = 0; j < g.mConvexCache.size(); j++) + { + numIndices += g.mConvexCache[j]->getVisTriIndices().size(); + } + g.mSubMeshes[i].mIndexCache.clear(); + if (numIndices >= g.mSubMeshes[i].mIndexCache.capacity()) + { + g.mSubMeshes[i].mIndexCache.reserve(numIndices); + } + mIndexBufferSize += numIndices; + } + // Fill for each convex + for (uint32_t j = 0; j < g.mConvexCache.size(); j++) + { + Convex* c = g.mConvexCache[j]; + uint32_t off = g.mVertexCache.size(); + // fill vertices + const Array<PxVec3>& verts = c->getVisVertices(); + const Array<PxVec3>& norms = c->getVisNormals(); + const Array<float>& texcs = c->getVisTexCoords(); + PX_ASSERT(verts.size() == norms.size() && verts.size() == (texcs.size()/2)); + for (uint32_t i = 0; i < verts.size(); i++) + { + g.mVertexCache.pushBack(verts[i]); + g.mNormalCache.pushBack(norms[i]); + g.mTexcoordCache.pushBack(PxVec2(texcs[2*i],texcs[2*i+1])); + g.mBoneIndexCache.pushBack((uint16_t)j); + } + // fill indicies for each submesh + for (uint32_t i = 0; i < g.mSubMeshes.size(); i++) + { + const Array<int32_t>& indices = c->getVisTriIndices(); + PX_ASSERT(indices.size()%3 == 0); + for (uint32_t a = 0; a < indices.size()/3; a++) + { + uint32_t subMeshID = 0; // <<<--- TODO: acquire subMeshID for triangle + if (subMeshID == i) + { + g.mSubMeshes[i].mIndexCache.pushBack(indices[3*a+0]+off); + g.mSubMeshes[i].mIndexCache.pushBack(indices[3*a+1]+off); + g.mSubMeshes[i].mIndexCache.pushBack(indices[3*a+2]+off); + } + } + } + g.mBoneCache.pushBack(c->getGlobalPose()); + } + } +} + +void Renderable::updateRenderCache(Actor* actor) +{ + if( actor == NULL ) return; + actor->mScene->getScene()->lockRead(); + //actor->mRenderResourcesDirty = true; + if( actor->mRenderResourcesDirty) + { + updateRenderCacheFull(actor); + mFullBufferDirty = true; + actor->mRenderResourcesDirty = false; + } + // Fill other caches + for (uint32_t k = 0; k < mConvexGroups.size(); k++) + { + ConvexGroup& g = mConvexGroups[k]; + g.mBoneCache.clear(); + // Fill bones for each convex + for (uint32_t j = 0; j < g.mConvexCache.size(); j++) + { + Convex* c = g.mConvexCache[j]; + g.mBoneCache.pushBack(c->getGlobalPose()); + } + } + actor->mScene->getScene()->unlockRead(); +} + +PxBounds3 Renderable::getBounds() const +{ + PxBounds3 bounds; + bounds.setEmpty(); + for (uint32_t k = 0; k < mConvexGroups.size(); k++) + { + const ConvexGroup& g = mConvexGroups[k]; + for (uint32_t j = 0; j < g.mConvexCache.size(); j++) + { + const Convex* c = g.mConvexCache[j]; + bounds.include(c->getBounds()); + } + } + return bounds; +} + +} +} +#endif
\ No newline at end of file |