GPWiki.org
GPWiki.org
It is currently Fri May 24, 2013 12:49 am

All times are UTC




Post new topic Reply to topic  [ 8 posts ] 
Author Message
PostPosted: Sun May 06, 2007 7:45 pm 
Level 22 Norse Warrior-Librarian
User avatar

Joined: Mon Sep 04, 2006 5:25 pm
Posts: 517
Location: U.S.
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:
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();
};

#endif


object.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
Ganadu'r, The Eternal Sage (Other Current Project) - http://rpg.naget.com
Programming tutorials and web-design services: http://www.wyrmmage.com


Last edited by wyrmmage on Mon May 07, 2007 9:05 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Mon May 07, 2007 7:33 am 
Babirusa
User avatar

Joined: Thu Aug 19, 2004 2:55 pm
Posts: 9241
Location: The Netherlands
Nice, but isn't it easier to zip up those source files instead of putting it in a forum message, losing markup )layout) and everything? :)

It might be useful for people who want to import wrl objects, pretty neat.

_________________
Serious game developer

http://www.persistentrealities.com
http://www.persistentrealities.com/vbfibre
http://www.ambiances.nl


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 07, 2007 1:46 pm 
13375p34k3r
User avatar

Joined: Tue Dec 06, 2005 3:54 pm
Posts: 1420
Location: A Nation inside a Nation.
The (lack of) indentation--it burns!

And if you're making a parser, why didn't you use bison or antlr or spirit or othe of the myriad other parser generators?

_________________
Hlade's Law: If you have a difficult task, give it to a lazy person -- they will find an easier way to do it.


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 07, 2007 9:06 pm 
Level 22 Norse Warrior-Librarian
User avatar

Joined: Mon Sep 04, 2006 5:25 pm
Posts: 517
Location: U.S.
Ok, I updated the code with indentation, and I should have a zipped version on my server available soon (wyrmmage.com/wrl/).
Why didn't I use on of the parser generators? Well, I didn't know that they existed :P Guess I will next time, though, so thanks :)
-wyrmmage

_________________
Worlds at War (Current Project) - http://www.awkward-games.com
Ganadu'r, The Eternal Sage (Other Current Project) - http://rpg.naget.com
Programming tutorials and web-design services: http://www.wyrmmage.com


Last edited by wyrmmage on Mon May 07, 2007 9:08 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Mon May 07, 2007 9:07 pm 
Babirusa
User avatar

Joined: Thu Aug 19, 2004 2:55 pm
Posts: 9241
Location: The Netherlands
Thanks! :)

_________________
Serious game developer

http://www.persistentrealities.com
http://www.persistentrealities.com/vbfibre
http://www.ambiances.nl


Top
 Profile  
 
 Post subject: Thank you
PostPosted: Thu Sep 30, 2010 12:50 pm 
Am very interested in it, so can you comment it please?
I think I need to make it parse objects without texture too.
I'll test the code on a Visual C++ project. Hope it works with me.
Thank you


Top
  
 
 Post subject: Errors!
PostPosted: Thu Sep 30, 2010 2:17 pm 
I tested it on the example that you joined. But this is what I've got :

Image

Some help :\


Top
  
 
 Post subject:
PostPosted: Sat Oct 02, 2010 3:44 am 
Level 22 Norse Warrior-Librarian
User avatar

Joined: Mon Sep 04, 2006 5:25 pm
Posts: 517
Location: U.S.
Ah, man, I haven't seen this code in a long time! :)

Would you mind posting the full error log? It's a bit hard to tell where things went wrong from the screenshot.

_________________
Worlds at War (Current Project) - http://www.awkward-games.com
Ganadu'r, The Eternal Sage (Other Current Project) - http://rpg.naget.com
Programming tutorials and web-design services: http://www.wyrmmage.com


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group