mirror of
https://github.com/godotengine/FBX2glTF.git
synced 2026-01-04 18:10:16 +03:00
Merge pull request #41 from lyuma/preserve_skeletons
Preserve skeletons which do not contain a mesh
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
//
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user