Leadwerks Engine BlitzxMax module - test 2

BlitzMax Forums/BlitzMax Programming/Leadwerks Engine BlitzxMax module - test 2

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.

I created a .b3d mesh loader. It doesn't handle materials yet, but this shows how you can add support for additional formats. Most of this is Mark's original .b3d parser code. Just put this in the engine directory and run it. Change the name of the .b3d file to load, since I didn't include the jeep b3d in the package.
Framework leadwerks.engine

AppTitle=StripAll(AppFile)
SetGraphicsDriver GLGraphicsDriver()
Graphics 1024,768,0,60,2

'A world must be created or loaded before you do anything:
CreateWorld()

'Create a mesh:
mesh:TMesh=LoadMesh("meshes\vehicles\jeep.b3d")

'Create a camera
camera:TCamera=CreateCamera()
CameraClsColor camera,0,0,255
MoveEntity camera,0,0,-400

'Create a light
light:TLight=CreateLight()
RotateEntity light,45,45,0

'Main loop
While Not KeyHit(KEY_ESCAPE)
	
	TurnEntity mesh,0,AppSpeed(),0

	UpdateWorld()
	RenderWorld()

	GLDrawText "UPS: "+UPS(),0,0
	GLDrawText TrisRendered()+" triangles",0,20

	Flip False	
Wend
End

