📄 mobjfile.cpp
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include ".\mobjfile.h"
#include <iostream>
using namespace std;
MObjFile::MObjFile(void)
{
NumOfVertex = 0;
NumOfNormal = 0;
NumOfTexture = 0;
NumOfMaterial = 0;
NumOfFace = 0;
vList = NULL;
nList = NULL;
tList = NULL;
fList = NULL;
mList = NULL;
MaxSupport = 100;
}
MObjFile::~MObjFile(void)
{
if (vList) delete [] vList;
if (nList) delete [] nList;
if (tList) delete [] tList;
if (fList) delete [] fList;
if (mList) delete [] mList;
}
void MObjFile::CountTokens(FILE *objFile)
{
char fBuf[100];
while(!feof(objFile))
{
fscanf(objFile,"%s", fBuf);
if (!strcmp(fBuf,"v"))
NumOfVertex++;
else if (!strcmp(fBuf,"vn"))
NumOfNormal++;
else if (!strcmp(fBuf,"vt"))
NumOfTexture++;
else if (!strcmp(fBuf,"f"))
NumOfFace++;
}
}
void MObjFile::AllocateArrays()
{
vList = new Point3[NumOfVertex + 1]; // The point is Start for 1;
nList = new Point3[NumOfNormal + 1]; //
tList = new Point3[NumOfTexture+ 1]; //
mList = new Material[MaxSupport];
fList = new FACE[NumOfFace];
}
bool MObjFile::LoadFile(const char *fileName)
{
if ( vList ) return true;
float defaultValue[3] = {1,1,1};
FILE *objFile = fopen(fileName, "r");
if (objFile == NULL) return false;
CountTokens(objFile);
AllocateArrays();
if (fseek(objFile, 0, SEEK_SET) != 0) return false;
vList[0].Set(defaultValue);
nList[0].Set(defaultValue);
tList[0].Set(defaultValue);
mList[0].Ka[0] = 0.0; mList[0].Ka[1] = 0.0; mList[0].Ka[2] = 0.0; mList[0].Ka[3] = 1.0;
mList[0].Kd[0] = 1.0; mList[0].Kd[1] = 1.0; mList[0].Kd[2] = 1.0; mList[0].Kd[3] = 1.0;
mList[0].Ks[0] = 0.8; mList[0].Ks[1] = 0.8; mList[0].Ks[2] = 0.8; mList[0].Ks[3] = 1.0;
mList[0].Ns = 32;
mList[0].d = 1;
NumOfMaterial = 1;
LoadMesh(objFile);
fclose(objFile);
return true;
}
void MObjFile::LoadMesh(FILE *objFile)
{
char token[100], buf[100], v[5][100] , texName[50];
float vec[3];
int n_vertex, n_texture, n_normal;
int curTex = 1 , curVer = 1 , curNor = 1 , curMat = 0 , curFac = 0;
while(!feof(objFile))
{
token[0] = NULL;
fscanf(objFile,"%s", token);
if (!strcmp(token,"g"))
{
fscanf(objFile,"%s",buf);
}
else if (!strcmp(token,"mtllib"))
{
fscanf(objFile,"%s", texName);
LoadTex(texName);
}
else if (!strcmp(token,"usemtl"))
{
fscanf(objFile,"%s",buf);
curMat = MaterialMap[string(buf)];
}
else if (!strcmp(token,"v"))
{
fscanf(objFile,"%f %f %f",&vec[0],&vec[1],&vec[2]);
vList[curVer++].Set(vec);
}
else if (!strcmp(token,"vn"))
{
fscanf(objFile,"%f %f %f",&vec[0],&vec[1],&vec[2]);
nList[curNor++].Set(vec);
}
else if (!strcmp(token,"vt"))
{
fscanf(objFile,"%f %f",&vec[0],&vec[1]); vec[2] = 0;
tList[curTex++].Set(vec);
}
else if (!strcmp(token,"f"))
{
for (int i=0;i<3;i++)
{
fscanf(objFile,"%s",v[i]);
//printf("[%s]",v[i]);
}
//printf("\n");
Vertex tVertex[3]; // for faceList structure
for (i=0;i<3;i++) // for each vertex of this face
{
char str[20], ch;
int base,offset;
base = offset = 0;
// calculate vertex-list index
while( (ch=v[i][base+offset]) != '/' && (ch=v[i][base+offset]) != '\0')
{
str[offset] = ch;
offset++;
}
str[offset] = '\0';
n_vertex = atoi(str);
base += (ch == '\0')? offset : offset+1;
offset = 0;
// calculate texture-list index
while( (ch=v[i][base+offset]) != '/' && (ch=v[i][base+offset]) != '\0')
{
str[offset] = ch;
offset++;
}
str[offset] = '\0';
n_texture = atoi(str);
base += (ch == '\0')? offset : offset+1;
offset = 0;
// calculate normal-list index
while( (ch=v[i][base+offset]) != '\0')
{
str[offset] = ch;
offset++;
}
str[offset] = '\0';
n_normal = atoi(str);
tVertex[i].IndexOfVertex = n_vertex;
tVertex[i].IndexOfTexture = n_texture;
tVertex[i].IndexOfNormal = n_normal;
tVertex[i].IndexOfMaterial = curMat;
}
fList[curFac++].Set(tVertex[0],tVertex[1],tVertex[2]);
}
}
}
void MObjFile::LoadTex(const char *texName)
{
char token[100], buf[100], fileName[256] = ".\\\\";
float r,g,b;
int i = 0;
int CurrentMaterial;
while( texName[i] )
fileName[ 3 + i ] = texName[i++];
FILE *texFile = fopen(fileName, "r");
if ( !texFile ) return;
while(!feof(texFile) && NumOfMaterial < MaxSupport )
{
token[0] = NULL;
fscanf(texFile,"%s", token);
if (!strcmp(token,"newmtl"))
{
fscanf(texFile,"%s",buf);
CurrentMaterial = NumOfMaterial++;
MaterialMap[string(buf)] = CurrentMaterial;
}
else if (!strcmp(token,"Ka"))
{
fscanf(texFile,"%f %f %f",&r,&g,&b);
mList[CurrentMaterial].Ka[0] = r;
mList[CurrentMaterial].Ka[1] = g;
mList[CurrentMaterial].Ka[2] = b;
mList[CurrentMaterial].Ka[3] = 1;
}
else if (!strcmp(token,"Kd"))
{
fscanf(texFile,"%f %f %f",&r,&g,&b);
mList[CurrentMaterial].Kd[0] = r;
mList[CurrentMaterial].Kd[1] = g;
mList[CurrentMaterial].Kd[2] = b;
mList[CurrentMaterial].Kd[3] = 1;
}
else if (!strcmp(token,"Ks"))
{
fscanf(texFile,"%f %f %f",&r,&g,&b);
mList[CurrentMaterial].Ks[0] = r;
mList[CurrentMaterial].Ks[1] = g;
mList[CurrentMaterial].Ks[2] = b;
mList[CurrentMaterial].Ks[3] = 1;
}
else if (!strcmp(token,"Ns"))
{
fscanf(texFile,"%f",&r);
mList[CurrentMaterial].Ns = r;
}
else if (!strcmp(token,"d"))
{
fscanf(texFile,"%f",&r);
mList[CurrentMaterial].d = r;
}
else if (!strcmp(token,"#"))
fgets(buf,100,texFile);
}
if (texFile) fclose(texFile);
}
void MObjFile::GetFaceVertex(const int face,const int vertex, Vertex3f &V)
{
V.x = vList[fList[face][vertex].IndexOfVertex][0];
V.y = vList[fList[face][vertex].IndexOfVertex][1];
V.z = vList[fList[face][vertex].IndexOfVertex][2];
}
void MObjFile::GetFaceNormal(const int face,const int vertex, Vertex3f &N)
{
N.x = nList[fList[face][vertex].IndexOfNormal][0];
N.y = nList[fList[face][vertex].IndexOfNormal][1];
N.z = nList[fList[face][vertex].IndexOfNormal][2];
}
void MObjFile::GetFaceTexture(const int face,const int vertex, Vertex2f &T)
{
T.u = tList[fList[face][vertex].IndexOfTexture][0];
T.v = tList[fList[face][vertex].IndexOfTexture][1];
}
void MObjFile::GetFaceMaterial(const int face,const int vertex, Material4f &M)
{
int i;
for(i = 0 ; i < 4; i++) {
M.Ka[i] = mList[fList[face][vertex].IndexOfMaterial].Ka[i];
M.Ka[i] = mList[fList[face][vertex].IndexOfMaterial].Ka[i];
M.Ka[i] = mList[fList[face][vertex].IndexOfMaterial].Ka[i];
}
M.Ns = mList[fList[face][vertex].IndexOfMaterial].Ns;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -