Pārlūkot izejas kodu

packed sprite close to working

Guide 6 gadi atpakaļ
vecāks
revīzija
7d152824cf

+ 1 - 0
dist/preview release/what's new.md

@@ -13,6 +13,7 @@
   - WebXR webVR parity helpers (Vive, WMR, Oculus Rift) ([TrevorDev](https://github.com/TrevorDev))
 
 ## Updates
+- SpritePackedManager extends SpriteManager so that a sprite sheet with different size sprites can be used ([JohnK](https://github.com/BabylonJSGuide))
 
 ### General
 - Added support for dual shock gamepads ([Deltakosh](https://github.com/deltakosh/))

+ 1 - 1
src/Shaders/sprites.vertex.fx

@@ -44,7 +44,7 @@ void main(void) {
 	vec2 uvSize = cellInfo.zw;
 
 	vUV.x = uvPlace.x + uvSize.x * uvOffset.x;
-	vUV.y = 1.0 - (uvPlace.y + uvSize.y * uvOffset.y);
+	vUV.y = uvPlace.y + uvSize.y * uvOffset.y;
 
 	// Fog
 #ifdef FOG

+ 66 - 12
src/Sprites/spriteManager.ts

@@ -13,6 +13,8 @@ import { Effect } from "../Materials/effect";
 import { Material } from "../Materials/material";
 import { SceneComponentConstants } from "../sceneComponent";
 import { Constants } from "../Engines/constants";
+import { AssetsManager } from "../Misc/assetsManager";
+import { Logger } from "../Misc/logger";
 
 import "../Shaders/sprites.fragment";
 import "../Shaders/sprites.vertex";
@@ -80,12 +82,13 @@ export class SpriteManager implements ISpriteManager {
     public cellWidth: number;
     /** Defines the default height of a cell in the spritesheet */
     public cellHeight: number;
+
     /** Associative array from JSON sprite data file */
-    public cellData: any;
+    private _cellData: any;
     /** Array of sprite names from JSON sprite data file */
-    public spriteMap: Array<string>;
+    private _spriteMap: Array<string>;
     /** True when packed cell data from JSON file is ready*/
-    public packedAndReady: boolean = false;
+    private _packedAndReady: boolean = false;
 
     /**
     * An event triggered when the manager is disposed.
@@ -143,7 +146,7 @@ export class SpriteManager implements ISpriteManager {
     constructor(
         /** defines the manager's name */
         public name: string,
-        imgUrl: string, capacity: number, cellSize: any, scene: Scene, epsilon: number = 0.01, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, fromPacked: boolean = false) {
+        imgUrl: string, capacity: number, cellSize: any, scene: Scene, epsilon: number = 0.01, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, fromPacked: boolean = false, spriteJSON: string = "") {
         if (!scene._getComponent(SceneComponentConstants.NAME_SPRITE)) {
             scene._addComponent(new SpriteSceneComponent(scene));
         }
@@ -208,6 +211,56 @@ export class SpriteManager implements ISpriteManager {
             [VertexBuffer.PositionKind, "options", "inverts", "cellInfo", VertexBuffer.ColorKind],
             ["view", "projection", "textureInfos", "alphaTest", "vFogInfos", "vFogColor"],
             ["diffuseSampler"], "#define FOG");
+
+        if (this._fromPacked) {
+            this._makePacked(imgUrl, spriteJSON);
+        }
+    }
+
+    private _makePacked(imgUrl: string, spriteJSON: string) {
+        if (spriteJSON !== null) {
+            try {
+                let celldata = JSON.parse(spriteJSON);
+                let spritemap = (<string[]>(<any>Reflect).ownKeys(celldata.frames));
+                this._spriteMap = spritemap;
+                this._packedAndReady = true;
+                this._cellData = celldata.frames;
+            }
+            catch (e) {
+                throw new Error(`Invalid JSON`);
+            }
+        }
+        else {
+            let re = /\./g;
+            let li: number;
+            do {
+                li = re.lastIndex;
+                re.test(imgUrl);
+            } while (re.lastIndex > 0);
+            let jsonUrl = imgUrl.substring(0, li - 1) + ".json";
+            let assetsManager = new AssetsManager(this._scene);
+            let task = assetsManager.addTextFileTask("LoadSpriteJSON", jsonUrl);
+
+            task.onSuccess = (task) => {
+                try {
+                    let celldata  = JSON.parse(task.text);
+                    let spritemap = (<string[]>(<any>Reflect).ownKeys(celldata.frames));
+                    this._spriteMap = spritemap;
+                    this._packedAndReady = true;
+                    this._cellData = celldata.frames;
+                }
+                catch (e) {
+                    throw new Error(`Invalid JSON`);
+                }
+            };
+
+            assetsManager.onTaskErrorObservable.add((task) => {
+                Logger.Error("Unable to Load Sprite JSON Data. Spritesheet managed with constant cell size.");
+                this._fromPacked = false;
+                this._packedAndReady = false;
+            });
+            assetsManager.load();
+        }
     }
 
     private _appendSpriteVertex(index: number, sprite: Sprite, offsetX: number, offsetY: number, baseSize: any): void {
@@ -241,14 +294,15 @@ export class SpriteManager implements ISpriteManager {
         this._vertexData[arrayOffset + 8] = sprite.invertU ? 1 : 0;
         this._vertexData[arrayOffset + 9] = sprite.invertV ? 1 : 0;
         // CellIfo
-        if (this.packedAndReady) {
-            if (sprite.cellIndex) {
-                sprite.cellRef = this.spriteMap[sprite.cellIndex];
+        if (this._packedAndReady) {
+            let num = sprite.cellIndex;
+            if (typeof (num) === "number" && isFinite(num) && Math.floor(num) === num) {
+                sprite.cellRef = this._spriteMap[sprite.cellIndex];
             }
-            this._vertexData[arrayOffset + 10] = this.cellData[sprite.cellRef].x / baseSize.width;
-            this._vertexData[arrayOffset + 11] = this.cellData[sprite.cellRef].y / baseSize.height;
-            this._vertexData[arrayOffset + 12] = this.cellData[sprite.cellRef].w / baseSize.width;
-            this._vertexData[arrayOffset + 13] = this.cellData[sprite.cellRef].h / baseSize.height;
+            this._vertexData[arrayOffset + 10] = this._cellData[sprite.cellRef].frame.x / baseSize.width;
+            this._vertexData[arrayOffset + 11] = this._cellData[sprite.cellRef].frame.y / baseSize.height;
+            this._vertexData[arrayOffset + 12] = this._cellData[sprite.cellRef].frame.w / baseSize.width;
+            this._vertexData[arrayOffset + 13] = this._cellData[sprite.cellRef].frame.h / baseSize.height;
         }
         else {
             var rowSize = baseSize.width / this.cellWidth;
@@ -349,7 +403,7 @@ export class SpriteManager implements ISpriteManager {
             return;
         }
 
-        if (this._fromPacked  && (!this.packedAndReady || !this.spriteMap || !this.cellData)) {
+        if (this._fromPacked  && (!this._packedAndReady || !this._spriteMap || !this._cellData)) {
             return;
         }
 

+ 10 - 52
src/Sprites/spritePackedManager.ts

@@ -1,10 +1,13 @@
 import { SpriteManager } from "./spriteManager";
-import { AssetsManager } from "../Misc/assetsManager";
 import { Scene } from "../scene";
 import { Texture } from "../Materials/Textures/texture";
-import { Logger } from "../Misc/logger";
 
-export class SpritePackedManager {
+/**
+ * Class used to manage multiple sprites of different sizes on the same spritesheet
+ * @see http://doc.babylonjs.com/babylon101/sprites
+ */
+
+export class SpritePackedManager extends SpriteManager{
 
     /**
      * Creates a new sprite manager from a packed sprite sheet
@@ -12,61 +15,16 @@ export class SpritePackedManager {
      * @param imgUrl defines the sprite sheet url
      * @param capacity defines the maximum allowed number of sprites
      * @param scene defines the hosting scene
-     * @param sspriteJSON, null otherwise a JSON object defining sprite sheet data
+     * @param spriteJSON, null otherwise a JSON object defining sprite sheet data
      * @param epsilon defines the epsilon value to align texture (0.01 by default)
      * @param samplingMode defines the smapling mode to use with spritesheet
      * @param fromPacked set to true; do not alter
      */
-    constructor(public name: string, imgUrl: string, capacity: number, scene: Scene, spriteJSON: string | null = null, epsilon: number = 0.01, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE) {
-
-        //the cellSize parameter is not used when built from JSON which provides individual cell data
-        let spriteManager = new SpriteManager(name, imgUrl, capacity, 0, scene, epsilon, samplingMode, true);
-
-        if (spriteJSON !== null) {
-            try {
-                let celldata = JSON.parse(spriteJSON);
-                let spritemap = (<string[]>(<any>Reflect).ownKeys(celldata.frames));
-                spriteManager.spriteMap = spritemap;
-                spriteManager.packedAndReady = true;
-                spriteManager.cellData = celldata.frames;
-                return spriteManager;
-            }
-            catch (e) {
-                throw new Error(`Invalid JSON`);
-            }
-        }
-        else {
-            let re = /\./g;
-            let li: number;
-            do {
-                li = re.lastIndex;
-                re.test(imgUrl);
-            } while (re.lastIndex > 0);
-            let jsonUrl = imgUrl.substring(0, li - 1) + ".json";
-            let assetsManager = new AssetsManager(scene);
-            let task = assetsManager.addTextFileTask("LoadSpriteJSON", jsonUrl);
 
-            task.onSuccess = (task) => {
-                try {
-                    let celldata  = JSON.parse(task.text);
-                    let spritemap = (<string[]>(<any>Reflect).ownKeys(celldata.frames));
-                    spriteManager.spriteMap = spritemap;
-                    spriteManager.packedAndReady = true;
-                    spriteManager.cellData = celldata.frames;
-                    return spriteManager;
-                }
-                catch (e) {
-                    throw new Error(`Invalid JSON`);
-                }
-            };
+    constructor(public name: string, imgUrl: string, capacity: number, scene: Scene, spriteJSON: string = "", epsilon: number = 0.01, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE) {
 
-            assetsManager.onTaskErrorObservable.add((task) => {
-                Logger.Error("Unable to Load Sprite JSON Data. Default Spritesheet managed.");
-                spriteManager.dispose();
-                return new SpriteManager("default", "https://www.babylonjs-playground.com/textures/amiga.jpg", 1, 64, scene);
-            });
-            assetsManager.load();
-        }
+        //the cellSize parameter is not used when built from JSON which provides individual cell data, defaults to 64 if JSON load fails
+        super(name, imgUrl, capacity, 64, scene, epsilon, samplingMode, true, spriteJSON);
 
     }
 }