'==========================================================
'B3D Mesh loader class
'
'To create a new mesh loader, declare the type, 
'indicate the supported file extensions, and write the Load() method.
'You can then use the standard LoadMesh() command to load the file format.
'
'==========================================================
Type B3DMeshLoader Extends TMeshLoader
	Global loader:TMeshLoader=New B3DMeshLoader
	
	Method New()
		extensions.addlast "b3d"
	EndMethod
	
	Method Load:TMesh(stream:TStream)
		b3dSetFile(stream)
		If b3dReadChunk$()<>"BB3D"
			DebugLog "Invalid b3d file."
			Return Null
		EndIf
		If b3dReadInt()/100>0
			DebugLog "Invalid b3d file version."
			Return Null
		EndIf
		root:TMesh=ReadChunks()
		b3dExitChunk()
		Return root
	EndMethod
	
	Function ReadChunks:TMesh( tab$="" )
		
		Global entity:TEntity
		Global root:TMesh
		Global vertexlist#[,]
		Global normallist#[,]
		Global texcoordList#[,,]
		Global colorList#[,]
		
		Global x_pos#
		Global y_pos#
		Global z_pos#
		Global x_scl#
		Global y_scl#
		Global z_scl#
		Global w_rot#
		Global x_rot#
		Global y_rot#
		Global z_rot#
		
		tt$=tab$
		tab$=tab$+"  "
		While b3dChunkSize()
			chunk$=b3dReadChunk$()
			DebugLog tt$+"Chunk:"+chunk$+" (size="+b3dChunkSize()+")"
			Select chunk$
			Rem
			Case "ANIM"
				flags=b3dReadInt()
				n_frames=b3dReadInt()
				fps=b3dReadFloat()
				DebugLog tab$+flags+" "+n_frames+" "+fps
			EndRem
			Rem	
			Case "KEYS"
				flags=b3dReadInt()
				sz=4
				If flags And 1 sz=sz+12
				If flags And 2 sz=sz+12
				If flags And 4 sz=sz+16
				n_keys=b3dChunkSize()/sz
				If n_keys*sz=b3dChunkSize() 
					DebugLog tab$+n_keys+" keys"
					'read all keys in chunk
					While b3dChunkSize()
						frame=b3dReadInt()
						If flags And 1
							key_px#=b3dReadFloat()
							key_py#=b3dReadFloat()
							key_pz#=b3dReadFloat()
						EndIf
						If flags And 2
							key_sx#=b3dReadFloat()
							key_sy#=b3dReadFloat()
							key_sz#=b3dReadFloat()
						EndIf
						If flags And 4
							key_rw#=b3dReadFloat()
							key_rx#=b3dReadFloat()
							key_ry#=b3dReadFloat()
							key_rz#=b3dReadFloat()
						EndIf
					Wend
				Else
					DebugLog tab$+"***** Illegal number of keys *****"
				EndIf
			EndRem
			Case "TEXS"
				While b3dChunkSize()
					name$=b3dReadString$()
					flags=b3dReadInt()
					blend=b3dReadInt()
					x_pos#=b3dReadFloat()
					y_pos#=b3dReadFloat()
					x_scl#=b3dReadFloat()
					y_scl#=b3dReadFloat()
					rot#=b3dReadFloat()
					DebugLog tab$+name$
				Wend
				'ReadChunks( tab$ )	'dump any subchunks
			Case "BRUS"
				n_texs=b3dReadInt()
				'read all brushes in chunk...
				While b3dChunkSize()
					name$=b3dReadString$()
					r#=b3dReadFloat()
					g#=b3dReadFloat()
					b#=b3dReadFloat()
					alp#=b3dReadFloat()
					shi#=b3dReadFloat()
					blend=b3dReadInt()
					fx=b3dReadInt()
					For k=0 To n_texs-1
						tex_id=b3dReadInt()
					Next
					DebugLog tab$+name$
				Wend
				'ReadChunks( tab$ )	'dump any subchunks
			Case "VRTS"
				flags=b3dReadInt()
				tc_sets=b3dReadInt()
				tc_size=b3dReadInt()
				sz=12+tc_sets*tc_size*4
				If (1 & flags) sz=sz+12
				If (2 & flags) sz=sz+16

				n_verts=b3dChunkSize()/sz
	
				Local verts#[n_verts,3]
				vertexlist=verts
				Local norms#[n_verts,3]
				normallist=norms
				tsize=tc_size
				If tsize<2 tsize=2
				tsets=tc_sets
				If tsets<2 tsets=2
				Local texcoords#[n_verts,tsize,tsets]
				texcoordList=texcoords
				
				If n_verts*sz=b3dChunkSize()
				
					DebugLog tab$+n_verts+" vertices"
					'read all verts in chunk
					n=0
					While b3dChunkSize()>0
						x#=b3dReadFloat()
						y#=b3dReadFloat()
						z#=b3dReadFloat()
						
						vertexlist[n,0]=x
						vertexlist[n,1]=y
						vertexlist[n,2]=z
						DebugLog x+", "+y+", "+z
						
						If (1 & flags)
							nx#=b3dReadFloat()
							ny#=b3dReadFloat()
							nz#=b3dReadFloat()
							normallist[n,0]=nx
							normallist[n,1]=ny
							normallist[n,2]=nz
						EndIf
						If (2 & flags)
							r#=b3dReadFloat()
							g#=b3dReadFloat()
							b#=b3dReadFloat()
							lfa#=b3dReadFloat()
						EndIf
						'read tex coords...
						For set=0 To tc_sets-1
							For coord=0 To tc_size-1
								texcoordList[n,coord,set]=b3dReadFloat()
							Next
						Next
						n:+1
					Wend
				Else
					DebugLog tab$+"***** Illegal number of vertices *****"
				EndIf
				'ReadChunks( tab$ )	'dump any subchunks
			Case "TRIS"
				brush_id=b3dReadInt()
				sz=12
				n_tris=b3dChunkSize()/sz

				If n_tris*sz=b3dChunkSize()
					'DebugLog tab$+n_tris+" triangles"
					'read all tris in chunk
					n=0
					
					surf:TSurface=CreateSurface(TMesh(entity))
					
					While b3dChunkSize()
						v0=b3dReadInt()
						v1=b3dReadInt()
						v2=b3dReadInt()
						
						DebugLog v0+", "+v1+", "+v2
						x0#=vertexlist[v0,0]
						y0#=vertexlist[v0,1]
						z0#=vertexlist[v0,2]
						x1#=vertexlist[v1,0]
						y1#=vertexlist[v1,1]
						z1#=vertexlist[v1,2]
						x2#=vertexlist[v2,0]
						y2#=vertexlist[v2,1]
						z2#=vertexlist[v2,2]
						nx0#=normallist[v0,0]
						ny0#=normallist[v0,1]
						nz0#=normallist[v0,2]
						nx1#=normallist[v1,0]
						ny1#=normallist[v1,1]
						nz1#=normallist[v1,2]
						nx2#=normallist[v2,0]
						ny2#=normallist[v2,1]
						nz2#=normallist[v2,2]
						u00#=texcoordlist[v0,0,0]
						v00#=texcoordlist[v0,1,0]
						u01#=texcoordlist[v0,0,1]
						v01#=texcoordlist[v0,1,1]
						u10#=texcoordlist[v1,0,0]
						v10#=texcoordlist[v1,1,0]
						u11#=texcoordlist[v1,0,1]
						v11#=texcoordlist[v1,1,1]
						u20#=texcoordlist[v2,0,0]
						v20#=texcoordlist[v2,1,0]
						u21#=texcoordlist[v2,0,1]
						v21#=texcoordlist[v2,1,1]
						v0=surf.findvertex(x0,y0,z0,nx0,ny0,nz0,u00,v00,u01,v01)
						v1=surf.findvertex(x1,y1,z1,nx1,ny1,nz1,u10,v10,u11,v11)
						v2=surf.findvertex(x2,y2,z2,nx2,ny2,nz2,u20,v20,u21,v21)
						surf.addtriangle(v0,v1,v2,True)
						
						'indicelist[n,0]=v0
						'indicelist[n,1]=v1
						'indicelist[n,2]=v2
						
						n:+1
					Wend
				Else
					DebugLog tab$+"***** Illegal number of triangles *****"
				EndIf
				'ReadChunks( tab$ )	'dump any subchunks
				
			Case "MESH"
				brush_id=b3dReadInt()
				
				entity=CreateMesh(entity)
				SetEntityProperty entity,"name",name$
				PositionEntity entity,x_pos,y_pos,z_pos
				ScaleEntity entity,x_scl,y_scl,z_scl
				EntityQuaternion entity,x_rot,y_rot,z_rot,w_rot
				reverttoparent=True
				
				'DebugLog tab$+"brush="+brush_id
			Rem
			Case "BONE"
				sz=8
				n_weights=b3dChunkSize()/sz
				If n_weights*sz=b3dChunkSize()
					DebugLog tab$+n_weights+" weights"
					'read all weights
					While b3dChunkSize()
						vertex_id=b3dReadInt()
						weight#=b3dReadFloat()
					Wend
				Else
					DebugLog tab$+"***** Illegal number of bone weights *****"
				EndIf
			EndRem
				ReadChunks( tab$ )	'dump any subchunks
			
			Case "NODE"
				name$=b3dReadString$()
				x_pos#=b3dReadFloat()
				y_pos#=b3dReadFloat()
				z_pos#=b3dReadFloat()
				x_scl#=b3dReadFloat()
				y_scl#=b3dReadFloat()
				z_scl#=b3dReadFloat()
				w_rot#=b3dReadFloat()
				x_rot#=b3dReadFloat()
				y_rot#=b3dReadFloat()
				z_rot#=b3dReadFloat()
				'DebugLog tab$+"name="+name$
				
				ReadChunks( tab$ )	'dump any subchunks
							
			EndSelect
			
			b3dExitChunk()		'Exit this chunk
			If root:TMesh=Null root=TMesh(entity)
			If reverttoparent
				If entity entity=entity.parent
			EndIf
		Wend
		Return root
	EndFunction
	
	'
	'b3d file utils To be included
	'
	Global b3d_stack[100]
	Global b3d_file:TStream,b3d_tos
	
	Function b3dSetFile( file:TStream )
		b3d_tos=0
		b3d_file=file
	End Function
	
	'***** functions For reading from B3D files *****
	
	Function b3dReadByte()
		Return ReadByte( b3d_file )
	End Function
	
	Function b3dReadInt()
		Return ReadInt( b3d_file )
	End Function
	
	Function b3dReadFloat#()
		Return ReadFloat( b3d_file )
	End Function
	
	Function b3dReadString$()
		Repeat
			ch=b3dReadByte()
			If ch=0 Return t$
			t$=t$+Chr$(ch)
		Forever
	End Function
	
	Function b3dReadChunk$()
		For k=1 To 4
			tag$=tag$+Chr$(b3dReadByte())
		Next
		sz=ReadInt( b3d_file )
		b3d_tos=b3d_tos+1
		b3d_stack[b3d_tos]=StreamPos( b3d_file )+sz
		Return tag$
	End Function
	
	Function b3dExitChunk()
		SeekStream b3d_file,b3d_stack[b3d_tos]
		b3d_tos=b3d_tos-1
	End Function
	
	Function b3dChunkSize()
		Return b3d_stack[b3d_tos]-StreamPos( b3d_file )
	End Function
	
	'***** Functions For writing To B3D files *****
	
	Function b3dWriteByte( n )
		WriteByte( b3d_file,n )
	End Function
	
	Function b3dWriteInt( n )
		WriteInt( b3d_file,n )
	End Function
	
	Function b3dWriteFloat( n# )
		WriteFloat( b3d_file,n )
	End Function
	
	Function b3dWriteString( t$ )
		For k=1 To Len( t$ )
			ch=Asc(Mid$(t$,k,1))
			b3dWriteByte(ch)
			If ch=0 Return
		Next
		b3dWriteByte( 0 )
	End Function
	
	Function b3dBeginChunk( tag$ )
		b3d_tos=b3d_tos+1
		For k=1 To 4
			b3dWriteByte(Asc(Mid$( tag$,k,1 )))
		Next
		b3dWriteInt( 0 )
		b3d_stack[b3d_tos]=StreamPos( b3d_file )
	End Function
	
	Function b3dEndChunk()
		n=StreamPos( b3d_file )
		SeekStream b3d_file,b3d_stack[b3d_tos]-4
		b3dWriteInt( n-b3d_stack[b3d_tos] )
		SeekStream b3d_file,n
		b3d_tos=b3d_tos-1
	End Function

EndType