From ad4f1023358bea38689b1266e2f547149b529498 Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Thu, 10 Aug 2017 05:17:02 +0100 Subject: [PATCH] Added ability to load Unity meta data files for sprite sheets --- v3/src/loader/BaseLoader.js | 15 +++ v3/src/loader/filetypes/UnityAtlasFile.js | 20 +++ v3/src/plugins/Loader.js | 12 ++ v3/src/textures/TextureManager.js | 9 ++ v3/src/textures/parsers/UnityYAML.js | 141 ++++++++++++++++++++++ v3/src/textures/parsers/index.js | 3 +- 6 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 v3/src/loader/filetypes/UnityAtlasFile.js create mode 100644 v3/src/textures/parsers/UnityYAML.js diff --git a/v3/src/loader/BaseLoader.js b/v3/src/loader/BaseLoader.js index ce8a06efa..da936fb32 100644 --- a/v3/src/loader/BaseLoader.js +++ b/v3/src/loader/BaseLoader.js @@ -373,6 +373,21 @@ var BaseLoader = new Class({ } break; + case 'unityatlas': + + fileA = file.fileA; + fileB = file.fileB; + + if (fileA.type === 'image') + { + textures.addUnityAtlas(fileA.key, fileA.data, fileB.data); + } + else + { + textures.addUnityAtlas(fileB.key, fileB.data, fileA.data); + } + break; + case 'bitmapfont': fileA = file.fileA; diff --git a/v3/src/loader/filetypes/UnityAtlasFile.js b/v3/src/loader/filetypes/UnityAtlasFile.js new file mode 100644 index 000000000..856d0c9b8 --- /dev/null +++ b/v3/src/loader/filetypes/UnityAtlasFile.js @@ -0,0 +1,20 @@ +var ImageFile = require('./ImageFile.js'); +var TextFile = require('./TextFile.js'); + +var UnityAtlasFile = function (key, textureURL, atlasURL, path, textureXhrSettings, atlasXhrSettings) +{ + var image = new ImageFile(key, textureURL, path, textureXhrSettings); + var data = new TextFile(key, atlasURL, path, atlasXhrSettings); + + // Link them together + image.linkFile = data; + data.linkFile = image; + + // Set the type + image.linkType = 'unityatlas'; + data.linkType = 'unityatlas'; + + return { texture: image, data: data }; +}; + +module.exports = UnityAtlasFile; diff --git a/v3/src/plugins/Loader.js b/v3/src/plugins/Loader.js index 76fa1819a..6d7f1a2e0 100644 --- a/v3/src/plugins/Loader.js +++ b/v3/src/plugins/Loader.js @@ -14,6 +14,7 @@ var ScriptFile = require('../loader/filetypes/ScriptFile'); var SpriteSheet = require('../loader/filetypes/SpriteSheet'); var SVGFile = require('../loader/filetypes/SVGFile'); var TextFile = require('../loader/filetypes/TextFile'); +var UnityAtlasFile = require('../loader/filetypes/UnityAtlasFile'); var XMLFile = require('../loader/filetypes/XMLFile'); var Loader = new Class({ @@ -91,6 +92,17 @@ var Loader = new Class({ // Multi-File Loaders // --------------------------------------------------- + unityAtlas: function (key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) + { + // Returns an object with two properties: 'texture' and 'data' + var files = new UnityAtlasFile(key, textureURL, atlasURL, this.path, textureXhrSettings, atlasXhrSettings); + + this.addFile(files.texture); + this.addFile(files.data); + + return this; + }, + atlas: function (key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) { // Returns an object with two properties: 'texture' and 'data' diff --git a/v3/src/textures/TextureManager.js b/v3/src/textures/TextureManager.js index d8bb6471d..81f65a87d 100644 --- a/v3/src/textures/TextureManager.js +++ b/v3/src/textures/TextureManager.js @@ -138,6 +138,15 @@ var TextureManager = new Class({ return texture; }, + addUnityAtlas: function (key, source, data) + { + var texture = this.create(key, source); + + Parser.UnityYAML(texture, 0, data); + + return texture; + }, + /** * [addSpriteSheet description] * @param {[type]} key [description] diff --git a/v3/src/textures/parsers/UnityYAML.js b/v3/src/textures/parsers/UnityYAML.js new file mode 100644 index 000000000..ad08e2952 --- /dev/null +++ b/v3/src/textures/parsers/UnityYAML.js @@ -0,0 +1,141 @@ +/* +Example data: + +TextureImporter: + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + spriteSheet: + sprites: + - name: asteroids_0 + rect: + serializedVersion: 2 + x: 5 + y: 328 + width: 65 + height: 82 + alignment: 0 + pivot: {x: 0, y: 0} + border: {x: 0, y: 0, z: 0, w: 0} + - name: asteroids_1 + rect: + serializedVersion: 2 + x: 80 + y: 322 + width: 53 + height: 88 + alignment: 0 + pivot: {x: 0, y: 0} + border: {x: 0, y: 0, z: 0, w: 0} + spritePackingTag: Asteroids +*/ + +var imageHeight = 0; + +var addFrame = function (texture, sourceIndex, name, frame) +{ + // The frame values are the exact coordinates to cut the frame out of the atlas from + + var y = imageHeight - frame.y - frame.height; + + var newFrame = texture.add(name, sourceIndex, frame.x, y, frame.width, frame.height); + + // console.log('name', name, 'rect', frame.x, y, frame.width, frame.height); + + // These are the original (non-trimmed) sprite values + /* + if (src.trimmed) + { + newFrame.setTrim( + src.sourceSize.w, + src.sourceSize.h, + src.spriteSourceSize.x, + src.spriteSourceSize.y, + src.spriteSourceSize.w, + src.spriteSourceSize.h + ); + } + */ +}; + +// https://docs.unity3d.com/ScriptReference/SpriteMetaData.html + +var UnityYAML = function (texture, sourceIndex, yaml) +{ + // Add in a __BASE entry (for the entire atlas) + var source = texture.source[sourceIndex]; + + texture.add('__BASE', sourceIndex, 0, 0, source.width, source.height); + + imageHeight = source.height; + + var data = yaml.split('\n'); + + var lineRegExp = /^[ ]*(- )*(\w+)+[: ]+(.*)/; + + var prevSprite = ''; + var currentSprite = ''; + var rect = { x: 0, y: 0, width: 0, height: 0 }; + var pivot = { x: 0, y: 0 }; + var border = { x: 0, y: 0, z: 0, w: 0 }; + + for (var i = 0; i < data.length; i++) + { + var results = data[i].match(lineRegExp); + + if (!results) + { + continue; + } + + var isList = (results[1] === '- '); + var key = results[2]; + var value = results[3]; + + if (isList) + { + if (currentSprite !== prevSprite) + { + addFrame(texture, sourceIndex, currentSprite, rect); + + prevSprite = currentSprite; + } + + rect = { x: 0, y: 0, width: 0, height: 0 }; + } + + if (key === 'name') + { + // Start new list + currentSprite = value; + continue; + } + + switch (key) + { + case 'x': + case 'y': + case 'width': + case 'height': + rect[key] = parseInt(value, 10); + break; + + case 'pivot': + pivot = eval('var obj = ' + value); + break; + + case 'border': + border = eval('var obj = ' + value); + break; + } + } + + if (currentSprite !== prevSprite) + { + addFrame(texture, sourceIndex, currentSprite, rect); + } + + return texture; +}; + +module.exports = UnityYAML; diff --git a/v3/src/textures/parsers/index.js b/v3/src/textures/parsers/index.js index e809195f2..607c1443b 100644 --- a/v3/src/textures/parsers/index.js +++ b/v3/src/textures/parsers/index.js @@ -7,5 +7,6 @@ module.exports = { Pyxel: require('./Pyxel'), SpriteSheet: require('./SpriteSheet'), SpriteSheetFromAtlas: require('./SpriteSheetFromAtlas'), - StarlingXML: require('./StarlingXML') + StarlingXML: require('./StarlingXML'), + UnityYAML: require('./UnityYAML') };