Has anyone written a B3D loader for Blitzmax

Miscellaneous Forums/General Discussion/Has anyone written a B3D loader for Blitzmax

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.

Yes i wrote one, didnt finish animation though >_>. Sorry theres pretty much no comments, as this was really just me messing around designing a 3d engine, its pretty hacking'ly done to... But it should give you a basic idea of the structure of the file.

Type TB3DLoader Extends TModelLoader
	
	Field MeshFileURL:String,	MeshStream:TStream
	Field CompleteMesh:TMesh
	Field ChunkName:String, ChunkStart:Int, ChunkLength:Int
	Field LastSurface:TSurface, LastBrush:TBrush, LastTexture:TTexture, LastBrushID:Int
	Field BrushList:Tlist = CreateList(), TextureList:Tlist = CreateList()
	
	Method New()
	
		Header = "BB3D"
	
	End Method

	Method Load(Mesh:TMesh,Stream:TStream,URL:String = "")
	
		' Seutp variables
		CompleteMesh = Mesh
		MeshFileURL	 = URL
		MeshStream	 = Stream
	
		' Recursivly read chunks
		While Not Eof(MeshStream)
			ReadChunk()
		Wend
	
		' Remove references
		CompleteMesh = Null
		MeshStream	 = Null
		ClearList(BrushList)
		ClearList(TextureList)
				
	End Method

	Method ReadChunk()

		' Read header 
		ChunkName       = ReadString(MeshStream,4)
		ChunkLength	 	= ReadInt(MeshStream)
		ChunkStart  	= StreamPos(MeshStream)
	
		' Check what type of chunk it is
		Select ChunkName
		
			Case "BB3D"
				Local Version:Int = ReadInt(MeshStream)
				If Version / 100 > 1 / 100 Then Throw "Unsupported version ("+Version+") of b3d file"
		
			Case "NODE"
				Local Name:String = ReadNTString(MeshStream)
				
				CompleteMesh.Position[0] = ReadFloat(MeshStream)
				CompleteMesh.Position[1] = ReadFloat(MeshStream)
				CompleteMesh.Position[2] = ReadFloat(MeshStream)
				
				CompleteMesh.Scale[0]	 = ReadFloat(MeshStream)
				CompleteMesh.Scale[1]	 = ReadFloat(MeshStream)
				CompleteMesh.Scale[2]	 = ReadFloat(MeshStream)

				Local WRot:Float = ReadFloat(MeshStream)
				CompleteMesh.Rotation[0] = ReadFloat(MeshStream)
				CompleteMesh.Rotation[1] = ReadFloat(MeshStream)
				CompleteMesh.Rotation[1] = ReadFloat(MeshStream)
				
			Case "TEXS"
				While Not EOC()

					LastTexture = New TTexture
					
					Local FileURL:String 	 	= ReadNTString(MeshStream)
					Local Flags:Int			= ReadInt(MeshStream)
					LastTexture.Blend		 	= ReadInt(MeshStream)
					LastTexture.Position[0]	= ReadFloat(MeshStream)
					LastTexture.Position[1]	= ReadFloat(MeshStream)
					LastTexture.Scale[0]	 	= ReadFloat(MeshStream)
					LastTexture.Scale[1]	 	= ReadFloat(MeshStream)
					LastTexture.Rotation	 	= ReadFloat(MeshStream)
									
					If FileType(FileURL) = 1 
						LastTexture.Load(FileURL)
					ElseIf FileType(ExtractDir(MeshFileURL)+""+StripDir(FileURL)) = 1
						LastTexture.Load(ExtractDir(MeshFileURL)+""+StripDir(FileURL))
					EndIf	
					
					ListAddLast(TextureList,LastTexture)					

				Wend

			Case "BRUS"		
				Local TexCount:Int = ReadInt(MeshStream)
					
				While Not EOC()
		
					LastBrush = New TBrush
					
					LastBrush.Name 			 = ReadNTString(MeshStream)
					LastBrush.Color[0] 		 = ReadFloat(MeshStream)
					LastBrush.Color[1] 		 = ReadFloat(MeshStream)
					LastBrush.Color[2] 		 = ReadFloat(MeshStream)
					LastBrush.Color[3] 		 = ReadFloat(MeshStream)
					
					LastBrush.Shininess		 = ReadFloat(MeshStream)
					LastBrush.Blend			 = ReadInt(MeshStream)
					LastBrush.FX			 	 = ReadInt(MeshStream)
					
					For Local Tex:Int = 1 To TexCount
						Local ID:Int 		 = ReadInt(MeshStream) 
						If ID <> -1 Then LastBrush.Texture = TTexture(TextureList.ValueAtIndex(ID))
					Next
									
					ListAddLast(BrushList,LastBrush)		

				Wend
																		
			Case "MESH"
				LastBrushID = ReadInt(meshStream) 
				If LastBrushID <> -1 Then TBrush(BrushList.ValueAtIndex(LastBrushID)).ApplyToMesh(CompleteMesh)
				
			Case "TRIS"
				LastSurface = CompleteMesh.AddSurface(0)			
				LastBrushID = ReadInt(meshStream)
				If LastBrushID <> -1 Then TBrush(BrushList.ValueAtIndex(LastBrushID)).ApplyToSurface(LastSurface)
				
				Local V0:Int, V1:Int, V2:Int						
				Local VSize:Int = 0
				Local ParseStart:Int = StreamPos(MeshStream)
				
				While Not EOC()
					ReadInt(MeshStream) ; ReadInt(MeshStream) ; ReadInt(MeshStream)
					VSize:+1
				Wend
				
				SeekStream(MeshStream,ParseStart)
				LastSurface.ResizePolygonList(LastSurface.PolyList.Length + VSize + 1)
								
				Local TChanger:Int = True
				While Not EOC()
				
					V0 = ReadInt(MeshStream)
					V1 = ReadInt(MeshStream)
					V2 = ReadInt(MeshStream)
					LastSurface.AddTriangle(CompleteMesh.GetVertex(V0),CompleteMesh.GetVertex(V1),CompleteMesh.GetVertex(V2))
				
				Wend
				
			Case "VRTS"
				Local Flags:Int = ReadInt(MeshStream)
				Local TexCoordSet:Int = ReadInt(MeshStream)
				Local TexCoordCount:Int = ReadInt(MeshStream)
				Local VX:Float, VY:Float, VZ:Float, VNX:Float, VNY:Float, VNZ:Float
				Local VR:Float = 255, VG:Float = 255, VB:Float = 255, VA:Float = 1
				Local VSize:Int = 0
				Local ParseStart:Int = StreamPos(MeshStream)
				
				While Not EOC()
					ReadFloat(MeshStream) ; ReadFloat(MeshStream) ; ReadFloat(MeshStream)
					If Flags & 1 Then ReadFloat(MeshStream) ; ReadFloat(MeshStream) ; ReadFloat(MeshStream)					
					If Flags & 2 Then ReadFloat(MeshStream) ; ReadFloat(MeshStream) ; ReadFloat(MeshStream)				
					For Local Set:Int = 1 To TexCoordSet
						For Local Size:Int = 1 To TexCoordCount
							ReadFloat(MeshStream)
						Next
					Next
					VSize:+1
				Wend
				
				SeekStream(MeshStream,ParseStart)
				CompleteMesh.ResizeVertexList(CompleteMesh.VertexList.Length + VSize + 1)
				
				While Not EOC()
				
					Local Vertex:TVertex = CompleteMesh.AddVertex(0,0,0)
					
					Vertex.Position[0] = ReadFloat(MeshStream)
					Vertex.Position[1] = ReadFloat(MeshStream)
					Vertex.Position[2] = ReadFloat(MeshStream)
					
					If Flags & 1
						Vertex.Normal[0] = ReadFloat(MeshStream)
						Vertex.Normal[1] = ReadFloat(MeshStream)
						Vertex.Normal[2] = ReadFloat(MeshStream)					
					EndIf
					
					If Flags & 2
						Vertex.Color[0] = ReadFloat(MeshStream)
						Vertex.Color[1] = ReadFloat(MeshStream)
						Vertex.Color[2] = ReadFloat(MeshStream)	
						Vertex.Color[3] = ReadFloat(MeshStream)					
					EndIf

					For Local Set:Int = 1 To TexCoordSet
						For Local Size:Int = 1 To TexCoordCount
							Local Temp:Float = ReadFloat(MeshStream)
							If Set = 1
								If Size = 1
									Vertex.TextureCoords[0] = Temp
								ElseIf Size = 2
									Vertex.TextureCoords[1] = Temp
								EndIf
							EndIf
						Next
					Next

				Wend
							
			Default
				NextChunk()
		
		End Select

	End Method
	
	Method NextChunk(Offset:Int = 0)
	
		SeekStream(MeshStream,ChunkStart + ChunkLength + Offset)
	
	End Method
	
	Method EOC:Int()
	
		If StreamPos(MeshStream) >= ChunkStart + ChunkLength Then Return True
		Return False
	
	End Method

End Type