Well, I've been busy

I decided to take the plunge and learn memblocks, which now that I have, I don't see how you can make anything serious without them. So, if you haven't used them, you better learn them, because you'll be glad you did. so, I decided to see if I could write the make_grid() function using memblocks. That was a success, and it works so well, I'll post it in the code snippets. So then I decided to try to do the weld_vertices() function. It too was a success, kind of. It doesn't really do it faster, in fact, it is slower with really large objects. But if all you are doing is primitives, which is what this whole thread was about anyway, then it does them lickety split. The biggest primitive you can have is a sphere, and it's limited to about 1100 verts in the vertexdata, so it can handle it. (100 cols x 100 rows). I know where the lag is in the code, its the two loops that search for the duplicates and order the indexes. I think its because I'm doing the loop and compares on the same memblock. I have an idea how I can speed it up by making a third memblock, and comparing between the two, but for now, this just proves it can be done. Oh, and the advantage so far over the old way, you don't need any global variables or types.
+ Code Snippetfunction 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
If you just add this function to the examples I already posted, then call this function with the parameters id(your object id) and texture_mode(0 for no UV map, 1 for stretch UV map), it should go. I commented it pretty good, and even have some file writing code in there so you can see what is going on in the memblock. Have fun.
EDITED TO ADD:
BTW, you must only use objects with an FVF format of 274, which is the standard format in DBPro. This can easily be modified for format 338 if need be, in fact it is on my list to do to check for format, and do either 274 or 338, and reject anything else.