DarkBASIC Professional Matrix Command Set

Miscellaneous Forums/Blitz Showcase/DarkBASIC Professional Matrix Command Set

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

Hehe, yep the title is right.

This is the DarkBASIC Professional matrix commands recreated in Blitz3D for the heck of it, just incase any DBP deserters missed them :)

The new B3D commands do not have spaces in the names:

Convert Commands
MAKE MATRIX Matrix Number, Width, Height, XSegments, ZSegments
DELETE MATRIX Matrix Number
PREPARE MATRIX TEXTURE Matrix Number, Image Number, Across, Down
POSITION MATRIX Matrix Number, X, Y, Z
FILL MATRIX Matrix Number, Height, Tile Number
RANDOMIZE MATRIX Matrix Number, Maximum Height
GHOST MATRIX ON Matrix Number[,2] (,2 reverse ghosts)
GHOST MATRIX OFF Matrix Number
SHIFT MATRIX DOWN Matrix Number
SHIFT MATRIX LEFT Matrix Number
SHIFT MATRIX RIGHT Matrix Number
SHIFT MATRIX UP Matrix Number
SET MATRIX HEIGHT Matrix Number, TileX, TileZ, Height
SET MATRIX NORMAL Matrix Number, TileX, TileZ, NX, NY, NZ
SET MATRIX TILE Matrix Number, TileX, TileZ, Tile Number
UPDATE MATRIX Matrix Number
=MATRIX EXIST(Matrix Number)
=MATRIX POSITION X(Matrix Number)
=MATRIX POSITION Y(Matrix Number)
=MATRIX POSITION Z(Matrix Number)
=MATRIX TILE COUNT(Matrix Number)
=MATRIX TILES EXIST(Matrix Number)
*=GET GROUND HEIGHT(Matrix Number, X, Z)
*=GET MATRIX HEIGHT(Matrix Number, TileX, TileZ)

Commands Not Included
SET MATRIX WIREFRAME ON Matrix Number
SET MATRIX WIREFRAME OFF Matrix Number
SET VECTOR3 TO MATRIX POSITION Vector, Matrix Number
SET MATRIX TEXTURE Matrix Number, Texture Mode, Mip Mode
SET MATRIX Matrix Number, Wire, Transparency, Cull, Filter, Light, Fog, Ambient
=MATRIX WIREFRAME STATE(Matrix Number)

Extra Commands Included
NORMALISE MATRIX Matrix Number
...Sets normals automatically
COLLISION MODE ON Matrix Number
...Sets matrix to Blitz style polygonal collision
*=GET COLLISION HEIGHT Matrix Number, X, Z
...Performs a collision test
COLLISION MODE OFF Matrix Number
...Turns off Blitz style polygonal collision

*returns an integer, but value also loaded into variable "height#" which can be globalised for float return.

Type matrix
	Field id,bank,ent,surface
	Field xSeg,zSeg
	Field xSize#,zSize
	Field tileSX#,tileSZ#

	Field texture
	Field tileCount
End Type
Type matrixTileTexture
	Field id
	Field tile
	Field u#,v#
	Field uM#,vM#
End Type

Const MatrixTileBankBit=14

;Demo & Test Program
Global height#
Graphics3D 800,600,0,2
SetBuffer BackBuffer()

makeMatrix(1,5000,5000,50,50)
texture=LoadTexture("D:\Banshee\MightyEmpires\Gfx\terrain.jpg",1+16+32)
prepareMatrixTexture(1,texture,4,4)
fillMatrix(1,5,0)
randomizeMatrix(1,100)
ghostMatrixOn(1)
ghostMatrixOff(1)
setMatrixHeight(1,25,25,0)
setMatrixHeight(1,26,25,0)
setMatrixHeight(1,25,26,0)
setMatrixHeight(1,26,26,0)
setMatrixTile(1,25,25,3)
updateMatrix(1)

collisionModeOn(1)

camera=CreateCamera()
CameraRange camera,.1,5000
PositionEntity camera,0,10,0
Repeat
	If KeyDown(200) Then MoveEntity camera,0,0,1
	If KeyDown(208) Then MoveEntity camera,0,0,-1
	If KeyDown(203) Then TurnEntity camera,0,1,0
	If KeyDown(205) Then TurnEntity camera,0,-1,0

	If KeyDown(57)
		shiftMatrixDown(1)
		updateMatrix(1)
	EndIf

	getCollisionHeight(1,EntityX(camera),EntityZ(camera))
