gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > Lost with 3D models...

#162392 - sarachiel - Mon Sep 01, 2008 9:08 pm

Hi everyone,

I am currently working on a homebrew that will be my "end-of-year project" (2009) in my school. This is a serious project; i'm not one of those kids who thinks he can do a game just by clicking there and here. I really can't find anything that can help me to uderstand how to use 3D models, so I hope some of you guys can.

I am a bit lost with this. I understood, from the libnds examples, that I can use opengl display_lists from .bin files. However I can't find any database where some nice examples of models are available. I tried to use Blender to make some models but nothing good came out of this.
The other thing that really bothers me, is how to animate my models. Shall I do one display_list for each frame of each animation of each model ? Should I use hardware transformations ? I really can't see where to start with this.
Finally, are textures as easy to use as in the Nehe examples ? How do I create textures ? Do I have to do it in Blender / Maya / 3DSmax too ? And are they also exported in the .bin file ?

Thank you all for enlightning me on this. If there was a similar thread that dealt with this subject before, excuse me for not having browse the forum enough.

#162394 - DekuTree64 - Mon Sep 01, 2008 10:27 pm

Are you wanting to do bones/skinning, or just segmented models? Segmented it much easier to start, but after you have that working, skinning is easy to understand. And have you done any 3D modelling and animating before? If not, I highly recommend building a simple character, even just a stick man, and animating a walk cycle or someting to get an idea what kind of data you're working with.

Generally a character will be built from a bunch of small meshes (e.g. torso, neck, head, left upper arm, left forearm, left hand, right thigh, right shin, right foot, and so on), all glued together in a nice hierarchy so for example rotating the thigh pulls the shin and foot along with it.

Animation can either be done by storing keyframes as needed for the translation/rotation/scale of each mesh, or by storing the absolute translation/rotation/scale for every mesh on every frame. 3D animations are generally created using keyframes, so you can get an idea how they work just by animating something. For the DS, it's probably better to store every frame, so you don't have to spend CPU cycles doing the interpolation between keyframes. It's still much less data than generating new display lists for every frame, and it can be compressed easily since a lot of it doesn't change frequently.

I can't say much for textures since the only 3D modeller I've used has terrible UV mapping tools, so I'm not sure how the normal workflow should go. But you'll normally be drawing textures in a seperate 2D art program. And for getting the textures onto the DS, you could either build them into your model file format, store them as seperate files and have the model reference them by filename, or whatever you want.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#162395 - TwentySeven - Mon Sep 01, 2008 11:02 pm

It's all about Tools, tools and more tools.

You'll need something industrial strength. Get the trial of 3dsmax 2008.

It exports a couple of ascii formats like .ase, and has lots of free models available.

I recommend you write a program for your PC that can load/parse .ase models, or whatever format you want to go with, and draw them using openGL or Direct3D. There is a heck of alot more documentation (and examples!) for doing this then there is for doing the equivilant on the DS hardware.

Once you can draw what you want using OpenGL, you'll need to write out a format the DS can digest a little easier. Display lists are pretty hairy to debug, personally I'd just go with vertex and index lists and render the model using standard gl-style draw calls.

#162397 - nce - Tue Sep 02, 2008 1:28 am

Well I guess one order to learn thinks are :

use a 3d program and export data for a static mesh ( I do my exporter in maxscript ) and load them in the ds in direct mode

you'll probably have to fight quite a lot already to get that working properly ( specially the uv )

http://forum.gbadev.org/viewtopic.php?t=14478
http://forum.gbadev.org/viewtopic.php?t=14577

if you need some extra speed you'll probably have to learn how to make a triangle strip while exporting

Once you get that working you can either looking in calllist or if the speed is not a big issue you can continue in direct mode

you can then start to look to animate your model. You'll have to be familliar with matrix computation to export bones animations and use the matrix stack of the ds ( that allows you to do a 'cheap' rigid skin )

http://forum.gbadev.org/viewtopic.php?t=14221

And if you really need nice blending between animation, additive animation or anything fancy, you'll have to start using quaternion...
_________________
-jerome-

#162398 - DensitY - Tue Sep 02, 2008 2:06 am

TwentySeven wrote:
It's all about Tools, tools and more tools.

You'll need something industrial strength. Get the trial of 3dsmax 2008.

It exports a couple of ascii formats like .ase, and has lots of free models available.

I recommend you write a program for your PC that can load/parse .ase models, or whatever format you want to go with, and draw them using openGL or Direct3D. There is a heck of alot more documentation (and examples!) for doing this then there is for doing the equivilant on the DS hardware.

