Hi guys, I havent had time to finish this or even work on it, not sure when i can get to it next but here is a Cal3d loader i was working on, currently i believe i was at the point of trying to weight the vertices to the loaded bones , but i had problems doing that at runtime.
Anyhoo here is the code thus far
Type C3DAnimation
Field duration#
Field numtracks
Field Tracks:C3DTrack[]
Method SetTracks()
Local ntracks:C3DTrack[numtracks]
Tracks = ntracks
End Method
End Type
Type C3DTrack
Field numkeyframes
Field ID
Field keys:C3DKey[]
Method SetKeys()
Local nkeys:C3DKey[numkeyframes]
keys = nkeys
End Method
End Type
Type C3DKey
Field time#
Field rot:C3DQuat = New C3DQuat
End Type
Type C3DFace
Field v1,v2,v3
End Type
Type C3DInfluence
Field v
Field ID
Field weight#
Field submesh:C3DSubMesh
End Type
Type C3DVertex
Field numinfluences
Field pos:C3DCoord = New C3DCoord
Field norm:C3DCoord = New C3DCoord
Field color:C3DCoord = New C3DCoord
Field u#,v#
Field influence:C3DInfluence[]
Field tmp_curr_influence = 0
Method SetInfluences()
Local nflue:C3DInfluence[numinfluences]
influence = nflue
End Method
End Type
Type C3DSubMesh
Field numvertices
Field numfaces
Field numlodsteps
Field numsprings
Field nummorphs
Field numtexcoords
Field matid
Field Vertices:C3DVertex[]
Field Faces:C3DFace[]
Field tmp_curr_face = 0
Field surface:TSurface
Field animsurf:TSurface
Method SetVertex()
Local nverts:C3DVertex[numvertices]
Vertices = nverts
End Method
Method SetFace()
Local nface:C3DFace[numfaces]
Faces = nface
End Method
End Type
Type C3DMesh
Field xmf:TBank
Field xsf:TBank
Field numbones
Field numsubmesh
Field mesh:TMesh = CreateMesh()' = New TMesh
Field bones:C3DBone[]
Field submeshes:C3DSubMesh[]
Field animations:C3DAnimation[]
Field numanims = 0
Method AddB3dBones()
Local dbones:TBone[numbones]
For id = 0 To numbones-1
dbones[id] = New TBone
dbones[id].name$ = bones[id].name$
dbones[id].class$="Bone"
dbones[id].px#=EntityX(bones[id].mesh,True)
dbones[id].py#=EntityY(bones[id].mesh,True)
dbones[id].pz#=EntityZ(bones[id].mesh,True)
dbones[id].rx#=EntityPitch(bones[id].mesh,True)
dbones[id].ry#=EntityYaw(bones[id].mesh,True)
dbones[id].rz#=EntityRoll(bones[id].mesh,True)
dbones[id].qw#=bones[id].rotation.QuatfromEuler(EntityPitch(bones[id].mesh,True),EntityYaw(bones[id].mesh,True),EntityRoll(bones[id].mesh,True)).quat[3]
dbones[id].qx#=bones[id].rotation.QuatfromEuler(EntityPitch(bones[id].mesh,True),EntityYaw(bones[id].mesh,True),EntityRoll(bones[id].mesh,True)).quat[0]
dbones[id].qy#=bones[id].rotation.QuatfromEuler(EntityPitch(bones[id].mesh,True),EntityYaw(bones[id].mesh,True),EntityRoll(bones[id].mesh,True)).quat[1]
dbones[id].qz#=bones[id].rotation.QuatfromEuler(EntityPitch(bones[id].mesh,True),EntityYaw(bones[id].mesh,True),EntityRoll(bones[id].mesh,True)).quat[2]
dbones[id].n_px#=EntityX(bones[id].mesh,True)
dbones[id].n_py#=EntityY(bones[id].mesh,True)
dbones[id].n_pz#=EntityZ(bones[id].mesh,True)
dbones[id].n_rx#=EntityPitch(bones[id].mesh,True)
dbones[id].n_ry#=EntityYaw(bones[id].mesh,True)
dbones[id].n_rz#=EntityRoll(bones[id].mesh,True)
dbones[id].n_qw#=bones[id].rotation.QuatfromEuler(EntityPitch(bones[id].mesh,True),EntityYaw(bones[id].mesh,True),EntityRoll(bones[id].mesh,True)).quat[3]
dbones[id].n_qx#=bones[id].rotation.QuatfromEuler(EntityPitch(bones[id].mesh,True),EntityYaw(bones[id].mesh,True),EntityRoll(bones[id].mesh,True)).quat[0]
dbones[id].n_qy#=bones[id].rotation.QuatfromEuler(EntityPitch(bones[id].mesh,True),EntityYaw(bones[id].mesh,True),EntityRoll(bones[id].mesh,True)).quat[1]
dbones[id].n_qz#=bones[id].rotation.QuatfromEuler(EntityPitch(bones[id].mesh,True),EntityYaw(bones[id].mesh,True),EntityRoll(bones[id].mesh,True)).quat[2]
PositionEntity(dbones[id],dbones[id].n_px#,dbones[id].n_py#,dbones[id].n_pz#,True)
RotateEntity(dbones[id],dbones[id].n_rx#,dbones[id].n_ry#,dbones[id].n_rz#,True)
'TQuaternion.QuatToMat(-dbones[id].n_qw#,dbones[id].n_qx#,dbones[id].n_qy#,-dbones[id].n_qz#,dbones[id].mat)
'dbones[id].mat.grid[3,0]=dbones[id].n_px#
'dbones[id].mat.grid[3,1]=dbones[id].n_py#
'dbones[id].mat.grid[3,2]=dbones[id].n_pz#
'dbones[id].inv_mat=dbones[id].mat.Inverse()
'dbones[id].EntityListAdd(TEntity.entity_list)
Next
'mesh.bones = dbones
'mesh.bones[id-1]=dbones[id]
'last_ent=dbones[id]
For id = 0 To numbones-1
If bones[id].parent <> -1 Then
dbones[id].parent = TEntity(dbones[bones[id].parent])
EntityParent(dbones[id],dbones[id].parent)
EndIf
Next
mesh.bones = dbones
End Method
Method DrawB3dLines(camera:TCamera)
For id = 0 To numbones-1
If mesh.bones[id].parent <> Null Then
CameraProject(camera, EntityX(TBone(mesh.bones[id].parent),True),EntityY(TBone(mesh.bones[id].parent),True),EntityZ(TBone(mesh.bones[id].parent),True))
lineax = ProjectedX()
lineay = ProjectedY()
lineaz = ProjectedZ()
CameraProject(camera, EntityX(mesh.bones[id],True),EntityY(mesh.bones[id],True),EntityZ(mesh.bones[id],True))
linebx = ProjectedX()
lineby = ProjectedY()
linebz = ProjectedZ()
DrawLine(lineax,lineay,linebx,lineby)
EndIf
Next
End Method
Method Drawlines(camera:TCamera,id = -1)
If id = -1 Then
For id = 0 To numbones-1
If bones[id].parent = -1 Then
If bones[id].numchildren > 0 Then
For a = EachIn bones[id].children
Drawlines(camera,a)
Next
CameraProject(camera, EntityX(bones[id].mesh,True),EntityY(bones[id].mesh,True),EntityZ(bones[id].mesh,True))
linebx = ProjectedX()
lineby = ProjectedY()
linebz = ProjectedZ()
DrawText(bones[id].name$,linebx,lineby)
EndIf
Exit
EndIf
Next
Else
If EntityVisible(camera,bones[id].mesh) = True Then
CameraProject(camera, EntityX(bones[bones[id].parent].mesh,True),EntityY(bones[bones[id].parent].mesh,True),EntityZ(bones[bones[id].parent].mesh,True))
lineax = ProjectedX()
lineay = ProjectedY()
lineaz = ProjectedZ()
CameraProject(camera, EntityX(bones[id].mesh,True),EntityY(bones[id].mesh,True),EntityZ(bones[id].mesh,True))
linebx = ProjectedX()
lineby = ProjectedY()
linebz = ProjectedZ()
DrawLine(lineax,lineay,linebx,lineby)
'DrawText(bones[id].name$,linebx,lineby)
EndIf
For a = EachIn bones[id].children
Drawlines(camera,a)
Next
EndIf
End Method
Method InitSkeleton(id = -1)
Local ppivot:TPivot
If id = -1 Then
For id = 0 To numbones-1
If bones[id].parent = -1 Then
PositionEntity(bones[id].mesh,bones[id].translation.coord[0],bones[id].translation.coord[1],bones[id].translation.coord[2],True)
If bones[id].numchildren > 0 Then
For a = EachIn bones[id].children
InitSkeleton(a)
Next
EndIf
Exit
EndIf
Next
AddB3dBones()
Else
PositionEntity(bones[id].mesh,EntityX(bones[bones[id].parent].mesh,True),EntityY(bones[bones[id].parent].mesh,True),EntityZ(bones[bones[id].parent].mesh,True))
RotateEntity(bones[id].mesh,EntityPitch(bones[bones[id].parent].mesh,True),EntityYaw(bones[bones[id].parent].mesh,True),EntityRoll(bones[bones[id].parent].mesh,True))
EntityParent(bones[id].mesh,bones[bones[id].parent].mesh)
TurnEntity(bones[id].mesh,bones[id].rotation.QuattoEuler().coord[0],bones[id].rotation.QuattoEuler().coord[1],-bones[id].rotation.QuattoEuler().coord[2])
PositionEntity(bones[id].mesh,bones[id].translation.coord[0],bones[id].translation.coord[1],bones[id].translation.coord[2])
If bones[id].numchildren > 0 Then
For a = EachIn bones[id].children
InitSkeleton(a)
Next
EndIf
EndIf
End Method
Method GenerateInfluenceList:TList()
Local i,e,o
Local Inlist:TList = New TList
If numsubmesh = 0 Then Return Null
For i = 0 To numsubmesh-1
If submeshes[i].Vertices.length = 0 Then
Continue
Else
For e = 0 To submeshes[i].Vertices.length-1
If submeshes[i].Vertices[e].influence.length = 0 Then
Continue
Else
For o = 0 To submeshes[i].Vertices[e].influence.length-1
ListAddLast(Inlist,submeshes[i].Vertices[e].influence[o])
Next
EndIf
Next
EndIf
Next
Return Inlist
End Method
Method WeighCal3DMesh()
Local i,l,e
Local bo_bone:TBone
Local influence:TList
Local influ:C3DInfluence
If bones.length = 0 Then Return False
mesh.anim=True
mesh.anim_seqs_first[0]=0
mesh.anim_seqs_last[0]=0
For Local surf:TSurface=EachIn mesh.surf_list
Local anim_surf:TSurface=New TSurface
For e = 0 To numsubmesh-1
If submeshes[e].surface = surf Then submeshes[e].animsurf = anim_surf
Next
ListAddLast(mesh.anim_surf_list,anim_surf)
anim_surf.no_verts=surf.no_verts
anim_surf.vert_coords=surf.vert_coords[..]
anim_surf.vert_bone1_no=anim_surf.vert_bone1_no[..surf.no_verts+1]
anim_surf.vert_bone2_no=anim_surf.vert_bone2_no[..surf.no_verts+1]
anim_surf.vert_bone3_no=anim_surf.vert_bone3_no[..surf.no_verts+1]
anim_surf.vert_bone4_no=anim_surf.vert_bone4_no[..surf.no_verts+1]
anim_surf.vert_weight1=anim_surf.vert_weight1[..surf.no_verts+1]
anim_surf.vert_weight2=anim_surf.vert_weight2[..surf.no_verts+1]
anim_surf.vert_weight3=anim_surf.vert_weight3[..surf.no_verts+1]
anim_surf.vert_weight4=anim_surf.vert_weight4[..surf.no_verts+1]
' transfer vmin/vmax values for using with TrimVerts func after
anim_surf.vmin=surf.vmin
anim_surf.vmax=surf.vmax
Next
influence = GenerateInfluenceList()
For influ = EachIn influence
Print "Vertex: "+influ.v+" Weight is "+influ.weight#+" vert weight 1 mb3d "+influ.submesh.animsurf.vert_weight1[influ.v]
If influ.weight#>influ.submesh.animsurf.vert_weight1[influ.v]
influ.submesh.animsurf.vert_bone4_no[influ.v]=influ.submesh.animsurf.vert_bone3_no[influ.v]
influ.submesh.animsurf.vert_weight4[influ.v]=influ.submesh.animsurf.vert_weight3[influ.v]
influ.submesh.animsurf.vert_bone3_no[influ.v]=influ.submesh.animsurf.vert_bone2_no[influ.v]
influ.submesh.animsurf.vert_weight3[influ.v]=influ.submesh.animsurf.vert_weight2[influ.v]
influ.submesh.animsurf.vert_bone2_no[influ.v]=influ.submesh.animsurf.vert_bone1_no[influ.v]
influ.submesh.animsurf.vert_weight2[influ.v]=influ.submesh.animsurf.vert_weight1[influ.v]
influ.submesh.animsurf.vert_bone1_no[influ.v]=influ.ID
influ.submesh.animsurf.vert_weight1[influ.v]=influ.weight#
Else If influ.weight#>influ.submesh.animsurf.vert_weight2[influ.v]
influ.submesh.animsurf.vert_bone4_no[influ.v]=influ.submesh.animsurf.vert_bone3_no[influ.v]
influ.submesh.animsurf.vert_weight4[influ.v]=influ.submesh.animsurf.vert_weight3[influ.v]
influ.submesh.animsurf.vert_bone3_no[influ.v]=influ.submesh.animsurf.vert_bone2_no[influ.v]
influ.submesh.animsurf.vert_weight3[influ.v]=influ.submesh.animsurf.vert_weight2[influ.v]
influ.submesh.animsurf.vert_bone2_no[influ.v]=influ.ID
influ.submesh.animsurf.vert_weight2[influ.v]=influ.weight#
Else If influ.weight#>influ.submesh.animsurf.vert_weight3[influ.v]
influ.submesh.animsurf.vert_bone4_no[influ.v]=influ.submesh.animsurf.vert_bone3_no[influ.v]
influ.submesh.animsurf.vert_weight4[influ.v]=influ.submesh.animsurf.vert_weight3[influ.v]
influ.submesh.animsurf.vert_bone3_no[influ.v]=influ.ID
influ.submesh.animsurf.vert_weight3[influ.v]=influ.weight#
Else If influ.weight#>influ.submesh.animsurf.vert_weight4[influ.v]
influ.submesh.animsurf.vert_bone4_no[influ.v]=influ.ID
influ.submesh.animsurf.vert_weight4[influ.v]=influ.weight#
EndIf
Next
End Method
Method BuildCal3DMesh()
Local i,e,v
Local s:TSurface
'Local smesh:TMesh
If bones.length = 0 Then Return False
If mesh = Null Then
mesh = CreateMesh()
EndIf
RotateEntity(mesh.bones[0],90,90,0)
'RotateEntity(mesh,90,90,0)
For i = 0 To numsubmesh-1
s = mesh.CreateSurface()
submeshes[i].surface = s
For e = 0 To submeshes[i].numvertices-1
v = s.AddVertex((submeshes[i].Vertices[e].pos.coord#[0])+bones[0].translation.coord#[0],(submeshes[i].Vertices[e].pos.coord#[1])+bones[0].translation.coord#[1],(submeshes[i].Vertices[e].pos.coord#[2])+bones[0].translation.coord#[2])
s.VertexTexCoords(v,submeshes[i].Vertices[e].u#,submeshes[i].Vertices[e].v#)
s.VertexNormal(v,submeshes[i].Vertices[e].norm.coord#[0],submeshes[i].Vertices[e].norm.coord#[1],submeshes[i].Vertices[e].norm.coord#[2])
s.VertexColor(v,submeshes[i].Vertices[e].color.coord#[0],submeshes[i].Vertices[e].color.coord#[1],submeshes[i].Vertices[e].color.coord#[2])
Next
For e = 0 To submeshes[i].numfaces-1
s.AddTriangle(submeshes[i].Faces[e].v1,submeshes[i].Faces[e].v2,submeshes[i].Faces[e].v3)
Print "Adding Triangle: "+e
Next
Next
UpdateNormals(mesh)
'ScaleMesh(mesh,0.02,0.02,0.02)
'PositionMesh(mesh,bones[0].local_translation.coord#[0],bones[0].local_translation.coord#[1],bones[0].local_translation.coord#[2])
'AddMesh(smesh,mesh)
'mesh = amesh
WeighCal3DMesh()
mesh.UpdateMat()
End Method
Method LoadCal3dAnim(file:Object)
If bones.length = 0 Then Return False
Local animdoc:xmlDocument = New xmlDocument
Local node:xmlNode,vid
Local subnode:xmlNode
Local infonode:xmlNode
Local CalString:Tokenizer
Local Info:String[]
Local xaf:TBank = LoadBank(file)
animdoc.Load(xaf)
If xaf = Null Then Return False
Select Lower(animdoc.Root().Name)
Case "animation"
numanims = numanims + 1
animations = animations[..numanims]
animations[numanims-1] = New C3DAnimation
animations[numanims-1].duration# = Float(animdoc.Root().Attribute("DURATION").value)
animations[numanims-1].numtracks = Int(animdoc.Root().Attribute("NUMTRACKS").value)
animations[numanims-1].SetTracks()
If animdoc.Root().HasChildren() = True Then
node = animdoc.Root().FirstChild()
curtrack = 0
While node <> Null
animations[numanims-1].Tracks[curtrack] = New C3DTrack
animations[numanims-1].Tracks[curtrack].numkeyframes = Int(node.Attribute("NUMKEYFRAMES").value)
animations[numanims-1].Tracks[curtrack].ID = Int(node.Attribute("BONEID").value)
animations[numanims-1].Tracks[curtrack].SetKeys()
If node.HasChildren() = True Then
subnode = node.FirstChild()
curkey = 0
While subnode <> Null
Select Lower(subnode.Name)
Case "keyframe"
animations[numanims-1].Tracks[curtrack].keys[curkey] = New C3DKey
animations[numanims-1].Tracks[curtrack].keys[curkey].time# = Float(subnode.Attribute("TIME").value)
If subnode.HasChildren() = True Then
infonode = subnode.FirstChild()
While infonode <> Null
Select Lower(infonode.Name)
Case "rotation"
animations[numanims-1].Tracks[curtrack].keys[curkey].rot.QuatfromString(infonode.value)
'Print "have anim rotations: "+animations[numanims-1].Tracks[curtrack].keys[curkey].rot.quat#[0]+" "+
End Select
infonode = infonode.NextSibling()
Wend
EndIf
End Select
curkey = curkey+1
subnode = subnode.NextSibling()
Wend
EndIf
curtrack = curtrack + 1
node = node.NextSibling()
Wend
EndIf
End Select
End Method
Method LoadCal3dMesh(file:Object)
If bones.length = 0 Then Return False
Local meshdoc:xmlDocument = New xmlDocument
Local node:xmlNode,vid
Local subnode:xmlNode
Local infonode:xmlNode
Local CalString:Tokenizer
Local Info:String[]
xmf = LoadBank(file)
meshdoc.Load(xmf)
If xmf = Null Then Return False
Select Lower(meshdoc.Root().Name)
Case "mesh"
numsubmesh = Int(meshdoc.Root().Attribute("NUMSUBMESH").value)
Local nsubs:C3dSubMesh[numsubmesh]
submeshes = nsubs
If meshdoc.Root().HasChildren() = True Then
node = meshdoc.Root().FirstChild()
cursub = 0
While node <> Null
submeshes[cursub] = New C3DSubMesh
submeshes[cursub].numvertices = Int(node.Attribute("NUMVERTICES").value)
submeshes[cursub].numfaces = Int(node.Attribute("NUMFACES").value)
submeshes[cursub].numlodsteps = Int(node.Attribute("NUMLODSTEPS").value)
submeshes[cursub].numsprings = Int(node.Attribute("NUMSPRINGS").value)
submeshes[cursub].nummorphs = Int(node.Attribute("NUMMORPHS").value)
submeshes[cursub].numtexcoords = Int(node.Attribute("NUMTEXCOORDS").value)
submeshes[cursub].matid = Int(node.Attribute("MATERIAL").value)
submeshes[cursub].SetVertex()
submeshes[cursub].SetFace()
submeshes[cursub].tmp_curr_face = 0
If node.HasChildren() = True Then
subnode = node.FirstChild()
While subnode <> Null
Select Lower(subnode.Name)
Case "vertex"
vid = Int(subnode.Attribute("ID").value)
submeshes[cursub].Vertices[vid] = New C3DVertex
submeshes[cursub].Vertices[vid].numinfluences = Int(subnode.Attribute("NUMINFLUENCES").value)
submeshes[cursub].Vertices[vid].SetInfluences()
submeshes[cursub].Vertices[vid].tmp_curr_influence = 0
If subnode.HasChildren() = True Then
infonode = subnode.FirstChild()
While infonode <> Null
Select Lower(infonode.Name)
Case "pos"
'CalString = New Tokenizer
'CalString.Set(infonode.value)
'CalString.Tokenize()
'Info = CalString.TokensToArray()
submeshes[cursub].Vertices[vid].pos.CoordfromString(infonode.value)' = Float(Info[0])
'submeshes[cursub].Vertices[vid].pos.coord#[1] = Float(Info[1])
'submeshes[cursub].Vertices[vid].pos.coord#[2] = Float(Info[2])
Case "norm"
'CalString = New Tokenizer
'CalString.Set(infonode.value)
'CalString.Tokenize()
'Info = CalString.TokensToArray()
submeshes[cursub].Vertices[vid].norm.CoordfromString(infonode.value)' = Float(Info[0])
'submeshes[cursub].Vertices[vid].norm.coord#[1] = Float(Info[1])
'submeshes[cursub].Vertices[vid].norm.coord#[2] = Float(Info[2])
Case "color"
'CalString = New Tokenizer
'CalString.Set(infonode.value)
'CalString.Tokenize()
'Info = CalString.TokensToArray()
submeshes[cursub].Vertices[vid].color.CoordfromString(infonode.value)' = Float(Info[0])
'submeshes[cursub].Vertices[vid].color.coord#[1] = Float(Info[1])
'submeshes[cursub].Vertices[vid].color.coord#[2] = Float(Info[2])
Case "texcoord"
CalString = New Tokenizer
CalString.Set(infonode.value)
CalString.Tokenize()
Info = CalString.TokensToArray()
submeshes[cursub].Vertices[vid].u# = Float(Info[0])
submeshes[cursub].Vertices[vid].v# = Float(Info[1])
Case "influence"
submeshes[cursub].Vertices[vid].Influence[submeshes[cursub].Vertices[vid].tmp_curr_influence] = New C3DInfluence
submeshes[cursub].Vertices[vid].Influence[submeshes[cursub].Vertices[vid].tmp_curr_influence].ID = Int(infonode.Attribute("ID").value)
submeshes[cursub].Vertices[vid].Influence[submeshes[cursub].Vertices[vid].tmp_curr_influence].weight# = Float(infonode.value)
submeshes[cursub].Vertices[vid].Influence[submeshes[cursub].Vertices[vid].tmp_curr_influence].v = vid
submeshes[cursub].Vertices[vid].Influence[submeshes[cursub].Vertices[vid].tmp_curr_influence].submesh = submeshes[cursub]
submeshes[cursub].Vertices[vid].tmp_curr_influence = submeshes[cursub].Vertices[vid].tmp_curr_influence + 1
End Select
infonode = infonode.NextSibling()
Wend
EndIf
Case "face"
CalString = New Tokenizer
CalString.Set(subnode.Attribute("VERTEXID").value)
CalString.Tokenize()
Info = CalString.TokensToArray()
submeshes[cursub].Faces[submeshes[cursub].tmp_curr_face] = New C3DFace
submeshes[cursub].Faces[submeshes[cursub].tmp_curr_face].v1 = Int(Info[0])
submeshes[cursub].Faces[submeshes[cursub].tmp_curr_face].v2 = Int(Info[1])
submeshes[cursub].Faces[submeshes[cursub].tmp_curr_face].v3 = Int(Info[2])
Print "Tokenized Triangle: "+Info[0]+" "+Info[1]+" "+Info[2]
submeshes[cursub].tmp_curr_face = submeshes[cursub].tmp_curr_face + 1
End Select
subnode = subnode.NextSibling()
Wend
EndIf
cursub = cursub + 1
node = node.NextSibling()
Wend
EndIf
End Select
BuildCal3DMesh()
End Method
Method LoadCal3dSkeleton(file:Object)
Local skeletondoc:xmlDocument = New xmlDocument
Local node:xmlNode
Local subnode:xmlNode
Local numchilds = 0
xsf = LoadBank(file)
If xsf = Null Then Return False
skeletondoc.Load(xsf)
Select Lower(skeletondoc.Root().Name)
Case "skeleton"
numbones = Int(skeletondoc.Root().Attribute("NUMBONES").value)
Local nbones:C3DBone[numbones]
bones = nbones
If skeletondoc.Root().HasChildren() = True Then
node = skeletondoc.Root().FirstChild()
While node <> Null
id = Int(node.Attribute("ID").value)
bones[id] = New C3DBone
bones[id].name$ = node.Attribute("NAME").value
numchilds = Int(node.Attribute("NUMCHILDS").value)
'Print "NAME: "+bones[id].name$+"NUMCHILDS: "+numchilds
bones[id].setchildren(numchilds)
If node.HasChildren() = True Then
subnode = node.FirstChild()
While subnode <> Null
Select Lower(subnode.Name)
Case "translation"
bones[id].translation.CoordfromString(subnode.value)
Case "rotation"
bones[id].rotation.QuatfromString(subnode.value)
Case "localtranslation"
bones[id].local_translation.CoordfromString(subnode.value)
Case "localrotation"
bones[id].local_rotation.QuatfromString(subnode.value)
Case "parentid"
bones[id].parent = Int(subnode.value)
Case "childid"
bones[id].children[bones[id].curr_child] = Int(subnode.value)
bones[id].curr_child = bones[id].curr_child + 1
End Select
subnode = subnode.NextSibling()
Wend
EndIf
bones[id].mesh = CreatePivot()
'EntityAlpha(bones[id].mesh,0.1)
'ScaleEntity(bones[id].mesh,0.02,0.02,0.02)
'bones[id].labelsprite = createsprite(bones[id].mesh)
'SpriteViewMode(bones[id].labelsprite,3)
'bones[id].labeltex = CreateTexture(128,64,2)
'Cls
'BeginMax2D()
'DrawText bones[id].name$,0,0
'EndMax2D()
'Flip
'BackBufferToTex(bones[id].labeltex)
'RotateTexture(bones[id].labeltex,180)
'ScaleTexture(bones[id].labeltex,-1,1)
'EntityTexture(bones[id].labelsprite,bones[id].labeltex )
'ScaleSprite(bones[id].labelsprite,0.10,0.10)
'EntityAlpha(bones[id].labelsprite,0.9)
'HideEntity(bones[id].labelsprite)
node = node.NextSibling()
Wend
EndIf
End Select
End Method
End Type
Type C3DBone
Field name$
Field children[]
Field id
Field translation:C3DCoord = New C3DCoord
Field rotation:C3DQuat = New C3DQuat
Field local_translation:C3DCoord = New C3DCoord
Field local_rotation:C3DQuat = New C3DQuat
Field parent
Field numchildren = 0
Field curr_child = 0
Field mesh:TEntity
Field labelsprite:TSprite
Field labeltex:TTexture
Method setchildren(amnt)
Local chlds[amnt]
children = chlds
numchildren = amnt
End Method
Method Combined_translation:C3DCoord()
Local mycoord:C3DCoord = New C3DCoord
mycoord.coord[0] = translation.coord[0] - local_translation.coord[0]
mycoord.coord[1] = translation.coord[1] - local_translation.coord[1]
mycoord.coord[2] = translation.coord[2] - local_translation.coord[2]
Return mycoord
End Method
End Type
Type C3DCoord
Field coord#[3]
Method CoordfromString(mstr$)
a1 = Instr( mstr$," " )
coord[0] = Float(Left$( mstr$,a1 ))
mstr$ = Right( mstr$,Len(mstr$)-a1)
a1 = Instr( mstr$," " )
coord[1] = Float(Left$( mstr$,a1 ))
mstr$ = Right( mstr$,Len(mstr$)-a1)
coord[2] = Float(mstr$)
Print "x: "+coord[0]+" y: "+coord[1]+" z: "+coord[2]
End Method
End Type
Type C3DQuat
Field quat#[4]
Field QuatToEulerAccuracy# = 0.001
Method QuatfromString(mstr$)
a1 = Instr( mstr$," " )
quat[0] = Float(Left$( mstr$,a1 ))
mstr$ = Right( mstr$,Len(mstr$)-a1)
a1 = Instr( mstr$," " )
quat[1] = Float(Left$( mstr$,a1 ))
mstr$ = Right( mstr$,Len(mstr$)-a1)
a1 = Instr( mstr$," " )
quat[2] = Float(Left$( mstr$,a1 ))
mstr$ = Right( mstr$,Len(mstr$)-a1)
quat[3] = Float(mstr$)
Print ""+quat[0]+" "+quat[1]+" "+quat[2]+" "+quat[3]
End Method
Method QuatfromEuler:C3DQuat(r#,p#,y#)
Local out:C3DQuat = New C3DQuat
Local cr# = Cos(-r/2)
Local cp# = Cos(p/2)
Local cy# = Cos(y/2)
Local sr# = Sin(-r/2)
Local sp# = Sin(p/2)
Local sy# = Sin(y/2)
' These variables are only here To cut down on the number of multiplications
Local cpcy# = cp * cy
Local spsy# = sp * sy
Local spcy# = sp * cy
Local cpsy# = cp * sy
' Generate the output quat
out.quat[3] = cr * cpcy + sr * spsy
out.quat[0] = sr * cpcy - cr * spsy
out.quat[1] = cr * spcy + sr * cpsy
out.quat[2] = cr * cpsy - sr * spcy
Return out
End Method
Method QuattoEuler:C3DCoord()
Local sint#, cost#, sinv#, cosv#, sinf#, cosf#
Local cost_temp#
Local out:C3DCoord = New C3DCoord
sint = (2 * quat[3] * quat[1]) - (2 * quat[0] * quat[2])
cost_temp = 1.0 - (sint * sint)
If Abs(cost_temp) > QuatToEulerAccuracy
cost = Sqr(cost_temp)
Else
cost = 0
EndIf
If Abs(cost) > QuatToEulerAccuracy
sinv = ((2 * quat[1] * quat[2]) + (2 * quat[3] * quat[0])) / cost
cosv = (1 - (2 * quat[0] * quat[0]) - (2 * quat[1] * quat[1])) / cost
sinf = ((2 * quat[0] * quat[1]) + (2 * quat[3] * quat[2])) / cost
cosf = (1 - (2 * quat[1] * quat[1]) - (2 * quat[2] * quat[2])) / cost
Else
sinv = (2 * quat[3] * quat[0]) - (2 * quat[1] * quat[2])
cosv = 1 - (2 * quat[0] * quat[0]) - (2 * quat[2] * quat[2])
sinf = 0
cosf = 1
EndIf
' Generate the output rotation
out.coord[0] = -ATan2(sinv, cosv) ' inverted due To change in handedness of coordinate system
out.coord[1] = ATan2(sint, cost)
out.coord[2] = ATan2(sinf, cosf)
'Print "R: "+out.coord[0]+" P: "+out.coord[1]+" Y: "+out.coord[2]
Return out
End Method
End Type
Function c3ddemo()
Local filter$="Skeleton Files:xsf; All Files:*"
Local tfile$ = RequestFile( "Select file to open",filter$ )
cmesh.LoadCal3dSkeleton(tfile$)
cmesh.InitSkeleton()
filter$="Mesh Files:xmf; All Files:*"
tfile$ = RequestFile( "Select file to open",filter$ )
cmesh.LoadCal3dMesh(tfile$)
filter$="Animation Files:xaf; All Files:*"
tfile$ = RequestFile( "Select file to open",filter$ )
cmesh.LoadCal3dAnim(tfile$)
End Function
Type Tokenizer
Field theString:String = ""
Field tokenList:TList = New TList
Field tokenLink:TLink = New TLink
Function Create:Tokenizer(theString:String)
Local newTokenizer:Tokenizer = New Tokenizer
newTokenizer.theString = theString
Return newTokenizer
End Function
Method Set(theString:String)
Self.theString = theString
End Method
Method Get:String()
Return ToString()
End Method
Method ToString:String()
Return theString
End Method
Method Tokenize(delim:String = " ")
tokenList.Clear()
lastI = -1
token:String = ""
For i = 0 To theString.length - 1
If theString[i..(i+delim.length)] = delim Then
token = theString[(lastI+1)..i]
tokenList.AddLast(token)
i = i + delim.length - 1 ' Needed for the support of a delimiter with more than 1 char
lastI = i
EndIf
Next
token = theString[(lastI+1)..]
tokenList.AddLast(token)
Self.GotoFirstToken()
End Method
Method CountTokens()
Return tokenList.Count()
End Method
Method NextToken:String()
If tokenLink = Null Then Return ""
token:String = tokenLink.Value().ToString()
tokenLink = tokenLink.NextLink()
Return token
End Method
Method GotoFirstToken()
tokenLink = tokenList.FirstLink()
End Method
Method HasMoreTokens()
If tokenLink = Null Then Return False
Return True
End Method
Method TokensToArray:String[]()
Local array:Object[]
array = tokenList.ToArray()
Local array2:String[array.length]
For i = 0 To array.length - 1
array2[i] = array[i].ToString()
Next
Return array2
End Method
Method Split:String[](delim:String = " ")
Tokenize(delim)
Return TokensToArray()
End Method
End Type
|