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);
|
||||
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 int rawSurfaceIndex = raw.AddSurface(meshName, pNode->GetName());
|
||||
const int rawSurfaceIndex = raw.AddSurface(meshName, surfaceId);
|
||||
|
||||
const FbxVector4 *controlPoints = pMesh->GetControlPoints();
|
||||
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);
|
||||
|
||||
int textures[RAW_TEXTURE_USAGE_MAX];
|
||||
std::fill_n(textures, RAW_TEXTURE_USAGE_MAX, -1);
|
||||
FbxString materialName;
|
||||
std::fill_n(textures, (int) RAW_TEXTURE_USAGE_MAX, -1);
|
||||
|
||||
std::shared_ptr<RawMatProps> rawMatProps;
|
||||
FbxString materialName;
|
||||
|
||||
if (fbxMaterial == nullptr) {
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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<MaterialData>> materialsByName;
|
||||
std::map<std::string, std::shared_ptr<MeshData>> meshByNodeName;
|
||||
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.
|
||||
BufferData &buffer = *gltf->buffers.hold(
|
||||
|
@ -883,32 +892,20 @@ ModelData *Raw2Gltf(
|
|||
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++) {
|
||||
const RawModel &surfaceModel = materialModels[surfaceIndex];
|
||||
|
||||
assert(surfaceModel.GetSurfaceCount() == 1);
|
||||
const RawSurface &rawSurface = surfaceModel.GetSurface(0);
|
||||
const int surfaceId = rawSurface.id;
|
||||
|
||||
const RawMaterial &rawMaterial = surfaceModel.GetMaterial(surfaceModel.GetTriangle(0).materialIndex);
|
||||
const MaterialData &mData = require(materialsByName, materialHash(rawMaterial));
|
||||
|
||||
std::string nodeName = rawSurface.nodeName;
|
||||
NodeData &meshNode = require(nodesByName, nodeName);
|
||||
|
||||
MeshData *mesh = nullptr;
|
||||
auto meshIter = meshByNodeName.find(nodeName);
|
||||
if (meshIter != meshByNodeName.end()) {
|
||||
MeshData *mesh = nullptr;
|
||||
auto meshIter = meshBySurfaceId.find(surfaceId);
|
||||
if (meshIter != meshBySurfaceId.end()) {
|
||||
mesh = meshIter->second.get();
|
||||
|
||||
} else {
|
||||
|
@ -917,36 +914,10 @@ ModelData *Raw2Gltf(
|
|||
defaultDeforms.push_back(channel.defaultDeform);
|
||||
}
|
||||
auto meshPtr = gltf->meshes.hold(new MeshData(rawSurface.name, defaultDeforms));
|
||||
meshByNodeName[nodeName] = meshPtr;
|
||||
meshNode.SetMesh(meshPtr->ix);
|
||||
meshBySurfaceId[surfaceId] = meshPtr;
|
||||
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;
|
||||
if (options.useDraco) {
|
||||
int triangleCount = surfaceModel.GetTriangleCount();
|
||||
|
@ -1087,6 +1058,53 @@ ModelData *Raw2Gltf(
|
|||
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
|
||||
//
|
||||
|
|
|
@ -165,18 +165,18 @@ int RawModel::AddSurface(const RawSurface &surface)
|
|||
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');
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
RawSurface surface;
|
||||
surface.id = surfaceId;
|
||||
surface.name = name;
|
||||
surface.nodeName = nodeName;
|
||||
surface.bounds.Clear();
|
||||
surface.discrete = false;
|
||||
|
||||
|
@ -248,6 +248,7 @@ int RawModel::AddNode(const char *name, const char *parentName)
|
|||
joint.isJoint = false;
|
||||
joint.name = name;
|
||||
joint.parentName = parentName;
|
||||
joint.surfaceId = 0;
|
||||
joint.translation = Vec3f(0, 0, 0);
|
||||
joint.rotation = Quatf(0, 0, 0, 1);
|
||||
joint.scale = Vec3f(1, 1, 1);
|
||||
|
@ -266,7 +267,7 @@ void RawModel::Condense()
|
|||
|
||||
for (auto &triangle : triangles) {
|
||||
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;
|
||||
triangle.surfaceIndex = surfaceIndex;
|
||||
}
|
||||
|
@ -523,3 +524,13 @@ int RawModel::GetNodeByName(const char *name) const
|
|||
}
|
||||
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
|
||||
{
|
||||
long id;
|
||||
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.
|
||||
Bounds<float, 3> bounds;
|
||||
std::vector<std::string> jointNames;
|
||||
|
@ -341,6 +341,7 @@ struct RawNode
|
|||
Vec3f translation;
|
||||
Quatf rotation;
|
||||
Vec3f scale;
|
||||
long surfaceId;
|
||||
};
|
||||
|
||||
class RawModel
|
||||
|
@ -358,7 +359,7 @@ public:
|
|||
const char *name, const RawMaterialType materialType, const int textures[RAW_TEXTURE_USAGE_MAX],
|
||||
std::shared_ptr<RawMatProps> materialInfo);
|
||||
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 AddCameraPerspective(
|
||||
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(); }
|
||||
const RawSurface &GetSurface(const int index) const { return surfaces[index]; }
|
||||
RawSurface &GetSurface(const int index) { return surfaces[index]; }
|
||||
int GetSurfaceById(const long id) const;
|
||||
|
||||
// Iterate over the animations.
|
||||
int GetAnimationCount() const { return (int) animations.size(); }
|
||||
|
|
Loading…
Reference in New Issue