Once you can draw what you want using OpenGL, you'll need to write out a format the DS can digest a little easier. Display lists are pretty hairy to debug, personally I'd just go with vertex and index lists and render the model using standard gl-style draw calls.


Pretty much agree with this here, esp getting the model rendered on PC first before working on converting it over to the DS which is going to introduce a bit more work.

#162405 - sarachiel - Tue Sep 02, 2008 9:09 am

I tank you all for these precious advices.
I already managed to render a model on PC with OpenGl. That was no big deal with all those libs that do it by themselves, which is why I chose to dev on DS actually :)
I guess i'll start generating those .bin files, then have textures on my models.

I still can't really see how i will deal with animations, everything in this seems wrong to me. Having a .bin file for each frame might take too much space on the DS cartridge, doesn'it ?
Oh well, I guess i'll see that later. Thank you all again.

#162411 - TwentySeven - Tue Sep 02, 2008 1:45 pm

Honestly, no. If you just store the vertex and normal data per frame in DS sized formats (fixed point, packed), it's really not too fat.

I have some small player models (about 500 verts) and they pack down to about 12kb a frame.

#162425 - tepples - Tue Sep 02, 2008 8:14 pm

But compare that to half a KB per frame for 2D sprites.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#162431 - sajiimori - Tue Sep 02, 2008 10:07 pm

Yeah, using bones will get you back down to half a KB per frame for a 500 poly model. (Exact values vary, obviously.)

#162435 - sarachiel - Tue Sep 02, 2008 11:10 pm

What is exactly that you call 'bones' ? Some kind of stickman that you move and on which you 'paste' meshes ? I did not manage to find a nice tutorial on the methods people mentioned here, so it just gets me confused :S

I plan to have around 20 or 30 different models if i have the time to do it all. I guess having a file for each frame will be too heavy for that. I just don't have time to study it all in a day. Damn work... ><

#162438 - silent_code - Tue Sep 02, 2008 11:46 pm

This may take months or even years to get right. It's quite complex, especially, for unexperienced people. So, get prepared to rethink your needs, if you have an assignment.
Btw: There's a ton of more or less good tutorials out there. Maybe you should take a look at Gamasutra or Gamedev or whatever. You read one mediocre tutorial and get the idea, you'll be able to do this.

