Skip to content

Commit

Permalink
Improve acc file loading
Browse files Browse the repository at this point in the history
Add warning and support for tolerating a common problem where objects have wrong kid count.
Add support for empty texture layers.
  • Loading branch information
IOBYTE authored and kimkulling committed Jan 9, 2024
1 parent 74af43f commit 81c20a5
Show file tree
Hide file tree
Showing 4 changed files with 565 additions and 20 deletions.
42 changes: 23 additions & 19 deletions code/AssetLib/AC/ACLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,9 @@ bool AC3DImporter::GetNextLine() {

// ------------------------------------------------------------------------------------------------
// Parse an object section in an AC file
void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
bool AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
if (!TokenMatch(buffer, "OBJECT", 6))
return;
return false;

SkipSpaces(&buffer);

Expand Down Expand Up @@ -212,10 +212,14 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
if (num) {
// load the children of this object recursively
obj.children.reserve(num);
for (unsigned int i = 0; i < num; ++i)
LoadObjectSection(obj.children);
for (unsigned int i = 0; i < num; ++i) {
if (!LoadObjectSection(obj.children)) {
ASSIMP_LOG_WARN("AC3D: wrong number of kids");
break;
}
}
}
return;
return true;
} else if (TokenMatch(buffer, "name", 4)) {
SkipSpaces(&buffer);
buffer = AcGetString(buffer, obj.name);
Expand All @@ -227,9 +231,16 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
}
} else if (TokenMatch(buffer, "texture", 7)) {
SkipSpaces(&buffer);
std::string texture;
buffer = AcGetString(buffer, texture);
obj.textures.push_back(texture);
// skip empty acc texture
if (*buffer != '\"') {
if (!TokenMatch(buffer, "empty_texture_no_mapping", 24)) {
ASSIMP_LOG_ERROR("AC3D: Unquoted texture string");
}
} else {
std::string texture;
buffer = AcGetString(buffer, texture);
obj.textures.push_back(texture);
}
} else if (TokenMatch(buffer, "texrep", 6)) {
SkipSpaces(&buffer);
buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &obj.texRepeat);
Expand Down Expand Up @@ -340,6 +351,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
}
}
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: \'kids\' line was expected");
return false;
}

// ------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -445,7 +457,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
idx = 0;
}
if ((*it).entries.empty()) {
ASSIMP_LOG_WARN("AC3D: surface her zero vertex references");
ASSIMP_LOG_WARN("AC3D: surface has zero vertex references");
}

// validate all vertex indices to make sure we won't crash here
Expand Down Expand Up @@ -574,15 +586,6 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
const Surface::SurfaceEntry &entry2 = src.entries[i + 1];
const Surface::SurfaceEntry &entry3 = src.entries[i + 2];

// skip degenerate triangles
if (object.vertices[entry1.first] == object.vertices[entry2.first] ||
object.vertices[entry1.first] == object.vertices[entry3.first] ||
object.vertices[entry2.first] == object.vertices[entry3.first]) {
mesh->mNumFaces--;
mesh->mNumVertices -= 3;
continue;
}

aiFace &face = *faces++;
face.mNumIndices = 3;
face.mIndices = new unsigned int[face.mNumIndices];
Expand Down Expand Up @@ -804,8 +807,9 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
buffer = TAcCheckedLoadFloatArray(buffer, "spec", 4, 3, &mat.spec);
buffer = TAcCheckedLoadFloatArray(buffer, "shi", 3, 1, &mat.shin);
buffer = TAcCheckedLoadFloatArray(buffer, "trans", 5, 1, &mat.trans);
} else {
LoadObjectSection(rootObjects);
}
LoadObjectSection(rootObjects);
}

if (rootObjects.empty() || !mNumMeshes) {
Expand Down
2 changes: 1 addition & 1 deletion code/AssetLib/AC/ACLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ class AC3DImporter : public BaseImporter {
* load subobjects, the method returns after a 'kids 0' was
* encountered.
* @objects List of output objects*/
void LoadObjectSection(std::vector<Object> &objects);
bool LoadObjectSection(std::vector<Object> &objects);

// -------------------------------------------------------------------
/** Convert all objects into meshes and nodes.
Expand Down
Loading

0 comments on commit 81c20a5

Please sign in to comment.