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/framework/src/ApexRenderMeshAsset.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/framework/src/ApexRenderMeshAsset.cpp')
| -rw-r--r-- | APEX_1.4/framework/src/ApexRenderMeshAsset.cpp | 495 |
1 files changed, 495 insertions, 0 deletions
diff --git a/APEX_1.4/framework/src/ApexRenderMeshAsset.cpp b/APEX_1.4/framework/src/ApexRenderMeshAsset.cpp new file mode 100644 index 00000000..6a199fa5 --- /dev/null +++ b/APEX_1.4/framework/src/ApexRenderMeshAsset.cpp @@ -0,0 +1,495 @@ +/* + * 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 "ApexRenderMeshAsset.h" +#include "ApexRenderMeshActor.h" +#include "ApexSharedUtils.h" + +#include "ApexSDKIntl.h" +#include "ResourceProviderIntl.h" + +namespace nvidia +{ +namespace apex +{ + + +// ApexRenderMeshAsset functions + +ApexRenderMeshAsset::ApexRenderMeshAsset(ResourceList& list, const char* name, AuthObjTypeID ownerModuleID) : + mOwnerModuleID(ownerModuleID), + mParams(NULL), + mOpaqueMesh(NULL), + mName(name) +{ + list.add(*this); +} + + + +ApexRenderMeshAsset::~ApexRenderMeshAsset() +{ + // this should have been cleared in releaseActor() + PX_ASSERT(mRuntimeSubmeshData.empty()); + + // Release named resources + ResourceProviderIntl* resourceProvider = GetInternalApexSDK()->getInternalResourceProvider(); + for (uint32_t i = 0 ; i < mMaterialIDs.size() ; i++) + { + resourceProvider->releaseResource(mMaterialIDs[i]); + } + + setSubmeshCount(0); +} + + + +void ApexRenderMeshAsset::destroy() +{ + for (uint32_t i = 0; i < mSubmeshes.size(); i++) + { + mSubmeshes[i]->setParams(NULL, NULL); + } + + if (mParams != NULL) + { + if (!mParams->isReferenced) + { + mParams->destroy(); + } + mParams = NULL; + } + + // this is necessary so that all the actors will be destroyed before the destructor runs + mActorList.clear(); + + delete this; +} + + + +bool ApexRenderMeshAsset::createFromParameters(RenderMeshAssetParameters* params) +{ + mParams = params; + + NvParameterized::Handle handle(*mParams); + uint32_t size; + + // submeshes + mParams->getParameterHandle("submeshes", handle); + mParams->getArraySize(handle, (int32_t&)size); + setSubmeshCount(size); + for (uint32_t i = 0; i < size; ++i) + { + NvParameterized::Handle elementHandle(*mParams); + handle.getChildHandle((int32_t)i, elementHandle); + NvParameterized::Interface* submeshParams = NULL; + mParams->getParamRef(elementHandle, submeshParams); + + mSubmeshes[i]->setParams(static_cast<SubmeshParameters*>(submeshParams), NULL); + } + + createLocalData(); + + return true; +} + +// Load all of our named resources (that consists of materials) if they are +// not registered in the NRP +uint32_t ApexRenderMeshAsset::forceLoadAssets() +{ + uint32_t assetLoadedCount = 0; + ResourceProviderIntl* nrp = GetInternalApexSDK()->getInternalResourceProvider(); + ResID materialNS = GetInternalApexSDK()->getMaterialNameSpace(); + + for (uint32_t i = 0; i < mMaterialIDs.size(); i++) + { + + if (!nrp->checkResource(materialNS, mParams->materialNames.buf[i])) + { + /* we know for SURE that createResource() has already been called, so just getResource() */ + nrp->getResource(mMaterialIDs[i]); + assetLoadedCount++; + } + } + + return assetLoadedCount; +} + + +RenderMeshActor* ApexRenderMeshAsset::createActor(const RenderMeshActorDesc& desc) +{ + return PX_NEW(ApexRenderMeshActor)(desc, *this, mActorList); +} + + + +void ApexRenderMeshAsset::releaseActor(RenderMeshActor& renderMeshActor) +{ + ApexRenderMeshActor* actor = DYNAMIC_CAST(ApexRenderMeshActor*)(&renderMeshActor); + actor->destroy(); + + // Last one out turns out the lights + if (!mActorList.getSize()) + { + UserRenderResourceManager* rrm = GetInternalApexSDK()->getUserRenderResourceManager(); + for (uint32_t i = 0 ; i < mRuntimeSubmeshData.size() ; i++) + { + if (mRuntimeSubmeshData[i].staticVertexBuffer != NULL) + { + rrm->releaseVertexBuffer(*mRuntimeSubmeshData[i].staticVertexBuffer); + mRuntimeSubmeshData[i].staticVertexBuffer = NULL; + } + if (mRuntimeSubmeshData[i].skinningVertexBuffer != NULL) + { + rrm->releaseVertexBuffer(*mRuntimeSubmeshData[i].skinningVertexBuffer); + mRuntimeSubmeshData[i].skinningVertexBuffer = NULL; + } + if (mRuntimeSubmeshData[i].dynamicVertexBuffer != NULL) + { + rrm->releaseVertexBuffer(*mRuntimeSubmeshData[i].dynamicVertexBuffer); + mRuntimeSubmeshData[i].dynamicVertexBuffer = NULL; + } + } + mRuntimeSubmeshData.clear(); + } +} + + + +void ApexRenderMeshAsset::permuteBoneIndices(const physx::Array<int32_t>& old2new) +{ + int32_t maxBoneIndex = -1; + for (uint32_t i = 0; i < mSubmeshes.size(); i++) + { + RenderDataFormat::Enum format; + const VertexBuffer& vb = mSubmeshes[i]->getVertexBuffer(); + const VertexFormat& vf = vb.getFormat(); + uint32_t bufferIndex = (uint32_t)vf.getBufferIndexFromID(vf.getSemanticID(nvidia::RenderVertexSemantic::BONE_INDEX)); + uint16_t* boneIndices = (uint16_t*)vb.getBufferAndFormat(format, bufferIndex); + if (boneIndices == NULL) + { + continue; + } + + uint32_t numBonesPerVertex = 0; + switch (format) + { + case RenderDataFormat::USHORT1: + numBonesPerVertex = 1; + break; + case RenderDataFormat::USHORT2: + numBonesPerVertex = 2; + break; + case RenderDataFormat::USHORT3: + numBonesPerVertex = 3; + break; + case RenderDataFormat::USHORT4: + numBonesPerVertex = 4; + break; + default: + continue; + } + + const uint32_t numVertices = vb.getVertexCount(); + for (uint32_t j = 0; j < numVertices; j++) + { + for (uint32_t k = 0; k < numBonesPerVertex; k++) + { + uint16_t& index = boneIndices[j * numBonesPerVertex + k]; + PX_ASSERT(old2new[index] >= 0); + PX_ASSERT(old2new[index] <= 0xffff); + index = (uint16_t)old2new[index]; + maxBoneIndex = PxMax(maxBoneIndex, (int32_t)index); + } + } + } + mParams->boneCount = (uint32_t)maxBoneIndex + 1; +} + + +void ApexRenderMeshAsset::reverseWinding() +{ + for (uint32_t submeshId = 0; submeshId < mSubmeshes.size(); submeshId++) + { + uint32_t numIndices = mSubmeshes[submeshId]->getTotalIndexCount(); + // assume that all of the parts are contiguous + uint32_t* indices = mSubmeshes[submeshId]->getIndexBufferWritable(0); + for (uint32_t i = 0; i < numIndices; i += 3) + { + nvidia::swap<uint32_t>(indices[i + 1], indices[i + 2]); + } + } + + updatePartBounds(); +} + +void ApexRenderMeshAsset::applyTransformation(const PxMat44& transformation, float scale) +{ + for (uint32_t submeshId = 0; submeshId < mSubmeshes.size(); submeshId++) + { + VertexBufferIntl& vb = mSubmeshes[submeshId]->getVertexBufferWritable(); + vb.applyScale(scale); + vb.applyTransformation(transformation); + } + + // if the transform will mirror the mesh, change the triangle winding in the ib + + const PxMat33 tm(transformation.column0.getXYZ(), + transformation.column1.getXYZ(), + transformation.column2.getXYZ()); + + if (tm.getDeterminant() * scale < 0.0f) + { + reverseWinding(); + } + else + { + updatePartBounds(); + } +} + + + +void ApexRenderMeshAsset::applyScale(float scale) +{ + for (uint32_t submeshId = 0; submeshId < mSubmeshes.size(); submeshId++) + { + VertexBufferIntl& vb = mSubmeshes[submeshId]->getVertexBufferWritable(); + vb.applyScale(scale); + } + + for (int partId = 0; partId < mParams->partBounds.arraySizes[0]; partId++) + { + PX_ASSERT(!mParams->partBounds.buf[partId].isEmpty()); + mParams->partBounds.buf[partId].minimum *= scale; + mParams->partBounds.buf[partId].maximum *= scale; + } + + if (scale < 0.0f) + { + for (int partId = 0; partId < mParams->partBounds.arraySizes[0]; partId++) + { + PX_ASSERT(!mParams->partBounds.buf[partId].isEmpty()); + nvidia::swap(mParams->partBounds.buf[partId].minimum, mParams->partBounds.buf[partId].maximum); + } + } +} + + + +bool ApexRenderMeshAsset::mergeBinormalsIntoTangents() +{ + bool changed = false; + for (uint32_t submeshId = 0; submeshId < mSubmeshes.size(); submeshId++) + { + VertexBufferIntl& vb = mSubmeshes[submeshId]->getVertexBufferWritable(); + changed |= vb.mergeBinormalsIntoTangents(); + } + return changed; +} + + + +TextureUVOrigin::Enum ApexRenderMeshAsset::getTextureUVOrigin() const +{ + PX_ASSERT(mParams->textureUVOrigin < 4); + return static_cast<TextureUVOrigin::Enum>(mParams->textureUVOrigin); +} + + + +void ApexRenderMeshAsset::createLocalData() +{ + mMaterialIDs.resize((uint32_t)mParams->materialNames.arraySizes[0]); + ResourceProviderIntl* resourceProvider = GetInternalApexSDK()->getInternalResourceProvider(); + ResID materialNS = GetInternalApexSDK()->getMaterialNameSpace(); + ResID customVBNS = GetInternalApexSDK()->getCustomVBNameSpace(); + + + // Resolve material names using the NRP... + for (uint32_t i = 0; i < (uint32_t)mParams->materialNames.arraySizes[0]; ++i) + { + if (resourceProvider) + { + mMaterialIDs[i] = resourceProvider->createResource(materialNS, mParams->materialNames.buf[i]); + } + else + { + mMaterialIDs[i] = INVALID_RESOURCE_ID; + } + } + + // Resolve custom vertex buffer semantics using the NRP... + mRuntimeCustomSubmeshData.resize(getSubmeshCount()); + //JPB memset(mRuntimeCustomSubmeshData.begin(), 0, sizeof(CustomSubmeshData) * mRuntimeCustomSubmeshData.size()); + + for (uint32_t i = 0; i < getSubmeshCount(); ++i) + { + const VertexFormat& fmt = getSubmesh(i).getVertexBuffer().getFormat(); + + mRuntimeCustomSubmeshData[i].customBufferFormats.resize(fmt.getCustomBufferCount()); + mRuntimeCustomSubmeshData[i].customBufferVoidPtrs.resize(fmt.getCustomBufferCount()); + + uint32_t customBufferIndex = 0; + for (uint32_t j = 0; j < fmt.getBufferCount(); ++j) + { + if (fmt.getBufferSemantic(j) != RenderVertexSemantic::CUSTOM) + { + continue; + } + RenderDataFormat::Enum f = fmt.getBufferFormat(j); + const char* name = fmt.getBufferName(j); + + mRuntimeCustomSubmeshData[i].customBufferFormats[customBufferIndex] = f; + mRuntimeCustomSubmeshData[i].customBufferVoidPtrs[customBufferIndex] = 0; + + if (resourceProvider) + { + ResID id = resourceProvider->createResource(customVBNS, name, true); + mRuntimeCustomSubmeshData[i].customBufferVoidPtrs[customBufferIndex] = GetInternalApexSDK()->getInternalResourceProvider()->getResource(id); + } + + ++customBufferIndex; + } + } + + // find the bone count + // LRR - required for new deserialize path + // PH - mBoneCount is now serialized + if (mParams->boneCount == 0) + { + for (uint32_t i = 0; i < getSubmeshCount(); i++) + { + + RenderDataFormat::Enum format; + const VertexBuffer& vb = mSubmeshes[i]->getVertexBuffer(); + const VertexFormat& vf = vb.getFormat(); + uint32_t bufferIndex = (uint32_t)vf.getBufferIndexFromID(vf.getSemanticID(nvidia::RenderVertexSemantic::BONE_INDEX)); + uint16_t* boneIndices = (uint16_t*)vb.getBufferAndFormat(format, bufferIndex); + + if (boneIndices == NULL) + { + continue; + } + + if (!vertexSemanticFormatValid(RenderVertexSemantic::BONE_INDEX, format)) + { + continue; + } + + const uint32_t bonesPerVert = vertexSemanticFormatElementCount(RenderVertexSemantic::BONE_INDEX, format); + + PX_ASSERT(format == RenderDataFormat::USHORT1 || format == RenderDataFormat::USHORT2 || format == RenderDataFormat::USHORT3 || format == RenderDataFormat::USHORT4); + + const uint32_t numVertices = vb.getVertexCount(); + for (uint32_t v = 0; v < numVertices; v++) + { + for (uint32_t b = 0; b < bonesPerVert; b++) + { + mParams->boneCount = PxMax(mParams->boneCount, (uint32_t)(boneIndices[v * bonesPerVert + b] + 1)); + } + } + } + } + + // PH - have one bone at all times, if it's just one, it is used as current pose (see ApexRenderMeshActor::dispatchRenderResources) + if (mParams->boneCount == 0) + { + mParams->boneCount = 1; + } +} + +void ApexRenderMeshAsset::getStats(RenderMeshAssetStats& stats) const +{ + stats.totalBytes = sizeof(ApexRenderMeshAsset); + + for (int i = 0; i < mParams->materialNames.arraySizes[0]; ++i) + { + stats.totalBytes += (uint32_t) strlen(mParams->materialNames.buf[i]) + 1; + } + + stats.totalBytes += mParams->partBounds.arraySizes[0] * sizeof(PxBounds3); + stats.totalBytes += mName.len() + 1; + + stats.submeshCount = mSubmeshes.size(); + stats.partCount = (uint32_t)mParams->partBounds.arraySizes[0]; + stats.vertexCount = 0; + stats.indexCount = 0; + stats.vertexBufferBytes = 0; + stats.indexBufferBytes = 0; + + for (uint32_t i = 0; i < mSubmeshes.size(); ++i) + { + const ApexRenderSubmesh& submesh = *mSubmeshes[i]; + + submesh.addStats(stats); + } +} + + +void ApexRenderMeshAsset::updatePartBounds() +{ + for (int i = 0; i < mParams->partBounds.arraySizes[0]; i++) + { + mParams->partBounds.buf[i].setEmpty(); + } + + for (uint32_t i = 0; i < mSubmeshes.size(); i++) + { + const uint32_t* part = mSubmeshes[i]->mParams->vertexPartition.buf; + + RenderDataFormat::Enum format; + const VertexBuffer& vb = mSubmeshes[i]->getVertexBuffer(); + const VertexFormat& vf = vb.getFormat(); + uint32_t bufferIndex = (uint32_t)vf.getBufferIndexFromID(vf.getSemanticID(nvidia::RenderVertexSemantic::POSITION)); + PxVec3* positions = (PxVec3*)vb.getBufferAndFormat(format, bufferIndex); + if (positions == NULL) + { + continue; + } + if (format != RenderDataFormat::FLOAT3) + { + continue; + } + + for (int p = 0; p < mParams->partBounds.arraySizes[0]; p++) + { + const uint32_t start = part[p]; + const uint32_t end = part[p + 1]; + for (uint32_t v = start; v < end; v++) + { + mParams->partBounds.buf[p].include(positions[v]); + } + } + } +} + +void ApexRenderMeshAsset::setSubmeshCount(uint32_t submeshCount) +{ + const uint32_t oldSize = mSubmeshes.size(); + + for (uint32_t i = oldSize; i-- > submeshCount;) + { + PX_DELETE(mSubmeshes[i]); + } + + mSubmeshes.resize(submeshCount); + + for (uint32_t i = oldSize; i < submeshCount; ++i) + { + mSubmeshes[i] = PX_NEW(ApexRenderSubmesh); + } +} + + +} +} // end namespace nvidia::apex |