Also, Milkshape + Roadkill (unwrapping freeware = blender's unwrapper) and some painting program are nice to have.

Enough advertising. Good luck. :^D
_________________
July 5th 08: "Volumetric Shadow Demo" 1.6.0 (final) source released
June 5th 08: "Zombie NDS" WIP released!
It's all on my page, just click WWW below.

#162657 - M3d10n - Sun Sep 07, 2008 6:19 pm

There are 3 major ways to handle animation (listed from the simplest to the most complex): hierarchical, per-vertex and skeletal.

In hierarchical animation your models are split in parts (torso, arms, forearms, hands, etc) which are arranged in a parent-child relationship (example: the torso is parent to the arm, that is parent to the forearm, that is parent to the hand). The children inherit the parent's transform, so if the arm rotates, the forearm and the hand go with it.

It is very straightforward to implement: you store the local transform (usually only rotation is enough, but translation and scale can be used for more complex animation) for each keyframe for each part. When rendering, you start with the root part, multiply its local transform on the MODELVIEW matrix, render, then traverse the hierarchy and do the same for each children. The limitation is that your models are likely to look like robots or wooden dolls. Each part is completely rigid and doesn't deform (like knees and elbows).

The per-vertex animation stores animation data for each vertex. So essentially you have a list of vertex positions (and maybe normals) for each keyframe. It can be very memory intensive, so all kinds of tricks are employed to reduce memory usage (storing deltas, compressing keyframes, etc). This one is a bit hard to export properly from authoring programs.

Skeletal animation is a mix of the two methods. You have an hierarchical skeleton, like in the first method, but you have each vertex of your mesh follow one (or more) bone(s). So, think of this as having each individual vertex being a child of a a bone. You can have each vertex also be affected by multiple joints (usually 2 or 3). The final vertex position is the weighted average position of the joints that affect it, but that uses more CPU, of course.

For all methods above you can reduce the amount of keyframes by using interpolation to achieve smooth animation without having as many keyframes as your framerate.

#162686 - sarachiel - Tue Sep 09, 2008 7:41 am

I appreciate your help. Thank you very much, I think I'll try the 3 of them asap :)

#162743 - sarachiel - Thu Sep 11, 2008 8:50 pm

Hey again.

I'm currently looking for a soft that converts 3d models to .bin files, those ones that are used in the libnds examples.

I managed to find 1 or 2 scripts here and there, that might be outdated. Is there some kind of 'reference', a widely used script/program for that purpose, that I should get instead of those that I found ? (They seem old, 2002 and 2004).

#162757 - M3d10n - Fri Sep 12, 2008 1:17 pm

Search for "display list". I remember at least two tools that converted models to displaylists and there was a very nice thread explaining how to create them.

You can copy a whole bunch of defines, macros and typedefs from libNDS and use them straight in a PC program to help creating the display lists.

Anyway, here's a summary: a display list (the .bin files) is a sequence of u32 values. You start with 4 commands packed into a 32-bit integer, then follows with the data for each command. Different commands require different amounts of data, so the commands you call determine how many u32's will come after the command (some commands don't need data at all). You can easily verify how much data each command uses by checking their corresponding immediate mode gl* functions.

For example, to convert the following immediate mode draw to a display list that could be used for glCallList:
Code:

   glBegin(GL_TRIANGLE);
   glColor(RGB15(31, 0, 0));
   glVertex3v16( 0, floattof32(1), 0 );
   glVertex3v16( floattof32(1), floattof32(-1), 0 );
   glVertex3v16( floattof32(-1), floattof32(-1), 0 );
   glEnd();


You'd need this:
Code:

u32 list[] = {
   10,
   FIFO_COMMAND_PACK(FIFO_BEGIN, FIFO_COLOR, FIFO_VERTEX16, FIFO_VERTEX16),
   GL_TRIANGLE,
   RGB15(31, 0, 0),
   VERTEX_PACK(0, floattof32(1)),
   0,
   VERTEX_PACK(floattof32(1), floattof32(-1)),
   0,
   FIFO_COMMAND_PACK(FIFO_VERTEX16, FIFO_END, FIFO_NOP, FIFO_NOP),
   VERTEX_PACK(floattof32(-1), floattof32(-1)),
   0
};


The first item in the array (10) is the actual length of the display list. It is used by glCallList to know how much data it needs to copy using DMA.

FIFO_COMMAND_PACK packs 4 commands into an entry. I packed the glBegin(), the glColor() and 2 glVertex3v16() calls. Then I need to provide the data for each command:

- GL_TRIANGLE is the data for FIFO_BEGIN
- RGB15(31, 0, 0) is the data for FIFO_COLOR
- Oops... the data for FIFO_VERTEX16 can't fit into a single u32! The data for the first FIFO_VERTEX16 is:
Code:

VERTEX_PACK(0, floattof32(1)),
0,

The vertex' X and Y are packed into the first u32, and Z goes alone on the next. So each FIFO_VERTEX16 needs two entries on the list.

- The second FIFO_COMMAND_PACK entry is there to call the remaining glVertex3v16() call and glEnd(). Since I only need two commands, I'll pad the rest with FIFO_NOP.
- Notice that glEnd doesn't need any data.

With that you can put together a small program that reads some 3D format and spits out basic display lists.

#162787 - sarachiel - Fri Sep 12, 2008 10:37 pm

Thank you for this explanation.
Well I managed to draw some strange things, but at least that works :)
I actually found later a python script for Blender, that exports a model to a .bin file, which is great since I'm a bit familiar with this software.
Just typed the right key-word on google ;) (VERTEX_PACK)

I am now working on textures, but I'm not really sure of what I'm doing, since this forum is kind of the only reliable source for 3d development on DS, and everyone is doing this a different way ^^
Every tutorial is at least 3 years old on this topic. I think I'll write some stuff when I am more familiar with everything.

#162900 - sarachiel - Mon Sep 15, 2008 9:58 pm

Hey people.

Didnt want to create another topic since this one is just fine.
I wondered if anyone ever played around with a blender model exporter like this one. http://grizzly.thewaffleiron.net/blender/

It's a nice tool, but I can't find how to export textures coordinates as well. I obviously miss something, but can't figure out what it is. I create new material and apply it to the mesh. Then I export it but there is no sign of "glTexCoord" in the generated display list.

I managed to make some nice animations and models. Only textures is missing :/

Oh, and is there something special to (re)initialize for the lights to work properly ? I put a light 'inside' a model, then move the model around with the arrows. Light doesnt move, but my model is still dark, why is that ?

#162985 - sarachiel - Wed Sep 17, 2008 9:12 pm

Little up cuz I am kinda blocked :(