Minor Update - Loading Obj Model is now faster than f1 - V10.4.0

This commit is contained in:
2025-05-12 14:18:43 +02:00
parent 32b71ac97f
commit c5bfa2e621
3 changed files with 110 additions and 90 deletions

View File

@@ -240,94 +240,110 @@ bool ModelClass::LoadModel(char* filename)
bool ModelClass::LoadObjModel(char* filename)
{
std::string line;
std::ifstream fin(filename);
// Lecture optimis<69>e du fichier en mode binaire
std::ifstream fin(filename, std::ios::in | std::ios::binary);
if (!fin)
{
Logger::Get().Log("<EFBFBD>chec d'ouverture du fichier mod<6F>le", __FILE__, __LINE__, Logger::LogLevel::Error);
return false;
}
// If it could not open the file then exit.
if (!fin)
{
Logger::Get().Log("Failed to open model file", __FILE__, __LINE__, Logger::LogLevel::Error);
return false;
}
// Lecture du fichier entier d'un coup (<28>vite la lecture ligne par ligne)
fin.seekg(0, std::ios::end);
const size_t fileSize = fin.tellg();
fin.seekg(0, std::ios::beg);
std::string fileContent;
fileContent.resize(fileSize);
fin.read(&fileContent[0], fileSize);
fin.close();
std::vector<XMFLOAT3> temp_positions;
std::vector<XMFLOAT2> temp_texcoords;
std::vector<XMFLOAT3> temp_normals;
std::vector<ModelType> temp_model;
// Pr<50>-allocation des vecteurs (<28>vite les r<>allocations)
const size_t estimatedVertices = fileSize / 150;
std::vector<XMFLOAT3> temp_positions;
std::vector<XMFLOAT2> temp_texcoords;
std::vector<XMFLOAT3> temp_normals;
std::vector<ModelType> temp_model;
// Read the file line by line.
while (std::getline(fin, line))
{
std::istringstream iss(line);
std::string type;
iss >> type;
temp_positions.reserve(estimatedVertices);
temp_texcoords.reserve(estimatedVertices);
temp_normals.reserve(estimatedVertices);
temp_model.reserve(estimatedVertices * 3);
if (type == "v") // Vertex position
{
XMFLOAT3 pos;
iss >> pos.x >> pos.y >> pos.z;
temp_positions.push_back(pos);
}
else if (type == "vt") // Texture coordinate
{
XMFLOAT2 tex;
iss >> tex.x >> tex.y;
temp_texcoords.push_back(tex);
}
else if (type == "vn") // Vertex normal
{
XMFLOAT3 norm;
iss >> norm.x >> norm.y >> norm.z;
temp_normals.push_back(norm);
}
else if (type == "f") // Face
{
int posIndex[3], texIndex[3], normIndex[3];
char slash; // To skip the slashes '/' in the .obj file format
for (int i = 0; i < 3; i++) // Each face in .obj format has 3 vertices
{
iss >> posIndex[i] >> slash >> texIndex[i] >> slash >> normIndex[i];
// Analyse du contenu
std::istringstream iss(fileContent);
std::string line;
// Handle negative indices
if (posIndex[i] < 0) posIndex[i] += temp_positions.size() + 1;
if (texIndex[i] < 0) texIndex[i] += temp_texcoords.size() + 1;
if (normIndex[i] < 0) normIndex[i] += temp_normals.size() + 1;
}
while (std::getline(iss, line))
{
if (line.empty() || line[0] == '#') continue;
// .obj indices start from 1, not 0
for (int i = 0; i < 3; i++)
{
ModelType vertex;
vertex.x = temp_positions[posIndex[i] - 1].x;
vertex.y = temp_positions[posIndex[i] - 1].y;
vertex.z = temp_positions[posIndex[i] - 1].z;
vertex.tu = temp_texcoords[texIndex[i] - 1].x;
vertex.tv = temp_texcoords[texIndex[i] - 1].y;
vertex.nx = temp_normals[normIndex[i] - 1].x;
vertex.ny = temp_normals[normIndex[i] - 1].y;
vertex.nz = temp_normals[normIndex[i] - 1].z;
temp_model.push_back(vertex);
}
}
}
// Analyse plus rapide bas<61>e sur le premier caract<63>re
if (line[0] == 'v')
{
if (line[1] == ' ') // Position de sommet
{
XMFLOAT3 pos;
sscanf_s(line.c_str() + 2, "%f %f %f", &pos.x, &pos.y, &pos.z);
temp_positions.push_back(pos);
}
else if (line[1] == 't') // Coordonn<6E>es de texture
{
XMFLOAT2 tex;
sscanf_s(line.c_str() + 3, "%f %f", &tex.x, &tex.y);
temp_texcoords.push_back(tex);
}
else if (line[1] == 'n') // Normales
{
XMFLOAT3 norm;
sscanf_s(line.c_str() + 3, "%f %f %f", &norm.x, &norm.y, &norm.z);
temp_normals.push_back(norm);
}
}
else if (line[0] == 'f')
{
int posIndex[3], texIndex[3], normIndex[3];
const char* linePtr = line.c_str() + 2; // Sauter "f "
for (int i = 0; i < 3; i++)
{
// Analyse rapide du format v/vt/vn
sscanf_s(linePtr, "%d/%d/%d", &posIndex[i], &texIndex[i], &normIndex[i]);
// Avancer au prochain ensemble d'indices
while (*linePtr && *linePtr != ' ') linePtr++;
while (*linePtr == ' ') linePtr++;
m_vertexCount = temp_model.size();
m_indexCount = temp_model.size();
if (posIndex[i] < 0) posIndex[i] += temp_positions.size() + 1;
if (texIndex[i] < 0) texIndex[i] += temp_texcoords.size() + 1;
if (normIndex[i] < 0) normIndex[i] += temp_normals.size() + 1;
}
// Create the model using the vertex count that was read in.
m_model = new ModelType[m_vertexCount];
for (int i = 0; i < m_vertexCount; i++)
{
m_model[i] = temp_model[i];
}
for (int i = 0; i < 3; i++)
{
ModelType vertex{};
vertex.x = temp_positions[posIndex[i] - 1].x;
vertex.y = temp_positions[posIndex[i] - 1].y;
vertex.z = temp_positions[posIndex[i] - 1].z;
vertex.tu = temp_texcoords[texIndex[i] - 1].x;
vertex.tv = temp_texcoords[texIndex[i] - 1].y;
vertex.nx = temp_normals[normIndex[i] - 1].x;
vertex.ny = temp_normals[normIndex[i] - 1].y;
vertex.nz = temp_normals[normIndex[i] - 1].z;
temp_model.push_back(vertex);
}
}
}
fin.close();
// Allocation et copie efficace du mod<6F>le final
m_vertexCount = temp_model.size();
m_indexCount = temp_model.size();
m_model = new ModelType[m_vertexCount];
std::memcpy(m_model, temp_model.data(), m_vertexCount * sizeof(ModelType));
return true;
return true;
}
bool ModelClass::LoadTxtModel(char* filename)
{
ifstream fin;