Model optimization
This commit is contained in:
1 parent
be6a8cca9e
commit
d24748df1e
5 files changed
+244
-10
No files matched your search
@@ -10,8 +10,22 @@
|
||||
namespace ZL
|
||||
{
|
||||
|
||||
static std::unordered_map<std::string, VertexDataStruct> s_meshCache;
|
||||
|
||||
static std::string CacheKey(const std::string& fileName)
|
||||
{
|
||||
if (fileName.size() > 4 && fileName.compare(fileName.size() - 4, 4, ".bin") == 0)
|
||||
return fileName.substr(0, fileName.size() - 4);
|
||||
return fileName;
|
||||
}
|
||||
|
||||
VertexDataStruct LoadFromTextFile02(const std::string& fileName, const std::string& ZIPFileName)
|
||||
{
|
||||
std::string key = CacheKey(fileName);
|
||||
auto it = s_meshCache.find(key);
|
||||
if (it != s_meshCache.end())
|
||||
return it->second;
|
||||
|
||||
VertexDataStruct result;
|
||||
std::istringstream f;
|
||||
|
||||
@@ -181,10 +195,81 @@ namespace ZL
|
||||
|
||||
std::cout << "Model loaded: " << numberVertices << " verts, " << numberTriangles << " tris." << std::endl;
|
||||
|
||||
s_meshCache[key] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
VertexDataStruct LoadModelFromBinFile(const std::string& fileName, const std::string& ZIPFileName)
|
||||
{
|
||||
std::string key = CacheKey(fileName);
|
||||
auto it = s_meshCache.find(key);
|
||||
if (it != s_meshCache.end())
|
||||
return it->second;
|
||||
|
||||
std::vector<char> fileData = !ZIPFileName.empty()
|
||||
? readFileFromZIP(fileName, ZIPFileName)
|
||||
: readFile(fileName);
|
||||
|
||||
if (fileData.size() < 16)
|
||||
throw std::runtime_error("Binary mesh file is too short: " + fileName);
|
||||
|
||||
const char* ptr = fileData.data();
|
||||
|
||||
if (ptr[0] != 'B' || ptr[1] != 'S' || ptr[2] != 'M' || ptr[3] != 'F')
|
||||
throw std::runtime_error("Invalid magic bytes in binary mesh file: " + fileName);
|
||||
ptr += 4;
|
||||
|
||||
uint32_t version = *reinterpret_cast<const uint32_t*>(ptr); ptr += 4;
|
||||
if (version != 1)
|
||||
throw std::runtime_error("Unsupported binary mesh version " + std::to_string(version) + ": " + fileName);
|
||||
|
||||
uint32_t numVertices = *reinterpret_cast<const uint32_t*>(ptr); ptr += 4;
|
||||
uint32_t numTriangles = *reinterpret_cast<const uint32_t*>(ptr); ptr += 4;
|
||||
|
||||
const size_t expectedSize = 16
|
||||
+ static_cast<size_t>(numVertices) * 8 * sizeof(float)
|
||||
+ static_cast<size_t>(numTriangles) * 3 * sizeof(uint32_t);
|
||||
if (fileData.size() < expectedSize)
|
||||
throw std::runtime_error("Binary mesh file is truncated: " + fileName);
|
||||
|
||||
std::vector<Vector3f> positions(numVertices);
|
||||
std::vector<Vector3f> normals(numVertices);
|
||||
std::vector<Vector2f> uvs(numVertices);
|
||||
|
||||
for (uint32_t i = 0; i < numVertices; ++i)
|
||||
{
|
||||
positions[i](0) = *reinterpret_cast<const float*>(ptr); ptr += 4;
|
||||
positions[i](1) = *reinterpret_cast<const float*>(ptr); ptr += 4;
|
||||
positions[i](2) = *reinterpret_cast<const float*>(ptr); ptr += 4;
|
||||
normals[i](0) = *reinterpret_cast<const float*>(ptr); ptr += 4;
|
||||
normals[i](1) = *reinterpret_cast<const float*>(ptr); ptr += 4;
|
||||
normals[i](2) = *reinterpret_cast<const float*>(ptr); ptr += 4;
|
||||
uvs[i](0) = *reinterpret_cast<const float*>(ptr); ptr += 4;
|
||||
uvs[i](1) = *reinterpret_cast<const float*>(ptr); ptr += 4;
|
||||
}
|
||||
|
||||
VertexDataStruct result;
|
||||
result.PositionData.reserve(numTriangles * 3);
|
||||
result.NormalData.reserve(numTriangles * 3);
|
||||
result.TexCoordData.reserve(numTriangles * 3);
|
||||
|
||||
for (uint32_t i = 0; i < numTriangles; ++i)
|
||||
{
|
||||
for (int k = 0; k < 3; ++k)
|
||||
{
|
||||
uint32_t idx = *reinterpret_cast<const uint32_t*>(ptr); ptr += 4;
|
||||
if (idx >= numVertices)
|
||||
throw std::runtime_error("Triangle index out of range in: " + fileName);
|
||||
result.PositionData.push_back(positions[idx]);
|
||||
result.NormalData.push_back(normals[idx]);
|
||||
result.TexCoordData.push_back(uvs[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Binary model loaded: " << numVertices << " verts, " << numTriangles << " tris." << std::endl;
|
||||
|
||||
s_meshCache[key] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,4 +7,5 @@
|
||||
namespace ZL
|
||||
{
|
||||
VertexDataStruct LoadFromTextFile02(const std::string& fileName, const std::string& ZIPFileName = "");
|
||||
VertexDataStruct LoadModelFromBinFile(const std::string& fileName, const std::string& ZIPFileName = "");
|
||||
}
|
||||
@@ -138,7 +138,10 @@ namespace ZL {
|
||||
|
||||
// Load mesh
|
||||
try {
|
||||
gameObj.mesh.data = LoadFromTextFile02(objData.meshPath, zipPath);
|
||||
if (objData.meshPath.size() > 4 && objData.meshPath.compare(objData.meshPath.size() - 4, 4, ".bin") == 0)
|
||||
gameObj.mesh.data = LoadModelFromBinFile(objData.meshPath, zipPath);
|
||||
else
|
||||
gameObj.mesh.data = LoadFromTextFile02(objData.meshPath, zipPath);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "GameObjectLoader: Failed to load mesh for '" << objData.name << "': " << e.what() << std::endl;
|
||||
@@ -211,7 +214,10 @@ namespace ZL {
|
||||
|
||||
// Load mesh
|
||||
try {
|
||||
intObj.mesh.data = LoadFromTextFile02(objData.meshPath, zipPath);
|
||||
if (objData.meshPath.size() > 4 && objData.meshPath.compare(objData.meshPath.size() - 4, 4, ".bin") == 0)
|
||||
intObj.mesh.data = LoadModelFromBinFile(objData.meshPath, zipPath);
|
||||
else
|
||||
intObj.mesh.data = LoadFromTextFile02(objData.meshPath, zipPath);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "GameObjectLoader: Failed to load mesh for interactive '" << objData.name << "': " << e.what() << std::endl;
|
||||
|
||||
Reference in new issue
Block a user