From 125484199515524575ef08e89799bace07a931ae Mon Sep 17 00:00:00 2001 From: Mike Thomas Date: Wed, 7 Jul 2010 18:04:52 +0000 Subject: [PATCH] Second pass on AS recoloring, fixed a bunch of bugs and tied to tiles/tilesets. git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@936 ed5b42cb-e716-0410-a449-f6a68f950b19 --- .../com/threerings/media/image/ClassRecord.as | 7 +++-- .../threerings/media/image/ColorPository.as | 18 ++++++++++- .../com/threerings/media/image/ColorRecord.as | 7 +++-- .../threerings/media/image/Colorization.as | 12 ++++---- .../threerings/media/image/PngRecolorUtil.as | 30 +++++++++++-------- .../threerings/media/tile/ObjectTileSet.as | 9 ++++-- .../threerings/media/tile/SwissArmyTileSet.as | 22 ++++++++++---- .../com/threerings/media/tile/TileDataPack.as | 19 +++++------- .../threerings/miso/client/MisoScenePanel.as | 13 +++++++- .../threerings/miso/client/TileIsoSprite.as | 2 +- 10 files changed, 89 insertions(+), 50 deletions(-) diff --git a/src/as/com/threerings/media/image/ClassRecord.as b/src/as/com/threerings/media/image/ClassRecord.as index 4147f7a5..af47fdcf 100644 --- a/src/as/com/threerings/media/image/ClassRecord.as +++ b/src/as/com/threerings/media/image/ClassRecord.as @@ -138,13 +138,14 @@ public class ClassRecord public static function fromXml (xml :XML) :ClassRecord { var rec :ClassRecord = new ClassRecord(); + rec.classId = xml.@classId; for each (var colorXml :XML in xml.color) { - rec.colors.put(colorXml.@colorId, ColorRecord.fromXml(colorXml)); + rec.colors.put(int(colorXml.@colorId), ColorRecord.fromXml(colorXml, rec)); } rec.name = xml.@name; var srcStr :String = xml.@source; - rec.source = parseInt(srcStr.substring(1, srcStr.length - 1), 16); + rec.source = parseInt(srcStr.substr(1, srcStr.length - 1), 16); rec.range = toNumArray(xml.@range); rec.defaultId = xml.@defaultId; @@ -157,7 +158,7 @@ public class ClassRecord return null; } - return str.split(",").map(function(element :*, index :int, arr :Array) :int { + return str.split(",").map(function(element :*, index :int, arr :Array) :Number { return Number(element); }); } diff --git a/src/as/com/threerings/media/image/ColorPository.as b/src/as/com/threerings/media/image/ColorPository.as index 37698cb8..22f4c858 100644 --- a/src/as/com/threerings/media/image/ColorPository.as +++ b/src/as/com/threerings/media/image/ColorPository.as @@ -22,6 +22,7 @@ package com.threerings.media.image { import com.threerings.util.Log; import com.threerings.util.Map; import com.threerings.util.Maps; +import com.threerings.util.StringUtil; public class ColorPository { @@ -120,12 +121,27 @@ public class ColorPository return null; } + /** + * Looks up a colorization by class and color Id. + */ + public function getColorizationByNameAndId (className :String, colorId :int) :Colorization + { + var crec :ClassRecord = getClassRecordByName(className); + if (crec != null) { + var color :ColorRecord = crec.colors.get(colorId); + if (color != null) { + return color.getColorization(); + } + } + return null; + } + /** * Loads up a colorization class by name and logs a warning if it doesn't exist. */ public function getClassRecordByName (className :String) :ClassRecord { - for each (var crec :ClassRecord in _classes) { + for each (var crec :ClassRecord in _classes.values()) { if (crec.name == className) { return crec; } diff --git a/src/as/com/threerings/media/image/ColorRecord.as b/src/as/com/threerings/media/image/ColorRecord.as index 61166886..f6af4268 100644 --- a/src/as/com/threerings/media/image/ColorRecord.as +++ b/src/as/com/threerings/media/image/ColorRecord.as @@ -72,13 +72,14 @@ public class ColorRecord } - public static function fromXml (xml :XML) :ColorRecord + public static function fromXml (xml :XML, cclass :ClassRecord) :ColorRecord { var rec :ColorRecord = new ColorRecord(); rec.colorId = xml.@colorId; rec.name = xml.@name; rec.offsets = toNumArray(xml.@offsets); rec.starter = xml.@starter; + rec.cclass = cclass; return rec; } @@ -89,8 +90,8 @@ public class ColorRecord return null; } - return str.split(",").map(function(element :*, index :int, arr :Array) :int { - return Number(element); + return str.split(",").map(function(element :String, index :int, arr :Array) :Number { + return Number(StringUtil.trim(element)); }); } diff --git a/src/as/com/threerings/media/image/Colorization.as b/src/as/com/threerings/media/image/Colorization.as index e604bc42..716bb8c8 100644 --- a/src/as/com/threerings/media/image/Colorization.as +++ b/src/as/com/threerings/media/image/Colorization.as @@ -55,7 +55,7 @@ public class Colorization // compute our HSV and fixed HSV _hsv = ColorUtil.RGBtoHSB(ColorUtil.getRed(rootColor), ColorUtil.getGreen(rootColor), ColorUtil.getBlue(rootColor)); - _fhsv = toFixedHSV(_hsv, null); + _fhsv = toFixedHSV(_hsv); } /** @@ -154,14 +154,12 @@ public class Colorization * @return the fhsv parameter if it was non-null or the * newly created target array. */ - public static function toFixedHSV (hsv :Array, fhsv :Array) :Array + public static function toFixedHSV (hsv :Array) :Array { - if (fhsv == null) { - fhsv = new Array(hsv.length); - } + var fhsv :Array = new Array(hsv.length); + for (var ii :int = 0; ii < hsv.length; ii++) { - // fhsv[i] = (int)(hsv[i]*Integer.MAX_VALUE); - fhsv[ii] = (int)(hsv[ii]*Short.MAX_VALUE); + fhsv[ii] = int(hsv[ii] * Short.MAX_VALUE); } return fhsv; } diff --git a/src/as/com/threerings/media/image/PngRecolorUtil.as b/src/as/com/threerings/media/image/PngRecolorUtil.as index e7d97719..01c04e1d 100644 --- a/src/as/com/threerings/media/image/PngRecolorUtil.as +++ b/src/as/com/threerings/media/image/PngRecolorUtil.as @@ -78,23 +78,23 @@ public class PngRecolorUtil } public static function recolorPNG (pngBytes :ByteArray, - colors :Array/* of Colorization */) :void + colors :Array/* of Colorization */) :ByteArray { - if (colors.length == 0) { - return; + if (colors == null || colors.length == 0) { + return pngBytes; } // first, lets make sure we really have a PNG if (!isPng(pngBytes)) { log.warning("recolorPNG received invalid pngBytes", new Error()); - return; + return pngBytes; } var chunks :Array = findChunks(pngBytes, [HEADER_CHUNK, PALETTE_CHUNK]); if (chunks.length != 2 || (chunks[0] as PngChunk).type != HEADER_CHUNK) { log.warning("recolorPNG received an unexected PNG format", "requiredChunksFound", chunks.length, new Error()); - return; + return pngBytes; } var header :PngChunk = chunks[0] as PngChunk; var palette :PngChunk = chunks[1] as PngChunk; @@ -103,7 +103,7 @@ public class PngRecolorUtil if (colorType != INDEXED_COLOR_TYPE) { log.warning( "Color Type in PNG header is not indexed-color", "type", colorType, new Error()); - return; + return pngBytes; } initializeCRCTable(); @@ -118,12 +118,16 @@ public class PngRecolorUtil var green :uint = pngBytes.readUnsignedByte(); var blue :uint = pngBytes.readUnsignedByte(); - var hsb :Array = ColorUtil.RGBtoHSB(red, green, blue); + var hsv :Array = ColorUtil.RGBtoHSB(red, green, blue); + var fhsv :Array = Colorization.toFixedHSV(hsv); for each (var color :Colorization in colors) { - var newRgb :uint = color.recolorColor(hsb); - pngBytes[ii] = ColorUtil.getRed(newRgb); - pngBytes[ii + 1] = ColorUtil.getGreen(newRgb); - pngBytes[ii + 2] = ColorUtil.getBlue(newRgb); + if (color != null && color.matches(hsv, fhsv)) { + var newRgb :uint = color.recolorColor(hsv); + pngBytes[ii] = red = ColorUtil.getRed(newRgb); + pngBytes[ii + 1] = green = ColorUtil.getGreen(newRgb); + pngBytes[ii + 2] = blue = ColorUtil.getBlue(newRgb); + break; + } } crc = F.foldl([red, green, blue], crc, crcCalc); @@ -132,6 +136,8 @@ public class PngRecolorUtil // write out the CRC for the modified color table pngBytes.position = palette.idx + palette.length; pngBytes.writeUnsignedInt(crc); + + return pngBytes; } protected static function initializeCRCTable () :void @@ -172,8 +178,6 @@ public class PngRecolorUtil protected static const COLOR_TYPE_IDX :int = 9; protected static const INDEXED_COLOR_TYPE :int = 3; - protected static const JAVA_SHORT_MAX :int = 0x7FFF; - protected static var _crcTable :Array; } } diff --git a/src/as/com/threerings/media/tile/ObjectTileSet.as b/src/as/com/threerings/media/tile/ObjectTileSet.as index ea421e51..8c98aed2 100644 --- a/src/as/com/threerings/media/tile/ObjectTileSet.as +++ b/src/as/com/threerings/media/tile/ObjectTileSet.as @@ -264,9 +264,12 @@ public class ObjectTileSet extends SwissArmyTileSet _yspots = toIntArray(xml.ySpots); _sorients = toIntArray(xml.sorients); var constraintStrArr :Array = toStrArray(xml.constraints); - _constraints = constraintStrArr.map(function(element :*, index :int, arr :Array) :Array { - return element.split("|"); - }); + if (constraintStrArr != null) { + _constraints = + constraintStrArr.map(function(element :*, index :int, arr :Array) :Array { + return element.split("|"); + }); + } } /** The width (in tile units) of our object tiles. */ diff --git a/src/as/com/threerings/media/tile/SwissArmyTileSet.as b/src/as/com/threerings/media/tile/SwissArmyTileSet.as index 9dd9f65b..df5b88bc 100644 --- a/src/as/com/threerings/media/tile/SwissArmyTileSet.as +++ b/src/as/com/threerings/media/tile/SwissArmyTileSet.as @@ -177,24 +177,34 @@ public class SwissArmyTileSet extends TileSet _widths = toIntArray(xml.widths); _heights = toIntArray(xml.heights); var offsetPosArr :Array = toIntArray(xml.offsetPos); - _offsetPos = new Point(offsetPosArr[0], offsetPosArr[1]); + if (offsetPosArr != null) { + _offsetPos = new Point(offsetPosArr[0], offsetPosArr[1]); + } else { + _offsetPos = new Point(0, 0); + } var gapSizeArr :Array = toIntArray(xml.gapSize); - _gapSize = new Point(gapSizeArr[0], gapSizeArr[1]); + if (gapSizeArr != null) { + _gapSize = new Point(gapSizeArr[0], gapSizeArr[1]); + } else { + _gapSize = new Point(0, 0); + } computeTileCount(); } protected static function toStrArray (str :String) :Array { - if (str == null) { + if (str == null || str.length == 0) { return null; } - return str.split(","); + return str.split(",").map(function(element :String, index :int, arr :Array) :String { + return StringUtil.trim(element); + }); } protected static function toBoolArray (str :String) :Array { - if (str == null) { + if (str == null || str.length == 0) { return null; } @@ -205,7 +215,7 @@ public class SwissArmyTileSet extends TileSet protected static function toIntArray (str :String) :Array { - if (str == null) { + if (str == null || str.length == 0) { return null; } diff --git a/src/as/com/threerings/media/tile/TileDataPack.as b/src/as/com/threerings/media/tile/TileDataPack.as index 1ed6ef66..14eab6df 100644 --- a/src/as/com/threerings/media/tile/TileDataPack.as +++ b/src/as/com/threerings/media/tile/TileDataPack.as @@ -34,6 +34,7 @@ import nochump.util.zip.ZipEntry; import nochump.util.zip.ZipError; import nochump.util.zip.ZipFile; +import com.threerings.media.image.PngRecolorUtil; import com.threerings.util.DataPack; import com.threerings.util.MultiLoader; @@ -85,23 +86,17 @@ public class TileDataPack extends DataPack public function getTileSetImage (path :String, zations :Array, callback :Function) :void { - // TODO - DO SOMETHING WITH ZATIONS - getDisplayObjects(path, callback); + MultiLoader.getContents(PngRecolorUtil.recolorPNG(getFile(path), zations), callback); } public function getTileImage (path :String, bounds :Rectangle, zations :Array, callback :Function) :void { - getTileSetImage(path, zations, function(result :DisplayObject) :void { - // TODO - DO SOMETHING TO SUB_REGION THIS - if (result is Bitmap) { - var data :BitmapData = - new BitmapData(bounds.width, bounds.height, true, 0x00000000); - data.copyPixels(Bitmap(result).bitmapData, bounds, new Point(0, 0)); - callback(new Bitmap(data)); - } else { - callback(result); - } + getTileSetImage(path, zations, function(result :Bitmap) :void { + var data :BitmapData = + new BitmapData(bounds.width, bounds.height, true, 0x00000000); + data.copyPixels(Bitmap(result).bitmapData, bounds, new Point(0, 0)); + callback(new Bitmap(data)); }); } } diff --git a/src/as/com/threerings/miso/client/MisoScenePanel.as b/src/as/com/threerings/miso/client/MisoScenePanel.as index 835c7f87..db6ba766 100644 --- a/src/as/com/threerings/miso/client/MisoScenePanel.as +++ b/src/as/com/threerings/miso/client/MisoScenePanel.as @@ -32,6 +32,7 @@ import flash.events.MouseEvent; import com.threerings.crowd.client.PlaceView; import com.threerings.crowd.data.PlaceObject; +import com.threerings.media.tile.Colorizer; import com.threerings.media.tile.NoSuchTileSetError; import com.threerings.media.tile.TileSet; import com.threerings.media.tile.TileUtil; @@ -166,7 +167,8 @@ public class MisoScenePanel extends Sprite scene.addChild( new ObjectTileIsoSprite(objInfo.x, objInfo.y, objTileId, - objTileSet.getTile(TileUtil.getTileIndex(objTileId)), _metrics)); + objTileSet.getTile(TileUtil.getTileIndex(objTileId), getColorizer(objInfo)), + _metrics)); } time = getTimer(); @@ -175,6 +177,15 @@ public class MisoScenePanel extends Sprite _isoView.addScene(scene); } + /** + * Derived classes can override this method and provide a colorizer that will be used to + * colorize the supplied scene object when rendering. + */ + protected function getColorizer (oinfo :ObjectInfo) :Colorizer + { + return null; + } + protected var _model :MisoSceneModel; protected var _isoView :IsoView; diff --git a/src/as/com/threerings/miso/client/TileIsoSprite.as b/src/as/com/threerings/miso/client/TileIsoSprite.as index 62875e5b..e4df3bd1 100644 --- a/src/as/com/threerings/miso/client/TileIsoSprite.as +++ b/src/as/com/threerings/miso/client/TileIsoSprite.as @@ -86,7 +86,7 @@ public class TileIsoSprite extends IsoDisplayObject image.x = -tile.getOriginX() + _metrics.tilewid * ((tile.getBaseWidth() - tile.getBaseHeight())/2);; image.y = -tile.getOriginY() + _metrics.tilehei * - (1 + (tile.getBaseWidth() + tile.getBaseHeight())/2); + ((tile.getBaseWidth() + tile.getBaseHeight())/2); sprite.sprites = [image]; sprite.setSize(tile.getBaseWidth(), tile.getBaseHeight(), 1); addChild(sprite);