Merge remote-tracking branch 'upstream/master' into feat-stingray-pbs
This commit is contained in:
commit
4d9ecea4fd
|
@ -691,8 +691,23 @@ static void ReadMesh(RawModel &raw, FbxScene *pScene, FbxNode *pNode, const std:
|
||||||
meshConverter.Triangulate(pNode->GetNodeAttribute(), true);
|
meshConverter.Triangulate(pNode->GetNodeAttribute(), true);
|
||||||
FbxMesh *pMesh = pNode->GetMesh();
|
FbxMesh *pMesh = pNode->GetMesh();
|
||||||
|
|
||||||
|
// Obtains the surface Id
|
||||||
|
const long surfaceId = pMesh->GetUniqueID();
|
||||||
|
|
||||||
|
// Associate the node to this surface
|
||||||
|
int nodeId = raw.GetNodeByName(pNode->GetName());
|
||||||
|
if (nodeId >= 0) {
|
||||||
|
RawNode &node = raw.GetNode(nodeId);
|
||||||
|
node.surfaceId = surfaceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (raw.GetSurfaceById(surfaceId) >= 0) {
|
||||||
|
// This surface is already loaded
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const char *meshName = (pNode->GetName()[0] != '\0') ? pNode->GetName() : pMesh->GetName();
|
const char *meshName = (pNode->GetName()[0] != '\0') ? pNode->GetName() : pMesh->GetName();
|
||||||
const int rawSurfaceIndex = raw.AddSurface(meshName, pNode->GetName());
|
const int rawSurfaceIndex = raw.AddSurface(meshName, surfaceId);
|
||||||
|
|
||||||
const FbxVector4 *controlPoints = pMesh->GetControlPoints();
|
const FbxVector4 *controlPoints = pMesh->GetControlPoints();
|
||||||
const FbxLayerElementAccess<FbxVector4> normalLayer(pMesh->GetElementNormal(), pMesh->GetElementNormalCount());
|
const FbxLayerElementAccess<FbxVector4> normalLayer(pMesh->GetElementNormal(), pMesh->GetElementNormalCount());
|
||||||
|
@ -771,9 +786,10 @@ static void ReadMesh(RawModel &raw, FbxScene *pScene, FbxNode *pNode, const std:
|
||||||
const std::shared_ptr<FbxMaterialInfo> fbxMaterial = materials.GetMaterial(polygonIndex);
|
const std::shared_ptr<FbxMaterialInfo> fbxMaterial = materials.GetMaterial(polygonIndex);
|
||||||
|
|
||||||
int textures[RAW_TEXTURE_USAGE_MAX];
|
int textures[RAW_TEXTURE_USAGE_MAX];
|
||||||
std::fill_n(textures, RAW_TEXTURE_USAGE_MAX, -1);
|
std::fill_n(textures, (int) RAW_TEXTURE_USAGE_MAX, -1);
|
||||||
FbxString materialName;
|
|
||||||
std::shared_ptr<RawMatProps> rawMatProps;
|
std::shared_ptr<RawMatProps> rawMatProps;
|
||||||
|
FbxString materialName;
|
||||||
|
|
||||||
if (fbxMaterial == nullptr) {
|
if (fbxMaterial == nullptr) {
|
||||||
materialName = "DefaultMaterial";
|
materialName = "DefaultMaterial";
|
||||||
|
|
106
src/Raw2Gltf.cpp
106
src/Raw2Gltf.cpp
|
@ -244,6 +244,15 @@ T &require(std::map<std::string, std::shared_ptr<T>> map, const std::string &key
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T &require(std::map<long, std::shared_ptr<T>> map, long key)
|
||||||
|
{
|
||||||
|
auto iter = map.find(key);
|
||||||
|
assert(iter != map.end());
|
||||||
|
T &result = *iter->second;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static const std::vector<TriangleIndex> getIndexArray(const RawModel &raw)
|
static const std::vector<TriangleIndex> getIndexArray(const RawModel &raw)
|
||||||
{
|
{
|
||||||
std::vector<TriangleIndex> result;
|
std::vector<TriangleIndex> result;
|
||||||
|
@ -297,8 +306,8 @@ ModelData *Raw2Gltf(
|
||||||
|
|
||||||
std::map<std::string, std::shared_ptr<NodeData>> nodesByName;
|
std::map<std::string, std::shared_ptr<NodeData>> nodesByName;
|
||||||
std::map<std::string, std::shared_ptr<MaterialData>> materialsByName;
|
std::map<std::string, std::shared_ptr<MaterialData>> materialsByName;
|
||||||
std::map<std::string, std::shared_ptr<MeshData>> meshByNodeName;
|
|
||||||
std::map<std::string, std::shared_ptr<TextureData>> textureByIndicesKey;
|
std::map<std::string, std::shared_ptr<TextureData>> textureByIndicesKey;
|
||||||
|
std::map<long, std::shared_ptr<MeshData>> meshBySurfaceId;
|
||||||
|
|
||||||
// for now, we only have one buffer; data->binary points to the same vector as that BufferData does.
|
// for now, we only have one buffer; data->binary points to the same vector as that BufferData does.
|
||||||
BufferData &buffer = *gltf->buffers.hold(
|
BufferData &buffer = *gltf->buffers.hold(
|
||||||
|
@ -883,32 +892,20 @@ ModelData *Raw2Gltf(
|
||||||
materialsByName[materialHash(material)] = mData;
|
materialsByName[materialHash(material)] = mData;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// surfaces
|
|
||||||
//
|
|
||||||
|
|
||||||
// in GLTF 2.0, the structural limitation is that a node can
|
|
||||||
// only belong to a single mesh. A mesh can however contain any
|
|
||||||
// number of primitives, which are essentially little meshes.
|
|
||||||
//
|
|
||||||
// so each RawSurface turns into a primitive, and we sort them
|
|
||||||
// by root node using this map; one mesh per node.
|
|
||||||
|
|
||||||
for (size_t surfaceIndex = 0; surfaceIndex < materialModels.size(); surfaceIndex++) {
|
for (size_t surfaceIndex = 0; surfaceIndex < materialModels.size(); surfaceIndex++) {
|
||||||
const RawModel &surfaceModel = materialModels[surfaceIndex];
|
const RawModel &surfaceModel = materialModels[surfaceIndex];
|
||||||
|
|
||||||
assert(surfaceModel.GetSurfaceCount() == 1);
|
assert(surfaceModel.GetSurfaceCount() == 1);
|
||||||
const RawSurface &rawSurface = surfaceModel.GetSurface(0);
|
const RawSurface &rawSurface = surfaceModel.GetSurface(0);
|
||||||
|
const int surfaceId = rawSurface.id;
|
||||||
|
|
||||||
const RawMaterial &rawMaterial = surfaceModel.GetMaterial(surfaceModel.GetTriangle(0).materialIndex);
|
const RawMaterial &rawMaterial = surfaceModel.GetMaterial(surfaceModel.GetTriangle(0).materialIndex);
|
||||||
const MaterialData &mData = require(materialsByName, materialHash(rawMaterial));
|
const MaterialData &mData = require(materialsByName, materialHash(rawMaterial));
|
||||||
|
|
||||||
std::string nodeName = rawSurface.nodeName;
|
|
||||||
NodeData &meshNode = require(nodesByName, nodeName);
|
|
||||||
|
|
||||||
MeshData *mesh = nullptr;
|
MeshData *mesh = nullptr;
|
||||||
auto meshIter = meshByNodeName.find(nodeName);
|
auto meshIter = meshBySurfaceId.find(surfaceId);
|
||||||
if (meshIter != meshByNodeName.end()) {
|
if (meshIter != meshBySurfaceId.end()) {
|
||||||
mesh = meshIter->second.get();
|
mesh = meshIter->second.get();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -917,36 +914,10 @@ ModelData *Raw2Gltf(
|
||||||
defaultDeforms.push_back(channel.defaultDeform);
|
defaultDeforms.push_back(channel.defaultDeform);
|
||||||
}
|
}
|
||||||
auto meshPtr = gltf->meshes.hold(new MeshData(rawSurface.name, defaultDeforms));
|
auto meshPtr = gltf->meshes.hold(new MeshData(rawSurface.name, defaultDeforms));
|
||||||
meshByNodeName[nodeName] = meshPtr;
|
meshBySurfaceId[surfaceId] = meshPtr;
|
||||||
meshNode.SetMesh(meshPtr->ix);
|
|
||||||
mesh = meshPtr.get();
|
mesh = meshPtr.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// surface skin
|
|
||||||
//
|
|
||||||
if (!rawSurface.jointNames.empty()) {
|
|
||||||
if (meshNode.skin == -1) {
|
|
||||||
// glTF uses column-major matrices
|
|
||||||
std::vector<Mat4f> inverseBindMatrices;
|
|
||||||
for (const auto &inverseBindMatrice : rawSurface.inverseBindMatrices) {
|
|
||||||
inverseBindMatrices.push_back(inverseBindMatrice.Transpose());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<uint32_t> jointIndexes;
|
|
||||||
for (const auto &jointName : rawSurface.jointNames) {
|
|
||||||
jointIndexes.push_back(require(nodesByName, jointName).ix);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write out inverseBindMatrices
|
|
||||||
auto accIBM = gltf->AddAccessorAndView(buffer, GLT_MAT4F, inverseBindMatrices);
|
|
||||||
|
|
||||||
auto skeletonRoot = require(nodesByName, rawSurface.skeletonRootName);
|
|
||||||
auto skin = *gltf->skins.hold(new SkinData(jointIndexes, *accIBM, skeletonRoot));
|
|
||||||
meshNode.SetSkin(skin.ix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<PrimitiveData> primitive;
|
std::shared_ptr<PrimitiveData> primitive;
|
||||||
if (options.useDraco) {
|
if (options.useDraco) {
|
||||||
int triangleCount = surfaceModel.GetTriangleCount();
|
int triangleCount = surfaceModel.GetTriangleCount();
|
||||||
|
@ -1087,6 +1058,53 @@ ModelData *Raw2Gltf(
|
||||||
mesh->AddPrimitive(primitive);
|
mesh->AddPrimitive(primitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Assign meshes to node
|
||||||
|
//
|
||||||
|
|
||||||
|
for (int i = 0; i < raw.GetNodeCount(); i++) {
|
||||||
|
|
||||||
|
const RawNode &node = raw.GetNode(i);
|
||||||
|
auto nodeData = gltf->nodes.ptrs[i];
|
||||||
|
|
||||||
|
//
|
||||||
|
// Assign mesh to node
|
||||||
|
//
|
||||||
|
if (node.surfaceId > 0)
|
||||||
|
{
|
||||||
|
int surfaceIndex = raw.GetSurfaceById(node.surfaceId);
|
||||||
|
const RawSurface &rawSurface = raw.GetSurface(surfaceIndex);
|
||||||
|
|
||||||
|
MeshData &meshData = require(meshBySurfaceId, rawSurface.id);
|
||||||
|
nodeData->SetMesh(meshData.ix);
|
||||||
|
|
||||||
|
//
|
||||||
|
// surface skin
|
||||||
|
//
|
||||||
|
if (!rawSurface.jointNames.empty()) {
|
||||||
|
if (nodeData->skin == -1) {
|
||||||
|
// glTF uses column-major matrices
|
||||||
|
std::vector<Mat4f> inverseBindMatrices;
|
||||||
|
for (const auto &inverseBindMatrice : rawSurface.inverseBindMatrices) {
|
||||||
|
inverseBindMatrices.push_back(inverseBindMatrice.Transpose());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint32_t> jointIndexes;
|
||||||
|
for (const auto &jointName : rawSurface.jointNames) {
|
||||||
|
jointIndexes.push_back(require(nodesByName, jointName).ix);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write out inverseBindMatrices
|
||||||
|
auto accIBM = gltf->AddAccessorAndView(buffer, GLT_MAT4F, inverseBindMatrices);
|
||||||
|
|
||||||
|
auto skeletonRoot = require(nodesByName, rawSurface.skeletonRootName);
|
||||||
|
auto skin = *gltf->skins.hold(new SkinData(jointIndexes, *accIBM, skeletonRoot));
|
||||||
|
nodeData->SetSkin(skin.ix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// cameras
|
// cameras
|
||||||
//
|
//
|
||||||
|
|
|
@ -165,18 +165,18 @@ int RawModel::AddSurface(const RawSurface &surface)
|
||||||
return (int) (surfaces.size() - 1);
|
return (int) (surfaces.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int RawModel::AddSurface(const char *name, const char *nodeName)
|
int RawModel::AddSurface(const char *name, const long surfaceId)
|
||||||
{
|
{
|
||||||
assert(name[0] != '\0');
|
assert(name[0] != '\0');
|
||||||
|
|
||||||
for (size_t i = 0; i < surfaces.size(); i++) {
|
for (size_t i = 0; i < surfaces.size(); i++) {
|
||||||
if (Gltf::StringUtils::CompareNoCase(surfaces[i].name, name) == 0) {
|
if (surfaces[i].id == surfaceId) {
|
||||||
return (int) i;
|
return (int) i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RawSurface surface;
|
RawSurface surface;
|
||||||
|
surface.id = surfaceId;
|
||||||
surface.name = name;
|
surface.name = name;
|
||||||
surface.nodeName = nodeName;
|
|
||||||
surface.bounds.Clear();
|
surface.bounds.Clear();
|
||||||
surface.discrete = false;
|
surface.discrete = false;
|
||||||
|
|
||||||
|
@ -248,6 +248,7 @@ int RawModel::AddNode(const char *name, const char *parentName)
|
||||||
joint.isJoint = false;
|
joint.isJoint = false;
|
||||||
joint.name = name;
|
joint.name = name;
|
||||||
joint.parentName = parentName;
|
joint.parentName = parentName;
|
||||||
|
joint.surfaceId = 0;
|
||||||
joint.translation = Vec3f(0, 0, 0);
|
joint.translation = Vec3f(0, 0, 0);
|
||||||
joint.rotation = Quatf(0, 0, 0, 1);
|
joint.rotation = Quatf(0, 0, 0, 1);
|
||||||
joint.scale = Vec3f(1, 1, 1);
|
joint.scale = Vec3f(1, 1, 1);
|
||||||
|
@ -266,7 +267,7 @@ void RawModel::Condense()
|
||||||
|
|
||||||
for (auto &triangle : triangles) {
|
for (auto &triangle : triangles) {
|
||||||
const RawSurface &surface = oldSurfaces[triangle.surfaceIndex];
|
const RawSurface &surface = oldSurfaces[triangle.surfaceIndex];
|
||||||
const int surfaceIndex = AddSurface(surface.name.c_str(), surface.nodeName.c_str());
|
const int surfaceIndex = AddSurface(surface.name.c_str(), surface.id);
|
||||||
surfaces[surfaceIndex] = surface;
|
surfaces[surfaceIndex] = surface;
|
||||||
triangle.surfaceIndex = surfaceIndex;
|
triangle.surfaceIndex = surfaceIndex;
|
||||||
}
|
}
|
||||||
|
@ -523,3 +524,13 @@ int RawModel::GetNodeByName(const char *name) const
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int RawModel::GetSurfaceById(const long surfaceId) const
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < surfaces.size(); i++) {
|
||||||
|
if (surfaces[i].id == surfaceId) {
|
||||||
|
return (int)i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
|
@ -275,8 +275,8 @@ struct RawBlendChannel
|
||||||
|
|
||||||
struct RawSurface
|
struct RawSurface
|
||||||
{
|
{
|
||||||
|
long id;
|
||||||
std::string name; // The name of this surface
|
std::string name; // The name of this surface
|
||||||
std::string nodeName; // The node that links to this surface.
|
|
||||||
std::string skeletonRootName; // The name of the root of the skeleton.
|
std::string skeletonRootName; // The name of the root of the skeleton.
|
||||||
Bounds<float, 3> bounds;
|
Bounds<float, 3> bounds;
|
||||||
std::vector<std::string> jointNames;
|
std::vector<std::string> jointNames;
|
||||||
|
@ -341,6 +341,7 @@ struct RawNode
|
||||||
Vec3f translation;
|
Vec3f translation;
|
||||||
Quatf rotation;
|
Quatf rotation;
|
||||||
Vec3f scale;
|
Vec3f scale;
|
||||||
|
long surfaceId;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RawModel
|
class RawModel
|
||||||
|
@ -358,7 +359,7 @@ public:
|
||||||
const char *name, const RawMaterialType materialType, const int textures[RAW_TEXTURE_USAGE_MAX],
|
const char *name, const RawMaterialType materialType, const int textures[RAW_TEXTURE_USAGE_MAX],
|
||||||
std::shared_ptr<RawMatProps> materialInfo);
|
std::shared_ptr<RawMatProps> materialInfo);
|
||||||
int AddSurface(const RawSurface &suface);
|
int AddSurface(const RawSurface &suface);
|
||||||
int AddSurface(const char *name, const char *nodeName);
|
int AddSurface(const char *name, long surfaceId);
|
||||||
int AddAnimation(const RawAnimation &animation);
|
int AddAnimation(const RawAnimation &animation);
|
||||||
int AddCameraPerspective(
|
int AddCameraPerspective(
|
||||||
const char *name, const char *nodeName, const float aspectRatio, const float fovDegreesX, const float fovDegreesY,
|
const char *name, const char *nodeName, const float aspectRatio, const float fovDegreesX, const float fovDegreesY,
|
||||||
|
@ -398,6 +399,7 @@ public:
|
||||||
int GetSurfaceCount() const { return (int) surfaces.size(); }
|
int GetSurfaceCount() const { return (int) surfaces.size(); }
|
||||||
const RawSurface &GetSurface(const int index) const { return surfaces[index]; }
|
const RawSurface &GetSurface(const int index) const { return surfaces[index]; }
|
||||||
RawSurface &GetSurface(const int index) { return surfaces[index]; }
|
RawSurface &GetSurface(const int index) { return surfaces[index]; }
|
||||||
|
int GetSurfaceById(const long id) const;
|
||||||
|
|
||||||
// Iterate over the animations.
|
// Iterate over the animations.
|
||||||
int GetAnimationCount() const { return (int) animations.size(); }
|
int GetAnimationCount() const { return (int) animations.size(); }
|
||||||
|
|
Loading…
Reference in New Issue