|
@@ -75,6 +75,8 @@ static constexpr aiImporterDesc desc = {
|
|
|
"ac acc ac3d"
|
|
|
};
|
|
|
|
|
|
+static constexpr auto ACDoubleSidedFlag = 0x20;
|
|
|
+
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
// skip to the next token
|
|
|
inline const char *AcSkipToNextToken(const char *buffer, const char *end) {
|
|
@@ -129,6 +131,30 @@ inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *end,
|
|
|
return buffer;
|
|
|
}
|
|
|
|
|
|
+// ------------------------------------------------------------------------------------------------
|
|
|
+// Reverses vertex indices in a face.
|
|
|
+static void flipWindingOrder(aiFace &f) {
|
|
|
+ std::reverse(f.mIndices, f.mIndices + f.mNumIndices);
|
|
|
+}
|
|
|
+
|
|
|
+// ------------------------------------------------------------------------------------------------
|
|
|
+// Duplicates a face and inverts it. Also duplicates all vertices (so the new face gets its own
|
|
|
+// set of normals and isn’t smoothed against the original).
|
|
|
+static void buildBacksideOfFace(const aiFace &origFace, aiFace *&outFaces, aiVector3D *&outVertices, const aiVector3D *allVertices,
|
|
|
+ aiVector3D *&outUV, const aiVector3D *allUV, unsigned &curIdx) {
|
|
|
+ auto &newFace = *outFaces++;
|
|
|
+ newFace = origFace;
|
|
|
+ flipWindingOrder(newFace);
|
|
|
+ for (unsigned f = 0; f < newFace.mNumIndices; ++f) {
|
|
|
+ *outVertices++ = allVertices[newFace.mIndices[f]];
|
|
|
+ if (outUV) {
|
|
|
+ *outUV = allUV[newFace.mIndices[f]];
|
|
|
+ outUV++;
|
|
|
+ }
|
|
|
+ newFace.mIndices[f] = curIdx++;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
// Constructor to be privately used by Importer
|
|
|
AC3DImporter::AC3DImporter() :
|
|
@@ -451,6 +477,8 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
|
|
|
if ((*it).entries.empty()) {
|
|
|
ASSIMP_LOG_WARN("AC3D: surface has zero vertex references");
|
|
|
}
|
|
|
+ const bool isDoubleSided = ACDoubleSidedFlag == (it->flags & ACDoubleSidedFlag);
|
|
|
+ const int doubleSidedFactor = isDoubleSided ? 2 : 1;
|
|
|
|
|
|
// validate all vertex indices to make sure we won't crash here
|
|
|
for (it2 = (*it).entries.begin(),
|
|
@@ -480,8 +508,8 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
|
|
|
|
|
|
// triangle strip
|
|
|
case Surface::TriangleStrip:
|
|
|
- needMat[idx].first += (unsigned int)(*it).entries.size() - 2;
|
|
|
- needMat[idx].second += ((unsigned int)(*it).entries.size() - 2) * 3;
|
|
|
+ needMat[idx].first += static_cast<unsigned int>(it->entries.size() - 2) * doubleSidedFactor;
|
|
|
+ needMat[idx].second += static_cast<unsigned int>(it->entries.size() - 2) * 3 * doubleSidedFactor;
|
|
|
break;
|
|
|
|
|
|
default:
|
|
@@ -494,8 +522,8 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
|
|
|
case Surface::Polygon:
|
|
|
// the number of faces increments by one, the number
|
|
|
// of vertices by surface.numref.
|
|
|
- needMat[idx].first++;
|
|
|
- needMat[idx].second += (unsigned int)(*it).entries.size();
|
|
|
+ needMat[idx].first += doubleSidedFactor;
|
|
|
+ needMat[idx].second += static_cast<unsigned int>(it->entries.size()) * doubleSidedFactor;
|
|
|
};
|
|
|
}
|
|
|
unsigned int *pip = node->mMeshes = new unsigned int[node->mNumMeshes];
|
|
@@ -545,6 +573,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
|
|
|
for (it = object.surfaces.begin(); it != end; ++it) {
|
|
|
if (mat == (*it).mat) {
|
|
|
const Surface &src = *it;
|
|
|
+ const bool isDoubleSided = ACDoubleSidedFlag == (src.flags & ACDoubleSidedFlag);
|
|
|
|
|
|
// closed polygon
|
|
|
uint8_t type = (*it).GetType();
|
|
@@ -570,6 +599,8 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
|
|
|
++uv;
|
|
|
}
|
|
|
}
|
|
|
+ if(isDoubleSided) // Need a backface?
|
|
|
+ buildBacksideOfFace(faces[-1], faces, vertices, mesh->mVertices, uv, mesh->mTextureCoords[0], cur);
|
|
|
}
|
|
|
} else if (type == Surface::TriangleStrip) {
|
|
|
for (unsigned int i = 0; i < (unsigned int)src.entries.size() - 2; ++i) {
|
|
@@ -619,6 +650,8 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
|
|
|
uv->y = entry3.second.y;
|
|
|
++uv;
|
|
|
}
|
|
|
+ if(isDoubleSided) // Need a backface?
|
|
|
+ buildBacksideOfFace(faces[-1], faces, vertices, mesh->mVertices, uv, mesh->mTextureCoords[0], cur);
|
|
|
}
|
|
|
} else {
|
|
|
|