Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411587 Posts in 69386 Topics- by 58443 Members - Latest Member: Mansreign

May 06, 2024, 09:01:54 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Loading 3D Files
Pages: [1]
Print
Author Topic: Loading 3D Files  (Read 2286 times)
Aik
Level 6
*


View Profile
« on: May 30, 2009, 06:06:18 AM »

I've been using this tutorial to try and get a .3ds loader up and running, and thus far everything's borked.

The initial problem was that a .3ds file exported using 3ds Max 8 didn't seem to have any data for the faces chunk. I only realised it was the file rather that my code that wasn't working when I used Blender to export a .3ds file and suddenly - faces data!

Unfortunately, this faces data seems to be rubbish - far too many digits for what I'm meant to be using it for.

The code in the tutorial files relies on the faces data when creating the triangles in openGL, but with the large digits it's well out of the array bounds. At the moment I very vaguely get the shape I want without using them, but it's nowhere near correct. I'm pretty sure my loading code for the .3ds files is correct - I've gone over it a hundred times and it's basically just what the tutorial says.

Soooo - any thoughts at all? I can't afford to spend much more time on this part, so if I can't get it working soon the game will just have to be about shooting down cubes instead of teapots, but I'd quite like it to work.

Alternatively, if anyone knows of a file loader (of whatever format, though one natively supported by 3ds Max would be nice) that I can just add to my project (no linking) and have it work without any dicking around, I will quite gladly jump ship Smiley
Logged
Ivan
Owl Country
Level 10
*


alright, let's see what we can see


View Profile
« Reply #1 on: May 30, 2009, 08:05:08 AM »

Check out this list and see which one you like best, MAX should export many of these:

