I am working on a c++ version of your code...
Making classes out of the functions. Onlything i'm stuck on is what is the proper c++ way to replace the sscanf() calls on the buffers? cause my buffers are strings...
But i will post the almost C++ compliant version of your code, with some added features.
>>>>><<<<<
>> EDIT <<
>>>>><<<<<
Well hear it is in its incomplete form...
Only error im stuck on is my ObjModel delete [] stuff. causes assertion failure
ObjLoader.h
/*-----------------------------------------------------------------//// April 10, 2005 //// Copyright (C) 2005 Justin Walsh //// //// This code is Released Under the GNU GPL //// http://www.gnu.org/copyleft/gpl.html ////-----------------------------------------------------------------*/
#ifndef OBJLOADER_H
#define OBJLOADER_H
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
struct ObjVertex{
float X, Y, Z;
};
struct ObjNormal{
float X, Y, Z;
};
struct ObjTexCoord{
float U, V;
};
struct ObjTriangle{
int Vertex[
3];
int Normal[
3];
int TexCoord[
3];
};
class ObjModel {
public:
ObjModel();
~ObjModel();
ObjModel(
const ObjModel& copy);
ObjModel&
operator=(
const ObjModel& right);
int NumVertex, NumNormal, NumTexCoord, NumTriangle;
ObjVertex *VertexArray;
ObjNormal *NormalArray;
ObjTexCoord *TexCoordArray;
ObjTriangle *TriangleArray;
};
class ObjLoader {
public:
ObjLoader();
~ObjLoader();
ObjLoader(string file);
void LoadObj(string file);
void FreeObj(
void);
ObjModel ReturnObj(
void);
protected:
string *fileName;
ObjModel *theObj;
void ReadData(
void);
};
#endifObjLoader.cpp
/*-----------------------------------------------------------------//// April 10, 2005 //// Copyright (C) 2005 Justin Walsh //// //// This code is Released Under the GNU GPL //// http://www.gnu.org/copyleft/gpl.html ////-----------------------------------------------------------------*/
#include "ObjLoader.h" ObjModel::ObjModel() {
ObjModel::NumNormal =
0;
ObjModel::NumTexCoord =
0;
ObjModel::NumTriangle =
0;
ObjModel::NumVertex =
0;
ObjModel::NormalArray = NULL;
ObjModel::TexCoordArray = NULL;
ObjModel::TriangleArray = NULL;
ObjModel::VertexArray = NULL;
}
ObjModel::~ObjModel() {
delete [] NormalArray;
delete [] TexCoordArray;
delete [] TriangleArray;
delete [] VertexArray;
}
ObjModel::ObjModel(
const ObjModel ©) {
NormalArray =
new ObjNormal[copy.NumNormal];
TexCoordArray =
new ObjTexCoord[copy.NumTexCoord];
TriangleArray =
new ObjTriangle[copy.NumTriangle];
VertexArray =
new ObjVertex[copy.NumVertex];
NumNormal = copy.NumNormal;
NumTexCoord = copy.NumTexCoord;
NumTriangle = copy.NumTriangle;
NumVertex = copy.NumVertex;
for(
int i =
0; i < NumNormal; i++)
NormalArray
= copy.NormalArray;
for(i = 0; i < NumTexCoord; i++)
TexCoordArray = copy.TexCoordArray;
for(i = 0; i < NumTriangle; i++)
TriangleArray = copy.TriangleArray;
for(i = 0; i < NumVertex; i++)
VertexArray = copy.VertexArray;
}
ObjModel& ObjModel::operator=(const ObjModel &right) {
delete [] NormalArray;
delete [] TexCoordArray;
delete [] TriangleArray;
delete [] VertexArray;
NormalArray = new ObjNormal[right.NumNormal];
TexCoordArray = new ObjTexCoord[right.NumTexCoord];
TriangleArray = new ObjTriangle[right.NumTriangle];
VertexArray = new ObjVertex[right.NumVertex];
NumNormal = right.NumNormal;
NumTexCoord = right.NumTexCoord;
NumTriangle = right.NumTriangle;
NumVertex = right.NumVertex;
for(int i = 0; i < NumNormal; i++)
NormalArray = right.NormalArray;
for(i = 0; i < NumTexCoord; i++)
TexCoordArray = right.TexCoordArray;
for(i = 0; i < NumTriangle; i++)
TriangleArray = right.TriangleArray;
for(i = 0; i < NumVertex; i++)
VertexArray = right.VertexArray;
return *this;
}
ObjLoader::ObjLoader() {
fileName = NULL;
theObj = NULL;
}
ObjLoader::~ObjLoader() {
FreeObj();
}
void ObjLoader::FreeObj(void) {
if(fileName != NULL) delete fileName;
if(theObj != NULL) delete theObj;
}
ObjModel ObjLoader::ReturnObj(void) {
ObjModel ret(*theObj);
return ret;
}
ObjLoader::ObjLoader(string file) {
fileName = new string(file);
theObj = new ObjModel();
ReadData();
}
void ObjLoader::LoadObj(string file) {
FreeObj();
fileName = new string(file);
theObj = new ObjModel();
ReadData();
}
void ObjLoader::ReadData(void) {
ifstream input(fileName->c_str());
string buffer;
if( !input.is_open() )
return;
while( !input.eof() ) {
getline(input, buffer);
if(buffer.substr(0,2) == "vn")
theObj->NumNormal++;
else if(buffer.substr(0,2) == "vt")
theObj->NumTexCoord++;
else if(buffer.substr(0,1) == "v")
theObj->NumVertex++;
else if(buffer.substr(0,1) == "f")
theObj->NumTriangle++;
}
theObj->NormalArray = new ObjNormal[theObj->NumNormal];
theObj->TexCoordArray = new ObjTexCoord[theObj->NumTexCoord];
theObj->TriangleArray = new ObjTriangle[theObj->NumTriangle];
theObj->VertexArray = new ObjVertex[theObj->NumVertex];
input.close();
input.open(fileName->c_str());
input.clear();
if( !input.is_open() )
return;
int nC, vC, tC, fC;
nC = vC = tC = fC = 0;
while( !input.eof() ) {
getline(input, buffer);
istringstream line(buffer);
string temp;
string f1, f2, f3;
if(buffer.substr(0,2) == "vn") {
line >> temp >> f1 >> f2 >> f3;
theObj->NormalArray[vC].X = atof(f1.c_str());
theObj->NormalArray[vC].Y = atof(f2.c_str());
theObj->NormalArray[vC].Z = atof(f3.c_str());
nC++;
}
else if(buffer.substr(0,2) == "vt") {
line >> temp >> f1 >> f2;
theObj->TexCoordArray[tC].U = atof(f1.c_str());
theObj->TexCoordArray[tC].V = atof(f2.c_str());
tC++;
}
else if(buffer.substr(0,1) == "v") {
line >> temp >> f1 >> f2 >> f3;
theObj->VertexArray[vC].X = atof(f1.c_str());
theObj->VertexArray[vC].Y = atof(f2.c_str());
theObj->VertexArray[vC].Z = atof(f3.c_str());
vC++;
}
else if(buffer.substr(0,1) == "f") {
line >> temp >> f1 >> f2 >> f3;
int sPos = 0;
int ePos = sPos;
string temp;
ePos = f1.find_first_of("/");
if(ePos != string::npos) {
temp = f1.substr(sPos, ePos - sPos);
theObj->TriangleArray[fC].Vertex[0] = atoi(temp.c_str()) - 1;
sPos = ePos+1;
ePos = f1.find("/", sPos);
temp = f1.substr(sPos, ePos - sPos);
theObj->TriangleArray[fC].Vertex[1] = atoi(temp.c_str()) - 1;
sPos = ePos+1;
ePos = f1.length();
temp = f1.substr(sPos, ePos - sPos);
theObj->TriangleArray[fC].Vertex[2] = atoi(temp.c_str()) - 1;
}
sPos = 0;
ePos = f2.find_first_of("/");
if(ePos != string::npos) {
temp = f2.substr(sPos, ePos - sPos);
theObj->TriangleArray[fC].TexCoord[0] = atoi(temp.c_str()) - 1;
sPos = ePos + 1;
ePos = f2.find("/", sPos+1);
temp = f2.substr(sPos, ePos - sPos);
theObj->TriangleArray[fC].TexCoord[1] = atoi(temp.c_str()) - 1;
sPos = ePos + 1;
ePos = f2.length();
temp = f2.substr(sPos, ePos - sPos);
theObj->TriangleArray[fC].TexCoord[2] = atoi(temp.c_str()) - 1;
}
sPos = 0;
ePos = f3.find_first_of("/");
if(ePos != string::npos) {
temp = f3.substr(sPos, ePos - sPos);
theObj->TriangleArray[fC].Normal[0] = atoi(temp.c_str()) - 1;
sPos = ePos + 1;
ePos = f3.find("/", sPos+1);
temp = f3.substr(sPos, ePos - sPos);
theObj->TriangleArray[fC].Normal[1] = atoi(temp.c_str()) - 1;
sPos = ePos + 1;
ePos = f3.length();
temp = f3.substr(sPos, ePos - sPos);
theObj->TriangleArray[fC].Normal[2] = atoi(temp.c_str()) - 1;
}
fC++;
}
}
}
main.cpp test program
/*-----------------------------------------------------------------//// April 10, 2005 //// Copyright (C) 2005 Justin Walsh //// //// This code is Released Under the GNU GPL //// http://www.gnu.org/copyleft/gpl.html ////-----------------------------------------------------------------*/
#include <iostream>
#include "ObjLoader.h"using namespace std;
int main(
void) {
ObjModel data;
ObjLoader LoaderClass;
LoaderClass.LoadObj(
"test.obj");
data = LoaderClass.ReturnObj();
cout <<
"Object Model has: " << data.NumTriangle <<
" faces! \n";
for(
int i =
0; i < data.NumVertex; i++) {
cout << data.VertexArray
.X
<< " "
<< data.VertexArray.Y
<< " "
<< data.VertexArray.Z
<< "\n";
}
for(i = 0; i < data.NumTriangle; i++) {
cout << "Indacies into faces:\n";
cout << data.TriangleArray.Vertex[0]
<< " "
<< data.TriangleArray.Vertex[1]
<< " "
<< data.TriangleArray.Vertex[2]
<< "\n";
}
cout << "Vertex from triangle info]:\n";
cout << data.VertexArray[data.TriangleArray[1].Vertex[0]].X
<< " "
<< data.VertexArray[data.TriangleArray[1].Vertex[0]].Y
<< " "
<< data.VertexArray[data.TriangleArray[1].Vertex[0]].Z
<< "\n"
<< data.VertexArray[data.TriangleArray[1].Vertex[1]].X
<< " "
<< data.VertexArray[data.TriangleArray[1].Vertex[1]].Y
<< " "
<< data.VertexArray[data.TriangleArray[1].Vertex[1]].Z
<< "\n"
<< data.VertexArray[data.TriangleArray[1].Vertex[2]].X
<< " "
<< data.VertexArray[data.TriangleArray[1].Vertex[2]].Y
<< " "
<< data.VertexArray[data.TriangleArray[1].Vertex[2]].Z
<< "\n";
system("PAUSE");
return 0;
}
Sorry to hijack the thread, but if we get this working in a C flavor and C++ flavor that will be awesome.
[Edited by - justinrwalsh on April 11, 2005 12:08:05 AM]