diff options
Diffstat (limited to 'samples/SampleBase/blast/BlastAssetModel.cpp')
| -rw-r--r-- | samples/SampleBase/blast/BlastAssetModel.cpp | 227 |
1 files changed, 198 insertions, 29 deletions
diff --git a/samples/SampleBase/blast/BlastAssetModel.cpp b/samples/SampleBase/blast/BlastAssetModel.cpp index c42215e..28ef44d 100644 --- a/samples/SampleBase/blast/BlastAssetModel.cpp +++ b/samples/SampleBase/blast/BlastAssetModel.cpp @@ -1,60 +1,229 @@ -/* -* 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. -*/ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and 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. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved. + #include "BlastAssetModel.h" #include "Renderer.h" #include "BlastController.h" #include "Utils.h" #include "ResourceManager.h" -#include "PsFileBuffer.h" #include "NvBlastExtPxAsset.h" #include <sstream> +#include <fstream> +#include "NvBlastExtExporter.h" +#include "PxPhysics.h" +#include <NvBlastGlobals.h> +#include "NvBlastExtAssetUtils.h" +#include "NvBlastExtPxAsset.h" +#include "NvBlastTkAsset.h" +#include "NvBlastExtSerialization.h" +#include "NvBlastExtLlSerialization.h" +#include "NvBlastExtTkSerialization.h" +#include "NvBlastExtPxSerialization.h" +#include "NvBlastExtAuthoring.h" +#include "NvBlastExtAuthoringCollisionBuilder.h" - -BlastAssetModel::BlastAssetModel(TkFramework& framework, PxPhysics& physics, PxCooking& cooking, Renderer& renderer, const char* modelName) +BlastAssetModel::BlastAssetModel(TkFramework& framework, PxPhysics& physics, PxCooking& cooking, ExtSerialization& serialization, Renderer& renderer, const char* modelName) : BlastAsset(renderer) { - ResourceManager& resourceManager = m_renderer.getResourceManager(); + const float unitConversion = 1.f; - // Physics Asset - std::ostringstream blastFileName; - blastFileName << modelName << ".bpxa"; + const NvcVec3 inputScale = { unitConversion, unitConversion, unitConversion }; + + ResourceManager& resourceManager = m_renderer.getResourceManager(); std::string path; - if (resourceManager.findFile(blastFileName.str(), path)) - { - PsFileBuffer fileBuf(path.c_str(), PxFileBuf::OPEN_READ_ONLY); - m_pxAsset = ExtPxAsset::deserialize(fileBuf, framework, physics); - ASSERT_PRINT(m_pxAsset != nullptr, "can't load bpxa file"); - } - else - { - ASSERT_PRINT(false, "wrong blastFilename"); - } // load obj file std::ostringstream objFileName; objFileName << modelName << ".obj"; + if (resourceManager.findFile(objFileName.str(), path)) { m_model = BlastModel::loadFromFileTinyLoader(path.c_str()); if (!m_model) { ASSERT_PRINT(false, "obj load failed"); + } + } + else // Obj is not found, try FBX + { + objFileName.clear(); + objFileName.str(""); + objFileName << modelName << ".fbx"; + if (resourceManager.findFile(objFileName.str(), path)) + { + m_model = BlastModel::loadFromFbxFile(path.c_str()); + if (!m_model) + { + ASSERT_PRINT(false, "fbx load failed"); + } + + } + else + { + ASSERT_PRINT(false, "mesh file not found"); } } - else + + for (auto& chunk : m_model->chunks) { - ASSERT_PRINT(false, "wrong objFileName"); + for (auto& mesh : chunk.meshes) + { + SimpleMesh& smesh = const_cast<SimpleMesh&>(mesh.mesh); + smesh.center *= unitConversion; + smesh.extents *= unitConversion; + for (auto& vertex : smesh.vertices) + { + vertex.position *= unitConversion; + } + } + } + + // Physics Asset + + // Read file into buffer + std::ostringstream blastFileName; + blastFileName << modelName << ".blast"; + if (resourceManager.findFile(blastFileName.str(), path)) + { + std::ifstream stream(path.c_str(), std::ios::binary); + std::streampos size = stream.tellg(); + stream.seekg(0, std::ios::end); + size = stream.tellg() - size; + stream.seekg(0, std::ios::beg); + std::vector<char> buffer(size); + stream.read(buffer.data(), buffer.size()); + stream.close(); + uint32_t objectTypeID; + void* asset = serialization.deserializeFromBuffer(buffer.data(), buffer.size(), &objectTypeID); + if (asset == nullptr) + { + ASSERT_PRINT(asset != nullptr, "can't load .blast file."); + } + else + if (objectTypeID == Nv::Blast::ExtPxObjectTypeID::Asset) + { + m_pxAsset = reinterpret_cast<ExtPxAsset*>(asset); + const TkAsset& tkAsset = m_pxAsset->getTkAsset(); + NvBlastAsset* llasset = const_cast<NvBlastAsset*>(tkAsset.getAssetLL()); + NvBlastExtAssetTransformInPlace(llasset, &inputScale, nullptr, nullptr); + ExtPxSubchunk* subchunks = const_cast<ExtPxSubchunk*>(m_pxAsset->getSubchunks()); + for (uint32_t i = 0; i < m_pxAsset->getSubchunkCount(); ++i) + { + subchunks[i].geometry.scale.scale = PxVec3(unitConversion); + } + } + else + { + TkAsset* tkAsset = nullptr; + if (objectTypeID == Nv::Blast::TkObjectTypeID::Asset) + { + tkAsset = reinterpret_cast<TkAsset*>(asset); + NvBlastAsset* llasset = const_cast<NvBlastAsset*>(tkAsset->getAssetLL()); + NvBlastExtAssetTransformInPlace(llasset, &inputScale, nullptr, nullptr); + } + else + if (objectTypeID == Nv::Blast::LlObjectTypeID::Asset) + { + NvBlastAsset* llasset = reinterpret_cast<NvBlastAsset*>(asset); + NvBlastExtAssetTransformInPlace(llasset, &inputScale, nullptr, nullptr); + tkAsset = framework.createAsset(llasset, nullptr, 0, true); + } + else + { + ASSERT_PRINT(false, ".blast file contains unknown object."); + } + + if (tkAsset != nullptr) + { + std::vector<ExtPxAssetDesc::ChunkDesc> physicsChunks; + std::vector<std::vector<ExtPxAssetDesc::SubchunkDesc> > physicsSubchunks; + /** + Try find FBX and check whether it contains collision geometry. + */ + objFileName.str(""); + objFileName << modelName << ".fbx"; + if (resourceManager.findFile(objFileName.str(), path)) + { + std::shared_ptr<IFbxFileReader> rdr(NvBlastExtExporterCreateFbxFileReader(), [](IFbxFileReader* p) {p->release(); }); + rdr->loadFromFile(path.c_str()); + if (rdr->isCollisionLoaded() == 0) + { + ASSERT_PRINT(false, "fbx doesn't contain collision geometry"); + } + uint32_t* hullsOffsets = nullptr; + CollisionHull** hulls = nullptr; + uint32_t meshCount = rdr->getCollision(hullsOffsets, hulls); + + /** + Create physics meshes; + */ + std::shared_ptr<Nv::Blast::ConvexMeshBuilder> collisionBuilder( + NvBlastExtAuthoringCreateConvexMeshBuilder(&cooking, &physics.getPhysicsInsertionCallback()), + [](Nv::Blast::ConvexMeshBuilder* cmb) {cmb->release(); }); + + physicsChunks.resize(meshCount); + physicsSubchunks.resize(meshCount); + + for (uint32_t i = 0; i < meshCount; ++i) + { + for (uint32_t sbHulls = hullsOffsets[i]; sbHulls < hullsOffsets[i+1]; ++sbHulls) + { + PxConvexMeshGeometry temp = physx::PxConvexMeshGeometry(collisionBuilder.get()->buildConvexMesh(*hulls[sbHulls])); + if (temp.isValid()) + { + physicsSubchunks[i].push_back(ExtPxAssetDesc::SubchunkDesc()); + physicsSubchunks[i].back().geometry = temp; + physicsSubchunks[i].back().transform = physx::PxTransform(physx::PxIdentity); + } + } + } + for (uint32_t i = 0; i < meshCount; ++i) + { + physicsChunks[i].isStatic = false; + physicsChunks[i].subchunkCount = (uint32_t)physicsSubchunks[i].size(); + physicsChunks[i].subchunks = physicsSubchunks[i].data(); + } + if (hullsOffsets) + { + NVBLAST_FREE(hullsOffsets); + } + if (hulls) + { + NVBLAST_FREE(hulls); + } + } + m_pxAsset = ExtPxAsset::create(tkAsset, physicsChunks.data(), (uint32_t)physicsChunks.size()); + ASSERT_PRINT(m_pxAsset != nullptr, "can't create asset"); + } + } } - validate(); + initialize(); } |