/** * Copyright (c) 2008 Donovan Adams, http://blog.hydrotik.com - donovan (at) hydrotik (dot) com * Copyright (c) 2007 Moses Gunesch, http://www.goasap.org * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.hydrotik.go { import org.goasap.utils.SequenceCA; import org.goasap.utils.SequenceStepCA; import org.goasap.utils.customadvance.SequenceAdvance; import org.goasap.utils.customadvance.OnPlayableComplete; import org.goasap.managers.LinearGoRepeater; import org.goasap.managers.OverlapMonitor; import org.goasap.GoEngine; import org.goasap.events.GoEvent; import org.goasap.utils.PlayableGroup; import org.goasap.interfaces.IPlayable; import flash.utils.Dictionary; import org.goasap.interfaces.IManageable; import org.goasap.items.LinearGo; import flash.display.DisplayObject; import flash.filters.BevelFilter; import flash.filters.BitmapFilter; import flash.filters.BlurFilter; import flash.filters.ColorMatrixFilter; import flash.filters.DropShadowFilter; import flash.filters.GlowFilter; public class HydroTween extends LinearGo implements IManageable { /* * HydroTween * * @author: Donovan Adams, E-Mail: donovan[(at)]hydrotik.com, url: http://blog.hydrotik.com/ * @author: Based on Moses Gunesch Go engine, http://www.goasap.org/ - Thanks Mo! * @version: 0.4.4 * * @description HydroTween is a generic tweening syntax parser for the Go tweening engine. * * * @example * * HydroTween.go(target, {width:760}, .8, 0, Exponential.easeInOut, onCompleteHandler); * * * * BENCHMARK PROGRESSION Benchmarks: ******** Go 0.3.0 Benchmark results: Go - HydroBenchmark (MacBook Pro Test Dual 2.16) Dec 20, 2007 8:39 PM ------------------ 100 Sprites :: Start Lag: 0.01 seconds :: FPS: 50 200 Sprites :: Start Lag: 0.01 seconds :: FPS: 50 400 Sprites :: Start Lag: 0.02 seconds :: FPS: 50 800 Sprites :: Start Lag: 0.03 seconds :: FPS: 50 1600 Sprites :: Start Lag: 0.08 seconds :: FPS: 35 3200 Sprites :: Start Lag: 0.11 seconds :: FPS: 25 6400 Sprites :: Start Lag: 0.26 seconds :: FPS: 8 Benchmark results: Go - HydroBenchmark (PowerPC Quad 2.5) Dec 21, 2007 10:08 AM ------------------ 100 Sprites :: Start Lag: 0.02 seconds :: FPS: 50 200 Sprites :: Start Lag: 0.02 seconds :: FPS: 50 400 Sprites :: Start Lag: 0.04 seconds :: FPS: 48 800 Sprites :: Start Lag: 0.04 seconds :: FPS: 44 1600 Sprites :: Start Lag: 0.16 seconds :: FPS: 27 3200 Sprites :: Start Lag: 0.15 seconds :: FPS: 10 ******** Go 0.4.0 Benchmark: Go - HydroBenchmark Benchmark results: Go - HydroBenchmark (PowerPC Quad 2.5) Jan 9, 2008 4:08 AM ------------------ 100 Sprites :: Start Lag: 0.01 seconds :: FPS: 96 :: End lag: 0.01 200 Sprites :: Start Lag: 0.04 seconds :: FPS: 93 :: End lag: 0.03 400 Sprites :: Start Lag: 0.06 seconds :: FPS: 91 :: End lag: 0.12 800 Sprites :: Start Lag: 0.06 seconds :: FPS: 81 :: End lag: 0.41 1600 Sprites :: Start Lag: 0.16 seconds :: FPS: 59 :: End lag: 1.74 3200 Sprites :: Start Lag: 0.18 seconds :: FPS: 25 :: End lag: 7.7 6400 Sprites :: Start Lag: 0.4 seconds :: FPS: 2 :: End lag: 15.08 ********* Go 0.4.3 Benchmark results: HydroTween - (PowerPC Quad 2.5) Feb 26, 2008 11:49 AM ------------------ 100 Sprites :: Start Lag: 0.03 seconds :: FPS: 96 :: End lag: 0.01 200 Sprites :: Start Lag: 0.03 seconds :: FPS: 95 :: End lag: 0.03 400 Sprites :: Start Lag: 0.06 seconds :: FPS: 90 :: End lag: 0.11 800 Sprites :: Start Lag: 0.05 seconds :: FPS: 72 :: End lag: 0.45 1600 Sprites :: Start Lag: 0.1 seconds :: FPS: 42 :: End lag: 1.89 3200 Sprites :: Start Lag: 0.22 seconds :: FPS: 18 :: End lag: 8.58 Test flatlined! (0-FPS seconds:15) 6400 Sprites :: Start Lag: 0.48 seconds :: FPS: 1 :: End lag: 15.08 ********* Go 0.4.4 Benchmark results: HydroTween - (PowerPC Quad 2.5) Feb 28, 2008 12:49 PM - PRE OPT ------------------ 100 Sprites :: Start Lag: 0.02 seconds :: FPS: 96 :: End lag: 0.01 200 Sprites :: Start Lag: 0.02 seconds :: FPS: 93 :: End lag: 0.03 400 Sprites :: Start Lag: 0.05 seconds :: FPS: 90 :: End lag: 0.1 800 Sprites :: Start Lag: 0.06 seconds :: FPS: 71 :: End lag: 0.38 1600 Sprites :: Start Lag: 0.12 seconds :: FPS: 43 :: End lag: 1.76 3200 Sprites :: Start Lag: 0.25 seconds :: FPS: 18 :: End lag: 7.95 Test flatlined! (0-FPS seconds:15) 6400 Sprites :: Start Lag: 0.54 seconds :: FPS: 1 :: End lag: 15.07 Benchmark results: HydroTween - (PowerPC Quad 2.5) Feb 28, 2008 2:34 AM - SWITCH DETECTION OF PROPS ------------------ 100 Sprites :: Start Lag: 0.03 seconds :: FPS: 96 :: End lag: 0.01 200 Sprites :: Start Lag: 0.04 seconds :: FPS: 95 :: End lag: 0.03 400 Sprites :: Start Lag: 0.03 seconds :: FPS: 95 :: End lag: 0.11 800 Sprites :: Start Lag: 0.07 seconds :: FPS: 79 :: End lag: 0.43 1600 Sprites :: Start Lag: 0.12 seconds :: FPS: 52 :: End lag: 1.94 3200 Sprites :: Start Lag: 0.19 seconds :: FPS: 22 :: End lag: 8.89 Test flatlined! (0-FPS seconds:15) 6400 Sprites :: Start Lag: 0.43 seconds :: FPS: 2 :: End lag: 15.07 Benchmark results: HydroTween - (PowerPC Quad 2.5) Mar 6, 2008 3:57 PM - Externalized Props/START/READ VALUES BROKEN ------------------ 100 Sprites :: Start Lag: 0.01 seconds :: FPS: 95 :: End lag: 0 200 Sprites :: Start Lag: 0.02 seconds :: FPS: 93 :: End lag: 0.01 400 Sprites :: Start Lag: 0.05 seconds :: FPS: 86 :: End lag: 0.01 800 Sprites :: Start Lag: 0.05 seconds :: FPS: 73 :: End lag: 0.02 1600 Sprites :: Start Lag: 0.12 seconds :: FPS: 45 :: End lag: 0.04 3200 Sprites :: Start Lag: 0.23 seconds :: FPS: 19 :: End lag: 0.07 6400 Sprites :: Start Lag: 0.42 seconds :: FPS: 5 :: End lag: 0.15 12800 Sprites :: Start Lag: 0.86 seconds :: FPS: 2 :: End lag: 0.29 Benchmark results: Go - HydroBenchmark - NEW VERSION - MacPro 2 x 3.0GHz dual Core May 6, 2008 12:54 ------------------ 100 Sprites :: Start Lag: 0.01 seconds :: FPS: 97 :: End lag: 0.02 200 Sprites :: Start Lag: 0.01 seconds :: FPS: 97 :: End lag: 0.01 400 Sprites :: Start Lag: 0.02 seconds :: FPS: 97 :: End lag: 0.04 800 Sprites :: Start Lag: 0.04 seconds :: FPS: 95 :: End lag: 0.16 1600 Sprites :: Start Lag: 0.08 seconds :: FPS: 84 :: End lag: 0.62 3200 Sprites :: Start Lag: 0.14 seconds :: FPS: 61 :: End lag: 2.46 ***********************************************************************************************/ public static const VERSION:String = "HydroTween 0.4.8 rev30 / Go 0.4.8jg1"; public static const INFO:String = VERSION + " (c) Donovan Adams/Moses Gunesch, MIT Licensed."; public static var VERBOSE : Boolean = true; public static var AUTOSTART : Boolean = true; private static var _init : Boolean = false; // DEFAULTS protected var _target : Object; protected var _closure : Function; protected var _update : Function; protected var _tweenStartProps : Dictionary = new Dictionary(true); protected var _htweens : Dictionary = new Dictionary(true); protected static var _propertyList:Dictionary = new Dictionary(true); protected var _tweenList:Dictionary = new Dictionary(true); private static var _r_lum:Number = 0.212671; private static var _g_lum:Number = 0.715160; private static var _b_lum:Number = 0.072169; private static const DELTA_INDEX:Array = [ 0, 0.01, 0.02, 0.04, 0.05, 0.06, 0.07, 0.08, 0.1, 0.11, 0.12, 0.14, 0.15, 0.16, 0.17, 0.18, 0.20, 0.21, 0.22, 0.24, 0.25, 0.27, 0.28, 0.30, 0.32, 0.34, 0.36, 0.38, 0.40, 0.42, 0.44, 0.46, 0.48, 0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68, 0.71, 0.74, 0.77, 0.80, 0.83, 0.86, 0.89, 0.92, 0.95, 0.98, 1.0, 1.06, 1.12, 1.18, 1.24, 1.30, 1.36, 1.42, 1.48, 1.54, 1.60, 1.66, 1.72, 1.78, 1.84, 1.90, 1.96, 2.0, 2.12, 2.25, 2.37, 2.50, 2.62, 2.75, 2.87, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.3, 4.7, 4.9, 5.0, 5.5, 6.0, 6.5, 6.8, 7.0, 7.3, 7.5, 7.8, 8.0, 8.4, 8.7, 9.0, 9.4, 9.6, 9.8, 10.0 ]; private static const IDENTITY:Array = [ 1,0,0,0,0, 0,1,0,0,0, 0,0,1,0,0, 0,0,0,1,0, 0,0,0,0,1]; protected var _matrix : Array = []; protected var _changeMatrix : Array = []; protected var _startMatrix : Array = []; public static function go(target : Object = null, propsTo : Object = null, duration : Number = NaN, delay : Number = NaN, easing : Function = null, closure : Function = null, update : Function = null, extraEasingParams : Array = null, repeater : Object=null, useRelative : Boolean = false, useRounding : Boolean = false, pulseInterval : Number = NaN ) : IPlayable { if(!_init) { if(!GoEngine.getManager("OverlapMonitor")) GoEngine.addManager(new OverlapMonitor()); _propertyList["x"] = {prop:"x", read:genericRead, write:genericWrite}; _propertyList["y"] = {prop:"y", read:genericRead, write:genericWrite}; _propertyList["scaleX"] = {prop:"scaleX", read:genericRead, write:genericWrite}; _propertyList["scaleY"] = {prop:"scaleY", read:genericRead, write:genericWrite}; _propertyList["width"] = {prop:"width", read:genericRead, write:genericWrite}; _propertyList["height"] = {prop:"height", read:genericRead, write:genericWrite}; _propertyList["rotation"] = {prop:"rotation", read:genericRead, write:genericWrite}; _propertyList["alpha"] = {prop:"alpha", read:genericRead, write:genericWrite}; // BevelFilter ---------------------------------------------------------------------------- _propertyList["Bevel_angle"] = {prop:"angle", definition: BevelFilter, read:filterRead, write:filterWrite}; _propertyList["Bevel_blurX"] = {prop:"blurX", definition: BevelFilter, read:filterRead, write:filterWrite}; _propertyList["Bevel_blurY"] = {prop:"blurY", definition: BevelFilter, read:filterRead, write:filterWrite}; _propertyList["Bevel_color"] = {prop:"color", definition: BevelFilter, read:filterRead, write:filterWrite}; _propertyList["Bevel_distance"] = {prop:"distance", definition: BevelFilter, read:filterRead, write:filterWrite}; _propertyList["Bevel_highlightAlpha"] = {prop:"highlightAlpha", definition: BevelFilter, read:filterRead, write:filterWrite}; _propertyList["Bevel_highlightColor"] = {prop:"highlightColor", definition: BevelFilter, read:filterRead, write:filterWrite}; _propertyList["Bevel_quality"] = {prop:"quality", definition: BevelFilter, read:filterRead, write:filterWrite}; _propertyList["Bevel_shadowAlpha"] = {prop:"shadowAlpha", definition: BevelFilter, read:filterRead, write:filterWrite}; _propertyList["Bevel_shadowColor"] = {prop:"shadowColor", definition: BevelFilter, read:filterRead, write:filterWrite}; _propertyList["Bevel_strength"] = {prop:"strength", definition: BevelFilter, read:filterRead, write:filterWrite}; // BlurFilter ---------------------------------------------------------------------------- _propertyList["Blur_blurX"] = {prop:"blurX", definition: BlurFilter, read:filterRead, write:filterWrite}; _propertyList["Blur_blurY"] = {prop:"blurY", definition: BlurFilter, read:filterRead, write:filterWrite}; _propertyList["Blur_quality"] = {prop:"quality", definition: BlurFilter, read:filterRead, write:filterWrite}; // DropShadowFilter ---------------------------------------------------------------------------- _propertyList["DropShadow_alpha"] = {prop:"alpha", definition: DropShadowFilter, read:filterRead, write:filterWrite}; _propertyList["DropShadow_angle"] = {prop:"angle", definition: DropShadowFilter, read:filterRead, write:filterWrite}; _propertyList["DropShadow_blurX"] = {prop:"blurX", definition: DropShadowFilter, read:filterRead, write:filterWrite}; _propertyList["DropShadow_blurY"] = {prop:"blurY", definition: DropShadowFilter, read:filterRead, write:filterWrite}; _propertyList["DropShadow_color"] = {prop:"color", definition: DropShadowFilter, read:filterRead, write:filterWrite}; _propertyList["DropShadow_distance"] = {prop:"distance", definition: DropShadowFilter, read:filterRead, write:filterWrite}; _propertyList["DropShadow_quality"] = {prop:"quality", definition: DropShadowFilter, read:filterRead, write:filterWrite}; _propertyList["DropShadow_strength"] = {prop:"strength", definition: DropShadowFilter, read:filterRead, write:filterWrite}; // GlowFilter ---------------------------------------------------------------------------- _propertyList["Glow_alpha"] = {prop:"alpha", definition: GlowFilter, read:filterRead, write:filterWrite}; _propertyList["Glow_blurX"] = {prop:"blurX", definition: GlowFilter, read:filterRead, write:filterWrite}; _propertyList["Glow_blurY"] = {prop:"blurY", definition: GlowFilter, read:filterRead, write:filterWrite}; _propertyList["Glow_color"] = {prop:"color", definition: GlowFilter, read:filterRead, write:filterWrite}; _propertyList["Glow_quality"] = {prop:"quality", definition: GlowFilter, read:filterRead, write:filterWrite}; _propertyList["Glow_strength"] = {prop:"strength", definition: GlowFilter, read:filterRead, write:filterWrite}; // Image ---------------------------------------------------------------------------- _propertyList["matrix"] = {prop:"matrix", definition: ColorMatrixFilter, read:filterRead, write:filterWrite, adjust:adjustMatrix}; _propertyList["brightness"] = {prop:"matrix", definition: ColorMatrixFilter, read:filterRead, write:filterWrite, adjust:adjustBrightness}; _propertyList["contrast"] = {prop:"matrix", definition: ColorMatrixFilter, read:filterRead, write:filterWrite, adjust:adjustContrast}; _propertyList["saturation"] = {prop:"matrix", definition: ColorMatrixFilter, read:filterRead, write:filterWrite, adjust:adjustSaturation}; _propertyList["hue"] = {prop:"matrix", definition: ColorMatrixFilter, read:filterRead, write:filterWrite, adjust:adjustHue}; _propertyList["tint"] = {prop:"matrix", definition: ColorMatrixFilter, read:filterRead, write:filterWrite, adjust:adjustColor}; // Hex ---------------------------------------------------------------------------- _propertyList["color"] = {prop:"matrix", definition: ColorMatrixFilter, read:filterRead, write:filterWrite, adjust:adjustHex}; //_propertyList["color"] = {prop:"color", definition: ColorMatrixFilter, read:hexRead, write:hexWrite}; _init = true; } //TODO see if I can attach the curry method for accessing arguments to the read and write functions instead of in the update handler //trace("Curry: "+partial_apply(HydroTween["multiply"])(2)(10)); /* private static function multiply(x:uint, y:uint):uint { return x * y; } private static function partial_apply(f:Function):Function{ return function():Function{ var partial_arguments:Array = arguments.slice(); return function():* { partial_arguments = partial_arguments.concat(arguments); return f.apply(null, partial_arguments); }; }; } */ var go:IPlayable; var group:PlayableGroup; var targArray:Array; var isGroup:Boolean = target is Array; if (isGroup) { group = new PlayableGroup; go = group; targArray = target as Array; } else { targArray = [ target ]; } for each (var targ:DisplayObject in targArray) { var tween: HydroTween = new HydroTween( target, propsTo, duration, delay, easing, closure, update, extraEasingParams, repeater, useRelative, useRounding, pulseInterval ); if (isGroup) group.addChild(tween); else go = tween; } //TODO Auto Play? Was deactivated for sequencing compatibility if(AUTOSTART) go.start(); return go; } public static function sequence(...actions): SequenceCA { if(AUTOSTART) AUTOSTART = false; var seq:SequenceCA = new SequenceCA(); for (var i:int = 0; i -1) return true; } } return false; } // When there's a conflict the manager calls this method so you can stop the tween. public function releaseHandling(...params) : void { //trace(this + " releaseHandling()"); super.stop(); } /* **************************************************************************************** PROPERTY UPDATERS ******************************************************************************************/ //Generic --------------------------------------------------------------------------------- protected static function genericRead(targ:DisplayObject, prop:String):Number { return targ[prop]; } protected static function genericWrite(targ:DisplayObject, prop:String, val:Number):void { targ[prop] = val; } //Filter --------------------------------------------------------------------------------- protected static function filterRead(targ:DisplayObject, key:String):* { var defVals:BitmapFilter; var filters:Array = targ.filters; for (var i:int = 0; i < targ.filters.length; i++) { if (filters[i] is _propertyList[key].definition) { return (targ.filters[i][_propertyList[key].prop]); } } defVals = getFilterDefaults()[_propertyList[key].definition]; return defVals[_propertyList[key].prop]; } protected static function filterWrite(targ:DisplayObject, key:String, val:*): void { var filters:Array = targ.filters; var filter:BitmapFilter; for (var i:int = 0; i < filters.length; i++) { if (filters[i] is _propertyList[key].definition) { filters[i][_propertyList[key].prop] = val; targ.filters = filters; return; } } if (filters == null) filters = new Array(); filter = getFilterDefaults()[_propertyList[key].definition]; filter[_propertyList[key].prop] = val; filters.push(filter); targ.filters = filters; } //Matrix/Color --------------------------------------------------------------------------------- private function scalarWrite(element:*, index:int, arr:Array):Number { return (_startMatrix[index] + _changeMatrix[index] * _position); } private function scalarSubtraction(element:*, index:int, arr:Array):Number { return element - _startMatrix[index]; } // Borrowed and tweaked w/permission from Grant Skinner's // ColorMatrix AS3 Class - thanks Grant! // http://www.gskinner.com/blog/archives/2007/12/colormatrix_upd.html public static function adjustMatrix(array:Array, val:Array):Array { return multiplyMatrix(array, val); } public static function adjustColor(array:Array, rgb:Number, amount:Number = 1):Array { if (rgb == -1) return multiplyMatrix(IDENTITY, array); var r:Number = ((rgb >> 16) & 0xff) / 255; var g:Number = ((rgb >> 8) & 0xff) / 255; var b:Number = (rgb & 0xff) / 255; var inv:Number = 1 - amount; return multiplyMatrix([inv + amount * r * _r_lum, amount * r * _g_lum, amount * r * _b_lum, 0, 0, amount * g * _r_lum, inv + amount * g * _g_lum, amount * g * _b_lum, 0, 0, amount * b * _r_lum, amount * b * _g_lum, inv + amount * b * _b_lum, 0, 0, 0, 0, 0, 1, 0], array); } public static function adjustHex(array:Array, rgb:Number, amount:Number = 1):Array { if (rgb == -1) return multiplyMatrix(IDENTITY, array); var r:Number = ((rgb >> 16) & 0xff) / 255; var g:Number = ((rgb >> 8) & 0xff) / 255; var b:Number = (rgb & 0xff) / 255; var inv:Number = 1 - amount; return multiplyMatrix([inv + amount * r, amount * r, amount * r, 0, 0, amount * g, inv + amount * g, amount * g, 0, 0, amount * b, amount * b, inv + amount * b, 0, 0, 0, 0, 0, 1, 0], array); } public static function adjustBrightness(array:Array, val:Number):Array { val = cleanValue(val,10) * 100; if (val == 0 || isNaN(val)) { return array; } return multiplyMatrix(array, [ 1,0,0,0,val, 0,1,0,0,val, 0,0,1,0,val, 0,0,0,1,0, 0,0,0,0,1 ]); } public static function adjustContrast(array:Array, val:Number):Array { val = cleanValue(val,1) * 100; if (val == 0 || isNaN(val)) { return array; } var x:Number; if (val<0) { x = 127+val/100*127; } else { x = val%1; if (x == 0) { x = DELTA_INDEX[val]; } else { x = DELTA_INDEX[(val<<0)]*(1-x)+DELTA_INDEX[(val<<0)+1]*x; } x = x*127+127; } return multiplyMatrix(array, [ x/127,0,0,0,0.5*(127-x), 0,x/127,0,0,0.5*(127-x), 0,0,x/127,0,0.5*(127-x), 0,0,0,1,0, 0,0,0,0,1 ]); } public static function adjustSaturation(array:Array, val:Number):Array { val = cleanValue(val,10) * 100; if (val == 0 || isNaN(val)) { return array; } var x:Number = 1+((val > 0) ? 3*val/100 : val/100); var _r_lum:Number = 0.3086; var _g_lum:Number = 0.6094; var _b_lum:Number = 0.0820; return multiplyMatrix(array, [ _r_lum*(1-x)+x,_g_lum*(1-x),_b_lum*(1-x),0,0, _r_lum*(1-x),_g_lum*(1-x)+x,_b_lum*(1-x),0,0, _r_lum*(1-x),_g_lum*(1-x),_b_lum*(1-x)+x,0,0, 0,0,0,1,0, 0,0,0,0,1 ]); } public static function adjustHue(array:Array, val:Number):Array { val = cleanValue(val,180)/180*Math.PI; if (val == 0 || isNaN(val)) { return array; } var cosVal:Number = Math.cos(val); var sinVal:Number = Math.sin(val); return multiplyMatrix(array, [ _r_lum+cosVal*(1-_r_lum)+sinVal*(-_r_lum),_g_lum+cosVal*(-_g_lum)+sinVal*(-_g_lum),_b_lum+cosVal*(-_b_lum)+sinVal*(1-_b_lum),0,0, _r_lum+cosVal*(-_r_lum)+sinVal*(0.143),_g_lum+cosVal*(1-_g_lum)+sinVal*(0.140),_b_lum+cosVal*(-_b_lum)+sinVal*(-0.283),0,0, _r_lum+cosVal*(-_r_lum)+sinVal*(-(1-_r_lum)),_g_lum+cosVal*(-_g_lum)+sinVal*(_g_lum),_b_lum+cosVal*(1-_b_lum)+sinVal*(_b_lum),0,0, 0,0,0,1,0, 0,0,0,0,1 ]); } // multiplies one matrix against another: protected static function multiplyMatrix(array:Array, matrix:Array):Array { var col:Array = []; var output:Array = []; for (var i:int=0;i<5;i++) { for (var j:int=0;j<5;j++) { col[j] = array[j+i*5]; } for (j=0;j<5;j++) { var val:Number=0; for (var k:Number=0;k<5;k++) { val += matrix[j+k*5]*col[k]; } output[j+i*5] = val; } } return output; } // make sure values are within the specified range, hue has a limit of 180, others are 100: protected static function cleanValue(val:Number,range:Number):Number { return Math.min(range,Math.max(-range,val)); } // makes sure matrixes are 5x5 (25 long): protected static function fixMatrix(matrix:Array = null):Array { if (matrix == null) { return IDENTITY; } if (matrix is Array) { matrix = matrix.slice(0); } if (matrix.length < IDENTITY.length) { matrix = matrix.slice(0,matrix.length).concat(IDENTITY.slice(matrix.length,IDENTITY.length)); } else if (matrix.length > IDENTITY.length) { matrix = matrix.slice(0,IDENTITY.length); } return matrix; } } } class HydroError extends Error { public function HydroError(message:String) { super(message); } }