Browse Source

texture packer

fixed some glitches and enabled POWER2 Mode.
Pryme8 5 years ago
parent
commit
698cf95a99
1 changed files with 89 additions and 56 deletions
  1. 89 56
      src/Materials/Textures/Packer/packer.ts

+ 89 - 56
src/Materials/Textures/Packer/packer.ts

@@ -146,7 +146,7 @@ export class TexturePacker{
         this.options.uvsOut = this.options.uvsOut || VertexBuffer.UVKind;
         this.options.uvsOut = this.options.uvsOut || VertexBuffer.UVKind;
         this.options.layout = this.options.layout || TexturePacker.LAYOUT_STRIP;
         this.options.layout = this.options.layout || TexturePacker.LAYOUT_STRIP;
 
 
-        if ( this.options.layout === TexturePacker.LAYOUT_COLNUM ) {
+        if (this.options.layout === TexturePacker.LAYOUT_COLNUM) {
             this.options.colcount = this.options.colcount || 8;
             this.options.colcount = this.options.colcount || 8;
         }
         }
 
 
@@ -166,7 +166,7 @@ export class TexturePacker{
         this._paddingValue = Math.ceil(this.options.frameSize * this.options.paddingRatio);
         this._paddingValue = Math.ceil(this.options.frameSize * this.options.paddingRatio);
 
 
         //Make it an even padding Number.
         //Make it an even padding Number.
-        if ( this._paddingValue % 2 !== 0 ) {
+        if (this._paddingValue % 2 !== 0) {
             this._paddingValue++;
             this._paddingValue++;
         }
         }
 
 
@@ -176,35 +176,35 @@ export class TexturePacker{
         /**
         /**
         * Create the promise and then run through the materials on the meshes.
         * Create the promise and then run through the materials on the meshes.
         */
         */
-        this.promise = new Promise ( ( resolve, reject ) => {
+        this.promise = new Promise ((resolve, reject) => {
             try {
             try {
                 let done = 0;
                 let done = 0;
-                const doneCheck = ( mat: Material ) => {
+                const doneCheck = (mat: Material) => {
                     done++;
                     done++;
                     //Check Status of all Textures on all meshes, till they are ready.
                     //Check Status of all Textures on all meshes, till they are ready.
-                    if ( this.options.map ) {
-                        for ( let j = 0; j < this.options.map.length; j++ ) {
+                    if (this.options.map) {
+                        for (let j = 0; j < this.options.map.length; j++) {
                             let index: string = this.options.map[j];
                             let index: string = this.options.map[j];
-                            let t: Texture = ( mat as any )[index];
+                            let t: Texture = (mat as any)[index];
 
 
-                            if ( t !== null ) {
-                                if ( !( this.sets as any )[this.options.map[j]] ) {
-                                    ( this.sets as any )[this.options.map[j]] = true;
+                            if (t !== null) {
+                                if (!(this.sets as any)[this.options.map[j]]) {
+                                    (this.sets as any)[this.options.map[j]] = true;
                                 }
                                 }
 
 
-                                if ( this.options.disposeSources ) {
-                                    this._disposeList.push( t );
+                                if (this.options.disposeSources) {
+                                    this._disposeList.push(t);
                                 }
                                 }
                             }
                             }
                         }
                         }
 
 
-                        if ( done === this.meshes.length ) {
-                            this._createFrames( resolve );
+                        if (done === this.meshes.length) {
+                            this._createFrames(resolve);
                         }
                         }
                     }
                     }
                 };
                 };
 
 
-                for ( let i = 0; i < this.meshes.length; i++ ) {
+                for (let i = 0; i < this.meshes.length; i++) {
 
 
                     let mesh = this.meshes[i];
                     let mesh = this.meshes[i];
                     let material: Nullable< Material > = mesh.material;
                     let material: Nullable< Material > = mesh.material;
@@ -213,13 +213,13 @@ export class TexturePacker{
                         return new Error('Mesh has no Material assigned!');
                         return new Error('Mesh has no Material assigned!');
                     }
                     }
 
 
-                    material.forceCompilationAsync( mesh ).then( () => {
-                        doneCheck( ( material as Material ) );
+                    material.forceCompilationAsync(mesh).then(() => {
+                        doneCheck((material as Material));
                     });
                     });
                 }
                 }
 
 
-            }catch ( e ) {
-                return reject( e );
+            }catch (e) {
+                return reject(e);
             }
             }
         });
         });
 
 
@@ -231,19 +231,19 @@ export class TexturePacker{
     * @param resolve The promises resolution function
     * @param resolve The promises resolution function
     * @returns TexturePacker
     * @returns TexturePacker
     */
     */
-    private _createFrames( resolve: () => void ) {
+    private _createFrames(resolve: () => void) {
 
 
         let dtSize = this._calculateSize();
         let dtSize = this._calculateSize();
-        let dtUnits = ( new Vector2( 1, 1 ) ).divide( dtSize );
+        let dtUnits = (new Vector2(1, 1)).divide(dtSize);
         let doneCount = 0;
         let doneCount = 0;
         let expecting = this._disposeList.length;
         let expecting = this._disposeList.length;
         let meshLength = this.meshes.length;
         let meshLength = this.meshes.length;
 
 
-        let sKeys = Object.keys( this.sets );
-        for ( let i = 0; i < sKeys.length; i++ ) {
+        let sKeys = Object.keys(this.sets);
+        for (let i = 0; i < sKeys.length; i++) {
             let setName = sKeys[i];
             let setName = sKeys[i];
 
 
-            let dt = new DynamicTexture( this.name + '.TexturePack.' + setName + 'Set',
+            let dt = new DynamicTexture(this.name + '.TexturePack.' + setName + 'Set',
                     { width: dtSize.x, height: dtSize.y },
                     { width: dtSize.x, height: dtSize.y },
                     this.scene,
                     this.scene,
                     true, //Generate Mips
                     true, //Generate Mips
@@ -253,21 +253,21 @@ export class TexturePacker{
 
 
             let dtx = dt.getContext();
             let dtx = dt.getContext();
             dtx.fillStyle = 'rgba(0,0,0,0)';
             dtx.fillStyle = 'rgba(0,0,0,0)';
-            dtx.fillRect( 0, 0, dtSize.x, dtSize.y ) ;
-            dt.update( false );
-            ( this.sets as any )[setName] = dt;
+            dtx.fillRect(0, 0, dtSize.x, dtSize.y) ;
+            dt.update(false);
+            (this.sets as any)[setName] = dt;
         }
         }
 
 
         let baseSize = this.options.frameSize || 256;
         let baseSize = this.options.frameSize || 256;
         let padding = this._paddingValue;
         let padding = this._paddingValue;
-        let tcs = baseSize + ( 2 * padding );
+        let tcs = baseSize + (2 * padding);
 
 
         const done = () => {
         const done = () => {
-            this._calculateMeshUVFrames( baseSize, padding, dtSize, dtUnits, this.options.updateInputMeshes || false );
+            this._calculateMeshUVFrames(baseSize, padding, dtSize, dtUnits, this.options.updateInputMeshes || false);
         };
         };
 
 
         //Update the Textures
         //Update the Textures
-        for ( let i = 0; i < meshLength; i++ ) {
+        for (let i = 0; i < meshLength; i++) {
             let m = this.meshes[i];
             let m = this.meshes[i];
             let mat = m.material;
             let mat = m.material;
 
 
@@ -276,8 +276,8 @@ export class TexturePacker{
             //Then apply the texture to the center and the 8 offsets
             //Then apply the texture to the center and the 8 offsets
             //Copy the Context and place in the correct frame on the DT
             //Copy the Context and place in the correct frame on the DT
 
 
-            for ( let j = 0; j < sKeys.length; j++ ) {
-                let tempTexture = new DynamicTexture( 'temp', tcs, this.scene, true );
+            for (let j = 0; j < sKeys.length; j++) {
+                let tempTexture = new DynamicTexture('temp', tcs, this.scene, true);
                 let tcx = tempTexture.getContext();
                 let tcx = tempTexture.getContext();
 
 
                 //tempTexture.update(false)
                 //tempTexture.update(false)
@@ -286,55 +286,71 @@ export class TexturePacker{
 
 
                 const updateDt = () => {
                 const updateDt = () => {
                     doneCount++;
                     doneCount++;
-                    let iDat = tcx.getImageData( 0, 0, tcs, tcs );
+                    tempTexture.update(false);
+                    let iDat = tcx.getImageData(0, 0, tcs, tcs);
+
                     //Update Set
                     //Update Set
-                    let dt = ( this.sets as any )[setName];
+                    let dt = (this.sets as any)[setName];
                     let dtx = dt.getContext();
                     let dtx = dt.getContext();
-                    dtx.putImageData( iDat, dtSize.x * offset.x, dtSize.y * offset.y );
+                    dtx.putImageData(iDat, dtSize.x * offset.x, dtSize.y * offset.y);
                     tempTexture.dispose();
                     tempTexture.dispose();
-                    dt.update( true );
-                    
-                    if ( doneCount == expecting ) {
+                    dt.update(false);
+                    if (doneCount == expecting) {
                         done();
                         done();
                         resolve();
                         resolve();
                     }
                     }
                 };
                 };
 
 
                 let setName = sKeys[j] || '_blank';
                 let setName = sKeys[j] || '_blank';
-                if ( ( mat as any )[setName] === null ) {
+                if ((mat as any)[setName] === null) {
                     tcx.fillStyle = 'rgba(0,0,0,0)';
                     tcx.fillStyle = 'rgba(0,0,0,0)';
 
 
-                    if ( this.options.fillBlanks ) {
-                        tcx.fillStyle = ( this.options.customFillColor as string );
+                    if (this.options.fillBlanks) {
+                        tcx.fillStyle = (this.options.customFillColor as string);
                     }
                     }
 
 
-                    tcx.fillRect( 0, 0, tcs, tcs );
-                    tempTexture.update( false );
+                    tcx.fillRect(0, 0, tcs, tcs);
+
                     updateDt();
                     updateDt();
 
 
                 }else {
                 }else {
                     let img = new Image();
                     let img = new Image();
-                    img.src = ( mat as any )[setName]!.url;
+                    img.src = (mat as any)[setName]!.url;
                     img.onload = () => {
                     img.onload = () => {
                         tcx.fillStyle = 'rgba(0,0,0,0)';
                         tcx.fillStyle = 'rgba(0,0,0,0)';
-                        tcx.fillRect( 0, 0, tcs, tcs );
-                        tempTexture.update( false );
-                        
-                        let cellOffsets = [ 0,0, 1,0, 1,1, 0,1, -1,1, -1,0, -1-1, 0,-1, 1,-1]
-                        
-                        for(let i=0; i<9; i++){
+                        tcx.fillRect(0, 0, tcs, tcs);
+                        tempTexture.update(false);
+
+                        tcx.setTransform(1, 0, 0, -1, 0, 0);
+
+                        let cellOffsets = [ 0, 0, 1, 0, 1, 1, 0, 1, -1, 1, -1, 0, -1 - 1, 0, -1, 1, -1];
+                        for (let i = 0; i < 9; i++) {
                             tcx.drawImage(
                             tcx.drawImage(
                             img,
                             img,
                             0,
                             0,
                             0,
                             0,
                             img.width,
                             img.width,
                             img.height,
                             img.height,
-                            padding + ( baseSize * cellOffsets[i]),
-                            padding + ( baseSize * cellOffsets[i + 1]),
+                            (padding) + (baseSize * cellOffsets[i]),
+                            ((padding) + (baseSize * cellOffsets[i + 1])) - tcs,
                             baseSize,
                             baseSize,
                             baseSize
                             baseSize
                             );
                             );
-                        } 
+                        }
+
+                        tcx.setTransform(1, 0, 0, 1, 0, 0);
+
+                        /*tempTexture.update( false );
+                        let iDat = tcx.getImageData( 0, 0, tcs, tcs );
+                        tcx.fillStyle = 'rgba(0,0,0,0)';
+                        tcx.fillRect( 0, 0, tcs, tcs );
+                        tempTexture.update( false );
+
+                        tcx.setTransform(1, 0, 0, -1, 0, 0);
+                        tcx.putImageData( iDat, 0, -tcs );
+                        tcx.setTransform(1, 0, 0, 1, 0, 0);
+                        tempTexture.update( false );*/
+
                         updateDt();
                         updateDt();
                     };
                     };
                 }
                 }
@@ -360,6 +376,12 @@ export class TexturePacker{
                     (baseSize) + (2 * padding)
                     (baseSize) + (2 * padding)
                 );
                 );
             break;
             break;
+            case 1 :
+                //POWER2
+                let sqrtCount = Math.max(2, Math.ceil(Math.sqrt(meshLength)));
+                let size = (baseSize * sqrtCount) + (2 * padding * sqrtCount);
+                return new Vector2(size, size);
+            break;
         }
         }
 
 
         return Vector2.Zero();
         return Vector2.Zero();
@@ -385,7 +407,7 @@ export class TexturePacker{
                 baseSize / dtSize.y,
                 baseSize / dtSize.y,
             );
             );
 
 
-            let pOffset: Vector2 = dtUnits.clone().scale(padding);
+            let pOffset: Vector2 = dtUnits.clone().scale(padding * 0.5);
             let frameOffset: Vector2 = this._getFrameOffset(i);
             let frameOffset: Vector2 = this._getFrameOffset(i);
             let offset: Vector2 = frameOffset.add(pOffset);
             let offset: Vector2 = frameOffset.add(pOffset);
 
 
@@ -404,16 +426,27 @@ export class TexturePacker{
     }
     }
 
 
     private _getFrameOffset(index: number): Vector2 {
     private _getFrameOffset(index: number): Vector2 {
+
         let meshLength = this.meshes.length;
         let meshLength = this.meshes.length;
+        let uvStep;
+
         switch (this.options.layout){
         switch (this.options.layout){
             case 0 :
             case 0 :
                 //STRIP_LAYOUT
                 //STRIP_LAYOUT
-                let xStep = 1 / meshLength;
+                uvStep = 1 / meshLength;
                 return new Vector2(
                 return new Vector2(
-                    index * xStep,
+                    index * uvStep,
                     0
                     0
                 );
                 );
             break;
             break;
+            case 1 :
+                //POWER2
+                let sqrtCount = Math.max(2, Math.ceil(Math.sqrt(meshLength)));
+                let yStep = Math.floor(index / sqrtCount);
+                let xStep = index - (yStep * sqrtCount);
+                uvStep = 1 / sqrtCount;
+                return new Vector2(xStep * uvStep , yStep * uvStep);
+            break;
         }
         }
 
 
         return Vector2.Zero();
         return Vector2.Zero();