@@ -139,8 +139,45 @@ function packSkin(
139139 tasks . push ( {
140140 description : `Packing skin "${ name } " texture...` ,
141141 async execute ( ) {
142+ const uniqueSprites = new Map <
143+ string ,
144+ {
145+ name : string
146+ texture : string
147+ padding : {
148+ left : boolean
149+ right : boolean
150+ top : boolean
151+ bottom : boolean
152+ }
153+ }
154+ > ( )
155+ const spriteMapping = new Map < string , string > ( )
156+ const textureHashCache = new Map < string , string > ( )
157+ for ( const s of skin . data . sprites ) {
158+ let hash = textureHashCache . get ( s . texture )
159+ if ( ! hash ) {
160+ const result = await packRaw ( s . texture )
161+ hash = result . hash
162+ textureHashCache . set ( s . texture , hash )
163+ }
164+ const key = `${ hash } :${ Number ( s . padding . left ) } :${ Number ( s . padding . right ) } :${ Number ( s . padding . top ) } :${ Number ( s . padding . bottom ) } `
165+ let unique = uniqueSprites . get ( key )
166+ if ( ! unique ) {
167+ unique = {
168+ name : s . name ,
169+ texture : s . texture ,
170+ padding : s . padding ,
171+ }
172+ uniqueSprites . set ( key , unique )
173+ }
174+ spriteMapping . set ( s . name , unique . name )
175+ }
176+
177+ const uniqueSpriteList = Array . from ( uniqueSprites . values ( ) )
178+
142179 const { size, layouts } = await tryCalculateLayout (
143- skin . data . sprites . map ( ( s ) => ( {
180+ uniqueSpriteList . map ( ( s ) => ( {
144181 name : s . name ,
145182 texture : s . texture ,
146183 padding : s . padding ,
@@ -158,18 +195,26 @@ function packSkin(
158195
159196 ctx . clearRect ( 0 , 0 , size , size )
160197
161- for ( const { name, x, y, w, h } of layouts ) {
162- const sprite = skin . data . sprites . find ( ( sprite ) => sprite . name === name )
163- if ( ! sprite ) throw new Error ( 'Unexpected missing sprite' )
198+ for ( const s of skin . data . sprites ) {
199+ const uniqueName = spriteMapping . get ( s . name )
200+ if ( ! uniqueName ) throw new Error ( 'Unexpected missing sprite mapping' )
201+
202+ const layout = layouts . find ( ( l ) => l . name === uniqueName )
203+ if ( ! layout ) throw new Error ( 'Unexpected missing sprite layout' )
164204
165205 skinData . sprites . push ( {
166- name,
167- x : x + ( sprite . padding . left ? 1 : 0 ) ,
168- y : y + ( sprite . padding . top ? 1 : 0 ) ,
169- w,
170- h,
171- transform : sprite . transform ,
206+ name : s . name ,
207+ x : layout . x + ( s . padding . left ? 1 : 0 ) ,
208+ y : layout . y + ( s . padding . top ? 1 : 0 ) ,
209+ w : layout . w ,
210+ h : layout . h ,
211+ transform : s . transform ,
172212 } )
213+ }
214+
215+ for ( const { name, x, y, w, h } of layouts ) {
216+ const sprite = skin . data . sprites . find ( ( s ) => s . name === name )
217+ if ( ! sprite ) throw new Error ( 'Unexpected missing sprite' )
173218
174219 await bakeSprite ( sprite , x , y , w , h , ctx )
175220 }
0 commit comments