@@ -830,72 +830,79 @@ async function createMCFile(
830830 }
831831 console . log ( 'Animation Scripts:' , animationScripts )
832832
833- function generateLeaf ( leaf : TreeLeaf ) {
834- const ret = [ ]
835- for ( const [ boneName , bone ] of Object . entries ( bones ) ) {
836- if ( boneName === 'head' ) {
837- console . log ( boneName )
838- console . log ( bone )
839- console . log ( leaf . item . bones [ boneName ] )
840- }
841- let pos = leaf . item . bones [ boneName ] . pos
842- pos = {
843- x : roundToN ( pos . x , 1000 ) ,
844- y : roundToN ( pos . y + headYOffset , 1000 ) ,
845- z : roundToN ( pos . z , 1000 ) ,
846- }
847- let rot = leaf . item . bones [ boneName ] . rot
848- rot = {
849- x : roundToN ( rot . x , 10000 ) ,
850- y : roundToN ( rot . y , 10000 ) ,
851- z : roundToN ( rot . z , 10000 ) ,
852- }
853- // prettier-ignore
854- ret . push ( 'say a' )
855- // ret.push(`execute if entity @s[tag=${format(tags.individualBone, {boneName})}] positioned ^${pos.x} ^${pos.y} ^${pos.z} run {
856- // name frame/${boneName}/${leaf.index}
857- // execute if entity @s [type=${entityTypes.boneDisplay}] run data modify entity @s Pose.Head set value [${rot.x}f,${rot.y}f,${rot.z}f]
858- // tp @s ~ ~ ~ ~ ~
859- // }`)
833+ function getPos ( boneName : string , leaf : TreeLeaf ) {
834+ let pos = leaf . item . bones [ boneName ] . pos
835+ return {
836+ x : roundToN ( pos . x , 1000 ) ,
837+ y : roundToN ( pos . y + headYOffset , 1000 ) ,
838+ z : roundToN ( pos . z , 1000 ) ,
860839 }
861- return ret . join ( '\n' )
862840 }
863841
864- function generateBoneTree ( ) {
865- const animationTree = generateTree ( animation . frames )
866- console . log ( 'Animation Tree:' , animationTree )
867-
868- function recurse ( item : TreeLeaf | TreeBranch ) {
869- switch ( item . type ) {
870- case 'branch' :
871- const innerTree = item . items
872- . map ( ( v : any ) => recurse ( v ) )
873- . join ( '\n' )
874- // prettier-ignore
875- return `execute if score .this ${ scoreboards . frame } matches ${ item . min } ..${ item . max - 1 } run {
876- name branch/${ item . min } -${ item . max - 1 }
877- ${ innerTree }
878- }`
879- case 'leaf' :
880- // prettier-ignore
881- return `execute if score .this ${ scoreboards . frame } matches ${ item . index } run {
882- name leaf/${ item . index }
883- ${ generateLeaf ( item ) }
884- }`
885- }
842+ function getRot ( boneName : string , leaf : TreeLeaf ) {
843+ let rot = leaf . item . bones [ boneName ] . rot
844+ return {
845+ x : roundToN ( rot . x , 10000 ) ,
846+ y : roundToN ( rot . y , 10000 ) ,
847+ z : roundToN ( rot . z , 10000 ) ,
886848 }
849+ }
850+
851+ function generateBoneTrees ( ) {
852+ const animationTree = generateTree ( animation . frames )
887853 if ( animationTree . type === 'leaf' )
888854 throw new Error (
889855 `Invalid top-level TreeLeaf for animation ${ animation . name } `
890856 )
891- return animationTree . items
892- . map ( ( v : any ) => recurse ( v ) )
893- . join ( '\n' )
857+ const boneTrees = Object . fromEntries (
858+ Object . keys ( bones ) . map ( ( v ) => [
859+ v ,
860+ { root : '' , display : '' } ,
861+ ] )
862+ )
863+
864+ for ( const boneName of Object . keys ( bones ) ) {
865+ function createRootTree ( item : TreeBranch | TreeLeaf ) {
866+ switch ( item . type ) {
867+ case 'branch' :
868+ // prettier-ignore
869+ return `execute if score .this ${ scoreboards . frame } matches ${ item . min } ..${ item . max - 1 } run {
870+ name tree/${ boneName } _root_${ item . min } -${ item . max - 1 }
871+ ${ item . items . map ( ( v : any ) => createRootTree ( v ) ) . join ( '\n' ) }
872+ }`
873+ case 'leaf' :
874+ const pos = getPos ( boneName , item )
875+ return `execute if score .this ${ scoreboards . frame } matches ${ item . index } run tp @s ^${ pos . x } ^${ pos . y } ^${ pos . z } ~ ~`
876+ }
877+ }
878+
879+ function createDisplayTree ( item : TreeBranch | TreeLeaf ) {
880+ switch ( item . type ) {
881+ case 'branch' :
882+ // prettier-ignore
883+ return `execute if score .this ${ scoreboards . frame } matches ${ item . min } ..${ item . max - 1 } run {
884+ name tree/${ boneName } _display_${ item . min } -${ item . max - 1 }
885+ ${ item . items . map ( ( v : any ) => createDisplayTree ( v ) ) . join ( '\n' ) }
886+ }`
887+ case 'leaf' :
888+ const rot = getRot ( boneName , item )
889+ return `execute if score .this ${ scoreboards . frame } matches ${ item . index } run data modify entity @s Pose.Head set value [${ rot . x } f,${ rot . y } f,${ rot . z } f]`
890+ }
891+ }
892+
893+ boneTrees [ boneName ] . root = animationTree . items
894+ . map ( ( v : any ) => createRootTree ( v ) )
895+ . join ( '\n' )
896+ boneTrees [ boneName ] . display = animationTree . items
897+ . map ( ( v : any ) => createDisplayTree ( v ) )
898+ . join ( '\n' )
899+ }
900+ return boneTrees
894901 }
895902
896- const boneTree = generateBoneTree ( )
903+ const boneTrees = generateBoneTrees ( )
897904 console . groupCollapsed ( 'Bone Tree' )
898- console . log ( boneTree )
905+ console . log ( boneTrees )
899906 console . groupEnd ( )
900907
901908 FILE . push ( `dir ${ animation . name } {` )
@@ -977,10 +984,30 @@ async function createMCFile(
977984 scoreboard players operation .this ${ scoreboards . id } = @s ${ scoreboards . id }
978985 scoreboard players operation .this ${ scoreboards . frame } = @s ${ scoreboards . frame }
979986 execute rotated ~ 0 as @e[type=${ entityTypes . bone } ,tag=${ tags . allBones } ,distance=..${ maxDistance } ] if score @s ${ scoreboards . id } = .this ${ scoreboards . id } run {
980- name branch/top
981- ${ boneTree }
982-
983- execute if entity @s[type=${ entityTypes . boneRoot } ] store result entity @s Air short 1 run scoreboard players get .this ${ scoreboards . frame }
987+ name tree/trunk
988+ # Bone Roots
989+ execute if entity @s[type=${ entityTypes . boneRoot } ] run {
990+ name tree/root_bone_name
991+ ${ Object . entries ( boneTrees ) . map ( ( [ boneName , trees ] ) =>
992+ `execute if entity @s[tag=${ format ( tags . individualBone , { boneName} ) } ] run {
993+ name tree/${ boneName } _root_top
994+ ${ trees . root }
995+ }`
996+ ) . join ( '\n' ) }
997+ execute store result entity @s Air short 1 run scoreboard players get .this ${ scoreboards . frame }
998+ }
999+ # Bone Displays
1000+ execute if entity @s[type=${ entityTypes . boneDisplay } ] run {
1001+ name tree/display_bone_name
1002+ ${ Object . entries ( boneTrees ) . map ( ( [ boneName , trees ] ) =>
1003+ `execute if entity @s[tag=${ format ( tags . individualBone , { boneName} ) } ] run {
1004+ name tree/${ boneName } _display_top
1005+ ${ trees . display }
1006+ }`
1007+ ) . join ( '\n' ) }
1008+ # Make sure rotation stays aligned with root entity
1009+ execute positioned as @s run tp @s ~ ~ ~ ~ ~
1010+ }
9841011 }
9851012
9861013 ${ animationScripts . length > 0 ? `
0 commit comments