Merge pull request #4977 from turol/lwo-fixes

LWO fixes
pull/4989/head
Kim Kulling 2023-02-27 16:10:27 +01:00 committed by GitHub
commit 90333340d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 380 additions and 44 deletions

View File

@ -178,7 +178,7 @@ void LWOImporter::InternReadFile(const std::string &pFile,
mLayers->push_back(Layer());
mCurLayer = &mLayers->back();
mCurLayer->mName = "<LWODefault>";
mCurLayer->mIndex = (uint16_t) -1;
mCurLayer->mIndex = 1;
// old lightwave file format (prior to v6)
mIsLWO2 = false;
@ -398,14 +398,6 @@ void LWOImporter::InternReadFile(const std::string &pFile,
pvVC[w]++;
}
#if 0
// process vertex weights. We can't properly reconstruct the whole skeleton for now,
// but we can create dummy bones for all weight channels which we have.
for (unsigned int w = 0; w < layer.mWeightChannels.size();++w)
{
}
#endif
face.mIndices[q] = vert;
}
pf->mIndices = face.mIndices;
@ -429,7 +421,7 @@ void LWOImporter::InternReadFile(const std::string &pFile,
// Generate nodes to render the mesh. Store the source layer in the mParent member of the nodes
unsigned int num = static_cast<unsigned int>(apcMeshes.size() - meshStart);
if (layer.mName != "<LWODefault>" || num > 0) {
aiNode *pcNode = new aiNode();
std::unique_ptr<aiNode> pcNode(new aiNode());
pcNode->mName.Set(layer.mName);
pcNode->mParent = (aiNode *)&layer;
pcNode->mNumMeshes = num;
@ -439,7 +431,8 @@ void LWOImporter::InternReadFile(const std::string &pFile,
for (unsigned int p = 0; p < pcNode->mNumMeshes; ++p)
pcNode->mMeshes[p] = p + meshStart;
}
apcNodes[layer.mIndex] = pcNode;
ASSIMP_LOG_DEBUG("insert apcNode for layer ", layer.mIndex, " \"", layer.mName, "\"");
apcNodes[layer.mIndex] = pcNode.release();
}
}
@ -572,40 +565,64 @@ void LWOImporter::GenerateNodeGraph(std::map<uint16_t, aiNode *> &apcNodes) {
aiNode *root = mScene->mRootNode = new aiNode();
root->mName.Set("<LWORoot>");
//Set parent of all children, inserting pivots
std::map<uint16_t, aiNode *> mapPivot;
for (auto itapcNodes = apcNodes.begin(); itapcNodes != apcNodes.end(); ++itapcNodes) {
//Get the parent index
LWO::Layer *nodeLayer = (LWO::Layer *)(itapcNodes->second->mParent);
uint16_t parentIndex = nodeLayer->mParent;
//Create pivot node, store it into the pivot map, and set the parent as the pivot
aiNode *pivotNode = new aiNode();
pivotNode->mName.Set("Pivot-" + std::string(itapcNodes->second->mName.data));
itapcNodes->second->mParent = pivotNode;
//Look for the parent node to attach the pivot to
if (apcNodes.find(parentIndex) != apcNodes.end()) {
pivotNode->mParent = apcNodes[parentIndex];
} else {
//If not, attach to the root node
pivotNode->mParent = root;
}
//Set the node and the pivot node transformation
itapcNodes->second->mTransformation.a4 = -nodeLayer->mPivot.x;
itapcNodes->second->mTransformation.b4 = -nodeLayer->mPivot.y;
itapcNodes->second->mTransformation.c4 = -nodeLayer->mPivot.z;
pivotNode->mTransformation.a4 = nodeLayer->mPivot.x;
pivotNode->mTransformation.b4 = nodeLayer->mPivot.y;
pivotNode->mTransformation.c4 = nodeLayer->mPivot.z;
mapPivot[-(itapcNodes->first + 2)] = pivotNode;
ASSIMP_LOG_DEBUG("apcNodes initial size: ", apcNodes.size());
if (!apcNodes.empty()) {
ASSIMP_LOG_DEBUG("first apcNode is: ", apcNodes.begin()->first, " \"", apcNodes.begin()->second->mName.C_Str(), "\"");
}
//Merge pivot map into node map
for (auto itMapPivot = mapPivot.begin(); itMapPivot != mapPivot.end(); ++itMapPivot) {
apcNodes[itMapPivot->first] = itMapPivot->second;
//Set parent of all children, inserting pivots
{
std::map<uint16_t, aiNode *> mapPivot;
for (auto itapcNodes = apcNodes.begin(); itapcNodes != apcNodes.end(); ++itapcNodes) {
//Get the parent index
LWO::Layer *nodeLayer = (LWO::Layer *)(itapcNodes->second->mParent);
uint16_t parentIndex = nodeLayer->mParent;
//Create pivot node, store it into the pivot map, and set the parent as the pivot
std::unique_ptr<aiNode> pivotNode(new aiNode());
pivotNode->mName.Set("Pivot-" + std::string(itapcNodes->second->mName.data));
itapcNodes->second->mParent = pivotNode.get();
//Look for the parent node to attach the pivot to
if (apcNodes.find(parentIndex) != apcNodes.end()) {
pivotNode->mParent = apcNodes[parentIndex];
} else {
//If not, attach to the root node
pivotNode->mParent = root;
}
//Set the node and the pivot node transformation
itapcNodes->second->mTransformation.a4 = -nodeLayer->mPivot.x;
itapcNodes->second->mTransformation.b4 = -nodeLayer->mPivot.y;
itapcNodes->second->mTransformation.c4 = -nodeLayer->mPivot.z;
pivotNode->mTransformation.a4 = nodeLayer->mPivot.x;
pivotNode->mTransformation.b4 = nodeLayer->mPivot.y;
pivotNode->mTransformation.c4 = nodeLayer->mPivot.z;
uint16_t pivotNodeId = static_cast<uint16_t>(-(itapcNodes->first + 2));
ASSIMP_LOG_DEBUG("insert pivot node: ", pivotNodeId);
auto oldNodeIt = mapPivot.find(pivotNodeId);
if (oldNodeIt != mapPivot.end()) {
ASSIMP_LOG_ERROR("attempted to insert pivot node which already exists in pivot map ", pivotNodeId, " \"", pivotNode->mName.C_Str(), "\"");
} else {
mapPivot.emplace(pivotNodeId, pivotNode.release());
}
}
ASSIMP_LOG_DEBUG("pivot nodes: ", mapPivot.size());
//Merge pivot map into node map
for (auto itMapPivot = mapPivot.begin(); itMapPivot != mapPivot.end();) {
uint16_t pivotNodeId = itMapPivot->first;
auto oldApcNodeIt = apcNodes.find(pivotNodeId);
if (oldApcNodeIt != apcNodes.end()) {
ASSIMP_LOG_ERROR("attempted to insert pivot node which already exists in apc nodes ", pivotNodeId, " \"", itMapPivot->second->mName.C_Str(), "\"");
} else {
apcNodes.emplace(pivotNodeId, itMapPivot->second);
}
itMapPivot->second = nullptr;
itMapPivot = mapPivot.erase(itMapPivot);
}
ASSIMP_LOG_DEBUG("total nodes: ", apcNodes.size());
}
//Set children of all parents
@ -627,8 +644,15 @@ void LWOImporter::GenerateNodeGraph(std::map<uint16_t, aiNode *> &apcNodes) {
}
}
if (!mScene->mRootNode->mNumChildren)
if (!mScene->mRootNode->mNumChildren) {
ASSIMP_LOG_DEBUG("All apcNodes:");
for (auto nodeIt = apcNodes.begin(); nodeIt != apcNodes.end(); ) {
ASSIMP_LOG_DEBUG("Node ", nodeIt->first, " \"", nodeIt->second->mName.C_Str(), "\"");
nodeIt->second = nullptr;
nodeIt = apcNodes.erase(nodeIt);
}
throw DeadlyImportError("LWO: Unable to build a valid node graph");
}
// Remove a single root node with no meshes assigned to it ...
if (1 == mScene->mRootNode->mNumChildren) {

View File

@ -75,3 +75,315 @@ TEST_F(utLWOImportExport, importLWOformatdetection) {
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOempty) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/invalid/empty.lwo", aiProcess_ValidateDataStructure);
EXPECT_EQ(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWObox_2uv_1unused) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/box_2uv_1unused.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWObox_2vc_1unused) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/box_2vc_1unused.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOconcave_polygon) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/concave_polygon.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOconcave_self_intersecting) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/concave_self_intersecting.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOhierarchy) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/hierarchy.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOhierarchy_smoothed) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/hierarchy_smoothed.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOearth_cylindrical_x) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/MappingModes/earth_cylindrical_x.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOearth_cylindrical_x_scale_222_wrap_21) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/MappingModes/earth_cylindrical_x_scale_222_wrap_21.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOearth_cylindrical_y) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/MappingModes/earth_cylindrical_y.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOearth_cylindrical_y_scale_111) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/MappingModes/earth_cylindrical_y_scale_111.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOearth_cylindrical_y_scale_111_wrap_21) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/MappingModes/earth_cylindrical_y_scale_111_wrap_21.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOearth_cylindrical_z) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/MappingModes/earth_cylindrical_z.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOearth_planar_x) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/MappingModes/earth_planar_x.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOearth_planar_y) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/MappingModes/earth_planar_y.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOearth_planar_z) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/MappingModes/earth_planar_z.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOearth_planar_z_scale_111) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/MappingModes/earth_planar_z_scale_111.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOearth_spherical_x) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/MappingModes/earth_spherical_x.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOearth_spherical_x_scale_222_wrap_22) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/MappingModes/earth_spherical_x_scale_222_wrap_22.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOearth_spherical_y) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/MappingModes/earth_spherical_y.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOearth_spherical_) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/MappingModes/earth_spherical_z.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOearth_spherical_z_wrap_22) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/MappingModes/earth_spherical_z_wrap_22.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOearth_uv_cylindrical_y) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/MappingModes/earth_uv_cylindrical_y.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOModoExport_vertNormals) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/ModoExport_vertNormals.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOnonplanar_polygon) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/nonplanar_polygon.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOCellShader) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/shader_test/CellShader.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOfastFresne) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/shader_test/fastFresnel.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOrealFresnel) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/shader_test/realFresnel.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOSuperCellShader) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/shader_test/SuperCellShader.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOsphere_with_gradient) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/sphere_with_gradient.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOsphere_with_mat_gloss_10pc) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/sphere_with_mat_gloss_10pc.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOSubdivision) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/Subdivision.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOtransparency) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/transparency.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOUglyVertexColors) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/UglyVertexColors.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOuvtest) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWO2/uvtest.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOBConcavePolygon) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWOB/ConcavePolygon.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOBbluewithcylindrictex) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWOB/MappingModes/bluewithcylindrictexz.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOBsphere_with_mat_gloss_10pc) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWOB/sphere_with_mat_gloss_10pc.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}
TEST_F(utLWOImportExport, importLWOBsphere_with_mat_gloss_50pc) {
::Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWO/LWOB/sphere_with_mat_gloss_50pc.lwo", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
}