diff options
| author | Bryan Galdrikian <[email protected]> | 2018-01-22 14:04:16 -0800 |
|---|---|---|
| committer | Bryan Galdrikian <[email protected]> | 2018-01-22 14:04:16 -0800 |
| commit | 1dc1a87fba520bb45c1ce8165e8ea2c83c0a308d (patch) | |
| tree | 5f8ca75a6b92c60fb5cf3b14282fc4cc1c127eb2 /sdk/extensions/exporter/source | |
| parent | Updating readme.md to show updated UE4 Blast integration branches (diff) | |
| download | blast-1dc1a87fba520bb45c1ce8165e8ea2c83c0a308d.tar.xz blast-1dc1a87fba520bb45c1ce8165e8ea2c83c0a308d.zip | |
Changes for 1.1.2 release candidate
See README.md, docs/release_notes.txt
Diffstat (limited to 'sdk/extensions/exporter/source')
6 files changed, 174 insertions, 31 deletions
diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.cpp b/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.cpp index 497c846..d465d65 100644 --- a/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.cpp +++ b/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.cpp @@ -69,6 +69,8 @@ FbxFileWriter::FbxFileWriter(): mRenderLayer = FbxDisplayLayer::Create(mScene, FbxUtils::getRenderGeometryLayerName().c_str()); mRenderLayer->Show.Set(true); mRenderLayer->Color.Set(FbxDouble3(0.0f, 1.0f, 0.0f)); + + mInteriorIndex = -1; } void FbxFileWriter::release() @@ -89,13 +91,19 @@ void FbxFileWriter::createMaterials(const ExporterMeshData& aResult) for (uint32_t i = 0; i < aResult.submeshCount; ++i) { - FbxSurfacePhong* material = FbxSurfacePhong::Create(sdkManager.get(), aResult.submeshNames[i]); + FbxSurfacePhong* material = FbxSurfacePhong::Create(sdkManager.get(), aResult.submeshMats[i].name); material->Diffuse.Set(FbxDouble3(float(rand()) / RAND_MAX , float(rand()) / RAND_MAX, float(rand()) / RAND_MAX)); material->DiffuseFactor.Set(1.0); mMaterials.push_back(material); } } +void FbxFileWriter::setInteriorIndex(int32_t index) +{ + mInteriorIndex = index; +} + + void FbxFileWriter::createMaterials(const AuthoringResult& aResult) { mMaterials.clear(); @@ -113,10 +121,19 @@ void FbxFileWriter::createMaterials(const AuthoringResult& aResult) material->DiffuseFactor.Set(1.0); mMaterials.push_back(material); } - FbxSurfacePhong* interiorMat = FbxSurfacePhong::Create(sdkManager.get(), "Interior_Material"); - interiorMat->Diffuse.Set(FbxDouble3(1.0, 0.0, 0.5)); - interiorMat->DiffuseFactor.Set(1.0); - mMaterials.push_back(interiorMat); + if (mInteriorIndex == -1) // No material setted. Create new one. + { + FbxSurfacePhong* interiorMat = FbxSurfacePhong::Create(sdkManager.get(), "Interior_Material"); + interiorMat->Diffuse.Set(FbxDouble3(1.0, 0.0, 0.5)); + interiorMat->DiffuseFactor.Set(1.0); + mMaterials.push_back(interiorMat); + } + else + { + if (mInteriorIndex < 0) mInteriorIndex = 0; + if (static_cast<size_t>(mInteriorIndex) >= mMaterials.size()) mInteriorIndex = 0; + } + } @@ -416,7 +433,7 @@ uint32_t FbxFileWriter::createChunkRecursive(uint32_t currentCpIdx, uint32_t chu mesh->AddPolygon(currentCpIdx + cpIdx + 1); mesh->AddPolygon(currentCpIdx + cpIdx + 2); mesh->EndPolygon(); - int32_t material = (tri.materialId != MATERIAL_INTERIOR) ? ((tri.materialId < int32_t(mMaterials.size() - 1)) ? tri.materialId : 0) : int32_t(mMaterials.size() - 1); + int32_t material = (tri.materialId != MATERIAL_INTERIOR) ? ((tri.materialId < int32_t(mMaterials.size())) ? tri.materialId : 0) : ((mInteriorIndex == -1) ? int32_t(mMaterials.size() - 1): mInteriorIndex); matElement->GetIndexArray().SetAt(polyCount, material); if (smElement) { @@ -648,7 +665,7 @@ void FbxFileWriter::createChunkRecursiveNonSkinned(const std::string& meshName, geUV->GetDirectArray().Add(uv); } mesh->EndPolygon(); - int32_t material = (geo.materialId != MATERIAL_INTERIOR) ? ((geo.materialId < int32_t(mMaterials.size() - 1))? geo.materialId : 0) : int32_t(mMaterials.size() - 1); + int32_t material = (geo.materialId != MATERIAL_INTERIOR) ? ((geo.materialId < int32_t(mMaterials.size()))? geo.materialId : 0) : ((mInteriorIndex == -1)? int32_t(mMaterials.size() - 1) : mInteriorIndex); matElement->GetIndexArray().SetAt(polyCount, material); if (smElement) diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.h b/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.h index f8490cb..b6d5859 100644 --- a/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.h +++ b/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.h @@ -84,11 +84,16 @@ public: virtual bool appendMesh(const ExporterMeshData& meshData, const char* assetName, bool nonSkinned) override; /** - Save scene to file. + Save scene to file. */ virtual bool saveToFile(const char* assetName, const char* outputPath) override; /** + Set interior material index. + */ + virtual void setInteriorIndex(int32_t index) override; + + /** Set true if FBX should be saved in ASCII mode. */ bool bOutputFBXAscii; @@ -129,6 +134,8 @@ private: void generateSmoothingGroups(fbxsdk::FbxMesh* mesh, FbxSkin* skin); void removeDuplicateControlPoints(fbxsdk::FbxMesh* mesh, FbxSkin* skin); + + int32_t mInteriorIndex; }; } diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.cpp b/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.cpp index fb6e9b3..9eba7d5 100644 --- a/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.cpp +++ b/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.cpp @@ -60,7 +60,18 @@ void ObjFileReader::loadFromFile(const char* filename) std::vector<tinyobj::material_t> mats; std::string err; std::string mtlPath; - bool ret = tinyobj::LoadObj(shapes, mats, err, filename); + + int32_t lastDelimeter = strlen(filename); + + while (lastDelimeter > 0 && filename[lastDelimeter] != '/' && filename[lastDelimeter] != '\\') + { + lastDelimeter--; + } + mtlPath = std::string(filename, filename + lastDelimeter); + mtlPath += '/'; + + bool ret = tinyobj::LoadObj(shapes, mats, err, filename, mtlPath.c_str()); + // can't load? if (!ret) { @@ -71,6 +82,18 @@ void ObjFileReader::loadFromFile(const char* filename) std::cout << "Can load only one object per mesh" << std::endl; } + if (!mats.empty()) + { + if (mats.size() == 1 && mats[0].name == "") + { + mats[0].name = "Default"; + } + for (uint32_t i = 0; i < mats.size(); ++i) + { + mMaterialNames.push_back(mats[i].name); + } + } + mVertexPositions.clear(); mVertexNormals.clear(); mVertexUv.clear(); @@ -93,6 +116,14 @@ void ObjFileReader::loadFromFile(const char* filename) } mIndices = shapes[0].mesh.indices; + mPerFaceMatId = shapes[0].mesh.material_ids; + for (uint32_t i = 0; i < mPerFaceMatId.size(); ++i) + { + if (mPerFaceMatId[i] == -1) // TinyOBJ loader sets ID to -1 when .mtl file not found. Set to default 0 material. + { + mPerFaceMatId[i] = 0; + } + } } diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.h b/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.h index 8990287..2e8c955 100644 --- a/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.h +++ b/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.h @@ -90,9 +90,9 @@ public: virtual uint32_t* getIndexArray() override; /** - Get loaded per triangle material ids. Currently not supported by OBJ. + Get loaded per triangle material ids. */ - int32_t* getMaterialIds() override { return nullptr; }; + int32_t* getMaterialIds() override { return mPerFaceMatId.data(); }; /** Get loaded per triangle smoothing groups. Currently not supported by OBJ. @@ -100,20 +100,24 @@ public: int32_t* getSmoothingGroups() override { return nullptr; }; /** - Get material name. Currently not supported by OBJ. + Get material name. */ - const char* getMaterialName(int32_t id) override { return nullptr; } + const char* getMaterialName(int32_t id) override { return mMaterialNames[id].c_str(); } /** Get material count. */ - int32_t getMaterialCount() { return 0; }; + int32_t getMaterialCount() { return mMaterialNames.size(); }; private: std::vector<physx::PxVec3> mVertexPositions; std::vector<physx::PxVec3> mVertexNormals; std::vector<physx::PxVec2> mVertexUv; std::vector<uint32_t> mIndices; + + std::vector<std::string> mMaterialNames; + std::vector<int32_t> mPerFaceMatId; + }; } diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterObjWriter.cpp b/sdk/extensions/exporter/source/NvBlastExtExporterObjWriter.cpp index a49e28f..b453a62 100644 --- a/sdk/extensions/exporter/source/NvBlastExtExporterObjWriter.cpp +++ b/sdk/extensions/exporter/source/NvBlastExtExporterObjWriter.cpp @@ -31,6 +31,7 @@ #include <sstream> #include "NvBlastExtAuthoringTypes.h" #include "NvBlastExtAuthoringMesh.h" +#include <algorithm> using namespace physx; @@ -43,6 +44,16 @@ void ObjFileWriter::release() delete this; } +void ObjFileWriter::setInteriorIndex(int32_t index) +{ + mIntSurfaceMatIndex = index; +} + +bool CompByMaterial(const Triangle& a, const Triangle& b) +{ + return a.materialId < b.materialId; +} + bool ObjFileWriter::appendMesh(const AuthoringResult& aResult, const char* /*assetName*/, bool /*nonSkinned*/) { mMeshData = std::shared_ptr<ExporterMeshData>(new ExporterMeshData(), [](ExporterMeshData* md) @@ -55,34 +66,90 @@ bool ObjFileWriter::appendMesh(const AuthoringResult& aResult, const char* /*ass delete[] md->positions; delete[] md->submeshOffsets; //delete[] md->texIndex; - delete[] md->submeshNames; + delete[] md->submeshMats; delete[] md->uvs; delete md; }); + + ExporterMeshData& md = *mMeshData.get(); uint32_t triCount = aResult.geometryOffset[aResult.chunkCount]; md.meshCount = aResult.chunkCount; - md.submeshOffsets = new uint32_t[md.meshCount + 1]; - for (uint32_t i = 0; i < md.meshCount + 1; i++) - { - md.submeshOffsets[i] = aResult.geometryOffset[i] * 3; + md.submeshCount = aResult.materialCount; + + int32_t additionalMats = 0; + + if (mIntSurfaceMatIndex == -1 || mIntSurfaceMatIndex >= (int32_t)md.submeshCount) + { + md.submeshCount += 1; + mIntSurfaceMatIndex = md.submeshCount - 1; + additionalMats = 1; + } + + md.submeshOffsets = new uint32_t[md.meshCount * md.submeshCount + 1]; + md.submeshMats = new Materials[md.submeshCount]; + + for (uint32_t i = 0; i < md.submeshCount - additionalMats; ++i) + { + md.submeshMats[i].name = aResult.materialNames[i]; + md.submeshMats[i].diffuse_tex = nullptr; + } + + if (additionalMats) + { + md.submeshMats[mIntSurfaceMatIndex].name = interiorNameStr.c_str(); + md.submeshMats[mIntSurfaceMatIndex].diffuse_tex = nullptr; } - //md.submeshOffsets = md.meshOffsets; - md.submeshCount = 1; - //md.indicesCount = triCount * 3; md.positionsCount = triCount * 3; md.normalsCount = md.positionsCount; md.uvsCount = md.positionsCount; md.positions = new PxVec3[md.positionsCount]; md.normals = new PxVec3[md.normalsCount]; md.uvs = new PxVec2[md.uvsCount]; + md.posIndex = new uint32_t[triCount * 3]; md.normIndex = md.posIndex; md.texIndex = md.posIndex; - md.submeshNames = new const char*[1]{ gTexPath }; + + + + /** + Now we need to sort input trianles chunk they belong to, then by material; + */ + std::vector<Triangle> sorted; + sorted.reserve(triCount); + + + int32_t perChunkOffset = 0; + for (uint32_t i = 0; i < md.meshCount; ++i) + { + std::vector<uint32_t> perMaterialCount(md.submeshCount); + + uint32_t first = aResult.geometryOffset[i]; + uint32_t last = aResult.geometryOffset[i + 1]; + uint32_t firstInSorted = sorted.size(); + for (uint32_t t = first; t < last; ++t) + { + sorted.push_back(aResult.geometry[t]); + int32_t cmat = sorted.back().materialId; + if (cmat == MATERIAL_INTERIOR) + { + cmat = mIntSurfaceMatIndex; + } + perMaterialCount[cmat]++; + } + for (uint32_t mof = 0; mof < md.submeshCount; ++mof) + { + md.submeshOffsets[i * md.submeshCount + mof] = perChunkOffset * 3; + perChunkOffset += perMaterialCount[mof]; + } + std::sort(sorted.begin() + firstInSorted, sorted.end(), CompByMaterial); + } + md.submeshOffsets[md.meshCount * md.submeshCount] = perChunkOffset * 3; + for (uint32_t vc = 0; vc < triCount; ++vc) { - Triangle& tri = aResult.geometry[vc]; + Triangle& tri = sorted[vc]; uint32_t i = vc * 3; md.positions[i+0] = tri.a.p; md.positions[i+1] = tri.b.p; @@ -129,8 +196,15 @@ bool ObjFileWriter::saveToFile(const char* assetName, const char* outputPath) for (uint32_t submeshIndex = 0; submeshIndex < md.submeshCount; ++submeshIndex) { - fprintf(f, "newmtl mat%d\n", submeshIndex); - fprintf(f, "\tmap_Kd %s\n", md.submeshNames[submeshIndex]); + fprintf(f, "newmtl %s\n", md.submeshMats[submeshIndex].name); + if (md.submeshMats[submeshIndex].diffuse_tex != nullptr) + { + fprintf(f, "\tmap_Kd %s\n", md.submeshMats[submeshIndex].diffuse_tex); + } + else + { + fprintf(f, "\tKd %f %f %f\n", float(rand()) / RAND_MAX, float(rand()) / RAND_MAX, float(rand()) / RAND_MAX); + } fprintf(f, "\n"); } @@ -165,13 +239,16 @@ bool ObjFileWriter::saveToFile(const char* assetName, const char* outputPath) for (uint32_t chunkIndex = 0; chunkIndex < chunkCount; ++chunkIndex) { + fprintf(f, "g %d \n", chunkIndex); for (uint32_t submeshIndex = 0; submeshIndex < md.submeshCount; ++submeshIndex) { uint32_t firstIdx = md.submeshOffsets[chunkIndex * md.submeshCount + submeshIndex]; uint32_t lastIdx = md.submeshOffsets[chunkIndex * md.submeshCount + submeshIndex + 1]; - fprintf(f, "g %d_%d \n", chunkIndex, submeshIndex); - fprintf(f, "usemtl mat%d\n", submeshIndex); - + if (firstIdx == lastIdx) // There is no trianlges in this submesh. + { + continue; + } + fprintf(f, "usemtl %s\n", md.submeshMats[submeshIndex].name); for (uint32_t i = firstIdx; i < lastIdx; i += 3) { fprintf(f, "f %d/%d/%d ", md.posIndex[i] + 1, md.texIndex[i] + 1, md.normIndex[i] + 1); diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterObjWriter.h b/sdk/extensions/exporter/source/NvBlastExtExporterObjWriter.h index 3152d42..65e3f0f 100644 --- a/sdk/extensions/exporter/source/NvBlastExtExporterObjWriter.h +++ b/sdk/extensions/exporter/source/NvBlastExtExporterObjWriter.h @@ -34,7 +34,7 @@ #include <vector> #include <PxVec2.h> #include <PxVec3.h> - +#include <string> struct NvBlastAsset; namespace Nv @@ -46,7 +46,7 @@ class ObjFileWriter : public IMeshFileWriter { public: - ObjFileWriter() {}; + ObjFileWriter(): mIntSurfaceMatIndex(-1), interiorNameStr("INTERIOR_MATERIAL") { }; ~ObjFileWriter() = default; virtual void release() override; @@ -63,8 +63,15 @@ public: */ virtual bool saveToFile(const char* assetName, const char* outputPath) override; + /** + Set interior material index. Not supported in OBJ since AuthoringTool doesn't created OBJ with materials currently. + */ + virtual void setInteriorIndex(int32_t index) override; + private: std::shared_ptr<ExporterMeshData> mMeshData; + int32_t mIntSurfaceMatIndex; + std::string interiorNameStr; }; } |