;	getGroundHeight(1,EntityX(camera),EntityZ(camera))
	PositionEntity camera,EntityX(camera),height+3,EntityZ(camera)
	
	RenderWorld
	landscape.matrix=First matrix
	Flip 0
Until KeyDown(1)
;end Demo




Function makeMatrix(id,xSize#,zSize#,xSegs,zSegs)
	If (xSegs*zSegs*4)-1>32768 Then RuntimeError("Matrix <"+id+"> exceeds vertex limit")

	landscape.matrix=New matrix
	landscape\id=id
	landscape\bank=CreateBank((xSegs+1)*(zSegs+1)*MatrixTileBankBit)
	landscape\ent=CreateMesh()
	landscape\surface=CreateSurface(landscape\ent)
	
	landscape\xSeg=xSegs
	landscape\zSeg=zSegs
	landscape\xSize=xSize
	landscape\zSize=zSize
	landscape\tileSX=Float(xSize)/xSegs
	landscape\tileSZ=Float(zSize)/zSegs
	
	For x=0 To xSegs-1
		For z=0 To zSegs-1
			bankPos=((x* landscape\zSeg)+z)*MatrixTileBankBit

			PokeShort landscape\bank,bankPos+0, AddVertex( landscape\surface, x*landscape\tileSX        ,0, z*landscape\tileSZ       , Float(x)/landscape\xSeg     ,Float(z)/landscape\zSeg )
			PokeShort landscape\bank,bankPos+2, AddVertex( landscape\surface, (x+1)*landscape\tileSX ,0, z*landscape\tileSZ       , Float(x+1)/landscape\xSeg ,Float(z)/landscape\zSeg )
			PokeShort landscape\bank,bankPos+4, AddVertex( landscape\surface, x*landscape\tileSX        ,0, (z+1)*landscape\tileSZ, Float(x)/landscape\xSeg     ,Float(z+1)/landscape\zSeg )
			PokeShort landscape\bank,bankPos+6, AddVertex( landscape\surface, (x+1)*landscape\tileSX ,0, (z+1)*landscape\tileSZ , Float(x+1)/landscape\xSeg,Float(z+1)/landscape\zSeg )

			AddTriangle landscape\surface,PeekShort(landscape\bank,bankPos+0),PeekShort(landscape\bank,bankPos+4),PeekShort(landscape\bank,bankPos+2)
			AddTriangle landscape\surface,PeekShort(landscape\bank,bankPos+2),PeekShort(landscape\bank,bankPos+4),PeekShort(landscape\bank,bankPos+6)
		Next
	Next
End Function
Function deleteMatrix(id)
	For landscape.matrix=Each matrix
		If landscape\id=id
			FreeBank landscape\bank
			FreeEntity landscape\ent
			If landscape\texture Then FreeTexture landscape\texture
			Delete landscape
		EndIf
	Next
End Function
Function prepareMatrixTexture(id,texture,xSegs,zSegs)
	pixelSizeU#=1.0/Float(TextureWidth(texture))
	pixelSizeV#=1.0/Float(TextureHeight(texture))

	For landscape.matrix=Each matrix
		If landscape\id=id
			landscape\texture=texture
			EntityTexture landscape\ent,landscape\texture
			
			For tex.matrixTileTexture=Each matrixTileTexture
				If tex\id=id Then Delete tex
			Next
			
			textureCount=xSegs*zSegs
			landscape\tileCount=textureCount
			x=0 : z=0 : tile=0
			u#=1.0/Float(xSegs)
			v#=1.0/Float(zSegs)
			
			For texture=0 To textureCount-1
				tex.matrixTileTexture=New matrixTileTexture
				tex\id=id

				tile=tile+1
				tex\tile=tile
				tex\u=x*u
				tex\v=z*v
				tex\uM=((x+1)*u)-pixelSizeU
				tex\vM=((z+1)*v)-pixelSizeV
				
				x=x+1
				If x=xSegs
					x=0
					z=z+1
				EndIf
			Next
		EndIf
	Next
End Function
Function positionMatrix(id,x#,y#,z#)
	For landscape.matrix=Each matrix
		If landscape\id=id
			PositionEntity landscape\id,x,y,z
		EndIf
	Next
End Function
Function fillMatrix(id,tile,height#=0.0)
	For landscape.matrix=Each matrix
		If landscape\id=id

			For x=0 To landscape\xSeg
				For z=0 To landscape\zSeg
					bankPos=((x* landscape\zSeg)+z)*MatrixTileBankBit
					PokeFloat landscape\bank,bankPos+8,height
					PokeShort landscape\bank,bankPos+12,tile
				Next
			Next

		EndIf
	Next
End Function
Function randomizeMatrix(id,height#)
	For landscape.matrix=Each matrix
		If landscape\id=id

			For x=0 To landscape\xSeg
				For z=0 To landscape\zSeg
					bankPos=((x* landscape\zSeg)+z)*MatrixTileBankBit
					PokeFloat landscape\bank,bankPos+8,Rnd(height)
				Next
			Next

		EndIf
	Next
End Function
Function ghostMatrixOn(id,mode=3)
	For landscape.matrix=Each matrix
		If landscape\id=id
			EntityBlend landscape\ent,mode
		EndIf
	Next
End Function
Function ghostMatrixOff(id,mode=1)
	For landscape.matrix=Each matrix
		If landscape\id=id
			EntityBlend landscape\ent,mode
		EndIf
	Next
End Function
Function setMatrixHeight(id,xSeg,zSeg,height#)
	For landscape.matrix=Each matrix
		If landscape\id=id
			PokeFloat landscape\bank,(((xSeg* landscape\zSeg)+zSeg)*MatrixTileBankBit)+8,height
		EndIf
	Next
End Function
Function setMatrixTile(id,xSeg,zSeg,tile)
	For landscape.matrix=Each matrix
		If landscape\id=id
			PokeShort landscape\bank,(((xSeg* landscape\zSeg)+zSeg)*MatrixTileBankBit)+12,tile
		EndIf
	Next
End Function
Function setMatrixNormal(id,xSeg,zSeg,nx#,ny#,nz#)
	For landscape.matrix=Each matrix
		If landscape\id=id
			bankPos=((xSeg* landscape\zSeg)+zSeg)*MatrixTileBankBit
			vertex=PeekShort(landscape\bank,bankPos+0)
			VertexNormal landscape\surface,vertex,nx,ny,nz
			vertex=PeekShort(landscape\bank,bankPos+2)
			VertexNormal landscape\surface,vertex,nx,ny,nz
			vertex=PeekShort(landscape\bank,bankPos+4)
			VertexNormal landscape\surface,vertex,nx,ny,nz
			vertex=PeekShort(landscape\bank,bankPos+6)
			VertexNormal landscape\surface,vertex,nx,ny,nz
		EndIf
	Next
End Function
Function normaliseMatrix(id)
	For landscape.matrix=Each matrix
		If landscape\id=id
			UpdateNormals landscape\ent
		EndIf
	Next
End Function
Function shiftMatrixLeft(id)
	For landscape.matrix=Each matrix
		If landscape\id=id
			oldBank=landscape\bank
			landscape\bank=CreateBank((landscape\xSeg+1)*(landscape\zSeg+1)*MatrixTileBankBit)
			
			For x=0 To landscape\xSeg
				destX=x-1
				If destX<0 Then destX=landscape\xSeg
				For z=0 To landscape\zSeg
					sourcePos=((x* landscape\zSeg)+z)*MatrixTileBankBit
					destPos=((destX* landscape\zSeg)+z)*MatrixTileBankBit
					For byte=0 To 7
						PokeByte landscape\bank,sourcePos+byte,PeekByte(oldBank,sourcePos+byte)
					Next
					For byte=8 To matrixTileBankBit-1
						PokeByte landscape\bank,destPos+byte,PeekByte(oldBank,sourcePos+byte)
					Next
				Next
			Next
			
			FreeBank oldBank
		EndIf
	Next
End Function
Function shiftMatrixRight(id)
	For landscape.matrix=Each matrix
		If landscape\id=id
			oldBank=landscape\bank
			landscape\bank=CreateBank((landscape\xSeg+1)*(landscape\zSeg+1)*MatrixTileBankBit)
			
			For x=0 To landscape\xSeg
				destX=x+1
				If destX>landscape\xSeg Then destX=0
				For z=0 To landscape\zSeg
					sourcePos=((x* landscape\zSeg)+z)*MatrixTileBankBit
					destPos=((destX* landscape\zSeg)+z)*MatrixTileBankBit
					For byte=0 To 7
						PokeByte landscape\bank,sourcePos+byte,PeekByte(oldBank,sourcePos+byte)
					Next
					For byte=8 To matrixTileBankBit-1
						PokeByte landscape\bank,destPos+byte,PeekByte(oldBank,sourcePos+byte)
					Next
				Next
			Next
			
			FreeBank oldBank
		EndIf
	Next
End Function
Function shiftMatrixUp(id)
	For landscape.matrix=Each matrix
		If landscape\id=id
			oldBank=landscape\bank
			landscape\bank=CreateBank((landscape\xSeg+1)*(landscape\zSeg+1)*MatrixTileBankBit)
			
			For z=0 To landscape\zSeg
				destZ=z-1
				If destZ<0 Then destZ=landscape\zSeg
				For x=0 To landscape\xSeg
					sourcePos=((x* landscape\zSeg)+z)*MatrixTileBankBit
					destPos=((x* landscape\zSeg)+destZ)*MatrixTileBankBit
					For byte=0 To 7
						PokeByte landscape\bank,sourcePos+byte,PeekByte(oldBank,sourcePos+byte)
					Next
					For byte=8 To matrixTileBankBit-1
						PokeByte landscape\bank,destPos+byte,PeekByte(oldBank,sourcePos+byte)
					Next
				Next
			Next
			
			FreeBank oldBank
		EndIf
	Next
End Function
Function shiftMatrixDown(id)
	For landscape.matrix=Each matrix
		If landscape\id=id
			oldBank=landscape\bank
			landscape\bank=CreateBank((landscape\xSeg+1)*(landscape\zSeg+1)*MatrixTileBankBit)
			
			For z=0 To landscape\zSeg
				destZ=z+1
				If destZ>landscape\zSeg Then destZ=0
				For x=0 To landscape\xSeg
					sourcePos=((x* landscape\zSeg)+z)*MatrixTileBankBit
					destPos=((x* landscape\zSeg)+destZ)*MatrixTileBankBit
					For byte=0 To 7
						PokeByte landscape\bank,sourcePos+byte,PeekByte(oldBank,sourcePos+byte)
					Next
					For byte=8 To matrixTileBankBit-1
						PokeByte landscape\bank,destPos+byte,PeekByte(oldBank,sourcePos+byte)
					Next
				Next
			Next
			
			FreeBank oldBank
		EndIf
	Next
End Function
Function debugMatrix(id)
	For landscape.matrix=Each matrix
		If landscape\id=id
			For x=0 To landscape\xSeg-1
				For z=0 To landscape\zSeg-1
					bankPos=((x* landscape\zSeg)+z)*MatrixTileBankBit
					Text x*50,z*20,Int(PeekFloat(landscape\bank,bankPos+8))
				Next
			Next
		EndIf
	Next
End Function
Function updateMatrix(id)
	For landscape.matrix=Each matrix
		If landscape\id=id

			For x=0 To landscape\xSeg-1
				For z=0 To landscape\zSeg-1
					bankPos=((x* landscape\zSeg)+z)*MatrixTileBankBit

					tiled=0
					For tex.matrixTileTexture=Each matrixTileTexture
						If tex\tile=PeekShort(landscape\bank,bankPos+12)
							u#=tex\u
							v#=tex\v
							uM#=tex\uM
							vM#=tex\vM
							tiled=1
						EndIf
					Next

					vertex=PeekShort(landscape\bank,bankPos+0)
					VertexCoords landscape\surface,vertex, VertexX(landscape\surface,vertex), PeekFloat(landscape\bank,bankPos+8), VertexZ(landscape\surface,vertex)
					If tiled Then VertexTexCoords landscape\surface,vertex,u,v

					bankVPos=(((x+1)* landscape\zSeg)+z)*MatrixTileBankBit
					vertex=PeekShort(landscape\bank,bankPos+2)
					VertexCoords landscape\surface,vertex, VertexX(landscape\surface,vertex), PeekFloat(landscape\bank,bankVPos+8), VertexZ(landscape\surface,vertex)
					If tiled Then VertexTexCoords landscape\surface,vertex,uM,v

					bankVPos=((x* landscape\zSeg)+z+1)*MatrixTileBankBit
					vertex=PeekShort(landscape\bank,bankPos+4)
					VertexCoords landscape\surface,vertex, VertexX(landscape\surface,vertex), PeekFloat(landscape\bank,bankVPos+8), VertexZ(landscape\surface,vertex)
					If tiled Then VertexTexCoords landscape\surface,vertex,u,vM

					bankVPos=(((x+1)* landscape\zSeg)+z+1)*MatrixTileBankBit
					vertex=PeekShort(landscape\bank,bankPos+6)
					VertexCoords landscape\surface,vertex, VertexX(landscape\surface,vertex), PeekFloat(landscape\bank,bankVPos+8), VertexZ(landscape\surface,vertex)
					If tiled Then VertexTexCoords landscape\surface,vertex,uM,vM
				Next
			Next

		EndIf
	Next
End Function
Function matrixExist(id)
	;Returns entity memory address or 0 for does not exist
	For landscape.matrix=Each matrix
		If landscape\id=id
			found=landscape\ent
			landscape=Last matrix
		EndIf
	Next
	Return found
End Function
Function matrixPositionX(id)
	;Returns integer only
	For landscape.matrix=Each matrix
		If landscape\id=id
			Return EntityX(landscape\ent)
		EndIf
	Next
End Function
Function matrixPositionY(id)
	;Returns integer only
	For landscape.matrix=Each matrix
		If landscape\id=id
			Return EntityY(landscape\ent)
		EndIf
	Next
End Function
Function matrixPositionZ(id)
	;Returns integer only
	For landscape.matrix=Each matrix
		If landscape\id=id
			Return EntityZ(landscape\ent)
		EndIf
	Next
End Function
Function matrixTileCount(id)
	For landscape.matrix=Each matrix
		If landscape\id=id
			Return landscape\tileCount
		EndIf
	Next
End Function
Function matrixTilesExist(id)
	For landscape.matrix=Each matrix
		If landscape\id=id
			If landscape\tileCount Then found=1
		EndIf
	Next
	Return found
End Function
Function getGroundHeight(id,x#,z#)
	;only returns an integer, but loads the variable height# with the result which can be globalised and read for a float return
	For landscape.matrix=Each matrix
		If landscape\id=id
			x=x-EntityX(landscape\ent)
			z=z-EntityZ(landscape\ent)
			tileX=Floor(x/ landscape\tileSx)
			tileZ=Floor(z/ landscape\tileSz)
			
			offX#=(x- (tileX*landscape\tileSx))/landscape\tileSx
			offZ#=(z- (tileZ*landscape\tileSz))/landscape\tileSz
			
			If tileX<=landscape\xSeg And tileX=>0
				HeightTL#=PeekFloat(landscape\bank, (((tilex* landscape\zSeg)+tilez)*MatrixTileBankBit)+8 )
			Else
				heightTL#=0.0
			EndIf
			If tileX+1<=landscape\xSeg And tileX=>0
				heightTR#=PeekFloat(landscape\bank, ((((tilex+1)* landscape\zSeg)+tilez)*MatrixTileBankBit)+8 )
			Else
				heightTR#=0.0
			EndIf
			If tileZ+1<=landscape\xSeg And tileZ=>0
				heightBL#=PeekFloat(landscape\bank, (((tileX* landscape\zSeg)+tilez+1)*MatrixTileBankBit)+8 )

				If tileX+1<=landscape\xSeg And tileX=>0
					heightBR#=PeekFloat(landscape\bank, ((((tileX+1)* landscape\zSeg)+tilez+1)*MatrixTileBankBit)+8 )
				Else
					heightBR#=0.0
				EndIf
			Else
				heightBL#=0.0
			EndIf
			reverseX#=1.0-offX
			reverseZ#=1.0-offZ
			height#=(heightTL*reverseX*reverseZ)+(heightTR*offX*reverseZ)+(heightBL*reverseX*offZ)+(heightBR*offX*offZ)
		EndIf
	Next

	Return height
End Function
Function getMatrixHeight(id,x,z)
	;only returns an integer, but loads the variable height# with the result which can be globalised and read for a float return
	For landscape.matrix=Each matrix
		If landscape\id=id
			height#=PeekFloat(landscape\bank, (((x* landscape\zSeg)+z)*MatrixTileBankBit)+8 )
		EndIf
	Next
	Return height
End Function
Function collisionModeOn(id)
	For landscape.matrix=Each matrix
		If landscape\id=id
			EntityPickMode landscape\ent,2
		EndIf
	Next
End Function
Function getCollisionHeight(id,x#,z#)
	ent=LinePick(x,65535.0,z, 0.0,-65535.0,0.0)
	height=PickedY()
	Return height
End Function
Function collisionModeOff(id)
	For landscape.matrix=Each matrix
		If landscape\id=id
			EntityPickMode landscape\ent,0
		EndIf
	Next
End Function