TGC Codebase Backup



Weld Vertices by Visigoth

22nd Jun 2007 0:07
Summary

This function will take a DBPro primitive, and probably any other object you want, as long as they are static, no animations, and weld the vertices. Creates a before an after .x fi



Description

The function basically takes an object, converts it into mesh data,copies all the vertex data into an array, then searches through the vertexdata looking for duplicate vertices. It marks any duplicates, then copies the unigue ones into their own placeholders in the array. Then, it gets the index values for the original vertices, and compares the vertices at those locations with the unique ones. Any matches get pointed to the unique vertices. Then, it deletes the unnecessary vertex indexes, and writes the unique ones to the remaining vertex indexes. Then, it writes the indice indexex to the vertexdata. It then converts the mesh back to an object, and then uses built in DBPro command Set Object Normals to calculate the normals. Works great so far on all the primitives, except the sphere, which has a very prominent seam, but this is some weird lighting effect, or problem with the normals creation. Great if you want to make your own primitives, like matrixes (that's why I wrote it). Have fun!
EDIT:
params are now weld_vertices (object ID,UV flag)
object ID is the object number of the object to weld
UV flag is either no UV mapping 0
Stretch UV mapping 1
I found two loops that were real slow, so I improved that, should go quite a bit faster with larger meshes. I also added a planar type UV mapping. You can't really tile a map on an object with welded verts, so I had to do this to stretch the map across the object. Great for large plains or matrix type objects. Use a flag of 1 in the second parameter.



Code
                                    ` This code was downloaded from The Game Creators
                                    ` It is reproduced here with full permission
                                    ` http://www.thegamecreators.com
                                    
                                    
REM Created by Mike Shihrer aka Visigoth
REM free to use,modify,etc have fun

function weld_vertices(id as integer,texturemode as integer)
remstart
rem put this at the top of your code

type vdata
   x1 as float
   y1 as float
   z1 as float
   u as integer
   v as integer
   index as integer
   index2 as integer
   x2 as float
   y2 as float
   z2 as float
   match as boolean
endtype
Global Dim copyv(1) as vdata

remend
rem a_time# = timer()
undim copyv()
numVerts = 0
vc = 0
rem create a mesh from an object
make mesh from object 1,id
rem save it to an .x file, so you can see the differences. This is not necessary, and can be deleted.
save mesh "beforeweld_obj"+str$(id)+".x",1
delete object id
lock vertexdata for mesh 1
rem get the total number of indexes (polys) and total number of vertexs
vi = get vertexdata index count()
vc = get vertexdata vertex count()
rem create our type array
Global Dim copyv(vi) as vdata

rem copy vertex data into type array
for i = 1 to vi
   copyv(i).index = get indexdata(i -1)
   copyv(i).x1 = get vertexdata position x(copyv(i).index)
   copyv(i).y1 = get vertexdata position y(copyv(i).index)
   copyv(i).z1 = get vertexdata position z(copyv(i).index)
   copyv(i).index2 = 0
   copyv(i).x2 = 0
   copyv(i).y2 = 0
   copyv(i).z2 = 0
next vi

rem look for duplicate vertices, and flag them this took 4.4 seconds on 3200 polys this is the slow part
for i = 1 to vi
   if copyv(i).match = 0 rem this fixed the slowness a bunch, only check the list if not already marked a match
      for j = i + 1 to vi
         if copyv(i).x1 = copyv(j).x1 and copyv(i).y1 = copyv(j).y1 and copyv(i).z1 = copyv(j).z1
            copyv(j).match = 1
         endif
      next j
   endif
next i


rem get the total count of unique vertices, copy them into type array
for i = 1 to vi
   If copyv(i).match = 0
      copyv(numVerts + 1).x2 = copyv(i).x1
      copyv(numVerts + 1).y2 = copyv(i).y1
      copyv(numVerts + 1).z2 = copyv(i).z1
      copyv(numVerts + 1).index2 = numVerts rem remove this?
      inc numVerts,1
   endif
next i

rem compare the unique verts to the original verts, and write the index data to the type array
rem I changed this to preload the x,y.z values into a variable so the code doesn't have to look backwards into the type everytime it compares.
rem this saved about a half second
for i = 1 to numVerts
   x2# = copyv(i).x2
   y2# = copyv(i).y2
   z2# = copyv(i).z2
   i2 = copyv(i).index2
   for j = i to vi
      if copyv(j).x1 = x2# and copyv(j).y1 = y2# and copyv(j).z1 = z2#
         copyv(j).index = i2
      endif
   next j
next i

rem resize the vertexdata to allow for only unique vertices
delete mesh from vertexdata numVerts,vc,0,0
rem write the vertices to the vertexdata
for i = 1 to numverts
   set vertexdata position (i - 1),copyv(i).x2,copyv(i).y2,copyv(i).z2
next i

rem and finally, update the indexdata so faces draw the same
for i = 1 to vi
   set indexdata (i - 1),copyv(i).index
next i
rem set uv coordinates to stretch across object
rem should probably break this down into its own function for different kinds of objects, like mode 0 for my grid, 1 for DBPro cubes, 2 for DBPro box, etc

unlock vertexdata
make object id,1,0
save mesh "afterweld_obj"+str$(id)+".x",1
delete mesh 1

If texturemode = 1
u# =  object size x(id)
v# =  object size z(id)

make mesh from object 1,id
delete object id
lock vertexdata for mesh 1

rem loop throught the texture coordinates and determine what percent of total width, height the vertex is at
for i = 0 to numverts - 1
   set vertexdata uv i, get vertexdata position x(i) / u#, v# - (get vertexdata position z(i) / v#)
next i
unlock vertexdata
make object id,1,0
save mesh "afterweld_obj"+str$(id)+".x",1
delete mesh 1
endif

rem create normals data for vertices
set object normals id
undim copyv()

rem b_time# = timer()
rem tw_time# = (b_time# - a_time#) * .001

endfunction