Merge pull request #41 from lyuma/preserve_skeletons

Preserve skeletons which do not contain a mesh
This commit is contained in:
K. S. Ernest (iFire) Lee
2023-06-10 16:10:06 -07:00
committed by GitHub
6 changed files with 59 additions and 8 deletions

View File

@@ -688,10 +688,19 @@ static void ReadNodeHierarchy(
FbxScene* pScene,
FbxNode* pNode,
const long parentId,
const std::string& path) {
const std::string& path,
int extraSkinIx) {
const FbxUInt64 nodeId = pNode->GetUniqueID();
const char* nodeName = pNode->GetName();
const int nodeIndex = raw.AddNode(nodeId, nodeName, parentId);
FbxSkeleton *skel = pNode->GetSkeleton();
if (skel == nullptr) {
extraSkinIx = -1;
} else {
if (skel->IsSkeletonRoot()) {
extraSkinIx = raw.CreateExtraSkinIndex();
}
}
const int nodeIndex = raw.AddNode(nodeId, nodeName, parentId, extraSkinIx);
RawNode& node = raw.GetNode(nodeIndex);
FbxTransform::EInheritType lInheritType;
@@ -745,7 +754,7 @@ static void ReadNodeHierarchy(
raw.SetRootNode(nodeId);
}
for (int child = 0; child < pNode->GetChildCount(); child++) {
ReadNodeHierarchy(raw, pScene, pNode->GetChild(child), nodeId, newPath);
ReadNodeHierarchy(raw, pScene, pNode->GetChild(child), nodeId, newPath, extraSkinIx);
}
}
@@ -1174,7 +1183,7 @@ bool LoadFBXFile(
// this is always 0.01, but let's opt for clarity.
scaleFactor = FbxSystemUnit::m.GetConversionFactorFrom(FbxSystemUnit::cm);
ReadNodeHierarchy(raw, pScene, pScene->GetRootNode(), 0, "");
ReadNodeHierarchy(raw, pScene, pScene->GetRootNode(), 0, "", -1);
ReadNodeAttributes(raw, pScene, pScene->GetRootNode(), textureLocations);
ReadAnimations(raw, pScene, options);

View File

@@ -853,6 +853,18 @@ ModelData* Raw2Gltf(
}
}
std::vector<std::vector<uint32_t>> extraJointIndexes;
extraJointIndexes.resize(raw.GetExtraSkinCount());
for (int i = 0; i < raw.GetNodeCount(); i++) {
const RawNode& node = raw.GetNode(i);
if (node.extraSkinIx >= 0) {
extraJointIndexes[node.extraSkinIx].push_back(i);
}
}
for (int i = 0; i < extraJointIndexes.size(); i++) {
gltf->skins.hold(new SkinData(extraJointIndexes[i], true));
}
//
// cameras
//

View File

@@ -18,9 +18,22 @@ SkinData::SkinData(
: Holdable(),
joints(joints),
inverseBindMatrices(inverseBindMatricesAccessor.ix),
skeletonRootNode(skeletonRootNode.ix) {}
skeletonRootNode(skeletonRootNode.ix),
isExtraSkin(false) {}
SkinData::SkinData(
const std::vector<uint32_t> joints,
bool isExtraSkin)
: Holdable(),
joints(joints),
inverseBindMatrices(0),
skeletonRootNode(0),
isExtraSkin(true) {}
json SkinData::serialize() const {
if (isExtraSkin) {
return {{"joints", joints}};
}
return {
{"joints", joints},
{"inverseBindMatrices", inverseBindMatrices},

View File

@@ -16,9 +16,14 @@ struct SkinData : Holdable {
const AccessorData& inverseBindMatricesAccessor,
const NodeData& skeletonRootNode);
SkinData(
const std::vector<uint32_t> joints,
bool isExtraSkin);
json serialize() const override;
const std::vector<uint32_t> joints;
const uint32_t skeletonRootNode;
const uint32_t inverseBindMatrices;
const bool isExtraSkin;
};

View File

@@ -69,7 +69,7 @@ size_t RawVertex::Difference(const RawVertex& other) const {
return attributes;
}
RawModel::RawModel() : vertexAttributes(0) {}
RawModel::RawModel() : nextExtraSkinIx(0), rootNodeId(0), vertexAttributes(0), globalMaxWeights(0) {}
void RawModel::AddVertexAttribute(const RawVertexAttribute attrib) {
vertexAttributes |= attrib;
@@ -311,7 +311,7 @@ int RawModel::AddCameraOrthographic(
return (int)cameras.size() - 1;
}
int RawModel::AddNode(const long id, const char* name, const long parentId) {
int RawModel::AddNode(const long id, const char* name, const long parentId, const int extraSkinIx) {
assert(name[0] != '\0');
for (size_t i = 0; i < nodes.size(); i++) {
@@ -330,6 +330,7 @@ int RawModel::AddNode(const long id, const char* name, const long parentId) {
joint.translation = Vec3f(0, 0, 0);
joint.rotation = Quatf(0, 0, 0, 1);
joint.scale = Vec3f(1, 1, 1);
joint.extraSkinIx = extraSkinIx;
nodes.emplace_back(joint);
return (int)nodes.size() - 1;

View File

@@ -355,6 +355,7 @@ struct RawNode {
long surfaceId;
long lightIx;
std::vector<std::string> userProperties;
int extraSkinIx;
};
class RawModel {
@@ -410,7 +411,7 @@ class RawModel {
const float nearZ,
const float farZ);
int AddNode(const RawNode& node);
int AddNode(const long id, const char* name, const long parentId);
int AddNode(const long id, const char* name, const long parentId, const int extraSkinIx);
void SetRootNode(const long nodeId) {
rootNodeId = nodeId;
}
@@ -541,9 +542,19 @@ class RawModel {
const int keepAttribs,
const bool forceDiscrete) const;
int CreateExtraSkinIndex() {
int ret = nextExtraSkinIx;
nextExtraSkinIx++;
return ret;
}
int GetExtraSkinCount() const {
return nextExtraSkinIx;
}
private:
Vec3f getFaceNormal(int verts[3]) const;
int nextExtraSkinIx;
long rootNodeId;
int vertexAttributes;
int globalMaxWeights;