(3DS and OBJ would be the best choices, though you're already doing 3DS)

http://www.wotsit.org/list.asp?fc=2

EDIT: Here's an OBJ loader for opengl
http://sourceforge.net/projects/objloader/


Alternatively, you can check out OGRE3D's mesh format which has an XML-based version that's very easy to load.
« Last Edit: May 30, 2009, 08:09:38 AM by Ivan » Logged

http://polycode.org/ - Free, cross-platform, open-source engine.
Snakey
Level 2
**


View Profile WWW
« Reply #2 on: May 30, 2009, 01:30:16 PM »

If you post some of your code up it would be handy to see what you're doing. I've tested the code on this website before and it has worked just fine for me.
Logged

I like turtles.
nihilocrat
Level 10
*****


Full of stars.


View Profile WWW
« Reply #3 on: May 30, 2009, 01:51:24 PM »

Alternatively, you can check out OGRE3D's mesh format which has an XML-based version that's very easy to load.

I can vouch for the coolness of OGRE3D's XML format. Having a human-legible intermediate format for things is really handy, as it's not hard to review exported meshes to see if they got exported right (this is how I discovered, for example, the Wings3D -> OGRE XML exporter wasn't preserving materials or vertex colors correctly) and it's seemingly easy to create an importer to read in the XML.
Logged

Aik
Level 6
*


View Profile
« Reply #4 on: May 30, 2009, 03:50:24 PM »

Thanks Snakey - I'd love to not have to throw out the code just because I've spent so much time debugging the damn thing.

Here's the specific bit of code that's having the problems (to summarise: doesn't run when using Max exported files, gives weird numbers when using Blender exported files).
Code:
           //face description
            case 0x4120:
            {
                fread(&quantity, sizeof(unsigned short), 1, file);
                object->numOfPolygons = quantity;

                for (int i = 0; i < quantity; i++)
                {
                    Poly p;

                    fread(&p.a, sizeof(unsigned short), 1, file);
                    fread(&p.b, sizeof(unsigned short), 1, file);
                    fread(&p.c, sizeof(unsigned short), 1, file);
                    fread(&faceFlags, sizeof(unsigned short), 1, file);

                    object->polygons.push_back(p);
                }
                break;
            }

And here's the entire file loading method:

Code:
void T3dsLoader::loadFile(T3DObject_ptr object, string filename)
{
    unsigned short chunkID;
    unsigned int chunkLength;
    unsigned char character;
    unsigned short quantity;
    unsigned short faceFlags;

    FILE *file;
    file = fopen(filename.c_str(), "rb");
    if (file == NULL) return;

    while (ftell(file) < fileLength(fileno(file)))
    {
        fread(&chunkID, 2, 1, file);
        fread(&chunkLength, 4, 1, file);

        switch(chunkID)
        {
            //main chunk
            case 0x4d4d:
                break;

            //3D editor chunk
            case 0x3d3d:
                break;

            //object chunk
            case 0x4000:
            {
                char name[20];
                int i = 0;
                do
                {
                    fread(&character, 1, 1, file);
                    name[i] = character;
                    i++;
                } while (character != '\0' && i < 20);
                object->name = name;
                break;
            }

            //triangular mesh
            case 0x4100:
                break;

            //vertices list
            case 0x4110:
            {
                fread(&quantity, sizeof(unsigned short), 1, file);
                object->numOfVertices = quantity;

                for (int i = 0; i < quantity; i++)
                {
                    Vertex v;

                    fread(&v.x, sizeof(float), 1, file);
                    fread(&v.y, sizeof(float), 1, file);
                    fread(&v.z, sizeof(float), 1, file);

                    object->vertices.push_back(v);
                }
                break;
            }

            //face description
            case 0x4120:
            {
                fread(&quantity, sizeof(unsigned short), 1, file);
                object->numOfPolygons = quantity;

                for (int i = 0; i < quantity; i++)
                {
                    Poly p;

                    fread(&p.a, sizeof(unsigned short), 1, file);
                    fread(&p.b, sizeof(unsigned short), 1, file);
                    fread(&p.c, sizeof(unsigned short), 1, file);
                    fread(&faceFlags, sizeof(unsigned short), 1, file);

                    object->polygons.push_back(p);
                }
                break;
            }

            //mapping coordinates list
            case 0x4140:
            {
                fread(&quantity, sizeof(unsigned short), 1, file);
                for (int i = 0; i < quantity; i++)
                {
                    MapCoord mc;

                    fread(&mc.u, sizeof(unsigned short), 1, file);
                    fread(&mc.v, sizeof(unsigned short), 1, file);
                }
                break;
            }

            default:
                fseek(file, chunkLength-6, SEEK_CUR);
        }

    }
    fclose(file);
}

And here are two of the .3ds files that I'm using to test: 3DSMax teapot, Blender monkey.
Logged
Impossible
Level 3
***



View Profile
« Reply #5 on: May 30, 2009, 11:58:41 PM »

I had luck with the OBJ loader that toasted linked, its pretty clean, straight forward and easy to use. It also does not require usage of OpenGL despite the name, I integrated it into a D3D app.

You might also want to look at the FBX SDK. It supports FBX, 3DS, OBJ and Collada file loading and saving through a common interface. It will be harder to use than a simple mesh file loader, but should be easier than writing a custom exporter for your favorite 3D app(s).
Logged
increpare
Guest
« Reply #6 on: May 31, 2009, 04:07:10 AM »

I wrote an obj loader before, though it was tailored to the particular meshes that I was importing (and, needless to say, useless for animated objects).  I'm planning on using the FBX library for my next thingy, because I need more than I can easily write exporters/importers for myself [skeletal stuff].  (though ogre, now that I look at it, is indeed quite tempting)
Logged
Snakey
Level 2
**


View Profile WWW
« Reply #7 on: May 31, 2009, 04:22:40 AM »

The main problem with the 3DS format is that if the binary is in any order other than what is expected, then the sequential reading will simply fail and not work. Thus if 3DSMax has changed the binary output ever so slight, then you'll be out of luck.

The problem with this of course, is that perhaps your 3DS files contain some random chunks of data which your code isn't handling. There are a lot of chunk data in 3DS meshes, more so than what is explained here. I think from memory, I had to include some extra chunk implementations.
Logged

I like turtles.
Aik
Level 6
*


View Profile
« Reply #8 on: May 31, 2009, 03:13:01 PM »

Eurch - sounds awful. When I turn this project into something interesting, I'll definately look into some other file format and loaders suggested.

Right now, I just realised how imminently due 'this Friday' actually means, and am going to stop working on irrelevant parts and get working on the stuff that's actually going to get me marks :p
Logged
David Pittman
Level 2
**


MAEK GAEM


View Profile WWW
« Reply #9 on: May 31, 2009, 03:25:46 PM »

The main problem with the 3DS format is that if the binary is in any order other than what is expected, then the sequential reading will simply fail and not work. Thus if 3DSMax has changed the binary output ever so slight, then you'll be out of luck.

The problem with this of course, is that perhaps your 3DS files contain some random chunks of data which your code isn't handling. There are a lot of chunk data in 3DS meshes, more so than what is explained here. I think from memory, I had to include some extra chunk implementations.

Aren't chunked file formats designed specifically to avoid this problem? That is, you can verify that the chunk length is what you're expecting and skip badly-sized or unexpected chunks without just bailing out of the whole routine. It's been a while since I messed with .3ds (yay Blender Python exporting!) but that's what I recall.
Logged

Snakey
Level 2
**


View Profile WWW
« Reply #10 on: June 01, 2009, 03:13:40 PM »

That's true to some extent, but you may need to read all chunk headers not just a select few. If a chunk happens to be more than 6 in length and you don't intepret it, you wind up in the middle of the chunk's data rather than skipping it.
Logged

I like turtles.
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic