Skip to content

Commit

Permalink
Collada: Don't copy the scene when exporting
Browse files Browse the repository at this point in the history
This was purely to add a virtual top-level node
Use a flag instead.
Also add more const
  • Loading branch information
RichardTea committed May 5, 2020
1 parent 6e447b2 commit 56a4e61
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 59 deletions.
105 changes: 49 additions & 56 deletions code/AssetLib/Collada/ColladaExporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,32 +117,44 @@ static const std::string XMLIDEncode(const std::string &name) {
return idEncoded.str();
}

// ------------------------------------------------------------------------------------------------
// Helper functions to create unique ids
inline bool IsUniqueId(const std::unordered_set<std::string> &idSet, const std::string &idStr) {
return (idSet.find(idStr) == idSet.end());
}

inline std::string MakeUniqueId(const std::unordered_set<std::string> &idSet, const std::string &idPrefix, const std::string &postfix) {
std::string result(idPrefix + postfix);
if (!IsUniqueId(idSet, result)) {
// Select a number to append
size_t idnum = 1;
do {
result = idPrefix + '_' + to_string(idnum) + postfix;
++idnum;
} while (!IsUniqueId(idSet, result));
}
return result;
}

// ------------------------------------------------------------------------------------------------
// Constructor for a specific scene to export
ColladaExporter::ColladaExporter(const aiScene *pScene, IOSystem *pIOSystem, const std::string &path, const std::string &file) :
mIOSystem(pIOSystem),
mPath(path),
mFile(file) {
mFile(file),
mScene(pScene),
endstr("\n") {
// make sure that all formatting happens using the standard, C locale and not the user's current locale
mOutput.imbue(std::locale("C"));
mOutput.precision(ASSIMP_AI_REAL_TEXT_PRECISION);

mScene = pScene;
mSceneOwned = false;

// set up strings
endstr = "\n";

// start writing the file
WriteFile();
}

// ------------------------------------------------------------------------------------------------
// Destructor
ColladaExporter::~ColladaExporter() {
if (mSceneOwned) {
delete mScene;
}
}

// ------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -171,10 +183,11 @@ void ColladaExporter::WriteFile() {
// customized, Writes the animation library
WriteAnimationsLibrary();

// useless Collada fu at the end, just in case we haven't had enough indirections, yet.
// instantiate the scene(s)
// For Assimp there will only ever be one
mOutput << startstr << "<scene>" << endstr;
PushTag();
mOutput << startstr << "<instance_visual_scene url=\"#" + GetNodeUniqueId(mScene->mRootNode) + "\" />" << endstr;
mOutput << startstr << "<instance_visual_scene url=\"#" + mSceneId + "\" />" << endstr;
PopTag();
mOutput << startstr << "</scene>" << endstr;
PopTag();
Expand Down Expand Up @@ -209,13 +222,13 @@ void ColladaExporter::WriteHeader() {
mScene->mRootNode->mTransformation.Decompose(scaling, rotation, position);
rotation.Normalize();

bool add_root_node = false;
mAdd_root_node = false;

ai_real scale = 1.0;
if (std::abs(scaling.x - scaling.y) <= epsilon && std::abs(scaling.x - scaling.z) <= epsilon && std::abs(scaling.y - scaling.z) <= epsilon) {
scale = (ai_real)((((double)scaling.x) + ((double)scaling.y) + ((double)scaling.z)) / 3.0);
} else {
add_root_node = true;
mAdd_root_node = true;
}

std::string up_axis = "Y_UP";
Expand All @@ -226,34 +239,19 @@ void ColladaExporter::WriteHeader() {
} else if (rotation.Equal(z_rot, epsilon)) {
up_axis = "Z_UP";
} else {
add_root_node = true;
mAdd_root_node = true;
}

if (!position.Equal(aiVector3D(0, 0, 0))) {
add_root_node = true;
mAdd_root_node = true;
}

// Assimp root nodes can have meshes, Collada Scenes cannot
if (mScene->mRootNode->mNumChildren == 0 || mScene->mRootNode->mMeshes != 0) {
add_root_node = true;
mAdd_root_node = true;
}

if (add_root_node) {
aiScene *scene = nullptr;
SceneCombiner::CopyScene(&scene, mScene);

aiNode *root = new aiNode("Scene");

root->mNumChildren = 1;
root->mChildren = new aiNode *[root->mNumChildren];

root->mChildren[0] = scene->mRootNode;
scene->mRootNode->mParent = root;
scene->mRootNode = root;

mScene = scene;
mSceneOwned = true;

if (mAdd_root_node) {
up_axis = "Y_UP";
scale = 1.0;
}
Expand Down Expand Up @@ -1227,17 +1225,29 @@ void ColladaExporter::WriteFloatArray(const std::string &pIdString, FloatDataTyp
// ------------------------------------------------------------------------------------------------
// Writes the scene library
void ColladaExporter::WriteSceneLibrary() {
const std::string sceneId = GetNodeUniqueId(mScene->mRootNode);
const std::string sceneName = GetNodeName(mScene->mRootNode);
// Determine if we are using the aiScene root or our own
std::string sceneName("Scene");
if (mAdd_root_node) {
mSceneId = MakeUniqueId(mUniqueIds, sceneName, std::string());
mUniqueIds.insert(mSceneId);
} else {
mSceneId = GetNodeUniqueId(mScene->mRootNode);
sceneName = GetNodeName(mScene->mRootNode);
}

mOutput << startstr << "<library_visual_scenes>" << endstr;
PushTag();
mOutput << startstr << "<visual_scene id=\"" + sceneId + "\" name=\"" + sceneName + "\">" << endstr;
mOutput << startstr << "<visual_scene id=\"" + mSceneId + "\" name=\"" + sceneName + "\">" << endstr;
PushTag();

// start recursive write at the root node
for (size_t a = 0; a < mScene->mRootNode->mNumChildren; ++a)
WriteNode(mScene->mRootNode->mChildren[a]);
if (mAdd_root_node) {
// Export the root node
WriteNode(mScene->mRootNode);
} else {
// Have already exported the root node
for (size_t a = 0; a < mScene->mRootNode->mNumChildren; ++a)
WriteNode(mScene->mRootNode->mChildren[a]);
}

PopTag();
mOutput << startstr << "</visual_scene>" << endstr;
Expand Down Expand Up @@ -1610,23 +1620,6 @@ void ColladaExporter::WriteNode(const aiNode *pNode) {
mOutput << startstr << "</node>" << endstr;
}

inline bool IsUniqueId(const std::unordered_set<std::string> &idSet, const std::string &idStr) {
return (idSet.find(idStr) == idSet.end());
}

inline std::string MakeUniqueId(const std::unordered_set<std::string> &idSet, const std::string &idPrefix, const std::string &postfix) {
std::string result(idPrefix + postfix);
if (!IsUniqueId(idSet, result)) {
// Select a number to append
size_t idnum = 1;
do {
result = idPrefix + '_' + to_string(idnum) + postfix;
++idnum;
} while (!IsUniqueId(idSet, result));
}
return result;
}

void ColladaExporter::CreateNodeIds(const aiNode *node) {
GetNodeUniqueId(node);
for (size_t a = 0; a < node->mNumChildren; ++a)
Expand Down
7 changes: 4 additions & 3 deletions code/AssetLib/Collada/ColladaExporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,13 +196,14 @@ class ColladaExporter {
const std::string mFile;

/// The scene to be written
const aiScene *mScene;
bool mSceneOwned;
const aiScene *const mScene;
std::string mSceneId;
bool mAdd_root_node = false;

/// current line start string, contains the current indentation for simple stream insertion
std::string startstr;
/// current line end string for simple stream insertion
std::string endstr;
const std::string endstr;

// pair of color and texture - texture precedences color
struct Surface {
Expand Down

0 comments on commit 56a4e61

Please sign in to comment.