[bb] Load/Save Anim .b3d by Ricky Smith [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:38

Previous topic - Next topic

BlitzBot

Title : Load/Save Anim .b3d
Author : Ricky Smith
Posted : 1+ years ago

Description : 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.


Code :
Code (blitzbasic) Select
;--------------------------------------------------------------
;
; 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
ame$=b3dReadString()
; b3dseqfstart%=b3dReadInt()
; b3dseqfend%=b3dReadInt()
; b3dseqseq%=ExtractAnimSeq (mesh,b3dseqfstart%,b3dseqfend%)
; b3dseqgui_id=AddListBoxItem( lstSeq, 0, b3dseqseq% + " - " + b3dseq
ame$)
Case "PHYS"
; b3dnodejoint_type=b3dReadInt()
; b3dnodeloangle#=b3dReadFloat()
; b3dnodehiangle#=b3dReadFloat()
; b3dnodeAxis1=b3dReadInt()
; b3dnodeAxis2=b3dReadInt()


Case "ANIM"

flags=b3dReadInt()
n_frames=b3dReadInt()
fps=b3dReadFloat()

AnimFrames%=n_frames
; DebugLog "Anim Frames :" + AnimFrames
AnimFPS#=fps

;___________________________________

b3dnodeanim_flags%=flags
b3dnodeNum_Frames%=n_frames
b3dnodeFramesPS#=fps
;_____________________________________
.keys
Case "KEYS"

;For mark=0 To PMK_MAX_KEYS;b3dmeshNum_Frames%
; b3dnodeframe%[mark]=-1
; b3dnodeframeP%[mark]=-1
; b3dnodeframeS%[mark]=-1
; b3dnodeframeR%[mark]=-1
; Next
flags=b3dReadInt()




b3dnodekeys_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
b3dnodekeys_count%=n_keys



If n_keys*sz=b3dChunkSize()

While b3dChunkSize()
frame=b3dReadInt()



b3dnodeframe%[frame]=frame


If flags And 1
b3dnodeframeP%[frame]=frame
key_px#=b3dReadFloat()
key_py#=b3dReadFloat()
key_pz#=b3dReadFloat()



b3dnodekey_px#[frame]=key_px#
b3dnodekey_py#[frame]=key_py#
b3dnodekey_pz#[frame]=key_pz#

EndIf

If flags And 2
b3dnodeframeS%[frame]=frame
key_sx#=b3dReadFloat()
key_sy#=b3dReadFloat()
key_sz#=b3dReadFloat()



b3dnodekey_sx#[frame]=key_sx#
b3dnodekey_sy#[frame]=key_sy#
b3dnodekey_sz#[frame]=key_sz#

EndIf

If flags And 4
b3dnodeframeR%[frame]=frame
key_rw#=b3dReadFloat()
key_rx#=b3dReadFloat()
key_ry#=b3dReadFloat()
key_rz#=b3dReadFloat()



b3dnodekey_rw#[frame]=key_rw#
b3dnodekey_rx#[frame]=key_rx#
b3dnodekey_ry#[frame]=key_ry#
b3dnodekey_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
ame$[index]=name$
b3dtexflags%[index]=flags
b3dtexlend%[index]=blend
b3dtexxpos#[index]=x_pos#
b3dtexypos#[index]=y_pos#
b3dtexxscale#[index]=x_scl#
b3dtexyscale#[index]=y_scl#
b3dtexot#[index]=rot#

index=index+1
Wend
b3dtex exs_count%=index
.brus
Case "BRUS"
b3dbrush.brus=New brus
n_texs=b3dReadInt()
b3dbrushrus_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
ame$[index]=name$
b3dbrushed#[index]=red#
b3dbrushgrn#[index]=grn#
b3dbrushlu#[index]=blu#
b3dbrushalp#[index]=alp#
b3dbrushshi#[index]=shi#
b3dbrushlend%[index]=blend
b3dbrushfx%[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
b3dbrushrus_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








b3dnodevrts_count%=n_verts
b3dnodevrts_flags%=flags
b3dnode exturecoordsets%=tc_sets
b3dnode exturecoordsize%=tc_size






If n_verts*sz=b3dChunkSize()
index%=0
;read all verts in chunk
While b3dChunkSize()


b3dnodevrts_index%[index]=0; Used for Selection !


x#=b3dReadFloat()
y#=b3dReadFloat()
z#=b3dReadFloat()



b3dnodex#[index]=x#
b3dnodey#[index]=y#
b3dnodez#[index]=z#













If flags And 1
nx#=b3dReadFloat()
ny#=b3dReadFloat()
nz#=b3dReadFloat()



b3dnode
x#[index]=nx#
b3dnode
y#[index]=ny#
b3dnode
z#[index]=nz#


EndIf
If flags And 2
r#=b3dReadFloat()
g#=b3dReadFloat()
b#=b3dReadFloat()
a#=b3dReadFloat()




b3dnode#[index]=r#
b3dnodeg#[index]=g#
b3dnode#[index]=b#
b3dnodea#[index]=a#


EndIf
;Parent vert boxes
; b3dnodevrts_ent[index]=CreateCube()
; NameEntity b3dnodevrts_ent[index],index
; EntityColor b3dnodevrts_ent[index],255,255,255
; EntityParent b3dnodevrts_ent[index],b3dnodejoint
; PositionEntity b3dnodevrts_ent[index],x,y,z,0
; ScaleMesh b3dnodevrts_ent[index],.1,.1,.1
; b3dnodeS#[index]=255
; b3dnodegS#[index]=255
; b3dnodeS#[index]=255
; EntityPickMode b3dnodevrts_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
b3dnodeu0#[index]=uvw
Else
b3dnodeu1#[index]=uvw
End If


ElseIf coordnameindex=2
cn$="v"
If Not set Then
b3dnodev0#[index]=uvw
Else
b3dnodev1#[index]=uvw
End If



Else
cn$="w"
If Not set Then
b3dnodew0#[index]=uvw
Else
b3dnodew1#[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 ris_count%=n_tris
b3dtris ris_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 v0%[index]=v0
b3dtris v1%[index]=v1
b3dtris v2%[index]=v2
index%=index%+1
Wend
Else
;;;DebugLog tab$+"***** Illegal number of triangles *****"
EndIf
Case "MESH"
brush_id=b3dReadInt()



b3dnodemesh_brush_id=brush_id
b3dnodeclass$="mesh"
b3dmesh=b3dnode
;HideEntity b3dmeshgeo
.bone
Case "BONE"

 
sz=8
n_weights=b3dChunkSize()/sz
b3dnodeweight_count%=n_weights

b3dnodeclass$="bone"
index%=0
If n_weights*sz=b3dChunkSize()
;read all weights
While b3dChunkSize()
vertex_id=b3dReadInt()
weight#=b3dReadFloat()

; If weight#>b3dnodeweight#[index]
b3dnodevert_target%[vertex_id]=1;vertex_id

b3dnodeweight#[vertex_id]=weight

; Else

; n_weights=n_weights-1
; End If

; For tmp.NodeChunk=Each NodeChunk
; EntityParent b3dmeshvrts_ent[vertex_id],b3dnodejoint
; DebugLog "Parenting "+ EntityName(b3dnodevrts_ent[vertex_id])+" to "+ b3dnode
ame$
flag=0
If  b3dmeshjoint1[vertex_id]=0 And flag=0 Then
b3dmeshjoint1[vertex_id]=b3dnodejoint
b3dmeshweight1#[vertex_id]=weight
flag=1
End If

If  b3dmeshjoint2[vertex_id]=0 And flag=0 Then
b3dmeshjoint2[vertex_id]=b3dnodejoint
b3dmeshweight2#[vertex_id]=weight
flag=2
End If

If  b3dmeshjoint3[vertex_id]=0 And flag=0 Then
b3dmeshjoint3[vertex_id]=b3dnodejoint
b3dmeshweight3#[vertex_id]=weight
flag=3
End If

If  b3dmeshjoint4[vertex_id]=0 And flag=0 Then
b3dmeshjoint4[vertex_id]=b3dnodejoint
b3dmeshweight4#[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
b3dnodeclass$="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
orm=1

b3dnodejoint=findchildentity(mesh,name$)
; DebugLog "creating "+name$ +" "+ b3dnodejoint


b3dnode
ame$=name$
b3dnodex_pos#=x_pos#
b3dnodey_pos#=y_pos#
b3dnodez_pos#=z_pos#
b3dnodex_scl#=x_scl#
b3dnodey_scl#=y_scl#
b3dnodez_scl#=z_scl#
b3dnodew_rot#=w_rot#
b3dnodex_rot#=x_rot#
b3dnodey_rot#=y_rot#
b3dnodez_rot#=z_rot#

For mark=0 To PMK_MAX_KEYS;b3dmeshNum_Frames%
b3dnodeframe%[mark]=-1
b3dnodeframeP%[mark]=-1
b3dnodeframeS%[mark]=-1
b3dnodeframeR%[mark]=-1
Next
;b3dnodeloangle#=-45.0;-45;-Pi*0.25;-45 degrees
;b3dnodehiangle#=45.0;Pi*0.25;-45 degrees
;b3dnodeAxis1=1
;b3dnodeAxis2=2
;b3dnodejoint_type% = 2
;b3dnodemax_force#=0.0
;b3dnodevel#=0.0
;b3dnodeangulardamp#=0.5
;b3dnodelineardamp#=0.5
;b3dnode
proxy=CreatePivot()
; DebugLog  b3dnode.NodeChunk
ame$

If b3dnodejoint=0 Then
;b3dnodegui_id=AddTreeViewNode( treeJoints, name$ );
; DebugLog "adding node  :"+b3dnode
ame$ +"  parent="+b3dnodejoint+"   mesh="+mesh

Else If GetParent(b3dnodejoint)=mesh Then

;b3dnodegui_id=AddTreeViewNode( treeJoints, name$ )
b3dnodeparent=mesh
Else

For tmp.Nodechunk=Each NodeChunk
; DebugLog "looking for.."+tmpjoint+"  parent   :"+GetParent (b3dnodejoint)
If tmpjoint=GetParent (b3dnodejoint) Then
;b3dnodegui_id=AddTreeViewNode( tmpgui_id, name$ )
; DebugLog "adding child node  :"+b3dnode
ame$+"  to  "+ tmp
ame$
;dad.nodechunk=getnodechunk(GetParent (b3dnodejoint))
;b3dnodeone=createRay.ray(EntityX#(dadjoint,1),EntityY#(dadjoint,1),EntityZ#(dadjoint,1),EntityX#(b3dnodejoint,1),EntityY#(b3dnodejoint,1),EntityZ#(b3dnodejoint,1), punit#*0.1,dadjoint, 1)
;EntityOrder b3dnodeoneentity,-1
;UpdateRay(b3dnode.nodechunk)
Else

;b3dnodegui_id=AddTreeViewNode( treeJoints, name$ )
End If
Next

End If

;b3dnodegeo=CreateSphere()
hnd.NodeChunk=b3dnode.NodeChunk
;NameEntity b3dnodegeo,"Sphere: " + name$
;EntityPickMode b3dnodegeo,2
;EntityAlpha b3dnodegeo,0.6
;EntityOrder b3dnodegeo,-3
;EntityColor b3dnodegeo,0,0,255
;EntityParent b3dnodegeo,b3dnodejoint,0
;EntityOrder b3dnodegeo,-1 - make optional
;HideEntity b3dnodegeo
;If b3dnodeent>0 DebugLog EntityName(b3dnodegeo) + " : " + EntityName(b3dnodeent)
;joint(NodeCount)=CreateSphere();
;ScaleEntity b3dnodegeo,.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 exs_count%-1
b3dWriteString b3dtex
ame$[x]
b3dWriteInt b3dtexflags%[x]
b3dWriteInt b3dtexlend%[x]
b3dWritefloat b3dtexxpos#[x]
b3dWritefloat b3dtexypos#[x]
b3dWritefloat b3dtexxscale#[x]
b3dWritefloat b3dtexyscale#[x]
b3dWritefloat b3dtexot#[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 tmpbrushrus_tex_count%

For x=0 To tmpbrushrus_count%-1
;0 textures per brush
b3dWriteString  tmpbrush
ame$[x] ;name
b3dWriteFloat   tmpbrushed#[x] ;red
b3dWriteFloat   tmpbrushgrn#[x] ;green
b3dWriteFloat   tmpbrushlu#[x] ;blue
b3dWriteFloat   tmpbrushalp#[x] ;alpha
b3dWriteFloat   tmpbrushshi#[x] ;shininess
b3dWriteInt     tmpbrushlend%[x] ;blend
b3dWriteInt     tmpbrushfx%[x]

For k=0 To tmpbrushrus_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
ame$
b3dWritefloat b3dmeshx_pos#
b3dWritefloat b3dmeshy_pos#
b3dWritefloat b3dmeshz_pos#
b3dWritefloat b3dmeshx_scl#
b3dWritefloat b3dmeshy_scl#
b3dWritefloat b3dmeshz_scl#
b3dWritefloat b3dmeshw_rot#
b3dWritefloat b3dmeshx_rot#
b3dWritefloat b3dmeshy_rot#
b3dWritefloat b3dmeshz_rot#


b3dBeginChunk("MESH")
DebugLog tab$+"Begin Chunk Mesh"
b3dWriteInt b3dmeshmesh_brush_id

b3dBeginChunk("VRTS")
DebugLog tab$+"Begin Chunk Vrts"

b3dWriteInt b3dmeshvrts_flags%
b3dWriteInt b3dmesh exturecoordsets%
b3dWriteInt b3dmesh exturecoordsize%


For x=0 To b3dmeshvrts_count%-1


b3dWritefloat b3dmeshx#[x]
b3dWritefloat b3dmeshy#[x]
b3dWritefloat b3dmeshz#[x]



If b3dmeshvrts_flags% And 1
b3dWritefloat b3dmesh
x#[x]
b3dWritefloat b3dmesh
y#[x]
b3dWritefloat b3dmesh
z#[x]

EndIf
If b3dmeshvrts_flags% And 2
b3dWritefloat b3dmesh#[x]
b3dWritefloat b3dmeshg#[x]
b3dWritefloat b3dmesh#[x]
b3dWritefloat b3dmesha#[x]
EndIf


If b3dmesh exturecoordsets%=1 Then


If b3dmesh exturecoordsize%>0 Then b3dWritefloat b3dmeshu0#[x]
If b3dmesh exturecoordsize%>1 Then b3dWritefloat b3dmeshv0#[x]
If b3dmesh exturecoordsize%>2 Then b3dWritefloat b3dmeshw0#[x]

End If

If b3dmesh exturecoordsets%=2 Then

If b3dmesh exturecoordsize%>0 Then b3dWritefloat b3dmeshu0#[x]
If b3dmesh exturecoordsize%>1 Then b3dWritefloat b3dmeshv0#[x]
If b3dmesh exturecoordsize%>2 Then b3dWritefloat b3dmeshw0#[x]

If b3dmesh exturecoordsize%>0 Then b3dWritefloat b3dmeshu1#[x]
If b3dmesh exturecoordsize%>1 Then b3dWritefloat b3dmeshv1#[x]
If b3dmesh exturecoordsize%>2 Then b3dWritefloat b3dmeshw1#[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 ris_brush_id%

For x = 0 To b3dtris ris_count%-1

b3dWriteInt b3dtris v0%[x]
b3dWriteInt b3dtris v1%[x]
b3dWriteInt b3dtris v2%[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 b3dmeshanim_flags%
b3dWriteInt b3dmeshNum_Frames%
b3dWriteFloat b3dmeshFramesPS#
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 tmpjoint=child And tmpclass$="bone" Then
currname$=tmp
ame$

b3dBeginChunk("NODE")
DebugLog tab$+"Begin Chunk Node  "+currname$
b3dWriteString tmp
ame$
b3dWritefloat tmpx_pos#
b3dWritefloat tmpy_pos#
b3dWritefloat tmpz_pos#
b3dWritefloat tmpx_scl#
b3dWritefloat tmpy_scl#
b3dWritefloat tmpz_scl#
b3dWritefloat tmpw_rot#
b3dWritefloat tmpx_rot#
b3dWritefloat tmpy_rot#
b3dWritefloat tmpz_rot#







If tmpclass$="bone" Then
b3dBeginChunk("BONE")
DebugLog tab$+"Begin Chunk Bone"

;If tmpweight_count%>0
For x=0 To b3dmeshvrts_count%-1
If tmpvert_target[x]=1
b3dWriteInt x
b3dWriteFloat tmpweight#[x]
; DebugLog tab$+"VERT "+tmpvert_target%[x]+"  WEIGHT "+tmpweight#[x]
End If
Next
;End If
b3dEndChunk(); end BONE Chunk
DebugLog tab$+"End Chunk Bone"



If tmpkeys_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;b3dmeshNum_Frames%
If tmpframeP%[x]>-1 Then
b3dWriteInt x

; If tmpkeys_flag% And 1

b3dWritefloat tmpkey_px#[x]
b3dWritefloat tmpkey_py#[x]
b3dWritefloat tmpkey_pz#[x]

; EndIf

; If tmpkeys_flag% And 2

; b3dWritefloat (1.0);tmpkey_sx#[x]
; b3dWritefloat (1.0);tmpkey_sy#[x]
; b3dWritefloat (1.0);tmpkey_sz#[x]

; End If

; If tmpkeys_flag% And 4

; b3dWritefloat tmpkey_rw#[x]
; b3dWritefloat tmpkey_rx#[x]
; b3dWritefloat tmpkey_ry#[x]
; b3dWritefloat tmpkey_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;b3dmeshNum_Frames%
; If tmpframeS%[x]>-1 Then
; b3dWriteInt x

; If tmpkeys_flag% And 1

; b3dWritefloat tmpkey_px#[x]
; b3dWritefloat tmpkey_py#[x]
; b3dWritefloat tmpkey_pz#[x]

; EndIf

; If tmpkeys_flag% And 2

; b3dWritefloat tmpkey_sx#[x]
; b3dWritefloat tmpkey_sy#[x]
; b3dWritefloat tmpkey_sz#[x]

; End If

; If tmpkeys_flag% And 4

; b3dWritefloat tmpkey_rw#[x]
; b3dWritefloat tmpkey_rx#[x]
; b3dWritefloat tmpkey_ry#[x]
; b3dWritefloat tmpkey_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;b3dmeshNum_Frames%
If tmpframeR%[x]>-1 Then
b3dWriteInt x

; If tmpkeys_flag% And 1

; b3dWritefloat tmpkey_px#[x]
; b3dWritefloat tmpkey_py#[x]
; b3dWritefloat tmpkey_pz#[x]

; EndIf

; If tmpkeys_flag% And 2

; b3dWritefloat (1.0);tmpkey_sx#[x]
; b3dWritefloat (1.0);tmpkey_sy#[x]
; b3dWritefloat (1.0);tmpkey_sz#[x]

; End If

; If tmpkeys_flag% And 4

b3dWritefloat tmpkey_rw#[x]
b3dWritefloat tmpkey_rx#[x]
b3dWritefloat tmpkey_ry#[x]
b3dWritefloat tmpkey_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
; B3dmeshu0#[vert index],B3dmeshv0#[vert index],B3dmeshw0#[vert index] for set 1 and
; B3dmeshu1#[vert index],B3dmeshv1#[vert index],B3dmeshw1#[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


Comments :


Bnesiba(Posted 1+ years ago)

 will this save animated .X files as well as animated .b3d?


Damien Sturdy(Posted 1+ years ago)

 No.


ShadowTurtle(Posted 1+ years ago)

 You can write an .X Loader for loading the data into the types and export it as (animated) b3d.


Bnesiba(Posted 1+ years ago)

 ok, if i use loadanimmesh() and load a .x file, then run the pmk2b3d() function will it save an animated .b3d or not?


Ricky Smith(Posted 1+ years ago)

 No, unfortunately Blitz3d only supports import of the DirectX7 animated .x file which doesn't use bones.The file would be saved as a static mesh.You would have to do as Shadow Turtle suggests and write a .X loader first to fill the type values then you could use the pmk2b3d() function to export as .b3d.


bytecode77(Posted 1+ years ago)

 can we access the exact vertex coords of each vertex somehow?and if, how?


Ricky Smith(Posted 1+ years ago)

 One way would be to keep the values in an array of some type and calculate and update the vertex positions manually when the model is animating - taking into consideration the vertex weighting. This would probably be too slow to be useful in  real-time.


H. T. U.(Posted 1+ years ago)

 Thanks, I wanted a way to edit fine details on my b3d models in-game.


jfk EO-11110(Posted 1+ years ago)

 Would be nice to have an Example that shows how to deal with the KeysChunk. Eg. how to alter some keys and save the Animesh with a new/edited animation. Some Field naes don't seem very obvious to me. Anyone?


Ricky Smith(Posted 1+ years ago)

 b3dnodex_pos#
  • =Position key X axis animation frame xb3dnodey_pos#
  • =Position key Y axis frame xb3dnodez_pos#
  • =Position key Z axis frame xb3dnodex_scl#
  • =Scale Key X frame xb3dnodey_scl#
  • =Scale key Y frame xb3dnodez_scl#
  • =Scale Key Z frame xb3dnodew_rot#
  • =W Quaternion(rotation) value for frame xb3dnodex_rot#
  • =X Quaternion(rotation) value for frame xb3dnodey_rot#
  • =Y Quaternion(rotation) value for frame xb3dnodez_rot#
  • =Z Quaternion(rotation) value for frame xJust load the model - set these values and then save to save the animation.[/li][/list]
    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,"Set the animation key values 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