sure, here is the code and some extra useful functions:
Another piece of code I usually add (and might add later) is the collection of textures used for the whole source DBO. This list then gets sorted and any duplicates get removed from the list.
Then with the addition of another bit of code that handles the limb texture assignment, you can load in and texture limbs using only the minimum of images over and over. Good resource optimization.
Rem Project: Object_UV_copy_v0.2
Rem Created: Thursday, July 26, 2018
Rem ***** Main Source File *****
sync on : sync rate 60
autocam off
// user temp folder
tmpfld as string
tmpfld = tempdir$()
// app folder
appfld as string
appfld = get dir$()
// dummy object ... a sphere of 0 size
dummy=400000
// start range ID for object creation
startobj=500000
// load in a DBO e.g. universe.dbo
dboobj=600000
set dir appfld
Load Object "in.dbo",dboobj
// had to update the 0.dds or 0.png to fill black
// background with white background to get the correct look
load image "0_white.png",1
// after loading the dbo i.e FPSC level universe.DBO files, I usually reposition the vertices
// find out how many limbs in the dbo e.g. might be an FPSC level
Perform CheckList For Object Limbs dboobj
mxlimbs=Checklist Quantity()
// comment this out if you don't want to reposition the level object
RepositionUniverseDBO(dboobj,mxlimbs)
// set folder to user appdata temp area for temp dumping out any files
set dir tmpfld
// make a dummy object for attaching limbs later
make object sphere dummy,0
for l = 0 to mxlimbs-1
make object from limb l+startobj,dboobj,l
f$="obj"+str$(l)+".dbo"
DeleteFile(f$)
save object f$,l+startobj
// change over UVs prior to saving out new DBO - experiment these for your needs
CopyObjectUVLayer(l+startobj,0,l+startobj,0,8,0)
for target=0 to 1
CopyObjectUVLayer(l+startobj,0,l+startobj,0,target,1)
next target
CopyObjectUVLayer(l+startobj,0,l+startobj,0,2,8)
make mesh from object l+startobj,l+startobj
delete object l+startobj
add limb dummy,l+1,l+startobj
texture limb dummy,l+1,1
f$="limb"+str$(l)+".x"
DeleteFile(f$)
save mesh f$,l+startobj
next l
// now delete the main dbo object
Delete Object dboobj
// set back to app folder to output final dbo and to
// prevent it accidentally being erased from user tamp folder later
// although you can set an exception deletion on a file in the cleanup
// function
set dir appfld
outdbo as string
// call this what you want
outdbo="out.dbo"
DeleteFile(outdbo)
save object outdbo,dummy
// uncomment this line below if not using the reposition function
//position camera 650,550,-500
// comment this out if not using the reposition function
position camera 200,0,-800
repeat
set cursor 0,0
print "camera pos x,y,z: "+str$(camera position x (0))+", "+str$(camera position y (0))+", "+str$(camera position z (0))
print "Use arrow keys to move around:"
control camera using arrowkeys 0,5.5,5.5
sync
until mouseclick()=2 // display until the right mouse button clicked
// cleanup
delete image 1
if object exist(dummy) then delete object dummy
for o=startobj to startobj+mxlimbs-1
if object exist(o) then delete object o
next o
// clear out temp files in user appdata temp folder
// comment out if you want to keep temp files in your appdata/local/temp folder
// add/remove suffixes to suff$ if need to
suff$=".dbo|.x|.txt|.tmp"
CleanUpTempFiles(tmpfld,suff$,"dbpdata",7,"")
end
///===========///
/// FUNCTIONS ///
///===========///
Function CopyObjectUVLayer(targetObject,targetLimb,sourceObject,sourceLimb,targetUVLayer,sourceUVLayer)
` Lock source limb for vertex access
Lock VertexData For Limb sourceObject, sourceLimb
vLen = get vertexdata vertex count()-1
` Create arrays of UV coordinates for assignment to the target limb
local Dim u#(vLen)
local Dim v#(vLen)
For v = 0 to vLen
u#(v) = Get VertexData U(v, sourceUVLayer)
v#(v) = Get VertexData V(v, sourceUVLayer)
Next v
` Unlock source limb
unlock vertexdata
` Lock target limb for vertex access in full overwrite mode 2
Lock VertexData For Limb targetObject, targetLimb, 2
vLen = get vertexdata vertex count()-1
` Write the coordinates to the target layer
For v = 0 to vLen
Set VertexData UV v, targetUVLayer, u#(v), v#(v)
Next v
` Update the target
Unlock VertexData
undim u#()
undim v#()
EndFunction
function DeleteFile(filetodel$)
if file exist(filetodel$) then delete file filetodel$
endfunction
function RepositionUniverseDBO(uniobj,limbs)
limbstart=1
limbend=limbs-1
// this FOR..NEXT loop determines the
// smallest/largest xyz coords
// and uses these values to
// determine the nearest 0,0,0 position
// may need to play around with this
// for better accuracy
for l = limbstart to limbend
Make Object From Limb l+1,uniobj,l
lastcenx#=lcenx#
lcenx#=Object Collision Center X (l+1)
lastceny#=lceny#
lceny#=Object Collision Center Y (l+1)
lastcenz#=lcenz#
lcenz#=Object Collision Center Z (l+1)
if lcenx# < lastcenx#
smallestx#=lcenx#
else
if lcenx# >= lastcenx#
largestx#=lcenx#
endif
endif
if lceny# < lastceny#
smallesty#=lceny#
else
if lceny# >= lastceny#
largesty#=lceny#
endif
endif
if lcenz# < lastcenz#
smallestz#=lcenz#
else
if lcenz# >= lastcenz#
largestz#=lcenz#
endif
endif
Delete Object l+1
next l
// this FOR..NEXT loop repositions
// each vertex based on largest/smallest
// values found at previous step
for l = limbstart to limbend
Lock VertexData For Limb uniobj,l,2
vtot=Get VertexData Vertex Count()
for v=0 to vtot
vx#=Get VertexData Position X(v)
vy#=Get VertexData Position Y(v)
vz#=Get VertexData Position Z(v)
Set VertexData Position v,vx#-largestx#,vy#-smallesty#,vz#-((largestz#-smallest)/2)
next v
Unlock VertexData
next l
endfunction
function CleanUpTempFiles(srcfold$,suff$,folders$,numcharstocheck,exceptionfile$)
if srcfold$ = ""
warningmessage "CleanUpTempFiles: No source folder selected!"
exitfunction
endif
if suff$ = ""
warningmessage "CleanUpTempFiles: No file extensions selected!"
exitfunction
else
numberofsuffixes = Occur(suff$,"|")
endif
// folders$ parameter is optional //
if folders$ <> ""
numberoffolders = Occur(folders$,"|")
endif
olddir$=get dir$()
set dir srcfold$
perform checklist for files
cq = checklist quantity()
for f=1 to cq
cs$=checklist string$(f)
file$=cs$
fext$=fast upper$(extract fileext$(file$))
for sp = 0 to numberofsuffixes
filespl$=split$(suff$,"|",sp)
if fast upper$(fext$) = fast upper$(filespl$) and fast upper$(file$) <> fast upper$(exceptionfile$)
if file exist(file$) then delete file file$
endif
next sp
for fld = 0 to numberoffolders
foldspl$=split$(folders$,"|",fld)
if fast upper$(file$) = fast upper$(foldspl$) or (numcharstocheck > 0 and fast left$(fast upper$(file$),numcharstocheck) = fast left$(fast upper$(foldspl$),numcharstocheck) )
delete directory file$
endif
next fld
next f
sync
set dir olddir$
endfunction
// Actually this function does same thing as Instr command, but has embedded warning messages
function Occur(src$,char$)
result = 0
if src$ =""
warningmessage "Occurs: No source string selected!"
exitfunction result
endif
if char$ =""
warningmessage "Occurs: No search character selected!"
exitfunction result
endif
slen = fast len(src$)
for c = 1 to slen
if mid$(src$,c)=char$
inc result
endif
next c
endfunction result
Professional Programmer, languages: SAS, C++, SQL, PL-SQL, DBPro, Purebasic, JavaScript, others