Not logged in, Join Here! or Log In Below:  
 
News Articles Search    
 

 Home / 3D Theory & Graphics / 3DS Model Interface :: Advice Account Manager
 
Archive Notice: This thread is old and no longer active. It is here for reference purposes. This thread was created on an older version of the flipcode forums, before the site closed in 2005. Please keep that in mind as you view this thread, as many of the topics and opinions may be outdated.
 
Skirmish

March 28, 2005, 07:11 AM

-Background-
I wrote a model class (3ds) some time ago wrapped it in a little app which I posted as an IOTD (http://www.flipcode.com/cgi-bin/fcarticles.cgi?show=65236). A couple of my friends as well as a few flipcoders have asked if I can provide the model classes (one each for GL/DX) for them to use.

-Problem-
I didn't design the classes with broader use in mind (I know, bad me). Instead I have provided functions to animate and render the model as a whole. This just won't cut it for general use though. At the very least I need to add the following functionality:
- ability to find objects/nodes by string name
- ability to render and animate individual objects/nodes
- ability to set material, alpha etc before each object/node is rendered
- ability to set shaders (have only used Cg to date personally)

-Ideas-
1. Expose all the helper functions and let the user handle the entirity of the render. This would mean that the user would need to know about all of the animation nodes. There is at least one node per object. Many nodes can exist for a single object eg a car may have only a single wheel mesh but 4 animations nodes may exist to render the wheel at each corner with the correct translation. The nodes are of course hierarchical.

This method could get very complex for the user, not the least because they would need to provide their own recursive functions to render the hierarchy.

2. Allow the user to register callback functions for each of the above functionality with the return code controlling the models response (eg returning TRUE for DrawNode would tell the model not to render that node). This approach would remove some of the flexibility for the user but would be much simpler to use. I would probably use function pointers instead of functors.

-Questions-
What other functionality is commonly provided/used by other people's model classes?

Of my two ideas, which sucks less? Alternatively feel free to propose a method that craps over both of them.

 
skullbonez

March 28, 2005, 07:15 PM

Yes - I NEED your loader for the game I am making this year, mainly because I know it is code I can trust and I know it is the best 3ds loader out there.

I would be inclined to ask you if you could make a simple wrapper class for the loader - make it so you create the object though a simple call to something like:

Constructor(char* fileName)

and the class can then contain accessors to nodes/objects etc.

Make it simple, so keyframe animation can be accessed simply like this:

Class::DrawAnimationFrame(int frameNumber)

Then when it comes to drawing the verts of the model for GL or DX to render, you should just be able to say

Class::DrawDefaultModel(void)

It would be great if you made it simple like this so gumbies like me can just load a model and use it - then you could make all of the model data public so it also allows the advanced programmers to access the model nodes etc.

Make it so you simply instantiate one object per model loaded - that way you could have models independant of each other loaded in the scene, moving about being drawn between translations, rotations and scales - that would be so simple to use!

Also, it would be good if you could build some basic methods into the class like Class::GetLowestVert(void) which would return the y value of the lowest vertex on the model (for basic coldet), and overload it with Class::GetLowestVert(int frameNumber)

I think simplicity is the way to go if you can wrap it all up - look at the OpenGL API - so concise - people are comfortable using it - more people will use your library if you make it easy to use too...

 
t2k

April 03, 2005, 04:10 PM

I'm interested in an API that does not concern itself with drawing the model/scene/etc, but focuses more on efficiently exposing the contents of the .3ds files. So, a class heirarchy seems desireable

class I3DSObject
class I3DSKeyframe
class I3DSAnimationNode
class I3DSTexture
class I3DSMaterial

class I3DSReader
{
virtual int LoadFile(const char *filename);
virtual I3DSObject *GetObject(const char *name)
virtual I3DSTexture *GetTexture(const char *name)
virtual I3DSMaterial *GetMaterial(const char *name)
virtual I3DSAnimationNode *GetAnimationNode(const char *name)
virtual int GetObjectNames(some list structure here)
virtual int GetMaterialNames(some list structure here)
virtual int GetTextureNames(some list structure here)
virtual int GetAnimationNodeNames(some list structure here)
}

I don't know exactly what kind of classes/objects are necessary to expose, but at a minimum something similar to this would go a long way:
class I3DSFace
{
virtual int *GetTriangleIndices() = 0;
virtual I3DSMaterial *GetFaceMaterial() = 0;
}

class I3DSObject
{
virtual int GetNumVertices() = 0;

virtual vec3 *GetVertexData() = 0;
virtual vec3 *GetVertexNormalData() = 0;
virtual vec2 *GetTextureCoordData() = 0;

virtual int GetNumFaces() = 0;
virtual I3DSFace *GetFaces() = 0;

virtual void GetBoundingRect(vec3 &outMin, vec3 &outMax) = 0;
}

this may seem like a lot of work, but having your code do all the drawing internally ends up requiring a lot of work too because at least for OpenGL you have to be carefuly about sharing the texture namespace with the rest of the application that is calling your code, careful about sharing the matrix state and the rest of the opengl state too. D3d is perhaps less of a problem if you're just going to draw everything internally, but either way you'd need at a minimum some way to start/stop animations and render the scene at an arbitrary time:

class I3DSRenderer
{
virtual int LoadFile(const char *filename) = 0;
virtual int GetAnimationNames(some output list structure) = 0;
virtual int StartAnimation(const char *name) = 0;
virtual int StopAnimation(const char *name) = 0;
virtual int GLRender(int frameNum, double frameTime) = 0;
};

what do you think?

Honestly I think the greatest strengh of your code is that it succesfully loads and interprets .3ds files - anyone can tack a renderer onto that because rendering is a much more widely known and accessible process to the rest of us. All the work you did decoding the file format and testing tons of .3ds files... thats what really attracted me to your work.

trey

 
This thread contains 3 messages.
 
 
Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.