Code archives/3D Graphics - Mesh/Load/Save Anim .b3d
This code has been declared by its author to be Public Domain code.
Download source code
| This is the function from the first version of PaceMaker to load and save animated .b3d files. It uses type structures to store the info. This was based on the b3d2Xml code by Peter Scheutz. |
;-------------------------------------------------------------- ; ; B3d importer ; Adapted for PaceMaker by Ricky Smith ; Based on code by M Sibley & Peter Sheultz ; ; ;-------------------------------------------------------------- Include "b3dfile.bb" ; get this file from www.blitzbasic.com -> ; Community -> Specs And utils -> Sample Blitz code ;OSB: in b3dfile.bb change "Function b3dReadFloat()" to "Function b3dReadFloat#()" Global mesh Dim PMK_tex_id%(255,255) Const PMK_ERROR_NONE=True Const PMK_ERROR_NOFILE=-1 Const PMK_ERROR_FILENOTVALID =-2 Const PMK_ERROR_WRONGVERSION =-3 Const PMK_FLAG_StripTexturePaths=1 Const PMK_FLAG_StripBrushPaths=2 Const PMK_FLAG_StripNodePaths=4 Const PMK_FLAG_SkipVertices=8 Const PMK_FLAG_SkipTriangles=16 Const PMK_FLAG_SkipKeys=32 Const PMK_FLAG_SkipWeights=64 Const PMK_MAX_KEYS = 5000 Const PMK_MAX_VRTS = 50000 Const PMK_MAX_TRIS = 20000 Const PMK_MAX_TEXS = 255 Const PMK_MAX_BRUS = 255 Global PMK_emf Global PMK_xml$ Global PMK_xmlpos Global PMK_xmlpos2 Global PMK_xmlpos3 Global PMK_kflags Global PMK_brushtexcount Global PMK_vflags Global PMK_vtexsets Global PMK_vtexsize ;Global cname$ .types Type NodeChunk Field name$ Field x_pos# Field y_pos# Field z_pos# Field x_scl# Field y_scl# Field z_scl# Field w_rot# Field x_rot# Field y_rot# Field z_rot# Field gui_id% Field joint Field geo ;Field bone.ray Field prename$ Field class$ Field xrot# Field yrot# Field zrot# Field norm=0 ;Field bp.bodypoint Field newborn=0 Field Parent ;Field rb.ODEGeom ;Field loangle#=-Pi*0.25;-45 degrees ;Field hiangle#=Pi*0.25;-45 degrees ;Field Axis1=1 ;Field Axis2=2 ;Field joint_type% = 2 ;Field max_force#=0.0 ;Field vel#=0.0 ;Field angulardamp#=0.5 ;Field lineardamp#=0.5 ;Field fixed=False ;Field nproxy Field anim_flags%,Num_Frames%,FramesPS# Field mesh_brush_id ; VrtsChunk Field vrts_count%,vrts_flags%,texturecoordsets%,texturecoordsize% ;fieldrS#[PMK_MAX_VRTS],gS#[PMK_MAX_VRTS],bS#[PMK_MAX_VRTS] Field vrts_index%[PMK_MAX_VRTS],x#[PMK_MAX_VRTS],y#[PMK_MAX_VRTS],z#[PMK_MAX_VRTS] Field u0#[PMK_MAX_VRTS],v0#[PMK_MAX_VRTS],w0#[PMK_MAX_VRTS];UVW coords Field u1#[PMK_MAX_VRTS],v1#[PMK_MAX_VRTS],w1#[PMK_MAX_VRTS];2nd UVW coords Field nx#[PMK_MAX_VRTS],ny#[PMK_MAX_VRTS],nz#[PMK_MAX_VRTS] Field r#[PMK_MAX_VRTS],g#[PMK_MAX_VRTS],b#[PMK_MAX_VRTS],a#[PMK_MAX_VRTS] Field vrts_ent%[PMK_MAX_VRTS],joint1%[PMK_MAX_VRTS],joint2%[PMK_MAX_VRTS],joint3%[PMK_MAX_VRTS],joint4%[PMK_MAX_VRTS] Field weight1#[PMK_MAX_VRTS],weight2#[PMK_MAX_VRTS],weight3#[PMK_MAX_VRTS],weight4#[PMK_MAX_VRTS] Field Frontfacing[PMK_MAX_VRTS] ;End ; BoneChunk Field weight_count%,vert_target%[PMK_MAX_VRTS],weight#[PMK_MAX_VRTS] ;End ; KeysChunk Field keys_flag%,keys_count%,moved=0 Field frame%[PMK_MAX_KEYS],frameP%[PMK_MAX_KEYS],frameS%[PMK_MAX_KEYS],frameR%[PMK_MAX_KEYS] Field key_px#[PMK_MAX_KEYS],key_py#[PMK_MAX_KEYS],key_pz#[PMK_MAX_KEYS] Field key_sx#[PMK_MAX_KEYS],key_sy#[PMK_MAX_KEYS],key_sz#[PMK_MAX_KEYS] Field key_rw#[PMK_MAX_KEYS],key_rx#[PMK_MAX_KEYS],key_ry#[PMK_MAX_KEYS],key_rz#[PMK_MAX_KEYS] ;Field key_qrw#[PMK_MAX_KEYS],key_qrx#[PMK_MAX_KEYS],key_qry#[PMK_MAX_KEYS],key_qrz#[PMK_MAX_KEYS] ;Field key_brw#[PMK_MAX_KEYS],key_brx#[PMK_MAX_KEYS],key_bry#[PMK_MAX_KEYS],key_brz#[PMK_MAX_KEYS] ;Field key_pitch#[PMK_MAX_KEYS],key_yaw#[PMK_MAX_KEYS],key_roll#[PMK_MAX_KEYS] ;Field bone_w#,bone_x#,bone_y#,bone_z# End Type Type Texs Field mesh Field name$[PMK_MAX_TEXS] Field flags%[PMK_MAX_TEXS] Field blend%[PMK_MAX_TEXS] Field xpos#[PMK_MAX_TEXS] Field ypos#[PMK_MAX_TEXS] Field xscale#[PMK_MAX_TEXS] Field yscale#[PMK_MAX_TEXS] Field rot#[PMK_MAX_TEXS] Field texs_count% End Type Type Brus Field name$[PMK_MAX_BRUS] Field red#[PMK_MAX_BRUS] Field grn#[PMK_MAX_BRUS] Field blu#[PMK_MAX_BRUS] Field alp#[PMK_MAX_BRUS] Field shi#[PMK_MAX_BRUS] Field blend%[PMK_MAX_BRUS] Field fx%[PMK_MAX_BRUS] ; Field tex_id%[PMK_MAX_TEXS] Field brus_count% Field brus_tex_count% End Type Type TrisChunk Field mesh,tris_count%,tris_brush_id%,tv0%[PMK_MAX_TRIS],tv1%[PMK_MAX_TRIS],tv2%[PMK_MAX_TRIS] End Type Global b3dbrush.brus Global b3dtex.texs Global b3dnode.NodeChunk Global b3dmesh.NodeChunk Global b3dtris.trischunk ;Global b3dseq.sequence Global Cnode.NodeChunk Global DoneRefKey=False Global retval ;Dim leaf(100) Global NodeCount=0 Global NewJointNo=0 ;Dim Joint(100) Global level Function b3d2pmk(b3dfile$,dumpflags=0) mesh=LoadAnimMesh(b3dfile$) Local file file=ReadFile( b3dfile$) If Not file Return PMK_ERROR_NOFILE b3dSetFile( file ) If b3dReadChunk$()<>"BB3D" Return PMK_ERROR_FILENOTVALID ;RuntimeError "Invalid b3d file" version=b3dReadInt() If version/100>0 Return PMK_ERROR_WRONGVERSION ;RuntimeError "Invalid b3d file version" DumpChunks(dumpflags,"*") b3dExitChunk() CloseFile file Return PMK_ERROR_NONE End Function Function DumpChunks(dumpflags, tab$="",level%=0) tt$=tab$ tab$=tab$+" " level%=level%+1 While b3dChunkSize() chunk$=b3dReadChunk$() .anim Select chunk$ Case "SEQS" ; b3dseq.sequence=New sequence ; b3dseq\name$=b3dReadString() ; b3dseq\fstart%=b3dReadInt() ; b3dseq\fend%=b3dReadInt() ; b3dseq\seq%=ExtractAnimSeq (mesh,b3dseq\fstart%,b3dseq\fend%) ; b3dseq\gui_id=AddListBoxItem( lstSeq, 0, b3dseq\seq% + " - " + b3dseq\name$) Case "PHYS" ; b3dnode\joint_type=b3dReadInt() ; b3dnode\loangle#=b3dReadFloat() ; b3dnode\hiangle#=b3dReadFloat() ; b3dnode\Axis1=b3dReadInt() ; b3dnode\Axis2=b3dReadInt() Case "ANIM" flags=b3dReadInt() n_frames=b3dReadInt() fps=b3dReadFloat() AnimFrames%=n_frames ; DebugLog "Anim Frames :" + AnimFrames AnimFPS#=fps ;___________________________________ b3dnode\anim_flags%=flags b3dnode\Num_Frames%=n_frames b3dnode\FramesPS#=fps ;_____________________________________ .keys Case "KEYS" ;For mark=0 To PMK_MAX_KEYS;b3dmesh\Num_Frames% ; b3dnode\frame%[mark]=-1 ; b3dnode\frameP%[mark]=-1 ; b3dnode\frameS%[mark]=-1 ; b3dnode\frameR%[mark]=-1 ; Next flags=b3dReadInt() b3dnode\keys_flag%=flags 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 b3dnode\keys_count%=n_keys If n_keys*sz=b3dChunkSize() While b3dChunkSize() frame=b3dReadInt() b3dnode\frame%[frame]=frame If flags And 1 b3dnode\frameP%[frame]=frame key_px#=b3dReadFloat() key_py#=b3dReadFloat() key_pz#=b3dReadFloat() b3dnode\key_px#[frame]=key_px# b3dnode\key_py#[frame]=key_py# b3dnode\key_pz#[frame]=key_pz# EndIf If flags And 2 b3dnode\frameS%[frame]=frame key_sx#=b3dReadFloat() key_sy#=b3dReadFloat() key_sz#=b3dReadFloat() b3dnode\key_sx#[frame]=key_sx# b3dnode\key_sy#[frame]=key_sy# b3dnode\key_sz#[frame]=key_sz# EndIf If flags And 4 b3dnode\frameR%[frame]=frame key_rw#=b3dReadFloat() key_rx#=b3dReadFloat() key_ry#=b3dReadFloat() key_rz#=b3dReadFloat() b3dnode\key_rw#[frame]=key_rw# b3dnode\key_rx#[frame]=key_rx# b3dnode\key_ry#[frame]=key_ry# b3dnode\key_rz#[frame]=key_rz# EndIf ; If frame > highframe Then highframe=frame Wend Else ;;;DebugLog tab$+"***** Illegal number of keys *****" EndIf Case "TEXS" b3dtex.texs=New texs index=0 While b3dChunkSize() name$=b3dReadString$() flags=b3dReadInt() blend=b3dReadInt() x_pos#=b3dReadFloat() y_pos#=b3dReadFloat() x_scl#=b3dReadFloat() y_scl#=b3dReadFloat() rot#=b3dReadFloat() If dumpflags And PMK_FLAG_StripTexturePaths Then name$=StripPath(name$) b3dtex\name$[index]=name$ b3dtex\flags%[index]=flags b3dtex\blend%[index]=blend b3dtex\xpos#[index]=x_pos# b3dtex\ypos#[index]=y_pos# b3dtex\xscale#[index]=x_scl# b3dtex\yscale#[index]=y_scl# b3dtex\rot#[index]=rot# index=index+1 Wend b3dtex\texs_count%=index .brus Case "BRUS" b3dbrush.brus=New brus n_texs=b3dReadInt() b3dbrush\brus_tex_count%=n_texs index=0 ;read all brushes in chunk... While b3dChunkSize() name$=b3dReadString$() red#=b3dReadFloat() grn#=b3dReadFloat() blu#=b3dReadFloat() alp#=b3dReadFloat() shi#=b3dReadFloat() blend=b3dReadInt() fx=b3dReadInt() b3dbrush\name$[index]=name$ b3dbrush\red#[index]=red# b3dbrush\grn#[index]=grn# b3dbrush\blu#[index]=blu# b3dbrush\alp#[index]=alp# b3dbrush\shi#[index]=shi# b3dbrush\blend%[index]=blend b3dbrush\fx%[index]=fx If dumpflags And PMK_FLAG_StripBrushPaths Then name$=StripPath(name$) For k=0 To n_texs-1 tex_id=b3dReadInt() PMK_tex_id%(index,k)=tex_id Next index=index+1 Wend b3dbrush\brus_count%=index .verts Case "VRTS" flags=b3dReadInt() tc_sets=b3dReadInt() tc_size=b3dReadInt() sz=12+tc_sets*tc_size*4 If flags And 1 Then sz=sz+12 If flags And 2 Then sz=sz+16 n_verts=b3dChunkSize()/sz b3dnode\vrts_count%=n_verts b3dnode\vrts_flags%=flags b3dnode\texturecoordsets%=tc_sets b3dnode\texturecoordsize%=tc_size If n_verts*sz=b3dChunkSize() index%=0 ;read all verts in chunk While b3dChunkSize() b3dnode\vrts_index%[index]=0; Used for Selection ! x#=b3dReadFloat() y#=b3dReadFloat() z#=b3dReadFloat() b3dnode\x#[index]=x# b3dnode\y#[index]=y# b3dnode\z#[index]=z# If flags And 1 nx#=b3dReadFloat() ny#=b3dReadFloat() nz#=b3dReadFloat() b3dnode\nx#[index]=nx# b3dnode\ny#[index]=ny# b3dnode\nz#[index]=nz# EndIf If flags And 2 r#=b3dReadFloat() g#=b3dReadFloat() b#=b3dReadFloat() a#=b3dReadFloat() b3dnode\r#[index]=r# b3dnode\g#[index]=g# b3dnode\b#[index]=b# b3dnode\a#[index]=a# EndIf ;Parent vert boxes ; b3dnode\vrts_ent[index]=CreateCube() ; NameEntity b3dnode\vrts_ent[index],index ; EntityColor b3dnode\vrts_ent[index],255,255,255 ; EntityParent b3dnode\vrts_ent[index],b3dnode\joint ; PositionEntity b3dnode\vrts_ent[index],x,y,z,0 ; ScaleMesh b3dnode\vrts_ent[index],.1,.1,.1 ; b3dnode\rS#[index]=255 ; b3dnode\gS#[index]=255 ; b3dnode\bS#[index]=255 ; EntityPickMode b3dnode\vrts_ent[index],2 coordnameindex=0 set=0 ;read tex coords... For j=1 To tc_sets*tc_size uvw#=b3dReadFloat() coordnameindex=coordnameindex + 1 If coordnameindex>tc_size Then coordnameindex =1 set=set+1 EndIf If coordnameindex=1 cn$="u" If Not set Then b3dnode\u0#[index]=uvw Else b3dnode\u1#[index]=uvw End If ElseIf coordnameindex=2 cn$="v" If Not set Then b3dnode\v0#[index]=uvw Else b3dnode\v1#[index]=uvw End If Else cn$="w" If Not set Then b3dnode\w0#[index]=uvw Else b3dnode\w1#[index]=uvw End If EndIf Next index=index+1 Wend Else ;;;DebugLog tab$+"***** Illegal number of vertices *****" EndIf Case "TRIS" b3dtris.trischunk=New trischunk brush_id=b3dReadInt() sz=12 n_tris=b3dChunkSize()/sz b3dtris\tris_count%=n_tris b3dtris\tris_brush_id%=brush_id .tris If n_tris*sz=b3dChunkSize() index%=0 ;read all tris in chunk While b3dChunkSize() v0=b3dReadInt() v1=b3dReadInt() v2=b3dReadInt() b3dtris\tv0%[index]=v0 b3dtris\tv1%[index]=v1 b3dtris\tv2%[index]=v2 index%=index%+1 Wend Else ;;;DebugLog tab$+"***** Illegal number of triangles *****" EndIf Case "MESH" brush_id=b3dReadInt() b3dnode\mesh_brush_id=brush_id b3dnode\class$="mesh" b3dmesh=b3dnode ;HideEntity b3dmesh\geo .bone Case "BONE" sz=8 n_weights=b3dChunkSize()/sz b3dnode\weight_count%=n_weights b3dnode\class$="bone" index%=0 If n_weights*sz=b3dChunkSize() ;read all weights While b3dChunkSize() vertex_id=b3dReadInt() weight#=b3dReadFloat() ; If weight#>b3dnode\weight#[index] b3dnode\vert_target%[vertex_id]=1;vertex_id b3dnode\weight#[vertex_id]=weight ; Else ; n_weights=n_weights-1 ; End If ; For tmp.NodeChunk=Each NodeChunk ; EntityParent b3dmesh\vrts_ent[vertex_id],b3dnode\joint ; DebugLog "Parenting "+ EntityName(b3dnode\vrts_ent[vertex_id])+" to "+ b3dnode\name$ flag=0 If b3dmesh\joint1[vertex_id]=0 And flag=0 Then b3dmesh\joint1[vertex_id]=b3dnode\joint b3dmesh\weight1#[vertex_id]=weight flag=1 End If If b3dmesh\joint2[vertex_id]=0 And flag=0 Then b3dmesh\joint2[vertex_id]=b3dnode\joint b3dmesh\weight2#[vertex_id]=weight flag=2 End If If b3dmesh\joint3[vertex_id]=0 And flag=0 Then b3dmesh\joint3[vertex_id]=b3dnode\joint b3dmesh\weight3#[vertex_id]=weight flag=3 End If If b3dmesh\joint4[vertex_id]=0 And flag=0 Then b3dmesh\joint4[vertex_id]=b3dnode\joint b3dmesh\weight4#[vertex_id]=weight flag=4 End If index%=index%+1 Wend Else ;;;DebugLog tab$+"***** Illegal number of bone weights *****" EndIf .nodes Case "NODE" ;If level%>1 b3dnode.NodeChunk=New NodeChunk ; End If b3dnode\class$="root" ; 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() ; If w_rot#<>1.0 Then b3dnode\norm=1 b3dnode\joint=findchildentity(mesh,name$) ; DebugLog "creating "+name$ +" "+ b3dnode\joint b3dnode\name$=name$ b3dnode\x_pos#=x_pos# b3dnode\y_pos#=y_pos# b3dnode\z_pos#=z_pos# b3dnode\x_scl#=x_scl# b3dnode\y_scl#=y_scl# b3dnode\z_scl#=z_scl# b3dnode\w_rot#=w_rot# b3dnode\x_rot#=x_rot# b3dnode\y_rot#=y_rot# b3dnode\z_rot#=z_rot# For mark=0 To PMK_MAX_KEYS;b3dmesh\Num_Frames% b3dnode\frame%[mark]=-1 b3dnode\frameP%[mark]=-1 b3dnode\frameS%[mark]=-1 b3dnode\frameR%[mark]=-1 Next ;b3dnode\loangle#=-45.0;-45;-Pi*0.25;-45 degrees ;b3dnode\hiangle#=45.0;Pi*0.25;-45 degrees ;b3dnode\Axis1=1 ;b3dnode\Axis2=2 ;b3dnode\joint_type% = 2 ;b3dnode\max_force#=0.0 ;b3dnode\vel#=0.0 ;b3dnode\angulardamp#=0.5 ;b3dnode\lineardamp#=0.5 ;b3dnode\nproxy=CreatePivot() ; DebugLog b3dnode.NodeChunk\name$ If b3dnode\joint=0 Then ;b3dnode\gui_id=AddTreeViewNode( treeJoints, name$ ); ; DebugLog "adding node :"+b3dnode\name$ +" parent="+b3dnode\joint+" mesh="+mesh Else If GetParent(b3dnode\joint)=mesh Then ;b3dnode\gui_id=AddTreeViewNode( treeJoints, name$ ) b3dnode\parent=mesh Else For tmp.Nodechunk=Each NodeChunk ; DebugLog "looking for.."+tmp\joint+" parent :"+GetParent (b3dnode\joint) If tmp\joint=GetParent (b3dnode\joint) Then ;b3dnode\gui_id=AddTreeViewNode( tmp\gui_id, name$ ) ; DebugLog "adding child node :"+b3dnode\name$+" to "+ tmp\name$ ;dad.nodechunk=getnodechunk(GetParent (b3dnode\joint)) ;b3dnode\bone=createRay.ray(EntityX#(dad\joint,1),EntityY#(dad\joint,1),EntityZ#(dad\joint,1),EntityX#(b3dnode\joint,1),EntityY#(b3dnode\joint,1),EntityZ#(b3dnode\joint,1), punit#*0.1,dad\joint, 1) ;EntityOrder b3dnode\bone\entity,-1 ;UpdateRay(b3dnode.nodechunk) Else ;b3dnode\gui_id=AddTreeViewNode( treeJoints, name$ ) End If Next End If ;b3dnode\geo=CreateSphere() hnd.NodeChunk=b3dnode.NodeChunk ;NameEntity b3dnode\geo,"Sphere: " + name$ ;EntityPickMode b3dnode\geo,2 ;EntityAlpha b3dnode\geo,0.6 ;EntityOrder b3dnode\geo,-3 ;EntityColor b3dnode\geo,0,0,255 ;EntityParent b3dnode\geo,b3dnode\joint,0 ;EntityOrder b3dnode\geo,-1 - make optional ;HideEntity b3dnode\geo ;If b3dnode\ent>0 DebugLog EntityName(b3dnode\geo) + " : " + EntityName(b3dnode\ent) ;joint(NodeCount)=CreateSphere(); ;ScaleEntity b3dnode\geo,.1,.1,.1; ;EntityParent joint(NodeCount),findchildentity(mesh,name$),0; ;NodeCount=NodeCount+1; ;NewJointNo=NewJointNo+1 ;PositionEntity ball,x_pos#,y_pos#,z_pos# ,True If dumpflags And PMK_FLAG_StripNodePaths Then name$=StripPath(name$) Default ; OBS untested! ; out$=BeginTag$(chunk$) ; out$=AddIntegerAttrib(out$,"size",b3dChunkSize()) ; out$ = CloseTag(out$) ; emit out$ ; out$="<![CDATA[" ; While b3dChunkSize() ; out$=out$ + Chr$(b3dReadByte()) ; Wend ; out$=out$ + "]]>" ; emit out$ End Select DumpChunks(dumpflags, tab$,level%) ;dump any subchunks b3dExitChunk() ;exit this chunk Wend End Function Function StripPath$(name$) Local pos For pos=Len(name$) To 1 Step -1 If Mid$(name$,pos,1)="\" Or Mid$(name$,pos,1)="/" Then Exit Next Return Right$(name$,Len(name$)-pos) End Function ;### name : 1-call recursive child search ### ;### by : jonathan pittock (skn3) ### ;### contact: skn3@acsv.net ### ;### www : www.acsv.net ### ;This value is used to size the buffer bank below. If the data needs more space, ;it will resize the bank in blocks of the amount below. (in bytes, 1k = 1024 bytes) Const recursive_resize=1024 ;This bank is used in each call to the search function. It is outside the function, ;as creating and deleting over and over from memory, can cause fragmentation, not... ;to mention slow downs. Global recursive_bank=CreateBank(recursive_resize),recursive_size=recursive_resize ;These are misc values, having them defined as global speeds up the function as... ;they don't need to be created/destroyed each time the function is called Global recursive_entity,recursive_parent,recursive_id,recursive_start,recursive_total,recursive_offset ;The function ;It will return the entity if found, or 0 if not. ;MyChild=findchildentity(entity,"child name") Function findchildentity(entity,name$) name$=Lower$(name$) recursive_parent=entity recursive_start=1 recursive_offset=0 .recursive_label recursive_total=CountChildren(recursive_parent) For recursive_id=recursive_start To recursive_total recursive_entity=GetChild(recursive_parent,recursive_id) If name$=Lower$(EntityName$(recursive_entity)) Return recursive_entity Else If recursive_offset+8 > recursive_size-1 ResizeBank(recursive_bank,recursive_size+recursive_resize) recursive_size=recursive_size+recursive_resize End If PokeInt(recursive_bank,recursive_offset,recursive_id+1) PokeInt(recursive_bank,recursive_offset+4,recursive_parent) recursive_offset=recursive_offset+8 recursive_start=1 recursive_parent=recursive_entity Goto recursive_label End If Next If recursive_offset=0 Return 0 Else recursive_start=PeekInt(recursive_bank,recursive_offset-8) recursive_parent=PeekInt(recursive_bank,recursive_offset-4) recursive_offset=recursive_offset-8 Goto recursive_label End If End Function ;;;;;;;;;;;;;;;;;;;EXPORT FUNCTIONS::::::::::::::::::::::::::::::::: Function pmk2b3d( f_name$,mesh ) file=WriteFile( f_name$ ) b3dSetFile( file ) b3dBeginChunk( "BB3D" ) DebugLog "Begin BB3d" b3dWriteInt( 1 ) ;version If b3dtex.texs<>Null Then b3dBeginChunk("TEXS") DebugLog "Begin Chunk Texs" For x=0 To b3dtex\texs_count%-1 b3dWriteString b3dtex\name$[x] b3dWriteInt b3dtex\flags%[x] b3dWriteInt b3dtex\blend%[x] b3dWritefloat b3dtex\xpos#[x] b3dWritefloat b3dtex\ypos#[x] b3dWritefloat b3dtex\xscale#[x] b3dWritefloat b3dtex\yscale#[x] b3dWritefloat b3dtex\rot#[x] Next b3dEndChunk();TEXS DebugLog "End Chunk Texs" End If .brus If b3dbrush.brus <> Null Then For tmpbrush.brus=Each brus b3dBeginChunk( "BRUS" ) DebugLog "Begin Chunk Brus" b3dWriteInt tmpbrush\brus_tex_count% For x=0 To tmpbrush\brus_count%-1 ;0 textures per brush b3dWriteString tmpbrush\name$[x] ;name b3dWriteFloat tmpbrush\red#[x] ;red b3dWriteFloat tmpbrush\grn#[x] ;green b3dWriteFloat tmpbrush\blu#[x] ;blue b3dWriteFloat tmpbrush\alp#[x] ;alpha b3dWriteFloat tmpbrush\shi#[x] ;shininess b3dWriteInt tmpbrush\blend%[x] ;blend b3dWriteInt tmpbrush\fx%[x] For k=0 To tmpbrush\brus_tex_count%-1 b3dWriteInt PMK_tex_id% (x,k) Next ;b3dWriteInt x Next b3dEndChunk() ;end of BRUS chunk DebugLog "End Chunk Brus" Next End If DebugLog "Begin NODE Chunk" b3dBeginChunk("NODE") b3dWriteString b3dmesh\name$ b3dWritefloat b3dmesh\x_pos# b3dWritefloat b3dmesh\y_pos# b3dWritefloat b3dmesh\z_pos# b3dWritefloat b3dmesh\x_scl# b3dWritefloat b3dmesh\y_scl# b3dWritefloat b3dmesh\z_scl# b3dWritefloat b3dmesh\w_rot# b3dWritefloat b3dmesh\x_rot# b3dWritefloat b3dmesh\y_rot# b3dWritefloat b3dmesh\z_rot# b3dBeginChunk("MESH") DebugLog tab$+"Begin Chunk Mesh" b3dWriteInt b3dmesh\mesh_brush_id b3dBeginChunk("VRTS") DebugLog tab$+"Begin Chunk Vrts" b3dWriteInt b3dmesh\vrts_flags% b3dWriteInt b3dmesh\texturecoordsets% b3dWriteInt b3dmesh\texturecoordsize% For x=0 To b3dmesh\vrts_count%-1 b3dWritefloat b3dmesh\x#[x] b3dWritefloat b3dmesh\y#[x] b3dWritefloat b3dmesh\z#[x] If b3dmesh\vrts_flags% And 1 b3dWritefloat b3dmesh\nx#[x] b3dWritefloat b3dmesh\ny#[x] b3dWritefloat b3dmesh\nz#[x] EndIf If b3dmesh\vrts_flags% And 2 b3dWritefloat b3dmesh\r#[x] b3dWritefloat b3dmesh\g#[x] b3dWritefloat b3dmesh\b#[x] b3dWritefloat b3dmesh\a#[x] EndIf If b3dmesh\texturecoordsets%=1 Then If b3dmesh\texturecoordsize%>0 Then b3dWritefloat b3dmesh\u0#[x] If b3dmesh\texturecoordsize%>1 Then b3dWritefloat b3dmesh\v0#[x] If b3dmesh\texturecoordsize%>2 Then b3dWritefloat b3dmesh\w0#[x] End If If b3dmesh\texturecoordsets%=2 Then If b3dmesh\texturecoordsize%>0 Then b3dWritefloat b3dmesh\u0#[x] If b3dmesh\texturecoordsize%>1 Then b3dWritefloat b3dmesh\v0#[x] If b3dmesh\texturecoordsize%>2 Then b3dWritefloat b3dmesh\w0#[x] If b3dmesh\texturecoordsize%>0 Then b3dWritefloat b3dmesh\u1#[x] If b3dmesh\texturecoordsize%>1 Then b3dWritefloat b3dmesh\v1#[x] If b3dmesh\texturecoordsize%>2 Then b3dWritefloat b3dmesh\w1#[x] End If Next b3dEndChunk();VRTS DebugLog tab$+"End Chunk Vrts" For b3dtris.trischunk=Each trischunk b3dBeginChunk("TRIS") DebugLog tab$+"Begin Chunk Tris" b3dWriteInt b3dtris\tris_brush_id% For x = 0 To b3dtris\tris_count%-1 b3dWriteInt b3dtris\tv0%[x] b3dWriteInt b3dtris\tv1%[x] b3dWriteInt b3dtris\tv2%[x] Next b3dEndChunk();TRIS Next DebugLog tab$+"End Chunk Tris" b3dEndChunk();MESH DebugLog tab$+"End Chunk Mesh" b3dBeginChunk("ANIM") DebugLog tab$+"Begin Chunk Anim" b3dWriteInt b3dmesh\anim_flags% b3dWriteInt b3dmesh\Num_Frames% b3dWriteFloat b3dmesh\FramesPS# b3dEndChunk();ANIM DebugLog tab$+"End Chunk Anim" If CountChildren(mesh)>0 Then WriteNodes(mesh); write joint hierarchy End If DebugLog "End Chunk ROOT" b3dEndChunk();End B3D Chunk CloseFile file Return PMK_ERROR_NONE End Function Function WriteNodes(parent,tab$="") tab$=tab$+" " WriteNode (parent,tab$) If CountChildren(parent)>0 Then For a=1 To CountChildren(parent) child=GetChild(parent,a) fin=WriteNodes(child,tab$) Next End If b3dEndChunk(); end NODE chunk DebugLog tab$+"End Chunk NOde ***********"+ EntityName(parent) ;If parent=mesh Then b3dEndChunk(); end NODE chunk ;DebugLog tab$+"End Chunk NOde"+ currname$ End Function Function WriteNode(child,tab$) For tmp.NodeChunk=Each NodeChunk If tmp\joint=child And tmp\class$="bone" Then currname$=tmp\name$ b3dBeginChunk("NODE") DebugLog tab$+"Begin Chunk Node "+currname$ b3dWriteString tmp\name$ b3dWritefloat tmp\x_pos# b3dWritefloat tmp\y_pos# b3dWritefloat tmp\z_pos# b3dWritefloat tmp\x_scl# b3dWritefloat tmp\y_scl# b3dWritefloat tmp\z_scl# b3dWritefloat tmp\w_rot# b3dWritefloat tmp\x_rot# b3dWritefloat tmp\y_rot# b3dWritefloat tmp\z_rot# If tmp\class$="bone" Then b3dBeginChunk("BONE") DebugLog tab$+"Begin Chunk Bone" ;If tmp\weight_count%>0 For x=0 To b3dmesh\vrts_count%-1 If tmp\vert_target[x]=1 b3dWriteInt x b3dWriteFloat tmp\weight#[x] ; DebugLog tab$+"VERT "+tmp\vert_target%[x]+" WEIGHT "+tmp\weight#[x] End If Next ;End If b3dEndChunk(); end BONE Chunk DebugLog tab$+"End Chunk Bone" If tmp\keys_count%>0 Then b3dBeginChunk("KEYS") DebugLog tab$+"Begin Chunk Keys" b3dWriteInt (1);Compressed for now....Pos and Rot only - get flag value at import For x=0 To PMK_MAX_KEYS-1;animframes;b3dmesh\Num_Frames% If tmp\frameP%[x]>-1 Then b3dWriteInt x ; If tmp\keys_flag% And 1 b3dWritefloat tmp\key_px#[x] b3dWritefloat tmp\key_py#[x] b3dWritefloat tmp\key_pz#[x] ; EndIf ; If tmp\keys_flag% And 2 ; b3dWritefloat (1.0);tmp\key_sx#[x] ; b3dWritefloat (1.0);tmp\key_sy#[x] ; b3dWritefloat (1.0);tmp\key_sz#[x] ; End If ; If tmp\keys_flag% And 4 ; b3dWritefloat tmp\key_rw#[x] ; b3dWritefloat tmp\key_rx#[x] ; b3dWritefloat tmp\key_ry#[x] ; b3dWritefloat tmp\key_rz#[x] End If Next b3dEndChunk(); end KEYS chunk ;b3dBeginChunk("KEYS") ; DebugLog tab$+"Begin Chunk Keys" ; b3dWriteInt (2);Compressed for now....Pos and Rot only - get flag value at import ; For x=0 To PMK_MAX_KEYS-1;b3dmesh\Num_Frames% ; If tmp\frameS%[x]>-1 Then ; b3dWriteInt x ; If tmp\keys_flag% And 1 ; b3dWritefloat tmp\key_px#[x] ; b3dWritefloat tmp\key_py#[x] ; b3dWritefloat tmp\key_pz#[x] ; EndIf ; If tmp\keys_flag% And 2 ; b3dWritefloat tmp\key_sx#[x] ; b3dWritefloat tmp\key_sy#[x] ; b3dWritefloat tmp\key_sz#[x] ; End If ; If tmp\keys_flag% And 4 ; b3dWritefloat tmp\key_rw#[x] ; b3dWritefloat tmp\key_rx#[x] ; b3dWritefloat tmp\key_ry#[x] ; b3dWritefloat tmp\key_rz#[x] ; End If ; Next ; b3dEndChunk(); end KEYS chunk b3dBeginChunk("KEYS") DebugLog tab$+"Begin Chunk Keys" b3dWriteInt (4);Compressed for now....Pos and Rot only - get flag value at import For x=0 To PMK_MAX_KEYS-1;b3dmesh\Num_Frames% If tmp\frameR%[x]>-1 Then b3dWriteInt x ; If tmp\keys_flag% And 1 ; b3dWritefloat tmp\key_px#[x] ; b3dWritefloat tmp\key_py#[x] ; b3dWritefloat tmp\key_pz#[x] ; EndIf ; If tmp\keys_flag% And 2 ; b3dWritefloat (1.0);tmp\key_sx#[x] ; b3dWritefloat (1.0);tmp\key_sy#[x] ; b3dWritefloat (1.0);tmp\key_sz#[x] ; End If ; If tmp\keys_flag% And 4 b3dWritefloat tmp\key_rw#[x] b3dWritefloat tmp\key_rx#[x] b3dWritefloat tmp\key_ry#[x] b3dWritefloat tmp\key_rz#[x] End If Next b3dEndChunk(); end KEYS chunk ;PMK_write_physics_nodes(tmp.nodechunk) DebugLog tab$+"End Chunk Keys" ;b3dEndChunk();End Node Return True End If End If End If Next Return False End Function ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ;;;;;;;;;;;;;TEST;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;First Load and Parse File: You will end up with a NodeChunk type for each node in the model. ; There will be a global NodeChunk type for the Mesh node - B3dmesh. This type contains the UV coords in ; B3dmesh\u0#[vert index],B3dmesh\v0#[vert index],B3dmesh\w0#[vert index] for set 1 and ; B3dmesh\u1#[vert index],B3dmesh\v1#[vert index],B3dmesh\w1#[vert index] for set 2 if exists ; Set 2 is normally used for lightmapping and so will not normally be found on animated models. Graphics3D 800,600, 16,2 file1$="oldfile.b3d" file2$="newfile.b3d" retval=b3d2pmk(file1$);Load and Parse Saving all info to types If retval=PMK_ERROR_NONE Repeat Text 10,10,"OK - Do whatever you want here ! . Text 10,20,"Hit Enter to save Flip Until KeyHit(28) retval=pmk2b3d(file2$,mesh);Save animated model using values held in types Else RuntimeError "Error loading file End If FreeEntity mesh FreeBank recursive_bank |