I don't mind if you use it. I have found a couple of bugs myself. If you can send me the code/model that won't save, I'll see if I can fix it.
Also until I learn the .x format a little better, this only supports 1 texture stage. If more than one stage is even possible in .x, as everyone seems to be having problems with it.
[edit] For now this may help you. Modify this part of code to add the convert object fvf 274. This will not affect the original object just the temp objects created for the limb data.
[edit2] Also possibly fixed a vert holding bug with the array size. I am at work so I can't test this.
`make types for arrays to save .x object
type newdata1
numverts as integer
numfaces as integer
endtype
type newdata2
xpos as float
ypos as float
zpos as float
xnorm as float
ynorm as float
znorm as float
u_data as float
v_data as float
endtype
`(object number to save, filename to save to)
function save_x( objnum, savefilename$ )
`make all lower case for easier checking
savefilename$ = lower$(savefilename$)
`if other than .x save name given prompt error then exit
if right$(savefilename$, 2) <> ".x"
message "Non .x model name given", "Please specify a .x file extension"
exitfunction
endif
`find free file number to use
filenum = find free file()
`create file to write to
open to write filenum, savefilename$
`default info for .x text file format with 32bit floats
write string filenum, "xof 0302txt 0032"
`comments at top of header (can be removed)
write string filenum, "//Test x format export, Based on CSHOP exported files"
write string filenum, "//Modified By Lost In Thought"
`defines start of header
write string filenum, "Header"
`no idea what this part means
write string filenum, " {"
write string filenum, " 1;"
write string filenum, " 0;"
write string filenum, " 1;"
write string filenum, " }"
`get number of limbs(meshes) and nummaterials(textures [1 per limb]) in object
perform checklist for object limbs objnum
nummeshs = checklist quantity()
empty checklist
nummaterials = nummeshs
`dim array to store number of verts and faces per limb
dim data_store(nummeshs) as newdata1
`find placeholder variable values to use
tempobjnum = find free object()
tempmeshnum = find free mesh()
tempmembnum = find free memblock()
TempNumVertInd = 0
`for each mesh save data
for i = 1 to nummeshs
`access the limbs data
make object from limb tempobjnum, objnum, i-1
`convert the limb data to fvf 274
convert object fvf tempobjnum, 274
`convert to mesh so we can extract data
make mesh from object tempmeshnum, tempobjnum
`remove the object made to access data
delete object tempobjnum
`extract data to memblock for easier logging
make memblock from mesh tempmembnum, tempmeshnum
`delete mesh used to access data
delete mesh tempmeshnum
`save num verts in limb
data_store(i).numverts = memblock dword( tempmembnum, 8 )
`save num faces (polys) in limb (3 verts per face is what I used)
data_store(i).numfaces = data_store(i).numverts/3
`dim array to store vert data for each vert of each limb
if data_store(i).numverts > TempNumVertInd
`resize the array to holf the max needed
TempNumVertInd = data_store(i).numverts
dim data_store2(nummeshs, TempNumVertInd) as newdata2
endif
`memblock position placeholder variable
a = 12
`save all vert data for current limb to array
`data format is data_store2(limbnumber, vertnumber).info
for j = 1 to data_store(i).numverts
`vert x position
data_store2(i,j).xpos = memblock float( tempmembnum, a )
inc a, 4
`vert y position
data_store2(i,j).ypos = memblock float( tempmembnum, a )
inc a, 4
`vert z position
data_store2(i,j).zpos = memblock float( tempmembnum, a )
inc a, 4
`vert x normal
data_store2(i,j).xnorm = memblock float( tempmembnum, a )
inc a, 4
`vert y normal
data_store2(i,j).ynorm = memblock float( tempmembnum, a )
inc a, 4
`vert z normal
data_store2(i,j).znorm = memblock float( tempmembnum, a )
inc a, 4
`vert u data
data_store2(i,j).u_data = memblock float( tempmembnum, a )
inc a, 4
`vert v data
data_store2(i,j).v_data = memblock float( tempmembnum, a )
inc a, 4
next j
`cleanup after each limb data is saved
delete memblock tempmembnum
next i
`write 1 material per texturename (or in my case 1 per limb in case I
`want to add an export a different texturename per limb ;-) )
for i = 1 to nummaterials
`give material/texture a nametag
write string filenum, "Material material_" + str$(i)
`default material info (no idea what it means)
write string filenum, " {"
write string filenum, " 1.0;1.0;1.0;1.0;;"
write string filenum, " 11.3137;"
write string filenum, " 0.0;0.0;0.0;;"
write string filenum, " 0.012549;0.0360784;0.0109804;;"
`texture filename section
write string filenum, " TextureFilename"
write string filenum, " {"
`assign filename to nametag
write string filenum, " " + chr$(34) + limb texture name( objnum, i-1 ) + chr$(34) + ";"
write string filenum, " }"
write string filenum, " }"
next i
`frame (one per file)
write string filenum, "Frame World"
write string filenum, " {"
`no idea what this is either
write string filenum, " FrameTransformMatrix"
write string filenum, " {"
write string filenum, " 1.0,0.0,0.0,0.0,"
write string filenum, " 0.0,1.0,0.0,0.0,"
write string filenum, " 0.0,0.0,1.0,0.0,"
write string filenum, " 0.0,0.0,0.0,1.0;;"
write string filenum, " }"
`write 1 per mesh/limb
for j = 1 to nummeshs
`give mesh/limb a nametag
write string filenum, " Mesh object" + str$(j)
write string filenum, " {"
`write number of verts per mesh
write string filenum, " "+str$(data_store(j).numverts)+";"
`set end of line character
endchar$ = ";,"
`write each vertex info
for i = 1 to data_store(j).numverts
`close data when done with ;; instead of ;,
if i = data_store(j).numverts
`when at end of info set end of line to close info
endchar$ = ";;"
endif
`get vert's x position
tempx_pos$ = str$(data_store2(j,i).xpos)
`check to make sure each value is a float
`if not then add .000000 as it is buggy otherwise
found = 0
for k = 1 to len(tempx_pos$)
if mid$(tempx_pos$,k) = "."
found = 1
exit
endif
next k
if found = 0
tempx_pos$ = tempx_pos$ + ".000000"
endif
`get vert's y position
tempy_pos$ = str$(data_store2(j,i).ypos)
`check to make sure each value is a float
`if not then add .000000 as it is buggy otherwise
found = 0
for k = 1 to len(tempy_pos$)
if mid$(tempy_pos$,k) = "."
found = 1
exit
endif
next k
if found = 0
tempy_pos$ = tempy_pos$ + ".000000"
endif
`get vert's z position
tempz_pos$ = str$(data_store2(j,i).zpos)
`check to make sure each value is a float
`if not then add .000000 as it is buggy otherwise
found = 0
for k = 1 to len(tempz_pos$)
if mid$(tempz_pos$,k) = "."
found = 1
exit
endif
next k
if found = 0
tempz_pos$ = tempz_pos$ + ".000000"
endif
`write finalized values once testing is done
write string filenum, " " + tempx_pos$ + ";" + tempy_pos$ + ";" + tempz_pos$ + endchar$
next i
`write the number of polys in the mesh
write string filenum, " "+ str$(data_store(j).numfaces) + ";"
`set end of line character
endchar$ = ";,"
`assign indexs/verts to poly
a = 0
for k = 1 to data_store(j).numfaces
`close data when done with ;; instead of ;,
if k = data_store(j).numfaces
`when at end of info set end of line to close info
endchar$ = ";;"
endif
`assign each poly 3 verts; index1, index2, index3
`each index is the vert number in the above vert info section
write string filenum, " 3;"+str$(a)+","+str$(a+1)+","+str$(a+2)+endchar$
inc a, 3
next k
`write mesh normals
write string filenum, " MeshNormals"
write string filenum, " {"
`number of verts
write string filenum, " " + str$(data_store(j).numverts)+";"
`set end of line character
endchar$ = ";,"
`write each vert's normal info
for i = 1 to data_store(j).numverts
`close data when done with ;; instead of ;,
if i = data_store(j).numverts
`when at end of info set end of line to close info
endchar$ = ";;"
endif
`get vert's x normal value
tempx_norm$ = str$(data_store2(j,i).xnorm)
`check to make sure each value is a float
`if not then add .000000 as it is buggy otherwise
found = 0
for k = 1 to len(tempx_norm$)
if mid$(tempx_norm$,k) = "."
found = 1
exit
endif
next k
if found = 0
tempx_norm$ = tempx_norm$ + ".000000"
endif
`get vert's x normal value
tempy_norm$ = str$(data_store2(j,i).ynorm)
`check to make sure each value is a float
`if not then add .000000 as it is buggy otherwise
found = 0
for k = 1 to len(tempy_norm$)
if mid$(tempy_norm$,k) = "."
found = 1
exit
endif
next k
if found = 0
tempy_norm$ = tempy_norm$ + ".000000"
endif
`get vert's x normal value
tempz_norm$ = str$(data_store2(j,i).znorm)
`check to make sure each value is a float
`if not then add .000000 as it is buggy otherwise
found = 0
for k = 1 to len(tempz_norm$)
if mid$(tempz_norm$,k) = "."
found = 1
exit
endif
next k
if found = 0
tempz_norm$ = tempz_norm$ + ".000000"
endif
`write finalized values once testing is done
write string filenum, " " + tempx_norm$ + ";" + tempy_norm$ + ";" + tempz_norm$ + endchar$
next i
`write the number of polys in the mesh
write string filenum, " "+ str$(data_store(j).numfaces) + ";"
`set end of line character
endchar$ = ";,"
`assign indexs/verts polys
a = 0
for k = 1 to data_store(j).numfaces
`close data when done with ;; instead of ;,
if k = data_store(j).numfaces
`when at end of info set end of line to close info
endchar$ = ";;"
endif
`assign each poly 3 verts; index1, index2, index3
`each index is the vert number in the above normal info section
write string filenum, " 3;"+str$(a)+","+str$(a+1)+","+str$(a+2)+endchar$
inc a, 3
next k
write string filenum, " }"
`write UV data
write string filenum, " MeshTextureCoords"
write string filenum, " {"
`write number of verts
write string filenum, " " + str$(data_store(j).numverts)+";"
`set end of line character
endchar$ = ";,"
`write each vert's texture coordinates
for i = 1 to data_store(j).numverts
`close data when done with ;; instead of ;,
if i = data_store(j).numverts
`when at end of info set end of line to close info
endchar$ = ";;"
endif
`get vert's U texture data
tempu$ = str$(data_store2(j,i).u_data)
`check to make sure each value is a float
`if not then add .000000 as it is buggy otherwise
found = 0
for k = 1 to len(tempu$)
if mid$(tempu$,k) = "."
found = 1
exit
endif
next k
if found = 0
tempu$ = tempu$ + ".000000"
endif
`get vert's V texture data
tempv$ = str$(data_store2(j,i).v_data)
found = 0
`check to make sure each value is a float
`if not then add .000000 as it is buggy otherwise
for k = 1 to len(tempv$)
if mid$(tempv$,k) = "."
found = 1
exit
endif
next k
if found = 0
tempv$ = tempv$ + ".000000"
endif
`write finalized data after testing
write string filenum, " " + tempu$ + ";" + tempv$ + endchar$
next i
write string filenum, " }"
`start of mesh material (testure name per face) list
write string filenum, " MeshMaterialList"
write string filenum, " {"
`in our code a poly is a face so they are equal
`write num faces
write string filenum, " "+str$(data_store(j).numfaces)+";"
`write numpolys
write string filenum, " "+str$(data_store(j).numfaces)+";"
`set end of line character
endchar$ = ","
`assign each poly a face index
for i = 1 to data_store(j).numfaces
`when at end change end of line to close data
if i = data_store(j).numfaces
endchar$ = ";;"
endif
`write poly to face data in order as a poly is a face
write string filenum, " "+str$(i-1)+endchar$
next i
`write the material data for each face/poly in order (all the same)
for i = 1 to data_store(j).numfaces
write string filenum, " { material_"+ str$(j) + " }"
next i
write string filenum, " }"
write string filenum, " }"
next j
write string filenum, " }"
close file filenum
`cleanup when done
undim data_store(0)
undim data_store2(0)
endfunction