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