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#