Writing B3D From and back into Blitz3D

Blitz3D Forums/Blitz3D Programming/Writing B3D From and back into Blitz3D

Gurney(Posted 2005) [#1]
We are creating meshes in our Blitz Application and we want to save the meshes to b3d format, and then read them back in.

This may seem basic...but it is a real headscratcher. Has anyone done extensive work on a utility that writes a mesh created with Blitz out to b3d format, and then will read it back in to Blitz maintaining integrity?

It needs to support at least two texture layers, and two sets of UV Coordinates. NOthing animated, no bones etc., just a single multitextured mesh.

Apparently, There aren't any native functions to interrogate the mesh for some of the data. In other words, there's no function to ask the mesh "How many texture layers are you using?" or "How many uv coordinate sets are you using?"

Thanks in advance for your reply!

Michael


BlackD(Posted 2005) [#2]
jfk's SaveB3D routines:

http://www.blitzbasic.co.nz/codearcs/codearcs.php?code=866

+BlackD


Ross C(Posted 2005) [#3]
i found that routine to save my mesh, but not my textures. the comments said that each surfaces must have a brush/texture. I didn't quite get what that meant, as i tried giving every surface a brush and it still appeared untextured. It's frustrating there is no code that will let you save out a fully textured, multi-surface blitz mesh. It would be brilliant if someone wrote that. It's beyond me to get my head around it.

I'v heard alot of people say, it's pretty easy to do this. Which begs the question, if it's that easy to do, why isn't there any code in the archives to do this. Me thinks it isn't that easy somehow...


Shambler(Posted 2005) [#4]
I know for a fact that jfk's routine works and works well, saving the .b3d in a very efficient format...you must be missing something e.g. textures are not in the current directory.


BlackD(Posted 2005) [#5]
a brush alone isn't enough. you must assign a texture to the brush.

For example:
mybrush=createbrush()
tex=createtexture(200,200)   ;create a texture rather than loading one
setbuffer texturebuffer(tex)   ;draw to the texture
color 200,200,200
rect 0,0,200,200,1
setbuffer backbuffer()
brushtexture mybrush,tex


+BlackD


Vorderman(Posted 2005) [#6]
If you have a look in this thread - http://www.blitzbasic.com/Community/posts.php?topic=51803 - I posted the modified version of JFK's B3D saving routines that I'm using for the Stunt Car track editor. It's saving 2 sets of texture coords (typically used for the diffuse and lightmap channels).

However it has a small bug in the FUNC_WriteBB3 function, so swap it out for this one and it should work -




Ross C(Posted 2005) [#7]
Thanks guys, looks good :o)


Gurney(Posted 2005) [#8]
Thank you so much! This gives us a great place to start. Its been a real pickle for us. I'll post back with issues/questions and feedback.

Best,

Michael


ICECAP(Posted 2005) [#9]
Has anyone attempted the same thing with a 3DS file?


Gurney(Posted 2005) [#10]
Vorderman

We are still having a bit of trouble with this. the code does not seem to write out multilayer texture information. when we save out an automatically generated texture with multi-layer textures using the functions in the above code, it reads back in blank...no textures. Does the above code support multi-texturing? thank you!

Michael


jfk EO-11110(Posted 2005) [#11]
The textures need to be in the same folder as the mesh. Other than that, read the sourcecode and its remarks, it should explain all you need to know to make it work somehow, assuming you're familar with blitz3d.

BTW if you still have problems with brushes versus textures:

instead of
tex=loadtexture("marble.bmp")
entitytexture floor,marble

use
tex=loadbrush("marble.bmp")
paintmesh floor,marble

that simple. Brushes have the pro that they allow more than a texture: multiple textures, color, fx, all stored in one brush and assigned to a mesh with one command.

Of course, you need to edit the save code if your mesh is using eg. 5 texture layers. Basicly it has to use the TEXS chunk to list all textures that are used by the mesh, and the BRUS chunk to define all brushes that are used by the mesh. A BRUS chunk will then name the textures (by index) that are used by the brush, as well as its fx parameters etc.


Vorderman(Posted 2005) [#12]
Does the above code support multi-texturing?

Sorry my mistake, it doesn't in that form.

However, it IS already exporting the second UV channel info, see these 2 lines in the code -
b3dWriteFloat( VertexU#( surf,j,1 ) ) ;lightmap uv
b3dWriteFloat( VertexV#( surf,j,1 ) ) ;lightmap uv

I think you need to change this line to export both channels -
b3dWriteInt( 1 )	;number of textures per brush ; (eg 2 with lightmap)

Try changing the 1 to a 2.

Also, have you declared the c_surfs arrays?
Const c_surfs													= 20

;arrays
Dim c_surf(c_surfs)
Dim c_brush(c_surfs)
Dim c_tex(c_surfs)
Dim c_tex_name$(c_surfs)


It DOES all work, because I have (or had, I've now ditched lightmapping for the moment) the Stunt Car Track Editor exporting the track plus the lightmap, and then loading it back in again. Bear in mind there was a bug in the original FUNC_WriteBB3D( f_name$,mesh ) function that would cause a MAV due to the texture placement, but that FUNC_WriteBB3D( f_name$,mesh ) routine I posted above should work OK.


jfk EO-11110(Posted 2005) [#13]
What MAV? is that bug inside th original code archive entry? Please explain, I got to fix it. (How do you mean "texture placement"?)


Gurney(Posted 2005) [#14]
I think you need to change this line to export both channels -

Both channels? What exactly do you mean by this? Do you have a separate channel within the texture file itself? (similar to an alpha channel?) If that's the case, we're using a different method then. We can post some example code of how we're building our meshes.

b3dWriteInt( 1 )	;number of textures per brush ; (eg 2 with lightmap)
Try changing the 1 to a 2.


Just doing this won't work because the code that writes the TEXS & BRUS chunks only iterates through the number of surfaces only. A surface brush can have up to 8 textures associated with it. Only one is written to the B3D file because the code assumes only one texture per surface.


Also, have you declared the c_surfs arrays?

Const c_surfs													= 20

;arrays
Dim c_surf(c_surfs)
Dim c_brush(c_surfs)
Dim c_tex(c_surfs)
Dim c_tex_name$(c_surfs)

Yes, but we have the same problem here, only one texture per surface is assumed and we have multiple textures per surface/brush. (In addition to using both sets of uv coords, but that's another problem. Let's fix this one first. :) )


Vorderman(Posted 2005) [#15]
Well I don't claim to be an expert here, seeing as someone else wrote the original code, but I changed the 1 to a 2, then added the lines shown above -
b3dWriteFloat( VertexU#( surf,j,1 ) ) ;lightmap uv
b3dWriteFloat( VertexV#( surf,j,1 ) ) ;lightmap uv

..and my SCR editor then saved the lightmap coords (channel 1) along with the main texture coords (channel 0), which enabled me to reload the model with lightmap coords intact.

Yes, but we have the same problem here, only one texture per surface is assumed

Well the number of textures is irrelevant, you can apply the same texture to all channels, but changing the 1 to a 2 alters the amount of TEXTURE COORDINATE CHANNELS that are saved.

Both channels? What exactly do you mean by this?

Both UV coordinate mapping channels - channel 0 for the normal (diffuse) mapping, and channel 1 for the lightmap.

Do you have a separate channel within the texture file itself?

No, this just relates to the UV coords saved with the mesh, so in this case it now saves 2 channels per surface.

What MAV? is that bug inside th original code archive entry?

Sort of - you have this line -
Global c_surfs=CountSurfaces(mesh)

Which can be set in advance because you already have the mesh you are going to save. In my case the mesh was yet to be built, so c_surfs was just set to a high number so the arrays were initialised with more than enough space for the mesh's possible surfaces.

HOWEVER, in the loop where it writes texture info you have this -
; track down used textures (thanks Mark!)
For i=1 To c_surfs


...which in my code would now cause a mesh error because c_surfs is going beyond the number of textures the mesh actually has, so reloading it caused a MAV.

So I used a new variable and all was well again.


jfk EO-11110(Posted 2005) [#16]
Hi, just an additional sidenote:

while writing both Texture Coordinate Sets may be easy when you read my remarks in the code, you need to modify the way, the surfaces are prepared for storage when there are multiple textures per brush. Usually you have one Lightmap as the second channel/layer for all surfaces, this makes things simple. But if you want to read in the used textures for all layers the same way as I did it with the first layer, you need to use the index flag.

Dim c_surf(c_surfs)
Dim c_brush(c_surfs)
Dim c_tex(c_surfs,7) ; note: allow 8 textures
Dim c_tex_name$(c_surfs,7) ; note: allow 8 texture paths

...
for i2=0 to 7
c_tex(i,i2)=GetBrushTexture( c_brush(i), i2 ) ; note i2 is index
c_tex_name$(i,i2)=Lower$(TextureName$( c_tex(i,i2)))

...
Of course it's then up to you to check for NULL-textures or empty path strings, (assuming non existing layers etc.) and use the retrieven Info to declare all brushes correctly. Now when you know this and how brush declaration works, it should be easy. Note: while 8 texture layers are possible, only 2 UV Coordinate sets are possible, so each of the max. 8 textures has to use one of the two sets.

BTW. it's always a good idea to read the "versions.txt" (in the Blitz3D installation folder), it contains information about the latest commands and functions, like TextureName$(tex,[index]) that was introduced in version 1.85.