package skeletal { import flash.display.*; import flash.geom.*; import frame.FrameInfo; import util.*; public class Piece { protected var size:Point; protected var frameInfo:FrameInfo; protected var compareData:BitmapData; protected var centerPoint:Point; public function get CenterPoint():Point { return centerPoint; } public function get FullData():BitmapData { return frameInfo == null ? null : frameInfo.frameData; } public function get Frame():FrameInfo { return frameInfo; } protected var valid = false; public function get Valid() { return valid; } public var Name:String = null; protected var usesBySequence = {}; public function AddUse(sequence) { if (!(sequence in usesBySequence)) { usesBySequence[sequence] = 0; } usesBySequence[sequence]++; } public function RemoveUse(sequence) { if (sequence in usesBySequence && usesBySequence[sequence] > 0) { usesBySequence[sequence]--; } } public function GetUses(sequence) { return (sequence in usesBySequence) ? usesBySequence[sequence] : 0; } public function get TotalUses() { var count = 0; for (var s in usesBySequence) { count += usesBySequence[s]; } return count; } // returns the center point public function InitFromClip(clip:DisplayObject, upscale:Number = 1):Point { var bounds:Rectangle = Utils.GetAccurateBounds(clip); size = new Point(bounds.width, bounds.height); valid = bounds.width > 0 && bounds.height > 0; if (valid) { var m:Matrix = clip is Shape ? clip.transform.matrix.clone() : new Matrix(); m.scale(upscale, upscale); Utils.TransformRect(bounds, m); Utils.RoundRect(bounds); m.translate(-bounds.left, -bounds.top); var fullData:BitmapData = new BitmapData(bounds.width, bounds.height, true, 0x0); fullData.draw(clip, m, clip is Shape && clip.parent ? clip.parent.transform.colorTransform : clip.transform.colorTransform, null, null, true); frameInfo = new FrameInfo(fullData, m, null); compareData = GenerateCompareData(clip); centerPoint = new Point(-bounds.left, -bounds.top); return centerPoint; } return null; } public function InitFromBitmapData(bd:BitmapData, centerPoint:Point = null) { if (centerPoint == null) centerPoint = new Point(0, 0); valid = true; size = new Point(bd.width, bd.height); frameInfo = new FrameInfo(bd, null, null); compareData = bd.clone(); this.centerPoint = centerPoint; } public function Matches(otherData:BitmapData, otherName) { if (false && otherName != null && Name != null) { //This whole section fails to match things properly... var m = Name.match("^([^0-9]+)(\\d*)"); var tempName = m ? m[1] : Name; var mo = otherName.match("^([^0-9]+)(\\d*)"); var tempOtherName = mo ? mo[1] : otherName; return tempName == tempOtherName; if (m) { if (otherName != m[1]) return false; return true; } else { if (otherName != Name) return false; return true; } } var threshold = 3; var maxPixels = 0; var result = compareData.compare(otherData); if (result == 0) return true; if (result is BitmapData) { var histo:Vector.<Vector.<Number>> = (result as BitmapData).histogram(); for (var i = 0; i < 4; i++) { var diff:Vector.<Number> = histo[i]; // for some STUPID reason, if all the colors match but the alphas dont, it returns FFFFFF for the color portion... // so DON'T compare the histogram for color channels up to 255 var max = i == 4 ? 255 : 254; for (var j = threshold; j < Math.min(max, diff.length); j++) { if (diff[j] > maxPixels) { return false; } } } return true; } return false; } public static function GenerateCompareData(clip:DisplayObject):BitmapData { var scale = 1; var quickBounds:Rectangle = clip.getBounds(clip); var orig:Rectangle = quickBounds.clone(); if (quickBounds.width == 0 || quickBounds.height == 0) return null; Utils.ScaleRect(quickBounds, scale); Utils.RoundRect(quickBounds); var m:Matrix = clip is Shape ? clip.transform.matrix.clone() : new Matrix(); m.scale(scale, scale); m.translate(-quickBounds.left, -quickBounds.top); var data:BitmapData = new BitmapData(quickBounds.width, quickBounds.height, true, 0x0); data.draw(clip, m, clip is Shape && clip.parent ? clip.parent.transform.colorTransform : clip.transform.colorTransform, null, null, true); return data; } } }