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
This commit is contained in:
@@ -138,13 +138,14 @@ public class ClassRecord
|
|||||||
public static function fromXml (xml :XML) :ClassRecord
|
public static function fromXml (xml :XML) :ClassRecord
|
||||||
{
|
{
|
||||||
var rec :ClassRecord = new ClassRecord();
|
var rec :ClassRecord = new ClassRecord();
|
||||||
|
rec.classId = xml.@classId;
|
||||||
for each (var colorXml :XML in xml.color) {
|
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;
|
rec.name = xml.@name;
|
||||||
var srcStr :String = xml.@source;
|
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.range = toNumArray(xml.@range);
|
||||||
rec.defaultId = xml.@defaultId;
|
rec.defaultId = xml.@defaultId;
|
||||||
|
|
||||||
@@ -157,7 +158,7 @@ public class ClassRecord
|
|||||||
return null;
|
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);
|
return Number(element);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ package com.threerings.media.image {
|
|||||||
import com.threerings.util.Log;
|
import com.threerings.util.Log;
|
||||||
import com.threerings.util.Map;
|
import com.threerings.util.Map;
|
||||||
import com.threerings.util.Maps;
|
import com.threerings.util.Maps;
|
||||||
|
import com.threerings.util.StringUtil;
|
||||||
|
|
||||||
public class ColorPository
|
public class ColorPository
|
||||||
{
|
{
|
||||||
@@ -120,12 +121,27 @@ public class ColorPository
|
|||||||
return null;
|
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.
|
* Loads up a colorization class by name and logs a warning if it doesn't exist.
|
||||||
*/
|
*/
|
||||||
public function getClassRecordByName (className :String) :ClassRecord
|
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) {
|
if (crec.name == className) {
|
||||||
return crec;
|
return crec;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
var rec :ColorRecord = new ColorRecord();
|
||||||
rec.colorId = xml.@colorId;
|
rec.colorId = xml.@colorId;
|
||||||
rec.name = xml.@name;
|
rec.name = xml.@name;
|
||||||
rec.offsets = toNumArray(xml.@offsets);
|
rec.offsets = toNumArray(xml.@offsets);
|
||||||
rec.starter = xml.@starter;
|
rec.starter = xml.@starter;
|
||||||
|
rec.cclass = cclass;
|
||||||
|
|
||||||
return rec;
|
return rec;
|
||||||
}
|
}
|
||||||
@@ -89,8 +90,8 @@ public class ColorRecord
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return str.split(",").map(function(element :*, index :int, arr :Array) :int {
|
return str.split(",").map(function(element :String, index :int, arr :Array) :Number {
|
||||||
return Number(element);
|
return Number(StringUtil.trim(element));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ public class Colorization
|
|||||||
// compute our HSV and fixed HSV
|
// compute our HSV and fixed HSV
|
||||||
_hsv = ColorUtil.RGBtoHSB(ColorUtil.getRed(rootColor), ColorUtil.getGreen(rootColor),
|
_hsv = ColorUtil.RGBtoHSB(ColorUtil.getRed(rootColor), ColorUtil.getGreen(rootColor),
|
||||||
ColorUtil.getBlue(rootColor));
|
ColorUtil.getBlue(rootColor));
|
||||||
_fhsv = toFixedHSV(_hsv, null);
|
_fhsv = toFixedHSV(_hsv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -154,14 +154,12 @@ public class Colorization
|
|||||||
* @return the <code>fhsv</code> parameter if it was non-null or the
|
* @return the <code>fhsv</code> parameter if it was non-null or the
|
||||||
* newly created target array.
|
* newly created target array.
|
||||||
*/
|
*/
|
||||||
public static function toFixedHSV (hsv :Array, fhsv :Array) :Array
|
public static function toFixedHSV (hsv :Array) :Array
|
||||||
{
|
{
|
||||||
if (fhsv == null) {
|
var fhsv :Array = new Array(hsv.length);
|
||||||
fhsv = new Array(hsv.length);
|
|
||||||
}
|
|
||||||
for (var ii :int = 0; ii < hsv.length; ii++) {
|
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;
|
return fhsv;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,23 +78,23 @@ public class PngRecolorUtil
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static function recolorPNG (pngBytes :ByteArray,
|
public static function recolorPNG (pngBytes :ByteArray,
|
||||||
colors :Array/* of Colorization */) :void
|
colors :Array/* of Colorization */) :ByteArray
|
||||||
{
|
{
|
||||||
if (colors.length == 0) {
|
if (colors == null || colors.length == 0) {
|
||||||
return;
|
return pngBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// first, lets make sure we really have a PNG
|
// first, lets make sure we really have a PNG
|
||||||
if (!isPng(pngBytes)) {
|
if (!isPng(pngBytes)) {
|
||||||
log.warning("recolorPNG received invalid pngBytes", new Error());
|
log.warning("recolorPNG received invalid pngBytes", new Error());
|
||||||
return;
|
return pngBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
var chunks :Array = findChunks(pngBytes, [HEADER_CHUNK, PALETTE_CHUNK]);
|
var chunks :Array = findChunks(pngBytes, [HEADER_CHUNK, PALETTE_CHUNK]);
|
||||||
if (chunks.length != 2 || (chunks[0] as PngChunk).type != HEADER_CHUNK) {
|
if (chunks.length != 2 || (chunks[0] as PngChunk).type != HEADER_CHUNK) {
|
||||||
log.warning("recolorPNG received an unexected PNG format", "requiredChunksFound",
|
log.warning("recolorPNG received an unexected PNG format", "requiredChunksFound",
|
||||||
chunks.length, new Error());
|
chunks.length, new Error());
|
||||||
return;
|
return pngBytes;
|
||||||
}
|
}
|
||||||
var header :PngChunk = chunks[0] as PngChunk;
|
var header :PngChunk = chunks[0] as PngChunk;
|
||||||
var palette :PngChunk = chunks[1] as PngChunk;
|
var palette :PngChunk = chunks[1] as PngChunk;
|
||||||
@@ -103,7 +103,7 @@ public class PngRecolorUtil
|
|||||||
if (colorType != INDEXED_COLOR_TYPE) {
|
if (colorType != INDEXED_COLOR_TYPE) {
|
||||||
log.warning(
|
log.warning(
|
||||||
"Color Type in PNG header is not indexed-color", "type", colorType, new Error());
|
"Color Type in PNG header is not indexed-color", "type", colorType, new Error());
|
||||||
return;
|
return pngBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeCRCTable();
|
initializeCRCTable();
|
||||||
@@ -118,12 +118,16 @@ public class PngRecolorUtil
|
|||||||
var green :uint = pngBytes.readUnsignedByte();
|
var green :uint = pngBytes.readUnsignedByte();
|
||||||
var blue :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) {
|
for each (var color :Colorization in colors) {
|
||||||
var newRgb :uint = color.recolorColor(hsb);
|
if (color != null && color.matches(hsv, fhsv)) {
|
||||||
pngBytes[ii] = ColorUtil.getRed(newRgb);
|
var newRgb :uint = color.recolorColor(hsv);
|
||||||
pngBytes[ii + 1] = ColorUtil.getGreen(newRgb);
|
pngBytes[ii] = red = ColorUtil.getRed(newRgb);
|
||||||
pngBytes[ii + 2] = ColorUtil.getBlue(newRgb);
|
pngBytes[ii + 1] = green = ColorUtil.getGreen(newRgb);
|
||||||
|
pngBytes[ii + 2] = blue = ColorUtil.getBlue(newRgb);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
crc = F.foldl([red, green, blue], crc, crcCalc);
|
crc = F.foldl([red, green, blue], crc, crcCalc);
|
||||||
@@ -132,6 +136,8 @@ public class PngRecolorUtil
|
|||||||
// write out the CRC for the modified color table
|
// write out the CRC for the modified color table
|
||||||
pngBytes.position = palette.idx + palette.length;
|
pngBytes.position = palette.idx + palette.length;
|
||||||
pngBytes.writeUnsignedInt(crc);
|
pngBytes.writeUnsignedInt(crc);
|
||||||
|
|
||||||
|
return pngBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static function initializeCRCTable () :void
|
protected static function initializeCRCTable () :void
|
||||||
@@ -172,8 +178,6 @@ public class PngRecolorUtil
|
|||||||
protected static const COLOR_TYPE_IDX :int = 9;
|
protected static const COLOR_TYPE_IDX :int = 9;
|
||||||
protected static const INDEXED_COLOR_TYPE :int = 3;
|
protected static const INDEXED_COLOR_TYPE :int = 3;
|
||||||
|
|
||||||
protected static const JAVA_SHORT_MAX :int = 0x7FFF;
|
|
||||||
|
|
||||||
protected static var _crcTable :Array;
|
protected static var _crcTable :Array;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -264,9 +264,12 @@ public class ObjectTileSet extends SwissArmyTileSet
|
|||||||
_yspots = toIntArray(xml.ySpots);
|
_yspots = toIntArray(xml.ySpots);
|
||||||
_sorients = toIntArray(xml.sorients);
|
_sorients = toIntArray(xml.sorients);
|
||||||
var constraintStrArr :Array = toStrArray(xml.constraints);
|
var constraintStrArr :Array = toStrArray(xml.constraints);
|
||||||
_constraints = constraintStrArr.map(function(element :*, index :int, arr :Array) :Array {
|
if (constraintStrArr != null) {
|
||||||
return element.split("|");
|
_constraints =
|
||||||
});
|
constraintStrArr.map(function(element :*, index :int, arr :Array) :Array {
|
||||||
|
return element.split("|");
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The width (in tile units) of our object tiles. */
|
/** The width (in tile units) of our object tiles. */
|
||||||
|
|||||||
@@ -177,24 +177,34 @@ public class SwissArmyTileSet extends TileSet
|
|||||||
_widths = toIntArray(xml.widths);
|
_widths = toIntArray(xml.widths);
|
||||||
_heights = toIntArray(xml.heights);
|
_heights = toIntArray(xml.heights);
|
||||||
var offsetPosArr :Array = toIntArray(xml.offsetPos);
|
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);
|
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();
|
computeTileCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static function toStrArray (str :String) :Array
|
protected static function toStrArray (str :String) :Array
|
||||||
{
|
{
|
||||||
if (str == null) {
|
if (str == null || str.length == 0) {
|
||||||
return null;
|
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
|
protected static function toBoolArray (str :String) :Array
|
||||||
{
|
{
|
||||||
if (str == null) {
|
if (str == null || str.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +215,7 @@ public class SwissArmyTileSet extends TileSet
|
|||||||
|
|
||||||
protected static function toIntArray (str :String) :Array
|
protected static function toIntArray (str :String) :Array
|
||||||
{
|
{
|
||||||
if (str == null) {
|
if (str == null || str.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import nochump.util.zip.ZipEntry;
|
|||||||
import nochump.util.zip.ZipError;
|
import nochump.util.zip.ZipError;
|
||||||
import nochump.util.zip.ZipFile;
|
import nochump.util.zip.ZipFile;
|
||||||
|
|
||||||
|
import com.threerings.media.image.PngRecolorUtil;
|
||||||
import com.threerings.util.DataPack;
|
import com.threerings.util.DataPack;
|
||||||
import com.threerings.util.MultiLoader;
|
import com.threerings.util.MultiLoader;
|
||||||
|
|
||||||
@@ -85,23 +86,17 @@ public class TileDataPack extends DataPack
|
|||||||
|
|
||||||
public function getTileSetImage (path :String, zations :Array, callback :Function) :void
|
public function getTileSetImage (path :String, zations :Array, callback :Function) :void
|
||||||
{
|
{
|
||||||
// TODO - DO SOMETHING WITH ZATIONS
|
MultiLoader.getContents(PngRecolorUtil.recolorPNG(getFile(path), zations), callback);
|
||||||
getDisplayObjects(path, callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTileImage (path :String, bounds :Rectangle, zations :Array,
|
public function getTileImage (path :String, bounds :Rectangle, zations :Array,
|
||||||
callback :Function) :void
|
callback :Function) :void
|
||||||
{
|
{
|
||||||
getTileSetImage(path, zations, function(result :DisplayObject) :void {
|
getTileSetImage(path, zations, function(result :Bitmap) :void {
|
||||||
// TODO - DO SOMETHING TO SUB_REGION THIS
|
var data :BitmapData =
|
||||||
if (result is Bitmap) {
|
new BitmapData(bounds.width, bounds.height, true, 0x00000000);
|
||||||
var data :BitmapData =
|
data.copyPixels(Bitmap(result).bitmapData, bounds, new Point(0, 0));
|
||||||
new BitmapData(bounds.width, bounds.height, true, 0x00000000);
|
callback(new Bitmap(data));
|
||||||
data.copyPixels(Bitmap(result).bitmapData, bounds, new Point(0, 0));
|
|
||||||
callback(new Bitmap(data));
|
|
||||||
} else {
|
|
||||||
callback(result);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import flash.events.MouseEvent;
|
|||||||
|
|
||||||
import com.threerings.crowd.client.PlaceView;
|
import com.threerings.crowd.client.PlaceView;
|
||||||
import com.threerings.crowd.data.PlaceObject;
|
import com.threerings.crowd.data.PlaceObject;
|
||||||
|
import com.threerings.media.tile.Colorizer;
|
||||||
import com.threerings.media.tile.NoSuchTileSetError;
|
import com.threerings.media.tile.NoSuchTileSetError;
|
||||||
import com.threerings.media.tile.TileSet;
|
import com.threerings.media.tile.TileSet;
|
||||||
import com.threerings.media.tile.TileUtil;
|
import com.threerings.media.tile.TileUtil;
|
||||||
@@ -166,7 +167,8 @@ public class MisoScenePanel extends Sprite
|
|||||||
|
|
||||||
scene.addChild(
|
scene.addChild(
|
||||||
new ObjectTileIsoSprite(objInfo.x, objInfo.y, objTileId,
|
new ObjectTileIsoSprite(objInfo.x, objInfo.y, objTileId,
|
||||||
objTileSet.getTile(TileUtil.getTileIndex(objTileId)), _metrics));
|
objTileSet.getTile(TileUtil.getTileIndex(objTileId), getColorizer(objInfo)),
|
||||||
|
_metrics));
|
||||||
}
|
}
|
||||||
|
|
||||||
time = getTimer();
|
time = getTimer();
|
||||||
@@ -175,6 +177,15 @@ public class MisoScenePanel extends Sprite
|
|||||||
_isoView.addScene(scene);
|
_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 _model :MisoSceneModel;
|
||||||
|
|
||||||
protected var _isoView :IsoView;
|
protected var _isoView :IsoView;
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ public class TileIsoSprite extends IsoDisplayObject
|
|||||||
image.x = -tile.getOriginX() + _metrics.tilewid *
|
image.x = -tile.getOriginX() + _metrics.tilewid *
|
||||||
((tile.getBaseWidth() - tile.getBaseHeight())/2);;
|
((tile.getBaseWidth() - tile.getBaseHeight())/2);;
|
||||||
image.y = -tile.getOriginY() + _metrics.tilehei *
|
image.y = -tile.getOriginY() + _metrics.tilehei *
|
||||||
(1 + (tile.getBaseWidth() + tile.getBaseHeight())/2);
|
((tile.getBaseWidth() + tile.getBaseHeight())/2);
|
||||||
sprite.sprites = [image];
|
sprite.sprites = [image];
|
||||||
sprite.setSize(tile.getBaseWidth(), tile.getBaseHeight(), 1);
|
sprite.setSize(tile.getBaseWidth(), tile.getBaseHeight(), 1);
|
||||||
addChild(sprite);
|
addChild(sprite);
|
||||||
|
|||||||
Reference in New Issue
Block a user