You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
122 lines
3.4 KiB
122 lines
3.4 KiB
#include "model.h"
|
|
#include "misc.h"
|
|
#include <stdio.h>
|
|
#include <string>
|
|
#include <sstream>
|
|
#include <vector>
|
|
|
|
VertexData * LoadObjModel(const char * filePath, unsigned int ** indexes, int & vertexCount, int & indexCount)
|
|
{
|
|
char* fileContent = LoadFileContent(filePath);
|
|
if (fileContent != nullptr) {
|
|
|
|
struct VertexInfo {
|
|
float v[3];
|
|
};
|
|
|
|
struct VertexDefine {
|
|
int positionIndex;
|
|
int texcoordIndex;
|
|
int normalIndex;
|
|
};
|
|
|
|
std::vector<VertexInfo> position;
|
|
std::vector<VertexInfo> texcoord;
|
|
std::vector<VertexInfo> normal;
|
|
|
|
std::vector<unsigned int> objIndexes; //点的索引 对应opengl的indexes
|
|
std::vector<VertexDefine> vertices; //每一个点 对应opengl的vertex
|
|
|
|
std::stringstream ssObjFile(fileContent);
|
|
char szOneLine[256];
|
|
std::string temp;
|
|
while (!ssObjFile.eof()) {
|
|
memset(szOneLine, 0, 256);
|
|
ssObjFile.getline(szOneLine, 256);
|
|
//printf("%s \n", szOneLine);
|
|
if (strlen(szOneLine) > 0) {
|
|
std::stringstream ssOneLine(szOneLine);
|
|
if (szOneLine[0] == 'v') {
|
|
if (szOneLine[1] == 't') {
|
|
ssOneLine >> temp;
|
|
VertexInfo vi;
|
|
ssOneLine >> vi.v[0];
|
|
ssOneLine >> vi.v[1];
|
|
texcoord.push_back(vi);
|
|
}
|
|
else if (szOneLine[1] == 'n') {
|
|
ssOneLine >> temp;
|
|
VertexInfo vi;
|
|
ssOneLine >> vi.v[0];
|
|
ssOneLine >> vi.v[1];
|
|
ssOneLine >> vi.v[2];
|
|
normal.push_back(vi);
|
|
}
|
|
else {
|
|
ssOneLine >> temp;
|
|
VertexInfo vi;
|
|
ssOneLine >> vi.v[0];
|
|
ssOneLine >> vi.v[1];
|
|
ssOneLine >> vi.v[2];
|
|
|
|
position.push_back(vi);
|
|
}
|
|
}
|
|
else if(szOneLine[0] == 'f'){
|
|
ssOneLine >> temp;
|
|
std::string vertexStr;
|
|
for (int i = 0; i < 3; i++) {
|
|
ssOneLine >> vertexStr;
|
|
|
|
size_t pos = vertexStr.find_first_of('/');
|
|
std::string positionIndexStr = vertexStr.substr(0, pos);
|
|
size_t pos2 = vertexStr.find_first_of('/', pos + 1);
|
|
std::string texcoordIndexStr = vertexStr.substr(pos + 1, pos2 - pos - 1);
|
|
std::string normalIndexStr = vertexStr.substr(pos2 + 1, vertexStr.length() - pos2 - 1);
|
|
|
|
VertexDefine vd;
|
|
vd.positionIndex = atoi(positionIndexStr.c_str()) - 1;
|
|
vd.texcoordIndex = atoi(texcoordIndexStr.c_str()) - 1;
|
|
vd.normalIndex = atoi(normalIndexStr.c_str()) - 1;
|
|
|
|
int nCurrentIndex = -1;
|
|
size_t nCurrentVerticeCount = vertices.size();
|
|
for (size_t j = 0; j < nCurrentVerticeCount; j++) {
|
|
if (vertices[j].positionIndex == vd.positionIndex &&
|
|
vertices[j].texcoordIndex == vd.texcoordIndex &&
|
|
vertices[j].normalIndex == vd.normalIndex) {
|
|
nCurrentIndex = j;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (nCurrentIndex == -1) {
|
|
nCurrentIndex = vertices.size();
|
|
vertices.push_back(vd);
|
|
}
|
|
|
|
objIndexes.push_back(nCurrentIndex);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
printf("face count %u\n", objIndexes.size() / 3);
|
|
|
|
indexCount = (int)objIndexes.size();
|
|
*indexes = new unsigned int[indexCount];
|
|
for (int i = 0; i < indexCount; i++) {
|
|
(*indexes)[i] = objIndexes[i];
|
|
}
|
|
|
|
vertexCount = (int)vertices.size();
|
|
VertexData *vertexes = new VertexData[vertexCount];
|
|
for (int i = 0; i < vertexCount; i++) {
|
|
memcpy(vertexes[i].position, position[vertices[i].positionIndex].v, sizeof(float) * 3);
|
|
memcpy(vertexes[i].texcoord, texcoord[vertices[i].texcoordIndex].v, sizeof(float) * 2);
|
|
memcpy(vertexes[i].normal, normal[vertices[i].normalIndex].v, sizeof(float) * 3);
|
|
}
|
|
return vertexes;
|
|
}
|
|
return nullptr;
|
|
}
|