Collada Root Nodes aren't allowed to have meshes
Create a null parent node insteadpull/3205/head
parent
6e200cb0d3
commit
8e73984a11
|
@ -233,12 +233,13 @@ void ColladaExporter::WriteHeader() {
|
||||||
add_root_node = true;
|
add_root_node = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mScene->mRootNode->mNumChildren == 0) {
|
// Assimp root nodes can have meshes, Collada Scenes cannot
|
||||||
|
if (mScene->mRootNode->mNumChildren == 0 || mScene->mRootNode->mMeshes != 0) {
|
||||||
add_root_node = true;
|
add_root_node = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (add_root_node) {
|
if (add_root_node) {
|
||||||
aiScene *scene;
|
aiScene *scene = nullptr;
|
||||||
SceneCombiner::CopyScene(&scene, mScene);
|
SceneCombiner::CopyScene(&scene, mScene);
|
||||||
|
|
||||||
aiNode *root = new aiNode("Scene");
|
aiNode *root = new aiNode("Scene");
|
||||||
|
@ -1493,12 +1494,9 @@ void ColladaExporter::WriteNode(const aiNode *pNode) {
|
||||||
const std::string node_name = GetNodeName(pNode);
|
const std::string node_name = GetNodeName(pNode);
|
||||||
mOutput << startstr << "<node ";
|
mOutput << startstr << "<node ";
|
||||||
if (is_skeleton_root) {
|
if (is_skeleton_root) {
|
||||||
mOutput << "id=\"" << node_id << "\" " << (is_joint ? "sid=\"" + node_id + "\" " : ""); // For now, only support one skeleton in a scene.
|
mFoundSkeletonRootNodeID = node_id; // For now, only support one skeleton in a scene.
|
||||||
mFoundSkeletonRootNodeID = node_id;
|
|
||||||
} else {
|
|
||||||
mOutput << "id=\"" << node_id << "\" " << (is_joint ? "sid=\"" + node_id + "\" " : "");
|
|
||||||
}
|
}
|
||||||
|
mOutput << "id=\"" << node_id << "\" " << (is_joint ? "sid=\"" + node_id + "\" " : "");
|
||||||
mOutput << "name=\"" << node_name
|
mOutput << "name=\"" << node_name
|
||||||
<< "\" type=\"" << node_type
|
<< "\" type=\"" << node_type
|
||||||
<< "\">" << endstr;
|
<< "\">" << endstr;
|
||||||
|
|
|
@ -2479,7 +2479,7 @@ void ColladaParser::ReadSceneLibrary() {
|
||||||
|
|
||||||
// read name if given.
|
// read name if given.
|
||||||
int indexName = TestAttribute("name");
|
int indexName = TestAttribute("name");
|
||||||
const char *attrName = "unnamed";
|
const char *attrName = "Scene";
|
||||||
if (indexName > -1)
|
if (indexName > -1)
|
||||||
attrName = mReader->getAttributeValue(indexName);
|
attrName = mReader->getAttributeValue(indexName);
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "UnitTestPCH.h"
|
#include "UnitTestPCH.h"
|
||||||
|
|
||||||
#include <assimp/ColladaMetaData.h>
|
#include <assimp/ColladaMetaData.h>
|
||||||
|
#include <assimp/SceneCombiner.h>
|
||||||
#include <assimp/commonMetaData.h>
|
#include <assimp/commonMetaData.h>
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
|
@ -211,6 +212,60 @@ TEST_F(utColladaImportExport, importDaeFromFileTest) {
|
||||||
EXPECT_TRUE(importerTest());
|
EXPECT_TRUE(importerTest());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int GetMeshUseCount(const aiNode *rootNode) {
|
||||||
|
unsigned int result = rootNode->mNumMeshes;
|
||||||
|
for (unsigned int i = 0; i < rootNode->mNumChildren; ++i) {
|
||||||
|
result += GetMeshUseCount(rootNode->mChildren[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(utColladaImportExport, exportRootNodeMeshTest) {
|
||||||
|
Assimp::Importer importer;
|
||||||
|
Assimp::Exporter exporter;
|
||||||
|
const char *outFile = "exportRootNodeMeshTest_out.dae";
|
||||||
|
|
||||||
|
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/Collada/duck.dae", aiProcess_ValidateDataStructure);
|
||||||
|
ASSERT_TRUE(scene != nullptr) << "Fatal: could not import duck.dae!";
|
||||||
|
|
||||||
|
ASSERT_EQ(0u, scene->mRootNode->mNumMeshes) << "Collada import should not give the root node a mesh";
|
||||||
|
|
||||||
|
{
|
||||||
|
// Clone the scene and give the root node a mesh and a transform
|
||||||
|
aiScene *rootMeshScene = nullptr;
|
||||||
|
SceneCombiner::CopyScene(&rootMeshScene, scene);
|
||||||
|
ASSERT_TRUE(rootMeshScene != nullptr) << "Fatal: could not copy scene!";
|
||||||
|
// Do this by moving the meshes from the first child that has some
|
||||||
|
aiNode *rootNode = rootMeshScene->mRootNode;
|
||||||
|
ASSERT_TRUE(rootNode->mNumChildren > 0) << "Fatal: root has no children";
|
||||||
|
aiNode *meshNode = rootNode->mChildren[0];
|
||||||
|
ASSERT_EQ(1u, meshNode->mNumMeshes) << "Fatal: First child node has no duck mesh";
|
||||||
|
|
||||||
|
// Move the meshes to the parent
|
||||||
|
rootNode->mNumMeshes = meshNode->mNumMeshes;
|
||||||
|
rootNode->mMeshes = new unsigned int[rootNode->mNumMeshes];
|
||||||
|
for (unsigned int i = 0; i < rootNode->mNumMeshes; ++i) {
|
||||||
|
rootNode->mMeshes[i] = meshNode->mMeshes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
meshNode->mNumMeshes = 0;
|
||||||
|
delete[] meshNode->mMeshes;
|
||||||
|
|
||||||
|
ASSERT_EQ(AI_SUCCESS, exporter.Export(rootMeshScene, "collada", outFile)) << "Fatal: Could not export file";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reimport and look for meshes
|
||||||
|
scene = importer.ReadFile(outFile, aiProcess_ValidateDataStructure);
|
||||||
|
ASSERT_TRUE(scene != nullptr) << "Fatal: could not reimport!";
|
||||||
|
|
||||||
|
// A Collada root node is not allowed to have a mesh
|
||||||
|
ASSERT_EQ(0u, scene->mRootNode->mNumMeshes) << "Collada reimport should not give the root node a mesh";
|
||||||
|
|
||||||
|
// Walk nodes and counts used meshes
|
||||||
|
// Should be exactly one
|
||||||
|
EXPECT_EQ(1u, GetMeshUseCount(scene->mRootNode)) << "Nodes had unexpected number of meshes in use";
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(utColladaImportExport, exporterUniqueIdsTest) {
|
TEST_F(utColladaImportExport, exporterUniqueIdsTest) {
|
||||||
Assimp::Importer importer;
|
Assimp::Importer importer;
|
||||||
Assimp::Exporter exporter;
|
Assimp::Exporter exporter;
|
||||||
|
|
Loading…
Reference in New Issue