VRML 2.0 (.wrl) custom parser code
Well, I just got done finishing the first draft of a program that parses a .wrl (Virtual Reality Modeling Language 2.0) file, and I thought I would post the code in case anyones interested.
The code should be relatively easy to modify to fit your own custom format, and if anyone is interested in it, I'll comment it and post another copy
Anyway, here goes:
object.hpp:
object.cpp:
mainFile.cpp
All files (and a .wrl file containing a cube and a cone) can be found at http://www.wyrmmage.com/wrl/
The code isn't very robust, so I'll go ahead and list its most obvious erros here:
If your object name has a '{', '}', '[', or ']' in it, the program will probably die.
Only translations, rotations, and objects are supported (no nurbs, etc.)
If your object is not textured, the program will die.
Lighting, crease angles, materials, etc. will be ignored.
No animation parsing code is in there because it probably wouldn't be very helpful, and I haven't gotten around to writing the code that I'm going to use for animation anyway XD
Hope this helps some people
-wyrmmage
(I haven't compiled this on the Mac, but it should work, and it works fine on Windows)
The code should be relatively easy to modify to fit your own custom format, and if anyone is interested in it, I'll comment it and post another copy

Anyway, here goes:
object.hpp:
Code:
#ifndef OBJECT_HPP
#define OBJECT_HPP
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
#define SRB '{'
#define SLB '}'
#define DRB "{"
#define DLB "}"
using namespace std;
class object
{
public:
int numOfObjects;
int tier;
int id;
bool locked;
double transX;
double transY;
double transZ;
double angle;
double rotX;
double rotY;
double rotZ;
int numOfIndexedShapes;
int currentShapeIndex;
vector<string> coords;
vector<int> indexedCoords;
vector<int> indexedInShape;
vector<string> textureCoords;
vector<int> indexedTextureCoords;
string name;
vector<object> objects;
object();
~object();
void makeNew();
void lockLast();
void setLastName(char theName[]);
void setLastTier(int theTier);
void setLastRotation(double theAngle, double theX, double theY, double theZ);
void setLastTranslation(double theX, double theY, double theZ);
void setLastId(int theId);
void addLastCoord(char theCoord[]);
void addLastTextureCoord(char theCoord[]);
void endIndexShape();
void addLastIndexCoord(int theCoord);
void addLastIndexTextureCoord(int theCoord);
int getTotal();
string output();
};
#endifobject.cpp:
Code:
#include "object.hpp"
object::object()
{
numOfObjects = -1;
name = "";
locked = 0;
transX = 0.0;
transY = 0.0;
transZ = 0.0;
angle = 0.0;
rotX = 0.0;
rotY = 0.0;
rotZ = 0.0;
numOfIndexedShapes = -1;
currentShapeIndex = -1;
}
object::~object()
{ }
void object::makeNew()
{
int lastFound = -1;
/*~~~~~~~~~~~~~~~*/
for(int i = 0; i <= numOfObjects; i++)
{
if(!objects[i].locked)
{
lastFound = i;
i = numOfObjects + 1;
}
}
if(lastFound == -1)
{
object tempObject;
objects.push_back(tempObject);
numOfObjects = numOfObjects + 1;
}
else
{
objects[lastFound].makeNew();
}
}
void object::lockLast()
{
int lastFound = -1;
for(int i = 0; i <= numOfObjects; i++)
{
if(!objects[i].locked)
{
lastFound = i;
i = numOfObjects + 1;
}
}
if(lastFound == -1)
{
locked = 1;
}
else
{
objects[lastFound].lockLast();
}
}
void object::setLastName(char theName[])
{
int lastFound = -1;
for(int i = 0; i <= numOfObjects; i++)
{
if(!objects[i].locked)
{
lastFound = i;
i = numOfObjects + 1;
}
}
if(lastFound == -1)
{
name = theName;
}
else
{
objects[lastFound].setLastName(theName);
}
}
void object::setLastTier(int theTier)
{
int lastFound = -1;
for(int i = 0; i <= numOfObjects; i++)
{
if(!objects[i].locked)
{
lastFound = i;
i = numOfObjects + 1;
}
}
if(lastFound == -1)
{
tier = theTier;
}
else
{
objects[lastFound].setLastTier(theTier);
}
}
void object::setLastId(int theId)
{
int lastFound = -1;
for(int i = 0; i <= numOfObjects; i++)
{
if(!objects[i].locked)
{
lastFound = i;
i = numOfObjects + 1;
}
}
if(lastFound == -1)
{
id = theId;
}
else
{
objects[lastFound].setLastId(theId);
}
}
void object::setLastRotation(double theAngle, double theX, double theY, double theZ)
{
int lastFound = -1;
for(int i = 0; i <= numOfObjects; i++)
{
if(!objects[i].locked)
{
lastFound = i;
i = numOfObjects + 1;
}
}
if(lastFound == -1)
{
angle = theAngle;
rotX = theX;
rotY = theY;
rotZ = theZ;
}
else
{
objects[lastFound].setLastRotation(theAngle, theX, theY, theZ);
}
}
void object::setLastTranslation(double theX, double theY, double theZ)
{
int lastFound = -1;
for(int i = 0; i <= numOfObjects; i++)
{
if(!objects[i].locked)
{
lastFound = i;
i = numOfObjects + 1;
}
}
if(lastFound == -1)
{
transX = theX;
transY = theY;
transZ = theZ;
}
else
{
objects[lastFound].setLastTranslation(theX, theY, theZ);
}
}
void object::addLastCoord(char theCoord[])
{
int lastFound = -1;
for(int i = 0; i <= numOfObjects; i++)
{
if(!objects[i].locked)
{
lastFound = i;
i = numOfObjects + 1;
}
}
if(lastFound == -1)
{
string tempRealString = theCoord;
coords.push_back(tempRealString);
}
else
{
objects[lastFound].addLastCoord(theCoord);
}
}
void object::addLastTextureCoord(char theCoord[])
{
int lastFound = -1;
for(int i = 0; i <= numOfObjects; i++)
{
if(!objects[i].locked)
{
lastFound = i;
i = numOfObjects + 1;
}
}
if(lastFound == -1)
{
string tempRealString = theCoord;
textureCoords.push_back(tempRealString);
}
else
{
objects[lastFound].addLastTextureCoord(theCoord);
}
}
void object::endIndexShape()
{
int lastFound = -1;
for(int i = 0; i <= numOfObjects; i++)
{
if(!objects[i].locked)
{
lastFound = i;
i = numOfObjects + 1;
}
}
if(lastFound == -1)
{
numOfIndexedShapes = numOfIndexedShapes + 1;
indexedInShape.push_back(currentShapeIndex);
currentShapeIndex = -1;
}
else
{
objects[lastFound].endIndexShape();
}
}
void object::addLastIndexCoord(int theCoord)
{
int lastFound = -1;
for(int i = 0; i <= numOfObjects; i++)
{
if(!objects[i].locked)
{
lastFound = i;
i = numOfObjects + 1;
}
}
if(lastFound == -1)
{
indexedCoords.push_back(theCoord);
currentShapeIndex = currentShapeIndex + 1;
}
else
{
objects[lastFound].addLastIndexCoord(theCoord);
}
}
void object::addLastIndexTextureCoord(int theCoord)
{
int lastFound = -1;
for(int i = 0; i <= numOfObjects; i++)
{
if(!objects[i].locked)
{
lastFound = i;
i = numOfObjects + 1;
}
}
if(lastFound == -1)
{
indexedTextureCoords.push_back(theCoord);
}
else
{
objects[lastFound].addLastIndexTextureCoord(theCoord);
}
}
int object::getTotal()
{
int total = -1;
int lastFound = -1;
for(int i = 0; i <= numOfObjects; i++)
{
total = total + objects[i].getTotal();
}
total = total + numOfObjects + 1;
return total;
}
string object::output()
{
stringstream theStream;
if(id != -1)
{
theStream <<
tier <<
"\n" <<
id <<
"\n" <<
transX <<
" " <<
transY <<
" " <<
transZ <<
"\n" <<
angle <<
" " <<
rotX <<
" " <<
rotY <<
" " <<
rotZ <<
"\n";
theStream << numOfIndexedShapes << "\n";
for(int i = 0; i <= numOfIndexedShapes; i++)
{
theStream << indexedInShape[i] << "\n";
for(int x = 0; x < indexedInShape[i]; x++)
{
theStream << coords[indexedCoords[0]] << " ";
theStream << textureCoords[indexedCoords[0]] << "\n";
vector<int>::iterator it = indexedCoords.begin();
indexedCoords.erase(it);
}
/*
* if(indexedInShape[i] != -1) { theStream << coords[indexedCoords[0]] << "\n";
* theStream << textureCoords[indexedCoords[0]] << "\n";
* vector<int>::iterator it=indexedCoords.begin();
* indexedCoords.erase(it);
* }
*/
}
}
for(int i = 0; i <= numOfObjects; i++)
{
theStream << objects[i].output();
}
string tempString = theStream.str();
return tempString;
}mainFile.cpp
Code:
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include "object.hpp"
using namespace std;
char *fileNameRead;
char *fileNameWrite;
char *tempString;
char tempChar;
ofstream writeFile;
char theNumbers[10];
int tier;
object parent;
int parseInt(char *theString)
{
int theNumber = 0;
int theLength = strlen(theString) - 1;
bool isNegative = 0;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if(theString[0] == '-')
{
isNegative = 1;
for(int i = 0; i < theLength; i++)
{
theString[i] = theString[i + 1];
}
theLength = theLength - 1;
}
int tempNum = 10;
for(int x = 0; x <= theLength; x++)
{
for(int i = 0; i <= 9; i++)
{
if(theString[x] == theNumbers[i])
{
for(int z = 0; z <= theLength - x - 1; z++)
{
tempNum = tempNum * 10;
}
theNumber = theNumber + (i * (tempNum / 10));
tempNum = 10;
}
}
}
if(isNegative)
{
theNumber = theNumber * -1;
}
return theNumber;
}
int main()
{
theNumbers[0] = '0';
theNumbers[1] = '1';
theNumbers[2] = '2';
theNumbers[3] = '3';
theNumbers[4] = '4';
theNumbers[5] = '5';
theNumbers[6] = '6';
theNumbers[7] = '7';
theNumbers[8] = '8';
theNumbers[9] = '9';
string entered;
tier = -1;
cout << "Enter a filename to be converted. \n";
cin >> entered;
fileNameRead = new char[entered.length() + 1];
for(int i = 0; i <= entered.length(); i++)
{
fileNameRead[i] = entered[i];
}
char fileNameWrite[entered.length() + 2];
for(int i = 0; i <= entered.length() - 4; i++)
{
fileNameWrite[i] = entered[i];
}
fileNameWrite[entered.length() - 3] = 'm';
fileNameWrite[entered.length() - 2] = 'e';
fileNameWrite[entered.length() - 1] = 's';
fileNameWrite[entered.length()] = 'h';
fileNameWrite[entered.length() + 1] = '\0';
tempString = new char[100];
writeFile.open(fileNameWrite);
FILE *readFile = fopen(fileNameRead, "r+t");
if(readFile)
{
cout << "opened file " << fileNameRead << "\n";
bool done = 0;
while(fscanf(readFile, "%s", tempString) != -1)
{
if(tempString[0] == '#')
{
cout << "found '#' (useless)\n";
while((tempChar = fgetc(readFile)) != '\n')
{ }
}
else if(!strcmp(tempString, "DEF"))
{
cout << "got DEF\n";
char theName[100];
fscanf(readFile, "%s", theName);
fscanf(readFile, "%s", tempString);
if(!strcmp(tempString, "Transform"))
{
while((tempChar = fgetc(readFile)) != SRB)
{ }
tier = tier + 1;
cout << "got transform '" << theName << "' at tier " << tier << "\n";
parent.makeNew();
parent.setLastName(theName);
parent.setLastTier(tier);
while(!done)
{
fscanf(readFile, "%s", tempString);
if(!strcmp(tempString, "translation"))
{
double tempX;
double tempY;
double tempZ;
fscanf(readFile, "%lf", &tempX);
fscanf(readFile, "%lf", &tempY);
fscanf(readFile, "%lf", &tempZ);
cout << "translation: " << tempX << ", " << tempY << ", " << tempZ << "\n";
parent.setLastTranslation(tempX, tempY, tempZ);
}
/* end translation if */
else if(!strcmp(tempString, "rotation"))
{
double angle;
double tempX;
double tempY;
double tempZ;
fscanf(readFile, "%lf", &angle);
fscanf(readFile, "%lf", &tempX);
fscanf(readFile, "%lf", &tempY);
fscanf(readFile, "%lf", &tempZ);
cout << "rotation: " << angle << ", " << tempX << ", " << tempY << ", " << tempZ << "\n";
parent.setLastRotation(angle, tempX, tempY, tempZ);
}
/* end rotation if */
else if(!strcmp(tempString, "children"))
{
cout << "got child\n";
while((tempChar = fgetc(readFile)) != '[')
{ }
done = 1;
}
/* end children if */
else if(!strcmp(tempString, DLB))
{
done = 1;
}
/* end ending if */
else
{
cout << "error! tempString: " << tempString << "\n";
}
/* if error */
}
done = 0;
}
else if(!strcmp(tempString, DLB))
{
done = 1;
}
else
{
cout << "error! tempString: " << tempString << "\n";
}
}
else if(!strcmp(tempString, "]"))
{
cout << "ended child\n";
}
else if(!strcmp(tempString, DLB))
{
cout << "ended tranform\n";
parent.lockLast();
}
else if(!strcmp(tempString, "Shape"))
{
cout << "got shape\n";
while((tempChar = fgetc(readFile)) != SRB)
{ }
while(!done)
{
fscanf(readFile, "%s", tempString);
if(!strcmp(tempString, DLB))
{
done = 1;
}
else if(!strcmp(tempString, "appearance"))
{
while(!done)
{
fscanf(readFile, "%s", tempString);
if(!strcmp(tempString, DLB))
{
done = 1;
}
else if(!strcmp(tempString, "material"))
{
while((tempChar = fgetc(readFile)) != SLB)
{ }
}
}
done = 0;
}
else if(!strcmp(tempString, "geometry"))
{
while(!done)
{
fscanf(readFile, "%s", tempString);
if(!strcmp(tempString, "ccw"))
{
fscanf(readFile, "%s", tempString);
}
else if(!strcmp(tempString, "solid"))
{
fscanf(readFile, "%s", tempString);
}
else if(!strcmp(tempString, "creaseAngle"))
{
fscanf(readFile, "%s", tempString);
}
else if(!strcmp(tempString, "coord"))
{
while((tempChar = fgetc(readFile)) != SRB)
{ }
while(!done)
{
fscanf(readFile, "%s", tempString);
if(!strcmp(tempString, DLB))
{
done = 1;
}
else if(!strcmp(tempString, "point"))
{
while((tempChar = fgetc(readFile)) != '[')
{ }
char coordPoint[13];
coordPoint[0] = '\0';
int currentIndex = 0;
tempChar = fgetc(readFile);
if(tempChar != ' ')
{
coordPoint[currentIndex] = tempChar;
currentIndex = currentIndex + 1;
}
bool wasUseless = 0;
while((tempChar = fgetc(readFile)) != ']')
{
if(tempChar == ',' || tempChar == ' ')
{
coordPoint[currentIndex] = '\0';
currentIndex = 0;
if(!wasUseless)
{
parent.addLastCoord(coordPoint);
}
wasUseless = 1;
}
else if(tempChar == '\n')
{ }
else
{
coordPoint[currentIndex] = tempChar;
currentIndex = currentIndex + 1;
wasUseless = 0;
}
}
}
}
done = 0;
}
else
{
cout << "error! tempString: " << tempString << "\n";
}
}
done = 0;
}
}
done = 0;
}
else
{
cout << "error! tempString: " << tempString << "\n";
}
}
done = 0;
}
else
{
cout << "could not open input file\n";
}
writeFile << parent.getTotal() << "\n";
writeFile << parent.output();
int theInteger;
cin >> theInteger;
}All files (and a .wrl file containing a cube and a cone) can be found at http://www.wyrmmage.com/wrl/
The code isn't very robust, so I'll go ahead and list its most obvious erros here:
If your object name has a '{', '}', '[', or ']' in it, the program will probably die.
Only translations, rotations, and objects are supported (no nurbs, etc.)
If your object is not textured, the program will die.
Lighting, crease angles, materials, etc. will be ignored.
No animation parsing code is in there because it probably wouldn't be very helpful, and I haven't gotten around to writing the code that I'm going to use for animation anyway XD
Hope this helps some people

-wyrmmage
(I haven't compiled this on the Mac, but it should work, and it works fine on Windows)
Worlds at War (Current Project) - http://www.awkward-games.com/forum/
Indentation!!!!
meh, fine...I'll put some indentation in; don't know how you guys can stand that stuff, though.... *shudders* 
-wyrmmage

-wyrmmage
Worlds at War (Current Project) - http://www.awkward-games.com/forum/
Um, the *usual* rule with indentation is that the closing brace is at the same level of indentation as the opening one... maybe that's why you have an inexplicable objection to it
ya, I know...I just wrote a simple little script that indents my code for me, that's why it's so bad looking 
I'll see if I can make it so that that doesn't happen.
-wyrmmage

I'll see if I can make it so that that doesn't happen.
-wyrmmage
Worlds at War (Current Project) - http://www.awkward-games.com/forum/
wyrmmage Wrote:ya, I know...I just wrote a simple little script that indents my code for me, that's why it's so bad looking
I'll see if I can make it so that that doesn't happen.
-wyrmmage
http://www.hmug.org/man/1/indent.php
ok, I indented the script for you guys 
-yrmmage

-yrmmage
Worlds at War (Current Project) - http://www.awkward-games.com/forum/

