Custom mesh exporting

Blitz3D Forums/Blitz3D Programming/Custom mesh exporting

RifRaf(Posted 2009) [#1]
Disregard,

I was having some issues with a custom export system, Right after posting my lengthly issue, I found my solution.

edit:
Ill try not to waste the post, and see if anyone can suggest a more effective way to save mesh data, im not really going for hard to crack format, just straight forward.

heres the meat of what im using now. Indents got a little funky when I pasted them. sorry



jfk EO-11110(Posted 2009) [#2]
Not exactly shure what you mean by more effective (size?), one way would be to save only the data that is used, eg. when there is no 2nd UV set then simply omit these parameters.
One 16-Bit Word in the header could be used to signal (bitwise)what Parameters are used. This way you even get 2 optional parameters (14,15) for future additions or so.

But it makes the code more complicated (harder to read and easier to embed bugs), so I am not sure if it's worth the troubles, only for a few kBytes.


Yasha(Posted 2009) [#3]
Unless all your meshes are completely unwelded, writing the vertices as they appear in each triangle is going to result in them being duplicated (so the result will always be unwelded, in fact). If you can use at least partially welded meshes you'd save some space by listing all the vertices in a surface first and then just storing the vertex indices in the triangle list, same as Blitz3D does internally. You wouldn't save any if you actually want unwelded meshes though.

As well as not storing the information you don't need (are you using vertex colours and a second UV set?) you might also be able to lose some precision on the information you do intend to use. Depending upon how important vertex normals are, you could multiply them all up by 127 (or so the largest one is 127, slightly better) and use only one byte to store them. Or do the same but with a short int. 16 bits is also usually enough precision for a simple, character-sized mesh - on those (ie. the tanks) you could set a single scale factor and multiply the vertex positions up so the largest is 32760 (ie. same suggestion as for normals, only with short ints - leave a bit off as error margin), then store these as short ints so they take up half the space. You'd have to convert short ints and bytes back to floats at load time, but there's probably not much of a speed hit for that. Anyway whether this is worthwhile depends on the complexity of your meshes, but if you use short ints for vertex positions and UVs in a normal sized character mesh the loss in quality is not likely to be noticeable (chances are that's still more precision than you were using anyway) for a 50% reduction in size.

Whatever you do, don't go crazy and decide to crush vertex positions down to single bytes (unless your meshes are super-simple and chunky and you don't care about quality). This is why MD2s look so bad and suffer from "wobbly" vertices. However, if you're feeling really stingy on space you can probably get away with this for the normals (you also don't need to store a scale for the normals as they can be whatever magnitude you like) and the UVs, which would normally be unsigned so you get twice the precision.


RifRaf(Posted 2009) [#4]
very useful tips, thanks guys.

(are you using vertex colours and a second UV set?)

well i'm not, but the map editor will allow the creator to use whatever origin media they want to , so I was trying to keep the door open on most things.. such as a lightmap set of coordinates.


RifRaf(Posted 2009) [#5]
Ok, if you look at the above export code, and the loading code below. can you spot what im doing wrong.. I have a lightmap applied through gile[s] on channel 1, but if i try to apply it.. I get a mess. I can load the primary uv fine if I bypass the lightmap textures it looks ok, just no lm.

Any help would be appeciated.. thanks!!

Heres what i want









And heres what I get





heres the load code snippet
    ;read the vert count for this surface          
        svcount=bank_ReadInt(loaded_pak)
        DebugLog "vert count is "+svcount
        For sv=0 To svcount-1
            x0#=bank_readfloat(loaded_pak)
            y0#=bank_readfloat(loaded_pak)
            z0#=bank_readfloat(loaded_pak)
            u0a#=bank_readfloat(loaded_pak)
            v0a#=bank_readfloat(loaded_pak)
            u02a#=bank_readfloat(loaded_pak)
            v02a#=bank_readfloat(loaded_pak)
            nx0#=bank_readfloat(loaded_pak)
            ny0#=bank_readfloat(loaded_pak)
            nz0#=bank_readfloat(loaded_pak)
            al0#=bank_readfloat(loaded_pak)
            r0#=bank_readfloat(loaded_pak)
            g0#=bank_readfloat(loaded_pak)
            b0#=bank_readfloat(loaded_pak)
            v0=AddVertex (s,x0,y0,z0)

            VertexTexCoords s,v0,u0a,v0a,  0,0
            VertexTexCoords s,v0,u02a,v02a,0,1
            VertexColor s,v0,r0,g0,b0,al0
            VertexNormal s,v0,nx0,ny0,nz0
			;;;;;;;;;;;;;;;;
		Next
        tc=bank_Readint(loaded_pak)
         For stt=0 To tc-1
           v1=bank_readint(loaded_pak)
           v2=bank_readint(loaded_pak)
           v3=bank_readint(loaded_pak)
           AddTriangle s,v1,v2,v3
        Next
   
          b=CreateBrush(255,255,255)
          BrushColor b,brush_Red,brush_Green,brush_blue
          If thistex <>0 Then  BrushTexture  b,thistex,0,0
          If thistex2<>0 Then  
                   TextureBlend thistex2,5
     		   BrushTexture b,thistex2,0,1
          EndIf
          BrushBlend b,brush_blend
          BrushFX b,brush_fx
          BrushShininess b,0;brush_shine#
          PaintSurface  s,b
          UpdateNormals mesh

     Next  
	 Return mesh




RifRaf(Posted 2009) [#6]
Problem solved.. it wasnt the code above. I forgot I was clusterizing my main map after loading wich was destroying the second uv set.. Thanks anyway! :)