aboutsummaryrefslogtreecommitdiff
path: root/sdk/extensions/exporter/source
diff options
context:
space:
mode:
authorBryan Galdrikian <[email protected]>2017-08-28 13:55:34 -0700
committerBryan Galdrikian <[email protected]>2017-08-28 13:55:34 -0700
commit1e887d827e65a084a0ad0ba933c61a8330aeee07 (patch)
tree1e2aab418dadd37f5dc0aae4d8b00e81d909fd24 /sdk/extensions/exporter/source
parentRemoving ArtistTools and CurveEditor projects (diff)
downloadblast-1e887d827e65a084a0ad0ba933c61a8330aeee07.tar.xz
blast-1e887d827e65a084a0ad0ba933c61a8330aeee07.zip
Candidate 1.1 release.
* SampleAssetViewer now unconditionally loads the commandline-defined asset. * Better error handling in AuthoringTool (stderr and user error handler). * More consistent commandline switches in AuthoringTool and ApexImporter (--ll, --tx, --px flags). * NvBlastExtAuthoring ** Mesh cleaner, tries to remove self intersections and open edges in the interior of a mesh. ** Ability to set interior material to existing (external) material, or a new material id. ** Material ID remapping API. ** Rotation of voronoi cells used for fracturing. * Fixed smoothing groups in FBX exporter code. * Impulse passing from parent to child chunks fixed. * Reading unskinned fbx meshes correctly. * Collision hull generation from fbx meshes fixed. * Win32/64 PerfTest crash fix.
Diffstat (limited to 'sdk/extensions/exporter/source')
-rw-r--r--sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.cpp282
-rw-r--r--sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.h94
-rw-r--r--sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.cpp34
-rw-r--r--sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.h4
-rw-r--r--sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.cpp10
-rw-r--r--sdk/extensions/exporter/source/NvBlastExtExporterObjReader.cpp7
-rw-r--r--sdk/extensions/exporter/source/NvBlastExtExporterObjReader.h6
7 files changed, 324 insertions, 113 deletions
diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.cpp b/sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.cpp
index c376701..263a660 100644
--- a/sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.cpp
+++ b/sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.cpp
@@ -28,17 +28,16 @@
#include "NvBlastExtExporterFbxReader.h"
#include "NvBlastExtExporterFbxUtils.h"
#include "NvBlastGlobals.h"
-#include "fileio/fbxiosettings.h"
-#include "fileio/fbxiosettingspath.h"
-#include "core/base/fbxstringlist.h"
+#include <fbxsdk.h>
#include <iostream>
#include <algorithm>
#include <cctype>
#include <sstream>
-#include "scene/geometry/fbxmesh.h"
+#include <unordered_map>
#include "PxVec3.h"
#include "PxVec2.h"
+#include "PxPlane.h"
#include "NvBlastExtAuthoringMesh.h"
#include "NvBlastExtAuthoringBondGenerator.h"
#include "NvBlastExtAuthoringCollisionBuilder.h"
@@ -50,7 +49,8 @@ using namespace Nv::Blast;
FbxFileReader::FbxFileReader()
{
- mBoneCount = 0;
+ mMeshCount = 0;
+ mChunkCount = 0;
}
void FbxFileReader::release()
@@ -74,11 +74,10 @@ void FbxFileReader::loadFromFile(const char* filename)
// Wrap in a shared ptr so that when it deallocates we get an auto destroy and all of the other assets created don't leak.
std::shared_ptr<FbxManager> sdkManager = std::shared_ptr<FbxManager>(FbxManager::Create(), [=](FbxManager* manager)
{
- std::cout << "Deleting FbxManager" << std::endl;
manager->Destroy();
});
- mBoneCount = 0;
+ mChunkCount = 0;
mCollisionNodes.clear();
FbxIOSettings* ios = FbxIOSettings::Create(sdkManager.get(), IOSROOT);
// Set some properties on the io settings
@@ -141,6 +140,7 @@ void FbxFileReader::loadFromFile(const char* filename)
blastUnits.ConvertScene(scene);
}
+ FbxGeometryConverter geoConverter(sdkManager.get());
FbxDisplayLayer* collisionDisplayLayer = scene->FindMember<FbxDisplayLayer>(FbxUtils::getCollisionGeometryLayerName().c_str());
// Recurse the fbx tree and find all meshes
@@ -155,11 +155,38 @@ void FbxFileReader::loadFromFile(const char* filename)
std::cout << "Found " << meshNodes.size() << " meshes." << std::endl;
- // Process just 0, because dumb. Fail out if more than 1?
if (meshNodes.size() > 1)
{
- std::cerr << "Can't load more that one graphics mesh." << std::endl;
- return;
+ FbxArray<FbxNode*> tempMeshArray;
+ tempMeshArray.Resize((int)meshNodes.size());
+ for (size_t i = 0; i < meshNodes.size(); i++)
+ {
+ FbxMesh* mesh = meshNodes[i]->GetMesh();
+ if (mesh->GetDeformerCount(FbxDeformer::eSkin) != 0)
+ {
+ std::cerr << "Multi-part mesh " << meshNodes[i]->GetName() << " is already skinned, not sure what to do" << std::endl;
+ return;
+ }
+ //Add a one-bone skin so later when we merge meshes the connection to the chunk transform will stick, this handles the non-skinned layout of the FBX file
+ FbxSkin* skin = FbxSkin::Create(scene, (std::string(meshNodes[i]->GetName()) + "_skin").c_str());
+ mesh->AddDeformer(skin);
+ FbxCluster* cluster = FbxCluster::Create(skin, (std::string(meshNodes[i]->GetName()) + "_cluster").c_str());
+ skin->AddCluster(cluster);
+ cluster->SetLink(meshNodes[i]);
+ const int cpCount = mesh->GetControlPointsCount();
+ cluster->SetControlPointIWCount(cpCount);
+ //Fully weight to the one bone
+ int* cpIdx = cluster->GetControlPointIndices();
+ double* cpWeights = cluster->GetControlPointWeights();
+ for (int cp = 0; cp < cpCount; cp++)
+ {
+ cpIdx[cp] = cp;
+ cpWeights[cp] = 1.0;
+ }
+ tempMeshArray.SetAt(int(i), meshNodes[i]);
+ }
+ meshNodes.resize(1);
+ meshNodes[0] = geoConverter.MergeMeshes(tempMeshArray, "MergedMesh", scene);
}
if (meshNodes.empty())
@@ -170,19 +197,16 @@ void FbxFileReader::loadFromFile(const char* filename)
FbxNode* meshNode = meshNodes[0];
FbxMesh* mesh = meshNode->GetMesh();
- int polyCount = mesh->GetPolygonCount();
-
-
- bool bAllTriangles = true;
// Verify that the mesh is triangulated.
- for (int i = 0; i < polyCount; i++)
+ bool bAllTriangles = mesh->IsTriangleMesh();
+ if (!bAllTriangles)
{
- if (mesh->GetPolygonSize(i) != 3)
- {
- bAllTriangles = false;
- }
+ //try letting the FBX SDK triangulate it
+ geoConverter.Triangulate(mesh, true);
+ bAllTriangles = mesh->IsTriangleMesh();
}
+ int polyCount = mesh->GetPolygonCount();
if (!bAllTriangles)
{
std::cerr << "Mesh 0 has " << polyCount << " but not all polygons are triangles. Mesh must be triangulated." << std::endl;
@@ -205,12 +229,7 @@ void FbxFileReader::loadFromFile(const char* filename)
uint32_t vertIndex = 0;
FbxAMatrix trans = getTransformForNode(meshNode);
- FbxVector4 rotation = trans.GetR();
- FbxVector4 scale = trans.GetS();
- FbxAMatrix normalTransf;
- normalTransf.SetR(rotation);
- normalTransf.SetS(scale);
- normalTransf = normalTransf.Inverse().Transpose();
+ FbxAMatrix normalTransf = trans.Inverse().Transpose();
int32_t matElements = mesh->GetElementMaterialCount();
if (matElements > 1)
@@ -220,12 +239,15 @@ void FbxFileReader::loadFromFile(const char* filename)
auto matLayer = mesh->GetElementMaterial(0);
auto smLayer = mesh->GetElementSmoothing();
+ const int triangleIndexMappingUnflipped[3] = { 0, 1, 2 };
+ const int triangleIndexMappingFlipped[3] = { 2, 1, 0 };
+ const int* triangleIndexMapping = trans.Determinant() < 0 ? triangleIndexMappingFlipped : triangleIndexMappingUnflipped;
for (int i = 0; i < polyCount; i++)
{
for (int vi = 0; vi < 3; vi++)
{
- int polyCPIdx = polyVertices[i*3+vi];
+ int polyCPIdx = polyVertices[i*3+ triangleIndexMapping[vi]];
FbxVector4 vert = mesh->GetControlPointAt(polyCPIdx);
FbxVector4 normVec;
@@ -321,33 +343,30 @@ bool FbxFileReader::isCollisionLoaded()
return !mCollisionNodes.empty();
}
-uint32_t FbxFileReader::getCollision(uint32_t*& hullsOffset, Nv::Blast::CollisionHull** hulls)
+uint32_t FbxFileReader::getCollision(uint32_t*& hullsOffset, Nv::Blast::CollisionHull**& hulls)
{
if (!isCollisionLoaded())
{
+ hullsOffset = nullptr;
+ hulls = nullptr;
return 0;
}
- hullsOffset = new uint32_t[mMeshCount + 1];
- hulls = new Nv::Blast::CollisionHull*[mMeshCount];
- memcpy(hullsOffset, mHullsOffset.data(), sizeof(uint32_t) * (mMeshCount + 1));
- memcpy(hulls, mHulls.data(), sizeof(Nv::Blast::CollisionHull*) * mMeshCount);
- return mMeshCount;
-}
-
-struct CollisionHullImpl : public Nv::Blast::CollisionHull
-{
- void release() override
+ hullsOffset = (uint32_t*)NVBLAST_ALLOC(sizeof(uint32_t) * mHullsOffset.size());
+ memcpy(hullsOffset, mHullsOffset.data(), sizeof(uint32_t) * mHullsOffset.size());
+
+
+ hulls = (Nv::Blast::CollisionHull**)NVBLAST_ALLOC(sizeof(Nv::Blast::CollisionHull*) * mHulls.size());
+ for (size_t i = 0; i < mHulls.size(); i++)
{
-
+ //This deep-copies the data inside
+ hulls[i] = new CollisionHullImpl(mHulls[i]);
}
-};
+ return mMeshCount;
+}
bool FbxFileReader::getCollisionInternal()
{
- for (auto hull : mHulls)
- {
- hull->release();
- }
+ mHulls.clear();
int32_t maxParentIndex = 0;
for (auto p : mCollisionNodes)
@@ -358,62 +377,126 @@ bool FbxFileReader::getCollisionInternal()
mMeshCount = maxParentIndex + 1;
mHullsOffset.resize(mMeshCount + 1);
mHulls.resize(mCollisionNodes.size());
- mHullsOffset[0] = 0;
+
+ uint32_t currentHullCount = 0;
+ uint32_t prevParentIndex = 0;
+ mHullsOffset[0] = currentHullCount;
for (auto p : mCollisionNodes) // it should be sorted by chunk id
{
- int32_t parentIndex = p.first;
- //hulls[parentIndex].push_back(Nv::Blast::CollisionHull());
- mHulls[mHullsOffset[parentIndex]] = new CollisionHullImpl();
- Nv::Blast::CollisionHull& chull = *mHulls[mHullsOffset[parentIndex]];
+ uint32_t parentIndex = p.first;
+ if (prevParentIndex != parentIndex)
+ {
+ for (uint32_t m = prevParentIndex + 1; m < parentIndex; m++)
+ {
+ //copy these if there were no collision meshes
+ mHullsOffset[m] = mHullsOffset[prevParentIndex];
+ }
+ mHullsOffset[parentIndex] = currentHullCount;
+ prevParentIndex = parentIndex;
+ }
+ Nv::Blast::CollisionHull& chull = mHulls[currentHullCount];
+ currentHullCount++;
+
FbxMesh* meshNode = p.second->GetMesh();
FbxAMatrix nodeTransform = getTransformForNode(p.second);
FbxAMatrix nodeTransformNormal = nodeTransform.Inverse().Transpose();
- chull.points = new PxVec3[meshNode->GetControlPointsCount()];
+ //PhysX seems to care about having welding verticies.
+ //Probably doing a dumb search is fast enough since how big could the convex hulls possibly be?
+ std::vector<FbxVector4> uniqueCPValues;
+ uniqueCPValues.reserve(meshNode->GetControlPointsCount());
+ std::vector<uint32_t> originalToNewCPMapping(meshNode->GetControlPointsCount(), ~0U);
+
FbxVector4* vpos = meshNode->GetControlPoints();
- /**
- Copy control points from FBX.
- */
for (int32_t i = 0; i < meshNode->GetControlPointsCount(); ++i)
{
FbxVector4 worldVPos = nodeTransform.MultT(*vpos);
+ bool found = false;
+ for (size_t j = 0; j < uniqueCPValues.size(); j++)
+ {
+ if (uniqueCPValues[j] == worldVPos)
+ {
+ originalToNewCPMapping[i] = uint32_t(j);
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ {
+ originalToNewCPMapping[i] = uint32_t(uniqueCPValues.size());
+ uniqueCPValues.push_back(worldVPos);
+ }
+ vpos++;
+ }
+
+ chull.points = new PxVec3[uniqueCPValues.size()];
+ chull.pointsCount = uint32_t(uniqueCPValues.size());
+
+ physx::PxVec3 hullCentroid(0.0f);
+
+ for (uint32_t i = 0; i < chull.pointsCount; ++i)
+ {
+ const FbxVector4& worldVPos = uniqueCPValues[i];
chull.points[i].x = (float)worldVPos[0];
chull.points[i].y = (float)worldVPos[1];
chull.points[i].z = (float)worldVPos[2];
- vpos++;
+ hullCentroid += chull.points[i];
+ }
+
+ if (chull.pointsCount)
+ {
+ hullCentroid /= (float)chull.pointsCount;
}
uint32_t polyCount = meshNode->GetPolygonCount();
chull.polygonData = new Nv::Blast::CollisionHull::HullPolygon[polyCount];
- FbxGeometryElementNormal* nrm = meshNode->GetElementNormal();
- FbxLayerElementArray& narr = nrm->GetDirectArray();
+ chull.polygonDataCount = polyCount;
+
+ chull.indicesCount = meshNode->GetPolygonVertexCount();
+ chull.indices = new uint32_t[chull.indicesCount];
+ uint32_t curIndexCount = 0;
for (uint32_t poly = 0; poly < polyCount; ++poly)
{
int32_t vInPolyCount = meshNode->GetPolygonSize(poly);
auto& pd = chull.polygonData[poly];
- pd.mIndexBase = (uint16_t)chull.indicesCount;
+ pd.mIndexBase = (uint16_t)curIndexCount;
pd.mNbVerts = (uint16_t)vInPolyCount;
int32_t* ind = &meshNode->GetPolygonVertices()[meshNode->GetPolygonVertexIndex(poly)];
- chull.indices = new uint32_t[vInPolyCount];
- memcpy(chull.indices, ind, sizeof(uint32_t) * vInPolyCount);
+ uint32_t* destInd = chull.indices + curIndexCount;
+ for (int32_t v = 0; v < vInPolyCount; v++)
+ {
+ destInd[v] = originalToNewCPMapping[ind[v]];
+ }
+ curIndexCount += vInPolyCount;
+
+ //Don't depend on the normals to create the plane normal, they could be wrong
+ PxVec3 lastThreeVerts[3] = {
+ chull.points[chull.indices[curIndexCount - 1]],
+ chull.points[chull.indices[curIndexCount - 2]],
+ chull.points[chull.indices[curIndexCount - 3]]
+ };
- FbxVector4 normal;
- narr.GetAt(poly, &normal);
+ physx::PxPlane plane(lastThreeVerts[0], lastThreeVerts[1], lastThreeVerts[2]);
+ plane.normalize();
- normal = nodeTransformNormal.MultT(normal);
+ const float s = plane.n.dot(lastThreeVerts[0] - hullCentroid) >= 0.0f ? 1.0f : -1.0f;
- pd.mPlane[0] = (float)normal[0];
- pd.mPlane[1] = (float)normal[1];
- pd.mPlane[2] = (float)normal[2];
- PxVec3 polyLastVertex = chull.points[chull.indices[vInPolyCount - 1]];
- pd.mPlane[3] = -((float)(polyLastVertex.x * normal[0] + polyLastVertex.y * normal[1] + polyLastVertex.z * normal[2]));
+ pd.mPlane[0] = s*plane.n.x;
+ pd.mPlane[1] = s*plane.n.y;
+ pd.mPlane[2] = s*plane.n.z;
+ pd.mPlane[3] = s*plane.d;
}
- mHullsOffset[parentIndex + 1] = mHullsOffset[parentIndex] + 1;
}
-
+
+ //Set the end marker
+ for (uint32_t m = prevParentIndex + 1; m <= mMeshCount; m++)
+ {
+ //copy these if there were no collision meshes
+ mHullsOffset[m] = currentHullCount;
+ }
return false;
}
@@ -424,43 +507,74 @@ bool FbxFileReader::getCollisionInternal()
**/
bool FbxFileReader::getBoneInfluencesInternal(FbxMesh* meshNode)
{
+ std::unordered_map<FbxNode*, uint32_t> boneToChunkIndex;
if (meshNode->GetDeformerCount() != 1)
{
std::cout << "Can't create bone mapping: There is no mesh deformers...: " << std::endl;
return false;
}
- mVertexToParentBoneMap.clear();
- mVertexToParentBoneMap.resize(mVertexPositions.size());
- std::vector<uint32_t> controlToParentBoneMap;
- controlToParentBoneMap.resize(meshNode->GetControlPointsCount());
+ mVertexToContainingChunkMap.clear();
+ mVertexToContainingChunkMap.resize(mVertexPositions.size());
+ std::vector<uint32_t> controlToParentChunkMap;
+ controlToParentChunkMap.resize(meshNode->GetControlPointsCount());
FbxSkin* def = (FbxSkin *)meshNode->GetDeformer(0, FbxDeformer::EDeformerType::eSkin);
if (def->GetClusterCount() == 0)
{
std::cout << "Can't create bone mapping: There is no vertex clusters...: " << std::endl;
return false;
- }
- mBoneCount = def->GetClusterCount();
+ }
+ //We want the number of chunks not the bones in the FBX file
+ mChunkCount = 0;
+
for (int32_t i = 0; i < def->GetClusterCount(); ++i)
{
FbxCluster* cls = def->GetCluster(i);
FbxNode* bone = cls->GetLink();
- int32_t parentChunk = atoi(bone->GetName() + 5);
+
+ uint32_t myChunkIndex;
+ auto findIt = boneToChunkIndex.find(bone);
+ if (findIt != boneToChunkIndex.end())
+ {
+ myChunkIndex = findIt->second;
+ }
+ else
+ {
+ myChunkIndex = FbxUtils::getChunkIndexForNode(bone);
+ if (myChunkIndex == UINT32_MAX)
+ {
+ //maybe an old file?
+ myChunkIndex = FbxUtils::getChunkIndexForNodeBackwardsCompatible(bone);
+ }
+
+ if (myChunkIndex == UINT32_MAX)
+ {
+ std::cerr << "Not sure what to do with node " << bone->GetName() << ". is this a chunk?" << std::endl;
+ }
+
+ boneToChunkIndex.emplace(bone, myChunkIndex);
+ if (myChunkIndex >= mChunkCount)
+ {
+ mChunkCount = myChunkIndex + 1;
+ }
+ }
+
int32_t* cpIndx = cls->GetControlPointIndices();
for (int32_t j = 0; j < cls->GetControlPointIndicesCount(); ++j)
{
- controlToParentBoneMap[*cpIndx] = parentChunk;
+ controlToParentChunkMap[*cpIndx] = myChunkIndex;
++cpIndx;
}
}
+
int* polyVertices = meshNode->GetPolygonVertices();
uint32_t lv = 0;
for (int i = 0; i < meshNode->GetPolygonCount(); i++)
{
for (int vi = 0; vi < 3; vi++)
{
- mVertexToParentBoneMap[lv] = controlToParentBoneMap[*polyVertices];
+ mVertexToContainingChunkMap[lv] = controlToParentChunkMap[*polyVertices];
polyVertices++;
lv++;
}
@@ -490,21 +604,21 @@ uint32_t* FbxFileReader::getIndexArray()
uint32_t FbxFileReader::getBoneInfluences(uint32_t*& out)
{
- out = static_cast<uint32_t*>(NVBLAST_ALLOC(sizeof(uint32_t) * mVertexToParentBoneMap.size()));
- memcpy(out, mVertexToParentBoneMap.data(), sizeof(uint32_t) * mVertexToParentBoneMap.size());
- return mVertexToParentBoneMap.size();
+ out = static_cast<uint32_t*>(NVBLAST_ALLOC(sizeof(uint32_t) * mVertexToContainingChunkMap.size()));
+ memcpy(out, mVertexToContainingChunkMap.data(), sizeof(uint32_t) * mVertexToContainingChunkMap.size());
+ return mVertexToContainingChunkMap.size();
}
uint32_t FbxFileReader::getBoneCount()
{
- return mBoneCount;
+ return mChunkCount;
}
-char* FbxFileReader::getMaterialName(int32_t id)
+const char* FbxFileReader::getMaterialName(int32_t id)
{
if (id < int32_t(mMaterialNames.size()) && id >= 0)
{
- return &mMaterialNames[id][0];
+ return mMaterialNames[id].c_str();
}
else
{
@@ -519,4 +633,4 @@ int32_t* FbxFileReader::getMaterialIds()
return nullptr;
}
return mMaterialIds.data();
-} \ No newline at end of file
+}
diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.h b/sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.h
index b7c81aa..db928f4 100644
--- a/sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.h
+++ b/sdk/extensions/exporter/source/NvBlastExtExporterFbxReader.h
@@ -44,6 +44,87 @@ class Mesh;
class FbxFileReader : public IFbxFileReader
{
+ struct CollisionHullImpl : public Nv::Blast::CollisionHull
+ {
+ void release() override
+ {
+ delete this;
+ }
+
+ //copy from existing
+ CollisionHullImpl(const CollisionHullImpl& other) : CollisionHullImpl()
+ {
+ copyFrom(other);
+ }
+
+ CollisionHullImpl()
+ {
+ pointsCount = 0;
+ indicesCount = 0;
+ polygonDataCount = 0;
+ points = nullptr;
+ indices = nullptr;
+ polygonData = nullptr;
+ }
+
+ CollisionHullImpl(CollisionHullImpl&& other)
+ {
+ operator=(std::move(other));
+ }
+
+ CollisionHullImpl& operator=(const CollisionHullImpl& other)
+ {
+ if (&other != this)
+ {
+ release();
+ copyFrom(other);
+ }
+ return *this;
+ }
+
+ CollisionHullImpl& operator=(CollisionHullImpl&& other)
+ {
+ if (&other != this)
+ {
+ pointsCount = other.pointsCount;
+ indicesCount = other.indicesCount;
+ polygonDataCount = other.polygonDataCount;
+ points = other.points;
+ indices = other.indices;
+ polygonData = other.polygonData;
+
+ other.pointsCount = 0;
+ other.indicesCount = 0;
+ other.polygonDataCount = 0;
+ other.points = nullptr;
+ other.indices = nullptr;
+ other.polygonData = nullptr;
+ }
+ return *this;
+ }
+
+ virtual ~CollisionHullImpl()
+ {
+ delete[] points;
+ delete[] indices;
+ delete[] polygonData;
+ }
+ private:
+
+ void copyFrom(const CollisionHullImpl& other)
+ {
+ pointsCount = other.pointsCount;
+ indicesCount = other.indicesCount;
+ polygonDataCount = other.polygonDataCount;
+ points = new physx::PxVec3[pointsCount];
+ indices = new uint32_t[indicesCount];
+ polygonData = new Nv::Blast::CollisionHull::HullPolygon[polygonDataCount];
+ memcpy(points, other.points, sizeof(points[0]) * pointsCount);
+ memcpy(indices, other.indices, sizeof(indices[0]) * indicesCount);
+ memcpy(polygonData, other.polygonData, sizeof(polygonData[0]) * polygonDataCount);
+ }
+ };
+
public:
FbxFileReader();
~FbxFileReader() = default;
@@ -60,7 +141,7 @@ public:
return mVertexPositions.size();
}
- virtual uint32_t getIdicesCount() const override
+ virtual uint32_t getIndicesCount() const override
{
return mIndices.size();
}
@@ -73,7 +154,7 @@ public:
/**
Retrieve collision geometry if it exist
*/
- virtual uint32_t getCollision(uint32_t*& hullsOffset, Nv::Blast::CollisionHull** hulls) override;
+ virtual uint32_t getCollision(uint32_t*& hullsOffset, Nv::Blast::CollisionHull**& hulls) override;
virtual uint32_t getBoneInfluences(uint32_t*& out) override;
@@ -109,7 +190,7 @@ public:
/**
Get material name.
*/
- char* getMaterialName(int32_t id) override;
+ const char* getMaterialName(int32_t id) override;
int32_t getMaterialCount() override;
@@ -117,9 +198,10 @@ public:
private:
uint32_t mMeshCount;
+ uint32_t mChunkCount;
std::vector<uint32_t> mHullsOffset;
- std::vector<Nv::Blast::CollisionHull*> mHulls;
- std::vector<uint32_t> mVertexToParentBoneMap;
+ std::vector<CollisionHullImpl> mHulls;
+ std::vector<uint32_t> mVertexToContainingChunkMap;
std::multimap<uint32_t, FbxNode*> mCollisionNodes;
std::vector<physx::PxVec3> mVertexPositions;
std::vector<physx::PxVec3> mVertexNormals;
@@ -128,8 +210,6 @@ private:
std::vector<int32_t> mSmoothingGroups;
std::vector<int32_t> mMaterialIds;
std::vector<std::string> mMaterialNames;
-
- uint32_t mBoneCount;
FbxAMatrix getTransformForNode(FbxNode* node);
void getFbxMeshes(FbxDisplayLayer* collisionDisplayLayer, FbxNode* node, std::vector<FbxNode*>& meshNodes);
diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.cpp b/sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.cpp
index 95a757f..a71af2b 100644
--- a/sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.cpp
+++ b/sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.cpp
@@ -146,10 +146,17 @@ std::string FbxUtils::FbxSystemUnitToString(const FbxSystemUnit& systemUnit)
return std::string(systemUnit.GetScaleFactorAsString());
}
-const static std::string chunkPrefix = "chunk_";
+const static std::string currentChunkPrefix = "chunk_";
+const static std::string oldChunkPrefix = "bone_";
-uint32_t FbxUtils::getChunkIndexForNode(FbxNode* node, bool includeParents /*= true*/)
+static uint32_t getChunkIndexForNodeInternal(const std::string& chunkPrefix, FbxNode* node, uint32_t* outParentChunkIndex /*=nullptr*/)
{
+ if (!node)
+ {
+ //Found nothing
+ return UINT32_MAX;
+ }
+
std::string nodeName(node->GetNameOnly());
for (char& c : nodeName)
c = (char)std::tolower(c);
@@ -161,23 +168,32 @@ uint32_t FbxUtils::getChunkIndexForNode(FbxNode* node, bool includeParents /*= t
iss >> ret;
if (!iss.fail())
{
+ if (outParentChunkIndex)
+ {
+ *outParentChunkIndex = getChunkIndexForNodeInternal(chunkPrefix, node->GetParent(), nullptr);
+ }
return ret;
}
}
- if (includeParents && node->GetParent())
- {
- return getChunkIndexForNode(node->GetParent(), true);
- }
- //Found nothing
- return UINT32_MAX;
+ return getChunkIndexForNodeInternal(chunkPrefix, node->GetParent(), outParentChunkIndex);
+}
+
+uint32_t FbxUtils::getChunkIndexForNode(FbxNode* node, uint32_t* outParentChunkIndex /*=nullptr*/)
+{
+ return getChunkIndexForNodeInternal(currentChunkPrefix, node, outParentChunkIndex);
+}
+
+uint32_t FbxUtils::getChunkIndexForNodeBackwardsCompatible(FbxNode* node, uint32_t* outParentChunkIndex /*= nullptr*/)
+{
+ return getChunkIndexForNodeInternal(oldChunkPrefix, node, outParentChunkIndex);
}
std::string FbxUtils::getChunkNodeName(uint32_t chunkIndex)
{
//This naming is required for the UE4 plugin to find them
std::ostringstream namestream;
- namestream << chunkPrefix << chunkIndex;
+ namestream << currentChunkPrefix << chunkIndex;
return namestream.str();
}
diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.h b/sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.h
index d26a9e9..d699a6c 100644
--- a/sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.h
+++ b/sdk/extensions/exporter/source/NvBlastExtExporterFbxUtils.h
@@ -57,7 +57,9 @@ public:
static std::string FbxSystemUnitToString(const FbxSystemUnit& systemUnit);
//returns UINT32_MAX if not a chunk
- static uint32_t getChunkIndexForNode(FbxNode* node, bool includeParents = true);
+ static uint32_t getChunkIndexForNode(FbxNode* node, uint32_t* outParentChunkIndex = nullptr);
+ //Search using the old naming
+ static uint32_t getChunkIndexForNodeBackwardsCompatible(FbxNode* node, uint32_t* outParentChunkIndex = nullptr);
static std::string getChunkNodeName(uint32_t chunkIndex);
static std::string getCollisionGeometryLayerName();
diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.cpp b/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.cpp
index eda8f7c..497c846 100644
--- a/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.cpp
+++ b/sdk/extensions/exporter/source/NvBlastExtExporterFbxWriter.cpp
@@ -55,7 +55,6 @@ FbxFileWriter::FbxFileWriter():
// Wrap in a shared ptr so that when it deallocates we get an auto destroy and all of the other assets created don't leak.
sdkManager = std::shared_ptr<FbxManager>(FbxManager::Create(), [=](FbxManager* manager)
{
- std::cout << "Deleting FbxManager" << std::endl;
manager->Destroy();
});
@@ -197,8 +196,8 @@ bool FbxFileWriter::appendMesh(const AuthoringResult& aResult, const char* asset
// Now walk the tree and create a skeleton with geometry at the same time
// Find a "root" chunk and walk the tree from there.
- uint32_t chunkCount = aResult.chunkCount;
- auto chunks = aResult.chunkDescs;
+ uint32_t chunkCount = NvBlastAssetGetChunkCount(aResult.asset, Nv::Blast::logLL);
+ auto chunks = NvBlastAssetGetChunks(aResult.asset, Nv::Blast::logLL);
uint32_t cpIdx = 0;
for (uint32_t i = 0; i < chunkCount; i++)
@@ -242,9 +241,8 @@ bool FbxFileWriter::appendNonSkinnedMesh(const AuthoringResult& aResult, const c
// Now walk the tree and create a skeleton with geometry at the same time
// Find a "root" chunk and walk the tree from there.
- uint32_t chunkCount = aResult.chunkCount;
-
- auto chunks = aResult.chunkDescs;
+ uint32_t chunkCount = NvBlastAssetGetChunkCount(aResult.asset, Nv::Blast::logLL);
+ auto chunks = NvBlastAssetGetChunks(aResult.asset, Nv::Blast::logLL);
for (uint32_t i = 0; i < chunkCount; i++)
{
diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.cpp b/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.cpp
index 95efb3e..fb6e9b3 100644
--- a/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.cpp
+++ b/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.cpp
@@ -103,10 +103,11 @@ bool ObjFileReader::isCollisionLoaded()
};
-uint32_t ObjFileReader::getCollision(uint32_t*& hullsOffset, Nv::Blast::CollisionHull** hulls)
+uint32_t ObjFileReader::getCollision(uint32_t*& hullsOffset, Nv::Blast::CollisionHull**& hulls)
{
- NV_UNUSED(hulls);
- return false;
+ hullsOffset = nullptr;
+ hulls = nullptr;
+ return 0;
};
physx::PxVec3* ObjFileReader::getPositionArray()
diff --git a/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.h b/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.h
index f80f8f9..8990287 100644
--- a/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.h
+++ b/sdk/extensions/exporter/source/NvBlastExtExporterObjReader.h
@@ -57,7 +57,7 @@ public:
return mVertexPositions.size();
}
- virtual uint32_t getIdicesCount() const override
+ virtual uint32_t getIndicesCount() const override
{
return mIndices.size();
}
@@ -70,7 +70,7 @@ public:
/**
Retrieve collision geometry if it exist
*/
- virtual uint32_t getCollision(uint32_t*& hullsOffset, Nv::Blast::CollisionHull** hulls) override;
+ virtual uint32_t getCollision(uint32_t*& hullsOffset, Nv::Blast::CollisionHull**& hulls) override;
/**
Get loaded vertex positions
@@ -102,7 +102,7 @@ public:
/**
Get material name. Currently not supported by OBJ.
*/
- char* getMaterialName(int32_t id) override { return nullptr; }
+ const char* getMaterialName(int32_t id) override { return nullptr; }
/**
Get material count.