Here are some somewhat useful matrix to object type functions that may be useful.
Matrix_to_Object converts a matrix into an object.
align_Obj_side aligns the sides of 2 specified matrix objects on the 2 sides specified.
get_obj_min_vert gets the minimum vert position on the axis specified for the object specified.
get_obj_max_vert gets the maximum vert position on the axis specified for the object specified.
`Main Source File
sync on : sync rate 0
autocam off
`start position and angle for camera
position camera 500, 1000, -500
point camera 500, 0, 500
`define constants for sides
#constant leftside 1
#constant nearside 2
#constant rightside 3
#constant farside 4
`define constants for axi
#constant x_axis 1
#constant y_axis 2
#constant z_axis 3
`default value for aligning terrains
skp = 0
`load enough images to texture each tile
load image "grass2a.png", 1
load image "grass2b.png", 2
load image "grass2c.png", 3
load image "grass2d.png", 4
load image "grass2e.png", 5
load image "grass2f.png", 6
load image "grass2g.png", 7
load image "grass2h.png", 8
load image "grass2i.png", 9
`make randomized matrix obbjects
for i = 1 to 4
`maker matrix to convert
make matrix 1, 1000, 1000, 24, 24
randomize matrix 1, 60
`prepare matrix texture 1, 1, 1, 1
update matrix 1
`convert matrix to object, usage is as follows
`command(objnum, matnum, matxsize, matzsize, matxsegs, matzsegs, tex_x_tiles, tex_z_tiles, limb_x_tiles, limb_z_tiles, begtexnum, endtexnum)
Matrix_to_Object( i, 1, 1000, 1000, 24, 24, 8, 8, 8, 8, 1, 9 )
delete matrix 1
next i
`arrange the terrains in a 2x2 grid
`the object size commands seem to be bugged when making objects from meshs
`you can save the object and reload and it works fine. I'll just use 1000
`for the example.
`tersizex# = object size x(1)
`tersizez# = object size z(1)
tersizex# = 1000
tersizez# = 1000
position object 1, 0, 0, 0
position object 2, tersizex#, 0, 0
position object 3, 0, 0, tersizez#
position object 4, tersizex#, 0, tersizez#
`main loop
do
`mlook
rotate camera camera angle x()+(mousemovey()/2),camera angle y()+(mousemovex()/2),0
if camera angle x()>90 then xrotate camera 90
if camera angle x()<-90 then xrotate camera -90
cx#=camera angle x() : cy#=camera angle y() : cz#=camera angle z()
`simple movement (arrow key free flight with strafe)
if upkey()=1
move camera 3
endif
if downkey()=1
move camera -3
endif
if rightkey()=1
xrotate camera 0: yrotate camera cy# + 90: move camera 3: xrotate camera cx#: yrotate camera cy#
endif
if leftkey()=1
xrotate camera 0: yrotate camera cy# - 90: move camera 3: xrotate camera cx#: yrotate camera cy#
endif
`line up terrains
if spacekey()=1
if skp = 0
skp = 1
`usage for function (source obj, dest obj, source side, dest side)
align_Obj_side( 1, 2, rightside, leftside )
align_Obj_side( 1, 3, farside, nearside )
align_Obj_side( 2, 4, farside, nearside )
align_Obj_side( 3, 4, rightside, leftside )
endif
endif
`simple messages
set cursor 5,5
if skp = 0
print "Press spacekey to line up terrains."
else
print "Terrains Aligned"
endif
`update screen
sync
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#
[edit] And here is the matrix to object code modified to create a carpet object to place on a matrix.
`Main Source File
sync on : sync rate 0
autocam off
`start position and angle for camera
position camera 500, 1000, -500
point camera 500, 0, 500
`load enough images to texture each tile
load image "grass2a.png", 1
load image "grass2b.png", 2
`maker matrix to convert
make matrix 1, 1000, 1000, 24, 24
randomize matrix 1, 60
prepare matrix texture 1, 1, 1, 1
update matrix 1
`make Carpet Object from Matrix, usage is as follows
`command(objnum, matnum, matxsize, matzsize, matxsegs, matzsegs, carpet_tile_x, carpet_tile_z, carpet_width, carpet_depth )
Matrix_Carpet_Object( 1, 1, 1000, 1000, 24, 24, 9, 11, 6, 3 )
do
`when pressed hide new object to see matrix
if spacekey()=1
hide object 1
else
show object 1
endif
`when pressed bring matrix up to match object's height
if returnkey()=1
position matrix 1, 0, -100, 0
else
position matrix 1, 0, 0, 0
endif
`mlook
rotate camera camera angle x()+(mousemovey()/2),camera angle y()+(mousemovex()/2),0
if camera angle x()>90 then xrotate camera 90
if camera angle x()<-90 then xrotate camera -90
cx#=camera angle x() : cy#=camera angle y() : cz#=camera angle z()
`simple movement (arrow key free flight with strafe)
if upkey()=1
move camera 3
endif
if downkey()=1
move camera -3
endif
if rightkey()=1
xrotate camera 0: yrotate camera cy# + 90: move camera 3: xrotate camera cx#: yrotate camera cy#
endif
if leftkey()=1
xrotate camera 0: yrotate camera cy# - 90: move camera 3: xrotate camera cx#: yrotate camera cy#
endif
sync
loop
function Matrix_Carpet_Object( objnum, matrixnum, matxsize#, matzsize#, matxsegs, matzsegs, carpet_tile_x, carpet_tile_z, carpet_width, carpet_depth )
`calc the number of polys in the carpet
num_carp_polys = (carpet_width*carpet_depth)*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_carp_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 = carpet_tile_z-1 to carpet_tile_z + carpet_depth-2
`one tile at a time (left to right)
for i = carpet_tile_x-1 to carpet_tile_x + carpet_width-2
`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)+.1
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)+.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)+.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)+.1
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)+.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)+.1
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_carp_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/carpet_width)
`calc how much to step each v data per tile
stepv# = (1.0/carpet_depth)
`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 carpet_depth
`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 carpet_width
`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 > carpet_width
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 > carpet_depth
basev# = 1-stepv#
ztiles = 1
endif
`next z tile
next k
`******************************************************************************
`******************************************************************************
`make object from matrix verts
`calc the memblock size
`formula is 12 byte header + (( 32 bytes per vert * num_carp_polys) * 3 verts per poly)
mat_mem_size = 12+((32*num_carp_polys)*3)
`make memblocks and write headers for each memblock and set the beginning
`position for vert data to 12
make memblock 1, mat_mem_size
`write objects fvf format as 274
write memblock dword 1, 0, 274
`write bytes per vert as 32 (8 floats xpos#,ypos#,zpos#,xnorm#,ynorm#,znorm#,u#,v#)
write memblock dword 1, 4, 32
`write number of verts in matrix (polys*3)
write memblock dword 1, 8, num_carp_polys*3
`set beginning position for vert data after header(0-8)+4 = 12
a = 12
`enter all polys' verts to memblock
for i = 1 to num_carp_polys
`write all 3 verts of each matrix poly
for j = 0 to 2
`xpos
write memblock float 1, a, vert_store#(i,j,0)
`increment the current memblock position
inc a, 4
`ypos
write memblock float 1, a, vert_store#(i,j,1)
inc a, 4
`zpos
write memblock float 1, a, vert_store#(i,j,2)
inc a, 4
`xnorm
write memblock float 1, a, vert_store#(i,j,3)
inc a, 4
`ynorm
write memblock float 1, a, vert_store#(i,j,4)
inc a, 4
`znorm
write memblock float 1, a, vert_store#(i,j,5)
inc a, 4
`u data
write memblock float 1, a, vert_store#(i,j,6)
inc a, 4
`v data
write memblock float 1, a, vert_store#(i,j,7)
inc a, 4
next j
next i
`undim arrays when done with them
undim vert_store#(0,0,0)
`set the mesh number to use (can be replaced with a findfreemesh function)
mesh = 1
`make temp mesh from info
make mesh from memblock mesh, 1
`delete temp memblock
delete memblock 1
`make and texture carpet object
make object objnum, 1, 2
`delete mesh
delete mesh 1
`******************************************************************************
endfunction