REM Project: Compo entry REM Created: 24/05/2006 19:33:22 REM REM ***** Main Source File ***** save=0 REM input "Filename: ", file$ Cls text 10, 10, "Map: "+file$ make matrix 1, 1000, 1000, 100, 100 SET MATRIX WIREFRAME ON 1 do if mouseclick()=1 then input "X segment: ", X$ if mouseclick()=2 then input "Z segment: ", Z$ if controlkey()=1 then input "Height: ", Height$ SET MATRIX HEIGHT 1, val(X$), val(Z$), val(Height$) update matrix 1 if spacekey()=1 then Matrix_to_object(1, 1, 1000, 1000, 100, 100, 100, 100, 100, 100, 0, 0) : save object file$+".dbo", 1 : inc save, 1 if save=1 and object exist(1) then Text 10, 10, "Save failed" control camera using arrowkeys 0, 1, 1 loop `convert a matrix to an object function Matrix_to_Object( object, matrixnum, matxsize#, matzsize#, matxsegs, matzsegs, tilex, tilez, limbx, limbz, begtexnum, endtexnum ) `safety in case matxsegs and matzsegs is not evenly divisible by tilex and tilez if matxsegs mod tilex > 0 EXIT PROMPT "Number of matrix xsegs not evenly divisible by tilex", "Texture tilex error" end endif if matzsegs mod tilez > 0 EXIT PROMPT "Number of matrix zsegs not evenly divisible by tilez", "Texture tilez error" end endif `safety in case limbx and limbz is smaller than the texture x and z a = 0 if limbx < tilex then limbx = tilex : a = 1 if limbz < tilez then limbz = tilez : a = 1 if a > 0 sync print "limbx or limbz was less than tilex or tilez : Error corrected" sync wait key endif `calc the number of polys in the matrix num_mat_polys = (matxsegs*matzsegs)*2 `make array to store vert info `storage indexs = poly number, vert number, x/y/z vert pos/norm/uv `polys are numbered starting from left to right, front to `back, one row at a time (with 2 polys per tile) dim vert_store#(num_mat_polys,2,7) `calc the width and depth of each tile on the matrix `formula size#/number mat_x_wide# = matxsize#/matxsegs mat_z_deep# = matzsize#/matzsegs `****************************************************************************** `get vert position data `placeholder variable for poly numbers a = 1 `one row at a time (front to back) for j = 0 to matzsegs - 1 `one tile at a time (left to right) for i = 0 to matxsegs - 1 `tile top left poly info `bottom left vert (x,y,z) vert_store#(a,0,0) = i*mat_x_wide# vert_store#(a,0,1) = GET MATRIX HEIGHT(matrixnum, i, j) vert_store#(a,0,2) = j*mat_z_deep# `top left vert (x,y,z) vert_store#(a,1,0) = i*mat_x_wide# vert_store#(a,1,1) = GET MATRIX HEIGHT(matrixnum, i, j+1) vert_store#(a,1,2) = (j+1)*mat_z_deep# `top right vert (x,y,z) vert_store#(a,2,0) = (i+1)*mat_x_wide# vert_store#(a,2,1) = GET MATRIX HEIGHT(matrixnum, i+1, j+1) vert_store#(a,2,2) = (j+1)*mat_z_deep# inc a, 1 `tile bottom right poly info `bottom left vert (x,y,z) vert_store#(a,0,0) = i*mat_x_wide# vert_store#(a,0,1) = GET MATRIX HEIGHT(matrixnum, i, j) vert_store#(a,0,2) = j*mat_z_deep# `top right vert (x,y,z) vert_store#(a,1,0) = (i+1)*mat_x_wide# vert_store#(a,1,1) = GET MATRIX HEIGHT(matrixnum, i+1, j+1) vert_store#(a,1,2) = (j+1)*mat_z_deep# `bottom right vert (x,y,z) vert_store#(a,2,0) = (i+1)*mat_x_wide# vert_store#(a,2,1) = GET MATRIX HEIGHT(matrixnum, i+1, j) vert_store#(a,2,2) = j*mat_z_deep# inc a, 1 next i next j `****************************************************************************** `****************************************************************************** `calc normals for polys `Thanks to ADR for posting this code on the DBP forums :) for i = 1 to num_mat_polys `acuire vert positions P1X# = vert_store#(i,0,0) P1Y# = vert_store#(i,0,1) P1Z# = vert_store#(i,0,2) P2X# = vert_store#(i,1,0) P2Y# = vert_store#(i,1,1) P2Z# = vert_store#(i,1,2) P3X# = vert_store#(i,2,0) P3Y# = vert_store#(i,2,1) P3Z# = vert_store#(i,2,2) null = make vector3(1) null = make vector3(2) null = make vector3(3) ` -- calculate the two directional vectors for the adj and opp edges... set vector3 1, P1X#, P1Y#, P1Z# set vector3 2, P2X#, P2Y#, P2Z# set vector3 3, P3X#, P3Y#, P3Z# subtract vector3 2, 2, 1 subtract vector3 3, 3, 1 ` -- vector 3 and 1 are now directional vectors normalize vector3 2,2 ` -- normalize em normalize vector3 3,3 cross product vector3 1, 2,3 ` -- use the origin vector (1) to store the face normal normalize vector3 1,1 `save normals (all 3 verts have same normals) vert_store#(i,0,3) = x vector3(1) vert_store#(i,0,4) = y vector3(1) vert_store#(i,0,5) = z vector3(1) vert_store#(i,1,3) = vert_store#(i,0,3) vert_store#(i,1,4) = vert_store#(i,0,4) vert_store#(i,1,5) = vert_store#(i,0,5) vert_store#(i,2,3) = vert_store#(i,0,3) vert_store#(i,2,4) = vert_store#(i,0,4) vert_store#(i,2,5) = vert_store#(i,0,5) null = delete vector3(1) null = delete vector3(2) null = delete vector3(3) next i `****************************************************************************** `****************************************************************************** `calc UV data for polys `save current x tile number xtiles = 1 `save current z tile number ztiles = 1 `calc how much to step each u data per tile stepu# = (1.0/tilex) `calc how much to step each v data per tile stepv# = (1.0/tilez) `set base u data for new set of tiles baseu# = 0 `set base v data for new set of tiles basev# = 1-stepv# `poly number placeholder variable i = 1 `from front to back for k = 1 to matzsegs `reset the number of x tiles to 1 and the u base to 0 `at the beginning of each row xtiles = 1 baseu# = 0 `from left to right for l = 1 to matxsegs `2 polys per tile for m = 1 to 2 `write all 3 verts of each matrix poly for j = 0 to 2 `select which formula to apply depending on polygon side `and vert number (0 to 2) `j selects the vert number `m selects the polygon side (back/left or front right : 1 or 2) select j case 0 if m = 1 testu# = baseu# testv# = basev#+stepv# else testu# = baseu# testv# = basev#+stepv# endif endcase case 1 if m = 1 testu# = baseu# testv# = basev# else testu# = baseu#+stepu# testv# = basev# endif endcase case 2 if m = 1 testu# = baseu#+stepu# testv# = basev# else testu# = baseu#+stepu# testv# = basev#+stepv# endif endcase endselect `store calculated data for each vert of each poly `u data vert_store#(i,j,6) = testu# `v data vert_store#(i,j,7) = testv# next j inc i, 1 `next polygon side of this tile next m `update u data and xtiles place holder inc baseu#, stepu# inc xtiles, 1 `reset data when texture tile width has been reached if xtiles > tilex baseu# = 0 xtiles = 1 endif `next x tile next l `update v data and ztiles place holder dec basev#, stepv# inc ztiles, 1 `reset data when texture depth has been reached if ztiles > tilez basev# = 1-stepv# ztiles = 1 endif `next z tile next k `****************************************************************************** `****************************************************************************** `make object from matrix verts `calc number of memblocks needed tempx = matxsegs/limbx tempz = matzsegs/limbz tempmem = tempx * tempz `make arrays to store memblock positions and memblock numbers dim membhold(tempx, tempz) dim mempos(tempmem) `enter memblock numbers for each texture tile based on the x and z limbs to use a = 1 for i = 1 to tempz for j = 1 to tempx membhold(j, i) = a inc a, 1 next j next i `calc the memblock size `formula is 12 byte header + ((( 32 bytes per vert * limb x segs)*(limb z segs * 2 polys))* 3 verts per poly) mat_mem_size = 12+(((32*limbx)*(limbz*2))*3) `make memblocks and write headers for each memblock and set the beginning `position for vert data to 12 for i = 1 to tempmem make memblock i, mat_mem_size `write objects fvf format as 274 write memblock dword i, 0, 274 `write bytes per vert as 32 (8 floats xpos#,ypos#,zpos#,xnorm#,ynorm#,znorm#,u#,v#) write memblock dword i, 4, 32 `write number of verts in matrix (polys*3) write memblock dword i, 8, ((limbx*limbz)*2)*3 `set beginning position for vert data after header(0-8)+4 = 12 mempos(i) = 12 next i `image tile, row, and memblock placeholders xtile = 1 ztile = 1 xrow = 1 xmem = 1 zmem = 1 `polygon placeholders (b=2 is 1 tile complete) b = 1 `enter all polys' verts to memblock for i = 1 to num_mat_polys `select memblock number to write to use current x and z limb tile to pick tempmemnum = membhold(xmem, zmem) `write all 3 verts of each matrix poly for j = 0 to 2 `xpos write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,0) `increment the current memblock position inc mempos(tempmemnum), 4 `ypos write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,1) inc mempos(tempmemnum), 4 `zpos write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,2) inc mempos(tempmemnum), 4 `xnorm write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,3) inc mempos(tempmemnum), 4 `ynorm write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,4) inc mempos(tempmemnum), 4 `znorm write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,5) inc mempos(tempmemnum), 4 `u data write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,6) inc mempos(tempmemnum), 4 `v data write memblock float tempmemnum, mempos(tempmemnum), vert_store#(i,j,7) inc mempos(tempmemnum), 4 next j `after each poly increase b by 1 inc b, 1 `after 2 polys have been completed 1 tile has been entered if b > 2 `reset poly count to 1 b = 1 `move to next x tile inc xtile, 1 `if at the next limb if xtile > limbx `reseet the x tile to 1 xtile = 1 `update the tile count to know when to move to the next row inc xrow, limbx `inc the xmem selector placeholder inc xmem, 1 `if at the last xmem wide then start back at the begining if xmem > tempx xmem = 1 endif endif `when at the end of the row if xrow > matxsegs `go back to the far left xrow = 1 `update the number of rows done inc ztile, 1 `when the number of rows done is > the preset depth if ztile > limbz `reset row count back to 1 ztile = 1 `move to the next zmem selector placeholder inc zmem, 1 `if row count overlaps predetermined number if zmem > tempz `wrap to 1 zmem = 1 endif endif endif endif next i `undim arrays when done with them undim vert_store#(0,0,0) undim membhold(0, 0) undim mempos(0) `set the mesh number to use (can be replaced with a findfreemesh function) mesh = 1 `make object and limbs from data setup for i = 1 to tempmem `make temp mesh from info make mesh from memblock mesh, i `delete temp memblock delete memblock i `if it is the first memblock mesh, use it as the base object if i = 1 `make temp object for NGC make object object, mesh, begtexnum `else turn each memblock mesh into limbs else add limb object, i-1, mesh endif `delete temp mesh delete mesh mesh next i `texture limbs j = begtexnum + 1 for i = 2 to tempmem texture limb object, i-1, j inc j, 1 if j > endtexnum then j = begtexnum next i `unrem this to make the lighting look exactly like a matrix `set object light object, 0 `****************************************************************************** endfunction `align the specified objects to the specified side function align_Obj_side( source as integer, dest as integer, source_side as integer, dest_side as integer ) `get the vert position to test source for depending on side to line up select source_side `if side = 1 or left side test for the x axis min case 1 vertpos1# = get_obj_min_vert( source, x_axis ) endcase `if side = 2 or near side test for the z axis min case 2 vertpos1# = get_obj_min_vert( source, z_axis ) endcase `if side = 3 or right side test for the x axis max case 3 vertpos1# = get_obj_max_vert( source, x_axis ) endcase `if side = 4 or far side test for the z axis max case 4 vertpos1# = get_obj_max_vert( source, z_axis ) endcase endselect `get the vert position to test dest for depending on side to line up `uses same testing as above but stores to different variable select dest_side case 1 vertpos2# = get_obj_min_vert( dest, x_axis ) endcase case 2 vertpos2# = get_obj_min_vert( dest, z_axis ) endcase case 3 vertpos2# = get_obj_max_vert( dest, x_axis ) endcase case 4 vertpos2# = get_obj_max_vert( dest, z_axis ) endcase endselect `get the number of limbs in both objects for testing perform checklist for object limbs source sourcelimbqty = checklist quantity()-1 empty checklist perform checklist for object limbs dest destlimbqty = checklist quantity()-1 empty checklist `dim arrays to store vert info dim tempinfo#(0,3) dim tempvert(0) `dim array to tell which destination limbs need updating dim limbused(destlimbqty) for i = 0 to destlimbqty limbused(i) = 0 next i `set placeholder vars matches = 0 matched = 0 updated = 0 matches_found = 0 rem Lock up source object data to obtain heights (quick means refresh or recreate) QuickRefreshFlag=1 `cycle through limbs for j = 0 to sourcelimbqty LOCK VERTEXDATA FOR LIMB source, j, QuickRefreshFlag `cycle through each limb's verts for V = 0 to GET VERTEXDATA VERTEX COUNT()-1 `gather info depending on the desired side select source_side `if side = 1 or left side test for the x axis min and save case 1 x1# = GET VERTEXDATA POSITION X(V) if x1# = vertpos1# `inc that you have found a matching vert and store info inc matches, 1 dim tempinfo#(matches,3) tempinfo#(matches,2)=GET VERTEXDATA POSITION Y(V) endif endcase `if side = 2 or near side test for the z axis min and save case 2 z1# = GET VERTEXDATA POSITION Z(V) if z1# = vertpos1# `inc that you have found a matching vert and store info inc matches, 1 dim tempinfo#(matches,3) tempinfo#(matches,2)=GET VERTEXDATA POSITION Y(V) endif endcase `if side = 3 or right side test for the x axis max and save case 3 x1# = GET VERTEXDATA POSITION X(V) if x1# = vertpos1# `inc that you have found a matching vert and store info inc matches, 1 dim tempinfo#(matches,3) tempinfo#(matches,2)=GET VERTEXDATA POSITION Y(V) endif endcase `if side = 4 or far side test for the z axis max and save case 4 z1# = GET VERTEXDATA POSITION Z(V) if z1# = vertpos1# `inc that you have found a matching vert and store info inc matches, 1 dim tempinfo#(matches,3) tempinfo#(matches,2)=GET VERTEXDATA POSITION Y(V) endif endcase endselect next V `store the number of matches per limb for later use `since I build the objects evenly it will be the same for each limb `and object if matches_found = 0 if matches > 0 num_matches = matches matches_found = 1 endif endif `unlock data when finished to do next limb UNLOCK VERTEXDATA next j rem Lock up dest object data to capture info on what needs updating for j = 0 to destlimbqty LOCK VERTEXDATA FOR LIMB dest, j, QuickRefreshFlag for V = 0 to GET VERTEXDATA VERTEX COUNT()-1 select dest_side `if side = 1 or left side test for the x axis min and save case 1 x2# = GET VERTEXDATA POSITION X(V) if x2# = vertpos2# inc matched, 1 dim tempvert(matched) tempvert(matched) = V limbused(j) = 1 endif endcase `if side = 2 or near side test for the z axis min and save case 2 z2# = GET VERTEXDATA POSITION Z(V) if z2# = vertpos2# inc matched, 1 dim tempvert(matched) tempvert(matched) = V limbused(j) = 1 endif endcase `if side = 3 or right side test for the x axis max and save case 3 x2# = GET VERTEXDATA POSITION X(V) if x2# = vertpos2# inc matched, 1 dim tempvert(matched) tempvert(matched) = V limbused(j) = 1 endif endcase `if side = 4 or far side test for the z axis max and save case 4 z2# = GET VERTEXDATA POSITION Z(V) if z2# = vertpos2# inc matched, 1 dim tempvert(matched) tempvert(matched) = V limbused(j )= 1 endif endcase endselect next V `unlock data when finished to do next limb UNLOCK VERTEXDATA next j `update vert positions that need it old = 1 `check all limbs of destination object that need it for j = 0 to destlimbqty `if limb needs updating then do so else skip it if limbused(j) = 1 LOCK VERTEXDATA FOR LIMB dest, j, QuickRefreshFlag `use the old var to tell when to move to another limb `use the matched var to make sure you don't go too far. for i = old to matched `since the verts are on opposite sides of the objects to line up `they will be in a different order to write than found `use the updated flag to set the order inc updated, 1 if updated > 3 then updated = 1 `select vert order to write depending on the side chosen if dest_side = leftside and source_side = rightside `the vert order will be written in 1,2,3 order `but copied from 3,2,3 order if updated = 1 temp = tempvert(i) tempx# = GET VERTEXDATA POSITION X(temp) tempz# = GET VERTEXDATA POSITION Z(temp) SET VERTEXDATA POSITION temp, tempx#, tempinfo#(i+2,2), tempz# endif if updated = 2 temp = tempvert(i) tempx# = GET VERTEXDATA POSITION X(temp) tempz# = GET VERTEXDATA POSITION Z(temp) SET VERTEXDATA POSITION temp, tempx#, tempinfo#(i,2), tempz# endif if updated = 3 temp = tempvert(i) tempx# = GET VERTEXDATA POSITION X(temp) tempz# = GET VERTEXDATA POSITION Z(temp) SET VERTEXDATA POSITION temp, tempx#, tempinfo#(i,2), tempz# endif endif if dest_side = nearside and source_side = farside `the vert order will be written in 1,2,3 order `but copied from 1,1,3 order if updated = 1 temp = tempvert(i) tempx# = GET VERTEXDATA POSITION X(temp) tempz# = GET VERTEXDATA POSITION Z(temp) SET VERTEXDATA POSITION temp, tempx#, tempinfo#(i,2), tempz# endif if updated = 2 temp = tempvert(i) tempx# = GET VERTEXDATA POSITION X(temp) tempz# = GET VERTEXDATA POSITION Z(temp) SET VERTEXDATA POSITION temp, tempx#, tempinfo#(i-1,2), tempz# endif if updated = 3 temp = tempvert(i) tempx# = GET VERTEXDATA POSITION X(temp) tempz# = GET VERTEXDATA POSITION Z(temp) SET VERTEXDATA POSITION temp, tempx#, tempinfo#(i,2), tempz# endif endif if dest_side = rightside and source_side = leftside `the vert order will be written in 1,2,3 order `but copied from 2,2,3 order if updated = 1 temp = tempvert(i) tempx# = GET VERTEXDATA POSITION X(temp) tempz# = GET VERTEXDATA POSITION Z(temp) SET VERTEXDATA POSITION temp, tempx#, tempinfo#(i+1,2), tempz# endif if updated = 2 temp = tempvert(i) tempx# = GET VERTEXDATA POSITION X(temp) tempz# = GET VERTEXDATA POSITION Z(temp) SET VERTEXDATA POSITION temp, tempx#, tempinfo#(i,2), tempz# endif if updated = 3 temp = tempvert(i) tempx# = GET VERTEXDATA POSITION X(temp) tempz# = GET VERTEXDATA POSITION Z(temp) SET VERTEXDATA POSITION temp, tempx#, tempinfo#(i,2), tempz# endif endif if dest_side = farside and source_side = nearside `the vert order will be written in 1,2,3 order `but copied from 1,3,3 order if updated = 1 temp = tempvert(i) tempx# = GET VERTEXDATA POSITION X(temp) tempz# = GET VERTEXDATA POSITION Z(temp) SET VERTEXDATA POSITION temp, tempx#, tempinfo#(i,2), tempz# endif if updated = 2 temp = tempvert(i) tempx# = GET VERTEXDATA POSITION X(temp) tempz# = GET VERTEXDATA POSITION Z(temp) SET VERTEXDATA POSITION temp, tempx#, tempinfo#(i+1,2), tempz# endif if updated = 3 temp = tempvert(i) tempx# = GET VERTEXDATA POSITION X(temp) tempz# = GET VERTEXDATA POSITION Z(temp) SET VERTEXDATA POSITION temp, tempx#, tempinfo#(i,2), tempz# endif endif `when you have written all ofthe changes for this limb move `on to the next if i = old + (num_matches - 1) old = i + 1 exit endif next i UNLOCK VERTEXDATA endif next j `undim no longer needed arrays undim tempinfo#(0) undim tempvert(0) undim limbused(0) endfunction `get the min vert position for an object axi are 1=x 2=y 3=z function get_obj_min_vert( obj as integer, axis as integer ) `get the number of limbs to test for lowest vert positions perform checklist for object limbs obj limbqty = checklist quantity() empty checklist rem Lock and manipulate main object data (quick means refresh or recreate) QuickRefreshFlag=1 `search through every limb's verts for the min positions to tell `whick is the left, near, or bottom side for j = 0 to limbqty-1 LOCK VERTEXDATA FOR LIMB Obj, j, QuickRefreshFlag for V=0 to GET VERTEXDATA VERTEX COUNT()-1 if V = 0 and j = 0 if axis = x_axis min#=GET VERTEXDATA POSITION X(V) endif if axis = y_axis min#=GET VERTEXDATA POSITION Y(V) endif if axis = z_axis min#=GET VERTEXDATA POSITION Z(V) endif else if axis = x_axis nmin#=GET VERTEXDATA POSITION X(V) endif if axis = y_axis nmin#=GET VERTEXDATA POSITION Y(V) endif if axis = z_axis nmin#=GET VERTEXDATA POSITION Z(V) endif if nmin# < min# then min# = nmin# endif next V UNLOCK VERTEXDATA next j endfunction min# `get the max vert position for an object axi are 1=x 2=y 3=z function get_obj_max_vert( obj as integer, axis as integer ) `get the number of limbs to test for highest vert positions perform checklist for object limbs obj limbqty = checklist quantity() empty checklist rem Lock and manipulate main object data (quick means refresh or recreate) QuickRefreshFlag=1 `search through every limb's verts for the max positions to tell `whick is the right, far, or top side for j = 0 to limbqty-1 LOCK VERTEXDATA FOR LIMB Obj, j, QuickRefreshFlag for V=0 to GET VERTEXDATA VERTEX COUNT()-1 if V = 0 and j = 0 if axis = x_axis max#=GET VERTEXDATA POSITION X(V) endif if axis = y_axis max#=GET VERTEXDATA POSITION Y(V) endif if axis = z_axis max#=GET VERTEXDATA POSITION Z(V) endif else if axis = x_axis nmax#=GET VERTEXDATA POSITION X(V) endif if axis = y_axis nmax#=GET VERTEXDATA POSITION Y(V) endif if axis = z_axis nmax#=GET VERTEXDATA POSITION Z(V) endif if nmax# > max# then max# = nmax# endif next V UNLOCK VERTEXDATA next j endfunction max#