mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
add stubbed FBXBaker leveraging FBX SDK for read/write
This commit is contained in:
parent
b04d507090
commit
26d4cc73e0
4 changed files with 202 additions and 1 deletions
7
libraries/model-baking/CMakeLists.txt
Normal file
7
libraries/model-baking/CMakeLists.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
set(TARGET_NAME model-baking)
|
||||
|
||||
setup_hifi_library()
|
||||
|
||||
find_package(FBXSDK REQUIRED)
|
||||
target_link_libraries(${TARGET_NAME} ${FBX_LIBRARIES})
|
||||
target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${FBX_INCLUDE_DIR})
|
156
libraries/model-baking/src/FBXBaker.cpp
Normal file
156
libraries/model-baking/src/FBXBaker.cpp
Normal file
|
@ -0,0 +1,156 @@
|
|||
//
|
||||
// FBXBaker.cpp
|
||||
// libraries/model-baking/src
|
||||
//
|
||||
// Created by Stephen Birarda on 3/30/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <fbxsdk.h>
|
||||
#include <fbxsdk/scene/shading/fbxlayeredtexture.h>
|
||||
|
||||
#include <QtCore/QFileInfo>
|
||||
|
||||
#include "FBXBaker.h"
|
||||
|
||||
Q_LOGGING_CATEGORY(model_baking, "hifi.model-baking");
|
||||
|
||||
FBXBaker::FBXBaker(std::string fbxPath) :
|
||||
_fbxPath(fbxPath)
|
||||
{
|
||||
// create an FBX SDK manager
|
||||
_sdkManager = FbxManager::Create();
|
||||
}
|
||||
|
||||
bool FBXBaker::bakeFBX() {
|
||||
|
||||
// load the scene from the FBX file
|
||||
if (importScene()) {
|
||||
// enumerate the textures found in the scene and bake them
|
||||
rewriteAndCollectSceneTextures();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FBXBaker::importScene() {
|
||||
// create an FBX SDK importer
|
||||
FbxImporter* importer = FbxImporter::Create(_sdkManager, "");
|
||||
|
||||
// import the FBX file at the given path
|
||||
bool importStatus = importer->Initialize(_fbxPath.c_str());
|
||||
|
||||
if (!importStatus) {
|
||||
// failed to import the FBX file, print an error and return
|
||||
qCDebug(model_baking) << "Failed to import FBX file at" << _fbxPath.c_str() << "- error:" << importer->GetStatus().GetErrorString();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// setup a new scene to hold the imported file
|
||||
_scene = FbxScene::Create(_sdkManager, "bakeScene");
|
||||
|
||||
// import the file to the created scene
|
||||
importer->Import(_scene);
|
||||
|
||||
// destroy the importer that is no longer needed
|
||||
importer->Destroy();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FBXBaker::rewriteAndCollectSceneTextures() {
|
||||
// grab the root node from the scene
|
||||
FbxNode* rootNode = _scene->GetRootNode();
|
||||
|
||||
if (rootNode) {
|
||||
// enumerate the children of the root node
|
||||
for (int i = 0; i < rootNode->GetChildCount(); ++i) {
|
||||
FbxNode* node = rootNode->GetChild(i);
|
||||
|
||||
// check if this child is a mesh node
|
||||
if (node->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::eMesh) {
|
||||
FbxMesh* mesh = (FbxMesh*) node->GetNodeAttribute();
|
||||
|
||||
// make sure this mesh is valid
|
||||
if (mesh->GetNode() != nullptr) {
|
||||
// figure out the number of materials in this mesh
|
||||
int numMaterials = mesh->GetNode()->GetSrcObjectCount<FbxSurfaceMaterial>();
|
||||
|
||||
// enumerate the materials in this mesh
|
||||
for (int materialIndex = 0; materialIndex < numMaterials; materialIndex++) {
|
||||
// grab this material
|
||||
FbxSurfaceMaterial* material = mesh->GetNode()->GetSrcObject<FbxSurfaceMaterial>(materialIndex);
|
||||
|
||||
if (material) {
|
||||
// enumerate the textures in this valid material
|
||||
int textureIndex;
|
||||
FBXSDK_FOR_EACH_TEXTURE(textureIndex) {
|
||||
// collect this texture so we know later to bake it
|
||||
FbxProperty property = material->FindProperty(FbxLayerElement::sTextureChannelNames[textureIndex]);
|
||||
if (property.IsValid()) {
|
||||
rewriteAndCollectChannelTextures(property);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FBXBaker::rewriteAndCollectChannelTextures(FbxProperty& property) {
|
||||
if (property.IsValid()) {
|
||||
int textureCount = property.GetSrcObjectCount<FbxTexture>();
|
||||
|
||||
// enumerate the textures for this channel
|
||||
for (int i = 0; i < textureCount; ++i) {
|
||||
// check if this texture is layered
|
||||
FbxLayeredTexture* layeredTexture = property.GetSrcObject<FbxLayeredTexture>(i);
|
||||
if (layeredTexture) {
|
||||
// enumerate the layers of the layered texture
|
||||
int numberOfLayers = layeredTexture->GetSrcObjectCount<FbxTexture>();
|
||||
|
||||
for (int j = 0; j < numberOfLayers; ++j) {
|
||||
FbxTexture* texture = layeredTexture->GetSrcObject<FbxTexture>(j);
|
||||
rewriteAndCollectTexture(texture);
|
||||
}
|
||||
} else {
|
||||
FbxTexture* texture = property.GetSrcObject<FbxTexture>(i);
|
||||
rewriteAndCollectTexture(texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const QString BAKED_TEXTURE_DIRECTORY = "textures";
|
||||
|
||||
bool FBXBaker::rewriteAndCollectTexture(fbxsdk::FbxTexture* texture) {
|
||||
FbxFileTexture* fileTexture = FbxCast<FbxFileTexture>(texture);
|
||||
if (fileTexture) {
|
||||
qCDebug(model_baking) << "Flagging" << fileTexture->GetRelativeFileName() << "for bake and re-mapping to .xtk in FBX";
|
||||
|
||||
// use QFileInfo to easily split up the existing texture filename into its components
|
||||
QFileInfo textureFileInfo { fileTexture->GetRelativeFileName() };
|
||||
|
||||
// construct the new baked texture file name
|
||||
QString bakedTextureFileName { BAKED_TEXTURE_DIRECTORY + "/" + textureFileInfo.baseName() + ".xtk" };
|
||||
|
||||
// write the new filename into the FBX scene
|
||||
fileTexture->SetRelativeFileName(bakedTextureFileName.toLocal8Bit());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
38
libraries/model-baking/src/FBXBaker.h
Normal file
38
libraries/model-baking/src/FBXBaker.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// FBXBaker.h
|
||||
// libraries/model-baking/src
|
||||
//
|
||||
// Created by Stephen Birarda on 3/30/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_FBXBaker_h
|
||||
#define hifi_FBXBaker_h
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(model_baking)
|
||||
|
||||
class FBXBaker {
|
||||
|
||||
public:
|
||||
FBXBaker(std::string fbxPath);
|
||||
bool bakeFBX();
|
||||
|
||||
private:
|
||||
bool importScene();
|
||||
bool rewriteAndCollectSceneTextures();
|
||||
bool rewriteAndCollectChannelTextures(FbxProperty& property);
|
||||
bool rewriteAndCollectTexture(FbxTexture* texture);
|
||||
|
||||
std::string _fbxPath;
|
||||
FbxManager* _sdkManager;
|
||||
FbxScene* _scene { nullptr };
|
||||
};
|
||||
|
||||
#endif // hifi_FBXBaker_h
|
|
@ -2,4 +2,4 @@ set(TARGET_NAME oven)
|
|||
|
||||
setup_hifi_project()
|
||||
|
||||
find_package(FBXSDK REQUIRED)
|
||||
link_hifi_libraries(model-baking)
|
||||
|
|
Loading…
Reference in a new issue