REM *** Include File: objects.dba ***
REM Created: 6/20/2007 2:39:06 AM
REM Created by Mike Shihrer aka Visigoth
REM Free to use and modify, just a credit would be nice
REM Special thanks to IanM for getting me to think about this!
REM Included in Project: E:\Dev\Projects\grids\grids.dbpro
REM
function weld_vertices(id as integer)
remstart
rem put this at the top of your code
type vdata
x1 as float
y1 as float
z1 as float
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
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 vertex x,y,z coordinates
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
for i = 1 to vi
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
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
for i = 1 to numVerts
for j = 1 to vi
if copyv(i).x2 = copyv(j).x1 and copyv(i).y2 = copyv(j).y1 and copyv(i).z2 = copyv(j).z1
copyv(j).index = copyv(i).index2
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
unlock vertexdata
make object id,1,0
rem create normals data for vertices
set object normals id
save mesh "afterweld_obj"+str$(id)+".x",1
delete mesh 1
undim copyv()
endfunction
REM Project: Demo
REM Created: 6/21/2007 9:47:00 PM
REM Created by Mike Shihrer aka Visigoth
REM ***** Main Source File *****
REM
set display mode 1024,768,32
autocam off
sync on
sync rate 0
type vdata
x1 as float
y1 as float
z1 as float
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
position camera 0,50,0
make_grid(1,1000,1000,20,20)
weld_vertices(1)
make mesh from object 1,1
delete object 1
lock vertexdata for mesh 1
vc = get vertexdata vertex count()
for i = 0 to vc
set vertexdata position i, get vertexdata position x(i),get vertexdata position y(i) + rnd(20), get vertexdata position z(i)
next i
unlock vertexdata
make object 1,1,0
delete mesh 1
set object wireframe 1,1
rem xrotate object 1,90
do
display_data()
move_camera()
sync
loop
function weld_vertices(id as integer)
remstart
rem put this at the top of your code
type vdata
x1 as float
y1 as float
z1 as float
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
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 vertex x,y,z coordinates
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
for i = 1 to vi
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
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
for i = 1 to numVerts
for j = 1 to vi
if copyv(i).x2 = copyv(j).x1 and copyv(i).y2 = copyv(j).y1 and copyv(i).z2 = copyv(j).z1
copyv(j).index = copyv(i).index2
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
unlock vertexdata
make object id,1,0
rem create normals data for vertices
rem set object normals id
save mesh "afterweld_obj"+str$(id)+".x",1
delete mesh 1
undim copyv()
set object wireframe id,1
endfunction
function make_grid(id as integer,x_width as float, z_height as float,x_segments as integer,z_segments as integer)
unitwidth# = x_width / x_segments
unitheight# = z_height / z_segments
xpos# = 0
zpos# = 0
J = 1
make object triangle 1,0,0,0,0,0,1,1,0,0
make mesh from object 1,1
lock vertexdata for mesh 1
delete mesh from vertexdata 0,3,0,3
unlock vertexdata
delete object 1
for I = 1 to x_segments
lock vertexdata for mesh 1
make object triangle 2,xpos#,0,zpos#,xpos#,0,zpos# + unitheight#,xpos# + unitwidth#,0,zpos#
make object triangle 3,xpos#,0,zpos# + unitheight#,xpos# + unitwidth#,0,zpos# + unitheight#,xpos# + unitwidth#,0,zpos#
make mesh from object 2,2
make mesh from object 3,3
add mesh to vertexdata 2
add mesh to vertexdata 3
delete mesh 2
delete mesh 3
unlock vertexdata
delete object 2
delete object 3
inc xpos#, unitwidth#
If J < z_segments
If I = x_segments
Inc J,1
inc zpos#,unitheight#
xpos# = 0
I = 0
endif
endif
next I
make object id,1,0
set object wireframe id,1
delete mesh 1
endfunction
function move_camera()
if upkey() then move camera 1
if downkey()then move camera -1
if leftkey() then turn camera left 1
if rightkey() then turn camera right 1
endfunction
function display_data()
text 0,0,"Total Polygons :" + str$(statistic(1))
endfunction
well, after some more testing, it seems I jumped the gun here. It works, but when you get BIG meshes, over 15,000 polys, things really bog down
1 -> 0 comparisons
2 -> 1 comparison
3 -> 3 comparisons
4 -> 5 comparisons
5 -> 10 comparisons
6 -> 15 comparisons
7 -> 21 comparisons
8 -> 28 comparisons
9 -> 36 comparisons
10 -> 45 comparisons
There are two ways to fix this
Change the algorithm. There are one or two alternatives that could reduce the number of comparisons that I'll need to look in to. Effectively, what we have at the moment has the same complexity as a bubblesort - we need the equivalent complexity of quicksort.
Having said that, I'm still using IanM's code and am just putting up with the 10 minute wait while it searches for matching vertices. But one day I'll write my own code to use the vertex matching information that I already have ...
REM Project: Demo
REM Created: 6/21/2007 9:47:00 PM
REM Created by Mike Shihrer aka Visigoth
REM ***** Main Source File *****
REM
set display mode 1024,768,32
autocam off
sync on
sync rate 0
type vdata
x1 as float
y1 as float
z1 as float
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
Global tw_time#
Global tc_time#
position camera 0,20,0
rem make_grid params: Object ID, grid width, grid height, squares per width, squares per height
make_grid(1,2000,2000,30,30)
weld_vertices(1)
rem randomize_grid params: Object ID, x position, y position, z position
randomize_grid(1,0,15,0)
set object wireframe 1,1
rem /////////////////////////////Main Loop///////////////////////////////////
do
display_data1()
move_camera1()
sync
loop
rem ////////////////////////////////////////////////////////////////////////
function weld_vertices(id as integer)
remstart
rem put this at the top of your code
type vdata
x1 as float
y1 as float
z1 as float
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
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.
rem 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 vertex x,y,z coordinates
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
for i = 1 to vi
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
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
for i = 1 to numVerts
for j = 1 to vi
if copyv(i).x2 = copyv(j).x1 and copyv(i).y2 = copyv(j).y1 and copyv(i).z2 = copyv(j).z1
copyv(j).index = copyv(i).index2
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
unlock vertexdata
make object id,1,0
rem create normals data for vertices
set object normals id
rem save mesh "afterweld_obj"+str$(id)+".x",1
delete mesh 1
undim copyv()
b_time = timer()
tw_time# = (b_time - a_time) * .001
endfunction
function make_grid(id as integer,x_width as float, z_height as float,x_segments as integer,z_segments as integer)
a_time = timer()
unitwidth# = x_width / x_segments
unitheight# = z_height / z_segments
xpos# = 0
zpos# = 0
J = 1
make object triangle 1,0,0,0,0,0,1,1,0,0
make mesh from object 1,1
lock vertexdata for mesh 1
delete mesh from vertexdata 0,3,0,3
unlock vertexdata
delete object 1
for I = 1 to x_segments
lock vertexdata for mesh 1
make object triangle 2,xpos#,0,zpos#,xpos#,0,zpos# + unitheight#,xpos# + unitwidth#,0,zpos#
make object triangle 3,xpos#,0,zpos# + unitheight#,xpos# + unitwidth#,0,zpos# + unitheight#,xpos# + unitwidth#,0,zpos#
make mesh from object 2,2
make mesh from object 3,3
add mesh to vertexdata 2
add mesh to vertexdata 3
delete mesh 2
delete mesh 3
unlock vertexdata
delete object 2
delete object 3
inc xpos#, unitwidth#
If J < z_segments
If I = x_segments
Inc J,1
inc zpos#,unitheight#
xpos# = 0
I = 0
endif
endif
next I
make object id,1,0
delete mesh 1
b_time = timer()
tc_time# = (b_time - a_time) * .001
endfunction
function move_camera1()
if upkey() then move camera 1
if downkey()then move camera -1
if leftkey() then turn camera left 1
if rightkey() then turn camera right 1
endfunction
function display_data1()
text (screen width()/2),0, "Use arrow keys to move"
text 0,0,"Total Polygons: " + str$(statistic(1))
text 0,10,"Screen FPS: " + str$(screen fps())
text 0,20,"Index Count: " + str$(vi)
text 0,30,"Vertex Count: " + str$(vc)
text 0,40,"Make Time: " + str$(tc_time#) + " seconds"
text 0,50,"Weld Time: " + str$(tw_time#) + " seconds"
endfunction
function randomize_grid(id as integer,x_val as float, y_val as float, z_val as float)
make mesh from object 1,id
delete object id
lock vertexdata for mesh 1
vc = get vertexdata vertex count()
for i = 0 to vc
set vertexdata position i, get vertexdata position x(i) + Rnd(x_val),get vertexdata position y(i) + rnd(y_val), get vertexdata position z(i) + rnd(z_val)
next i
unlock vertexdata
make object 1,1,0
delete mesh 1
endfunction
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
function memblock_weld_vertices(id as integer,texture_mode as integer)
rem Created by Mike Shihrer, aka Visigoth
rem and as always, free to use and modify
a_time# = timer()
make mesh from object 1,id
delete object id
make memblock from mesh 1,1
delete mesh 1
m_size = get memblock size(1)
m_header = memblock dword(1,0)
m_vertices = memblock dword(1,8)
remstart
rem make a new memblock with a new structure to create an index data index
rem for when we write the new index and coordinates to the vertexdata
rem new format will be:
dword /header data
dword /header data
dword /header data
float /x coord position
float /y coord position
float /z coord position
dword /vertex index
dword /index index
dword /duplicate flag
float /u
float /v
remend
make memblock 2,m_size
m2_size = get memblock size(2)
rem write some header stuff. This is just a buffer space to match original fvf format
write memblock dword 2,0,111
write memblock dword 2,4,222
write memblock dword 2,8,333
rem copy the vertices into the new memblock and create a vertex index
a = 0
For i = 12 to (m_size - 32) step 32
x1# = memblock float(1,i) : y1# = memblock float(1,i + 4) : z1# = memblock float(1,i + 8) rem get our triangle data from the original memblock
write memblock float 2,i,x1# : write memblock float 2,i + 4,y1# : write memblock float 2,i + 8,z1# rem our triangle data pasted to the new memblock
write memblock dword 2,i + 12,a rem this will create a vertex index number
write memblock dword 2,i + 16,a rem this will be our indexdata index
write memblock dword 2,i + 20,0 rem this is our duplicate flag
write memblock float 2,i + 24,1 rem u mapping data just going to put 1 here for now
write memblock float 2,i + 28,1 rem v mapping data just going to put 1 here for now
inc a,1
next i
rem loop through the new memblock, look for duplicates and flag them
rem what this will do is flag all duplicate vertices with a 1, uniques will be left at 0
For i = 12 to (m_size - 32) step 32
x1# = memblock float(2,i) : y1# = memblock float(2,i + 4) : z1# = memblock float(2,i + 8)
for j = (i + 32) to (m_size - 32) step 32
x2# = memblock float(2,j) : y2# = memblock float(2,j + 4) : z2# = memblock float(2,j + 8)
If (x1# = x2#) and (y1# = y2#) and (z1# = z2#)
write memblock dword 2,i + 20,1
endif
next j
next i
rem assign new vertexdata index to the unique vertices
a = 0
For i = 12 to (m_size - 32) step 32
if memblock dword(2,i + 20) = 0
write memblock dword 2,i + 12,a
inc a,1
endif
next i
rem compare the unique vertices to the duplicate vertices, and write the indexdata value of the duplicate
rem to point at the matching unique vertice
numVerts = 0
For i = 12 to (m_size - 32) step 32
if memblock dword(2,i + 20) = 0
x1# = memblock float(2,i) : y1# = memblock float(2,i + 4) : z1# = memblock float(2,i + 8)
inc numVerts,1
for j = 12 to (m_size - 32) step 32
x2# = memblock float(2,j) : y2# = memblock float(2,j + 4) : z2# = memblock float(2,j + 8)
If (x1# = x2#) and (y1# = y2#) and (z1# = z2#)
write memblock dword 2,j + 16,memblock dword(2,i + 12)
endif
next j
endif
next i
remstart
rem this is just a block of code to write a data file of what is in the memblock
rem not needed unless you want to see it.
if file exist("memblocktest.txt") = 0
open to write 1,"memblocktest.txt"
else
delete file "memblocktest.txt"
open to write 1,"memblocktest.txt"
endif
For i = 12 to (m2_size - 32) step 32
write string 1,str$(memblock float(2,i)) + "," + str$(memblock float(2,i + 4)) + "," + str$(memblock float(2,i + 8)) rem x,y,z pos
write string 1,"vertex index: " + str$(memblock dword(2,i + 12))
write string 1,"indexdata index: " + str$(memblock dword(2,i + 16))
write string 1,"duplicate: " + str$(memblock dword(2,i + 20))
write string 1,"--------------"
next i
close file 1
remend
rem for some reason, you can't delete a mesh from a mesh made from a memblock. Possible bug?
rem so that is why I made a mesh from memblock, then an object, then a mesh from an object
make mesh from memblock 1,1
rem lock vertexdata for mesh 1
rem numVerts = get vertexdata index count()
rem delete mesh from vertexdata numVerts,m_vertices,0,0
make object id,1,0
delete mesh 1
make mesh from object 1,id
delete object id
lock vertexdata for mesh 1
numVerts = get vertexdata index count()
delete mesh from vertexdata numVerts,m_vertices,0,0
rem write the vertices to the vertexdata
a = 0
For i = 12 to (m_size - 32) step 32
if memblock dword(2,i + 20) = 0
x1# = memblock float(2,i) : y1# = memblock float(2,i + 4) : z1# = memblock float(2,i + 8)
set vertexdata position a,x1#,y1#,z1#
inc a,1
endif
next i
rem and finally, write the indexdata
a = 0
For i = 12 to (m_size - 32) step 32
index_value = memblock dword(2,i + 16)
set indexdata (a),index_value
inc a,1
next i
unlock vertexdata
make object id,1,0
delete mesh 1
delete memblock 1
delete memblock 2
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
rem right now, this just a planar type mapping
If texture_mode = 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
a = get vertexdata index count()
for i = 0 to a
set vertexdata uv i, get vertexdata position x(i) / u#, get vertexdata position z(i) / v#
next i
unlock vertexdata
make object id,1,0
rem save mesh "afterweld_obj"+str$(id)+".x",1
delete mesh 1
endif
b_time# = timer()
tw_time# = (b_time# - a_time#) * .001
endfunction
function memblock_weld_vertices(id as integer,texture_mode as integer)
make mesh from object 1,id
save mesh "before_weld_memblock.x",1
delete object id
make memblock from mesh 1,1
delete mesh 1
m_size = get memblock size(1)
m_header = memblock dword(1,0)
m_vertices = memblock dword(1,8)
remstart
rem make a new memblock with a new structure to create an index data index
rem for when we write the new index and coordinates to the vertexdata
rem new format will be:
dword /header data
dword /header data
dword /header data
float /x coord position
float /y coord position
float /z coord position
dword /vertex index
dword /index index
dword /duplicate flag
float /u
float /v
remend
make memblock 2,m_size
m2_size = get memblock size(2)
rem write some header stuff. This is just a buffer space to match original fvf format
write memblock dword 2,0,111
write memblock dword 2,4,222
write memblock dword 2,8,333
rem copy the vertices into the new memblock and create a vertex index
a = 0
For i = 12 to (m_size - 32) step 32
x1# = memblock float(1,i) : y1# = memblock float(1,i + 4) : z1# = memblock float(1,i + 8) rem get our triangle data from the original memblock
write memblock float 2,i,x1# : write memblock float 2,i + 4,y1# : write memblock float 2,i + 8,z1# rem our triangle data pasted to the new memblock
write memblock dword 2,i + 12,a rem this will create a vertex index number
write memblock dword 2,i + 16,a rem this will be our indexdata index
write memblock dword 2,i + 20,0 rem this is our duplicate flag
write memblock float 2,i + 24,1 rem u mapping data just going to put 1 here for now
write memblock float 2,i + 28,1 rem v mapping data just going to put 1 here for now
inc a,1
next i
rem a_time# = timer()
rem loop through the new memblock, look for duplicates and flag them
rem what this will do is flag all duplicate vertices with a 1, uniques will be left at 0
For i = 12 to (m_size - 32) step 32
x1# = memblock float(2,i) : y1# = memblock float(2,i + 4) : z1# = memblock float(2,i + 8)
rem search until a duplicate is found, then exit search
for j = (i + 32) to (m_size - 32) step 32
if memblock dword(2,i + 20) = 0
x2# = memblock float(2,j) : y2# = memblock float(2,j + 4) : z2# = memblock float(2,j + 8)
If (x1# = x2#) and (y1# = y2#) and (z1# = z2#)
write memblock dword 2,i + 20,1
endif
endif
next j
next i
rem b_time# = timer()
rem assign new vertexdata index to the unique vertices
a = 0
For i = 12 to (m_size - 32) step 32
if memblock dword(2,i + 20) = 0
write memblock dword 2,i + 12,a
inc a,1
endif
next i
rem compare the unique vertices to the duplicate vertices, and write the indexdata value of the duplicate
rem to point at the matching unique vertice
For i = 12 to (m_size - 32) step 32
if memblock dword(2,i + 20) = 0
x1# = memblock float(2,i) : y1# = memblock float(2,i + 4) : z1# = memblock float(2,i + 8)
inc numVerts,1
for j = 12 to (m_size - 32) step 32
x2# = memblock float(2,j) : y2# = memblock float(2,j + 4) : z2# = memblock float(2,j + 8)
If (x1# = x2#) and (y1# = y2#) and (z1# = z2#)
write memblock dword 2,j + 16,memblock dword(2,i + 12)
endif
next j
endif
next i
remstart
rem this is just a block of code to write a data file of what is in the memblock
rem not needed unless you want to see it.
if file exist("memblocktest.txt") = 0
open to write 1,"memblocktest.txt"
else
delete file "memblocktest.txt"
open to write 1,"memblocktest.txt"
endif
For i = 12 to (m2_size - 32) step 32
write string 1,str$(memblock float(2,i)) + "," + str$(memblock float(2,i + 4)) + "," + str$(memblock float(2,i + 8)) rem x,y,z pos
write string 1,"vertex index: " + str$(memblock dword(2,i + 12))
write string 1,"indexdata index: " + str$(memblock dword(2,i + 16))
write string 1,"duplicate: " + str$(memblock dword(2,i + 20))
write string 1,"--------------"
next i
close file 1
remend
rem for some reason, you can't delete a mesh from a mesh made from a memblock. Possible bug?
rem No longer necessary to use delete mesh from vertexdata(). It really has no effect on the mesh
rem All you really need to do is reorder the index data to weld.
make mesh from memblock 1,1
save mesh "memblock.x",1
lock vertexdata for mesh 1
rem write the vertices to the vertexdata
a = 0
For i = 12 to (m_size - 32) step 32
if memblock dword(2,i + 20) = 0
x1# = memblock float(2,i) : y1# = memblock float(2,i + 4) : z1# = memblock float(2,i + 8)
set vertexdata position a,x1#,y1#,z1#
inc a,1
endif
next i
rem and finally, write the indexdata
a = 0
For i = 12 to (m_size - 32) step 32
index_value = memblock dword(2,i + 16)
set indexdata (a),index_value
inc a,1
next i
unlock vertexdata
make object id,1,0
save mesh "mb_afterweld_obj"+str$(id)+".x",1
delete mesh 1
delete memblock 1
delete memblock 2
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
rem right now, this just a planar type mapping
If texture_mode = 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
a = get vertexdata index count()
for i = 0 to a
set vertexdata uv i, get vertexdata position x(i) / u#, 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 tw_time# = (b_time# - a_time#) * .001
endfunction