Jump to content
  • Advertisement
Sign in to follow this  
PixelPhil

LWO loading and UVs

This topic is 4832 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I am currently implementing the lwo mesh loading feature in my engine. But unfortunately I can't get the UV to be loaded correctly and the result looks wrong like this: (this is supposed to be a dead imp like the one we can see in Doom3's demon museum) I use the C parser code provided in the Newtek SDK to read the file and to add uv coordinates to my vertexbuffer (verts) I use the following code.
for (lwVMap* vmap = layer->vmap; vmap; vmap = vmap->next)
{
   if (vmap->dim == 2) // texture coords
   {
       for (int i = 0; i < vmap->nverts; i++)
       {
           int index = vmap->vindex;
           float *values = vmap->val;
           verts[index].uv = D3DXVECTOR2(values[0], 1.0 - values[1]);
       }                 
   }
}
Here I only deal with 1 layer and my vmap contains as much values as I get vertices so I assume it is a bijection (no projected texture here). I tried to flip and swizzle u and v but didn't get a convincing result. I render using DirectX. I'd really appreciate some hints. Phil

Share this post


Link to post
Share on other sites
Advertisement
Yeah, I've got one working, but it's a plugin rather than an external loader:

(cut-and-paste code here. No attempt at cleaning it up for the forums)


void expMesh::ExportUVMaps( void )
{
int i;
uint a, j, p;

int numUVMaps = obj->numVMaps(LWVMAP_TXUV);
void *uvmap = AQ_NULL;

//Find valid UV maps (this is WAY more complicated than it needs to be >_<)
for (i = 0; i < numUVMaps; i++)
{
const char *uvname = AQ_NULL;
uvname = obj->vmapName(LWVMAP_TXUV, i);
if (uvname)
{
uvmap = meshInfo->pntVLookup( meshInfo, LWVMAP_TXUV, uvname );
for(j = 0; j < polys.Size(); j++)
{
for(p = 0; p < 3; p++)
{
aQVect2 uvtemp( 0.0f, 0.0f );

a = polys[j].index

;

//Check "discontinuous" UV maps first, then continuous
//If it's a discontinuous coord, then we'll have to create a new vertex to hold
//the correct UV. If you ask me this is just a plain fucked up design... *sigh*
if( meshInfo->pntVPIDGet( meshInfo, points[a].pid, polys[j].pid, uvtemp.GetPointer(), uvmap ) )
{
expPoint newPoint = points[a];

newPoint.uv = uvtemp;

polys[j].index

= points.Push( newPoint );
}
else if( meshInfo->pntVIDGet( meshInfo, points[a].pid, uvtemp.GetPointer(), uvmap ) )
{
points[a].uv = uvtemp;
}
}
}
}
}

if(expFlags & EXP_DEBUG)
{
InfoBox("UV Extraction Complete");
}

return;
}





Hope that helps some. I'm at work now, so I don't have much time to explain, but I'll try to post some more in-depth info when I have a free moment.

Share this post


Link to post
Share on other sites
This post cheers me up. Thanks.
Though I'm not quite sure what meshInfo->pntVPIDGet does... Any hints?
I don't recognises newtek's structures here though the are similar enough for me ta make the connection.

What is that constinuous/discontinuous thing?

EDIT: now I see that some polygons have a vmap and some don't and I understand that points are not doubled as they should be at texture seams. but I have a hard time putting it all together... This vmap mechanism is really a pain in the ...

Phil

[Edited by - PixelPhil on September 23, 2005 7:40:16 PM]

Share this post


Link to post
Share on other sites
Quote:
This vmap mechanism is really a pain in the ...


That really says it all right there. You're right in saying that the verticies aren't doubled up correctly in places where the texture breaks. More accurately: ther is only one "vertex" stored per unique position, and that vertex may have multiple texture coordinates associated with it. It's up to you as the exporter to bring the two togheter logically. (Which is really dumb if you ask me)

In this case they're stored as "continuous" and "discontinuous" mappings. A Continuous mapping is, for example, a point on your imp's head. All of the verticies around it have UV's that can interpolate directly from one point to another without breaking (hence the "continuous" bit). You will only ever have one continuous UV map per vertex, so it's "safe" to store that UV in the original vertex structure. This is what you are doing right now.

A Discontinuous map is essentially anywhere that there is a seam in the texture. These are a little more difficult to get at, but not too hard. The biggest difference is that while you only have to pass in a pointID to get a continous mapping, you must pass in both a polygonID AND a pointID to get a discontinous map. (Probably obvious, but the pointID you supply must be one of the points on that polygon.) If you do get a discontinous map coordinate, you'll have to create a duplicate of your current vertex with the new texture coordinates. Then adjust the index for that point within that polygon.

It's all a little strange to wrap your head around, but it eventually falls into place. Try looking through the code I posted again and you'll see how I handle this (polies and points both use a structure very similar to std::vector)

*sigh* I typed twice as much but I don't think I made any more sense... let me know if you have any other questions!

Share this post


Link to post
Share on other sites
Mmmm... things are getting clearer now though as i use the C version of the parser I don't have these two functions. pntVIDGet is quite straightforward (though it's a stupid inneficient linear search). But i don't see how to implement pntVPIDGet with the structures I got.

My structures are:


typedef struct st_lwVMap {
struct st_lwVMap *next, *prev;
char *name;
unsigned int type;
int dim;
int nverts;
int perpoly;
int *vindex; /* array of point indexes */
int *pindex; /* array of polygon indexes */
float **val;
} lwVMap;

typedef struct st_lwPolVert {
int index; /* index into the point array */
float norm[ 3 ];
int nvmaps;
lwVMapPt *vm; /* array of vmap references */
} lwPolVert;

typedef struct st_lwPolygon {
lwSurface *surf;
int part; /* part index */
int smoothgrp; /* smoothing group */
int flags;
unsigned int type;
float norm[ 3 ];
int nverts;
lwPolVert *v; /* array of vertex records */
} lwPolygon;


somehow pindex is NULL on the vmaps of the imp.

Phil

EDIT: Whooohooo! it works! I figured out that discontinuous and continuous UVs where stored in different lwVMap with the same name. Anyway, thanks for your precious help, you made my day. You might see something coming in the image of the day in a near future ;) Thanks. Phil

[Edited by - PixelPhil on September 24, 2005 12:20:31 PM]

Share this post


Link to post
Share on other sites
Great! Glad you got that straightened out! I'm going to be looking forward to that IOTD ^_^

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!