Vadorequest

pixi.js

Nov 29th, 2013
530
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.  * @author Mat Groves http://matgroves.com/ @Doormat23
  3.  */
  4.  
  5. (function(){
  6.  
  7.     var root = this;
  8.  
  9. /**
  10.  * @author Mat Groves http://matgroves.com/ @Doormat23
  11.  */
  12.  
  13. /**
  14.  * @module PIXI
  15.  */
  16. var PIXI = PIXI || {};
  17.     window['PIXI'] = PIXI;
  18. /**
  19.  * @author Mat Groves http://matgroves.com/ @Doormat23
  20.  */
  21.  
  22. /**
  23.  * The Point object represents a location in a two-dimensional coordinate system, where x represents the horizontal axis and y represents the vertical axis.
  24.  *
  25.  * @class Point
  26.  * @constructor
  27.  * @param x {Number} position of the point
  28.  * @param y {Number} position of the point
  29.  */
  30. PIXI.Point = function(x, y)
  31. {
  32.     /**
  33.      * @property x
  34.      * @type Number
  35.      * @default 0
  36.      */
  37.     this.x = x || 0;
  38.  
  39.     /**
  40.      * @property y
  41.      * @type Number
  42.      * @default 0
  43.      */
  44.     this.y = y || 0;
  45. }
  46.  
  47. /**
  48.  * Creates a clone of this point
  49.  *
  50.  * @method clone
  51.  * @return {Point} a copy of the point
  52.  */
  53. PIXI.Point.prototype.clone = function()
  54. {
  55.     return new PIXI.Point(this.x, this.y);
  56. }
  57.  
  58. // constructor
  59. PIXI.Point.prototype.constructor = PIXI.Point;
  60.  
  61.  
  62. /**
  63.  * @author Mat Groves http://matgroves.com/
  64.  */
  65.  
  66. /**
  67.  * the Rectangle object is an area defined by its position, as indicated by its top-left corner point (x, y) and by its width and its height.
  68.  *
  69.  * @class Rectangle
  70.  * @constructor
  71.  * @param x {Number} The X coord of the upper-left corner of the rectangle
  72.  * @param y {Number} The Y coord of the upper-left corner of the rectangle
  73.  * @param width {Number} The overall width of this rectangle
  74.  * @param height {Number} The overall height of this rectangle
  75.  */
  76. PIXI.Rectangle = function(x, y, width, height)
  77. {
  78.     /**
  79.      * @property x
  80.      * @type Number
  81.      * @default 0
  82.      */
  83.     this.x = x || 0;
  84.  
  85.     /**
  86.      * @property y
  87.      * @type Number
  88.      * @default 0
  89.      */
  90.     this.y = y || 0;
  91.  
  92.     /**
  93.      * @property width
  94.      * @type Number
  95.      * @default 0
  96.      */
  97.     this.width = width || 0;
  98.  
  99.     /**
  100.      * @property height
  101.      * @type Number
  102.      * @default 0
  103.      */
  104.     this.height = height || 0;
  105. }
  106.  
  107. /**
  108.  * Creates a clone of this Rectangle
  109.  *
  110.  * @method clone
  111.  * @return {Rectangle} a copy of the rectangle
  112.  */
  113. PIXI.Rectangle.prototype.clone = function()
  114. {
  115.     return new PIXI.Rectangle(this.x, this.y, this.width, this.height);
  116. }
  117.  
  118. /**
  119.  * Checks if the x, and y coords passed to this function are contained within this Rectangle
  120.  *
  121.  * @method contains
  122.  * @param x {Number} The X coord of the point to test
  123.  * @param y {Number} The Y coord of the point to test
  124.  * @return {Boolean} if the x/y coords are within this Rectangle
  125.  */
  126. PIXI.Rectangle.prototype.contains = function(x, y)
  127. {
  128.     if(this.width <= 0 || this.height <= 0)
  129.         return false;
  130.  
  131.     var x1 = this.x;
  132.     if(x >= x1 && x <= x1 + this.width)
  133.     {
  134.         var y1 = this.y;
  135.  
  136.         if(y >= y1 && y <= y1 + this.height)
  137.         {
  138.             return true;
  139.         }
  140.     }
  141.  
  142.     return false;
  143. }
  144.  
  145. // constructor
  146. PIXI.Rectangle.prototype.constructor = PIXI.Rectangle;
  147.  
  148.  
  149. /**
  150.  * @author Adrien Brault <adrien.brault@gmail.com>
  151.  */
  152.  
  153. /**
  154.  * @class Polygon
  155.  * @constructor
  156.  * @param points* {Array<Point>|Array<Number>|Point...|Number...} This can be an array of Points that form the polygon,
  157.  *      a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arguments passed can be
  158.  *      all the points of the polygon e.g. `new PIXI.Polygon(new PIXI.Point(), new PIXI.Point(), ...)`, or the
  159.  *      arguments passed can be flat x,y values e.g. `new PIXI.Polygon(x,y, x,y, x,y, ...)` where `x` and `y` are
  160.  *      Numbers.
  161.  */
  162. PIXI.Polygon = function(points)
  163. {
  164.     //if points isn't an array, use arguments as the array
  165.     if(!(points instanceof Array))
  166.         points = Array.prototype.slice.call(arguments);
  167.  
  168.     //if this is a flat array of numbers, convert it to points
  169.     if(typeof points[0] === 'number') {
  170.         var p = [];
  171.         for(var i = 0, il = points.length; i < il; i+=2) {
  172.             p.push(
  173.                 new PIXI.Point(points[i], points[i + 1])
  174.             );
  175.         }
  176.  
  177.         points = p;
  178.     }
  179.  
  180.     this.points = points;
  181. }
  182.  
  183. /**
  184.  * Creates a clone of this polygon
  185.  *
  186.  * @method clone
  187.  * @return {Polygon} a copy of the polygon
  188.  */
  189. PIXI.Polygon.prototype.clone = function()
  190. {
  191.     var points = [];
  192.     for (var i=0; i<this.points.length; i++) {
  193.         points.push(this.points[i].clone());
  194.     }
  195.  
  196.     return new PIXI.Polygon(points);
  197. }
  198.  
  199. /**
  200.  * Checks if the x, and y coords passed to this function are contained within this polygon
  201.  *
  202.  * @method contains
  203.  * @param x {Number} The X coord of the point to test
  204.  * @param y {Number} The Y coord of the point to test
  205.  * @return {Boolean} if the x/y coords are within this polygon
  206.  */
  207. PIXI.Polygon.prototype.contains = function(x, y)
  208. {
  209.     var inside = false;
  210.  
  211.     // use some raycasting to test hits
  212.     // https://github.com/substack/point-in-polygon/blob/master/index.js
  213.     for(var i = 0, j = this.points.length - 1; i < this.points.length; j = i++) {
  214.         var xi = this.points[i].x, yi = this.points[i].y,
  215.             xj = this.points[j].x, yj = this.points[j].y,
  216.             intersect = ((yi > y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
  217.  
  218.         if(intersect) inside = !inside;
  219.     }
  220.  
  221.     return inside;
  222. }
  223.  
  224. // constructor
  225. PIXI.Polygon.prototype.constructor = PIXI.Polygon;
  226.  
  227. /**
  228.  * @author Chad Engler <chad@pantherdev.com>
  229.  */
  230.  
  231. /**
  232.  * The Circle object can be used to specify a hit area for displayobjects
  233.  *
  234.  * @class Circle
  235.  * @constructor
  236.  * @param x {Number} The X coord of the upper-left corner of the framing rectangle of this circle
  237.  * @param y {Number} The Y coord of the upper-left corner of the framing rectangle of this circle
  238.  * @param radius {Number} The radius of the circle
  239.  */
  240. PIXI.Circle = function(x, y, radius)
  241. {
  242.     /**
  243.      * @property x
  244.      * @type Number
  245.      * @default 0
  246.      */
  247.     this.x = x || 0;
  248.  
  249.     /**
  250.      * @property y
  251.      * @type Number
  252.      * @default 0
  253.      */
  254.     this.y = y || 0;
  255.  
  256.     /**
  257.      * @property radius
  258.      * @type Number
  259.      * @default 0
  260.      */
  261.     this.radius = radius || 0;
  262. }
  263.  
  264. /**
  265.  * Creates a clone of this Circle instance
  266.  *
  267.  * @method clone
  268.  * @return {Circle} a copy of the polygon
  269.  */
  270. PIXI.Circle.prototype.clone = function()
  271. {
  272.     return new PIXI.Circle(this.x, this.y, this.radius);
  273. }
  274.  
  275. /**
  276.  * Checks if the x, and y coords passed to this function are contained within this circle
  277.  *
  278.  * @method contains
  279.  * @param x {Number} The X coord of the point to test
  280.  * @param y {Number} The Y coord of the point to test
  281.  * @return {Boolean} if the x/y coords are within this polygon
  282.  */
  283. PIXI.Circle.prototype.contains = function(x, y)
  284. {
  285.     if(this.radius <= 0)
  286.         return false;
  287.  
  288.     var dx = (this.x - x),
  289.         dy = (this.y - y),
  290.         r2 = this.radius * this.radius;
  291.  
  292.     dx *= dx;
  293.     dy *= dy;
  294.  
  295.     return (dx + dy <= r2);
  296. }
  297.  
  298. // constructor
  299. PIXI.Circle.prototype.constructor = PIXI.Circle;
  300.  
  301.  
  302. /**
  303.  * @author Chad Engler <chad@pantherdev.com>
  304.  */
  305.  
  306. /**
  307.  * The Ellipse object can be used to specify a hit area for displayobjects
  308.  *
  309.  * @class Ellipse
  310.  * @constructor
  311.  * @param x {Number} The X coord of the upper-left corner of the framing rectangle of this ellipse
  312.  * @param y {Number} The Y coord of the upper-left corner of the framing rectangle of this ellipse
  313.  * @param width {Number} The overall width of this ellipse
  314.  * @param height {Number} The overall height of this ellipse
  315.  */
  316. PIXI.Ellipse = function(x, y, width, height)
  317. {
  318.     /**
  319.      * @property x
  320.      * @type Number
  321.      * @default 0
  322.      */
  323.     this.x = x || 0;
  324.  
  325.     /**
  326.      * @property y
  327.      * @type Number
  328.      * @default 0
  329.      */
  330.     this.y = y || 0;
  331.  
  332.     /**
  333.      * @property width
  334.      * @type Number
  335.      * @default 0
  336.      */
  337.     this.width = width || 0;
  338.  
  339.     /**
  340.      * @property height
  341.      * @type Number
  342.      * @default 0
  343.      */
  344.     this.height = height || 0;
  345. }
  346.  
  347. /**
  348.  * Creates a clone of this Ellipse instance
  349.  *
  350.  * @method clone
  351.  * @return {Ellipse} a copy of the ellipse
  352.  */
  353. PIXI.Ellipse.prototype.clone = function()
  354. {
  355.     return new PIXI.Ellipse(this.x, this.y, this.width, this.height);
  356. }
  357.  
  358. /**
  359.  * Checks if the x, and y coords passed to this function are contained within this ellipse
  360.  *
  361.  * @method contains
  362.  * @param x {Number} The X coord of the point to test
  363.  * @param y {Number} The Y coord of the point to test
  364.  * @return {Boolean} if the x/y coords are within this ellipse
  365.  */
  366. PIXI.Ellipse.prototype.contains = function(x, y)
  367. {
  368.     if(this.width <= 0 || this.height <= 0)
  369.         return false;
  370.  
  371.     //normalize the coords to an ellipse with center 0,0
  372.     //and a radius of 0.5
  373.     var normx = ((x - this.x) / this.width) - 0.5,
  374.         normy = ((y - this.y) / this.height) - 0.5;
  375.  
  376.     normx *= normx;
  377.     normy *= normy;
  378.  
  379.     return (normx + normy < 0.25);
  380. }
  381.  
  382. PIXI.Ellipse.getBounds = function()
  383. {
  384.     return new PIXI.Rectangle(this.x, this.y, this.width, this.height);
  385. }
  386.  
  387. // constructor
  388. PIXI.Ellipse.prototype.constructor = PIXI.Ellipse;
  389.  
  390.  
  391.  
  392. /*
  393.  * A lighter version of the rad gl-matrix created by Brandon Jones, Colin MacKenzie IV
  394.  * you both rock!
  395.  */
  396.  
  397. function determineMatrixArrayType() {
  398.     PIXI.Matrix = (typeof Float32Array !== 'undefined') ? Float32Array : Array;
  399.     return PIXI.Matrix;
  400. }
  401.  
  402. determineMatrixArrayType();
  403.  
  404. PIXI.mat3 = {};
  405.  
  406. PIXI.mat3.create = function()
  407. {
  408.     var matrix = new PIXI.Matrix(9);
  409.  
  410.     matrix[0] = 1;
  411.     matrix[1] = 0;
  412.     matrix[2] = 0;
  413.     matrix[3] = 0;
  414.     matrix[4] = 1;
  415.     matrix[5] = 0;
  416.     matrix[6] = 0;
  417.     matrix[7] = 0;
  418.     matrix[8] = 1;
  419.  
  420.     return matrix;
  421. }
  422.  
  423.  
  424. PIXI.mat3.identity = function(matrix)
  425. {
  426.     matrix[0] = 1;
  427.     matrix[1] = 0;
  428.     matrix[2] = 0;
  429.     matrix[3] = 0;
  430.     matrix[4] = 1;
  431.     matrix[5] = 0;
  432.     matrix[6] = 0;
  433.     matrix[7] = 0;
  434.     matrix[8] = 1;
  435.  
  436.     return matrix;
  437. }
  438.  
  439.  
  440. PIXI.mat4 = {};
  441.  
  442. PIXI.mat4.create = function()
  443. {
  444.     var matrix = new PIXI.Matrix(16);
  445.  
  446.     matrix[0] = 1;
  447.     matrix[1] = 0;
  448.     matrix[2] = 0;
  449.     matrix[3] = 0;
  450.     matrix[4] = 0;
  451.     matrix[5] = 1;
  452.     matrix[6] = 0;
  453.     matrix[7] = 0;
  454.     matrix[8] = 0;
  455.     matrix[9] = 0;
  456.     matrix[10] = 1;
  457.     matrix[11] = 0;
  458.     matrix[12] = 0;
  459.     matrix[13] = 0;
  460.     matrix[14] = 0;
  461.     matrix[15] = 1;
  462.  
  463.     return matrix;
  464. }
  465.  
  466. PIXI.mat3.multiply = function (mat, mat2, dest)
  467. {
  468.     if (!dest) { dest = mat; }
  469.  
  470.     // Cache the matrix values (makes for huge speed increases!)
  471.     var a00 = mat[0], a01 = mat[1], a02 = mat[2],
  472.         a10 = mat[3], a11 = mat[4], a12 = mat[5],
  473.         a20 = mat[6], a21 = mat[7], a22 = mat[8],
  474.  
  475.         b00 = mat2[0], b01 = mat2[1], b02 = mat2[2],
  476.         b10 = mat2[3], b11 = mat2[4], b12 = mat2[5],
  477.         b20 = mat2[6], b21 = mat2[7], b22 = mat2[8];
  478.  
  479.     dest[0] = b00 * a00 + b01 * a10 + b02 * a20;
  480.     dest[1] = b00 * a01 + b01 * a11 + b02 * a21;
  481.     dest[2] = b00 * a02 + b01 * a12 + b02 * a22;
  482.  
  483.     dest[3] = b10 * a00 + b11 * a10 + b12 * a20;
  484.     dest[4] = b10 * a01 + b11 * a11 + b12 * a21;
  485.     dest[5] = b10 * a02 + b11 * a12 + b12 * a22;
  486.  
  487.     dest[6] = b20 * a00 + b21 * a10 + b22 * a20;
  488.     dest[7] = b20 * a01 + b21 * a11 + b22 * a21;
  489.     dest[8] = b20 * a02 + b21 * a12 + b22 * a22;
  490.  
  491.     return dest;
  492. }
  493.  
  494. PIXI.mat3.clone = function(mat)
  495. {
  496.     var matrix = new PIXI.Matrix(9);
  497.  
  498.     matrix[0] = mat[0];
  499.     matrix[1] = mat[1];
  500.     matrix[2] = mat[2];
  501.     matrix[3] = mat[3];
  502.     matrix[4] = mat[4];
  503.     matrix[5] = mat[5];
  504.     matrix[6] = mat[6];
  505.     matrix[7] = mat[7];
  506.     matrix[8] = mat[8];
  507.  
  508.     return matrix;
  509. }
  510.  
  511. PIXI.mat3.transpose = function (mat, dest)
  512. {
  513.     // If we are transposing ourselves we can skip a few steps but have to cache some values
  514.     if (!dest || mat === dest) {
  515.         var a01 = mat[1], a02 = mat[2],
  516.             a12 = mat[5];
  517.  
  518.         mat[1] = mat[3];
  519.         mat[2] = mat[6];
  520.         mat[3] = a01;
  521.         mat[5] = mat[7];
  522.         mat[6] = a02;
  523.         mat[7] = a12;
  524.         return mat;
  525.     }
  526.  
  527.     dest[0] = mat[0];
  528.     dest[1] = mat[3];
  529.     dest[2] = mat[6];
  530.     dest[3] = mat[1];
  531.     dest[4] = mat[4];
  532.     dest[5] = mat[7];
  533.     dest[6] = mat[2];
  534.     dest[7] = mat[5];
  535.     dest[8] = mat[8];
  536.     return dest;
  537. }
  538.  
  539. PIXI.mat3.toMat4 = function (mat, dest)
  540. {
  541.     if (!dest) { dest = PIXI.mat4.create(); }
  542.  
  543.     dest[15] = 1;
  544.     dest[14] = 0;
  545.     dest[13] = 0;
  546.     dest[12] = 0;
  547.  
  548.     dest[11] = 0;
  549.     dest[10] = mat[8];
  550.     dest[9] = mat[7];
  551.     dest[8] = mat[6];
  552.  
  553.     dest[7] = 0;
  554.     dest[6] = mat[5];
  555.     dest[5] = mat[4];
  556.     dest[4] = mat[3];
  557.  
  558.     dest[3] = 0;
  559.     dest[2] = mat[2];
  560.     dest[1] = mat[1];
  561.     dest[0] = mat[0];
  562.  
  563.     return dest;
  564. }
  565.  
  566.  
  567. /////
  568.  
  569.  
  570. PIXI.mat4.create = function()
  571. {
  572.     var matrix = new PIXI.Matrix(16);
  573.  
  574.     matrix[0] = 1;
  575.     matrix[1] = 0;
  576.     matrix[2] = 0;
  577.     matrix[3] = 0;
  578.     matrix[4] = 0;
  579.     matrix[5] = 1;
  580.     matrix[6] = 0;
  581.     matrix[7] = 0;
  582.     matrix[8] = 0;
  583.     matrix[9] = 0;
  584.     matrix[10] = 1;
  585.     matrix[11] = 0;
  586.     matrix[12] = 0;
  587.     matrix[13] = 0;
  588.     matrix[14] = 0;
  589.     matrix[15] = 1;
  590.  
  591.     return matrix;
  592. }
  593.  
  594. PIXI.mat4.transpose = function (mat, dest)
  595. {
  596.     // If we are transposing ourselves we can skip a few steps but have to cache some values
  597.     if (!dest || mat === dest)
  598.     {
  599.         var a01 = mat[1], a02 = mat[2], a03 = mat[3],
  600.             a12 = mat[6], a13 = mat[7],
  601.             a23 = mat[11];
  602.  
  603.         mat[1] = mat[4];
  604.         mat[2] = mat[8];
  605.         mat[3] = mat[12];
  606.         mat[4] = a01;
  607.         mat[6] = mat[9];
  608.         mat[7] = mat[13];
  609.         mat[8] = a02;
  610.         mat[9] = a12;
  611.         mat[11] = mat[14];
  612.         mat[12] = a03;
  613.         mat[13] = a13;
  614.         mat[14] = a23;
  615.         return mat;
  616.     }
  617.  
  618.     dest[0] = mat[0];
  619.     dest[1] = mat[4];
  620.     dest[2] = mat[8];
  621.     dest[3] = mat[12];
  622.     dest[4] = mat[1];
  623.     dest[5] = mat[5];
  624.     dest[6] = mat[9];
  625.     dest[7] = mat[13];
  626.     dest[8] = mat[2];
  627.     dest[9] = mat[6];
  628.     dest[10] = mat[10];
  629.     dest[11] = mat[14];
  630.     dest[12] = mat[3];
  631.     dest[13] = mat[7];
  632.     dest[14] = mat[11];
  633.     dest[15] = mat[15];
  634.     return dest;
  635. }
  636.  
  637. PIXI.mat4.multiply = function (mat, mat2, dest)
  638. {
  639.     if (!dest) { dest = mat; }
  640.  
  641.     // Cache the matrix values (makes for huge speed increases!)
  642.     var a00 = mat[ 0], a01 = mat[ 1], a02 = mat[ 2], a03 = mat[3];
  643.     var a10 = mat[ 4], a11 = mat[ 5], a12 = mat[ 6], a13 = mat[7];
  644.     var a20 = mat[ 8], a21 = mat[ 9], a22 = mat[10], a23 = mat[11];
  645.     var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15];
  646.  
  647.     // Cache only the current line of the second matrix
  648.     var b0  = mat2[0], b1 = mat2[1], b2 = mat2[2], b3 = mat2[3];
  649.     dest[0] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
  650.     dest[1] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
  651.     dest[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
  652.     dest[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
  653.  
  654.     b0 = mat2[4];
  655.     b1 = mat2[5];
  656.     b2 = mat2[6];
  657.     b3 = mat2[7];
  658.     dest[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
  659.     dest[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
  660.     dest[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
  661.     dest[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
  662.  
  663.     b0 = mat2[8];
  664.     b1 = mat2[9];
  665.     b2 = mat2[10];
  666.     b3 = mat2[11];
  667.     dest[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
  668.     dest[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
  669.     dest[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
  670.     dest[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
  671.  
  672.     b0 = mat2[12];
  673.     b1 = mat2[13];
  674.     b2 = mat2[14];
  675.     b3 = mat2[15];
  676.     dest[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
  677.     dest[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
  678.     dest[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
  679.     dest[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
  680.  
  681.     return dest;
  682. }
  683.  
  684. /**
  685.  * @author Mat Groves http://matgroves.com/ @Doormat23
  686.  */
  687.  
  688. /**
  689.  * The base class for all objects that are rendered on the screen.
  690.  *
  691.  * @class DisplayObject
  692.  * @constructor
  693.  */
  694. PIXI.DisplayObject = function()
  695. {
  696.     this.last = this;
  697.     this.first = this;
  698.     /**
  699.      * The coordinate of the object relative to the local coordinates of the parent.
  700.      *
  701.      * @property position
  702.      * @type Point
  703.      */
  704.     this.position = new PIXI.Point();
  705.  
  706.     /**
  707.      * The scale factor of the object.
  708.      *
  709.      * @property scale
  710.      * @type Point
  711.      */
  712.     this.scale = new PIXI.Point(1,1);//{x:1, y:1};
  713.  
  714.     /**
  715.      * The pivot point of the displayObject that it rotates around
  716.      *
  717.      * @property pivot
  718.      * @type Point
  719.      */
  720.     this.pivot = new PIXI.Point(0,0);
  721.  
  722.     /**
  723.      * The rotation of the object in radians.
  724.      *
  725.      * @property rotation
  726.      * @type Number
  727.      */
  728.     this.rotation = 0;
  729.  
  730.     /**
  731.      * The opacity of the object.
  732.      *
  733.      * @property alpha
  734.      * @type Number
  735.      */
  736.     this.alpha = 1;
  737.  
  738.     /**
  739.      * The visibility of the object.
  740.      *
  741.      * @property visible
  742.      * @type Boolean
  743.      */
  744.     this.visible = true;
  745.  
  746.     /**
  747.      * This is the defined area that will pick up mouse / touch events. It is null by default.
  748.      * Setting it is a neat way of optimising the hitTest function that the interactionManager will use (as it will not need to hit test all the children)
  749.      *
  750.      * @property hitArea
  751.      * @type Rectangle|Circle|Ellipse|Polygon
  752.      */
  753.     this.hitArea = null;
  754.  
  755.     /**
  756.      * This is used to indicate if the displayObject should display a mouse hand cursor on rollover
  757.      *
  758.      * @property buttonMode
  759.      * @type Boolean
  760.      */
  761.     this.buttonMode = false;
  762.  
  763.     /**
  764.      * Can this object be rendered
  765.      *
  766.      * @property renderable
  767.      * @type Boolean
  768.      */
  769.     this.renderable = false;
  770.  
  771.     /**
  772.      * [read-only] The display object container that contains this display object.
  773.      *
  774.      * @property parent
  775.      * @type DisplayObjectContainer
  776.      * @readOnly
  777.      */
  778.     this.parent = null;
  779.  
  780.     /**
  781.      * [read-only] The stage the display object is connected to, or undefined if it is not connected to the stage.
  782.      *
  783.      * @property stage
  784.      * @type Stage
  785.      * @readOnly
  786.      */
  787.     this.stage = null;
  788.  
  789.     /**
  790.      * [read-only] The multiplied alpha of the displayobject
  791.      *
  792.      * @property worldAlpha
  793.      * @type Number
  794.      * @readOnly
  795.      */
  796.     this.worldAlpha = 1;
  797.  
  798.     /**
  799.      * [read-only] Whether or not the object is interactive, do not toggle directly! use the `interactive` property
  800.      *
  801.      * @property _interactive
  802.      * @type Boolean
  803.      * @readOnly
  804.      * @private
  805.      */
  806.     this._interactive = false;
  807.  
  808.     /**
  809.      * [read-only] Current transform of the object based on world (parent) factors
  810.      *
  811.      * @property worldTransform
  812.      * @type Mat3
  813.      * @readOnly
  814.      * @private
  815.      */
  816.     this.worldTransform = PIXI.mat3.create()//mat3.identity();
  817.  
  818.     /**
  819.      * [read-only] Current transform of the object locally
  820.      *
  821.      * @property localTransform
  822.      * @type Mat3
  823.      * @readOnly
  824.      * @private
  825.      */
  826.     this.localTransform = PIXI.mat3.create()//mat3.identity();
  827.  
  828.     /**
  829.      * [NYI] Unkown
  830.      *
  831.      * @property color
  832.      * @type Array<>
  833.      * @private
  834.      */
  835.     this.color = [];
  836.  
  837.     /**
  838.      * [NYI] Holds whether or not this object is dynamic, for rendering optimization
  839.      *
  840.      * @property dynamic
  841.      * @type Boolean
  842.      * @private
  843.      */
  844.     this.dynamic = true;
  845.  
  846.     // chach that puppy!
  847.     this._sr = 0;
  848.     this._cr = 1;
  849.  
  850.  
  851.     this.filterArea = new PIXI.Rectangle(0,0,1,1);
  852.    
  853.     /*
  854.      * MOUSE Callbacks
  855.      */
  856.  
  857.     /**
  858.      * A callback that is used when the users clicks on the displayObject with their mouse
  859.      * @method click
  860.      * @param interactionData {InteractionData}
  861.      */
  862.  
  863.     /**
  864.      * A callback that is used when the user clicks the mouse down over the sprite
  865.      * @method mousedown
  866.      * @param interactionData {InteractionData}
  867.      */
  868.  
  869.     /**
  870.      * A callback that is used when the user releases the mouse that was over the displayObject
  871.      * for this callback to be fired the mouse must have been pressed down over the displayObject
  872.      * @method mouseup
  873.      * @param interactionData {InteractionData}
  874.      */
  875.  
  876.     /**
  877.      * A callback that is used when the user releases the mouse that was over the displayObject but is no longer over the displayObject
  878.      * for this callback to be fired, The touch must have started over the displayObject
  879.      * @method mouseupoutside
  880.      * @param interactionData {InteractionData}
  881.      */
  882.  
  883.     /**
  884.      * A callback that is used when the users mouse rolls over the displayObject
  885.      * @method mouseover
  886.      * @param interactionData {InteractionData}
  887.      */
  888.  
  889.     /**
  890.      * A callback that is used when the users mouse leaves the displayObject
  891.      * @method mouseout
  892.      * @param interactionData {InteractionData}
  893.      */
  894.  
  895.  
  896.     /*
  897.      * TOUCH Callbacks
  898.      */
  899.  
  900.     /**
  901.      * A callback that is used when the users taps on the sprite with their finger
  902.      * basically a touch version of click
  903.      * @method tap
  904.      * @param interactionData {InteractionData}
  905.      */
  906.  
  907.     /**
  908.      * A callback that is used when the user touch's over the displayObject
  909.      * @method touchstart
  910.      * @param interactionData {InteractionData}
  911.      */
  912.  
  913.     /**
  914.      * A callback that is used when the user releases a touch over the displayObject
  915.      * @method touchend
  916.      * @param interactionData {InteractionData}
  917.      */
  918.  
  919.     /**
  920.      * A callback that is used when the user releases the touch that was over the displayObject
  921.      * for this callback to be fired, The touch must have started over the sprite
  922.      * @method touchendoutside
  923.      * @param interactionData {InteractionData}
  924.      */
  925. }
  926.  
  927. // constructor
  928. PIXI.DisplayObject.prototype.constructor = PIXI.DisplayObject;
  929.  
  930. /**
  931.  * [Deprecated] Indicates if the sprite will have touch and mouse interactivity. It is false by default
  932.  * Instead of using this function you can now simply set the interactive property to true or false
  933.  *
  934.  * @method setInteractive
  935.  * @param interactive {Boolean}
  936.  * @deprecated Simply set the `interactive` property directly
  937.  */
  938. PIXI.DisplayObject.prototype.setInteractive = function(interactive)
  939. {
  940.     this.interactive = interactive;
  941. }
  942.  
  943. /**
  944.  * Indicates if the sprite will have touch and mouse interactivity. It is false by default
  945.  *
  946.  * @property interactive
  947.  * @type Boolean
  948.  * @default false
  949.  */
  950. Object.defineProperty(PIXI.DisplayObject.prototype, 'interactive', {
  951.     get: function() {
  952.         return this._interactive;
  953.     },
  954.     set: function(value) {
  955.         this._interactive = value;
  956.        
  957.         // TODO more to be done here..
  958.         // need to sort out a re-crawl!
  959.         if(this.stage)this.stage.dirty = true;
  960.     }
  961. });
  962.  
  963. /**
  964.  * Sets a mask for the displayObject. A mask is an object that limits the visibility of an object to the shape of the mask applied to it.
  965.  * In PIXI a regular mask must be a PIXI.Ggraphics object. This allows for much faster masking in canvas as it utilises shape clipping.
  966.  * To remove a mask, set this property to null.
  967.  *
  968.  * @property mask
  969.  * @type Graphics
  970.  */
  971. Object.defineProperty(PIXI.DisplayObject.prototype, 'mask', {
  972.     get: function() {
  973.         return this._mask;
  974.     },
  975.     set: function(value) {
  976.        
  977.        
  978.         if(value)
  979.         {
  980.             if(this._mask)
  981.             {
  982.                 value.start = this._mask.start;
  983.                 value.end = this._mask.end;
  984.             }
  985.             else
  986.             {
  987.                 this.addFilter(value);
  988.                 value.renderable = false;
  989.             }
  990.         }
  991.         else
  992.         {
  993.              this.removeFilter(this._mask);
  994.              this._mask.renderable = true;
  995.         }
  996.        
  997.         this._mask = value;
  998.     }
  999. });
  1000.  
  1001. /**
  1002.  * Sets the filters for the displayObject.
  1003.  * * IMPORTANT: This is a webGL only feature and will be ignored by the canvas renderer.
  1004.  * To remove filters simply set this property to 'null'
  1005.  * @property filters
  1006.  * @type Array An array of filters
  1007.  */
  1008. Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', {
  1009.     get: function() {
  1010.         return this._filters;
  1011.     },
  1012.     set: function(value) {
  1013.        
  1014.         if(value)
  1015.         {
  1016.             if(this._filters)this.removeFilter(this._filters);
  1017.             this.addFilter(value);
  1018.  
  1019.             // now put all the passes in one place..
  1020.             var passes = [];
  1021.             for (var i = 0; i < value.length; i++)
  1022.             {
  1023.                 var filterPasses = value[i].passes;
  1024.                 for (var j = 0; j < filterPasses.length; j++)
  1025.                 {
  1026.                     passes.push(filterPasses[j]);
  1027.                 };
  1028.             };
  1029.  
  1030.             value.start.filterPasses = passes;
  1031.         }
  1032.         else
  1033.         {
  1034.             if(this._filters)this.removeFilter(this._filters);
  1035.         }
  1036.        
  1037.         this._filters = value;
  1038.  
  1039.        
  1040.  
  1041.        
  1042.     }
  1043. });
  1044.  
  1045. /*
  1046.  * Adds a filter to this displayObject
  1047.  *
  1048.  * @method addFilter
  1049.  * @param mask {Graphics} the graphics object to use as a filter
  1050.  * @private
  1051.  */
  1052. PIXI.DisplayObject.prototype.addFilter = function(data)
  1053. {
  1054.     //if(this.filter)return;
  1055.     //this.filter = true;
  1056. //  data[0].target = this;
  1057.    
  1058.  
  1059.     // insert a filter block..
  1060.     // TODO Onject pool thease bad boys..
  1061.     var start = new PIXI.FilterBlock();
  1062.     var end = new PIXI.FilterBlock();
  1063.    
  1064.     data.start = start;
  1065.     data.end = end;
  1066.    
  1067.     start.data = data;
  1068.     end.data = data;
  1069.    
  1070.     start.first = start.last =  this;
  1071.     end.first = end.last = this;
  1072.    
  1073.     start.open = true;
  1074.    
  1075.     start.target = this;
  1076.    
  1077.     /*
  1078.      * insert start
  1079.      */
  1080.    
  1081.     var childFirst = start
  1082.     var childLast = start
  1083.     var nextObject;
  1084.     var previousObject;
  1085.        
  1086.     previousObject = this.first._iPrev;
  1087.    
  1088.     if(previousObject)
  1089.     {
  1090.         nextObject = previousObject._iNext;
  1091.         childFirst._iPrev = previousObject;
  1092.         previousObject._iNext = childFirst;    
  1093.     }
  1094.     else
  1095.     {
  1096.         nextObject = this;
  1097.     }  
  1098.    
  1099.     if(nextObject)
  1100.     {
  1101.         nextObject._iPrev = childLast;
  1102.         childLast._iNext = nextObject;
  1103.     }
  1104.    
  1105.    
  1106.     // now insert the end filter block..
  1107.    
  1108.     /*
  1109.      * insert end filter
  1110.      */
  1111.     var childFirst = end
  1112.     var childLast = end
  1113.     var nextObject = null;
  1114.     var previousObject = null;
  1115.        
  1116.     previousObject = this.last;
  1117.     nextObject = previousObject._iNext;
  1118.    
  1119.     if(nextObject)
  1120.     {
  1121.         nextObject._iPrev = childLast;
  1122.         childLast._iNext = nextObject;
  1123.     }
  1124.    
  1125.     childFirst._iPrev = previousObject;
  1126.     previousObject._iNext = childFirst;
  1127.    
  1128.     var updateLast = this;
  1129.    
  1130.     var prevLast = this.last;
  1131.     while(updateLast)
  1132.     {
  1133.         if(updateLast.last == prevLast)
  1134.         {
  1135.             updateLast.last = end;
  1136.         }
  1137.         updateLast = updateLast.parent;
  1138.     }
  1139.    
  1140.     this.first = start;
  1141.    
  1142.     // if webGL...
  1143.     if(this.__renderGroup)
  1144.     {
  1145.         this.__renderGroup.addFilterBlocks(start, end);
  1146.     }
  1147.    
  1148. }
  1149.  
  1150. /*
  1151.  * Removes the filter to this displayObject
  1152.  *
  1153.  * @method removeFilter
  1154.  * @private
  1155.  */
  1156. PIXI.DisplayObject.prototype.removeFilter = function(data)
  1157. {
  1158.     //if(!this.filter)return;
  1159.     //this.filter = false;
  1160.     console.log("YUOIO")
  1161.     // modify the list..
  1162.     var startBlock = data.start;
  1163.    
  1164.    
  1165.     var nextObject = startBlock._iNext;
  1166.     var previousObject = startBlock._iPrev;
  1167.        
  1168.     if(nextObject)nextObject._iPrev = previousObject;
  1169.     if(previousObject)previousObject._iNext = nextObject;      
  1170.    
  1171.     this.first = startBlock._iNext;
  1172.    
  1173.     // remove the end filter
  1174.     var lastBlock = data.end;
  1175.    
  1176.     var nextObject = lastBlock._iNext;
  1177.     var previousObject = lastBlock._iPrev;
  1178.        
  1179.     if(nextObject)nextObject._iPrev = previousObject;
  1180.     previousObject._iNext = nextObject;    
  1181.    
  1182.     // this is always true too!
  1183.     var tempLast =  lastBlock._iPrev;  
  1184.     // need to make sure the parents last is updated too
  1185.     var updateLast = this;
  1186.     while(updateLast.last == lastBlock)
  1187.     {
  1188.         updateLast.last = tempLast;
  1189.         updateLast = updateLast.parent;
  1190.         if(!updateLast)break;
  1191.     }
  1192.    
  1193.     // if webGL...
  1194.     if(this.__renderGroup)
  1195.     {
  1196.         this.__renderGroup.removeFilterBlocks(startBlock, lastBlock);
  1197.     }
  1198. }
  1199.  
  1200. /*
  1201.  * Updates the object transform for rendering
  1202.  *
  1203.  * @method updateTransform
  1204.  * @private
  1205.  */
  1206. PIXI.DisplayObject.prototype.updateTransform = function()
  1207. {
  1208.     // TODO OPTIMIZE THIS!! with dirty
  1209.     if(this.rotation !== this.rotationCache)
  1210.     {
  1211.         this.rotationCache = this.rotation;
  1212.         this._sr =  Math.sin(this.rotation);
  1213.         this._cr =  Math.cos(this.rotation);
  1214.     }  
  1215.    
  1216.     var localTransform = this.localTransform;
  1217.     var parentTransform = this.parent.worldTransform;
  1218.     var worldTransform = this.worldTransform;
  1219.     //console.log(localTransform)
  1220.     localTransform[0] = this._cr * this.scale.x;
  1221.     localTransform[1] = -this._sr * this.scale.y
  1222.     localTransform[3] = this._sr * this.scale.x;
  1223.     localTransform[4] = this._cr * this.scale.y;
  1224.    
  1225.     // TODO --> do we even need a local matrix???
  1226.    
  1227.     var px = this.pivot.x;
  1228.     var py = this.pivot.y;
  1229.    
  1230.     // Cache the matrix values (makes for huge speed increases!)
  1231.     var a00 = localTransform[0], a01 = localTransform[1], a02 = this.position.x - localTransform[0] * px - py * localTransform[1],
  1232.         a10 = localTransform[3], a11 = localTransform[4], a12 = this.position.y - localTransform[4] * py - px * localTransform[3],
  1233.  
  1234.         b00 = parentTransform[0], b01 = parentTransform[1], b02 = parentTransform[2],
  1235.         b10 = parentTransform[3], b11 = parentTransform[4], b12 = parentTransform[5];
  1236.  
  1237.     localTransform[2] = a02
  1238.     localTransform[5] = a12
  1239.    
  1240.     worldTransform[0] = b00 * a00 + b01 * a10;
  1241.     worldTransform[1] = b00 * a01 + b01 * a11;
  1242.     worldTransform[2] = b00 * a02 + b01 * a12 + b02;
  1243.  
  1244.     worldTransform[3] = b10 * a00 + b11 * a10;
  1245.     worldTransform[4] = b10 * a01 + b11 * a11;
  1246.     worldTransform[5] = b10 * a02 + b11 * a12 + b12;
  1247.  
  1248.     // because we are using affine transformation, we can optimise the matrix concatenation process.. wooo!
  1249.     // mat3.multiply(this.localTransform, this.parent.worldTransform, this.worldTransform);
  1250.     this.worldAlpha = this.alpha * this.parent.worldAlpha;
  1251.    
  1252.     this.vcount = PIXI.visibleCount;
  1253.  
  1254. }
  1255.  
  1256. PIXI.visibleCount = 0;
  1257. /**
  1258.  * @author Mat Groves http://matgroves.com/ @Doormat23
  1259.  */
  1260.  
  1261.  
  1262. /**
  1263.  * A DisplayObjectContainer represents a collection of display objects.
  1264.  * It is the base class of all display objects that act as a container for other objects.
  1265.  *
  1266.  * @class DisplayObjectContainer
  1267.  * @extends DisplayObject
  1268.  * @constructor
  1269.  */
  1270. PIXI.DisplayObjectContainer = function()
  1271. {
  1272.     PIXI.DisplayObject.call( this );
  1273.    
  1274.     /**
  1275.      * [read-only] The of children of this container.
  1276.      *
  1277.      * @property children
  1278.      * @type Array<DisplayObject>
  1279.      * @readOnly
  1280.      */
  1281.     this.children = [];
  1282. }
  1283.  
  1284. // constructor
  1285. PIXI.DisplayObjectContainer.prototype = Object.create( PIXI.DisplayObject.prototype );
  1286. PIXI.DisplayObjectContainer.prototype.constructor = PIXI.DisplayObjectContainer;
  1287.  
  1288. /**
  1289.  * Adds a child to the container.
  1290.  *
  1291.  * @method addChild
  1292.  * @param child {DisplayObject} The DisplayObject to add to the container
  1293.  */
  1294. PIXI.DisplayObjectContainer.prototype.addChild = function(child)
  1295. {
  1296.     if(child.parent != undefined)
  1297.     {
  1298.        
  1299.         //// COULD BE THIS???
  1300.         child.parent.removeChild(child);
  1301.     //  return;
  1302.     }
  1303.  
  1304.     child.parent = this;
  1305.    
  1306.     this.children.push(child); 
  1307.    
  1308.     // update the stage refference..
  1309.    
  1310.     if(this.stage)
  1311.     {
  1312.         var tmpChild = child;
  1313.         do
  1314.         {
  1315.             if(tmpChild.interactive)this.stage.dirty = true;
  1316.             tmpChild.stage = this.stage;
  1317.             tmpChild = tmpChild._iNext;
  1318.         }  
  1319.         while(tmpChild)
  1320.     }
  1321.    
  1322.     // LINKED LIST //
  1323.    
  1324.     // modify the list..
  1325.     var childFirst = child.first
  1326.     var childLast = child.last;
  1327.     var nextObject;
  1328.     var previousObject;
  1329.    
  1330.     // this could be wrong if there is a filter??
  1331.     if(this._filters || this._mask)
  1332.     {
  1333.         previousObject =  this.last._iPrev;
  1334.     }
  1335.     else
  1336.     {
  1337.         previousObject = this.last;
  1338.     }
  1339.  
  1340.     nextObject = previousObject._iNext;
  1341.    
  1342.     // always true in this case
  1343.     // need to make sure the parents last is updated too
  1344.     var updateLast = this;
  1345.     var prevLast = previousObject;
  1346.    
  1347.     while(updateLast)
  1348.     {
  1349.         if(updateLast.last == prevLast)
  1350.         {
  1351.             updateLast.last = child.last;
  1352.         }
  1353.         updateLast = updateLast.parent;
  1354.     }
  1355.    
  1356.     if(nextObject)
  1357.     {
  1358.         nextObject._iPrev = childLast;
  1359.         childLast._iNext = nextObject;
  1360.     }
  1361.    
  1362.     childFirst._iPrev = previousObject;
  1363.     previousObject._iNext = childFirst;    
  1364.  
  1365.     // need to remove any render groups..
  1366.     if(this.__renderGroup)
  1367.     {
  1368.         // being used by a renderTexture.. if it exists then it must be from a render texture;
  1369.         if(child.__renderGroup)child.__renderGroup.removeDisplayObjectAndChildren(child);
  1370.         // add them to the new render group..
  1371.         this.__renderGroup.addDisplayObjectAndChildren(child);
  1372.     }
  1373.    
  1374. }
  1375.  
  1376. /**
  1377.  * Adds a child to the container at a specified index. If the index is out of bounds an error will be thrown
  1378.  *
  1379.  * @method addChildAt
  1380.  * @param child {DisplayObject} The child to add
  1381.  * @param index {Number} The index to place the child in
  1382.  */
  1383. PIXI.DisplayObjectContainer.prototype.addChildAt = function(child, index)
  1384. {
  1385.     if(index >= 0 && index <= this.children.length)
  1386.     {
  1387.         if(child.parent != undefined)
  1388.         {
  1389.             child.parent.removeChild(child);
  1390.         }
  1391.         child.parent = this;
  1392.        
  1393.         if(this.stage)
  1394.         {
  1395.             var tmpChild = child;
  1396.             do
  1397.             {
  1398.                 if(tmpChild.interactive)this.stage.dirty = true;
  1399.                 tmpChild.stage = this.stage;
  1400.                 tmpChild = tmpChild._iNext;
  1401.             }
  1402.             while(tmpChild)
  1403.         }
  1404.        
  1405.         // modify the list..
  1406.         var childFirst = child.first;
  1407.         var childLast = child.last;
  1408.         var nextObject;
  1409.         var previousObject;
  1410.        
  1411.         if(index == this.children.length)
  1412.         {
  1413.             previousObject =  this.last;
  1414.             var updateLast = this;
  1415.             var prevLast = this.last;
  1416.             while(updateLast)
  1417.             {
  1418.                 if(updateLast.last == prevLast)
  1419.                 {
  1420.                     updateLast.last = child.last;
  1421.                 }
  1422.                 updateLast = updateLast.parent;
  1423.             }
  1424.         }
  1425.         else if(index == 0)
  1426.         {
  1427.             previousObject = this;
  1428.         }
  1429.         else
  1430.         {
  1431.             previousObject = this.children[index-1].last;
  1432.         }
  1433.        
  1434.         nextObject = previousObject._iNext;
  1435.        
  1436.         // always true in this case
  1437.         if(nextObject)
  1438.         {
  1439.             nextObject._iPrev = childLast;
  1440.             childLast._iNext = nextObject;
  1441.         }
  1442.        
  1443.         childFirst._iPrev = previousObject;
  1444.         previousObject._iNext = childFirst;    
  1445.  
  1446.         this.children.splice(index, 0, child);
  1447.         // need to remove any render groups..
  1448.         if(this.__renderGroup)
  1449.         {
  1450.             // being used by a renderTexture.. if it exists then it must be from a render texture;
  1451.             if(child.__renderGroup)child.__renderGroup.removeDisplayObjectAndChildren(child);
  1452.             // add them to the new render group..
  1453.             this.__renderGroup.addDisplayObjectAndChildren(child);
  1454.         }
  1455.        
  1456.     }
  1457.     else
  1458.     {
  1459.         throw new Error(child + " The index "+ index +" supplied is out of bounds " + this.children.length);
  1460.     }
  1461. }
  1462.  
  1463. /**
  1464.  * [NYI] Swaps the depth of 2 displayObjects
  1465.  *
  1466.  * @method swapChildren
  1467.  * @param child {DisplayObject}
  1468.  * @param child2 {DisplayObject}
  1469.  * @private
  1470.  */
  1471. PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2)
  1472. {
  1473.     /*
  1474.      * this funtion needs to be recoded..
  1475.      * can be done a lot faster..
  1476.      */
  1477.     return;
  1478.    
  1479.     // need to fix this function :/
  1480.     /*
  1481.     // TODO I already know this??
  1482.     var index = this.children.indexOf( child );
  1483.     var index2 = this.children.indexOf( child2 );
  1484.    
  1485.     if ( index !== -1 && index2 !== -1 )
  1486.     {
  1487.         // cool
  1488.        
  1489.         /*
  1490.         if(this.stage)
  1491.         {
  1492.             // this is to satisfy the webGL batching..
  1493.             // TODO sure there is a nicer way to achieve this!
  1494.             this.stage.__removeChild(child);
  1495.             this.stage.__removeChild(child2);
  1496.            
  1497.             this.stage.__addChild(child);
  1498.             this.stage.__addChild(child2);
  1499.         }
  1500.        
  1501.         // swap the positions..
  1502.         this.children[index] = child2;
  1503.         this.children[index2] = child;
  1504.        
  1505.     }
  1506.     else
  1507.     {
  1508.         throw new Error(child + " Both the supplied DisplayObjects must be a child of the caller " + this);
  1509.     }*/
  1510. }
  1511.  
  1512. /**
  1513.  * Returns the Child at the specified index
  1514.  *
  1515.  * @method getChildAt
  1516.  * @param index {Number} The index to get the child from
  1517.  */
  1518. PIXI.DisplayObjectContainer.prototype.getChildAt = function(index)
  1519. {
  1520.     if(index >= 0 && index < this.children.length)
  1521.     {
  1522.         return this.children[index];
  1523.     }
  1524.     else
  1525.     {
  1526.         throw new Error(child + " Both the supplied DisplayObjects must be a child of the caller " + this);
  1527.     }
  1528. }
  1529.  
  1530. /**
  1531.  * Removes a child from the container.
  1532.  *
  1533.  * @method removeChild
  1534.  * @param child {DisplayObject} The DisplayObject to remove
  1535.  */
  1536. PIXI.DisplayObjectContainer.prototype.removeChild = function(child)
  1537. {
  1538.     var index = this.children.indexOf( child );
  1539.     if ( index !== -1 )
  1540.     {
  1541.         // unlink //
  1542.         // modify the list..
  1543.         var childFirst = child.first;
  1544.         var childLast = child.last;
  1545.        
  1546.         var nextObject = childLast._iNext;
  1547.         var previousObject = childFirst._iPrev;
  1548.            
  1549.         if(nextObject)nextObject._iPrev = previousObject;
  1550.         previousObject._iNext = nextObject;    
  1551.        
  1552.         if(this.last == childLast)
  1553.         {
  1554.             var tempLast =  childFirst._iPrev; 
  1555.             // need to make sure the parents last is updated too
  1556.             var updateLast = this;
  1557.             while(updateLast.last == childLast.last)
  1558.             {
  1559.                 updateLast.last = tempLast;
  1560.                 updateLast = updateLast.parent;
  1561.                 if(!updateLast)break;
  1562.             }
  1563.         }
  1564.        
  1565.         childLast._iNext = null;
  1566.         childFirst._iPrev = null;
  1567.          
  1568.         // update the stage reference..
  1569.         if(this.stage)
  1570.         {
  1571.             var tmpChild = child;
  1572.             do
  1573.             {
  1574.                 if(tmpChild.interactive)this.stage.dirty = true;
  1575.                 tmpChild.stage = null;
  1576.                 tmpChild = tmpChild._iNext;
  1577.             }  
  1578.             while(tmpChild)
  1579.         }
  1580.    
  1581.         // webGL trim
  1582.         if(child.__renderGroup)
  1583.         {
  1584.             child.__renderGroup.removeDisplayObjectAndChildren(child);
  1585.         }
  1586.        
  1587.         child.parent = undefined;
  1588.         this.children.splice( index, 1 );
  1589.     }
  1590.     else
  1591.     {
  1592.         throw new Error(child + " The supplied DisplayObject must be a child of the caller " + this);
  1593.     }
  1594. }
  1595.  
  1596. /*
  1597.  * Updates the container's children's transform for rendering
  1598.  *
  1599.  * @method updateTransform
  1600.  * @private
  1601.  */
  1602. PIXI.DisplayObjectContainer.prototype.updateTransform = function()
  1603. {
  1604.     if(!this.visible)return;
  1605.    
  1606.     PIXI.DisplayObject.prototype.updateTransform.call( this );
  1607.    
  1608.     for(var i=0,j=this.children.length; i<j; i++)
  1609.     {
  1610.         this.children[i].updateTransform();
  1611.     }
  1612. }
  1613. /**
  1614.  * @author Mat Groves http://matgroves.com/ @Doormat23
  1615.  */
  1616.  
  1617. PIXI.blendModes = {};
  1618. PIXI.blendModes.NORMAL = 0;
  1619. PIXI.blendModes.SCREEN = 1;
  1620.  
  1621.  
  1622. /**
  1623.  * The SPrite object is the base for all textured objects that are rendered to the screen
  1624.  *
  1625.  * @class Sprite
  1626.  * @extends DisplayObjectContainer
  1627.  * @constructor
  1628.  * @param texture {Texture} The texture for this sprite
  1629.  * @type String
  1630.  */
  1631. PIXI.Sprite = function(texture)
  1632. {
  1633.     PIXI.DisplayObjectContainer.call( this );
  1634.  
  1635.     /**
  1636.      * The anchor sets the origin point of the texture.
  1637.      * The default is 0,0 this means the textures origin is the top left
  1638.      * Setting than anchor to 0.5,0.5 means the textures origin is centered
  1639.      * Setting the anchor to 1,1 would mean the textures origin points will be the bottom right
  1640.      *
  1641.      * @property anchor
  1642.      * @type Point
  1643.      */
  1644.     this.anchor = new PIXI.Point();
  1645.  
  1646.     /**
  1647.      * The texture that the sprite is using
  1648.      *
  1649.      * @property texture
  1650.      * @type Texture
  1651.      */
  1652.     this.texture = texture;
  1653.  
  1654.     /**
  1655.      * The blend mode of sprite.
  1656.      * currently supports PIXI.blendModes.NORMAL and PIXI.blendModes.SCREEN
  1657.      *
  1658.      * @property blendMode
  1659.      * @type Number
  1660.      */
  1661.     this.blendMode = PIXI.blendModes.NORMAL;
  1662.  
  1663.     /**
  1664.      * The width of the sprite (this is initially set by the texture)
  1665.      *
  1666.      * @property _width
  1667.      * @type Number
  1668.      * @private
  1669.      */
  1670.     this._width = 0;
  1671.  
  1672.     /**
  1673.      * The height of the sprite (this is initially set by the texture)
  1674.      *
  1675.      * @property _height
  1676.      * @type Number
  1677.      * @private
  1678.      */
  1679.     this._height = 0;
  1680.  
  1681.     if(texture.baseTexture.hasLoaded)
  1682.     {
  1683.         this.updateFrame = true;
  1684.     }
  1685.     else
  1686.     {
  1687.         this.onTextureUpdateBind = this.onTextureUpdate.bind(this);
  1688.         this.texture.addEventListener( 'update', this.onTextureUpdateBind );
  1689.     }
  1690.  
  1691.     this.renderable = true;
  1692. }
  1693.  
  1694. // constructor
  1695. PIXI.Sprite.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
  1696. PIXI.Sprite.prototype.constructor = PIXI.Sprite;
  1697.  
  1698. /**
  1699.  * The width of the sprite, setting this will actually modify the scale to acheive the value set
  1700.  *
  1701.  * @property width
  1702.  * @type Number
  1703.  */
  1704. Object.defineProperty(PIXI.Sprite.prototype, 'width', {
  1705.     get: function() {
  1706.         return this.scale.x * this.texture.frame.width;
  1707.     },
  1708.     set: function(value) {
  1709.         this.scale.x = value / this.texture.frame.width
  1710.         this._width = value;
  1711.     }
  1712. });
  1713.  
  1714. /**
  1715.  * The height of the sprite, setting this will actually modify the scale to acheive the value set
  1716.  *
  1717.  * @property height
  1718.  * @type Number
  1719.  */
  1720. Object.defineProperty(PIXI.Sprite.prototype, 'height', {
  1721.     get: function() {
  1722.         return  this.scale.y * this.texture.frame.height;
  1723.     },
  1724.     set: function(value) {
  1725.         this.scale.y = value / this.texture.frame.height
  1726.         this._height = value;
  1727.     }
  1728. });
  1729.  
  1730. /**
  1731.  * Sets the texture of the sprite
  1732.  *
  1733.  * @method setTexture
  1734.  * @param texture {Texture} The PIXI texture that is displayed by the sprite
  1735.  */
  1736. PIXI.Sprite.prototype.setTexture = function(texture)
  1737. {
  1738.     // stop current texture;
  1739.     if(this.texture.baseTexture != texture.baseTexture)
  1740.     {
  1741.         this.textureChange = true; 
  1742.         this.texture = texture;
  1743.        
  1744.         if(this.__renderGroup)
  1745.         {
  1746.             this.__renderGroup.updateTexture(this);
  1747.         }
  1748.     }
  1749.     else
  1750.     {
  1751.         this.texture = texture;
  1752.     }
  1753.    
  1754.     this.updateFrame = true;
  1755. }
  1756.  
  1757. /**
  1758.  * When the texture is updated, this event will fire to update the scale and frame
  1759.  *
  1760.  * @method onTextureUpdate
  1761.  * @param event
  1762.  * @private
  1763.  */
  1764. PIXI.Sprite.prototype.onTextureUpdate = function(event)
  1765. {
  1766.     //this.texture.removeEventListener( 'update', this.onTextureUpdateBind );
  1767.    
  1768.     // so if _width is 0 then width was not set..
  1769.     if(this._width)this.scale.x = this._width / this.texture.frame.width;
  1770.     if(this._height)this.scale.y = this._height / this.texture.frame.height;
  1771.    
  1772.     this.updateFrame = true;
  1773. }
  1774.  
  1775. // some helper functions..
  1776.  
  1777. /**
  1778.  *
  1779.  * Helper function that creates a sprite that will contain a texture from the TextureCache based on the frameId
  1780.  * The frame ids are created when a Texture packer file has been loaded
  1781.  *
  1782.  * @method fromFrame
  1783.  * @static
  1784.  * @param frameId {String} The frame Id of the texture in the cache
  1785.  * @return {Sprite} A new Sprite using a texture from the texture cache matching the frameId
  1786.  */
  1787. PIXI.Sprite.fromFrame = function(frameId)
  1788. {
  1789.     var texture = PIXI.TextureCache[frameId];
  1790.     if(!texture)throw new Error("The frameId '"+ frameId +"' does not exist in the texture cache" + this);
  1791.     return new PIXI.Sprite(texture);
  1792. }
  1793.  
  1794. /**
  1795.  *
  1796.  * Helper function that creates a sprite that will contain a texture based on an image url
  1797.  * If the image is not in the texture cache it will be loaded
  1798.  *
  1799.  * @method fromImage
  1800.  * @static
  1801.  * @param imageId {String} The image url of the texture
  1802.  * @return {Sprite} A new Sprite using a texture from the texture cache matching the image id
  1803.  */
  1804. PIXI.Sprite.fromImage = function(imageId)
  1805. {
  1806.     var texture = PIXI.Texture.fromImage(imageId);
  1807.     return new PIXI.Sprite(texture);
  1808. }
  1809.  
  1810. /**
  1811.  * @author Mat Groves http://matgroves.com/ @Doormat23
  1812.  */
  1813.  
  1814. /**
  1815.  * A MovieClip is a simple way to display an animation depicted by a list of textures.
  1816.  *
  1817.  * @class MovieClip
  1818.  * @extends Sprite
  1819.  * @constructor
  1820.  * @param textures {Array<Texture>} an array of {Texture} objects that make up the animation
  1821.  */
  1822. PIXI.MovieClip = function(textures)
  1823. {
  1824.     PIXI.Sprite.call(this, textures[0]);
  1825.  
  1826.     /**
  1827.      * The array of textures that make up the animation
  1828.      *
  1829.      * @property textures
  1830.      * @type Array
  1831.      */
  1832.     this.textures = textures;
  1833.  
  1834.     /**
  1835.      * The speed that the MovieClip will play at. Higher is faster, lower is slower
  1836.      *
  1837.      * @property animationSpeed
  1838.      * @type Number
  1839.      * @default 1
  1840.      */
  1841.     this.animationSpeed = 1;
  1842.  
  1843.     /**
  1844.      * Whether or not the movie clip repeats after playing.
  1845.      *
  1846.      * @property loop
  1847.      * @type Boolean
  1848.      * @default true
  1849.      */
  1850.     this.loop = true;
  1851.  
  1852.     /**
  1853.      * Function to call when a MovieClip finishes playing
  1854.      *
  1855.      * @property onComplete
  1856.      * @type Function
  1857.      */
  1858.     this.onComplete = null;
  1859.  
  1860.     /**
  1861.      * [read-only] The index MovieClips current frame (this may not have to be a whole number)
  1862.      *
  1863.      * @property currentFrame
  1864.      * @type Number
  1865.      * @default 0
  1866.      * @readOnly
  1867.      */
  1868.     this.currentFrame = 0;
  1869.  
  1870.     /**
  1871.      * [read-only] Indicates if the MovieClip is currently playing
  1872.      *
  1873.      * @property playing
  1874.      * @type Boolean
  1875.      * @readOnly
  1876.      */
  1877.     this.playing = false;
  1878. }
  1879.  
  1880. // constructor
  1881. PIXI.MovieClip.prototype = Object.create( PIXI.Sprite.prototype );
  1882. PIXI.MovieClip.prototype.constructor = PIXI.MovieClip;
  1883.  
  1884. /**
  1885. * [read-only] totalFrames is the total number of frames in the MovieClip. This is the same as number of textures
  1886. * assigned to the MovieClip.
  1887. *
  1888. * @property totalFrames
  1889. * @type Number
  1890. * @default 0
  1891. * @readOnly
  1892. */
  1893. Object.defineProperty( PIXI.MovieClip.prototype, 'totalFrames', {
  1894.     get: function() {
  1895.  
  1896.         return this.textures.length;
  1897.     }
  1898. });
  1899.  
  1900.  
  1901. /**
  1902.  * Stops the MovieClip
  1903.  *
  1904.  * @method stop
  1905.  */
  1906. PIXI.MovieClip.prototype.stop = function()
  1907. {
  1908.     this.playing = false;
  1909. }
  1910.  
  1911. /**
  1912.  * Plays the MovieClip
  1913.  *
  1914.  * @method play
  1915.  */
  1916. PIXI.MovieClip.prototype.play = function()
  1917. {
  1918.     this.playing = true;
  1919. }
  1920.  
  1921. /**
  1922.  * Stops the MovieClip and goes to a specific frame
  1923.  *
  1924.  * @method gotoAndStop
  1925.  * @param frameNumber {Number} frame index to stop at
  1926.  */
  1927. PIXI.MovieClip.prototype.gotoAndStop = function(frameNumber)
  1928. {
  1929.     this.playing = false;
  1930.     this.currentFrame = frameNumber;
  1931.     var round = (this.currentFrame + 0.5) | 0;
  1932.     this.setTexture(this.textures[round % this.textures.length]);
  1933. }
  1934.  
  1935. /**
  1936.  * Goes to a specific frame and begins playing the MovieClip
  1937.  *
  1938.  * @method gotoAndPlay
  1939.  * @param frameNumber {Number} frame index to start at
  1940.  */
  1941. PIXI.MovieClip.prototype.gotoAndPlay = function(frameNumber)
  1942. {
  1943.     this.currentFrame = frameNumber;
  1944.     this.playing = true;
  1945. }
  1946.  
  1947. /*
  1948.  * Updates the object transform for rendering
  1949.  *
  1950.  * @method updateTransform
  1951.  * @private
  1952.  */
  1953. PIXI.MovieClip.prototype.updateTransform = function()
  1954. {
  1955.     PIXI.Sprite.prototype.updateTransform.call(this);
  1956.  
  1957.     if(!this.playing)return;
  1958.  
  1959.     this.currentFrame += this.animationSpeed;
  1960.  
  1961.     var round = (this.currentFrame + 0.5) | 0;
  1962.  
  1963.     if(this.loop || round < this.textures.length)
  1964.     {
  1965.         this.setTexture(this.textures[round % this.textures.length]);
  1966.     }
  1967.     else if(round >= this.textures.length)
  1968.     {
  1969.         this.gotoAndStop(this.textures.length - 1);
  1970.         if(this.onComplete)
  1971.         {
  1972.             this.onComplete();
  1973.         }
  1974.     }
  1975. }
  1976. /**
  1977.  * @author Mat Groves http://matgroves.com/ @Doormat23
  1978.  */
  1979.  
  1980.  
  1981.  
  1982. PIXI.FilterBlock = function()
  1983. {
  1984.     this.visible = true;
  1985.     this.renderable = true;
  1986. }
  1987. /**
  1988.  * @author Mat Groves http://matgroves.com/ @Doormat23
  1989.  */
  1990.  
  1991. /**
  1992.  * A Text Object will create a line(s) of text to split a line you can use "\n"
  1993.  *
  1994.  * @class Text
  1995.  * @extends Sprite
  1996.  * @constructor
  1997.  * @param text {String} The copy that you would like the text to display
  1998.  * @param [style] {Object} The style parameters
  1999.  * @param [style.font] {String} default "bold 20pt Arial" The style and size of the font
  2000.  * @param [style.fill="black"] {Object} A canvas fillstyle that will be used on the text eg "red", "#00FF00"
  2001.  * @param [style.align="left"] {String} An alignment of the multiline text ("left", "center" or "right")
  2002.  * @param [style.stroke] {String} A canvas fillstyle that will be used on the text stroke eg "blue", "#FCFF00"
  2003.  * @param [style.strokeThickness=0] {Number} A number that represents the thickness of the stroke. Default is 0 (no stroke)
  2004.  * @param [style.wordWrap=false] {Boolean} Indicates if word wrap should be used
  2005.  * @param [style.wordWrapWidth=100] {Number} The width at which text will wrap
  2006.  */
  2007. PIXI.Text = function(text, style)
  2008. {
  2009.     this.canvas = document.createElement("canvas");
  2010.     this.context = this.canvas.getContext("2d");
  2011.     PIXI.Sprite.call(this, PIXI.Texture.fromCanvas(this.canvas));
  2012.  
  2013.     this.setText(text);
  2014.     this.setStyle(style);
  2015.  
  2016.     this.updateText();
  2017.     this.dirty = false;
  2018. };
  2019.  
  2020. // constructor
  2021. PIXI.Text.prototype = Object.create(PIXI.Sprite.prototype);
  2022. PIXI.Text.prototype.constructor = PIXI.Text;
  2023.  
  2024. /**
  2025.  * Set the style of the text
  2026.  *
  2027.  * @method setStyle
  2028.  * @param [style] {Object} The style parameters
  2029.  * @param [style.font="bold 20pt Arial"] {String} The style and size of the font
  2030.  * @param [style.fill="black"] {Object} A canvas fillstyle that will be used on the text eg "red", "#00FF00"
  2031.  * @param [style.align="left"] {String} An alignment of the multiline text ("left", "center" or "right")
  2032.  * @param [style.stroke="black"] {String} A canvas fillstyle that will be used on the text stroke eg "blue", "#FCFF00"
  2033.  * @param [style.strokeThickness=0] {Number} A number that represents the thickness of the stroke. Default is 0 (no stroke)
  2034.  * @param [style.wordWrap=false] {Boolean} Indicates if word wrap should be used
  2035.  * @param [style.wordWrapWidth=100] {Number} The width at which text will wrap
  2036.  */
  2037. PIXI.Text.prototype.setStyle = function(style)
  2038. {
  2039.     style = style || {};
  2040.     style.font = style.font || "bold 20pt Arial";
  2041.     style.fill = style.fill || "black";
  2042.     style.align = style.align || "left";
  2043.     style.stroke = style.stroke || "black"; //provide a default, see: https://github.com/GoodBoyDigital/pixi.js/issues/136
  2044.     style.strokeThickness = style.strokeThickness || 0;
  2045.     style.wordWrap = style.wordWrap || false;
  2046.     style.wordWrapWidth = style.wordWrapWidth || 100;
  2047.     this.style = style;
  2048.     this.dirty = true;
  2049. };
  2050.  
  2051. /**
  2052.  * Set the copy for the text object. To split a line you can use "\n"
  2053.  *
  2054.  * @methos setText
  2055.  * @param {String} text The copy that you would like the text to display
  2056.  */
  2057. PIXI.Text.prototype.setText = function(text)
  2058. {
  2059.     this.text = text.toString() || " ";
  2060.     this.dirty = true;
  2061. };
  2062.  
  2063. /**
  2064.  * Renders text
  2065.  *
  2066.  * @method updateText
  2067.  * @private
  2068.  */
  2069. PIXI.Text.prototype.updateText = function()
  2070. {
  2071.     this.context.font = this.style.font;
  2072.  
  2073.     var outputText = this.text;
  2074.  
  2075.     // word wrap
  2076.     // preserve original text
  2077.     if(this.style.wordWrap)outputText = this.wordWrap(this.text);
  2078.  
  2079.     //split text into lines
  2080.     var lines = outputText.split(/(?:\r\n|\r|\n)/);
  2081.  
  2082.     //calculate text width
  2083.     var lineWidths = [];
  2084.     var maxLineWidth = 0;
  2085.     for (var i = 0; i < lines.length; i++)
  2086.     {
  2087.         var lineWidth = this.context.measureText(lines[i]).width;
  2088.         lineWidths[i] = lineWidth;
  2089.         maxLineWidth = Math.max(maxLineWidth, lineWidth);
  2090.     }
  2091.     this.canvas.width = maxLineWidth + this.style.strokeThickness;
  2092.  
  2093.     //calculate text height
  2094.     var lineHeight = this.determineFontHeight("font: " + this.style.font  + ";") + this.style.strokeThickness;
  2095.     this.canvas.height = lineHeight * lines.length;
  2096.  
  2097.     //set canvas text styles
  2098.     this.context.fillStyle = this.style.fill;
  2099.     this.context.font = this.style.font;
  2100.  
  2101.     this.context.strokeStyle = this.style.stroke;
  2102.     this.context.lineWidth = this.style.strokeThickness;
  2103.  
  2104.     this.context.textBaseline = "top";
  2105.  
  2106.     //draw lines line by line
  2107.     for (i = 0; i < lines.length; i++)
  2108.     {
  2109.         var linePosition = new PIXI.Point(this.style.strokeThickness / 2, this.style.strokeThickness / 2 + i * lineHeight);
  2110.  
  2111.         if(this.style.align == "right")
  2112.         {
  2113.             linePosition.x += maxLineWidth - lineWidths[i];
  2114.         }
  2115.         else if(this.style.align == "center")
  2116.         {
  2117.             linePosition.x += (maxLineWidth - lineWidths[i]) / 2;
  2118.         }
  2119.  
  2120.         if(this.style.stroke && this.style.strokeThickness)
  2121.         {
  2122.             this.context.strokeText(lines[i], linePosition.x, linePosition.y);
  2123.         }
  2124.  
  2125.         if(this.style.fill)
  2126.         {
  2127.             this.context.fillText(lines[i], linePosition.x, linePosition.y);
  2128.         }
  2129.     }
  2130.  
  2131.     this.updateTexture();
  2132. };
  2133.  
  2134. /**
  2135.  * Updates texture size based on canvas size
  2136.  *
  2137.  * @method updateTexture
  2138.  * @private
  2139.  */
  2140. PIXI.Text.prototype.updateTexture = function()
  2141. {
  2142.     this.texture.baseTexture.width = this.canvas.width;
  2143.     this.texture.baseTexture.height = this.canvas.height;
  2144.     this.texture.frame.width = this.canvas.width;
  2145.     this.texture.frame.height = this.canvas.height;
  2146.  
  2147.     this._width = this.canvas.width;
  2148.     this._height = this.canvas.height;
  2149.  
  2150.     PIXI.texturesToUpdate.push(this.texture.baseTexture);
  2151. };
  2152.  
  2153. /**
  2154.  * Updates the transfor of this object
  2155.  *
  2156.  * @method updateTransform
  2157.  * @private
  2158.  */
  2159. PIXI.Text.prototype.updateTransform = function()
  2160. {
  2161.     if(this.dirty)
  2162.     {
  2163.         this.updateText();
  2164.         this.dirty = false;
  2165.     }
  2166.  
  2167.     PIXI.Sprite.prototype.updateTransform.call(this);
  2168. };
  2169.  
  2170. /*
  2171.  * http://stackoverflow.com/users/34441/ellisbben
  2172.  * great solution to the problem!
  2173.  *
  2174.  * @method determineFontHeight
  2175.  * @param fontStyle {Object}
  2176.  * @private
  2177.  */
  2178. PIXI.Text.prototype.determineFontHeight = function(fontStyle)
  2179. {
  2180.     // build a little reference dictionary so if the font style has been used return a
  2181.     // cached version...
  2182.     var result = PIXI.Text.heightCache[fontStyle];
  2183.  
  2184.     if(!result)
  2185.     {
  2186.         var body = document.getElementsByTagName("body")[0];
  2187.         var dummy = document.createElement("div");
  2188.         var dummyText = document.createTextNode("M");
  2189.         dummy.appendChild(dummyText);
  2190.         dummy.setAttribute("style", fontStyle + ';position:absolute;top:0;left:0');
  2191.         body.appendChild(dummy);
  2192.  
  2193.         result = dummy.offsetHeight;
  2194.         PIXI.Text.heightCache[fontStyle] = result;
  2195.  
  2196.         body.removeChild(dummy);
  2197.     }
  2198.  
  2199.     return result;
  2200. };
  2201.  
  2202. /**
  2203.  * Applies newlines to a string to have it optimally fit into the horizontal
  2204.  * bounds set by the Text object's wordWrapWidth property.
  2205.  *
  2206.  * @method wordWrap
  2207.  * @param text {String}
  2208.  * @private
  2209.  */
  2210. PIXI.Text.prototype.wordWrap = function(text)
  2211. {
  2212.     // Greedy wrapping algorithm that will wrap words as the line grows longer
  2213.     // than its horizontal bounds.
  2214.     var result = "";
  2215.     var lines = text.split("\n");
  2216.     for (var i = 0; i < lines.length; i++)
  2217.     {
  2218.         var spaceLeft = this.style.wordWrapWidth;
  2219.         var words = lines[i].split(" ");
  2220.         for (var j = 0; j < words.length; j++)
  2221.         {
  2222.             var wordWidth = this.context.measureText(words[j]).width;
  2223.             var wordWidthWithSpace = wordWidth + this.context.measureText(" ").width;
  2224.             if(wordWidthWithSpace > spaceLeft)
  2225.             {
  2226.                 // Skip printing the newline if it's the first word of the line that is
  2227.                 // greater than the word wrap width.
  2228.                 if(j > 0)
  2229.                 {
  2230.                     result += "\n";
  2231.                 }
  2232.                 result += words[j] + " ";
  2233.                 spaceLeft = this.style.wordWrapWidth - wordWidth;
  2234.             }
  2235.             else
  2236.             {
  2237.                 spaceLeft -= wordWidthWithSpace;
  2238.                 result += words[j] + " ";
  2239.             }
  2240.         }
  2241.         result += "\n";
  2242.     }
  2243.     return result;
  2244. };
  2245.  
  2246. /**
  2247.  * Destroys this text object
  2248.  *
  2249.  * @method destroy
  2250.  * @param destroyTexture {Boolean}
  2251.  */
  2252. PIXI.Text.prototype.destroy = function(destroyTexture)
  2253. {
  2254.     if(destroyTexture)
  2255.     {
  2256.         this.texture.destroy();
  2257.     }
  2258.  
  2259. };
  2260.  
  2261. PIXI.Text.heightCache = {};
  2262.  
  2263. /**
  2264.  * @author Mat Groves http://matgroves.com/ @Doormat23
  2265.  */
  2266.  
  2267. /**
  2268.  * A Text Object will create a line(s) of text using bitmap font. To split a line you can use "\n", "\r" or "\r\n"
  2269.  * You can generate the fnt files using
  2270.  * http://www.angelcode.com/products/bmfont/ for windows or
  2271.  * http://www.bmglyph.com/ for mac.
  2272.  *
  2273.  * @class BitmapText
  2274.  * @extends DisplayObjectContainer
  2275.  * @constructor
  2276.  * @param text {String} The copy that you would like the text to display
  2277.  * @param style {Object} The style parameters
  2278.  * @param style.font {String} The size (optional) and bitmap font id (required) eq "Arial" or "20px Arial" (must have loaded previously)
  2279.  * @param [style.align="left"] {String} An alignment of the multiline text ("left", "center" or "right")
  2280.  */
  2281. PIXI.BitmapText = function(text, style)
  2282. {
  2283.     PIXI.DisplayObjectContainer.call(this);
  2284.  
  2285.     this.setText(text);
  2286.     this.setStyle(style);
  2287.     this.updateText();
  2288.     this.dirty = false
  2289.  
  2290. };
  2291.  
  2292. // constructor
  2293. PIXI.BitmapText.prototype = Object.create(PIXI.DisplayObjectContainer.prototype);
  2294. PIXI.BitmapText.prototype.constructor = PIXI.BitmapText;
  2295.  
  2296. /**
  2297.  * Set the copy for the text object
  2298.  *
  2299.  * @method setText
  2300.  * @param text {String} The copy that you would like the text to display
  2301.  */
  2302. PIXI.BitmapText.prototype.setText = function(text)
  2303. {
  2304.     this.text = text || " ";
  2305.     this.dirty = true;
  2306. };
  2307.  
  2308. /**
  2309.  * Set the style of the text
  2310.  *
  2311.  * @method setStyle
  2312.  * @param style {Object} The style parameters
  2313.  * @param style.font {String} The size (optional) and bitmap font id (required) eq "Arial" or "20px Arial" (must have loaded previously)
  2314.  * @param [style.align="left"] {String} An alignment of the multiline text ("left", "center" or "right")
  2315.  */
  2316. PIXI.BitmapText.prototype.setStyle = function(style)
  2317. {
  2318.     style = style || {};
  2319.     style.align = style.align || "left";
  2320.     this.style = style;
  2321.  
  2322.     var font = style.font.split(" ");
  2323.     this.fontName = font[font.length - 1];
  2324.     this.fontSize = font.length >= 2 ? parseInt(font[font.length - 2], 10) : PIXI.BitmapText.fonts[this.fontName].size;
  2325.  
  2326.     this.dirty = true;
  2327. };
  2328.  
  2329. /**
  2330.  * Renders text
  2331.  *
  2332.  * @method updateText
  2333.  * @private
  2334.  */
  2335. PIXI.BitmapText.prototype.updateText = function()
  2336. {
  2337.     var data = PIXI.BitmapText.fonts[this.fontName];
  2338.     var pos = new PIXI.Point();
  2339.     var prevCharCode = null;
  2340.     var chars = [];
  2341.     var maxLineWidth = 0;
  2342.     var lineWidths = [];
  2343.     var line = 0;
  2344.     var scale = this.fontSize / data.size;
  2345.     for(var i = 0; i < this.text.length; i++)
  2346.     {
  2347.         var charCode = this.text.charCodeAt(i);
  2348.         if(/(?:\r\n|\r|\n)/.test(this.text.charAt(i)))
  2349.         {
  2350.             lineWidths.push(pos.x);
  2351.             maxLineWidth = Math.max(maxLineWidth, pos.x);
  2352.             line++;
  2353.  
  2354.             pos.x = 0;
  2355.             pos.y += data.lineHeight;
  2356.             prevCharCode = null;
  2357.             continue;
  2358.         }
  2359.  
  2360.         var charData = data.chars[charCode];
  2361.         if(!charData) continue;
  2362.  
  2363.         if(prevCharCode && charData[prevCharCode])
  2364.         {
  2365.            pos.x += charData.kerning[prevCharCode];
  2366.         }
  2367.         chars.push({texture:charData.texture, line: line, charCode: charCode, position: new PIXI.Point(pos.x + charData.xOffset, pos.y + charData.yOffset)});
  2368.         pos.x += charData.xAdvance;
  2369.  
  2370.         prevCharCode = charCode;
  2371.     }
  2372.  
  2373.     lineWidths.push(pos.x);
  2374.     maxLineWidth = Math.max(maxLineWidth, pos.x);
  2375.  
  2376.     var lineAlignOffsets = [];
  2377.     for(i = 0; i <= line; i++)
  2378.     {
  2379.         var alignOffset = 0;
  2380.         if(this.style.align == "right")
  2381.         {
  2382.             alignOffset = maxLineWidth - lineWidths[i];
  2383.         }
  2384.         else if(this.style.align == "center")
  2385.         {
  2386.             alignOffset = (maxLineWidth - lineWidths[i]) / 2;
  2387.         }
  2388.         lineAlignOffsets.push(alignOffset);
  2389.     }
  2390.  
  2391.     for(i = 0; i < chars.length; i++)
  2392.     {
  2393.         var c = new PIXI.Sprite(chars[i].texture)//PIXI.Sprite.fromFrame(chars[i].charCode);
  2394.         c.position.x = (chars[i].position.x + lineAlignOffsets[chars[i].line]) * scale;
  2395.         c.position.y = chars[i].position.y * scale;
  2396.         c.scale.x = c.scale.y = scale;
  2397.         this.addChild(c);
  2398.     }
  2399.  
  2400.     this.width = pos.x * scale;
  2401.     this.height = (pos.y + data.lineHeight) * scale;
  2402. };
  2403.  
  2404. /**
  2405.  * Updates the transfor of this object
  2406.  *
  2407.  * @method updateTransform
  2408.  * @private
  2409.  */
  2410. PIXI.BitmapText.prototype.updateTransform = function()
  2411. {
  2412.     if(this.dirty)
  2413.     {
  2414.         while(this.children.length > 0)
  2415.         {
  2416.             this.removeChild(this.getChildAt(0));
  2417.         }
  2418.         this.updateText();
  2419.  
  2420.         this.dirty = false;
  2421.     }
  2422.  
  2423.     PIXI.DisplayObjectContainer.prototype.updateTransform.call(this);
  2424. };
  2425.  
  2426. PIXI.BitmapText.fonts = {};
  2427.  
  2428. /**
  2429.  * @author Mat Groves http://matgroves.com/ @Doormat23
  2430.  */
  2431.  
  2432.  /**
  2433.  * The interaction manager deals with mouse and touch events. Any DisplayObject can be interactive
  2434.  * This manager also supports multitouch.
  2435.  *
  2436.  * @class InteractionManager
  2437.  * @constructor
  2438.  * @param stage {Stage} The stage to handle interactions
  2439.  */
  2440. PIXI.InteractionManager = function(stage)
  2441. {
  2442.     /**
  2443.      * a refference to the stage
  2444.      *
  2445.      * @property stage
  2446.      * @type Stage
  2447.      */
  2448.     this.stage = stage;
  2449.  
  2450.     /**
  2451.      * the mouse data
  2452.      *
  2453.      * @property mouse
  2454.      * @type InteractionData
  2455.      */
  2456.     this.mouse = new PIXI.InteractionData();
  2457.  
  2458.     /**
  2459.      * an object that stores current touches (InteractionData) by id reference
  2460.      *
  2461.      * @property touchs
  2462.      * @type Object
  2463.      */
  2464.     this.touchs = {};
  2465.  
  2466.  
  2467.    
  2468.     // helpers
  2469.     this.tempPoint = new PIXI.Point();
  2470.     //this.tempMatrix =  mat3.create();
  2471.  
  2472.     this.mouseoverEnabled = true;
  2473.  
  2474.     //tiny little interactiveData pool!
  2475.     this.pool = [];
  2476.  
  2477.     this.interactiveItems = [];
  2478.     this.interactionDOMElement = null;
  2479.  
  2480.     //this will make it so that you dont have to call bind all the time
  2481.     this.onMouseMove = this.onMouseMove.bind( this );
  2482.     this.onMouseDown = this.onMouseDown.bind(this);
  2483.     this.onMouseOut = this.onMouseOut.bind(this);
  2484.     this.onMouseUp = this.onMouseUp.bind(this);
  2485.  
  2486.     this.onTouchStart = this.onTouchStart.bind(this);
  2487.     this.onTouchEnd = this.onTouchEnd.bind(this);
  2488.     this.onTouchMove = this.onTouchMove.bind(this);
  2489.    
  2490.    
  2491.     this.last = 0;
  2492. }
  2493.  
  2494. // constructor
  2495. PIXI.InteractionManager.prototype.constructor = PIXI.InteractionManager;
  2496.  
  2497. /**
  2498.  * Collects an interactive sprite recursively to have their interactions managed
  2499.  *
  2500.  * @method collectInteractiveSprite
  2501.  * @param displayObject {DisplayObject} the displayObject to collect
  2502.  * @param iParent {DisplayObject}
  2503.  * @private
  2504.  */
  2505. PIXI.InteractionManager.prototype.collectInteractiveSprite = function(displayObject, iParent)
  2506. {
  2507.     var children = displayObject.children;
  2508.     var length = children.length;
  2509.    
  2510.     /// make an interaction tree... {item.__interactiveParent}
  2511.     for (var i = length-1; i >= 0; i--)
  2512.     {
  2513.         var child = children[i];
  2514.        
  2515. //      if(child.visible) {
  2516.             // push all interactive bits
  2517.             if(child.interactive)
  2518.             {
  2519.                 iParent.interactiveChildren = true;
  2520.                 //child.__iParent = iParent;
  2521.                 this.interactiveItems.push(child);
  2522.  
  2523.                 if(child.children.length > 0)
  2524.                 {
  2525.                     this.collectInteractiveSprite(child, child);
  2526.                 }
  2527.             }
  2528.             else
  2529.             {
  2530.                 child.__iParent = null;
  2531.  
  2532.                 if(child.children.length > 0)
  2533.                 {
  2534.                     this.collectInteractiveSprite(child, iParent);
  2535.                 }
  2536.             }
  2537. //      }
  2538.     }
  2539. }
  2540.  
  2541. /**
  2542.  * Sets the target for event delegation
  2543.  *
  2544.  * @method setTarget
  2545.  * @param target {WebGLRenderer|CanvasRenderer} the renderer to bind events to
  2546.  * @private
  2547.  */
  2548. PIXI.InteractionManager.prototype.setTarget = function(target)
  2549. {
  2550.     this.target = target;
  2551.  
  2552.     //check if the dom element has been set. If it has don't do anything
  2553.     if( this.interactionDOMElement === null ) {
  2554.  
  2555.         this.setTargetDomElement( target.view );
  2556.     }
  2557.  
  2558.     document.body.addEventListener('mouseup',  this.onMouseUp, true);
  2559. }
  2560.  
  2561.  
  2562. /**
  2563.  * Sets the dom element which will receive mouse/touch events. This is useful for when you have other DOM
  2564.  * elements ontop of the renderers Canvas element. With this you'll be able to delegate another dom element
  2565.  * to receive those events
  2566.  *
  2567.  * @method setTargetDomElement
  2568.  * @param domElement {DOMElement} the dom element which will receive mouse and touch events
  2569.  * @private
  2570.  */
  2571. PIXI.InteractionManager.prototype.setTargetDomElement = function(domElement)
  2572. {
  2573.     //remove previouse listeners
  2574.     if( this.interactionDOMElement !== null )
  2575.     {
  2576.         this.interactionDOMElement.style['-ms-content-zooming'] = '';
  2577.         this.interactionDOMElement.style['-ms-touch-action'] = '';
  2578.  
  2579.         this.interactionDOMElement.removeEventListener('mousemove',  this.onMouseMove, true);
  2580.         this.interactionDOMElement.removeEventListener('mousedown',  this.onMouseDown, true);
  2581.         this.interactionDOMElement.removeEventListener('mouseout',   this.onMouseOut, true);
  2582.  
  2583.         // aint no multi touch just yet!
  2584.         this.interactionDOMElement.removeEventListener('touchstart', this.onTouchStart, true);
  2585.         this.interactionDOMElement.removeEventListener('touchend', this.onTouchEnd, true);
  2586.         this.interactionDOMElement.removeEventListener('touchmove', this.onTouchMove, true);
  2587.     }
  2588.  
  2589.  
  2590.     if (window.navigator.msPointerEnabled)
  2591.     {
  2592.         // time to remove some of that zoom in ja..
  2593.         domElement.style['-ms-content-zooming'] = 'none';
  2594.         domElement.style['-ms-touch-action'] = 'none';
  2595.    
  2596.         // DO some window specific touch!
  2597.     }
  2598.  
  2599.     this.interactionDOMElement = domElement;
  2600.  
  2601.     domElement.addEventListener('mousemove',  this.onMouseMove, true);
  2602.     domElement.addEventListener('mousedown',  this.onMouseDown, true);
  2603.     domElement.addEventListener('mouseout',   this.onMouseOut, true);
  2604.  
  2605.     // aint no multi touch just yet!
  2606.     domElement.addEventListener('touchstart', this.onTouchStart, true);
  2607.     domElement.addEventListener('touchend', this.onTouchEnd, true);
  2608.     domElement.addEventListener('touchmove', this.onTouchMove, true);
  2609. }
  2610.  
  2611.  
  2612. /**
  2613.  * updates the state of interactive objects
  2614.  *
  2615.  * @method update
  2616.  * @private
  2617.  */
  2618. PIXI.InteractionManager.prototype.update = function()
  2619. {
  2620.     if(!this.target)return;
  2621.    
  2622.     // frequency of 30fps??
  2623.     var now = Date.now();
  2624.     var diff = now - this.last;
  2625.     diff = (diff * 30) / 1000;
  2626.     if(diff < 1)return;
  2627.     this.last = now;
  2628.     //
  2629.    
  2630.     // ok.. so mouse events??
  2631.     // yes for now :)
  2632.     // OPTIMSE - how often to check??
  2633.     if(this.dirty)
  2634.     {
  2635.         this.dirty = false;
  2636.        
  2637.         var len = this.interactiveItems.length;
  2638.        
  2639.         for (var i=0; i < len; i++) {
  2640.           this.interactiveItems[i].interactiveChildren = false;
  2641.         }
  2642.        
  2643.         this.interactiveItems = [];
  2644.        
  2645.         if(this.stage.interactive)this.interactiveItems.push(this.stage);
  2646.         // go through and collect all the objects that are interactive..
  2647.         this.collectInteractiveSprite(this.stage, this.stage);
  2648.     }
  2649.    
  2650.     // loop through interactive objects!
  2651.     var length = this.interactiveItems.length;
  2652.    
  2653.     this.interactionDOMElement.style.cursor = "default";   
  2654.                
  2655.     for (var i = 0; i < length; i++)
  2656.     {
  2657.         var item = this.interactiveItems[i];
  2658.        
  2659.        
  2660.         //if(!item.visible)continue;
  2661.        
  2662.         // OPTIMISATION - only calculate every time if the mousemove function exists..
  2663.         // OK so.. does the object have any other interactive functions?
  2664.         // hit-test the clip!
  2665.        
  2666.        
  2667.         if(item.mouseover || item.mouseout || item.buttonMode)
  2668.         {
  2669.             // ok so there are some functions so lets hit test it..
  2670.             item.__hit = this.hitTest(item, this.mouse);
  2671.             this.mouse.target = item;
  2672.             // ok so deal with interactions..
  2673.             // loks like there was a hit!
  2674.             if(item.__hit)
  2675.             {
  2676.                 if(item.buttonMode) this.interactionDOMElement.style.cursor = "pointer";   
  2677.                
  2678.                 if(!item.__isOver)
  2679.                 {
  2680.                    
  2681.                     if(item.mouseover)item.mouseover(this.mouse);
  2682.                     item.__isOver = true;  
  2683.                 }
  2684.             }
  2685.             else
  2686.             {
  2687.                 if(item.__isOver)
  2688.                 {
  2689.                     // roll out!
  2690.                     if(item.mouseout)item.mouseout(this.mouse);
  2691.                     item.__isOver = false; 
  2692.                 }
  2693.             }
  2694.         }
  2695.        
  2696.         // --->
  2697.     }
  2698. }
  2699.  
  2700. /**
  2701.  * Is called when the mouse moves accross the renderer element
  2702.  *
  2703.  * @method onMouseMove
  2704.  * @param event {Event} The DOM event of the mouse moving
  2705.  * @private
  2706.  */
  2707. PIXI.InteractionManager.prototype.onMouseMove = function(event)
  2708. {
  2709.     this.mouse.originalEvent = event || window.event; //IE uses window.event
  2710.     // TODO optimize by not check EVERY TIME! maybe half as often? //
  2711.     var rect = this.interactionDOMElement.getBoundingClientRect();
  2712.    
  2713.     this.mouse.global.x = (event.clientX - rect.left) * (this.target.width / rect.width);
  2714.     this.mouse.global.y = (event.clientY - rect.top) * ( this.target.height / rect.height);
  2715.    
  2716.     var length = this.interactiveItems.length;
  2717.     var global = this.mouse.global;
  2718.    
  2719.    
  2720.     for (var i = 0; i < length; i++)
  2721.     {
  2722.         var item = this.interactiveItems[i];
  2723.        
  2724.         if(item.mousemove)
  2725.         {
  2726.             //call the function!
  2727.             item.mousemove(this.mouse);
  2728.         }
  2729.     }
  2730. }
  2731.  
  2732. /**
  2733.  * Is called when the mouse button is pressed down on the renderer element
  2734.  *
  2735.  * @method onMouseDown
  2736.  * @param event {Event} The DOM event of a mouse button being pressed down
  2737.  * @private
  2738.  */
  2739. PIXI.InteractionManager.prototype.onMouseDown = function(event)
  2740. {
  2741.     this.mouse.originalEvent = event || window.event; //IE uses window.event
  2742.    
  2743.     // loop through inteaction tree...
  2744.     // hit test each item! ->
  2745.     // get interactive items under point??
  2746.     //stage.__i
  2747.     var length = this.interactiveItems.length;
  2748.     var global = this.mouse.global;
  2749.    
  2750.     var index = 0;
  2751.     var parent = this.stage;
  2752.    
  2753.     // while
  2754.     // hit test
  2755.     for (var i = 0; i < length; i++)
  2756.     {
  2757.         var item = this.interactiveItems[i];
  2758.        
  2759.         if(item.mousedown || item.click)
  2760.         {
  2761.             item.__mouseIsDown = true;
  2762.             item.__hit = this.hitTest(item, this.mouse);
  2763.            
  2764.             if(item.__hit)
  2765.             {
  2766.                 //call the function!
  2767.                 if(item.mousedown)item.mousedown(this.mouse);
  2768.                 item.__isDown = true;
  2769.                
  2770.                 // just the one!
  2771.                 if(!item.interactiveChildren)break;
  2772.             }
  2773.         }
  2774.     }
  2775. }
  2776.  
  2777.  
  2778. PIXI.InteractionManager.prototype.onMouseOut = function(event)
  2779. {
  2780.     var length = this.interactiveItems.length;
  2781.    
  2782.     this.interactionDOMElement.style.cursor = "default";   
  2783.                
  2784.     for (var i = 0; i < length; i++)
  2785.     {
  2786.         var item = this.interactiveItems[i];
  2787.        
  2788.         if(item.__isOver)
  2789.         {
  2790.             this.mouse.target = item;
  2791.             if(item.mouseout)item.mouseout(this.mouse);
  2792.             item.__isOver = false; 
  2793.         }
  2794.     }
  2795. }
  2796.  
  2797. /**
  2798.  * Is called when the mouse button is released on the renderer element
  2799.  *
  2800.  * @method onMouseUp
  2801.  * @param event {Event} The DOM event of a mouse button being released
  2802.  * @private
  2803.  */
  2804. PIXI.InteractionManager.prototype.onMouseUp = function(event)
  2805. {
  2806.     this.mouse.originalEvent = event || window.event; //IE uses window.event
  2807.    
  2808.     var global = this.mouse.global;
  2809.    
  2810.    
  2811.     var length = this.interactiveItems.length;
  2812.     var up = false;
  2813.    
  2814.     for (var i = 0; i < length; i++)
  2815.     {
  2816.         var item = this.interactiveItems[i];
  2817.        
  2818.         if(item.mouseup || item.mouseupoutside || item.click)
  2819.         {
  2820.             item.__hit = this.hitTest(item, this.mouse);
  2821.            
  2822.             if(item.__hit && !up)
  2823.             {
  2824.                 //call the function!
  2825.                 if(item.mouseup)
  2826.                 {
  2827.                     item.mouseup(this.mouse);
  2828.                 }
  2829.                 if(item.__isDown)
  2830.                 {
  2831.                     if(item.click)item.click(this.mouse);
  2832.                 }
  2833.                
  2834.                 if(!item.interactiveChildren)up = true;
  2835.             }
  2836.             else
  2837.             {
  2838.                 if(item.__isDown)
  2839.                 {
  2840.                     if(item.mouseupoutside)item.mouseupoutside(this.mouse);
  2841.                 }
  2842.             }
  2843.        
  2844.             item.__isDown = false; 
  2845.         }
  2846.     }
  2847. }
  2848.  
  2849. /**
  2850.  * Tests if the current mouse coords hit a sprite
  2851.  *
  2852.  * @method hitTest
  2853.  * @param item {DisplayObject} The displayObject to test for a hit
  2854.  * @param interactionData {InteractionData} The interactiondata object to update in the case of a hit
  2855.  * @private
  2856.  */
  2857. PIXI.InteractionManager.prototype.hitTest = function(item, interactionData)
  2858. {
  2859.     var global = interactionData.global;
  2860.    
  2861.     if(item.vcount !== PIXI.visibleCount)return false;
  2862.  
  2863.     var isSprite = (item instanceof PIXI.Sprite),
  2864.         worldTransform = item.worldTransform,
  2865.         a00 = worldTransform[0], a01 = worldTransform[1], a02 = worldTransform[2],
  2866.         a10 = worldTransform[3], a11 = worldTransform[4], a12 = worldTransform[5],
  2867.         id = 1 / (a00 * a11 + a01 * -a10),
  2868.         x = a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id,
  2869.         y = a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id;
  2870.  
  2871.     interactionData.target = item;
  2872.    
  2873.     //a sprite or display object with a hit area defined
  2874.     if(item.hitArea && item.hitArea.contains) {
  2875.         if(item.hitArea.contains(x, y)) {
  2876.             //if(isSprite)
  2877.             interactionData.target = item;
  2878.  
  2879.             return true;
  2880.         }
  2881.        
  2882.         return false;
  2883.     }
  2884.     // a sprite with no hitarea defined
  2885.     else if(isSprite)
  2886.     {
  2887.         var width = item.texture.frame.width,
  2888.             height = item.texture.frame.height,
  2889.             x1 = -width * item.anchor.x,
  2890.             y1;
  2891.        
  2892.         if(x > x1 && x < x1 + width)
  2893.         {
  2894.             y1 = -height * item.anchor.y;
  2895.        
  2896.             if(y > y1 && y < y1 + height)
  2897.             {
  2898.                 // set the target property if a hit is true!
  2899.                 interactionData.target = item
  2900.                 return true;
  2901.             }
  2902.         }
  2903.     }
  2904.  
  2905.     var length = item.children.length;
  2906.    
  2907.     for (var i = 0; i < length; i++)
  2908.     {
  2909.         var tempItem = item.children[i];
  2910.         var hit = this.hitTest(tempItem, interactionData);
  2911.         if(hit)
  2912.         {
  2913.             // hmm.. TODO SET CORRECT TARGET?
  2914.             interactionData.target = item
  2915.             return true;
  2916.         }
  2917.     }
  2918.  
  2919.     return false;  
  2920. }
  2921.  
  2922. /**
  2923.  * Is called when a touch is moved accross the renderer element
  2924.  *
  2925.  * @method onTouchMove
  2926.  * @param event {Event} The DOM event of a touch moving accross the renderer view
  2927.  * @private
  2928.  */
  2929. PIXI.InteractionManager.prototype.onTouchMove = function(event)
  2930. {
  2931.     var rect = this.interactionDOMElement.getBoundingClientRect();
  2932.     var changedTouches = event.changedTouches;
  2933.    
  2934.     for (var i=0; i < changedTouches.length; i++)
  2935.     {
  2936.         var touchEvent = changedTouches[i];
  2937.         var touchData = this.touchs[touchEvent.identifier];
  2938.         touchData.originalEvent =  event || window.event;
  2939.        
  2940.         // update the touch position
  2941.         touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width);
  2942.         touchData.global.y = (touchEvent.clientY - rect.top)  * (this.target.height / rect.height);
  2943.     }
  2944.    
  2945.     var length = this.interactiveItems.length;
  2946.     for (var i = 0; i < length; i++)
  2947.     {
  2948.         var item = this.interactiveItems[i];
  2949.         if(item.touchmove)item.touchmove(touchData);
  2950.     }
  2951. }
  2952.  
  2953. /**
  2954.  * Is called when a touch is started on the renderer element
  2955.  *
  2956.  * @method onTouchStart
  2957.  * @param event {Event} The DOM event of a touch starting on the renderer view
  2958.  * @private
  2959.  */
  2960. PIXI.InteractionManager.prototype.onTouchStart = function(event)
  2961. {
  2962.     var rect = this.interactionDOMElement.getBoundingClientRect();
  2963.    
  2964.     var changedTouches = event.changedTouches;
  2965.     for (var i=0; i < changedTouches.length; i++)
  2966.     {
  2967.         var touchEvent = changedTouches[i];
  2968.        
  2969.         var touchData = this.pool.pop();
  2970.         if(!touchData)touchData = new PIXI.InteractionData();
  2971.        
  2972.         touchData.originalEvent =  event || window.event;
  2973.        
  2974.         this.touchs[touchEvent.identifier] = touchData;
  2975.         touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width);
  2976.         touchData.global.y = (touchEvent.clientY - rect.top)  * (this.target.height / rect.height);
  2977.        
  2978.         var length = this.interactiveItems.length;
  2979.        
  2980.         for (var j = 0; j < length; j++)
  2981.         {
  2982.             var item = this.interactiveItems[j];
  2983.            
  2984.             if(item.touchstart || item.tap)
  2985.             {
  2986.                 item.__hit = this.hitTest(item, touchData);
  2987.                
  2988.                 if(item.__hit)
  2989.                 {
  2990.                     //call the function!
  2991.                     if(item.touchstart)item.touchstart(touchData);
  2992.                     item.__isDown = true;
  2993.                     item.__touchData = touchData;
  2994.                    
  2995.                     if(!item.interactiveChildren)break;
  2996.                 }
  2997.             }
  2998.         }
  2999.     }
  3000. }
  3001.  
  3002. /**
  3003.  * Is called when a touch is ended on the renderer element
  3004.  *
  3005.  * @method onTouchEnd
  3006.  * @param event {Event} The DOM event of a touch ending on the renderer view
  3007.  * @private
  3008.  */
  3009. PIXI.InteractionManager.prototype.onTouchEnd = function(event)
  3010. {
  3011.     //this.mouse.originalEvent = event || window.event; //IE uses window.event
  3012.     var rect = this.interactionDOMElement.getBoundingClientRect();
  3013.     var changedTouches = event.changedTouches;
  3014.    
  3015.     for (var i=0; i < changedTouches.length; i++)
  3016.     {
  3017.         var touchEvent = changedTouches[i];
  3018.         var touchData = this.touchs[touchEvent.identifier];
  3019.         var up = false;
  3020.         touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width);
  3021.         touchData.global.y = (touchEvent.clientY - rect.top)  * (this.target.height / rect.height);
  3022.        
  3023.         var length = this.interactiveItems.length;
  3024.         for (var j = 0; j < length; j++)
  3025.         {
  3026.             var item = this.interactiveItems[j];
  3027.             var itemTouchData = item.__touchData; // <-- Here!
  3028.             item.__hit = this.hitTest(item, touchData);
  3029.        
  3030.             if(itemTouchData == touchData)
  3031.             {
  3032.                 // so this one WAS down...
  3033.                 touchData.originalEvent =  event || window.event;
  3034.                 // hitTest??
  3035.                
  3036.                 if(item.touchend || item.tap)
  3037.                 {
  3038.                     if(item.__hit && !up)
  3039.                     {
  3040.                         if(item.touchend)item.touchend(touchData);
  3041.                         if(item.__isDown)
  3042.                         {
  3043.                             if(item.tap)item.tap(touchData);
  3044.                         }
  3045.                        
  3046.                         if(!item.interactiveChildren)up = true;
  3047.                     }
  3048.                     else
  3049.                     {
  3050.                         if(item.__isDown)
  3051.                         {
  3052.                             if(item.touchendoutside)item.touchendoutside(touchData);
  3053.                         }
  3054.                     }
  3055.                    
  3056.                     item.__isDown = false;
  3057.                 }
  3058.                
  3059.                 item.__touchData = null;
  3060.                    
  3061.             }
  3062.             else
  3063.             {
  3064.                
  3065.             }
  3066.         }
  3067.         // remove the touch..
  3068.         this.pool.push(touchData);
  3069.         this.touchs[touchEvent.identifier] = null;
  3070.     }
  3071. }
  3072.  
  3073. /**
  3074.  * Holds all information related to an Interaction event
  3075.  *
  3076.  * @class InteractionData
  3077.  * @constructor
  3078.  */
  3079. PIXI.InteractionData = function()
  3080. {
  3081.     /**
  3082.      * This point stores the global coords of where the touch/mouse event happened
  3083.      *
  3084.      * @property global
  3085.      * @type Point
  3086.      */
  3087.     this.global = new PIXI.Point();
  3088.    
  3089.     // this is here for legacy... but will remove
  3090.     this.local = new PIXI.Point();
  3091.  
  3092.     /**
  3093.      * The target Sprite that was interacted with
  3094.      *
  3095.      * @property target
  3096.      * @type Sprite
  3097.      */
  3098.     this.target;
  3099.  
  3100.     /**
  3101.      * When passed to an event handler, this will be the original DOM Event that was captured
  3102.      *
  3103.      * @property originalEvent
  3104.      * @type Event
  3105.      */
  3106.     this.originalEvent;
  3107. }
  3108.  
  3109. /**
  3110.  * This will return the local coords of the specified displayObject for this InteractionData
  3111.  *
  3112.  * @method getLocalPosition
  3113.  * @param displayObject {DisplayObject} The DisplayObject that you would like the local coords off
  3114.  * @return {Point} A point containing the coords of the InteractionData position relative to the DisplayObject
  3115.  */
  3116. PIXI.InteractionData.prototype.getLocalPosition = function(displayObject)
  3117. {
  3118.     var worldTransform = displayObject.worldTransform;
  3119.     var global = this.global;
  3120.    
  3121.     // do a cheeky transform to get the mouse coords;
  3122.     var a00 = worldTransform[0], a01 = worldTransform[1], a02 = worldTransform[2],
  3123.         a10 = worldTransform[3], a11 = worldTransform[4], a12 = worldTransform[5],
  3124.         id = 1 / (a00 * a11 + a01 * -a10);
  3125.     // set the mouse coords...
  3126.     return new PIXI.Point(a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id,
  3127.                                a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id)
  3128. }
  3129.  
  3130. // constructor
  3131. PIXI.InteractionData.prototype.constructor = PIXI.InteractionData;
  3132.  
  3133. /**
  3134.  * @author Mat Groves http://matgroves.com/ @Doormat23
  3135.  */
  3136.  
  3137. /**
  3138.  * A Stage represents the root of the display tree. Everything connected to the stage is rendered
  3139.  *
  3140.  * @class Stage
  3141.  * @extends DisplayObjectContainer
  3142.  * @constructor
  3143.  * @param backgroundColor {Number} the background color of the stage, easiest way to pass this in is in hex format
  3144.  *      like: 0xFFFFFF for white
  3145.  */
  3146. PIXI.Stage = function(backgroundColor)
  3147. {
  3148.     PIXI.DisplayObjectContainer.call( this );
  3149.  
  3150.     /**
  3151.      * [read-only] Current transform of the object based on world (parent) factors
  3152.      *
  3153.      * @property worldTransform
  3154.      * @type Mat3
  3155.      * @readOnly
  3156.      * @private
  3157.      */
  3158.     this.worldTransform = PIXI.mat3.create();
  3159.  
  3160.     /**
  3161.      * Whether or not the stage is interactive
  3162.      *
  3163.      * @property interactive
  3164.      * @type Boolean
  3165.      */
  3166.     this.interactive = true;
  3167.  
  3168.     /**
  3169.      * The interaction manage for this stage, manages all interactive activity on the stage
  3170.      *
  3171.      * @property interactive
  3172.      * @type InteractionManager
  3173.      */
  3174.     this.interactionManager = new PIXI.InteractionManager(this);
  3175.  
  3176.     /**
  3177.      * Whether the stage is dirty and needs to have interactions updated
  3178.      *
  3179.      * @property dirty
  3180.      * @type Boolean
  3181.      * @private
  3182.      */
  3183.     this.dirty = true;
  3184.  
  3185.     this.__childrenAdded = [];
  3186.     this.__childrenRemoved = [];
  3187.  
  3188.     //the stage is it's own stage
  3189.     this.stage = this;
  3190.  
  3191.     //optimize hit detection a bit
  3192.     this.stage.hitArea = new PIXI.Rectangle(0,0,100000, 100000);
  3193.  
  3194.     this.setBackgroundColor(backgroundColor);
  3195.     this.worldVisible = true;
  3196. }
  3197.  
  3198. // constructor
  3199. PIXI.Stage.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
  3200. PIXI.Stage.prototype.constructor = PIXI.Stage;
  3201.  
  3202. /**
  3203.  * Sets another DOM element which can receive mouse/touch interactions instead of the default Canvas element.
  3204.  * This is useful for when you have other DOM elements ontop of the Canvas element.
  3205.  *
  3206.  * @method setInteractionDelegate
  3207.  * @param domElement {DOMElement} This new domElement which will receive mouse/touch events
  3208.  */
  3209. PIXI.Stage.prototype.setInteractionDelegate = function(domElement)
  3210. {
  3211.     this.interactionManager.setTargetDomElement( domElement );
  3212. }
  3213.  
  3214. /*
  3215.  * Updates the object transform for rendering
  3216.  *
  3217.  * @method updateTransform
  3218.  * @private
  3219.  */
  3220. PIXI.Stage.prototype.updateTransform = function()
  3221. {
  3222.     this.worldAlpha = 1;       
  3223.     this.vcount = PIXI.visibleCount;
  3224.    
  3225.     for(var i=0,j=this.children.length; i<j; i++)
  3226.     {
  3227.         this.children[i].updateTransform();
  3228.     }
  3229.    
  3230.     if(this.dirty)
  3231.     {
  3232.         this.dirty = false;
  3233.         // update interactive!
  3234.         this.interactionManager.dirty = true;
  3235.     }
  3236.    
  3237.    
  3238.     if(this.interactive)this.interactionManager.update();
  3239. }
  3240.  
  3241. /**
  3242.  * Sets the background color for the stage
  3243.  *
  3244.  * @method setBackgroundColor
  3245.  * @param backgroundColor {Number} the color of the background, easiest way to pass this in is in hex format
  3246.  *      like: 0xFFFFFF for white
  3247.  */
  3248. PIXI.Stage.prototype.setBackgroundColor = function(backgroundColor)
  3249. {
  3250.     this.backgroundColor = backgroundColor || 0x000000;
  3251.     this.backgroundColorSplit = HEXtoRGB(this.backgroundColor);
  3252.     var hex = this.backgroundColor.toString(16);
  3253.     hex = "000000".substr(0, 6 - hex.length) + hex;
  3254.     this.backgroundColorString = "#" + hex;
  3255. }
  3256.  
  3257. /**
  3258.  * This will return the point containing global coords of the mouse.
  3259.  *
  3260.  * @method getMousePosition
  3261.  * @return {Point} The point containing the coords of the global InteractionData position.
  3262.  */
  3263. PIXI.Stage.prototype.getMousePosition = function()
  3264. {
  3265.     return this.interactionManager.mouse.global;
  3266. }
  3267.  
  3268. // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
  3269. // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
  3270.  
  3271. // requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
  3272.  
  3273. // MIT license
  3274.  
  3275. /**
  3276.  * A polyfill for requestAnimationFrame
  3277.  *
  3278.  * @method requestAnimationFrame
  3279.  */
  3280. /**
  3281.  * A polyfill for cancelAnimationFrame
  3282.  *
  3283.  * @method cancelAnimationFrame
  3284.  */
  3285. var lastTime = 0;
  3286. var vendors = ['ms', 'moz', 'webkit', 'o'];
  3287. for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
  3288.     window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
  3289.     window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
  3290.                                || window[vendors[x]+'CancelRequestAnimationFrame'];
  3291. }
  3292.  
  3293. if (!window.requestAnimationFrame)
  3294.     window.requestAnimationFrame = function(callback, element) {
  3295.         var currTime = new Date().getTime();
  3296.         var timeToCall = Math.max(0, 16 - (currTime - lastTime));
  3297.         var id = window.setTimeout(function() { callback(currTime + timeToCall); },
  3298.           timeToCall);
  3299.         lastTime = currTime + timeToCall;
  3300.         return id;
  3301.     };
  3302.  
  3303. if (!window.cancelAnimationFrame)
  3304.     window.cancelAnimationFrame = function(id) {
  3305.         clearTimeout(id);
  3306.     };
  3307.  
  3308. window.requestAnimFrame = window.requestAnimationFrame;
  3309.  
  3310. /**
  3311.  * Converts a hex color number to an [R, G, B] array
  3312.  *
  3313.  * @method HEXtoRGB
  3314.  * @param hex {Number}
  3315.  */
  3316. function HEXtoRGB(hex) {
  3317.     return [(hex >> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255];
  3318. }
  3319.  
  3320. /**
  3321.  * A polyfill for Function.prototype.bind
  3322.  *
  3323.  * @method bind
  3324.  */
  3325. if (typeof Function.prototype.bind != 'function') {
  3326.   Function.prototype.bind = (function () {
  3327.     var slice = Array.prototype.slice;
  3328.     return function (thisArg) {
  3329.       var target = this, boundArgs = slice.call(arguments, 1);
  3330.  
  3331.       if (typeof target != 'function') throw new TypeError();
  3332.  
  3333.       function bound() {
  3334.     var args = boundArgs.concat(slice.call(arguments));
  3335.     target.apply(this instanceof bound ? this : thisArg, args);
  3336.       }
  3337.  
  3338.       bound.prototype = (function F(proto) {
  3339.           proto && (F.prototype = proto);
  3340.           if (!(this instanceof F)) return new F;
  3341.     })(target.prototype);
  3342.  
  3343.       return bound;
  3344.     };
  3345.   })();
  3346. }
  3347.  
  3348. /**
  3349.  * A wrapper for ajax requests to be handled cross browser
  3350.  *
  3351.  * @class AjaxRequest
  3352.  * @constructor
  3353.  */
  3354. var AjaxRequest = PIXI.AjaxRequest = function()
  3355. {
  3356.     var activexmodes = ["Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.3.0", "Microsoft.XMLHTTP"] //activeX versions to check for in IE
  3357.  
  3358.     if (window.ActiveXObject)
  3359.     { //Test for support for ActiveXObject in IE first (as XMLHttpRequest in IE7 is broken)
  3360.         for (var i=0; i<activexmodes.length; i++)
  3361.         {
  3362.             try{
  3363.                 return new ActiveXObject(activexmodes[i])
  3364.             }
  3365.             catch(e){
  3366.                 //suppress error
  3367.             }
  3368.         }
  3369.     }
  3370.     else if (window.XMLHttpRequest) // if Mozilla, Safari etc
  3371.     {
  3372.         return new XMLHttpRequest()
  3373.     }
  3374.     else
  3375.     {
  3376.         return false;
  3377.     }
  3378. }
  3379.  
  3380. /*
  3381.  * DEBUGGING ONLY
  3382.  */
  3383. PIXI.runList = function(item)
  3384. {
  3385.     console.log(">>>>>>>>>")
  3386.     console.log("_")
  3387.     var safe = 0;
  3388.     var tmp = item.first;
  3389.     console.log(tmp);
  3390.  
  3391.     while(tmp._iNext)
  3392.     {
  3393.         safe++;
  3394.         tmp = tmp._iNext;
  3395.         console.log(tmp);
  3396.     //  console.log(tmp);
  3397.  
  3398.         if(safe > 100)
  3399.         {
  3400.             console.log("BREAK")
  3401.             break
  3402.         }
  3403.     }
  3404. }
  3405.  
  3406.  
  3407.  
  3408.  
  3409.  
  3410.  
  3411. /**
  3412.  * https://github.com/mrdoob/eventtarget.js/
  3413.  * THankS mr DOob!
  3414.  */
  3415.  
  3416. /**
  3417.  * Adds event emitter functionality to a class
  3418.  *
  3419.  * @class EventTarget
  3420.  * @example
  3421.  *      function MyEmitter() {
  3422.  *          PIXI.EventTarget.call(this); //mixes in event target stuff
  3423.  *      }
  3424.  *
  3425.  *      var em = new MyEmitter();
  3426.  *      em.emit({ type: 'eventName', data: 'some data' });
  3427.  */
  3428. PIXI.EventTarget = function () {
  3429.  
  3430.     var listeners = {};
  3431.  
  3432.     this.addEventListener = this.on = function ( type, listener ) {
  3433.  
  3434.  
  3435.         if ( listeners[ type ] === undefined ) {
  3436.  
  3437.             listeners[ type ] = [];
  3438.  
  3439.         }
  3440.  
  3441.         if ( listeners[ type ].indexOf( listener ) === - 1 ) {
  3442.  
  3443.             listeners[ type ].push( listener );
  3444.         }
  3445.  
  3446.     };
  3447.  
  3448.     this.dispatchEvent = this.emit = function ( event ) {
  3449.  
  3450.         if ( !listeners[ event.type ] || !listeners[ event.type ].length ) {
  3451.  
  3452.             return;
  3453.  
  3454.         }
  3455.  
  3456.         for(var i = 0, l = listeners[ event.type ].length; i < l; i++) {
  3457.  
  3458.             listeners[ event.type ][ i ]( event );
  3459.  
  3460.         }
  3461.  
  3462.     };
  3463.  
  3464.     this.removeEventListener = this.off = function ( type, listener ) {
  3465.  
  3466.         var index = listeners[ type ].indexOf( listener );
  3467.  
  3468.         if ( index !== - 1 ) {
  3469.  
  3470.             listeners[ type ].splice( index, 1 );
  3471.  
  3472.         }
  3473.  
  3474.     };
  3475.  
  3476. };
  3477.  
  3478. /**
  3479.  * @author Mat Groves http://matgroves.com/ @Doormat23
  3480.  */
  3481.  
  3482. /**
  3483.  * This helper function will automatically detect which renderer you should be using.
  3484.  * WebGL is the preferred renderer as it is a lot fastest. If webGL is not supported by
  3485.  * the browser then this function will return a canvas renderer
  3486.  *
  3487.  * @method autoDetectRenderer
  3488.  * @static
  3489.  * @param width {Number} the width of the renderers view
  3490.  * @param height {Number} the height of the renderers view
  3491.  * @param view {Canvas} the canvas to use as a view, optional
  3492.  * @param transparent=false {Boolean} the transparency of the render view, default false
  3493.  * @param antialias=false {Boolean} sets antialias (only applicable in webGL chrome at the moment)
  3494.  *
  3495.  * antialias
  3496.  */
  3497. PIXI.autoDetectRenderer = function(width, height, view, transparent, antialias)
  3498. {
  3499.     if(!width)width = 800;
  3500.     if(!height)height = 600;
  3501.  
  3502.     // BORROWED from Mr Doob (mrdoob.com)
  3503.     var webgl = ( function () { try { var canvas = document.createElement( 'canvas' ); return !! window.WebGLRenderingContext && ( canvas.getContext( 'webgl' ) || canvas.getContext( 'experimental-webgl' ) ); } catch( e ) { return false; } } )();
  3504.  
  3505.     if(webgl)
  3506.     {
  3507.         var ie =  (navigator.userAgent.toLowerCase().indexOf('msie') != -1);
  3508.          webgl = !ie;
  3509.     }
  3510.    
  3511.     //console.log(webgl);
  3512.     if( webgl )
  3513.     {
  3514.         return new PIXI.WebGLRenderer(width, height, view, transparent, antialias);
  3515.     }
  3516.  
  3517.     return  new PIXI.CanvasRenderer(width, height, view, transparent);
  3518. };
  3519.  
  3520.  
  3521.  
  3522. /*
  3523.     PolyK library
  3524.     url: http://polyk.ivank.net
  3525.     Released under MIT licence.
  3526.  
  3527.     Copyright (c) 2012 Ivan Kuckir
  3528.  
  3529.     Permission is hereby granted, free of charge, to any person
  3530.     obtaining a copy of this software and associated documentation
  3531.     files (the "Software"), to deal in the Software without
  3532.     restriction, including without limitation the rights to use,
  3533.     copy, modify, merge, publish, distribute, sublicense, and/or sell
  3534.     copies of the Software, and to permit persons to whom the
  3535.     Software is furnished to do so, subject to the following
  3536.     conditions:
  3537.  
  3538.     The above copyright notice and this permission notice shall be
  3539.     included in all copies or substantial portions of the Software.
  3540.  
  3541.     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  3542.     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  3543.     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  3544.     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  3545.     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  3546.     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  3547.     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  3548.     OTHER DEALINGS IN THE SOFTWARE.
  3549.  
  3550.     This is an amazing lib!
  3551.  
  3552.     slightly modified by mat groves (matgroves.com);
  3553. */
  3554.  
  3555. PIXI.PolyK = {};
  3556.  
  3557. /**
  3558.  * Triangulates shapes for webGL graphic fills
  3559.  *
  3560.  * @method Triangulate
  3561.  * @namespace PolyK
  3562.  * @constructor
  3563.  */
  3564. PIXI.PolyK.Triangulate = function(p)
  3565. {
  3566.     var sign = true;
  3567.  
  3568.     var n = p.length>>1;
  3569.     if(n<3) return [];
  3570.     var tgs = [];
  3571.     var avl = [];
  3572.     for(var i=0; i<n; i++) avl.push(i);
  3573.  
  3574.     var i = 0;
  3575.     var al = n;
  3576.     while(al > 3)
  3577.     {
  3578.         var i0 = avl[(i+0)%al];
  3579.         var i1 = avl[(i+1)%al];
  3580.         var i2 = avl[(i+2)%al];
  3581.  
  3582.         var ax = p[2*i0],  ay = p[2*i0+1];
  3583.         var bx = p[2*i1],  by = p[2*i1+1];
  3584.         var cx = p[2*i2],  cy = p[2*i2+1];
  3585.  
  3586.         var earFound = false;
  3587.         if(PIXI.PolyK._convex(ax, ay, bx, by, cx, cy, sign))
  3588.         {
  3589.             earFound = true;
  3590.             for(var j=0; j<al; j++)
  3591.             {
  3592.                 var vi = avl[j];
  3593.                 if(vi==i0 || vi==i1 || vi==i2) continue;
  3594.                 if(PIXI.PolyK._PointInTriangle(p[2*vi], p[2*vi+1], ax, ay, bx, by, cx, cy)) {earFound = false; break;}
  3595.             }
  3596.         }
  3597.         if(earFound)
  3598.         {
  3599.             tgs.push(i0, i1, i2);
  3600.             avl.splice((i+1)%al, 1);
  3601.             al--;
  3602.             i = 0;
  3603.         }
  3604.         else if(i++ > 3*al)
  3605.         {
  3606.             // need to flip flip reverse it!
  3607.             // reset!
  3608.             if(sign)
  3609.             {
  3610.                 var tgs = [];
  3611.                 avl = [];
  3612.                 for(var i=0; i<n; i++) avl.push(i);
  3613.  
  3614.                 i = 0;
  3615.                 al = n;
  3616.  
  3617.                 sign = false;
  3618.             }
  3619.             else
  3620.             {
  3621.                 console.log("PIXI Warning: shape too complex to fill")
  3622.                 return [];
  3623.             }
  3624.         }
  3625.     }
  3626.     tgs.push(avl[0], avl[1], avl[2]);
  3627.     return tgs;
  3628. }
  3629.  
  3630. /**
  3631.  * Checks if a point is within a triangle
  3632.  *
  3633.  * @class _PointInTriangle
  3634.  * @namespace PolyK
  3635.  * @private
  3636.  */
  3637. PIXI.PolyK._PointInTriangle = function(px, py, ax, ay, bx, by, cx, cy)
  3638. {
  3639.     var v0x = cx-ax;
  3640.     var v0y = cy-ay;
  3641.     var v1x = bx-ax;
  3642.     var v1y = by-ay;
  3643.     var v2x = px-ax;
  3644.     var v2y = py-ay;
  3645.  
  3646.     var dot00 = v0x*v0x+v0y*v0y;
  3647.     var dot01 = v0x*v1x+v0y*v1y;
  3648.     var dot02 = v0x*v2x+v0y*v2y;
  3649.     var dot11 = v1x*v1x+v1y*v1y;
  3650.     var dot12 = v1x*v2x+v1y*v2y;
  3651.  
  3652.     var invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
  3653.     var u = (dot11 * dot02 - dot01 * dot12) * invDenom;
  3654.     var v = (dot00 * dot12 - dot01 * dot02) * invDenom;
  3655.  
  3656.     // Check if point is in triangle
  3657.     return (u >= 0) && (v >= 0) && (u + v < 1);
  3658. }
  3659.  
  3660. /**
  3661.  * Checks if a shape is convex
  3662.  *
  3663.  * @class _convex
  3664.  * @namespace PolyK
  3665.  * @private
  3666.  */
  3667. PIXI.PolyK._convex = function(ax, ay, bx, by, cx, cy, sign)
  3668. {
  3669.     return ((ay-by)*(cx-bx) + (bx-ax)*(cy-by) >= 0) == sign;
  3670. }
  3671.  
  3672. /**
  3673.  * @author Mat Groves http://matgroves.com/ @Doormat23
  3674.  */
  3675.  
  3676.  
  3677. PIXI.initDefaultShaders = function()
  3678. {
  3679.     PIXI.primitiveShader = new PIXI.PrimitiveShader();
  3680.   PIXI.primitiveShader.init();
  3681.  
  3682.   PIXI.stripShader = new PIXI.StripShader();
  3683.   PIXI.stripShader.init();
  3684.  
  3685.     PIXI.defaultShader = new PIXI.PixiShader();
  3686.     PIXI.defaultShader.init();
  3687.  
  3688.   var gl = PIXI.gl;
  3689.   var shaderProgram = PIXI.defaultShader.program;
  3690.  
  3691.  
  3692.   gl.useProgram(shaderProgram);
  3693.  
  3694.   gl.enableVertexAttribArray(PIXI.defaultShader.aVertexPosition);
  3695.   gl.enableVertexAttribArray(PIXI.defaultShader.colorAttribute);
  3696.   gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord);
  3697. }
  3698.  
  3699. PIXI.activatePrimitiveShader = function()
  3700. {
  3701.   var gl = PIXI.gl;
  3702.  
  3703.   gl.useProgram(PIXI.primitiveShader.program);
  3704.  
  3705.   gl.disableVertexAttribArray(PIXI.defaultShader.aVertexPosition);
  3706.   gl.disableVertexAttribArray(PIXI.defaultShader.colorAttribute);
  3707.   gl.disableVertexAttribArray(PIXI.defaultShader.aTextureCoord);
  3708.  
  3709.   gl.enableVertexAttribArray(PIXI.primitiveShader.aVertexPosition);
  3710.   gl.enableVertexAttribArray(PIXI.primitiveShader.colorAttribute);
  3711. }
  3712.  
  3713. PIXI.deactivatePrimitiveShader = function()
  3714. {
  3715.   var gl = PIXI.gl;
  3716.  
  3717.   gl.useProgram(PIXI.defaultShader.program);
  3718.  
  3719.   gl.disableVertexAttribArray(PIXI.primitiveShader.aVertexPosition);
  3720.   gl.disableVertexAttribArray(PIXI.primitiveShader.colorAttribute);
  3721.  
  3722.   gl.enableVertexAttribArray(PIXI.defaultShader.aVertexPosition);
  3723.   gl.enableVertexAttribArray(PIXI.defaultShader.colorAttribute);
  3724.   gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord);
  3725.  
  3726. }
  3727.  
  3728. PIXI.activateStripShader = function()
  3729. {
  3730.   var gl = PIXI.gl;
  3731.  
  3732.   gl.useProgram(PIXI.stripShader.program);
  3733.  // gl.disableVertexAttribArray(PIXI.defaultShader.aTextureCoord);
  3734. }
  3735.  
  3736. PIXI.deactivateStripShader = function()
  3737. {
  3738.   var gl = PIXI.gl;
  3739.  
  3740.   gl.useProgram(PIXI.defaultShader.program);
  3741.   //gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord);
  3742. }
  3743.  
  3744. /*
  3745.  
  3746. SHADER COMPILER HELPERS
  3747. */
  3748.  
  3749. PIXI.CompileVertexShader = function(gl, shaderSrc)
  3750. {
  3751.   return PIXI._CompileShader(gl, shaderSrc, gl.VERTEX_SHADER);
  3752. }
  3753.  
  3754. PIXI.CompileFragmentShader = function(gl, shaderSrc)
  3755. {
  3756.   return PIXI._CompileShader(gl, shaderSrc, gl.FRAGMENT_SHADER);
  3757. }
  3758.  
  3759. PIXI._CompileShader = function(gl, shaderSrc, shaderType)
  3760. {
  3761.   var src = shaderSrc.join("\n");
  3762.   var shader = gl.createShader(shaderType);
  3763.   gl.shaderSource(shader, src);
  3764.   gl.compileShader(shader);
  3765.  
  3766.   if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
  3767.     console.log(gl.getShaderInfoLog(shader));
  3768.     return null;
  3769.   }
  3770.  
  3771.   return shader;
  3772. }
  3773.  
  3774.  
  3775. PIXI.compileProgram = function(vertexSrc, fragmentSrc)
  3776. {
  3777.     var gl = PIXI.gl;
  3778.     var fragmentShader = PIXI.CompileFragmentShader(gl, fragmentSrc);
  3779.     var vertexShader = PIXI.CompileVertexShader(gl, vertexSrc);
  3780.    
  3781.     var shaderProgram = gl.createProgram();
  3782.    
  3783.     gl.attachShader(shaderProgram, vertexShader);
  3784.     gl.attachShader(shaderProgram, fragmentShader);
  3785.     gl.linkProgram(shaderProgram);
  3786.  
  3787.     if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
  3788.         console.log("Could not initialise shaders");
  3789.     }
  3790.  
  3791.     return shaderProgram;
  3792. }
  3793.  
  3794. /**
  3795.  * @author Mat Groves http://matgroves.com/ @Doormat23
  3796.  */
  3797.  
  3798.  
  3799. PIXI.PixiShader = function()
  3800. {
  3801.     // the webGL program..
  3802.     this.program;
  3803.    
  3804.     this.fragmentSrc = [
  3805.       "precision lowp float;",
  3806.       "varying vec2 vTextureCoord;",
  3807.       "varying float vColor;",
  3808.       "uniform sampler2D uSampler;",
  3809.       "void main(void) {",
  3810.         "gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;",
  3811.       "}"
  3812.     ];
  3813.    
  3814. }
  3815.  
  3816. PIXI.PixiShader.prototype.init = function()
  3817. {
  3818.     var program = PIXI.compileProgram(this.vertexSrc || PIXI.PixiShader.defaultVertexSrc, this.fragmentSrc)
  3819.    
  3820.     var gl = PIXI.gl;
  3821.    
  3822.     gl.useProgram(program);
  3823.    
  3824.     // get and store the uniforms for the shader
  3825.     this.uSampler = gl.getUniformLocation(program, "uSampler");
  3826.     this.projectionVector = gl.getUniformLocation(program, "projectionVector");
  3827.     this.offsetVector = gl.getUniformLocation(program, "offsetVector");
  3828.     //this.dimensions = gl.getUniformLocation(this.program, "dimensions");
  3829.    
  3830.     // get and store the attributes
  3831.     this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition");
  3832.     this.colorAttribute = gl.getAttribLocation(program, "aColor");
  3833.     this.aTextureCoord = gl.getAttribLocation(program, "aTextureCoord");
  3834.      
  3835.     // add those custom shaders!
  3836.     for (var key in this.uniforms)
  3837.     {
  3838.        
  3839.         // get the uniform locations..
  3840.     //  program[key] =
  3841.         this.uniforms[key].uniformLocation = gl.getUniformLocation(program, key);
  3842.  
  3843.      
  3844.     }
  3845.  
  3846.     this.program = program;
  3847. }
  3848.  
  3849. PIXI.PixiShader.prototype.syncUniforms = function()
  3850. {
  3851.     var gl = PIXI.gl;
  3852.    
  3853.     for (var key in this.uniforms)
  3854.     {
  3855.         //var
  3856.         var type = this.uniforms[key].type;
  3857.        
  3858.         // need to grow this!
  3859.         if(type == "f")
  3860.         {
  3861.             gl.uniform1f(this.uniforms[key].uniformLocation, this.uniforms[key].value);
  3862.         }
  3863.         if(type == "f2")
  3864.         {
  3865.         //  console.log(this.program[key])
  3866.             gl.uniform2f(this.uniforms[key].uniformLocation, this.uniforms[key].value.x, this.uniforms[key].value.y);
  3867.         }
  3868.         else if(type == "f4")
  3869.         {
  3870.            // console.log(this.uniforms[key].value)
  3871.             gl.uniform4fv(this.uniforms[key].uniformLocation, this.uniforms[key].value);
  3872.         }
  3873.         else if(type == "mat4")
  3874.         {
  3875.             gl.uniformMatrix4fv(this.uniforms[key].uniformLocation, false, this.uniforms[key].value);
  3876.         }
  3877.         else if(type == "sampler2D")
  3878.         {
  3879.             // first texture...
  3880.             var texture = this.uniforms[key].value;
  3881.            
  3882.             gl.activeTexture(gl.TEXTURE1);
  3883.             gl.bindTexture(gl.TEXTURE_2D, texture.baseTexture._glTexture);
  3884.            
  3885.             gl.uniform1i(this.uniforms[key].uniformLocation, 1);
  3886.            
  3887.             // activate texture..
  3888.             // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value);
  3889.             // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value);
  3890.         }
  3891.     }
  3892.    
  3893. }
  3894.  
  3895. PIXI.PixiShader.defaultVertexSrc = [
  3896.   "attribute vec2 aVertexPosition;",
  3897.   "attribute vec2 aTextureCoord;",
  3898.   "attribute float aColor;",
  3899.  
  3900.   "uniform vec2 projectionVector;",
  3901.  "uniform vec2 offsetVector;",
  3902.   "varying vec2 vTextureCoord;",
  3903.  
  3904.   "varying float vColor;",
  3905.  
  3906.   "const vec2 center = vec2(-1.0, 1.0);",
  3907.   "void main(void) {",
  3908.     "gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);",
  3909.     "vTextureCoord = aTextureCoord;",
  3910.     "vColor = aColor;",
  3911.   "}"
  3912. ];
  3913.  
  3914. /**
  3915.  * @author Mat Groves http://matgroves.com/ @Doormat23
  3916.  */
  3917.  
  3918.  
  3919. PIXI.StripShader = function()
  3920. {
  3921.     // the webGL program..
  3922.     this.program;
  3923.    
  3924.     this.fragmentSrc = [
  3925.       "precision mediump float;",
  3926.       "varying vec2 vTextureCoord;",
  3927.       "varying float vColor;",
  3928.       "uniform float alpha;",
  3929.       "uniform sampler2D uSampler;",
  3930.       "void main(void) {",
  3931.         "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));",
  3932.         "gl_FragColor = gl_FragColor * alpha;",
  3933.       "}"
  3934.     ];
  3935.  
  3936.     this.vertexSrc = [
  3937.       "attribute vec2 aVertexPosition;",
  3938.       "attribute vec2 aTextureCoord;",
  3939.       "attribute float aColor;",
  3940.       "uniform mat3 translationMatrix;",
  3941.       "uniform vec2 projectionVector;",
  3942.       "varying vec2 vTextureCoord;",
  3943.       "varying vec2 offsetVector;",
  3944.       "varying float vColor;",
  3945.       "void main(void) {",
  3946.         "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);",
  3947.         "v -= offsetVector.xyx;",
  3948.         "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / projectionVector.y + 1.0 , 0.0, 1.0);",
  3949.         "vTextureCoord = aTextureCoord;",
  3950.         "vColor = aColor;",
  3951.       "}"
  3952.     ];
  3953. }
  3954.  
  3955. PIXI.StripShader.prototype.init = function()
  3956. {
  3957.     var program = PIXI.compileProgram(this.vertexSrc, this.fragmentSrc)
  3958.    
  3959.     var gl = PIXI.gl;
  3960.    
  3961.     gl.useProgram(program);
  3962.  
  3963.     // get and store the uniforms for the shader
  3964.     this.uSampler = gl.getUniformLocation(program, "uSampler");
  3965.     this.projectionVector = gl.getUniformLocation(program, "projectionVector");
  3966.     this.offsetVector = gl.getUniformLocation(program, "offsetVector");
  3967.     this.colorAttribute = gl.getAttribLocation(program, "aColor");
  3968.     //this.dimensions = gl.getUniformLocation(this.program, "dimensions");
  3969.    
  3970.     // get and store the attributes
  3971.     this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition");
  3972.     this.aTextureCoord = gl.getAttribLocation(program, "aTextureCoord");
  3973.      
  3974.     this.translationMatrix = gl.getUniformLocation(program, "translationMatrix");
  3975.     this.alpha = gl.getUniformLocation(program, "alpha");
  3976.  
  3977.     this.program = program;
  3978. }
  3979.  
  3980. /**
  3981.  * @author Mat Groves http://matgroves.com/ @Doormat23
  3982.  */
  3983.  
  3984.  
  3985. PIXI.PrimitiveShader = function()
  3986. {
  3987.     // the webGL program..
  3988.     this.program;
  3989.        
  3990.     this.fragmentSrc = [
  3991.       "precision mediump float;",
  3992.       "varying vec4 vColor;",
  3993.       "void main(void) {",
  3994.         "gl_FragColor = vColor;",
  3995.       "}"
  3996.     ];
  3997.  
  3998.     this.vertexSrc  = [
  3999.       "attribute vec2 aVertexPosition;",
  4000.       "attribute vec4 aColor;",
  4001.       "uniform mat3 translationMatrix;",
  4002.       "uniform vec2 projectionVector;",
  4003.       "uniform vec2 offsetVector;",
  4004.       "uniform float alpha;",
  4005.       "varying vec4 vColor;",
  4006.       "void main(void) {",
  4007.         "vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);",
  4008.         "v -= offsetVector.xyx;",
  4009.         "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
  4010.         "vColor = aColor  * alpha;",
  4011.       "}"
  4012.     ];
  4013.    
  4014. }
  4015.  
  4016. PIXI.PrimitiveShader.prototype.init = function()
  4017. {
  4018.     var program = PIXI.compileProgram(this.vertexSrc, this.fragmentSrc);
  4019.    
  4020.     var gl = PIXI.gl;
  4021.    
  4022.   gl.useProgram(program);
  4023.    
  4024.     // get and store the uniforms for the shader
  4025.     this.projectionVector = gl.getUniformLocation(program, "projectionVector");
  4026.     this.offsetVector = gl.getUniformLocation(program, "offsetVector");
  4027.  
  4028.   // get and store the attributes
  4029.   this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition");
  4030.     this.colorAttribute = gl.getAttribLocation(program, "aColor");
  4031.    
  4032.   this.translationMatrix = gl.getUniformLocation(program, "translationMatrix");
  4033.   this.alpha = gl.getUniformLocation(program, "alpha");
  4034.  
  4035.     this.program = program;
  4036. }
  4037.  
  4038. /**
  4039.  * @author Mat Groves http://matgroves.com/ @Doormat23
  4040.  */
  4041.  
  4042. /**
  4043.  * A set of functions used by the webGL renderer to draw the primitive graphics data
  4044.  *
  4045.  * @class CanvasGraphics
  4046.  */
  4047. PIXI.WebGLGraphics = function()
  4048. {
  4049.    
  4050. }
  4051.  
  4052. /**
  4053.  * Renders the graphics object
  4054.  *
  4055.  * @static
  4056.  * @private
  4057.  * @method renderGraphics
  4058.  * @param graphics {Graphics}
  4059.  * @param projection {Object}
  4060.  */
  4061. PIXI.WebGLGraphics.renderGraphics = function(graphics, projection)
  4062. {
  4063.     var gl = PIXI.gl;
  4064.    
  4065.     if(!graphics._webGL)graphics._webGL = {points:[], indices:[], lastIndex:0,
  4066.                                            buffer:gl.createBuffer(),
  4067.                                            indexBuffer:gl.createBuffer()};
  4068.    
  4069.     if(graphics.dirty)
  4070.     {
  4071.         graphics.dirty = false;
  4072.        
  4073.         if(graphics.clearDirty)
  4074.         {
  4075.             graphics.clearDirty = false;
  4076.            
  4077.             graphics._webGL.lastIndex = 0;
  4078.             graphics._webGL.points = [];
  4079.             graphics._webGL.indices = [];
  4080.            
  4081.         }
  4082.        
  4083.         PIXI.WebGLGraphics.updateGraphics(graphics);
  4084.     }
  4085.    
  4086.     PIXI.activatePrimitiveShader();
  4087.    
  4088.     // This  could be speeded up fo sure!
  4089.     var m = PIXI.mat3.clone(graphics.worldTransform);
  4090.    
  4091.     PIXI.mat3.transpose(m);
  4092.    
  4093.     // set the matrix transform for the
  4094.     gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
  4095.  
  4096.     gl.uniformMatrix3fv(PIXI.primitiveShader.translationMatrix, false, m);
  4097.    
  4098.     gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y);
  4099.     gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y);
  4100.    
  4101.     gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha);
  4102.     gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer);
  4103.    
  4104.     gl.vertexAttribPointer(PIXI.primitiveShader.aVertexPosition, 2, gl.FLOAT, false, 4 * 6, 0);
  4105.     gl.vertexAttribPointer(PIXI.primitiveShader.colorAttribute, 4, gl.FLOAT, false,4 * 6, 2 * 4);
  4106.    
  4107.     // set the index buffer!
  4108.     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer);
  4109.    
  4110.  
  4111.     gl.drawElements(gl.TRIANGLE_STRIP,  graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 );
  4112.    
  4113.     PIXI.deactivatePrimitiveShader();
  4114.    
  4115.    
  4116.     // return to default shader...
  4117. //  PIXI.activateShader(PIXI.defaultShader);
  4118. }
  4119.  
  4120. /**
  4121.  * Updates the graphics object
  4122.  *
  4123.  * @static
  4124.  * @private
  4125.  * @method updateGraphics
  4126.  * @param graphics {Graphics}
  4127.  */
  4128. PIXI.WebGLGraphics.updateGraphics = function(graphics)
  4129. {
  4130.     for (var i=graphics._webGL.lastIndex; i < graphics.graphicsData.length; i++)
  4131.     {
  4132.         var data = graphics.graphicsData[i];
  4133.        
  4134.         if(data.type == PIXI.Graphics.POLY)
  4135.         {
  4136.             if(data.fill)
  4137.             {
  4138.                 if(data.points.length>3)
  4139.                 PIXI.WebGLGraphics.buildPoly(data, graphics._webGL);
  4140.             }
  4141.            
  4142.             if(data.lineWidth > 0)
  4143.             {
  4144.                 PIXI.WebGLGraphics.buildLine(data, graphics._webGL);
  4145.             }
  4146.         }
  4147.         else if(data.type == PIXI.Graphics.RECT)
  4148.         {
  4149.             PIXI.WebGLGraphics.buildRectangle(data, graphics._webGL);
  4150.         }
  4151.         else if(data.type == PIXI.Graphics.CIRC || data.type == PIXI.Graphics.ELIP)
  4152.         {
  4153.             PIXI.WebGLGraphics.buildCircle(data, graphics._webGL);
  4154.         }
  4155.     };
  4156.    
  4157.     graphics._webGL.lastIndex = graphics.graphicsData.length;
  4158.    
  4159.     var gl = PIXI.gl;
  4160.  
  4161.     graphics._webGL.glPoints = new Float32Array(graphics._webGL.points);
  4162.    
  4163.     gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer);
  4164.     gl.bufferData(gl.ARRAY_BUFFER, graphics._webGL.glPoints, gl.STATIC_DRAW);
  4165.    
  4166.     graphics._webGL.glIndicies = new Uint16Array(graphics._webGL.indices);
  4167.    
  4168.     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer);
  4169.     gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.glIndicies, gl.STATIC_DRAW);
  4170. }
  4171.  
  4172. /**
  4173.  * Builds a rectangle to draw
  4174.  *
  4175.  * @static
  4176.  * @private
  4177.  * @method buildRectangle
  4178.  * @param graphics {Graphics}
  4179.  * @param webGLData {Object}
  4180.  */
  4181. PIXI.WebGLGraphics.buildRectangle = function(graphicsData, webGLData)
  4182. {
  4183.     // --- //
  4184.     // need to convert points to a nice regular data
  4185.     //
  4186.     var rectData = graphicsData.points;
  4187.     var x = rectData[0];
  4188.     var y = rectData[1];
  4189.     var width = rectData[2];
  4190.     var height = rectData[3];
  4191.    
  4192.    
  4193.     if(graphicsData.fill)
  4194.     {
  4195.         var color = HEXtoRGB(graphicsData.fillColor);
  4196.         var alpha = graphicsData.fillAlpha;
  4197.        
  4198.         var r = color[0] * alpha;
  4199.         var g = color[1] * alpha;
  4200.         var b = color[2] * alpha;
  4201.    
  4202.         var verts = webGLData.points;
  4203.         var indices = webGLData.indices;
  4204.    
  4205.         var vertPos = verts.length/6;
  4206.        
  4207.         // start
  4208.         verts.push(x, y);
  4209.         verts.push(r, g, b, alpha);
  4210.        
  4211.         verts.push(x + width, y);
  4212.         verts.push(r, g, b, alpha);
  4213.        
  4214.         verts.push(x , y + height);
  4215.         verts.push(r, g, b, alpha);
  4216.        
  4217.         verts.push(x + width, y + height);
  4218.         verts.push(r, g, b, alpha);
  4219.        
  4220.         // insert 2 dead triangles..
  4221.         indices.push(vertPos, vertPos, vertPos+1, vertPos+2, vertPos+3, vertPos+3)
  4222.     }
  4223.    
  4224.     if(graphicsData.lineWidth)
  4225.     {
  4226.         graphicsData.points = [x, y,
  4227.                   x + width, y,
  4228.                   x + width, y + height,
  4229.                   x, y + height,
  4230.                   x, y];
  4231.    
  4232.         PIXI.WebGLGraphics.buildLine(graphicsData, webGLData);
  4233.     }
  4234.    
  4235. }
  4236.  
  4237. /**
  4238.  * Builds a circle to draw
  4239.  *
  4240.  * @static
  4241.  * @private
  4242.  * @method buildCircle
  4243.  * @param graphics {Graphics}
  4244.  * @param webGLData {Object}
  4245.  */
  4246. PIXI.WebGLGraphics.buildCircle = function(graphicsData, webGLData)
  4247. {
  4248.     // --- //
  4249.     // need to convert points to a nice regular data
  4250.     //
  4251.     var rectData = graphicsData.points;
  4252.     var x = rectData[0];
  4253.     var y = rectData[1];
  4254.     var width = rectData[2];
  4255.     var height = rectData[3];
  4256.    
  4257.     var totalSegs = 40;
  4258.     var seg = (Math.PI * 2) / totalSegs ;
  4259.        
  4260.     if(graphicsData.fill)
  4261.     {
  4262.         var color = HEXtoRGB(graphicsData.fillColor);
  4263.         var alpha = graphicsData.fillAlpha;
  4264.  
  4265.         var r = color[0] * alpha;
  4266.         var g = color[1] * alpha;
  4267.         var b = color[2] * alpha;
  4268.    
  4269.         var verts = webGLData.points;
  4270.         var indices = webGLData.indices;
  4271.    
  4272.         var vecPos = verts.length/6;
  4273.        
  4274.         indices.push(vecPos);
  4275.        
  4276.         for (var i=0; i < totalSegs + 1 ; i++)
  4277.         {
  4278.             verts.push(x,y, r, g, b, alpha);
  4279.            
  4280.             verts.push(x + Math.sin(seg * i) * width,
  4281.                        y + Math.cos(seg * i) * height,
  4282.                        r, g, b, alpha);
  4283.        
  4284.             indices.push(vecPos++, vecPos++);
  4285.         };
  4286.        
  4287.         indices.push(vecPos-1);
  4288.     }
  4289.    
  4290.     if(graphicsData.lineWidth)
  4291.     {
  4292.         graphicsData.points = [];
  4293.        
  4294.         for (var i=0; i < totalSegs + 1; i++)
  4295.         {
  4296.             graphicsData.points.push(x + Math.sin(seg * i) * width,
  4297.                                      y + Math.cos(seg * i) * height)
  4298.         };
  4299.        
  4300.         PIXI.WebGLGraphics.buildLine(graphicsData, webGLData);
  4301.     }
  4302.    
  4303. }
  4304.  
  4305. /**
  4306.  * Builds a line to draw
  4307.  *
  4308.  * @static
  4309.  * @private
  4310.  * @method buildLine
  4311.  * @param graphics {Graphics}
  4312.  * @param webGLData {Object}
  4313.  */
  4314. PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData)
  4315. {
  4316.     // TODO OPTIMISE!
  4317.    
  4318.     var wrap = true;
  4319.     var points = graphicsData.points;
  4320.     if(points.length == 0)return;
  4321.    
  4322.     // if the line width is an odd number add 0.5 to align to a whole pixel
  4323.     if(graphicsData.lineWidth%2)
  4324.     {
  4325.         for (var i = 0; i < points.length; i++) {
  4326.             points[i] += 0.5;
  4327.         };
  4328.     }
  4329.  
  4330.     // get first and last point.. figure out the middle!
  4331.     var firstPoint = new PIXI.Point( points[0], points[1] );
  4332.     var lastPoint = new PIXI.Point( points[points.length - 2], points[points.length - 1] );
  4333.    
  4334.     // if the first point is the last point - goona have issues :)
  4335.     if(firstPoint.x == lastPoint.x && firstPoint.y == lastPoint.y)
  4336.     {
  4337.         points.pop();
  4338.         points.pop();
  4339.        
  4340.         lastPoint = new PIXI.Point( points[points.length - 2], points[points.length - 1] );
  4341.        
  4342.         var midPointX = lastPoint.x + (firstPoint.x - lastPoint.x) *0.5;
  4343.         var midPointY = lastPoint.y + (firstPoint.y - lastPoint.y) *0.5;
  4344.        
  4345.         points.unshift(midPointX, midPointY);
  4346.         points.push(midPointX, midPointY)
  4347.     }
  4348.    
  4349.     var verts = webGLData.points;
  4350.     var indices = webGLData.indices;
  4351.     var length = points.length / 2;
  4352.     var indexCount = points.length;
  4353.     var indexStart = verts.length/6;
  4354.    
  4355.     // DRAW the Line
  4356.     var width = graphicsData.lineWidth / 2;
  4357.    
  4358.     // sort color
  4359.     var color = HEXtoRGB(graphicsData.lineColor);
  4360.     var alpha = graphicsData.lineAlpha;
  4361.     var r = color[0] * alpha;
  4362.     var g = color[1] * alpha;
  4363.     var b = color[2] * alpha;
  4364.    
  4365.     var p1x, p1y, p2x, p2y, p3x, p3y;
  4366.     var perpx, perpy, perp2x, perp2y, perp3x, perp3y;
  4367.     var ipx, ipy;
  4368.     var a1, b1, c1, a2, b2, c2;
  4369.     var denom, pdist, dist;
  4370.    
  4371.     p1x = points[0];
  4372.     p1y = points[1];
  4373.    
  4374.     p2x = points[2];
  4375.     p2y = points[3];
  4376.    
  4377.     perpx = -(p1y - p2y);
  4378.     perpy =  p1x - p2x;
  4379.    
  4380.     dist = Math.sqrt(perpx*perpx + perpy*perpy);
  4381.    
  4382.     perpx /= dist;
  4383.     perpy /= dist;
  4384.     perpx *= width;
  4385.     perpy *= width;
  4386.    
  4387.     // start
  4388.     verts.push(p1x - perpx , p1y - perpy,
  4389.                 r, g, b, alpha);
  4390.    
  4391.     verts.push(p1x + perpx , p1y + perpy,
  4392.                 r, g, b, alpha);
  4393.    
  4394.     for (var i = 1; i < length-1; i++)
  4395.     {
  4396.         p1x = points[(i-1)*2];
  4397.         p1y = points[(i-1)*2 + 1];
  4398.        
  4399.         p2x = points[(i)*2]
  4400.         p2y = points[(i)*2 + 1]
  4401.        
  4402.         p3x = points[(i+1)*2];
  4403.         p3y = points[(i+1)*2 + 1];
  4404.        
  4405.         perpx = -(p1y - p2y);
  4406.         perpy = p1x - p2x;
  4407.        
  4408.         dist = Math.sqrt(perpx*perpx + perpy*perpy);
  4409.         perpx /= dist;
  4410.         perpy /= dist;
  4411.         perpx *= width;
  4412.         perpy *= width;
  4413.  
  4414.         perp2x = -(p2y - p3y);
  4415.         perp2y = p2x - p3x;
  4416.        
  4417.         dist = Math.sqrt(perp2x*perp2x + perp2y*perp2y);
  4418.         perp2x /= dist;
  4419.         perp2y /= dist;
  4420.         perp2x *= width;
  4421.         perp2y *= width;
  4422.        
  4423.         a1 = (-perpy + p1y) - (-perpy + p2y);
  4424.         b1 = (-perpx + p2x) - (-perpx + p1x);
  4425.         c1 = (-perpx + p1x) * (-perpy + p2y) - (-perpx + p2x) * (-perpy + p1y);
  4426.         a2 = (-perp2y + p3y) - (-perp2y + p2y);
  4427.         b2 = (-perp2x + p2x) - (-perp2x + p3x);
  4428.         c2 = (-perp2x + p3x) * (-perp2y + p2y) - (-perp2x + p2x) * (-perp2y + p3y);
  4429.      
  4430.         denom = a1*b2 - a2*b1;
  4431.  
  4432.        if(Math.abs(denom) < 0.1 )
  4433.         {
  4434.        
  4435.             denom+=10.1;
  4436.             verts.push(p2x - perpx , p2y - perpy,
  4437.                 r, g, b, alpha);
  4438.    
  4439.             verts.push(p2x + perpx , p2y + perpy,
  4440.                 r, g, b, alpha);
  4441.            
  4442.             continue;
  4443.         }
  4444.        
  4445.         px = (b1*c2 - b2*c1)/denom;
  4446.         py = (a2*c1 - a1*c2)/denom;
  4447.        
  4448.            
  4449.         pdist = (px -p2x) * (px -p2x) + (py -p2y) + (py -p2y);
  4450.        
  4451.  
  4452.         if(pdist > 140 * 140)
  4453.         {
  4454.             perp3x = perpx - perp2x;
  4455.             perp3y = perpy - perp2y;
  4456.            
  4457.             dist = Math.sqrt(perp3x*perp3x + perp3y*perp3y);
  4458.             perp3x /= dist;
  4459.             perp3y /= dist;
  4460.             perp3x *= width;
  4461.             perp3y *= width;
  4462.            
  4463.             verts.push(p2x - perp3x, p2y -perp3y);
  4464.             verts.push(r, g, b, alpha);
  4465.            
  4466.             verts.push(p2x + perp3x, p2y +perp3y);
  4467.             verts.push(r, g, b, alpha);
  4468.            
  4469.             verts.push(p2x - perp3x, p2y -perp3y);
  4470.             verts.push(r, g, b, alpha);
  4471.            
  4472.             indexCount++;
  4473.         }
  4474.         else
  4475.         {
  4476.  
  4477.             verts.push(px , py);
  4478.             verts.push(r, g, b, alpha);
  4479.            
  4480.             verts.push(p2x - (px-p2x), p2y - (py - p2y));
  4481.             verts.push(r, g, b, alpha);
  4482.         }
  4483.     }
  4484.    
  4485.     p1x = points[(length-2)*2]
  4486.     p1y = points[(length-2)*2 + 1]
  4487.    
  4488.     p2x = points[(length-1)*2]
  4489.     p2y = points[(length-1)*2 + 1]
  4490.    
  4491.     perpx = -(p1y - p2y)
  4492.     perpy = p1x - p2x;
  4493.    
  4494.     dist = Math.sqrt(perpx*perpx + perpy*perpy);
  4495.     perpx /= dist;
  4496.     perpy /= dist;
  4497.     perpx *= width;
  4498.     perpy *= width;
  4499.    
  4500.     verts.push(p2x - perpx , p2y - perpy)
  4501.     verts.push(r, g, b, alpha);
  4502.    
  4503.     verts.push(p2x + perpx , p2y + perpy)
  4504.     verts.push(r, g, b, alpha);
  4505.    
  4506.     indices.push(indexStart);
  4507.    
  4508.     for (var i=0; i < indexCount; i++)
  4509.     {
  4510.         indices.push(indexStart++);
  4511.     };
  4512.    
  4513.     indices.push(indexStart-1);
  4514. }
  4515.  
  4516. /**
  4517.  * Builds a polygon to draw
  4518.  *
  4519.  * @static
  4520.  * @private
  4521.  * @method buildPoly
  4522.  * @param graphics {Graphics}
  4523.  * @param webGLData {Object}
  4524.  */
  4525. PIXI.WebGLGraphics.buildPoly = function(graphicsData, webGLData)
  4526. {
  4527.     var points = graphicsData.points;
  4528.     if(points.length < 6)return;
  4529.    
  4530.     // get first and last point.. figure out the middle!
  4531.     var verts = webGLData.points;
  4532.     var indices = webGLData.indices;
  4533.    
  4534.     var length = points.length / 2;
  4535.    
  4536.     // sort color
  4537.     var color = HEXtoRGB(graphicsData.fillColor);
  4538.     var alpha = graphicsData.fillAlpha;
  4539.     var r = color[0] * alpha;
  4540.     var g = color[1] * alpha;
  4541.     var b = color[2] * alpha;
  4542.    
  4543.     var triangles = PIXI.PolyK.Triangulate(points);
  4544.    
  4545.     var vertPos = verts.length / 6;
  4546.    
  4547.     for (var i=0; i < triangles.length; i+=3)
  4548.     {
  4549.         indices.push(triangles[i] + vertPos);
  4550.         indices.push(triangles[i] + vertPos);
  4551.         indices.push(triangles[i+1] + vertPos);
  4552.         indices.push(triangles[i+2] +vertPos);
  4553.         indices.push(triangles[i+2] + vertPos);
  4554.     };
  4555.    
  4556.     for (var i = 0; i < length; i++)
  4557.     {
  4558.         verts.push(points[i * 2], points[i * 2 + 1],
  4559.                    r, g, b, alpha);
  4560.     };
  4561. }
  4562.  
  4563. function HEXtoRGB(hex) {
  4564.     return [(hex >> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255];
  4565. }
  4566.  
  4567.  
  4568.  
  4569.  
  4570.  
  4571. /**
  4572.  * @author Mat Groves http://matgroves.com/ @Doormat23
  4573.  */
  4574.  
  4575. PIXI._defaultFrame = new PIXI.Rectangle(0,0,1,1);
  4576.  
  4577. // an instance of the gl context..
  4578. // only one at the moment :/
  4579. PIXI.gl;
  4580.  
  4581. /**
  4582.  * the WebGLRenderer is draws the stage and all its content onto a webGL enabled canvas. This renderer
  4583.  * should be used for browsers support webGL. This Render works by automatically managing webGLBatchs.
  4584.  * So no need for Sprite Batch's or Sprite Cloud's
  4585.  * Dont forget to add the view to your DOM or you will not see anything :)
  4586.  *
  4587.  * @class WebGLRenderer
  4588.  * @constructor
  4589.  * @param width=0 {Number} the width of the canvas view
  4590.  * @param height=0 {Number} the height of the canvas view
  4591.  * @param view {Canvas} the canvas to use as a view, optional
  4592.  * @param transparent=false {Boolean} the transparency of the render view, default false
  4593.  * @param antialias=false {Boolean} sets antialias (only applicable in chrome at the moment)
  4594.  *
  4595.  */
  4596. PIXI.WebGLRenderer = function(width, height, view, transparent, antialias)
  4597. {
  4598.     // do a catch.. only 1 webGL renderer..
  4599.  
  4600.     this.transparent = !!transparent;
  4601.  
  4602.     this.width = width || 800;
  4603.     this.height = height || 600;
  4604.  
  4605.     this.view = view || document.createElement( 'canvas' );
  4606.     this.view.width = this.width;
  4607.     this.view.height = this.height;
  4608.  
  4609.     // deal with losing context..  
  4610.     var scope = this;
  4611.     this.view.addEventListener('webglcontextlost', function(event) { scope.handleContextLost(event); }, false)
  4612.     this.view.addEventListener('webglcontextrestored', function(event) { scope.handleContextRestored(event); }, false)
  4613.  
  4614.     this.batchs = [];
  4615.  
  4616.     var options = {
  4617.         alpha: this.transparent,
  4618.         antialias:!!antialias, // SPEED UP??
  4619.         premultipliedAlpha:false,
  4620.         stencil:true
  4621.     }
  4622.  
  4623.     //try 'experimental-webgl'
  4624.     try {
  4625.         PIXI.gl = this.gl = this.view.getContext("experimental-webgl",  options);
  4626.     } catch (e) {
  4627.         //try 'webgl'
  4628.         try {
  4629.             PIXI.gl = this.gl = this.view.getContext("webgl",  options);
  4630.         } catch (e) {
  4631.             // fail, not able to get a context
  4632.             throw new Error(" This browser does not support webGL. Try using the canvas renderer" + this);
  4633.         }
  4634.     }
  4635.  
  4636.     PIXI.initDefaultShaders();
  4637.  
  4638.  
  4639.    
  4640.  
  4641.    // PIXI.activateDefaultShader();
  4642.  
  4643.     var gl = this.gl;
  4644.    
  4645.     gl.useProgram(PIXI.defaultShader.program);
  4646.  
  4647.  
  4648.     PIXI.WebGLRenderer.gl = gl;
  4649.  
  4650.     this.batch = new PIXI.WebGLBatch(gl);
  4651.     gl.disable(gl.DEPTH_TEST);
  4652.     gl.disable(gl.CULL_FACE);
  4653.  
  4654.     gl.enable(gl.BLEND);
  4655.     gl.colorMask(true, true, true, this.transparent);
  4656.  
  4657.     PIXI.projection = new PIXI.Point(400, 300);
  4658.     PIXI.offset = new PIXI.Point(0, 0);
  4659.  
  4660.     // TODO remove thease globals..
  4661.  
  4662.     this.resize(this.width, this.height);
  4663.     this.contextLost = false;
  4664.  
  4665.     //PIXI.pushShader(PIXI.defaultShader);
  4666.  
  4667.     this.stageRenderGroup = new PIXI.WebGLRenderGroup(this.gl, this.transparent);
  4668.   //  this.stageRenderGroup. = this.transparent
  4669. }
  4670.  
  4671. // constructor
  4672. PIXI.WebGLRenderer.prototype.constructor = PIXI.WebGLRenderer;
  4673.  
  4674. /**
  4675.  * Gets a new WebGLBatch from the pool
  4676.  *
  4677.  * @static
  4678.  * @method getBatch
  4679.  * @return {WebGLBatch}
  4680.  * @private
  4681.  */
  4682. PIXI.WebGLRenderer.getBatch = function()
  4683. {
  4684.     if(PIXI._batchs.length == 0)
  4685.     {
  4686.         return new PIXI.WebGLBatch(PIXI.WebGLRenderer.gl);
  4687.     }
  4688.     else
  4689.     {
  4690.         return PIXI._batchs.pop();
  4691.     }
  4692. }
  4693.  
  4694. /**
  4695.  * Puts a batch back into the pool
  4696.  *
  4697.  * @static
  4698.  * @method returnBatch
  4699.  * @param batch {WebGLBatch} The batch to return
  4700.  * @private
  4701.  */
  4702. PIXI.WebGLRenderer.returnBatch = function(batch)
  4703. {
  4704.     batch.clean(); 
  4705.     PIXI._batchs.push(batch);
  4706. }
  4707.  
  4708. /**
  4709.  * Renders the stage to its webGL view
  4710.  *
  4711.  * @method render
  4712.  * @param stage {Stage} the Stage element to be rendered
  4713.  */
  4714. PIXI.WebGLRenderer.prototype.render = function(stage)
  4715. {
  4716.     if(this.contextLost)return;
  4717.    
  4718.    
  4719.     // if rendering a new stage clear the batchs..
  4720.     if(this.__stage !== stage)
  4721.     {
  4722.         // TODO make this work
  4723.         // dont think this is needed any more?
  4724.         this.__stage = stage;
  4725.         this.stageRenderGroup.setRenderable(stage);
  4726.     }
  4727.  
  4728.     // update any textures 
  4729.     PIXI.WebGLRenderer.updateTextures();
  4730.        
  4731.     // update the scene graph  
  4732.     PIXI.visibleCount++;
  4733.     stage.updateTransform();
  4734.    
  4735.     var gl = this.gl;
  4736.    
  4737.     // -- Does this need to be set every frame? -- //
  4738.     gl.colorMask(true, true, true, this.transparent);
  4739.     gl.viewport(0, 0, this.width, this.height);
  4740.    
  4741.     gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  4742.        
  4743.     gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent);    
  4744.     gl.clear(gl.COLOR_BUFFER_BIT);
  4745.  
  4746.     // HACK TO TEST
  4747.    
  4748.     this.stageRenderGroup.backgroundColor = stage.backgroundColorSplit;
  4749.    
  4750.     PIXI.projection.x =  this.width/2;
  4751.     PIXI.projection.y =  -this.height/2;
  4752.    
  4753.     this.stageRenderGroup.render(PIXI.projection);
  4754.    
  4755.     // interaction
  4756.     // run interaction!
  4757.     if(stage.interactive)
  4758.     {
  4759.         //need to add some events!
  4760.         if(!stage._interactiveEventsAdded)
  4761.         {
  4762.             stage._interactiveEventsAdded = true;
  4763.             stage.interactionManager.setTarget(this);
  4764.         }
  4765.     }
  4766.    
  4767.     // after rendering lets confirm all frames that have been uodated..
  4768.     if(PIXI.Texture.frameUpdates.length > 0)
  4769.     {
  4770.         for (var i=0; i < PIXI.Texture.frameUpdates.length; i++)
  4771.         {
  4772.             PIXI.Texture.frameUpdates[i].updateFrame = false;
  4773.         };
  4774.        
  4775.         PIXI.Texture.frameUpdates = [];
  4776.     }
  4777. }
  4778.  
  4779. /**
  4780.  * Updates the textures loaded into this webgl renderer
  4781.  *
  4782.  * @static
  4783.  * @method updateTextures
  4784.  * @private
  4785.  */
  4786. PIXI.WebGLRenderer.updateTextures = function()
  4787. {
  4788.     //TODO break this out into a texture manager...
  4789.     for (var i=0; i < PIXI.texturesToUpdate.length; i++) PIXI.WebGLRenderer.updateTexture(PIXI.texturesToUpdate[i]);
  4790.     for (var i=0; i < PIXI.texturesToDestroy.length; i++) PIXI.WebGLRenderer.destroyTexture(PIXI.texturesToDestroy[i]);
  4791.     PIXI.texturesToUpdate = [];
  4792.     PIXI.texturesToDestroy = [];
  4793. }
  4794.  
  4795. /**
  4796.  * Updates a loaded webgl texture
  4797.  *
  4798.  * @static
  4799.  * @method updateTexture
  4800.  * @param texture {Texture} The texture to update
  4801.  * @private
  4802.  */
  4803. PIXI.WebGLRenderer.updateTexture = function(texture)
  4804. {
  4805.     //TODO break this out into a texture manager...
  4806.     var gl = PIXI.gl;
  4807.    
  4808.     if(!texture._glTexture)
  4809.     {
  4810.         texture._glTexture = gl.createTexture();
  4811.     }
  4812.  
  4813.     if(texture.hasLoaded)
  4814.     {
  4815.         gl.bindTexture(gl.TEXTURE_2D, texture._glTexture);
  4816.         gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
  4817.  
  4818.         gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);
  4819.         gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  4820.         gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  4821.  
  4822.         // reguler...
  4823.  
  4824.         if(!texture._powerOf2)
  4825.         {
  4826.             gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  4827.             gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  4828.         }
  4829.         else
  4830.         {
  4831.             gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
  4832.             gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
  4833.         }
  4834.  
  4835.         gl.bindTexture(gl.TEXTURE_2D, null);
  4836.     }
  4837. }
  4838.  
  4839. /**
  4840.  * Destroys a loaded webgl texture
  4841.  *
  4842.  * @method destroyTexture
  4843.  * @param texture {Texture} The texture to update
  4844.  * @private
  4845.  */
  4846. PIXI.WebGLRenderer.destroyTexture = function(texture)
  4847. {
  4848.     //TODO break this out into a texture manager...
  4849.     var gl = PIXI.gl;
  4850.  
  4851.     if(texture._glTexture)
  4852.     {
  4853.         texture._glTexture = gl.createTexture();
  4854.         gl.deleteTexture(gl.TEXTURE_2D, texture._glTexture);
  4855.     }
  4856. }
  4857.  
  4858. /**
  4859.  * resizes the webGL view to the specified width and height
  4860.  *
  4861.  * @method resize
  4862.  * @param width {Number} the new width of the webGL view
  4863.  * @param height {Number} the new height of the webGL view
  4864.  */
  4865. PIXI.WebGLRenderer.prototype.resize = function(width, height)
  4866. {
  4867.     this.width = width;
  4868.     this.height = height;
  4869.  
  4870.     this.view.width = width;
  4871.     this.view.height = height;
  4872.  
  4873.     this.gl.viewport(0, 0, this.width, this.height);   
  4874.  
  4875.     //var projectionMatrix = this.projectionMatrix;
  4876.  
  4877.     PIXI.projection.x =  this.width/2;
  4878.     PIXI.projection.y =  -this.height/2;
  4879.    
  4880.     //PIXI.size.x =  this.width/2;
  4881.     //PIXI.size.y =  -this.height/2;
  4882.  
  4883. //  projectionMatrix[0] = 2/this.width;
  4884. //  projectionMatrix[5] = -2/this.height;
  4885. //  projectionMatrix[12] = -1;
  4886. //  projectionMatrix[13] = 1;
  4887. }
  4888.  
  4889. /**
  4890.  * Handles a lost webgl context
  4891.  *
  4892.  * @method handleContextLost
  4893.  * @param event {Event}
  4894.  * @private
  4895.  */
  4896. PIXI.WebGLRenderer.prototype.handleContextLost = function(event)
  4897. {
  4898.     event.preventDefault();
  4899.     this.contextLost = true;
  4900. }
  4901.  
  4902. /**
  4903.  * Handles a restored webgl context
  4904.  *
  4905.  * @method handleContextRestored
  4906.  * @param event {Event}
  4907.  * @private
  4908.  */
  4909. PIXI.WebGLRenderer.prototype.handleContextRestored = function(event)
  4910. {
  4911.     this.gl = this.view.getContext("experimental-webgl",  {    
  4912.         alpha: true
  4913.     });
  4914.  
  4915.     this.initShaders();
  4916.  
  4917.     for(var key in PIXI.TextureCache)
  4918.     {
  4919.             var texture = PIXI.TextureCache[key].baseTexture;
  4920.             texture._glTexture = null;
  4921.             PIXI.WebGLRenderer.updateTexture(texture);
  4922.     };
  4923.  
  4924.     for (var i=0; i <  this.batchs.length; i++)
  4925.     {
  4926.         this.batchs[i].restoreLostContext(this.gl)//
  4927.         this.batchs[i].dirty = true;
  4928.     };
  4929.  
  4930.     PIXI._restoreBatchs(this.gl);
  4931.  
  4932.     this.contextLost = false;
  4933. }
  4934.  
  4935. /**
  4936.  * @author Mat Groves http://matgroves.com/ @Doormat23
  4937.  */
  4938.  
  4939. PIXI._batchs = [];
  4940.  
  4941. /**
  4942.  * @private
  4943.  */
  4944. PIXI._getBatch = function(gl)
  4945. {
  4946.     if(PIXI._batchs.length == 0)
  4947.     {
  4948.         return new PIXI.WebGLBatch(gl);
  4949.     }
  4950.     else
  4951.     {
  4952.         return PIXI._batchs.pop();
  4953.     }
  4954. }
  4955.  
  4956. /**
  4957.  * @private
  4958.  */
  4959. PIXI._returnBatch = function(batch)
  4960. {
  4961.     batch.clean(); 
  4962.     PIXI._batchs.push(batch);
  4963. }
  4964.  
  4965. /**
  4966.  * @private
  4967.  */
  4968. PIXI._restoreBatchs = function(gl)
  4969. {
  4970.     for (var i=0; i < PIXI._batchs.length; i++)
  4971.     {
  4972.       PIXI._batchs[i].restoreLostContext(gl);
  4973.     };
  4974. }
  4975.  
  4976. /**
  4977.  * A WebGLBatch Enables a group of sprites to be drawn using the same settings.
  4978.  * if a group of sprites all have the same baseTexture and blendMode then they can be grouped into a batch.
  4979.  * All the sprites in a batch can then be drawn in one go by the GPU which is hugely efficient. ALL sprites
  4980.  * in the webGL renderer are added to a batch even if the batch only contains one sprite. Batching is handled
  4981.  * automatically by the webGL renderer. A good tip is: the smaller the number of batchs there are, the faster
  4982.  * the webGL renderer will run.
  4983.  *
  4984.  * @class WebGLBatch
  4985.  * @constructor
  4986.  * @param gl {WebGLContext} an instance of the webGL context
  4987.  */
  4988. PIXI.WebGLBatch = function(gl)
  4989. {
  4990.     this.gl = gl;
  4991.    
  4992.     this.size = 0;
  4993.  
  4994.     this.vertexBuffer =  gl.createBuffer();
  4995.     this.indexBuffer =  gl.createBuffer();
  4996.     this.uvBuffer =  gl.createBuffer();
  4997.     this.colorBuffer =  gl.createBuffer();
  4998.     this.blendMode = PIXI.blendModes.NORMAL;
  4999.     this.dynamicSize = 1;
  5000. }
  5001.  
  5002. // constructor
  5003. PIXI.WebGLBatch.prototype.constructor = PIXI.WebGLBatch;
  5004.  
  5005. /**
  5006.  * Cleans the batch so that is can be returned to an object pool and reused
  5007.  *
  5008.  * @method clean
  5009.  */
  5010. PIXI.WebGLBatch.prototype.clean = function()
  5011. {
  5012.     this.verticies = [];
  5013.     this.uvs = [];
  5014.     this.indices = [];
  5015.     this.colors = [];
  5016.     this.dynamicSize = 1;
  5017.     this.texture = null;
  5018.     this.last = null;
  5019.     this.size = 0;
  5020.     this.head;
  5021.     this.tail;
  5022. }
  5023.  
  5024. /**
  5025.  * Recreates the buffers in the event of a context loss
  5026.  *
  5027.  * @method restoreLostContext
  5028.  * @param gl {WebGLContext}
  5029.  */
  5030. PIXI.WebGLBatch.prototype.restoreLostContext = function(gl)
  5031. {
  5032.     this.gl = gl;
  5033.     this.vertexBuffer =  gl.createBuffer();
  5034.     this.indexBuffer =  gl.createBuffer();
  5035.     this.uvBuffer =  gl.createBuffer();
  5036.     this.colorBuffer =  gl.createBuffer();
  5037. }
  5038.  
  5039. /**
  5040.  * inits the batch's texture and blend mode based if the supplied sprite
  5041.  *
  5042.  * @method init
  5043.  * @param sprite {Sprite} the first sprite to be added to the batch. Only sprites with
  5044.  *      the same base texture and blend mode will be allowed to be added to this batch
  5045.  */
  5046. PIXI.WebGLBatch.prototype.init = function(sprite)
  5047. {
  5048.     sprite.batch = this;
  5049.     this.dirty = true;
  5050.     this.blendMode = sprite.blendMode;
  5051.     this.texture = sprite.texture.baseTexture;
  5052.     this.head = sprite;
  5053.     this.tail = sprite;
  5054.     this.size = 1;
  5055.  
  5056.     this.growBatch();
  5057. }
  5058.  
  5059. /**
  5060.  * inserts a sprite before the specified sprite
  5061.  *
  5062.  * @method insertBefore
  5063.  * @param sprite {Sprite} the sprite to be added
  5064.  * @param nextSprite {nextSprite} the first sprite will be inserted before this sprite
  5065.  */
  5066. PIXI.WebGLBatch.prototype.insertBefore = function(sprite, nextSprite)
  5067. {
  5068.     this.size++;
  5069.  
  5070.     sprite.batch = this;
  5071.     this.dirty = true;
  5072.     var tempPrev = nextSprite.__prev;
  5073.     nextSprite.__prev = sprite;
  5074.     sprite.__next = nextSprite;
  5075.  
  5076.     if(tempPrev)
  5077.     {
  5078.         sprite.__prev = tempPrev;
  5079.         tempPrev.__next = sprite;
  5080.     }
  5081.     else
  5082.     {
  5083.         this.head = sprite;
  5084.     }
  5085. }
  5086.  
  5087. /**
  5088.  * inserts a sprite after the specified sprite
  5089.  *
  5090.  * @method insertAfter
  5091.  * @param sprite {Sprite} the sprite to be added
  5092.  * @param  previousSprite {Sprite} the first sprite will be inserted after this sprite
  5093.  */
  5094. PIXI.WebGLBatch.prototype.insertAfter = function(sprite, previousSprite)
  5095. {
  5096.     this.size++;
  5097.  
  5098.     sprite.batch = this;
  5099.     this.dirty = true;
  5100.  
  5101.     var tempNext = previousSprite.__next;
  5102.     previousSprite.__next = sprite;
  5103.     sprite.__prev = previousSprite;
  5104.  
  5105.     if(tempNext)
  5106.     {
  5107.         sprite.__next = tempNext;
  5108.         tempNext.__prev = sprite;
  5109.     }
  5110.     else
  5111.     {
  5112.         this.tail = sprite
  5113.     }
  5114. }
  5115.  
  5116. /**
  5117.  * removes a sprite from the batch
  5118.  *
  5119.  * @method remove
  5120.  * @param sprite {Sprite} the sprite to be removed
  5121.  */
  5122. PIXI.WebGLBatch.prototype.remove = function(sprite)
  5123. {
  5124.     this.size--;
  5125.  
  5126.     if(this.size == 0)
  5127.     {
  5128.         sprite.batch = null;
  5129.         sprite.__prev = null;
  5130.         sprite.__next = null;
  5131.         return;
  5132.     }
  5133.  
  5134.     if(sprite.__prev)
  5135.     {
  5136.         sprite.__prev.__next = sprite.__next;
  5137.     }
  5138.     else
  5139.     {
  5140.         this.head = sprite.__next;
  5141.         this.head.__prev = null;
  5142.     }
  5143.  
  5144.     if(sprite.__next)
  5145.     {
  5146.         sprite.__next.__prev = sprite.__prev;
  5147.     }
  5148.     else
  5149.     {
  5150.         this.tail = sprite.__prev;
  5151.         this.tail.__next = null
  5152.     }
  5153.  
  5154.     sprite.batch = null;
  5155.     sprite.__next = null;
  5156.     sprite.__prev = null;
  5157.     this.dirty = true;
  5158. }
  5159.  
  5160. /**
  5161.  * Splits the batch into two with the specified sprite being the start of the new batch.
  5162.  *
  5163.  * @method split
  5164.  * @param sprite {Sprite} the sprite that indicates where the batch should be split
  5165.  * @return {WebGLBatch} the new batch
  5166.  */
  5167. PIXI.WebGLBatch.prototype.split = function(sprite)
  5168. {
  5169.     this.dirty = true;
  5170.  
  5171.     var batch = new PIXI.WebGLBatch(this.gl);
  5172.     batch.init(sprite);
  5173.     batch.texture = this.texture;
  5174.     batch.tail = this.tail;
  5175.  
  5176.     this.tail = sprite.__prev;
  5177.     this.tail.__next = null;
  5178.  
  5179.     sprite.__prev = null;
  5180.     // return a splite batch!
  5181.  
  5182.     // TODO this size is wrong!
  5183.     // need to recalculate :/ problem with a linked list!
  5184.     // unless it gets calculated in the "clean"?
  5185.  
  5186.     // need to loop through items as there is no way to know the length on a linked list :/
  5187.     var tempSize = 0;
  5188.     while(sprite)
  5189.     {
  5190.         tempSize++;
  5191.         sprite.batch = batch;
  5192.         sprite = sprite.__next;
  5193.     }
  5194.  
  5195.     batch.size = tempSize;
  5196.     this.size -= tempSize;
  5197.  
  5198.     return batch;
  5199. }
  5200.  
  5201. /**
  5202.  * Merges two batchs together
  5203.  *
  5204.  * @method merge
  5205.  * @param batch {WebGLBatch} the batch that will be merged
  5206.  */
  5207. PIXI.WebGLBatch.prototype.merge = function(batch)
  5208. {
  5209.     this.dirty = true;
  5210.  
  5211.     this.tail.__next = batch.head;
  5212.     batch.head.__prev = this.tail;
  5213.  
  5214.     this.size += batch.size;
  5215.  
  5216.     this.tail = batch.tail;
  5217.  
  5218.     var sprite = batch.head;
  5219.     while(sprite)
  5220.     {
  5221.         sprite.batch = this;
  5222.         sprite = sprite.__next;
  5223.     }
  5224. }
  5225.  
  5226. /**
  5227.  * Grows the size of the batch. As the elements in the batch cannot have a dynamic size this
  5228.  * function is used to increase the size of the batch. It also creates a little extra room so
  5229.  * that the batch does not need to be resized every time a sprite is added
  5230.  *
  5231.  * @method growBatch
  5232.  */
  5233. PIXI.WebGLBatch.prototype.growBatch = function()
  5234. {
  5235.     var gl = this.gl;
  5236.     if( this.size == 1)
  5237.     {
  5238.         this.dynamicSize = 1;
  5239.     }
  5240.     else
  5241.     {
  5242.         this.dynamicSize = this.size * 1.5
  5243.     }
  5244.     // grow verts
  5245.     this.verticies = new Float32Array(this.dynamicSize * 8);
  5246.  
  5247.     gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
  5248.     gl.bufferData(gl.ARRAY_BUFFER,this.verticies , gl.DYNAMIC_DRAW);
  5249.  
  5250.     this.uvs  = new Float32Array( this.dynamicSize * 8 );
  5251.     gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
  5252.     gl.bufferData(gl.ARRAY_BUFFER, this.uvs , gl.DYNAMIC_DRAW);
  5253.  
  5254.     this.dirtyUVS = true;
  5255.  
  5256.     this.colors  = new Float32Array( this.dynamicSize * 4 );
  5257.     gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer);
  5258.     gl.bufferData(gl.ARRAY_BUFFER, this.colors , gl.DYNAMIC_DRAW);
  5259.  
  5260.     this.dirtyColors = true;
  5261.  
  5262.     this.indices = new Uint16Array(this.dynamicSize * 6);
  5263.     var length = this.indices.length/6;
  5264.  
  5265.     for (var i=0; i < length; i++)
  5266.     {
  5267.         var index2 = i * 6;
  5268.         var index3 = i * 4;
  5269.         this.indices[index2 + 0] = index3 + 0;
  5270.         this.indices[index2 + 1] = index3 + 1;
  5271.         this.indices[index2 + 2] = index3 + 2;
  5272.         this.indices[index2 + 3] = index3 + 0;
  5273.         this.indices[index2 + 4] = index3 + 2;
  5274.         this.indices[index2 + 5] = index3 + 3;
  5275.     };
  5276.  
  5277.     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
  5278.     gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW);
  5279. }
  5280.  
  5281. /**
  5282.  * Refresh's all the data in the batch and sync's it with the webGL buffers
  5283.  *
  5284.  * @method refresh
  5285.  */
  5286. PIXI.WebGLBatch.prototype.refresh = function()
  5287. {
  5288.     var gl = this.gl;
  5289.  
  5290.     if (this.dynamicSize < this.size)
  5291.     {
  5292.         this.growBatch();
  5293.     }
  5294.  
  5295.     var indexRun = 0;
  5296.     var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index;
  5297.     var a, b, c, d, tx, ty;
  5298.  
  5299.     var displayObject = this.head;
  5300.  
  5301.     while(displayObject)
  5302.     {
  5303.         index = indexRun * 8;
  5304.  
  5305.         var texture = displayObject.texture;
  5306.  
  5307.         var frame = texture.frame;
  5308.         var tw = texture.baseTexture.width;
  5309.         var th = texture.baseTexture.height;
  5310.  
  5311.         this.uvs[index + 0] = frame.x / tw;
  5312.         this.uvs[index +1] = frame.y / th;
  5313.  
  5314.         this.uvs[index +2] = (frame.x + frame.width) / tw;
  5315.         this.uvs[index +3] = frame.y / th;
  5316.  
  5317.         this.uvs[index +4] = (frame.x + frame.width) / tw;
  5318.         this.uvs[index +5] = (frame.y + frame.height) / th;
  5319.  
  5320.         this.uvs[index +6] = frame.x / tw;
  5321.         this.uvs[index +7] = (frame.y + frame.height) / th;
  5322.  
  5323.         displayObject.updateFrame = false;
  5324.  
  5325.         colorIndex = indexRun * 4;
  5326.         this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha;
  5327.  
  5328.         displayObject = displayObject.__next;
  5329.  
  5330.         indexRun ++;
  5331.     }
  5332.  
  5333.     this.dirtyUVS = true;
  5334.     this.dirtyColors = true;
  5335. }
  5336.  
  5337. /**
  5338.  * Updates all the relevant geometry and uploads the data to the GPU
  5339.  *
  5340.  * @method update
  5341.  */
  5342. PIXI.WebGLBatch.prototype.update = function()
  5343. {
  5344.     var gl = this.gl;
  5345.     var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index, index2, index3
  5346.  
  5347.     var a, b, c, d, tx, ty;
  5348.  
  5349.     var indexRun = 0;
  5350.  
  5351.     var displayObject = this.head;
  5352.     var verticies = this.verticies;
  5353.     var uvs = this.uvs;
  5354.     var colors = this.colors;
  5355.    
  5356.     while(displayObject)
  5357.     {
  5358.         if(displayObject.vcount === PIXI.visibleCount)
  5359.         {
  5360.             width = displayObject.texture.frame.width;
  5361.             height = displayObject.texture.frame.height;
  5362.  
  5363.             // TODO trim??
  5364.             aX = displayObject.anchor.x;// - displayObject.texture.trim.x
  5365.             aY = displayObject.anchor.y; //- displayObject.texture.trim.y
  5366.             w0 = width * (1-aX);
  5367.             w1 = width * -aX;
  5368.  
  5369.             h0 = height * (1-aY);
  5370.             h1 = height * -aY;
  5371.  
  5372.             index = indexRun * 8;
  5373.  
  5374.             worldTransform = displayObject.worldTransform;
  5375.  
  5376.             a = worldTransform[0];
  5377.             b = worldTransform[3];
  5378.             c = worldTransform[1];
  5379.             d = worldTransform[4];
  5380.             tx = worldTransform[2];
  5381.             ty = worldTransform[5];
  5382.  
  5383.             verticies[index + 0 ] = a * w1 + c * h1 + tx;
  5384.             verticies[index + 1 ] = d * h1 + b * w1 + ty;
  5385.  
  5386.             verticies[index + 2 ] = a * w0 + c * h1 + tx;
  5387.             verticies[index + 3 ] = d * h1 + b * w0 + ty;
  5388.  
  5389.             verticies[index + 4 ] = a * w0 + c * h0 + tx;
  5390.             verticies[index + 5 ] = d * h0 + b * w0 + ty;
  5391.  
  5392.             verticies[index + 6] =  a * w1 + c * h0 + tx;
  5393.             verticies[index + 7] =  d * h0 + b * w1 + ty;
  5394.  
  5395.             if(displayObject.updateFrame || displayObject.texture.updateFrame)
  5396.             {
  5397.                 this.dirtyUVS = true;
  5398.  
  5399.                 var texture = displayObject.texture;
  5400.  
  5401.                 var frame = texture.frame;
  5402.                 var tw = texture.baseTexture.width;
  5403.                 var th = texture.baseTexture.height;
  5404.  
  5405.                 uvs[index + 0] = frame.x / tw;
  5406.                 uvs[index +1] = frame.y / th;
  5407.  
  5408.                 uvs[index +2] = (frame.x + frame.width) / tw;
  5409.                 uvs[index +3] = frame.y / th;
  5410.  
  5411.                 uvs[index +4] = (frame.x + frame.width) / tw;
  5412.                 uvs[index +5] = (frame.y + frame.height) / th;
  5413.  
  5414.                 uvs[index +6] = frame.x / tw;
  5415.                 uvs[index +7] = (frame.y + frame.height) / th;
  5416.  
  5417.                 displayObject.updateFrame = false;
  5418.             }
  5419.  
  5420.             // TODO this probably could do with some optimisation....
  5421.             if(displayObject.cacheAlpha != displayObject.worldAlpha)
  5422.             {
  5423.                 displayObject.cacheAlpha = displayObject.worldAlpha;
  5424.  
  5425.                 var colorIndex = indexRun * 4;
  5426.                 colors[colorIndex] = colors[colorIndex + 1] = colors[colorIndex + 2] = colors[colorIndex + 3] = displayObject.worldAlpha;
  5427.                 this.dirtyColors = true;
  5428.             }
  5429.         }
  5430.         else
  5431.         {
  5432.             index = indexRun * 8;
  5433.  
  5434.             verticies[index + 0 ] = verticies[index + 1 ] = verticies[index + 2 ] = verticies[index + 3 ] = verticies[index + 4 ] = verticies[index + 5 ] = verticies[index + 6] =  verticies[index + 7] = 0;
  5435.         }
  5436.  
  5437.         indexRun++;
  5438.         displayObject = displayObject.__next;
  5439.    }
  5440. }
  5441.  
  5442. /**
  5443.  * Draws the batch to the frame buffer
  5444.  *
  5445.  * @method render
  5446.  */
  5447. PIXI.WebGLBatch.prototype.render = function(start, end)
  5448. {
  5449.     start = start || 0;
  5450.  
  5451.     if(end == undefined)end = this.size;
  5452.    
  5453.     if(this.dirty)
  5454.     {
  5455.         this.refresh();
  5456.         this.dirty = false;
  5457.     }
  5458.  
  5459.     if (this.size == 0)return;
  5460.  
  5461.     this.update();
  5462.     var gl = this.gl;
  5463.  
  5464.     //TODO optimize this!
  5465.  
  5466.     var shaderProgram = PIXI.defaultShader;
  5467.    
  5468.     //gl.useProgram(shaderProgram);
  5469.  
  5470.     // update the verts..
  5471.     gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
  5472.     // ok..
  5473.     gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.verticies)
  5474.     gl.vertexAttribPointer(shaderProgram.aVertexPosition, 2, gl.FLOAT, false, 0, 0);
  5475.     // update the uvs
  5476.     //var isDefault = (shaderProgram == PIXI.shaderProgram)
  5477.  
  5478.     gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
  5479.  
  5480.     if(this.dirtyUVS)
  5481.     {
  5482.         this.dirtyUVS = false;
  5483.         gl.bufferSubData(gl.ARRAY_BUFFER,  0, this.uvs);
  5484.     }
  5485.  
  5486.     gl.vertexAttribPointer(shaderProgram.aTextureCoord, 2, gl.FLOAT, false, 0, 0);
  5487.  
  5488.     gl.activeTexture(gl.TEXTURE0);
  5489.     gl.bindTexture(gl.TEXTURE_2D, this.texture._glTexture);
  5490.  
  5491.     // update color!
  5492.     gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer);
  5493.  
  5494.     if(this.dirtyColors)
  5495.     {
  5496.         this.dirtyColors = false;
  5497.         gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.colors);
  5498.     }
  5499.  
  5500.     gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0);
  5501.     // dont need to upload!
  5502.     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
  5503.  
  5504.     var len = end - start;
  5505.  
  5506.     // DRAW THAT this!
  5507.     gl.drawElements(gl.TRIANGLES, len * 6, gl.UNSIGNED_SHORT, start * 2 * 6 );
  5508. }
  5509.  
  5510. /**
  5511.  * @author Mat Groves http://matgroves.com/ @Doormat23
  5512.  */
  5513.  
  5514. /**
  5515.  * A WebGLBatch Enables a group of sprites to be drawn using the same settings.
  5516.  * if a group of sprites all have the same baseTexture and blendMode then they can be
  5517.  * grouped into a batch. All the sprites in a batch can then be drawn in one go by the
  5518.  * GPU which is hugely efficient. ALL sprites in the webGL renderer are added to a batch
  5519.  * even if the batch only contains one sprite. Batching is handled automatically by the
  5520.  * webGL renderer. A good tip is: the smaller the number of batchs there are, the faster
  5521.  * the webGL renderer will run.
  5522.  *
  5523.  * @class WebGLBatch
  5524.  * @contructor
  5525.  * @param gl {WebGLContext} An instance of the webGL context
  5526.  */
  5527. PIXI.WebGLRenderGroup = function(gl, transparent)
  5528. {
  5529.     this.gl = gl;
  5530.     this.root;
  5531.    
  5532.     this.backgroundColor;
  5533.     this.transparent = transparent == undefined ? true : transparent;
  5534.    
  5535.     this.batchs = [];
  5536.     this.toRemove = [];
  5537.     console.log(this.transparent)
  5538.     this.filterManager = new PIXI.WebGLFilterManager(this.transparent);
  5539. }
  5540.  
  5541. // constructor
  5542. PIXI.WebGLRenderGroup.prototype.constructor = PIXI.WebGLRenderGroup;
  5543.  
  5544. /**
  5545.  * Add a display object to the webgl renderer
  5546.  *
  5547.  * @method setRenderable
  5548.  * @param displayObject {DisplayObject}
  5549.  * @private
  5550.  */
  5551. PIXI.WebGLRenderGroup.prototype.setRenderable = function(displayObject)
  5552. {
  5553.     // has this changed??
  5554.     if(this.root)this.removeDisplayObjectAndChildren(this.root);
  5555.    
  5556.     displayObject.worldVisible = displayObject.visible;
  5557.    
  5558.     // soooooo //
  5559.     // to check if any batchs exist already??
  5560.    
  5561.     // TODO what if its already has an object? should remove it
  5562.     this.root = displayObject;
  5563.     this.addDisplayObjectAndChildren(displayObject);
  5564. }
  5565.  
  5566. /**
  5567.  * Renders the stage to its webgl view
  5568.  *
  5569.  * @method render
  5570.  * @param projection {Object}
  5571.  */
  5572. PIXI.WebGLRenderGroup.prototype.render = function(projection, buffer)
  5573. {
  5574.     PIXI.WebGLRenderer.updateTextures();
  5575.    
  5576.     var gl = this.gl;
  5577.     gl.uniform2f(PIXI.defaultShader.projectionVector, projection.x, projection.y);
  5578.  
  5579.     this.filterManager.begin(projection, buffer);
  5580.  
  5581.    
  5582.     gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
  5583.     // will render all the elements in the group
  5584.     var renderable;
  5585.  
  5586.     for (var i=0; i < this.batchs.length; i++)
  5587.     {
  5588.        
  5589.         renderable = this.batchs[i];
  5590.         if(renderable instanceof PIXI.WebGLBatch)
  5591.         {
  5592.             this.batchs[i].render();
  5593.             continue;
  5594.         }
  5595.        
  5596.         // render special
  5597.         this.renderSpecial(renderable, projection);
  5598.     }
  5599.    
  5600. }
  5601.  
  5602. /**
  5603.  * Renders a specific displayObject
  5604.  *
  5605.  * @method renderSpecific
  5606.  * @param displayObject {DisplayObject}
  5607.  * @param projection {Object}
  5608.  * @private
  5609.  */
  5610. PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection, buffer)
  5611. {
  5612.     PIXI.WebGLRenderer.updateTextures();
  5613.     var gl = this.gl;
  5614.  
  5615.     gl.uniform2f(PIXI.defaultShader.projectionVector, projection.x, projection.y);
  5616.  
  5617.     this.filterManager.begin(projection, buffer);
  5618.  
  5619.     // to do!
  5620.     // render part of the scene...
  5621.    
  5622.     var startIndex;
  5623.     var startBatchIndex;
  5624.    
  5625.     var endIndex;
  5626.     var endBatchIndex;
  5627.    
  5628.     /*
  5629.      *  LOOK FOR THE NEXT SPRITE
  5630.      *  This part looks for the closest next sprite that can go into a batch
  5631.      *  it keeps looking until it finds a sprite or gets to the end of the display
  5632.      *  scene graph
  5633.      */
  5634.     var nextRenderable = displayObject.first;
  5635.     while(nextRenderable._iNext)
  5636.     {
  5637.         if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
  5638.         nextRenderable = nextRenderable._iNext;
  5639.     }
  5640.     var startBatch = nextRenderable.batch;
  5641.     //console.log(nextRenderable);
  5642.    
  5643.     //console.log(renderable)
  5644.     if(nextRenderable instanceof PIXI.Sprite)
  5645.     {
  5646.         startBatch = nextRenderable.batch;
  5647.        
  5648.         var head = startBatch.head;
  5649.         var next = head;
  5650.        
  5651.         // ok now we have the batch.. need to find the start index!
  5652.         if(head == nextRenderable)
  5653.         {
  5654.             startIndex = 0;
  5655.         }
  5656.         else
  5657.         {
  5658.             startIndex = 1;
  5659.            
  5660.             while(head.__next != nextRenderable)
  5661.             {
  5662.                 startIndex++;
  5663.                 head = head.__next;
  5664.             }
  5665.         }
  5666.     }
  5667.     else
  5668.     {
  5669.         startBatch = nextRenderable;
  5670.     }
  5671.    
  5672.     // Get the LAST renderable object
  5673.     var lastRenderable = displayObject.last;
  5674.     while(lastRenderable._iPrev)
  5675.     {
  5676.         if(lastRenderable.renderable && lastRenderable.__renderGroup)break;
  5677.         lastRenderable = lastRenderable._iNext;
  5678.     }
  5679.    
  5680.     if(lastRenderable instanceof PIXI.Sprite)
  5681.     {
  5682.         endBatch = lastRenderable.batch;
  5683.        
  5684.         var head = endBatch.head;
  5685.        
  5686.         if(head == lastRenderable)
  5687.         {
  5688.             endIndex = 0;
  5689.         }
  5690.         else
  5691.         {
  5692.             endIndex = 1;
  5693.            
  5694.             while(head.__next != lastRenderable)
  5695.             {
  5696.                 endIndex++;
  5697.                 head = head.__next;
  5698.             }
  5699.         }
  5700.     }
  5701.     else
  5702.     {
  5703.         endBatch = lastRenderable;
  5704.     }
  5705.    
  5706.     //console.log(endBatch);
  5707.     // TODO - need to fold this up a bit!
  5708.    
  5709.     if(startBatch == endBatch)
  5710.     {
  5711.         if(startBatch instanceof PIXI.WebGLBatch)
  5712.         {
  5713.             startBatch.render(startIndex, endIndex+1);
  5714.         }
  5715.         else
  5716.         {
  5717.             this.renderSpecial(startBatch, projection);
  5718.         }
  5719.         return;
  5720.     }
  5721.    
  5722.     // now we have first and last!
  5723.     startBatchIndex = this.batchs.indexOf(startBatch);
  5724.     endBatchIndex = this.batchs.indexOf(endBatch);
  5725.    
  5726.     // DO the first batch
  5727.     if(startBatch instanceof PIXI.WebGLBatch)
  5728.     {
  5729.         startBatch.render(startIndex);
  5730.     }
  5731.     else
  5732.     {
  5733.         this.renderSpecial(startBatch, projection);
  5734.     }
  5735.    
  5736.     // DO the middle batchs..
  5737.     for (var i=startBatchIndex+1; i < endBatchIndex; i++)
  5738.     {
  5739.         renderable = this.batchs[i];
  5740.    
  5741.         if(renderable instanceof PIXI.WebGLBatch)
  5742.         {
  5743.             this.batchs[i].render();
  5744.         }
  5745.         else
  5746.         {
  5747.             this.renderSpecial(renderable, projection);
  5748.         }
  5749.     }
  5750.    
  5751.     // DO the last batch..
  5752.     if(endBatch instanceof PIXI.WebGLBatch)
  5753.     {
  5754.         endBatch.render(0, endIndex+1);
  5755.     }
  5756.     else
  5757.     {
  5758.         this.renderSpecial(endBatch, projection);
  5759.     }
  5760. }
  5761.  
  5762. /**
  5763.  * Renders a specific renderable
  5764.  *
  5765.  * @method renderSpecial
  5766.  * @param renderable {DisplayObject}
  5767.  * @param projection {Object}
  5768.  * @private
  5769.  */
  5770. PIXI.WebGLRenderGroup.prototype.renderSpecial = function(renderable, projection)
  5771. {
  5772.    
  5773.     var worldVisible = renderable.vcount === PIXI.visibleCount
  5774.  
  5775.  
  5776.     if(renderable instanceof PIXI.TilingSprite)
  5777.     {
  5778.         if(worldVisible)this.renderTilingSprite(renderable, projection);
  5779.     }
  5780.     else if(renderable instanceof PIXI.Strip)
  5781.     {
  5782.         if(worldVisible)this.renderStrip(renderable, projection);
  5783.     }
  5784.     else if(renderable instanceof PIXI.CustomRenderable)
  5785.     {
  5786.         if(worldVisible) renderable.renderWebGL(this, projection);
  5787.     }
  5788.     else if(renderable instanceof PIXI.Graphics)
  5789.     {
  5790.         if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);
  5791.     }
  5792.     else if(renderable instanceof PIXI.FilterBlock)
  5793.     {
  5794.         this.handleFilterBlock(renderable, projection);
  5795.     }
  5796. }
  5797.  
  5798. flip = false;
  5799. var maskStack = [];
  5800. var maskPosition = 0;
  5801.  
  5802. //var usedMaskStack = [];
  5803.  
  5804. PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(filterBlock, projection)
  5805. {
  5806.     /*
  5807.      * for now only masks are supported..
  5808.      */
  5809.     var gl = PIXI.gl;
  5810.    
  5811.     if(filterBlock.open)
  5812.     {
  5813.         if(filterBlock.data instanceof Array)
  5814.         {
  5815.             this.filterManager.pushFilter(filterBlock);
  5816.             // ok so..
  5817.            
  5818.         }
  5819.         else
  5820.         {  
  5821.             maskPosition++;
  5822.  
  5823.             maskStack.push(filterBlock)
  5824.    
  5825.             gl.enable(gl.STENCIL_TEST);
  5826.            
  5827.             gl.colorMask(false, false, false, false);
  5828.            
  5829.             gl.stencilFunc(gl.ALWAYS,1,1);
  5830.             gl.stencilOp(gl.KEEP,gl.KEEP,gl.INCR);
  5831.    
  5832.             PIXI.WebGLGraphics.renderGraphics(filterBlock.data, projection);
  5833.            
  5834.             gl.colorMask(true, true, true, true);
  5835.             gl.stencilFunc(gl.NOTEQUAL,0,maskStack.length);
  5836.             gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
  5837.         }
  5838.     }
  5839.     else
  5840.     {
  5841.         if(filterBlock.data instanceof Array)
  5842.         {
  5843.             this.filterManager.popFilter();
  5844.         }
  5845.         else
  5846.         {
  5847.             var maskData = maskStack.pop(filterBlock)
  5848.  
  5849.  
  5850.             if(maskData)
  5851.             {
  5852.                 gl.colorMask(false, false, false, false);
  5853.            
  5854.                 gl.stencilFunc(gl.ALWAYS,1,1);
  5855.                 gl.stencilOp(gl.KEEP,gl.KEEP,gl.DECR);
  5856.  
  5857.                 PIXI.WebGLGraphics.renderGraphics(maskData.data, projection);
  5858.            
  5859.                 gl.colorMask(true, true, true, true);
  5860.                 gl.stencilFunc(gl.NOTEQUAL,0,maskStack.length);
  5861.                 gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
  5862.             };
  5863.  
  5864.             gl.disable(gl.STENCIL_TEST);
  5865.         }
  5866.     }
  5867. }
  5868.  
  5869. /**
  5870.  * Updates a webgl texture
  5871.  *
  5872.  * @method updateTexture
  5873.  * @param displayObject {DisplayObject}
  5874.  * @private
  5875.  */
  5876. PIXI.WebGLRenderGroup.prototype.updateTexture = function(displayObject)
  5877. {
  5878.    
  5879.     // TODO definitely can optimse this function..
  5880.    
  5881.     this.removeObject(displayObject);
  5882.    
  5883.     /*
  5884.      *  LOOK FOR THE PREVIOUS RENDERABLE
  5885.      *  This part looks for the closest previous sprite that can go into a batch
  5886.      *  It keeps going back until it finds a sprite or the stage
  5887.      */
  5888.     var previousRenderable = displayObject.first;
  5889.     while(previousRenderable != this.root)
  5890.     {
  5891.         previousRenderable = previousRenderable._iPrev;
  5892.         if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
  5893.     }
  5894.    
  5895.     /*
  5896.      *  LOOK FOR THE NEXT SPRITE
  5897.      *  This part looks for the closest next sprite that can go into a batch
  5898.      *  it keeps looking until it finds a sprite or gets to the end of the display
  5899.      *  scene graph
  5900.      */
  5901.     var nextRenderable = displayObject.last;
  5902.     while(nextRenderable._iNext)
  5903.     {
  5904.         nextRenderable = nextRenderable._iNext;
  5905.         if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
  5906.     }
  5907.    
  5908.     this.insertObject(displayObject, previousRenderable, nextRenderable);
  5909. }
  5910.  
  5911. /**
  5912.  * Adds filter blocks
  5913.  *
  5914.  * @method addFilterBlocks
  5915.  * @param start {FilterBlock}
  5916.  * @param end {FilterBlock}
  5917.  * @private
  5918.  */
  5919. PIXI.WebGLRenderGroup.prototype.addFilterBlocks = function(start, end)
  5920. {
  5921.     start.__renderGroup = this;
  5922.     end.__renderGroup = this;
  5923.     /*
  5924.      *  LOOK FOR THE PREVIOUS RENDERABLE
  5925.      *  This part looks for the closest previous sprite that can go into a batch
  5926.      *  It keeps going back until it finds a sprite or the stage
  5927.      */
  5928.     var previousRenderable = start;
  5929.     while(previousRenderable != this.root.first)
  5930.     {
  5931.         previousRenderable = previousRenderable._iPrev;
  5932.         if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
  5933.     }
  5934.     this.insertAfter(start, previousRenderable);
  5935.        
  5936.     /*
  5937.      *  LOOK FOR THE NEXT SPRITE
  5938.      *  This part looks for the closest next sprite that can go into a batch
  5939.      *  it keeps looking until it finds a sprite or gets to the end of the display
  5940.      *  scene graph
  5941.      */
  5942.     var previousRenderable2 = end;
  5943.     while(previousRenderable2 != this.root.first)
  5944.     {
  5945.         previousRenderable2 = previousRenderable2._iPrev;
  5946.         if(previousRenderable2.renderable && previousRenderable2.__renderGroup)break;
  5947.     }
  5948.     this.insertAfter(end, previousRenderable2);
  5949. }
  5950.  
  5951. /**
  5952.  * Remove filter blocks
  5953.  *
  5954.  * @method removeFilterBlocks
  5955.  * @param start {FilterBlock}
  5956.  * @param end {FilterBlock}
  5957.  * @private
  5958.  */
  5959. PIXI.WebGLRenderGroup.prototype.removeFilterBlocks = function(start, end)
  5960. {
  5961.     this.removeObject(start);
  5962.     this.removeObject(end);
  5963. }
  5964.  
  5965. /**
  5966.  * Adds a display object and children to the webgl context
  5967.  *
  5968.  * @method addDisplayObjectAndChildren
  5969.  * @param displayObject {DisplayObject}
  5970.  * @private
  5971.  */
  5972. PIXI.WebGLRenderGroup.prototype.addDisplayObjectAndChildren = function(displayObject)
  5973. {
  5974.     if(displayObject.__renderGroup)displayObject.__renderGroup.removeDisplayObjectAndChildren(displayObject);
  5975.    
  5976.     /*
  5977.      *  LOOK FOR THE PREVIOUS RENDERABLE
  5978.      *  This part looks for the closest previous sprite that can go into a batch
  5979.      *  It keeps going back until it finds a sprite or the stage
  5980.      */
  5981.    
  5982.     var previousRenderable = displayObject.first;
  5983.     while(previousRenderable != this.root.first)
  5984.     {
  5985.         previousRenderable = previousRenderable._iPrev;
  5986.         if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
  5987.     }
  5988.    
  5989.     /*
  5990.      *  LOOK FOR THE NEXT SPRITE
  5991.      *  This part looks for the closest next sprite that can go into a batch
  5992.      *  it keeps looking until it finds a sprite or gets to the end of the display
  5993.      *  scene graph
  5994.      */
  5995.     var nextRenderable = displayObject.last;
  5996.     while(nextRenderable._iNext)
  5997.     {
  5998.         nextRenderable = nextRenderable._iNext;
  5999.         if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
  6000.     }
  6001.    
  6002.     // one the display object hits this. we can break the loop 
  6003.    
  6004.     var tempObject = displayObject.first;
  6005.     var testObject = displayObject.last._iNext;
  6006.     do 
  6007.     {
  6008.         tempObject.__renderGroup = this;
  6009.        
  6010.         if(tempObject.renderable)
  6011.         {
  6012.        
  6013.             this.insertObject(tempObject, previousRenderable, nextRenderable);
  6014.             previousRenderable = tempObject;
  6015.         }
  6016.        
  6017.         tempObject = tempObject._iNext;
  6018.     }
  6019.     while(tempObject != testObject)
  6020. }
  6021.  
  6022. /**
  6023.  * Removes a display object and children to the webgl context
  6024.  *
  6025.  * @method removeDisplayObjectAndChildren
  6026.  * @param displayObject {DisplayObject}
  6027.  * @private
  6028.  */
  6029. PIXI.WebGLRenderGroup.prototype.removeDisplayObjectAndChildren = function(displayObject)
  6030. {
  6031.     if(displayObject.__renderGroup != this)return;
  6032.    
  6033. //  var displayObject = displayObject.first;
  6034.     var lastObject = displayObject.last;
  6035.     do 
  6036.     {
  6037.         displayObject.__renderGroup = null;
  6038.         if(displayObject.renderable)this.removeObject(displayObject);
  6039.         displayObject = displayObject._iNext;
  6040.     }
  6041.     while(displayObject)
  6042. }
  6043.  
  6044. /**
  6045.  * Inserts a displayObject into the linked list
  6046.  *
  6047.  * @method insertObject
  6048.  * @param displayObject {DisplayObject}
  6049.  * @param previousObject {DisplayObject}
  6050.  * @param nextObject {DisplayObject}
  6051.  * @private
  6052.  */
  6053. PIXI.WebGLRenderGroup.prototype.insertObject = function(displayObject, previousObject, nextObject)
  6054. {
  6055.     // while looping below THE OBJECT MAY NOT HAVE BEEN ADDED
  6056.     var previousSprite = previousObject;
  6057.     var nextSprite = nextObject;
  6058.    
  6059.     /*
  6060.      * so now we have the next renderable and the previous renderable
  6061.      *
  6062.      */
  6063.     if(displayObject instanceof PIXI.Sprite)
  6064.     {
  6065.         var previousBatch
  6066.         var nextBatch
  6067.        
  6068.         if(previousSprite instanceof PIXI.Sprite)
  6069.         {
  6070.             previousBatch = previousSprite.batch;
  6071.             if(previousBatch)
  6072.             {
  6073.                 if(previousBatch.texture == displayObject.texture.baseTexture && previousBatch.blendMode == displayObject.blendMode)
  6074.                 {
  6075.                     previousBatch.insertAfter(displayObject, previousSprite);
  6076.                     return;
  6077.                 }
  6078.             }
  6079.         }
  6080.         else
  6081.         {
  6082.             // TODO reword!
  6083.             previousBatch = previousSprite;
  6084.         }
  6085.    
  6086.         if(nextSprite)
  6087.         {
  6088.             if(nextSprite instanceof PIXI.Sprite)
  6089.             {
  6090.                 nextBatch = nextSprite.batch;
  6091.            
  6092.                 //batch may not exist if item was added to the display list but not to the webGL
  6093.                 if(nextBatch)
  6094.                 {
  6095.                     if(nextBatch.texture == displayObject.texture.baseTexture && nextBatch.blendMode == displayObject.blendMode)
  6096.                     {
  6097.                         nextBatch.insertBefore(displayObject, nextSprite);
  6098.                         return;
  6099.                     }
  6100.                     else
  6101.                     {
  6102.                         if(nextBatch == previousBatch)
  6103.                         {
  6104.                             // THERE IS A SPLIT IN THIS BATCH! //
  6105.                             var splitBatch = previousBatch.split(nextSprite);
  6106.                             // COOL!
  6107.                             // add it back into the array  
  6108.                             /*
  6109.                              * OOPS!
  6110.                              * seems the new sprite is in the middle of a batch
  6111.                              * lets split it..
  6112.                              */
  6113.                             var batch = PIXI.WebGLRenderer.getBatch();
  6114.  
  6115.                             var index = this.batchs.indexOf( previousBatch );
  6116.                             batch.init(displayObject);
  6117.                             this.batchs.splice(index+1, 0, batch, splitBatch);
  6118.                            
  6119.                             return;
  6120.                         }
  6121.                     }
  6122.                 }
  6123.             }
  6124.             else
  6125.             {
  6126.                 // TODO re-word!
  6127.                
  6128.                 nextBatch = nextSprite;
  6129.             }
  6130.         }
  6131.        
  6132.         /*
  6133.          * looks like it does not belong to any batch!
  6134.          * but is also not intersecting one..
  6135.          * time to create anew one!
  6136.          */
  6137.        
  6138.         var batch =  PIXI.WebGLRenderer.getBatch();
  6139.         batch.init(displayObject);
  6140.  
  6141.         if(previousBatch) // if this is invalid it means
  6142.         {
  6143.             var index = this.batchs.indexOf( previousBatch );
  6144.             this.batchs.splice(index+1, 0, batch);
  6145.         }
  6146.         else
  6147.         {
  6148.             this.batchs.push(batch);
  6149.         }
  6150.        
  6151.         return;
  6152.     }
  6153.     else if(displayObject instanceof PIXI.TilingSprite)
  6154.     {
  6155.        
  6156.         // add to a batch!!
  6157.         this.initTilingSprite(displayObject);
  6158.     //  this.batchs.push(displayObject);
  6159.        
  6160.     }
  6161.     else if(displayObject instanceof PIXI.Strip)
  6162.     {
  6163.         // add to a batch!!
  6164.         this.initStrip(displayObject);
  6165.     //  this.batchs.push(displayObject);
  6166.     }
  6167.     else if(displayObject)// instanceof PIXI.Graphics)
  6168.     {
  6169.         //displayObject.initWebGL(this);
  6170.        
  6171.         // add to a batch!!
  6172.         //this.initStrip(displayObject);
  6173.         //this.batchs.push(displayObject);
  6174.     }
  6175.    
  6176.     this.insertAfter(displayObject, previousSprite);
  6177.            
  6178.     // insert and SPLIT!
  6179.  
  6180. }
  6181.  
  6182. /**
  6183.  * Inserts a displayObject into the linked list
  6184.  *
  6185.  * @method insertAfter
  6186.  * @param item {DisplayObject}
  6187.  * @param displayObject {DisplayObject} The object to insert
  6188.  * @private
  6189.  */
  6190. PIXI.WebGLRenderGroup.prototype.insertAfter = function(item, displayObject)
  6191. {
  6192.     if(displayObject instanceof PIXI.Sprite)
  6193.     {
  6194.         var previousBatch = displayObject.batch;
  6195.        
  6196.         if(previousBatch)
  6197.         {
  6198.             // so this object is in a batch!
  6199.            
  6200.             // is it not? need to split the batch
  6201.             if(previousBatch.tail == displayObject)
  6202.             {
  6203.                 // is it tail? insert in to batchs 
  6204.                 var index = this.batchs.indexOf( previousBatch );
  6205.                 this.batchs.splice(index+1, 0, item);
  6206.             }
  6207.             else
  6208.             {
  6209.                 // TODO MODIFY ADD / REMOVE CHILD TO ACCOUNT FOR FILTERS (also get prev and next) //
  6210.                
  6211.                 // THERE IS A SPLIT IN THIS BATCH! //
  6212.                 var splitBatch = previousBatch.split(displayObject.__next);
  6213.                
  6214.                 // COOL!
  6215.                 // add it back into the array  
  6216.                 /*
  6217.                  * OOPS!
  6218.                  * seems the new sprite is in the middle of a batch
  6219.                  * lets split it..
  6220.                  */
  6221.                 var index = this.batchs.indexOf( previousBatch );
  6222.                 this.batchs.splice(index+1, 0, item, splitBatch);
  6223.             }
  6224.         }
  6225.         else
  6226.         {
  6227.             this.batchs.push(item);
  6228.         }
  6229.     }
  6230.     else
  6231.     {
  6232.         var index = this.batchs.indexOf( displayObject );
  6233.         this.batchs.splice(index+1, 0, item);
  6234.     }
  6235. }
  6236.  
  6237. /**
  6238.  * Removes a displayObject from the linked list
  6239.  *
  6240.  * @method removeObject
  6241.  * @param displayObject {DisplayObject} The object to remove
  6242.  * @private
  6243.  */
  6244. PIXI.WebGLRenderGroup.prototype.removeObject = function(displayObject)
  6245. {
  6246.     // loop through children..
  6247.     // display object //
  6248.    
  6249.     // add a child from the render group..
  6250.     // remove it and all its children!
  6251.     //displayObject.cacheVisible = false;//displayObject.visible;
  6252.  
  6253.     /*
  6254.      * removing is a lot quicker..
  6255.      *
  6256.      */
  6257.     var batchToRemove;
  6258.    
  6259.     if(displayObject instanceof PIXI.Sprite)
  6260.     {
  6261.         // should always have a batch!
  6262.         var batch = displayObject.batch;
  6263.         if(!batch)return; // this means the display list has been altered befre rendering
  6264.        
  6265.         batch.remove(displayObject);
  6266.        
  6267.         if(batch.size==0)
  6268.         {
  6269.             batchToRemove = batch;
  6270.         }
  6271.     }
  6272.     else
  6273.     {
  6274.         batchToRemove = displayObject;
  6275.     }
  6276.    
  6277.     /*
  6278.      * Looks like there is somthing that needs removing!
  6279.      */
  6280.     if(batchToRemove)  
  6281.     {
  6282.         var index = this.batchs.indexOf( batchToRemove );
  6283.         if(index == -1)return;// this means it was added then removed before rendered
  6284.        
  6285.         // ok so.. check to see if you adjacent batchs should be joined.
  6286.         // TODO may optimise?
  6287.         if(index == 0 || index == this.batchs.length-1)
  6288.         {
  6289.             // wha - eva! just get of the empty batch!
  6290.             this.batchs.splice(index, 1);
  6291.             if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
  6292.        
  6293.             return;
  6294.         }
  6295.        
  6296.         if(this.batchs[index-1] instanceof PIXI.WebGLBatch && this.batchs[index+1] instanceof PIXI.WebGLBatch)
  6297.         {
  6298.             if(this.batchs[index-1].texture == this.batchs[index+1].texture && this.batchs[index-1].blendMode == this.batchs[index+1].blendMode)
  6299.             {
  6300.                 //console.log("MERGE")
  6301.                 this.batchs[index-1].merge(this.batchs[index+1]);
  6302.                
  6303.                 if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
  6304.                 PIXI.WebGLRenderer.returnBatch(this.batchs[index+1]);
  6305.                 this.batchs.splice(index, 2);
  6306.                 return;
  6307.             }
  6308.         }
  6309.        
  6310.         this.batchs.splice(index, 1);
  6311.         if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
  6312.     }
  6313. }
  6314.  
  6315.  
  6316. /**
  6317.  * Initializes a tiling sprite
  6318.  *
  6319.  * @method initTilingSprite
  6320.  * @param sprite {TilingSprite} The tiling sprite to initialize
  6321.  * @private
  6322.  */
  6323. PIXI.WebGLRenderGroup.prototype.initTilingSprite = function(sprite)
  6324. {
  6325.     var gl = this.gl;
  6326.  
  6327.     // make the texture tilable..
  6328.            
  6329.     sprite.verticies = new Float32Array([0, 0,
  6330.                                           sprite.width, 0,
  6331.                                           sprite.width,  sprite.height,
  6332.                                          0,  sprite.height]);
  6333.                    
  6334.     sprite.uvs = new Float32Array([0, 0,
  6335.                                     1, 0,
  6336.                                     1, 1,
  6337.                                     0, 1]);
  6338.                
  6339.     sprite.colors = new Float32Array([1,1,1,1]);
  6340.    
  6341.     sprite.indices =  new Uint16Array([0, 1, 3,2])//, 2]);
  6342.    
  6343.     sprite._vertexBuffer = gl.createBuffer();
  6344.     sprite._indexBuffer = gl.createBuffer();
  6345.     sprite._uvBuffer = gl.createBuffer();
  6346.     sprite._colorBuffer = gl.createBuffer();
  6347.                        
  6348.     gl.bindBuffer(gl.ARRAY_BUFFER, sprite._vertexBuffer);
  6349.     gl.bufferData(gl.ARRAY_BUFFER, sprite.verticies, gl.STATIC_DRAW);
  6350.  
  6351.     gl.bindBuffer(gl.ARRAY_BUFFER, sprite._uvBuffer);
  6352.     gl.bufferData(gl.ARRAY_BUFFER,  sprite.uvs, gl.DYNAMIC_DRAW);
  6353.  
  6354.     gl.bindBuffer(gl.ARRAY_BUFFER, sprite._colorBuffer);
  6355.     gl.bufferData(gl.ARRAY_BUFFER, sprite.colors, gl.STATIC_DRAW);
  6356.  
  6357.     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sprite._indexBuffer);
  6358.     gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, sprite.indices, gl.STATIC_DRAW);
  6359.    
  6360. //    return ( (x > 0) && ((x & (x - 1)) == 0) );
  6361.  
  6362.     if(sprite.texture.baseTexture._glTexture)
  6363.     {
  6364.         gl.bindTexture(gl.TEXTURE_2D, sprite.texture.baseTexture._glTexture);
  6365.         gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
  6366.         gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
  6367.         sprite.texture.baseTexture._powerOf2 = true;
  6368.     }
  6369.     else
  6370.     {
  6371.         sprite.texture.baseTexture._powerOf2 = true;
  6372.     }
  6373. }
  6374.  
  6375. /**
  6376.  * Renders a Strip
  6377.  *
  6378.  * @method renderStrip
  6379.  * @param strip {Strip} The strip to render
  6380.  * @param projection {Object}
  6381.  * @private
  6382.  */
  6383. PIXI.WebGLRenderGroup.prototype.renderStrip = function(strip, projection)
  6384. {
  6385.     var gl = this.gl;
  6386.  
  6387.     PIXI.activateStripShader();
  6388.  
  6389.     var shader = PIXI.stripShader;
  6390.  
  6391.     var program = shader.program;
  6392.    
  6393.     var m = PIXI.mat3.clone(strip.worldTransform);
  6394.    
  6395.     PIXI.mat3.transpose(m);
  6396.    
  6397. //  console.log(projection)
  6398.     // set the matrix transform for the
  6399.     gl.uniformMatrix3fv(shader.translationMatrix, false, m);
  6400.     gl.uniform2f(shader.projectionVector, projection.x, projection.y);
  6401.     gl.uniform2f(shader.offsetVector, -PIXI.offset.x, -PIXI.offset.y);
  6402.    
  6403.     gl.uniform1f(shader.alpha, strip.worldAlpha);
  6404.  
  6405.     /*
  6406.     if(strip.blendMode == PIXI.blendModes.NORMAL)
  6407.     {
  6408.         gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
  6409.     }
  6410.     else
  6411.     {
  6412.         gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_COLOR);
  6413.     }
  6414.     */
  6415.    
  6416.     //console.log("!!")
  6417.     if(!strip.dirty)
  6418.     {  
  6419.         gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
  6420.         gl.bufferSubData(gl.ARRAY_BUFFER, 0, strip.verticies)
  6421.         gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0);
  6422.        
  6423.         // update the uvs
  6424.         gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
  6425.         gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0);
  6426.            
  6427.         gl.activeTexture(gl.TEXTURE0);
  6428.         gl.bindTexture(gl.TEXTURE_2D, strip.texture.baseTexture._glTexture);
  6429.        
  6430.         gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
  6431.         gl.vertexAttribPointer(shader.colorAttribute, 1, gl.FLOAT, false, 0, 0);
  6432.        
  6433.         // dont need to upload!
  6434.         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
  6435.     }
  6436.     else
  6437.     {
  6438.         strip.dirty = false;
  6439.         gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
  6440.         gl.bufferData(gl.ARRAY_BUFFER, strip.verticies, gl.STATIC_DRAW)
  6441.         gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0);
  6442.        
  6443.         // update the uvs
  6444.         gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
  6445.         gl.bufferData(gl.ARRAY_BUFFER, strip.uvs, gl.STATIC_DRAW)
  6446.         gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0);
  6447.            
  6448.         gl.activeTexture(gl.TEXTURE0);
  6449.         gl.bindTexture(gl.TEXTURE_2D, strip.texture.baseTexture._glTexture);
  6450.     //  console.log(strip.texture.baseTexture._glTexture)
  6451.         gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
  6452.         gl.bufferData(gl.ARRAY_BUFFER, strip.colors, gl.STATIC_DRAW)
  6453.         gl.vertexAttribPointer(shader.colorAttribute, 1, gl.FLOAT, false, 0, 0);
  6454.        
  6455.         // dont need to upload!
  6456.         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
  6457.         gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, strip.indices, gl.STATIC_DRAW);
  6458.        
  6459.     }
  6460.    
  6461.     gl.drawElements(gl.TRIANGLE_STRIP, strip.indices.length, gl.UNSIGNED_SHORT, 0);
  6462.    
  6463.     PIXI.deactivateStripShader();
  6464.     //gl.useProgram(PIXI.currentProgram);
  6465. }
  6466.  
  6467. /**
  6468.  * Renders a TilingSprite
  6469.  *
  6470.  * @method renderTilingSprite
  6471.  * @param sprite {TilingSprite} The tiling sprite to render
  6472.  * @param projectionMatrix {Object}
  6473.  * @private
  6474.  */
  6475. PIXI.WebGLRenderGroup.prototype.renderTilingSprite = function(sprite, projectionMatrix)
  6476. {
  6477.     var gl = this.gl;
  6478.  
  6479.  
  6480.     var shaderProgram = PIXI.shaderProgram;
  6481.    
  6482.     var tilePosition = sprite.tilePosition;
  6483.     var tileScale = sprite.tileScale;
  6484.    
  6485.     var offsetX =  tilePosition.x/sprite.texture.baseTexture.width;
  6486.     var offsetY =  tilePosition.y/sprite.texture.baseTexture.height;
  6487.    
  6488.     var scaleX =  (sprite.width / sprite.texture.baseTexture.width)  / tileScale.x;
  6489.     var scaleY =  (sprite.height / sprite.texture.baseTexture.height) / tileScale.y;
  6490.  
  6491.     sprite.uvs[0] = 0 - offsetX;
  6492.     sprite.uvs[1] = 0 - offsetY;
  6493.    
  6494.     sprite.uvs[2] = (1 * scaleX)  -offsetX;
  6495.     sprite.uvs[3] = 0 - offsetY;
  6496.    
  6497.     sprite.uvs[4] = (1 *scaleX) - offsetX;
  6498.     sprite.uvs[5] = (1 *scaleY) - offsetY;
  6499.    
  6500.     sprite.uvs[6] = 0 - offsetX;
  6501.     sprite.uvs[7] = (1 *scaleY) - offsetY;
  6502.    
  6503.     gl.bindBuffer(gl.ARRAY_BUFFER, sprite._uvBuffer);
  6504.     gl.bufferSubData(gl.ARRAY_BUFFER, 0, sprite.uvs)
  6505.    
  6506.     this.renderStrip(sprite, projectionMatrix);
  6507. }
  6508.  
  6509. /**
  6510.  * Initializes a strip to be rendered
  6511.  *
  6512.  * @method initStrip
  6513.  * @param strip {Strip} The strip to initialize
  6514.  * @private
  6515.  */
  6516. PIXI.WebGLRenderGroup.prototype.initStrip = function(strip)
  6517. {
  6518.     // build the strip!
  6519.     var gl = this.gl;
  6520.     var shaderProgram = this.shaderProgram;
  6521.    
  6522.     strip._vertexBuffer = gl.createBuffer();
  6523.     strip._indexBuffer = gl.createBuffer();
  6524.     strip._uvBuffer = gl.createBuffer();
  6525.     strip._colorBuffer = gl.createBuffer();
  6526.    
  6527.     gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
  6528.     gl.bufferData(gl.ARRAY_BUFFER, strip.verticies, gl.DYNAMIC_DRAW);
  6529.  
  6530.     gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
  6531.     gl.bufferData(gl.ARRAY_BUFFER,  strip.uvs, gl.STATIC_DRAW);
  6532.  
  6533.     gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
  6534.     gl.bufferData(gl.ARRAY_BUFFER, strip.colors, gl.STATIC_DRAW);
  6535.  
  6536.    
  6537.     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
  6538.     gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, strip.indices, gl.STATIC_DRAW);
  6539. }
  6540.  
  6541.  
  6542. /**
  6543.  * @author Mat Groves http://matgroves.com/ @Doormat23
  6544.  */
  6545.  
  6546.  
  6547. PIXI.WebGLFilterManager = function(transparent)
  6548. {
  6549.     this.transparent = transparent;
  6550.    
  6551.     this.filterStack = [];
  6552.     this.texturePool = [];
  6553.    
  6554.     this.offsetX = 0;
  6555.     this.offsetY = 0;
  6556.    
  6557.     this.initShaderBuffers();
  6558. }
  6559.  
  6560. // API
  6561.  
  6562. PIXI.WebGLFilterManager.prototype.begin = function(projection, buffer)
  6563. {
  6564.     this.width = projection.x * 2;
  6565.     this.height = -projection.y * 2;
  6566.     this.buffer = buffer;
  6567. }
  6568.  
  6569. PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock)
  6570. {
  6571.     var gl = PIXI.gl;
  6572.  
  6573.     // filter program
  6574.     // OPTIMISATION - the first filter is free if its a simple color change?
  6575.     this.filterStack.push(filterBlock);
  6576.  
  6577.     var filter = filterBlock.filterPasses[0];
  6578.  
  6579.    
  6580.  
  6581.     this.offsetX += filterBlock.target.filterArea.x;
  6582.     this.offsetY += filterBlock.target.filterArea.y;
  6583.    
  6584.    
  6585.    
  6586.    
  6587.    
  6588.     var texture = this.texturePool.pop();
  6589.     if(!texture)texture = new PIXI.FilterTexture(this.width, this.height);
  6590.    
  6591.     gl.bindTexture(gl.TEXTURE_2D,  texture.texture);
  6592.    
  6593.     this.getBounds(filterBlock.target);
  6594.        
  6595.     // addpadding?
  6596.     //displayObject.filterArea.x
  6597.  
  6598.     var filterArea = filterBlock.target.filterArea;
  6599.  
  6600.     var padidng = filter.padding;
  6601.     filterArea.x -= padidng;
  6602.     filterArea.y -= padidng;
  6603.     filterArea.width += padidng * 2;
  6604.     filterArea.height += padidng * 2;
  6605.  
  6606.     // cap filter to screen size..
  6607.     if(filterArea.x < 0)filterArea.x = 0;  
  6608.     if(filterArea.width > this.width)filterArea.width = this.width;
  6609.     if(filterArea.y < 0)filterArea.y = 0;  
  6610.     if(filterArea.height > this.height)filterArea.height = this.height;
  6611.  
  6612.  
  6613.     //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA,  filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
  6614.     gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer);
  6615.    
  6616.   // console.log(filterArea)
  6617.     // set view port
  6618.     gl.viewport(0, 0, filterArea.width, filterArea.height);
  6619.    
  6620.     PIXI.projection.x = filterArea.width/2;
  6621.     PIXI.projection.y = -filterArea.height/2;
  6622.    
  6623.     PIXI.offset.x = -filterArea.x;
  6624.     PIXI.offset.y = -filterArea.y;
  6625.  
  6626.     //console.log(PIXI.defaultShader.projectionVector)
  6627.     // update projection
  6628.     gl.uniform2f(PIXI.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2);
  6629.     gl.uniform2f(PIXI.defaultShader.offsetVector, -filterArea.x, -filterArea.y);
  6630.     //PIXI.primitiveProgram
  6631.  
  6632.     gl.colorMask(true, true, true, true);
  6633.     gl.clearColor(0,0,0, 0);    
  6634.     gl.clear(gl.COLOR_BUFFER_BIT);
  6635.    
  6636.     //filter.texture = texture;
  6637.     filterBlock._glFilterTexture = texture;
  6638.  
  6639.     //console.log("PUSH")
  6640. }
  6641.  
  6642.  
  6643. PIXI.WebGLFilterManager.prototype.popFilter = function()
  6644. {
  6645.    
  6646.     var gl = PIXI.gl;
  6647.    
  6648.     var filterBlock = this.filterStack.pop();
  6649.  
  6650.  
  6651.  
  6652.     var filterArea = filterBlock.target.filterArea;
  6653.  
  6654.     var texture = filterBlock._glFilterTexture;
  6655.  
  6656.     if(filterBlock.filterPasses.length > 1)
  6657.     {
  6658.         gl.viewport(0, 0, filterArea.width, filterArea.height);
  6659.  
  6660.         gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
  6661.    
  6662.         this.vertexArray[0] = 0;
  6663.         this.vertexArray[1] = filterArea.height;
  6664.        
  6665.         this.vertexArray[2] = filterArea.width;
  6666.         this.vertexArray[3] = filterArea.height;
  6667.        
  6668.         this.vertexArray[4] = 0;
  6669.         this.vertexArray[5] = 0;
  6670.        
  6671.         this.vertexArray[6] = filterArea.width;
  6672.         this.vertexArray[7] = 0;
  6673.  
  6674.  
  6675.         gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray);
  6676.  
  6677.    
  6678.         gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
  6679.         // nnow set the uvs..
  6680.         this.uvArray[2] = filterArea.width/this.width;
  6681.         this.uvArray[5] = filterArea.height/this.height;
  6682.         this.uvArray[6] = filterArea.width/this.width;
  6683.         this.uvArray[7] = filterArea.height/this.height;
  6684.        
  6685.         gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray);
  6686.  
  6687.         var inputTexture = texture;
  6688.         var outputTexture = this.texturePool.pop();
  6689.         if(!outputTexture)outputTexture = new PIXI.FilterTexture(this.width, this.height);
  6690.        
  6691.         // need to clear this FBO as it may have some left over elements from a prvious filter.
  6692.         gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer );    
  6693.         gl.clear(gl.COLOR_BUFFER_BIT);
  6694.      
  6695.         gl.disable(gl.BLEND);
  6696.        
  6697.         for (var i = 0; i < filterBlock.filterPasses.length-1; i++)
  6698.         {
  6699.             var filterPass = filterBlock.filterPasses[i];
  6700.    
  6701.             gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer );
  6702.            
  6703.             // set texture
  6704.             gl.activeTexture(gl.TEXTURE0);
  6705.             gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture);
  6706.            
  6707.             // draw texture..
  6708.             //filterPass.applyFilterPass(filterArea.width, filterArea.height);
  6709.             this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height);
  6710.  
  6711.             // swap the textures..
  6712.             var temp = inputTexture;
  6713.             inputTexture = outputTexture;
  6714.             outputTexture = temp;
  6715.            
  6716.         };
  6717.  
  6718.         gl.enable(gl.BLEND);
  6719.  
  6720.         texture = inputTexture;
  6721.         this.texturePool.push(outputTexture);
  6722.     }
  6723.  
  6724.     var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1];
  6725.    
  6726.     this.offsetX -= filterArea.x;
  6727.     this.offsetY -= filterArea.y;
  6728.  
  6729.    
  6730.     var sizeX = this.width;
  6731.     var sizeY = this.height;
  6732.    
  6733.     var offsetX = 0;
  6734.     var offsetY = 0;
  6735.    
  6736.     var buffer = this.buffer;
  6737.    
  6738.     // time to render the filters texture to the previous scene
  6739.     if(this.filterStack.length === 0)
  6740.     {
  6741.         gl.colorMask(true, true, true, this.transparent);
  6742.     }
  6743.     else
  6744.     {
  6745.         var currentFilter = this.filterStack[this.filterStack.length-1];
  6746.         var filterArea = currentFilter.target.filterArea;
  6747.        
  6748.         sizeX = filterArea.width;
  6749.         sizeY = filterArea.height;
  6750.        
  6751.         offsetX = filterArea.x;
  6752.         offsetY = filterArea.y;
  6753.        
  6754.         buffer =  currentFilter._glFilterTexture.frameBuffer;
  6755.     }
  6756.    
  6757.    
  6758.  
  6759.     // TODO need toremove thease global elements..
  6760.     PIXI.projection.x = sizeX/2;
  6761.     PIXI.projection.y = -sizeY/2;
  6762.  
  6763.     PIXI.offset.x = offsetX;
  6764.     PIXI.offset.y = offsetY;
  6765.    
  6766.  
  6767.     var filterArea =  filterBlock.target.filterArea;
  6768.     var x = filterArea.x-offsetX;
  6769.     var y = filterArea.y-offsetY;
  6770.    
  6771.     // update the buffers..
  6772.     // make sure to flip the y!
  6773.     gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
  6774.    
  6775.     this.vertexArray[0] = x;
  6776.     this.vertexArray[1] = y + filterArea.height;
  6777.    
  6778.     this.vertexArray[2] = x + filterArea.width;
  6779.     this.vertexArray[3] = y + filterArea.height;
  6780.    
  6781.     this.vertexArray[4] = x;
  6782.     this.vertexArray[5] = y;
  6783.    
  6784.     this.vertexArray[6] = x + filterArea.width;
  6785.     this.vertexArray[7] = y;
  6786.  
  6787.     gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray);
  6788.    
  6789.     gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
  6790.  
  6791.     this.uvArray[2] = filterArea.width/this.width;
  6792.     this.uvArray[5] = filterArea.height/this.height;
  6793.     this.uvArray[6] = filterArea.width/this.width;
  6794.     this.uvArray[7] = filterArea.height/this.height;
  6795.    
  6796.     gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray);
  6797.  
  6798.     gl.viewport(0, 0, sizeX, sizeY);   
  6799.     // bind the buffer
  6800.     gl.bindFramebuffer(gl.FRAMEBUFFER, buffer );
  6801.    
  6802.     // set texture
  6803.     gl.activeTexture(gl.TEXTURE0);
  6804.     gl.bindTexture(gl.TEXTURE_2D, texture.texture);
  6805.    
  6806.     // apply!
  6807.     //filter.applyFilterPass(sizeX, sizeY);
  6808.     this.applyFilterPass(filter, filterArea, sizeX, sizeY);
  6809.  
  6810.     // now restore the regular shader..
  6811.     gl.useProgram(PIXI.defaultShader.program);
  6812.     gl.uniform2f(PIXI.defaultShader.projectionVector, sizeX/2, -sizeY/2);
  6813.     gl.uniform2f(PIXI.defaultShader.offsetVector, -offsetX, -offsetY);
  6814.  
  6815.     // return the texture to the pool
  6816.     this.texturePool.push(texture);
  6817.     filterBlock._glFilterTexture = null;   
  6818. }
  6819.  
  6820. PIXI.WebGLFilterManager.prototype.applyFilterPass = function(filter, filterArea, width, height)
  6821. {
  6822.     // use program
  6823.     var gl = PIXI.gl;
  6824.  
  6825.     if(!filter.shader)
  6826.     {
  6827.         var shader = new PIXI.PixiShader();
  6828.                
  6829.         shader.fragmentSrc = filter.fragmentSrc;
  6830.         shader.uniforms = filter.uniforms;
  6831.         shader.init();
  6832.        
  6833.         filter.shader = shader;
  6834.     }
  6835.  
  6836.     var shader = filter.shader;
  6837.    
  6838.     // set the shader
  6839.     gl.useProgram(shader.program);
  6840.  
  6841.     gl.uniform2f(shader.projectionVector, width/2, -height/2);
  6842.     gl.uniform2f(shader.offsetVector, 0,0)
  6843.  
  6844.     if(filter.uniforms.dimensions)
  6845.     {
  6846.         //console.log(filter.uniforms.dimensions)
  6847.         filter.uniforms.dimensions.value[0] = this.width;//width;
  6848.         filter.uniforms.dimensions.value[1] = this.height;//height;
  6849.         filter.uniforms.dimensions.value[2] = this.vertexArray[0];
  6850.         filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height;
  6851.     //  console.log(this.vertexArray[5])
  6852.     }
  6853.  
  6854.     shader.syncUniforms();
  6855.    
  6856.     gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
  6857.     gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0);
  6858.    
  6859.     gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
  6860.     gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0);
  6861.    
  6862.     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
  6863.    
  6864.     // draw the filter...
  6865.     gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );
  6866. }
  6867.  
  6868. PIXI.WebGLFilterManager.prototype.initShaderBuffers = function()
  6869. {
  6870.     var gl = PIXI.gl;
  6871.    
  6872.     // create some buffers
  6873.     this.vertexBuffer = gl.createBuffer(); 
  6874.     this.uvBuffer = gl.createBuffer();
  6875.     this.indexBuffer = gl.createBuffer();
  6876.    
  6877.     // bind and upload the vertexs..
  6878.     // keep a refferance to the vertexFloatData..
  6879.     this.vertexArray = new Float32Array([0.0, 0.0,
  6880.                                          1.0, 0.0,
  6881.                                          0.0, 1.0,
  6882.                                          1.0, 1.0]);
  6883.    
  6884.     gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
  6885.     gl.bufferData(
  6886.     gl.ARRAY_BUFFER,
  6887.     this.vertexArray,
  6888.     gl.STATIC_DRAW);
  6889.    
  6890.    
  6891.     // bind and upload the uv buffer
  6892.     this.uvArray = new Float32Array([0.0, 0.0,
  6893.                                      1.0, 0.0,
  6894.                                      0.0, 1.0,
  6895.                                      1.0, 1.0]);
  6896.                                          
  6897.     gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
  6898.     gl.bufferData(
  6899.     gl.ARRAY_BUFFER,
  6900.     this.uvArray,
  6901.     gl.STATIC_DRAW);
  6902.    
  6903.     // bind and upload the index
  6904.     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
  6905.     gl.bufferData(
  6906.     gl.ELEMENT_ARRAY_BUFFER,
  6907.     new Uint16Array([0, 1, 2, 1, 3, 2]),
  6908.     gl.STATIC_DRAW);
  6909. }
  6910.  
  6911. PIXI.WebGLFilterManager.prototype.getBounds = function(displayObject)
  6912. {
  6913.     // time to get the width and height of the object!
  6914.     var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index, doTest;
  6915.     var a, b, c, d, tx, ty, x1, x2, x3, x4, y1, y2, y3, y4;
  6916.  
  6917.     var tempObject = displayObject.first;
  6918.     var testObject = displayObject.last._iNext;
  6919.    
  6920.     var maxX = -Infinity;
  6921.     var maxY = -Infinity;
  6922.    
  6923.     var minX = Infinity;
  6924.     var minY = Infinity;
  6925.    
  6926.     do 
  6927.     {
  6928.         // TODO can be optimized! - what if there is no scale / rotation?
  6929.        
  6930.         if(tempObject.visible)
  6931.         {
  6932.             if(tempObject instanceof PIXI.Sprite)
  6933.             {
  6934.                 width = tempObject.texture.frame.width;
  6935.                 height = tempObject.texture.frame.height;
  6936.  
  6937.                 // TODO trim??
  6938.                 aX = tempObject.anchor.x;
  6939.                 aY = tempObject.anchor.y;
  6940.                 w0 = width * (1-aX);
  6941.                 w1 = width * -aX;
  6942.  
  6943.                 h0 = height * (1-aY);
  6944.                 h1 = height * -aY;
  6945.  
  6946.                 doTest = true;
  6947.             }
  6948.             else if(tempObject instanceof PIXI.Graphics)
  6949.             {
  6950.                 tempObject.updateFilterBounds();
  6951.  
  6952.                 var bounds = tempObject.bounds;
  6953.  
  6954.                 width = bounds.width;
  6955.                 height = bounds.height;
  6956.  
  6957.                 w0 = bounds.x
  6958.                 w1 = bounds.x + bounds.width;
  6959.  
  6960.                 h0 = bounds.y
  6961.                 h1 = bounds.y + bounds.height;
  6962.  
  6963.                 doTest = true; 
  6964.             }
  6965.         }
  6966.        
  6967.         if(doTest)
  6968.         {
  6969.             worldTransform = tempObject.worldTransform;
  6970.  
  6971.             a = worldTransform[0];
  6972.             b = worldTransform[3];
  6973.             c = worldTransform[1];
  6974.             d = worldTransform[4];
  6975.             tx = worldTransform[2];
  6976.             ty = worldTransform[5];
  6977.  
  6978.             x1 = a * w1 + c * h1 + tx;
  6979.             y1 = d * h1 + b * w1 + ty;
  6980.  
  6981.             x2 = a * w0 + c * h1 + tx;
  6982.             y2 = d * h1 + b * w0 + ty;
  6983.  
  6984.             x3 = a * w0 + c * h0 + tx;
  6985.             y3 = d * h0 + b * w0 + ty;
  6986.  
  6987.             x4 =  a * w1 + c * h0 + tx;
  6988.             y4 =  d * h0 + b * w1 + ty;
  6989.  
  6990.             minX = x1 < minX ? x1 : minX;
  6991.             minX = x2 < minX ? x2 : minX;
  6992.             minX = x3 < minX ? x3 : minX;
  6993.             minX = x4 < minX ? x4 : minX;
  6994.            
  6995.             minY = y1 < minY ? y1 : minY;
  6996.             minY = y2 < minY ? y2 : minY;
  6997.             minY = y3 < minY ? y3 : minY;
  6998.             minY = y4 < minY ? y4 : minY;
  6999.            
  7000.             maxX = x1 > maxX ? x1 : maxX;
  7001.             maxX = x2 > maxX ? x2 : maxX;
  7002.             maxX = x3 > maxX ? x3 : maxX;
  7003.             maxX = x4 > maxX ? x4 : maxX;
  7004.            
  7005.             maxY = y1 > maxY ? y1 : maxY;
  7006.             maxY = y2 > maxY ? y2 : maxY;
  7007.             maxY = y3 > maxY ? y3 : maxY;
  7008.             maxY = y4 > maxY ? y4 : maxY;
  7009.         }
  7010.  
  7011.         doTest = false;
  7012.         tempObject = tempObject._iNext;
  7013.  
  7014.     }
  7015.     while(tempObject != testObject)
  7016.    
  7017.     // maximum bounds is the size of the screen..
  7018.     //minX = minX > 0 ? minX : 0;
  7019.     //minY = minY > 0 ? minY : 0;
  7020.  
  7021.     displayObject.filterArea.x = minX;
  7022.     displayObject.filterArea.y = minY;
  7023.  
  7024. //  console.log(maxX+ " : " + minX)
  7025.     displayObject.filterArea.width = maxX - minX;
  7026.     displayObject.filterArea.height = maxY - minY;
  7027. }
  7028.  
  7029. PIXI.FilterTexture = function(width, height)
  7030. {
  7031.     var gl = PIXI.gl;
  7032.    
  7033.     // next time to create a frame buffer and texture
  7034.     this.frameBuffer = gl.createFramebuffer();
  7035.     this.texture = gl.createTexture();
  7036.  
  7037.     gl.bindTexture(gl.TEXTURE_2D,  this.texture);
  7038.     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  7039.     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  7040.     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  7041.     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  7042.     gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer );
  7043.    
  7044.     gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer );
  7045.     gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0);
  7046.    
  7047.     this.resize(width, height);
  7048. }
  7049.  
  7050. PIXI.FilterTexture.prototype.resize = function(width, height)
  7051. {
  7052.     this.width = width;
  7053.     this.height = height;
  7054.  
  7055.     var gl = PIXI.gl;
  7056.  
  7057.     gl.bindTexture(gl.TEXTURE_2D,  this.texture);
  7058.     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA,  width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
  7059.    
  7060. }
  7061. /**
  7062.  * @author Mat Groves http://matgroves.com/ @Doormat23
  7063.  */
  7064.  
  7065.  
  7066. /**
  7067.  * the CanvasRenderer draws the stage and all its content onto a 2d canvas. This renderer should be used for browsers that do not support webGL.
  7068.  * Dont forget to add the view to your DOM or you will not see anything :)
  7069.  *
  7070.  * @class CanvasRenderer
  7071.  * @constructor
  7072.  * @param width=0 {Number} the width of the canvas view
  7073.  * @param height=0 {Number} the height of the canvas view
  7074.  * @param view {Canvas} the canvas to use as a view, optional
  7075.  * @param transparent=false {Boolean} the transparency of the render view, default false
  7076.  */
  7077. PIXI.CanvasRenderer = function(width, height, view, transparent)
  7078. {
  7079.     this.transparent = transparent;
  7080.  
  7081.     /**
  7082.      * The width of the canvas view
  7083.      *
  7084.      * @property width
  7085.      * @type Number
  7086.      * @default 800
  7087.      */
  7088.     this.width = width || 800;
  7089.  
  7090.     /**
  7091.      * The height of the canvas view
  7092.      *
  7093.      * @property height
  7094.      * @type Number
  7095.      * @default 600
  7096.      */
  7097.     this.height = height || 600;
  7098.  
  7099.     /**
  7100.      * The canvas element that the everything is drawn to
  7101.      *
  7102.      * @property view
  7103.      * @type Canvas
  7104.      */
  7105.     this.view = view || document.createElement( 'canvas' );
  7106.  
  7107.     /**
  7108.      * The canvas context that the everything is drawn to
  7109.      * @property context
  7110.      * @type Canvas 2d Context
  7111.      */
  7112.     this.context = this.view.getContext("2d");
  7113.  
  7114.     this.refresh = true;
  7115.     // hack to enable some hardware acceleration!
  7116.     //this.view.style["transform"] = "translatez(0)";
  7117.    
  7118.     this.view.width = this.width;
  7119.     this.view.height = this.height;  
  7120.     this.count = 0;
  7121. }
  7122.  
  7123. // constructor
  7124. PIXI.CanvasRenderer.prototype.constructor = PIXI.CanvasRenderer;
  7125.  
  7126. /**
  7127.  * Renders the stage to its canvas view
  7128.  *
  7129.  * @method render
  7130.  * @param stage {Stage} the Stage element to be rendered
  7131.  */
  7132. PIXI.CanvasRenderer.prototype.render = function(stage)
  7133. {
  7134.    
  7135.     //stage.__childrenAdded = [];
  7136.     //stage.__childrenRemoved = [];
  7137.    
  7138.     // update textures if need be
  7139.     PIXI.texturesToUpdate = [];
  7140.     PIXI.texturesToDestroy = [];
  7141.    
  7142.     PIXI.visibleCount++;
  7143.     stage.updateTransform();
  7144.    
  7145.     // update the background color
  7146.     if(this.view.style.backgroundColor!=stage.backgroundColorString && !this.transparent)this.view.style.backgroundColor = stage.backgroundColorString;
  7147.  
  7148.     this.context.setTransform(1,0,0,1,0,0);
  7149.     this.context.clearRect(0, 0, this.width, this.height)
  7150.     this.renderDisplayObject(stage);
  7151.     //as
  7152.    
  7153.     // run interaction!
  7154.     if(stage.interactive)
  7155.     {
  7156.         //need to add some events!
  7157.         if(!stage._interactiveEventsAdded)
  7158.         {
  7159.             stage._interactiveEventsAdded = true;
  7160.             stage.interactionManager.setTarget(this);
  7161.         }
  7162.     }
  7163.    
  7164.     // remove frame updates..
  7165.     if(PIXI.Texture.frameUpdates.length > 0)
  7166.     {
  7167.         PIXI.Texture.frameUpdates = [];
  7168.     }
  7169.    
  7170.    
  7171. }
  7172.  
  7173. /**
  7174.  * resizes the canvas view to the specified width and height
  7175.  *
  7176.  * @method resize
  7177.  * @param width {Number} the new width of the canvas view
  7178.  * @param height {Number} the new height of the canvas view
  7179.  */
  7180. PIXI.CanvasRenderer.prototype.resize = function(width, height)
  7181. {
  7182.     this.width = width;
  7183.     this.height = height;
  7184.    
  7185.     this.view.width = width;
  7186.     this.view.height = height;
  7187. }
  7188.  
  7189. /**
  7190.  * Renders a display object
  7191.  *
  7192.  * @method renderDisplayObject
  7193.  * @param displayObject {DisplayObject} The displayObject to render
  7194.  * @private
  7195.  */
  7196. PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject)
  7197. {
  7198.     // no loger recurrsive!
  7199.     var transform;
  7200.     var context = this.context;
  7201.    
  7202.     context.globalCompositeOperation = 'source-over';
  7203.    
  7204.     // one the display object hits this. we can break the loop 
  7205.     var testObject = displayObject.last._iNext;
  7206.     displayObject = displayObject.first;
  7207.    
  7208.     do 
  7209.     {
  7210.         transform = displayObject.worldTransform;
  7211.        
  7212.         if(!displayObject.visible)
  7213.         {
  7214.             displayObject = displayObject.last._iNext;
  7215.             continue;
  7216.         }
  7217.        
  7218.         if(!displayObject.renderable)
  7219.         {
  7220.             displayObject = displayObject._iNext;
  7221.             continue;
  7222.         }
  7223.        
  7224.         if(displayObject instanceof PIXI.Sprite)
  7225.         {
  7226.                
  7227.             var frame = displayObject.texture.frame;
  7228.            
  7229.             if(frame && frame.width && frame.height)
  7230.             {
  7231.                 context.globalAlpha = displayObject.worldAlpha;
  7232.                
  7233.                 context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]);
  7234.                    
  7235.                 context.drawImage(displayObject.texture.baseTexture.source,
  7236.                                    frame.x,
  7237.                                    frame.y,
  7238.                                    frame.width,
  7239.                                    frame.height,
  7240.                                    (displayObject.anchor.x) * -frame.width,
  7241.                                    (displayObject.anchor.y) * -frame.height,
  7242.                                    frame.width,
  7243.                                    frame.height);
  7244.             }                      
  7245.         }
  7246.         else if(displayObject instanceof PIXI.Strip)
  7247.         {
  7248.             context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5])
  7249.             this.renderStrip(displayObject);
  7250.         }
  7251.         else if(displayObject instanceof PIXI.TilingSprite)
  7252.         {
  7253.             context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5])
  7254.             this.renderTilingSprite(displayObject);
  7255.         }
  7256.         else if(displayObject instanceof PIXI.CustomRenderable)
  7257.         {
  7258.             context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]);
  7259.             displayObject.renderCanvas(this);
  7260.         }
  7261.         else if(displayObject instanceof PIXI.Graphics)
  7262.         {
  7263.             context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5])
  7264.             PIXI.CanvasGraphics.renderGraphics(displayObject, context);
  7265.         }
  7266.         else if(displayObject instanceof PIXI.FilterBlock)
  7267.         {
  7268.             if(displayObject.data instanceof PIXI.Graphics)
  7269.             {
  7270.                 var mask = displayObject.data;
  7271.  
  7272.                 if(displayObject.open)
  7273.                 {
  7274.                     context.save();
  7275.                    
  7276.                     var cacheAlpha = mask.alpha;
  7277.                     var maskTransform = mask.worldTransform;
  7278.                    
  7279.                     context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5])
  7280.                    
  7281.                     mask.worldAlpha = 0.5;
  7282.                    
  7283.                     context.worldAlpha = 0;
  7284.                    
  7285.                     PIXI.CanvasGraphics.renderGraphicsMask(mask, context);
  7286.                     context.clip();
  7287.                    
  7288.                     mask.worldAlpha = cacheAlpha;
  7289.                 }
  7290.                 else
  7291.                 {
  7292.                     context.restore();
  7293.                 }
  7294.             }
  7295.             else
  7296.             {
  7297.                 // only masks supported right now!
  7298.             }
  7299.         }
  7300.     //  count++
  7301.         displayObject = displayObject._iNext;
  7302.        
  7303.        
  7304.     }
  7305.     while(displayObject != testObject)
  7306.  
  7307.    
  7308. }
  7309.  
  7310. /**
  7311.  * Renders a flat strip
  7312.  *
  7313.  * @method renderStripFlat
  7314.  * @param strip {Strip} The Strip to render
  7315.  * @private
  7316.  */
  7317. PIXI.CanvasRenderer.prototype.renderStripFlat = function(strip)
  7318. {
  7319.     var context = this.context;
  7320.     var verticies = strip.verticies;
  7321.     var uvs = strip.uvs;
  7322.    
  7323.     var length = verticies.length/2;
  7324.     this.count++;
  7325.    
  7326.     context.beginPath();
  7327.     for (var i=1; i < length-2; i++)
  7328.     {
  7329.        
  7330.         // draw some triangles!
  7331.         var index = i*2;
  7332.        
  7333.          var x0 = verticies[index],   x1 = verticies[index+2], x2 = verticies[index+4];
  7334.          var y0 = verticies[index+1], y1 = verticies[index+3], y2 = verticies[index+5];
  7335.          
  7336.         context.moveTo(x0, y0);
  7337.         context.lineTo(x1, y1);
  7338.         context.lineTo(x2, y2);
  7339.        
  7340.     }; 
  7341.    
  7342.     context.fillStyle = "#FF0000";
  7343.     context.fill();
  7344.     context.closePath();
  7345. }
  7346.  
  7347. /**
  7348.  * Renders a tiling sprite
  7349.  *
  7350.  * @method renderTilingSprite
  7351.  * @param sprite {TilingSprite} The tilingsprite to render
  7352.  * @private
  7353.  */
  7354. PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite)
  7355. {
  7356.     var context = this.context;
  7357.    
  7358.     context.globalAlpha = sprite.worldAlpha;
  7359.    
  7360.     if(!sprite.__tilePattern) sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, "repeat");
  7361.    
  7362.     context.beginPath();
  7363.    
  7364.     var tilePosition = sprite.tilePosition;
  7365.     var tileScale = sprite.tileScale;
  7366.    
  7367.     // offset
  7368.     context.scale(tileScale.x,tileScale.y);
  7369.     context.translate(tilePosition.x, tilePosition.y);
  7370.    
  7371.     context.fillStyle = sprite.__tilePattern;
  7372.     context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y);
  7373.    
  7374.     context.scale(1/tileScale.x, 1/tileScale.y);
  7375.     context.translate(-tilePosition.x, -tilePosition.y);
  7376.    
  7377.     context.closePath();
  7378. }
  7379.  
  7380. /**
  7381.  * Renders a strip
  7382.  *
  7383.  * @method renderStrip
  7384.  * @param strip {Strip} The Strip to render
  7385.  * @private
  7386.  */
  7387. PIXI.CanvasRenderer.prototype.renderStrip = function(strip)
  7388. {
  7389.     var context = this.context;
  7390.  
  7391.     // draw triangles!!
  7392.     var verticies = strip.verticies;
  7393.     var uvs = strip.uvs;
  7394.    
  7395.     var length = verticies.length/2;
  7396.     this.count++;
  7397.     for (var i=1; i < length-2; i++)
  7398.     {
  7399.        
  7400.         // draw some triangles!
  7401.         var index = i*2;
  7402.        
  7403.          var x0 = verticies[index],   x1 = verticies[index+2], x2 = verticies[index+4];
  7404.          var y0 = verticies[index+1], y1 = verticies[index+3], y2 = verticies[index+5];
  7405.          
  7406.          var u0 = uvs[index] * strip.texture.width,   u1 = uvs[index+2] * strip.texture.width, u2 = uvs[index+4]* strip.texture.width;
  7407.          var v0 = uvs[index+1]* strip.texture.height, v1 = uvs[index+3] * strip.texture.height, v2 = uvs[index+5]* strip.texture.height;
  7408.  
  7409.  
  7410.         context.save();
  7411.         context.beginPath();
  7412.         context.moveTo(x0, y0);
  7413.         context.lineTo(x1, y1);
  7414.         context.lineTo(x2, y2);
  7415.         context.closePath();
  7416.        
  7417.         context.clip();
  7418.        
  7419.        
  7420.         // Compute matrix transform
  7421.         var delta = u0*v1 + v0*u2 + u1*v2 - v1*u2 - v0*u1 - u0*v2;
  7422.         var delta_a = x0*v1 + v0*x2 + x1*v2 - v1*x2 - v0*x1 - x0*v2;
  7423.         var delta_b = u0*x1 + x0*u2 + u1*x2 - x1*u2 - x0*u1 - u0*x2;
  7424.         var delta_c = u0*v1*x2 + v0*x1*u2 + x0*u1*v2 - x0*v1*u2 - v0*u1*x2 - u0*x1*v2;
  7425.         var delta_d = y0*v1 + v0*y2 + y1*v2 - v1*y2 - v0*y1 - y0*v2;
  7426.         var delta_e = u0*y1 + y0*u2 + u1*y2 - y1*u2 - y0*u1 - u0*y2;
  7427.         var delta_f = u0*v1*y2 + v0*y1*u2 + y0*u1*v2 - y0*v1*u2 - v0*u1*y2 - u0*y1*v2;
  7428.        
  7429.        
  7430.        
  7431.            
  7432.         context.transform(delta_a/delta, delta_d/delta,
  7433.                       delta_b/delta, delta_e/delta,
  7434.                       delta_c/delta, delta_f/delta);
  7435.                  
  7436.         context.drawImage(strip.texture.baseTexture.source, 0, 0);
  7437.         context.restore();
  7438.     };
  7439.    
  7440. }
  7441.  
  7442. /**
  7443.  * @author Mat Groves http://matgroves.com/ @Doormat23
  7444.  */
  7445.  
  7446.  
  7447. /**
  7448.  * A set of functions used by the canvas renderer to draw the primitive graphics data
  7449.  *
  7450.  * @class CanvasGraphics
  7451.  */
  7452. PIXI.CanvasGraphics = function()
  7453. {
  7454.  
  7455. }
  7456.  
  7457.  
  7458. /*
  7459.  * Renders the graphics object
  7460.  *
  7461.  * @static
  7462.  * @private
  7463.  * @method renderGraphics
  7464.  * @param graphics {Graphics}
  7465.  * @param context {Context2D}
  7466.  */
  7467. PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
  7468. {
  7469.     var worldAlpha = graphics.worldAlpha;
  7470.  
  7471.     for (var i=0; i < graphics.graphicsData.length; i++)
  7472.     {
  7473.         var data = graphics.graphicsData[i];
  7474.         var points = data.points;
  7475.  
  7476.         context.strokeStyle = color = '#' + ('00000' + ( data.lineColor | 0).toString(16)).substr(-6);
  7477.  
  7478.         context.lineWidth = data.lineWidth;
  7479.  
  7480.         if(data.type == PIXI.Graphics.POLY)
  7481.         {
  7482.             context.beginPath();
  7483.  
  7484.             context.moveTo(points[0], points[1]);
  7485.  
  7486.             for (var j=1; j < points.length/2; j++)
  7487.             {
  7488.                 context.lineTo(points[j * 2], points[j * 2 + 1]);
  7489.             }
  7490.  
  7491.             // if the first and last point are the same close the path - much neater :)
  7492.             if(points[0] == points[points.length-2] && points[1] == points[points.length-1])
  7493.             {
  7494.                 context.closePath();
  7495.             }
  7496.  
  7497.             if(data.fill)
  7498.             {
  7499.                 context.globalAlpha = data.fillAlpha * worldAlpha;
  7500.                 context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6);
  7501.                 context.fill();
  7502.             }
  7503.             if(data.lineWidth)
  7504.             {
  7505.                 context.globalAlpha = data.lineAlpha * worldAlpha;
  7506.                 context.stroke();
  7507.             }
  7508.         }
  7509.         else if(data.type == PIXI.Graphics.RECT)
  7510.         {
  7511.  
  7512.             if(data.fillColor || data.fillColor === 0)
  7513.             {
  7514.                 context.globalAlpha = data.fillAlpha * worldAlpha;
  7515.                 context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6);
  7516.                 context.fillRect(points[0], points[1], points[2], points[3]);
  7517.  
  7518.             }
  7519.             if(data.lineWidth)
  7520.             {
  7521.                 context.globalAlpha = data.lineAlpha * worldAlpha;
  7522.                 context.strokeRect(points[0], points[1], points[2], points[3]);
  7523.             }
  7524.  
  7525.         }
  7526.         else if(data.type == PIXI.Graphics.CIRC)
  7527.         {
  7528.             // TODO - need to be Undefined!
  7529.             context.beginPath();
  7530.             context.arc(points[0], points[1], points[2],0,2*Math.PI);
  7531.             context.closePath();
  7532.  
  7533.             if(data.fill)
  7534.             {
  7535.                 context.globalAlpha = data.fillAlpha * worldAlpha;
  7536.                 context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6);
  7537.                 context.fill();
  7538.             }
  7539.             if(data.lineWidth)
  7540.             {
  7541.                 context.globalAlpha = data.lineAlpha * worldAlpha;
  7542.                 context.stroke();
  7543.             }
  7544.         }
  7545.         else if(data.type == PIXI.Graphics.ELIP)
  7546.         {
  7547.  
  7548.             // elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
  7549.  
  7550.             var elipseData =  data.points;
  7551.  
  7552.             var w = elipseData[2] * 2;
  7553.             var h = elipseData[3] * 2;
  7554.  
  7555.             var x = elipseData[0] - w/2;
  7556.             var y = elipseData[1] - h/2;
  7557.  
  7558.             context.beginPath();
  7559.  
  7560.             var kappa = .5522848,
  7561.             ox = (w / 2) * kappa, // control point offset horizontal
  7562.             oy = (h / 2) * kappa, // control point offset vertical
  7563.             xe = x + w,           // x-end
  7564.             ye = y + h,           // y-end
  7565.             xm = x + w / 2,       // x-middle
  7566.             ym = y + h / 2;       // y-middle
  7567.  
  7568.             context.moveTo(x, ym);
  7569.             context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
  7570.             context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
  7571.             context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
  7572.             context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
  7573.  
  7574.             context.closePath();
  7575.  
  7576.             if(data.fill)
  7577.             {
  7578.                 context.globalAlpha = data.fillAlpha * worldAlpha;
  7579.                 context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6);
  7580.                 context.fill();
  7581.             }
  7582.             if(data.lineWidth)
  7583.             {
  7584.                 context.globalAlpha = data.lineAlpha * worldAlpha;
  7585.                 context.stroke();
  7586.             }
  7587.         }
  7588.  
  7589.     };
  7590. }
  7591.  
  7592. /*
  7593.  * Renders a graphics mask
  7594.  *
  7595.  * @static
  7596.  * @private
  7597.  * @method renderGraphicsMask
  7598.  * @param graphics {Graphics}
  7599.  * @param context {Context2D}
  7600.  */
  7601. PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context)
  7602. {
  7603.     var worldAlpha = graphics.worldAlpha;
  7604.  
  7605.     var len = graphics.graphicsData.length;
  7606.     if(len === 0)return;
  7607.  
  7608.     if(len > 1)
  7609.     {
  7610.         len = 1;
  7611.         console.log("Pixi.js warning: masks in canvas can only mask using the first path in the graphics object")
  7612.     }
  7613.  
  7614.     for (var i=0; i < 1; i++)
  7615.     {
  7616.         var data = graphics.graphicsData[i];
  7617.         var points = data.points;
  7618.  
  7619.         if(data.type == PIXI.Graphics.POLY)
  7620.         {
  7621.             context.beginPath();
  7622.             context.moveTo(points[0], points[1]);
  7623.  
  7624.             for (var j=1; j < points.length/2; j++)
  7625.             {
  7626.                 context.lineTo(points[j * 2], points[j * 2 + 1]);
  7627.             }
  7628.  
  7629.             // if the first and last point are the same close the path - much neater :)
  7630.             if(points[0] == points[points.length-2] && points[1] == points[points.length-1])
  7631.             {
  7632.                 context.closePath();
  7633.             }
  7634.  
  7635.         }
  7636.         else if(data.type == PIXI.Graphics.RECT)
  7637.         {
  7638.             context.beginPath();
  7639.             context.rect(points[0], points[1], points[2], points[3]);
  7640.             context.closePath();
  7641.         }
  7642.         else if(data.type == PIXI.Graphics.CIRC)
  7643.         {
  7644.             // TODO - need to be Undefined!
  7645.             context.beginPath();
  7646.             context.arc(points[0], points[1], points[2],0,2*Math.PI);
  7647.             context.closePath();
  7648.         }
  7649.         else if(data.type == PIXI.Graphics.ELIP)
  7650.         {
  7651.  
  7652.             // elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
  7653.             var elipseData =  data.points;
  7654.  
  7655.             var w = elipseData[2] * 2;
  7656.             var h = elipseData[3] * 2;
  7657.  
  7658.             var x = elipseData[0] - w/2;
  7659.             var y = elipseData[1] - h/2;
  7660.  
  7661.             context.beginPath();
  7662.  
  7663.             var kappa = .5522848,
  7664.             ox = (w / 2) * kappa, // control point offset horizontal
  7665.             oy = (h / 2) * kappa, // control point offset vertical
  7666.             xe = x + w,           // x-end
  7667.             ye = y + h,           // y-end
  7668.             xm = x + w / 2,       // x-middle
  7669.             ym = y + h / 2;       // y-middle
  7670.  
  7671.             context.moveTo(x, ym);
  7672.             context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
  7673.             context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
  7674.             context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
  7675.             context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
  7676.             context.closePath();
  7677.         }
  7678.  
  7679.  
  7680.     };
  7681. }
  7682.  
  7683. /**
  7684.  * @author Mat Groves http://matgroves.com/ @Doormat23
  7685.  */
  7686.  
  7687.  
  7688. /**
  7689.  * The Graphics class contains a set of methods that you can use to create primitive shapes and lines.
  7690.  * It is important to know that with the webGL renderer only simple polys can be filled at this stage
  7691.  * Complex polys will not be filled. Heres an example of a complex poly: http://www.goodboydigital.com/wp-content/uploads/2013/06/complexPolygon.png
  7692.  *
  7693.  * @class Graphics
  7694.  * @extends DisplayObjectContainer
  7695.  * @constructor
  7696.  */
  7697. PIXI.Graphics = function()
  7698. {
  7699.     PIXI.DisplayObjectContainer.call( this );
  7700.  
  7701.     this.renderable = true;
  7702.  
  7703.     /**
  7704.      * The alpha of the fill of this graphics object
  7705.      *
  7706.      * @property fillAlpha
  7707.      * @type Number
  7708.      */
  7709.     this.fillAlpha = 1;
  7710.  
  7711.     /**
  7712.      * The width of any lines drawn
  7713.      *
  7714.      * @property lineWidth
  7715.      * @type Number
  7716.      */
  7717.     this.lineWidth = 0;
  7718.  
  7719.     /**
  7720.      * The color of any lines drawn
  7721.      *
  7722.      * @property lineColor
  7723.      * @type String
  7724.      */
  7725.     this.lineColor = "black";
  7726.  
  7727.     /**
  7728.      * Graphics data
  7729.      *
  7730.      * @property graphicsData
  7731.      * @type Array
  7732.      * @private
  7733.      */
  7734.     this.graphicsData = [];
  7735.  
  7736.     /**
  7737.      * Current path
  7738.      *
  7739.      * @property currentPath
  7740.      * @type Object
  7741.      * @private
  7742.      */
  7743.     this.currentPath = {points:[]};
  7744. }
  7745.  
  7746. // constructor
  7747. PIXI.Graphics.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
  7748. PIXI.Graphics.prototype.constructor = PIXI.Graphics;
  7749.  
  7750. /**
  7751.  * Specifies a line style used for subsequent calls to Graphics methods such as the lineTo() method or the drawCircle() method.
  7752.  *
  7753.  * @method lineStyle
  7754.  * @param lineWidth {Number} width of the line to draw, will update the object's stored style
  7755.  * @param color {Number} color of the line to draw, will update the object's stored style
  7756.  * @param alpha {Number} alpha of the line to draw, will update the object's stored style
  7757.  */
  7758. PIXI.Graphics.prototype.lineStyle = function(lineWidth, color, alpha)
  7759. {
  7760.     if(this.currentPath.points.length == 0)this.graphicsData.pop();
  7761.  
  7762.     this.lineWidth = lineWidth || 0;
  7763.     this.lineColor = color || 0;
  7764.     this.lineAlpha = (alpha == undefined) ? 1 : alpha;
  7765.  
  7766.     this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha,
  7767.                         fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, points:[], type:PIXI.Graphics.POLY};
  7768.  
  7769.     this.graphicsData.push(this.currentPath);
  7770. }
  7771.  
  7772. /**
  7773.  * Moves the current drawing position to (x, y).
  7774.  *
  7775.  * @method moveTo
  7776.  * @param x {Number} the X coord to move to
  7777.  * @param y {Number} the Y coord to move to
  7778.  */
  7779. PIXI.Graphics.prototype.moveTo = function(x, y)
  7780. {
  7781.     if(this.currentPath.points.length == 0)this.graphicsData.pop();
  7782.  
  7783.     this.currentPath = this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha,
  7784.                         fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, points:[], type:PIXI.Graphics.POLY};
  7785.  
  7786.     this.currentPath.points.push(x, y);
  7787.  
  7788.     this.graphicsData.push(this.currentPath);
  7789. }
  7790.  
  7791. /**
  7792.  * Draws a line using the current line style from the current drawing position to (x, y);
  7793.  * the current drawing position is then set to (x, y).
  7794.  *
  7795.  * @method lineTo
  7796.  * @param x {Number} the X coord to draw to
  7797.  * @param y {Number} the Y coord to draw to
  7798.  */
  7799. PIXI.Graphics.prototype.lineTo = function(x, y)
  7800. {
  7801.     this.currentPath.points.push(x, y);
  7802.     this.dirty = true;
  7803. }
  7804.  
  7805. /**
  7806.  * Specifies a simple one-color fill that subsequent calls to other Graphics methods
  7807.  * (such as lineTo() or drawCircle()) use when drawing.
  7808.  *
  7809.  * @method beginFill
  7810.  * @param color {uint} the color of the fill
  7811.  * @param alpha {Number} the alpha
  7812.  */
  7813. PIXI.Graphics.prototype.beginFill = function(color, alpha)
  7814. {
  7815.     this.filling = true;
  7816.     this.fillColor = color || 0;
  7817.     this.fillAlpha = (alpha == undefined) ? 1 : alpha;
  7818. }
  7819.  
  7820. /**
  7821.  * Applies a fill to the lines and shapes that were added since the last call to the beginFill() method.
  7822.  *
  7823.  * @method endFill
  7824.  */
  7825. PIXI.Graphics.prototype.endFill = function()
  7826. {
  7827.     this.filling = false;
  7828.     this.fillColor = null;
  7829.     this.fillAlpha = 1;
  7830. }
  7831.  
  7832. /**
  7833.  * @method drawRect
  7834.  *
  7835.  * @param x {Number} The X coord of the top-left of the rectangle
  7836.  * @param y {Number} The Y coord of the top-left of the rectangle
  7837.  * @param width {Number} The width of the rectangle
  7838.  * @param height {Number} The height of the rectangle
  7839.  */
  7840. PIXI.Graphics.prototype.drawRect = function( x, y, width, height )
  7841. {
  7842.     if(this.currentPath.points.length == 0)this.graphicsData.pop();
  7843.  
  7844.     this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha,
  7845.                         fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling,
  7846.                         points:[x, y, width, height], type:PIXI.Graphics.RECT};
  7847.  
  7848.     this.graphicsData.push(this.currentPath);
  7849.     this.dirty = true;
  7850. }
  7851.  
  7852. /**
  7853.  * Draws a circle.
  7854.  *
  7855.  * @method drawCircle
  7856.  * @param x {Number} The X coord of the center of the circle
  7857.  * @param y {Number} The Y coord of the center of the circle
  7858.  * @param radius {Number} The radius of the circle
  7859.  */
  7860. PIXI.Graphics.prototype.drawCircle = function( x, y, radius)
  7861. {
  7862.     if(this.currentPath.points.length == 0)this.graphicsData.pop();
  7863.  
  7864.     this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha,
  7865.                         fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling,
  7866.                         points:[x, y, radius, radius], type:PIXI.Graphics.CIRC};
  7867.  
  7868.     this.graphicsData.push(this.currentPath);
  7869.     this.dirty = true;
  7870. }
  7871.  
  7872. /**
  7873.  * Draws an elipse.
  7874.  *
  7875.  * @method drawElipse
  7876.  * @param x {Number}
  7877.  * @param y {Number}
  7878.  * @param width {Number}
  7879.  * @param height {Number}
  7880.  */
  7881. PIXI.Graphics.prototype.drawElipse = function( x, y, width, height)
  7882. {
  7883.     if(this.currentPath.points.length == 0)this.graphicsData.pop();
  7884.  
  7885.     this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha,
  7886.                         fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling,
  7887.                         points:[x, y, width, height], type:PIXI.Graphics.ELIP};
  7888.  
  7889.     this.graphicsData.push(this.currentPath);
  7890.     this.dirty = true;
  7891. }
  7892.  
  7893. /**
  7894.  * Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings.
  7895.  *
  7896.  * @method clear
  7897.  */
  7898. PIXI.Graphics.prototype.clear = function()
  7899. {
  7900.     this.lineWidth = 0;
  7901.     this.filling = false;
  7902.  
  7903.     this.dirty = true;
  7904.     this.clearDirty = true;
  7905.     this.graphicsData = [];
  7906.  
  7907.     this.bounds = null//new PIXI.Rectangle();
  7908. }
  7909.  
  7910.  
  7911. PIXI.Graphics.prototype.updateFilterBounds = function()
  7912. {
  7913.     if(!this.bounds)
  7914.     {
  7915.         var minX = Infinity;
  7916.         var maxX = -Infinity;
  7917.  
  7918.         var minY = Infinity;
  7919.         var maxY = -Infinity;
  7920.  
  7921.         var points, x, y;
  7922.  
  7923.         for (var i = 0; i < this.graphicsData.length; i++) {
  7924.            
  7925.  
  7926.             var data = this.graphicsData[i];
  7927.             var type = data.type;
  7928.             var lineWidth = data.lineWidth;
  7929.  
  7930.             points = data.points;
  7931.  
  7932.             if(type === PIXI.Graphics.RECT)
  7933.             {
  7934.                 x = points.x - lineWidth/2;
  7935.                 y = points.y - lineWidth/2;
  7936.                 var width = points.width + lineWidth;
  7937.                 var height = points.height + lineWidth;
  7938.  
  7939.                 minX = x < minX ? x : minX;
  7940.                 maxX = x + width > maxX ? x + width : maxX;
  7941.  
  7942.                 minY = y < minY ? x : minY;
  7943.                 maxY = y + height > maxY ? y + height : maxY;
  7944.             }
  7945.             else if(type === PIXI.Graphics.CIRC || type === PIXI.Graphics.ELIP)
  7946.             {
  7947.                 x = points.x;
  7948.                 y = points.y;
  7949.                 var radius = points.radius + lineWidth/2;
  7950.                
  7951.                 minX = x - radius < minX ? x - radius : minX;
  7952.                 maxX = x + radius > maxX ? x + radius : maxX;
  7953.  
  7954.                 minY = y - radius < minY ? y - radius : minY;
  7955.                 maxY = y + radius > maxY ? y + radius : maxY;
  7956.             }
  7957.             else
  7958.             {
  7959.                 // POLY
  7960.                 for (var j = 0; j < points.length; j+=2)
  7961.                 {
  7962.                    
  7963.                     x = points[j];
  7964.                     y = points[j+1];
  7965.  
  7966.                     minX = x-lineWidth < minX ? x-lineWidth : minX;
  7967.                     maxX = x+lineWidth > maxX ? x+lineWidth : maxX;
  7968.  
  7969.                     minY = y-lineWidth < minY ? y-lineWidth : minY;
  7970.                     maxY = y+lineWidth > maxY ? y+lineWidth : maxY;
  7971.                 };
  7972.             }
  7973.  
  7974.         };
  7975.  
  7976.         this.bounds = new PIXI.Rectangle(minX, minY, maxX - minX, maxY - minY);
  7977.  
  7978.     }
  7979.  
  7980. //  console.log(this.bounds);
  7981. }
  7982.  
  7983. // SOME TYPES:
  7984. PIXI.Graphics.POLY = 0;
  7985. PIXI.Graphics.RECT = 1;
  7986. PIXI.Graphics.CIRC = 2;
  7987. PIXI.Graphics.ELIP = 3;
  7988.  
  7989. /**
  7990.  * @author Mat Groves http://matgroves.com/
  7991.  */
  7992.  
  7993. PIXI.Strip = function(texture, width, height)
  7994. {
  7995.     PIXI.DisplayObjectContainer.call( this );
  7996.     this.texture = texture;
  7997.     this.blendMode = PIXI.blendModes.NORMAL;
  7998.  
  7999.     try
  8000.     {
  8001.         this.uvs = new Float32Array([0, 1,
  8002.                 1, 1,
  8003.                 1, 0, 0,1]);
  8004.  
  8005.         this.verticies = new Float32Array([0, 0,
  8006.                           0,0,
  8007.                           0,0, 0,
  8008.                           0, 0]);
  8009.  
  8010.         this.colors = new Float32Array([1, 1, 1, 1]);
  8011.  
  8012.         this.indices = new Uint16Array([0, 1, 2, 3]);
  8013.     }
  8014.     catch(error)
  8015.     {
  8016.         this.uvs = [0, 1,
  8017.                 1, 1,
  8018.                 1, 0, 0,1];
  8019.  
  8020.         this.verticies = [0, 0,
  8021.                           0,0,
  8022.                           0,0, 0,
  8023.                           0, 0];
  8024.  
  8025.         this.colors = [1, 1, 1, 1];
  8026.  
  8027.         this.indices = [0, 1, 2, 3];
  8028.     }
  8029.  
  8030.  
  8031.     /*
  8032.     this.uvs = new Float32Array()
  8033.     this.verticies = new Float32Array()
  8034.     this.colors = new Float32Array()
  8035.     this.indices = new Uint16Array()
  8036. */
  8037.     this.width = width;
  8038.     this.height = height;
  8039.  
  8040.     // load the texture!
  8041.     if(texture.baseTexture.hasLoaded)
  8042.     {
  8043.         this.width   = this.texture.frame.width;
  8044.         this.height  = this.texture.frame.height;
  8045.         this.updateFrame = true;
  8046.     }
  8047.     else
  8048.     {
  8049.         this.onTextureUpdateBind = this.onTextureUpdate.bind(this);
  8050.         this.texture.addEventListener( 'update', this.onTextureUpdateBind );
  8051.     }
  8052.  
  8053.     this.renderable = true;
  8054. }
  8055.  
  8056. // constructor
  8057. PIXI.Strip.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
  8058. PIXI.Strip.prototype.constructor = PIXI.Strip;
  8059.  
  8060. PIXI.Strip.prototype.setTexture = function(texture)
  8061. {
  8062.     //TODO SET THE TEXTURES
  8063.     //TODO VISIBILITY
  8064.  
  8065.     // stop current texture
  8066.     this.texture = texture;
  8067.     this.width   = texture.frame.width;
  8068.     this.height  = texture.frame.height;
  8069.     this.updateFrame = true;
  8070. }
  8071.  
  8072. PIXI.Strip.prototype.onTextureUpdate = function(event)
  8073. {
  8074.     this.updateFrame = true;
  8075. }
  8076. // some helper functions..
  8077.  
  8078.  
  8079. /**
  8080.  * @author Mat Groves http://matgroves.com/
  8081.  */
  8082.  
  8083.  
  8084. PIXI.Rope = function(texture, points)
  8085. {
  8086.     PIXI.Strip.call( this, texture );
  8087.     this.points = points;
  8088.  
  8089.     try
  8090.     {
  8091.         this.verticies = new Float32Array( points.length * 4);
  8092.         this.uvs = new Float32Array( points.length * 4);
  8093.         this.colors = new Float32Array(  points.length * 2);
  8094.         this.indices = new Uint16Array( points.length * 2);
  8095.     }
  8096.     catch(error)
  8097.     {
  8098.         this.verticies = verticies
  8099.  
  8100.         this.uvs = uvs
  8101.         this.colors = colors
  8102.         this.indices = indices
  8103.     }
  8104.  
  8105.     this.refresh();
  8106. }
  8107.  
  8108.  
  8109. // constructor
  8110. PIXI.Rope.prototype = Object.create( PIXI.Strip.prototype );
  8111. PIXI.Rope.prototype.constructor = PIXI.Rope;
  8112.  
  8113. PIXI.Rope.prototype.refresh = function()
  8114. {
  8115.     var points = this.points;
  8116.     if(points.length < 1)return;
  8117.  
  8118.     var uvs = this.uvs
  8119.     var indices = this.indices;
  8120.     var colors = this.colors;
  8121.  
  8122.     var lastPoint = points[0];
  8123.     var nextPoint;
  8124.     var perp = {x:0, y:0};
  8125.     var point = points[0];
  8126.  
  8127.     this.count-=0.2;
  8128.  
  8129.  
  8130.     uvs[0] = 0
  8131.     uvs[1] = 1
  8132.     uvs[2] = 0
  8133.     uvs[3] = 1
  8134.  
  8135.     colors[0] = 1;
  8136.     colors[1] = 1;
  8137.  
  8138.     indices[0] = 0;
  8139.     indices[1] = 1;
  8140.  
  8141.     var total = points.length;
  8142.  
  8143.     for (var i =  1; i < total; i++)
  8144.     {
  8145.  
  8146.         var point = points[i];
  8147.         var index = i * 4;
  8148.         // time to do some smart drawing!
  8149.         var amount = i/(total-1)
  8150.  
  8151.         if(i%2)
  8152.         {
  8153.             uvs[index] = amount;
  8154.             uvs[index+1] = 0;
  8155.  
  8156.             uvs[index+2] = amount
  8157.             uvs[index+3] = 1
  8158.  
  8159.         }
  8160.         else
  8161.         {
  8162.             uvs[index] = amount
  8163.             uvs[index+1] = 0
  8164.  
  8165.             uvs[index+2] = amount
  8166.             uvs[index+3] = 1
  8167.         }
  8168.  
  8169.         index = i * 2;
  8170.         colors[index] = 1;
  8171.         colors[index+1] = 1;
  8172.  
  8173.         index = i * 2;
  8174.         indices[index] = index;
  8175.         indices[index + 1] = index + 1;
  8176.  
  8177.         lastPoint = point;
  8178.     }
  8179. }
  8180.  
  8181. PIXI.Rope.prototype.updateTransform = function()
  8182. {
  8183.  
  8184.     var points = this.points;
  8185.     if(points.length < 1)return;
  8186.  
  8187.     var verticies = this.verticies
  8188.  
  8189.     var lastPoint = points[0];
  8190.     var nextPoint;
  8191.     var perp = {x:0, y:0};
  8192.     var point = points[0];
  8193.  
  8194.     this.count-=0.2;
  8195.  
  8196.     verticies[0] = point.x + perp.x
  8197.     verticies[1] = point.y + perp.y //+ 200
  8198.     verticies[2] = point.x - perp.x
  8199.     verticies[3] = point.y - perp.y//+200
  8200.     // time to do some smart drawing!
  8201.  
  8202.     var total = points.length;
  8203.  
  8204.     for (var i =  1; i < total; i++)
  8205.     {
  8206.  
  8207.         var point = points[i];
  8208.         var index = i * 4;
  8209.  
  8210.         if(i < points.length-1)
  8211.         {
  8212.             nextPoint = points[i+1];
  8213.         }
  8214.         else
  8215.         {
  8216.             nextPoint = point
  8217.         }
  8218.  
  8219.         perp.y = -(nextPoint.x - lastPoint.x);
  8220.         perp.x = nextPoint.y - lastPoint.y;
  8221.  
  8222.         var ratio = (1 - (i / (total-1))) * 10;
  8223.                 if(ratio > 1)ratio = 1;
  8224.  
  8225.         var perpLength = Math.sqrt(perp.x * perp.x + perp.y * perp.y);
  8226.         var num = this.texture.height/2//(20 + Math.abs(Math.sin((i + this.count) * 0.3) * 50) )* ratio;
  8227.         perp.x /= perpLength;
  8228.         perp.y /= perpLength;
  8229.  
  8230.         perp.x *= num;
  8231.         perp.y *= num;
  8232.  
  8233.         verticies[index] = point.x + perp.x
  8234.         verticies[index+1] = point.y + perp.y
  8235.         verticies[index+2] = point.x - perp.x
  8236.         verticies[index+3] = point.y - perp.y
  8237.  
  8238.         lastPoint = point;
  8239.     }
  8240.  
  8241.     PIXI.DisplayObjectContainer.prototype.updateTransform.call( this );
  8242. }
  8243.  
  8244. PIXI.Rope.prototype.setTexture = function(texture)
  8245. {
  8246.     // stop current texture
  8247.     this.texture = texture;
  8248.     this.updateFrame = true;
  8249. }
  8250.  
  8251.  
  8252.  
  8253.  
  8254.  
  8255. /**
  8256.  * @author Mat Groves http://matgroves.com/
  8257.  */
  8258.  
  8259. /**
  8260.  * A tiling sprite is a fast way of rendering a tiling image
  8261.  *
  8262.  * @class TilingSprite
  8263.  * @extends DisplayObjectContainer
  8264.  * @constructor
  8265.  * @param texture {Texture} the texture of the tiling sprite
  8266.  * @param width {Number}  the width of the tiling sprite
  8267.  * @param height {Number} the height of the tiling sprite
  8268.  */
  8269. PIXI.TilingSprite = function(texture, width, height)
  8270. {
  8271.     PIXI.DisplayObjectContainer.call( this );
  8272.  
  8273.     /**
  8274.      * The texture that the sprite is using
  8275.      *
  8276.      * @property texture
  8277.      * @type Texture
  8278.      */
  8279.     this.texture = texture;
  8280.  
  8281.     /**
  8282.      * The width of the tiling sprite
  8283.      *
  8284.      * @property width
  8285.      * @type Number
  8286.      */
  8287.     this.width = width;
  8288.  
  8289.     /**
  8290.      * The height of the tiling sprite
  8291.      *
  8292.      * @property height
  8293.      * @type Number
  8294.      */
  8295.     this.height = height;
  8296.  
  8297.     /**
  8298.      * The scaling of the image that is being tiled
  8299.      *
  8300.      * @property tileScale
  8301.      * @type Point
  8302.      */
  8303.     this.tileScale = new PIXI.Point(1,1);
  8304.  
  8305.     /**
  8306.      * The offset position of the image that is being tiled
  8307.      *
  8308.      * @property tilePosition
  8309.      * @type Point
  8310.      */
  8311.     this.tilePosition = new PIXI.Point(0,0);
  8312.  
  8313.     this.renderable = true;
  8314.  
  8315.     this.blendMode = PIXI.blendModes.NORMAL
  8316. }
  8317.  
  8318. // constructor
  8319. PIXI.TilingSprite.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
  8320. PIXI.TilingSprite.prototype.constructor = PIXI.TilingSprite;
  8321.  
  8322. /**
  8323.  * Sets the texture of the tiling sprite
  8324.  *
  8325.  * @method setTexture
  8326.  * @param texture {Texture} The PIXI texture that is displayed by the sprite
  8327.  */
  8328. PIXI.TilingSprite.prototype.setTexture = function(texture)
  8329. {
  8330.     //TODO SET THE TEXTURES
  8331.     //TODO VISIBILITY
  8332.  
  8333.     // stop current texture
  8334.     this.texture = texture;
  8335.     this.updateFrame = true;
  8336. }
  8337.  
  8338. /**
  8339.  * When the texture is updated, this event will fire to update the frame
  8340.  *
  8341.  * @method onTextureUpdate
  8342.  * @param event
  8343.  * @private
  8344.  */
  8345. PIXI.TilingSprite.prototype.onTextureUpdate = function(event)
  8346. {
  8347.     this.updateFrame = true;
  8348. }
  8349.  
  8350.  
  8351. /**
  8352.  * @author Mat Groves http://matgroves.com/ @Doormat23
  8353.  * based on pixi impact spine implementation made by Eemeli Kelokorpi (@ekelokorpi) https://github.com/ekelokorpi
  8354.  *
  8355.  * Awesome JS run time provided by EsotericSoftware
  8356.  * https://github.com/EsotericSoftware/spine-runtimes
  8357.  *
  8358.  */
  8359.  
  8360. /**
  8361.  * A class that enables the you to import and run your spine animations in pixi.
  8362.  * Spine animation data needs to be loaded using the PIXI.AssetLoader or PIXI.SpineLoader before it can be used by this class
  8363.  * See example 12 (http://www.goodboydigital.com/pixijs/examples/12/) to see a working example and check out the source
  8364.  *
  8365.  * @class Spine
  8366.  * @extends DisplayObjectContainer
  8367.  * @constructor
  8368.  * @param url {String} The url of the spine anim file to be used
  8369.  */
  8370. PIXI.Spine = function (url) {
  8371.     PIXI.DisplayObjectContainer.call(this);
  8372.  
  8373.     this.spineData = PIXI.AnimCache[url];
  8374.  
  8375.     if (!this.spineData) {
  8376.         throw new Error("Spine data must be preloaded using PIXI.SpineLoader or PIXI.AssetLoader: " + url);
  8377.     }
  8378.  
  8379.     this.skeleton = new spine.Skeleton(this.spineData);
  8380.     this.skeleton.updateWorldTransform();
  8381.  
  8382.     this.stateData = new spine.AnimationStateData(this.spineData);
  8383.     this.state = new spine.AnimationState(this.stateData);
  8384.  
  8385.     this.slotContainers = [];
  8386.  
  8387.     for (var i = 0, n = this.skeleton.drawOrder.length; i < n; i++) {
  8388.         var slot = this.skeleton.drawOrder[i];
  8389.         var attachment = slot.attachment;
  8390.         var slotContainer = new PIXI.DisplayObjectContainer();
  8391.         this.slotContainers.push(slotContainer);
  8392.         this.addChild(slotContainer);
  8393.         if (!(attachment instanceof spine.RegionAttachment)) {
  8394.             continue;
  8395.         }
  8396.         var spriteName = attachment.rendererObject.name;
  8397.         var sprite = this.createSprite(slot, attachment.rendererObject);
  8398.         slot.currentSprite = sprite;
  8399.         slot.currentSpriteName = spriteName;
  8400.         slotContainer.addChild(sprite);
  8401.     }
  8402. };
  8403.  
  8404. PIXI.Spine.prototype = Object.create(PIXI.DisplayObjectContainer.prototype);
  8405. PIXI.Spine.prototype.constructor = PIXI.Spine;
  8406.  
  8407. /*
  8408.  * Updates the object transform for rendering
  8409.  *
  8410.  * @method updateTransform
  8411.  * @private
  8412.  */
  8413. PIXI.Spine.prototype.updateTransform = function () {
  8414.     this.lastTime = this.lastTime || Date.now();
  8415.     var timeDelta = (Date.now() - this.lastTime) * 0.001;
  8416.     this.lastTime = Date.now();
  8417.     this.state.update(timeDelta);
  8418.     this.state.apply(this.skeleton);
  8419.     this.skeleton.updateWorldTransform();
  8420.  
  8421.     var drawOrder = this.skeleton.drawOrder;
  8422.     for (var i = 0, n = drawOrder.length; i < n; i++) {
  8423.         var slot = drawOrder[i];
  8424.         var attachment = slot.attachment;
  8425.         var slotContainer = this.slotContainers[i];
  8426.         if (!(attachment instanceof spine.RegionAttachment)) {
  8427.             slotContainer.visible = false;
  8428.             continue;
  8429.         }
  8430.  
  8431.         if (attachment.rendererObject) {
  8432.             if (!slot.currentSpriteName || slot.currentSpriteName != attachment.name) {
  8433.                 var spriteName = attachment.rendererObject.name;
  8434.                 if (slot.currentSprite !== undefined) {
  8435.                     slot.currentSprite.visible = false;
  8436.                 }
  8437.                 slot.sprites = slot.sprites || {};
  8438.                 if (slot.sprites[spriteName] !== undefined) {
  8439.                     slot.sprites[spriteName].visible = true;
  8440.                 } else {
  8441.                     var sprite = this.createSprite(slot, attachment.rendererObject);
  8442.                     slotContainer.addChild(sprite);
  8443.                 }
  8444.                 slot.currentSprite = slot.sprites[spriteName];
  8445.                 slot.currentSpriteName = spriteName;
  8446.             }
  8447.         }
  8448.         slotContainer.visible = true;
  8449.  
  8450.         var bone = slot.bone;
  8451.  
  8452.         slotContainer.position.x = bone.worldX + attachment.x * bone.m00 + attachment.y * bone.m01;
  8453.         slotContainer.position.y = bone.worldY + attachment.x * bone.m10 + attachment.y * bone.m11;
  8454.         slotContainer.scale.x = bone.worldScaleX;
  8455.         slotContainer.scale.y = bone.worldScaleY;
  8456.  
  8457.         slotContainer.rotation = -(slot.bone.worldRotation * Math.PI / 180);
  8458.     }
  8459.  
  8460.     PIXI.DisplayObjectContainer.prototype.updateTransform.call(this);
  8461. };
  8462.  
  8463.  
  8464. PIXI.Spine.prototype.createSprite = function (slot, descriptor) {
  8465.     var name = PIXI.TextureCache[descriptor.name] ? descriptor.name : descriptor.name + ".png";
  8466.     var sprite = new PIXI.Sprite(PIXI.Texture.fromFrame(name));
  8467.     sprite.scale = descriptor.scale;
  8468.     sprite.rotation = descriptor.rotation;
  8469.     sprite.anchor.x = sprite.anchor.y = 0.5;
  8470.  
  8471.     slot.sprites = slot.sprites || {};
  8472.     slot.sprites[descriptor.name] = sprite;
  8473.     return sprite;
  8474. };
  8475.  
  8476. /*
  8477.  * Awesome JS run time provided by EsotericSoftware
  8478.  *
  8479.  * https://github.com/EsotericSoftware/spine-runtimes
  8480.  *
  8481.  */
  8482.  
  8483. var spine = {};
  8484.  
  8485. spine.BoneData = function (name, parent) {
  8486.     this.name = name;
  8487.     this.parent = parent;
  8488. };
  8489. spine.BoneData.prototype = {
  8490.     length: 0,
  8491.     x: 0, y: 0,
  8492.     rotation: 0,
  8493.     scaleX: 1, scaleY: 1
  8494. };
  8495.  
  8496. spine.SlotData = function (name, boneData) {
  8497.     this.name = name;
  8498.     this.boneData = boneData;
  8499. };
  8500. spine.SlotData.prototype = {
  8501.     r: 1, g: 1, b: 1, a: 1,
  8502.     attachmentName: null
  8503. };
  8504.  
  8505. spine.Bone = function (boneData, parent) {
  8506.     this.data = boneData;
  8507.     this.parent = parent;
  8508.     this.setToSetupPose();
  8509. };
  8510. spine.Bone.yDown = false;
  8511. spine.Bone.prototype = {
  8512.     x: 0, y: 0,
  8513.     rotation: 0,
  8514.     scaleX: 1, scaleY: 1,
  8515.     m00: 0, m01: 0, worldX: 0, // a b x
  8516.     m10: 0, m11: 0, worldY: 0, // c d y
  8517.     worldRotation: 0,
  8518.     worldScaleX: 1, worldScaleY: 1,
  8519.     updateWorldTransform: function (flipX, flipY) {
  8520.         var parent = this.parent;
  8521.         if (parent != null) {
  8522.             this.worldX = this.x * parent.m00 + this.y * parent.m01 + parent.worldX;
  8523.             this.worldY = this.x * parent.m10 + this.y * parent.m11 + parent.worldY;
  8524.             this.worldScaleX = parent.worldScaleX * this.scaleX;
  8525.             this.worldScaleY = parent.worldScaleY * this.scaleY;
  8526.             this.worldRotation = parent.worldRotation + this.rotation;
  8527.         } else {
  8528.             this.worldX = this.x;
  8529.             this.worldY = this.y;
  8530.             this.worldScaleX = this.scaleX;
  8531.             this.worldScaleY = this.scaleY;
  8532.             this.worldRotation = this.rotation;
  8533.         }
  8534.         var radians = this.worldRotation * Math.PI / 180;
  8535.         var cos = Math.cos(radians);
  8536.         var sin = Math.sin(radians);
  8537.         this.m00 = cos * this.worldScaleX;
  8538.         this.m10 = sin * this.worldScaleX;
  8539.         this.m01 = -sin * this.worldScaleY;
  8540.         this.m11 = cos * this.worldScaleY;
  8541.         if (flipX) {
  8542.             this.m00 = -this.m00;
  8543.             this.m01 = -this.m01;
  8544.         }
  8545.         if (flipY) {
  8546.             this.m10 = -this.m10;
  8547.             this.m11 = -this.m11;
  8548.         }
  8549.         if (spine.Bone.yDown) {
  8550.             this.m10 = -this.m10;
  8551.             this.m11 = -this.m11;
  8552.         }
  8553.     },
  8554.     setToSetupPose: function () {
  8555.         var data = this.data;
  8556.         this.x = data.x;
  8557.         this.y = data.y;
  8558.         this.rotation = data.rotation;
  8559.         this.scaleX = data.scaleX;
  8560.         this.scaleY = data.scaleY;
  8561.     }
  8562. };
  8563.  
  8564. spine.Slot = function (slotData, skeleton, bone) {
  8565.     this.data = slotData;
  8566.     this.skeleton = skeleton;
  8567.     this.bone = bone;
  8568.     this.setToSetupPose();
  8569. };
  8570. spine.Slot.prototype = {
  8571.     r: 1, g: 1, b: 1, a: 1,
  8572.     _attachmentTime: 0,
  8573.     attachment: null,
  8574.     setAttachment: function (attachment) {
  8575.         this.attachment = attachment;
  8576.         this._attachmentTime = this.skeleton.time;
  8577.     },
  8578.     setAttachmentTime: function (time) {
  8579.         this._attachmentTime = this.skeleton.time - time;
  8580.     },
  8581.     getAttachmentTime: function () {
  8582.         return this.skeleton.time - this._attachmentTime;
  8583.     },
  8584.     setToSetupPose: function () {
  8585.         var data = this.data;
  8586.         this.r = data.r;
  8587.         this.g = data.g;
  8588.         this.b = data.b;
  8589.         this.a = data.a;
  8590.  
  8591.         var slotDatas = this.skeleton.data.slots;
  8592.         for (var i = 0, n = slotDatas.length; i < n; i++) {
  8593.             if (slotDatas[i] == data) {
  8594.                 this.setAttachment(!data.attachmentName ? null : this.skeleton.getAttachmentBySlotIndex(i, data.attachmentName));
  8595.                 break;
  8596.             }
  8597.         }
  8598.     }
  8599. };
  8600.  
  8601. spine.Skin = function (name) {
  8602.     this.name = name;
  8603.     this.attachments = {};
  8604. };
  8605. spine.Skin.prototype = {
  8606.     addAttachment: function (slotIndex, name, attachment) {
  8607.         this.attachments[slotIndex + ":" + name] = attachment;
  8608.     },
  8609.     getAttachment: function (slotIndex, name) {
  8610.         return this.attachments[slotIndex + ":" + name];
  8611.     },
  8612.     _attachAll: function (skeleton, oldSkin) {
  8613.         for (var key in oldSkin.attachments) {
  8614.             var colon = key.indexOf(":");
  8615.             var slotIndex = parseInt(key.substring(0, colon));
  8616.             var name = key.substring(colon + 1);
  8617.             var slot = skeleton.slots[slotIndex];
  8618.             if (slot.attachment && slot.attachment.name == name) {
  8619.                 var attachment = this.getAttachment(slotIndex, name);
  8620.                 if (attachment) slot.setAttachment(attachment);
  8621.             }
  8622.         }
  8623.     }
  8624. };
  8625.  
  8626. spine.Animation = function (name, timelines, duration) {
  8627.     this.name = name;
  8628.     this.timelines = timelines;
  8629.     this.duration = duration;
  8630. };
  8631. spine.Animation.prototype = {
  8632.     apply: function (skeleton, time, loop) {
  8633.         if (loop && this.duration != 0) time %= this.duration;
  8634.         var timelines = this.timelines;
  8635.         for (var i = 0, n = timelines.length; i < n; i++)
  8636.             timelines[i].apply(skeleton, time, 1);
  8637.     },
  8638.     mix: function (skeleton, time, loop, alpha) {
  8639.         if (loop && this.duration != 0) time %= this.duration;
  8640.         var timelines = this.timelines;
  8641.         for (var i = 0, n = timelines.length; i < n; i++)
  8642.             timelines[i].apply(skeleton, time, alpha);
  8643.     }
  8644. };
  8645.  
  8646. spine.binarySearch = function (values, target, step) {
  8647.     var low = 0;
  8648.     var high = Math.floor(values.length / step) - 2;
  8649.     if (high == 0) return step;
  8650.     var current = high >>> 1;
  8651.     while (true) {
  8652.         if (values[(current + 1) * step] <= target)
  8653.             low = current + 1;
  8654.         else
  8655.             high = current;
  8656.         if (low == high) return (low + 1) * step;
  8657.         current = (low + high) >>> 1;
  8658.     }
  8659. };
  8660. spine.linearSearch = function (values, target, step) {
  8661.     for (var i = 0, last = values.length - step; i <= last; i += step)
  8662.         if (values[i] > target) return i;
  8663.     return -1;
  8664. };
  8665.  
  8666. spine.Curves = function (frameCount) {
  8667.     this.curves = []; // dfx, dfy, ddfx, ddfy, dddfx, dddfy, ...
  8668.     this.curves.length = (frameCount - 1) * 6;
  8669. };
  8670. spine.Curves.prototype = {
  8671.     setLinear: function (frameIndex) {
  8672.         this.curves[frameIndex * 6] = 0/*LINEAR*/;
  8673.     },
  8674.     setStepped: function (frameIndex) {
  8675.         this.curves[frameIndex * 6] = -1/*STEPPED*/;
  8676.     },
  8677.     /** Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next.
  8678.      * cx1 and cx2 are from 0 to 1, representing the percent of time between the two keyframes. cy1 and cy2 are the percent of
  8679.      * the difference between the keyframe's values. */
  8680.     setCurve: function (frameIndex, cx1, cy1, cx2, cy2) {
  8681.         var subdiv_step = 1 / 10/*BEZIER_SEGMENTS*/;
  8682.         var subdiv_step2 = subdiv_step * subdiv_step;
  8683.         var subdiv_step3 = subdiv_step2 * subdiv_step;
  8684.         var pre1 = 3 * subdiv_step;
  8685.         var pre2 = 3 * subdiv_step2;
  8686.         var pre4 = 6 * subdiv_step2;
  8687.         var pre5 = 6 * subdiv_step3;
  8688.         var tmp1x = -cx1 * 2 + cx2;
  8689.         var tmp1y = -cy1 * 2 + cy2;
  8690.         var tmp2x = (cx1 - cx2) * 3 + 1;
  8691.         var tmp2y = (cy1 - cy2) * 3 + 1;
  8692.         var i = frameIndex * 6;
  8693.         var curves = this.curves;
  8694.         curves[i] = cx1 * pre1 + tmp1x * pre2 + tmp2x * subdiv_step3;
  8695.         curves[i + 1] = cy1 * pre1 + tmp1y * pre2 + tmp2y * subdiv_step3;
  8696.         curves[i + 2] = tmp1x * pre4 + tmp2x * pre5;
  8697.         curves[i + 3] = tmp1y * pre4 + tmp2y * pre5;
  8698.         curves[i + 4] = tmp2x * pre5;
  8699.         curves[i + 5] = tmp2y * pre5;
  8700.     },
  8701.     getCurvePercent: function (frameIndex, percent) {
  8702.         percent = percent < 0 ? 0 : (percent > 1 ? 1 : percent);
  8703.         var curveIndex = frameIndex * 6;
  8704.         var curves = this.curves;
  8705.         var dfx = curves[curveIndex];
  8706.         if (!dfx/*LINEAR*/) return percent;
  8707.         if (dfx == -1/*STEPPED*/) return 0;
  8708.         var dfy = curves[curveIndex + 1];
  8709.         var ddfx = curves[curveIndex + 2];
  8710.         var ddfy = curves[curveIndex + 3];
  8711.         var dddfx = curves[curveIndex + 4];
  8712.         var dddfy = curves[curveIndex + 5];
  8713.         var x = dfx, y = dfy;
  8714.         var i = 10/*BEZIER_SEGMENTS*/ - 2;
  8715.         while (true) {
  8716.             if (x >= percent) {
  8717.                 var lastX = x - dfx;
  8718.                 var lastY = y - dfy;
  8719.                 return lastY + (y - lastY) * (percent - lastX) / (x - lastX);
  8720.             }
  8721.             if (i == 0) break;
  8722.             i--;
  8723.             dfx += ddfx;
  8724.             dfy += ddfy;
  8725.             ddfx += dddfx;
  8726.             ddfy += dddfy;
  8727.             x += dfx;
  8728.             y += dfy;
  8729.         }
  8730.         return y + (1 - y) * (percent - x) / (1 - x); // Last point is 1,1.
  8731.     }
  8732. };
  8733.  
  8734. spine.RotateTimeline = function (frameCount) {
  8735.     this.curves = new spine.Curves(frameCount);
  8736.     this.frames = []; // time, angle, ...
  8737.     this.frames.length = frameCount * 2;
  8738. };
  8739. spine.RotateTimeline.prototype = {
  8740.     boneIndex: 0,
  8741.     getFrameCount: function () {
  8742.         return this.frames.length / 2;
  8743.     },
  8744.     setFrame: function (frameIndex, time, angle) {
  8745.         frameIndex *= 2;
  8746.         this.frames[frameIndex] = time;
  8747.         this.frames[frameIndex + 1] = angle;
  8748.     },
  8749.     apply: function (skeleton, time, alpha) {
  8750.         var frames = this.frames;
  8751.         if (time < frames[0]) return; // Time is before first frame.
  8752.  
  8753.         var bone = skeleton.bones[this.boneIndex];
  8754.  
  8755.         if (time >= frames[frames.length - 2]) { // Time is after last frame.
  8756.             var amount = bone.data.rotation + frames[frames.length - 1] - bone.rotation;
  8757.             while (amount > 180)
  8758.                 amount -= 360;
  8759.             while (amount < -180)
  8760.                 amount += 360;
  8761.             bone.rotation += amount * alpha;
  8762.             return;
  8763.         }
  8764.  
  8765.         // Interpolate between the last frame and the current frame.
  8766.         var frameIndex = spine.binarySearch(frames, time, 2);
  8767.         var lastFrameValue = frames[frameIndex - 1];
  8768.         var frameTime = frames[frameIndex];
  8769.         var percent = 1 - (time - frameTime) / (frames[frameIndex - 2/*LAST_FRAME_TIME*/] - frameTime);
  8770.         percent = this.curves.getCurvePercent(frameIndex / 2 - 1, percent);
  8771.  
  8772.         var amount = frames[frameIndex + 1/*FRAME_VALUE*/] - lastFrameValue;
  8773.         while (amount > 180)
  8774.             amount -= 360;
  8775.         while (amount < -180)
  8776.             amount += 360;
  8777.         amount = bone.data.rotation + (lastFrameValue + amount * percent) - bone.rotation;
  8778.         while (amount > 180)
  8779.             amount -= 360;
  8780.         while (amount < -180)
  8781.             amount += 360;
  8782.         bone.rotation += amount * alpha;
  8783.     }
  8784. };
  8785.  
  8786. spine.TranslateTimeline = function (frameCount) {
  8787.     this.curves = new spine.Curves(frameCount);
  8788.     this.frames = []; // time, x, y, ...
  8789.     this.frames.length = frameCount * 3;
  8790. };
  8791. spine.TranslateTimeline.prototype = {
  8792.     boneIndex: 0,
  8793.     getFrameCount: function () {
  8794.         return this.frames.length / 3;
  8795.     },
  8796.     setFrame: function (frameIndex, time, x, y) {
  8797.         frameIndex *= 3;
  8798.         this.frames[frameIndex] = time;
  8799.         this.frames[frameIndex + 1] = x;
  8800.         this.frames[frameIndex + 2] = y;
  8801.     },
  8802.     apply: function (skeleton, time, alpha) {
  8803.         var frames = this.frames;
  8804.         if (time < frames[0]) return; // Time is before first frame.
  8805.  
  8806.         var bone = skeleton.bones[this.boneIndex];
  8807.  
  8808.         if (time >= frames[frames.length - 3]) { // Time is after last frame.
  8809.             bone.x += (bone.data.x + frames[frames.length - 2] - bone.x) * alpha;
  8810.             bone.y += (bone.data.y + frames[frames.length - 1] - bone.y) * alpha;
  8811.             return;
  8812.         }
  8813.  
  8814.         // Interpolate between the last frame and the current frame.
  8815.         var frameIndex = spine.binarySearch(frames, time, 3);
  8816.         var lastFrameX = frames[frameIndex - 2];
  8817.         var lastFrameY = frames[frameIndex - 1];
  8818.         var frameTime = frames[frameIndex];
  8819.         var percent = 1 - (time - frameTime) / (frames[frameIndex + -3/*LAST_FRAME_TIME*/] - frameTime);
  8820.         percent = this.curves.getCurvePercent(frameIndex / 3 - 1, percent);
  8821.  
  8822.         bone.x += (bone.data.x + lastFrameX + (frames[frameIndex + 1/*FRAME_X*/] - lastFrameX) * percent - bone.x) * alpha;
  8823.         bone.y += (bone.data.y + lastFrameY + (frames[frameIndex + 2/*FRAME_Y*/] - lastFrameY) * percent - bone.y) * alpha;
  8824.     }
  8825. };
  8826.  
  8827. spine.ScaleTimeline = function (frameCount) {
  8828.     this.curves = new spine.Curves(frameCount);
  8829.     this.frames = []; // time, x, y, ...
  8830.     this.frames.length = frameCount * 3;
  8831. };
  8832. spine.ScaleTimeline.prototype = {
  8833.     boneIndex: 0,
  8834.     getFrameCount: function () {
  8835.         return this.frames.length / 3;
  8836.     },
  8837.     setFrame: function (frameIndex, time, x, y) {
  8838.         frameIndex *= 3;
  8839.         this.frames[frameIndex] = time;
  8840.         this.frames[frameIndex + 1] = x;
  8841.         this.frames[frameIndex + 2] = y;
  8842.     },
  8843.     apply: function (skeleton, time, alpha) {
  8844.         var frames = this.frames;
  8845.         if (time < frames[0]) return; // Time is before first frame.
  8846.  
  8847.         var bone = skeleton.bones[this.boneIndex];
  8848.  
  8849.         if (time >= frames[frames.length - 3]) { // Time is after last frame.
  8850.             bone.scaleX += (bone.data.scaleX - 1 + frames[frames.length - 2] - bone.scaleX) * alpha;
  8851.             bone.scaleY += (bone.data.scaleY - 1 + frames[frames.length - 1] - bone.scaleY) * alpha;
  8852.             return;
  8853.         }
  8854.  
  8855.         // Interpolate between the last frame and the current frame.
  8856.         var frameIndex = spine.binarySearch(frames, time, 3);
  8857.         var lastFrameX = frames[frameIndex - 2];
  8858.         var lastFrameY = frames[frameIndex - 1];
  8859.         var frameTime = frames[frameIndex];
  8860.         var percent = 1 - (time - frameTime) / (frames[frameIndex + -3/*LAST_FRAME_TIME*/] - frameTime);
  8861.         percent = this.curves.getCurvePercent(frameIndex / 3 - 1, percent);
  8862.  
  8863.         bone.scaleX += (bone.data.scaleX - 1 + lastFrameX + (frames[frameIndex + 1/*FRAME_X*/] - lastFrameX) * percent - bone.scaleX) * alpha;
  8864.         bone.scaleY += (bone.data.scaleY - 1 + lastFrameY + (frames[frameIndex + 2/*FRAME_Y*/] - lastFrameY) * percent - bone.scaleY) * alpha;
  8865.     }
  8866. };
  8867.  
  8868. spine.ColorTimeline = function (frameCount) {
  8869.     this.curves = new spine.Curves(frameCount);
  8870.     this.frames = []; // time, r, g, b, a, ...
  8871.     this.frames.length = frameCount * 5;
  8872. };
  8873. spine.ColorTimeline.prototype = {
  8874.     slotIndex: 0,
  8875.     getFrameCount: function () {
  8876.         return this.frames.length / 2;
  8877.     },
  8878.     setFrame: function (frameIndex, time, x, y) {
  8879.         frameIndex *= 5;
  8880.         this.frames[frameIndex] = time;
  8881.         this.frames[frameIndex + 1] = r;
  8882.         this.frames[frameIndex + 2] = g;
  8883.         this.frames[frameIndex + 3] = b;
  8884.         this.frames[frameIndex + 4] = a;
  8885.     },
  8886.     apply: function (skeleton, time, alpha) {
  8887.         var frames = this.frames;
  8888.         if (time < frames[0]) return; // Time is before first frame.
  8889.  
  8890.         var slot = skeleton.slots[this.slotIndex];
  8891.  
  8892.         if (time >= frames[frames.length - 5]) { // Time is after last frame.
  8893.             var i = frames.length - 1;
  8894.             slot.r = frames[i - 3];
  8895.             slot.g = frames[i - 2];
  8896.             slot.b = frames[i - 1];
  8897.             slot.a = frames[i];
  8898.             return;
  8899.         }
  8900.  
  8901.         // Interpolate between the last frame and the current frame.
  8902.         var frameIndex = spine.binarySearch(frames, time, 5);
  8903.         var lastFrameR = frames[frameIndex - 4];
  8904.         var lastFrameG = frames[frameIndex - 3];
  8905.         var lastFrameB = frames[frameIndex - 2];
  8906.         var lastFrameA = frames[frameIndex - 1];
  8907.         var frameTime = frames[frameIndex];
  8908.         var percent = 1 - (time - frameTime) / (frames[frameIndex - 5/*LAST_FRAME_TIME*/] - frameTime);
  8909.         percent = this.curves.getCurvePercent(frameIndex / 5 - 1, percent);
  8910.  
  8911.         var r = lastFrameR + (frames[frameIndex + 1/*FRAME_R*/] - lastFrameR) * percent;
  8912.         var g = lastFrameG + (frames[frameIndex + 2/*FRAME_G*/] - lastFrameG) * percent;
  8913.         var b = lastFrameB + (frames[frameIndex + 3/*FRAME_B*/] - lastFrameB) * percent;
  8914.         var a = lastFrameA + (frames[frameIndex + 4/*FRAME_A*/] - lastFrameA) * percent;
  8915.         if (alpha < 1) {
  8916.             slot.r += (r - slot.r) * alpha;
  8917.             slot.g += (g - slot.g) * alpha;
  8918.             slot.b += (b - slot.b) * alpha;
  8919.             slot.a += (a - slot.a) * alpha;
  8920.         } else {
  8921.             slot.r = r;
  8922.             slot.g = g;
  8923.             slot.b = b;
  8924.             slot.a = a;
  8925.         }
  8926.     }
  8927. };
  8928.  
  8929. spine.AttachmentTimeline = function (frameCount) {
  8930.     this.curves = new spine.Curves(frameCount);
  8931.     this.frames = []; // time, ...
  8932.     this.frames.length = frameCount;
  8933.     this.attachmentNames = []; // time, ...
  8934.     this.attachmentNames.length = frameCount;
  8935. };
  8936. spine.AttachmentTimeline.prototype = {
  8937.     slotIndex: 0,
  8938.     getFrameCount: function () {
  8939.             return this.frames.length;
  8940.     },
  8941.     setFrame: function (frameIndex, time, attachmentName) {
  8942.         this.frames[frameIndex] = time;
  8943.         this.attachmentNames[frameIndex] = attachmentName;
  8944.     },
  8945.     apply: function (skeleton, time, alpha) {
  8946.         var frames = this.frames;
  8947.         if (time < frames[0]) return; // Time is before first frame.
  8948.  
  8949.         var frameIndex;
  8950.         if (time >= frames[frames.length - 1]) // Time is after last frame.
  8951.             frameIndex = frames.length - 1;
  8952.         else
  8953.             frameIndex = spine.binarySearch(frames, time, 1) - 1;
  8954.  
  8955.         var attachmentName = this.attachmentNames[frameIndex];
  8956.         skeleton.slots[this.slotIndex].setAttachment(!attachmentName ? null : skeleton.getAttachmentBySlotIndex(this.slotIndex, attachmentName));
  8957.     }
  8958. };
  8959.  
  8960. spine.SkeletonData = function () {
  8961.     this.bones = [];
  8962.     this.slots = [];
  8963.     this.skins = [];
  8964.     this.animations = [];
  8965. };
  8966. spine.SkeletonData.prototype = {
  8967.     defaultSkin: null,
  8968.     /** @return May be null. */
  8969.     findBone: function (boneName) {
  8970.         var bones = this.bones;
  8971.         for (var i = 0, n = bones.length; i < n; i++)
  8972.             if (bones[i].name == boneName) return bones[i];
  8973.         return null;
  8974.     },
  8975.     /** @return -1 if the bone was not found. */
  8976.     findBoneIndex: function (boneName) {
  8977.         var bones = this.bones;
  8978.         for (var i = 0, n = bones.length; i < n; i++)
  8979.             if (bones[i].name == boneName) return i;
  8980.         return -1;
  8981.     },
  8982.     /** @return May be null. */
  8983.     findSlot: function (slotName) {
  8984.         var slots = this.slots;
  8985.         for (var i = 0, n = slots.length; i < n; i++) {
  8986.             if (slots[i].name == slotName) return slot[i];
  8987.         }
  8988.         return null;
  8989.     },
  8990.     /** @return -1 if the bone was not found. */
  8991.     findSlotIndex: function (slotName) {
  8992.         var slots = this.slots;
  8993.         for (var i = 0, n = slots.length; i < n; i++)
  8994.             if (slots[i].name == slotName) return i;
  8995.         return -1;
  8996.     },
  8997.     /** @return May be null. */
  8998.     findSkin: function (skinName) {
  8999.         var skins = this.skins;
  9000.         for (var i = 0, n = skins.length; i < n; i++)
  9001.             if (skins[i].name == skinName) return skins[i];
  9002.         return null;
  9003.     },
  9004.     /** @return May be null. */
  9005.     findAnimation: function (animationName) {
  9006.         var animations = this.animations;
  9007.         for (var i = 0, n = animations.length; i < n; i++)
  9008.             if (animations[i].name == animationName) return animations[i];
  9009.         return null;
  9010.     }
  9011. };
  9012.  
  9013. spine.Skeleton = function (skeletonData) {
  9014.     this.data = skeletonData;
  9015.  
  9016.     this.bones = [];
  9017.     for (var i = 0, n = skeletonData.bones.length; i < n; i++) {
  9018.         var boneData = skeletonData.bones[i];
  9019.         var parent = !boneData.parent ? null : this.bones[skeletonData.bones.indexOf(boneData.parent)];
  9020.         this.bones.push(new spine.Bone(boneData, parent));
  9021.     }
  9022.  
  9023.     this.slots = [];
  9024.     this.drawOrder = [];
  9025.     for (var i = 0, n = skeletonData.slots.length; i < n; i++) {
  9026.         var slotData = skeletonData.slots[i];
  9027.         var bone = this.bones[skeletonData.bones.indexOf(slotData.boneData)];
  9028.         var slot = new spine.Slot(slotData, this, bone);
  9029.         this.slots.push(slot);
  9030.         this.drawOrder.push(slot);
  9031.     }
  9032. };
  9033. spine.Skeleton.prototype = {
  9034.     x: 0, y: 0,
  9035.     skin: null,
  9036.     r: 1, g: 1, b: 1, a: 1,
  9037.     time: 0,
  9038.     flipX: false, flipY: false,
  9039.     /** Updates the world transform for each bone. */
  9040.     updateWorldTransform: function () {
  9041.         var flipX = this.flipX;
  9042.         var flipY = this.flipY;
  9043.         var bones = this.bones;
  9044.         for (var i = 0, n = bones.length; i < n; i++)
  9045.             bones[i].updateWorldTransform(flipX, flipY);
  9046.     },
  9047.     /** Sets the bones and slots to their setup pose values. */
  9048.     setToSetupPose: function () {
  9049.         this.setBonesToSetupPose();
  9050.         this.setSlotsToSetupPose();
  9051.     },
  9052.     setBonesToSetupPose: function () {
  9053.         var bones = this.bones;
  9054.         for (var i = 0, n = bones.length; i < n; i++)
  9055.             bones[i].setToSetupPose();
  9056.     },
  9057.     setSlotsToSetupPose: function () {
  9058.         var slots = this.slots;
  9059.         for (var i = 0, n = slots.length; i < n; i++)
  9060.             slots[i].setToSetupPose(i);
  9061.     },
  9062.     /** @return May return null. */
  9063.     getRootBone: function () {
  9064.         return this.bones.length == 0 ? null : this.bones[0];
  9065.     },
  9066.     /** @return May be null. */
  9067.     findBone: function (boneName) {
  9068.         var bones = this.bones;
  9069.         for (var i = 0, n = bones.length; i < n; i++)
  9070.             if (bones[i].data.name == boneName) return bones[i];
  9071.         return null;
  9072.     },
  9073.     /** @return -1 if the bone was not found. */
  9074.     findBoneIndex: function (boneName) {
  9075.         var bones = this.bones;
  9076.         for (var i = 0, n = bones.length; i < n; i++)
  9077.             if (bones[i].data.name == boneName) return i;
  9078.         return -1;
  9079.     },
  9080.     /** @return May be null. */
  9081.     findSlot: function (slotName) {
  9082.         var slots = this.slots;
  9083.         for (var i = 0, n = slots.length; i < n; i++)
  9084.             if (slots[i].data.name == slotName) return slots[i];
  9085.         return null;
  9086.     },
  9087.     /** @return -1 if the bone was not found. */
  9088.     findSlotIndex: function (slotName) {
  9089.         var slots = this.slots;
  9090.         for (var i = 0, n = slots.length; i < n; i++)
  9091.             if (slots[i].data.name == slotName) return i;
  9092.         return -1;
  9093.     },
  9094.     setSkinByName: function (skinName) {
  9095.         var skin = this.data.findSkin(skinName);
  9096.         if (!skin) throw "Skin not found: " + skinName;
  9097.         this.setSkin(skin);
  9098.     },
  9099.     /** Sets the skin used to look up attachments not found in the {@link SkeletonData#getDefaultSkin() default skin}. Attachments
  9100.      * from the new skin are attached if the corresponding attachment from the old skin was attached.
  9101.      * @param newSkin May be null. */
  9102.     setSkin: function (newSkin) {
  9103.         if (this.skin && newSkin) newSkin._attachAll(this, this.skin);
  9104.         this.skin = newSkin;
  9105.     },
  9106.     /** @return May be null. */
  9107.     getAttachmentBySlotName: function (slotName, attachmentName) {
  9108.         return this.getAttachmentBySlotIndex(this.data.findSlotIndex(slotName), attachmentName);
  9109.     },
  9110.     /** @return May be null. */
  9111.     getAttachmentBySlotIndex: function (slotIndex, attachmentName) {
  9112.         if (this.skin) {
  9113.             var attachment = this.skin.getAttachment(slotIndex, attachmentName);
  9114.             if (attachment) return attachment;
  9115.         }
  9116.         if (this.data.defaultSkin) return this.data.defaultSkin.getAttachment(slotIndex, attachmentName);
  9117.         return null;
  9118.     },
  9119.     /** @param attachmentName May be null. */
  9120.     setAttachment: function (slotName, attachmentName) {
  9121.         var slots = this.slots;
  9122.         for (var i = 0, n = slots.size; i < n; i++) {
  9123.             var slot = slots[i];
  9124.             if (slot.data.name == slotName) {
  9125.                 var attachment = null;
  9126.                 if (attachmentName) {
  9127.                     attachment = this.getAttachment(i, attachmentName);
  9128.                     if (attachment == null) throw "Attachment not found: " + attachmentName + ", for slot: " + slotName;
  9129.                 }
  9130.                 slot.setAttachment(attachment);
  9131.                 return;
  9132.             }
  9133.         }
  9134.         throw "Slot not found: " + slotName;
  9135.     },
  9136.     update: function (delta) {
  9137.         time += delta;
  9138.     }
  9139. };
  9140.  
  9141. spine.AttachmentType = {
  9142.     region: 0
  9143. };
  9144.  
  9145. spine.RegionAttachment = function () {
  9146.     this.offset = [];
  9147.     this.offset.length = 8;
  9148.     this.uvs = [];
  9149.     this.uvs.length = 8;
  9150. };
  9151. spine.RegionAttachment.prototype = {
  9152.     x: 0, y: 0,
  9153.     rotation: 0,
  9154.     scaleX: 1, scaleY: 1,
  9155.     width: 0, height: 0,
  9156.     rendererObject: null,
  9157.     regionOffsetX: 0, regionOffsetY: 0,
  9158.     regionWidth: 0, regionHeight: 0,
  9159.     regionOriginalWidth: 0, regionOriginalHeight: 0,
  9160.     setUVs: function (u, v, u2, v2, rotate) {
  9161.         var uvs = this.uvs;
  9162.         if (rotate) {
  9163.             uvs[2/*X2*/] = u;
  9164.             uvs[3/*Y2*/] = v2;
  9165.             uvs[4/*X3*/] = u;
  9166.             uvs[5/*Y3*/] = v;
  9167.             uvs[6/*X4*/] = u2;
  9168.             uvs[7/*Y4*/] = v;
  9169.             uvs[0/*X1*/] = u2;
  9170.             uvs[1/*Y1*/] = v2;
  9171.         } else {
  9172.             uvs[0/*X1*/] = u;
  9173.             uvs[1/*Y1*/] = v2;
  9174.             uvs[2/*X2*/] = u;
  9175.             uvs[3/*Y2*/] = v;
  9176.             uvs[4/*X3*/] = u2;
  9177.             uvs[5/*Y3*/] = v;
  9178.             uvs[6/*X4*/] = u2;
  9179.             uvs[7/*Y4*/] = v2;
  9180.         }
  9181.     },
  9182.     updateOffset: function () {
  9183.         var regionScaleX = this.width / this.regionOriginalWidth * this.scaleX;
  9184.         var regionScaleY = this.height / this.regionOriginalHeight * this.scaleY;
  9185.         var localX = -this.width / 2 * this.scaleX + this.regionOffsetX * regionScaleX;
  9186.         var localY = -this.height / 2 * this.scaleY + this.regionOffsetY * regionScaleY;
  9187.         var localX2 = localX + this.regionWidth * regionScaleX;
  9188.         var localY2 = localY + this.regionHeight * regionScaleY;
  9189.         var radians = this.rotation * Math.PI / 180;
  9190.         var cos = Math.cos(radians);
  9191.         var sin = Math.sin(radians);
  9192.         var localXCos = localX * cos + this.x;
  9193.         var localXSin = localX * sin;
  9194.         var localYCos = localY * cos + this.y;
  9195.         var localYSin = localY * sin;
  9196.         var localX2Cos = localX2 * cos + this.x;
  9197.         var localX2Sin = localX2 * sin;
  9198.         var localY2Cos = localY2 * cos + this.y;
  9199.         var localY2Sin = localY2 * sin;
  9200.         var offset = this.offset;
  9201.         offset[0/*X1*/] = localXCos - localYSin;
  9202.         offset[1/*Y1*/] = localYCos + localXSin;
  9203.         offset[2/*X2*/] = localXCos - localY2Sin;
  9204.         offset[3/*Y2*/] = localY2Cos + localXSin;
  9205.         offset[4/*X3*/] = localX2Cos - localY2Sin;
  9206.         offset[5/*Y3*/] = localY2Cos + localX2Sin;
  9207.         offset[6/*X4*/] = localX2Cos - localYSin;
  9208.         offset[7/*Y4*/] = localYCos + localX2Sin;
  9209.     },
  9210.     computeVertices: function (x, y, bone, vertices) {
  9211.         x += bone.worldX;
  9212.         y += bone.worldY;
  9213.         var m00 = bone.m00;
  9214.         var m01 = bone.m01;
  9215.         var m10 = bone.m10;
  9216.         var m11 = bone.m11;
  9217.         var offset = this.offset;
  9218.         vertices[0/*X1*/] = offset[0/*X1*/] * m00 + offset[1/*Y1*/] * m01 + x;
  9219.         vertices[1/*Y1*/] = offset[0/*X1*/] * m10 + offset[1/*Y1*/] * m11 + y;
  9220.         vertices[2/*X2*/] = offset[2/*X2*/] * m00 + offset[3/*Y2*/] * m01 + x;
  9221.         vertices[3/*Y2*/] = offset[2/*X2*/] * m10 + offset[3/*Y2*/] * m11 + y;
  9222.         vertices[4/*X3*/] = offset[4/*X3*/] * m00 + offset[5/*X3*/] * m01 + x;
  9223.         vertices[5/*X3*/] = offset[4/*X3*/] * m10 + offset[5/*X3*/] * m11 + y;
  9224.         vertices[6/*X4*/] = offset[6/*X4*/] * m00 + offset[7/*Y4*/] * m01 + x;
  9225.         vertices[7/*Y4*/] = offset[6/*X4*/] * m10 + offset[7/*Y4*/] * m11 + y;
  9226.     }
  9227. }
  9228.  
  9229. spine.AnimationStateData = function (skeletonData) {
  9230.     this.skeletonData = skeletonData;
  9231.     this.animationToMixTime = {};
  9232. };
  9233. spine.AnimationStateData.prototype = {
  9234.         defaultMix: 0,
  9235.     setMixByName: function (fromName, toName, duration) {
  9236.         var from = this.skeletonData.findAnimation(fromName);
  9237.         if (!from) throw "Animation not found: " + fromName;
  9238.         var to = this.skeletonData.findAnimation(toName);
  9239.         if (!to) throw "Animation not found: " + toName;
  9240.         this.setMix(from, to, duration);
  9241.     },
  9242.     setMix: function (from, to, duration) {
  9243.         this.animationToMixTime[from.name + ":" + to.name] = duration;
  9244.     },
  9245.     getMix: function (from, to) {
  9246.         var time = this.animationToMixTime[from.name + ":" + to.name];
  9247.             return time ? time : this.defaultMix;
  9248.     }
  9249. };
  9250.  
  9251. spine.AnimationState = function (stateData) {
  9252.     this.data = stateData;
  9253.     this.queue = [];
  9254. };
  9255. spine.AnimationState.prototype = {
  9256.     current: null,
  9257.     previous: null,
  9258.     currentTime: 0,
  9259.     previousTime: 0,
  9260.     currentLoop: false,
  9261.     previousLoop: false,
  9262.     mixTime: 0,
  9263.     mixDuration: 0,
  9264.     update: function (delta) {
  9265.         this.currentTime += delta;
  9266.         this.previousTime += delta;
  9267.         this.mixTime += delta;
  9268.  
  9269.         if (this.queue.length > 0) {
  9270.             var entry = this.queue[0];
  9271.             if (this.currentTime >= entry.delay) {
  9272.                 this._setAnimation(entry.animation, entry.loop);
  9273.                 this.queue.shift();
  9274.             }
  9275.         }
  9276.     },
  9277.     apply: function (skeleton) {
  9278.         if (!this.current) return;
  9279.         if (this.previous) {
  9280.             this.previous.apply(skeleton, this.previousTime, this.previousLoop);
  9281.             var alpha = this.mixTime / this.mixDuration;
  9282.             if (alpha >= 1) {
  9283.                 alpha = 1;
  9284.                 this.previous = null;
  9285.             }
  9286.             this.current.mix(skeleton, this.currentTime, this.currentLoop, alpha);
  9287.         } else
  9288.             this.current.apply(skeleton, this.currentTime, this.currentLoop);
  9289.     },
  9290.     clearAnimation: function () {
  9291.         this.previous = null;
  9292.         this.current = null;
  9293.         this.queue.length = 0;
  9294.     },
  9295.     _setAnimation: function (animation, loop) {
  9296.         this.previous = null;
  9297.         if (animation && this.current) {
  9298.             this.mixDuration = this.data.getMix(this.current, animation);
  9299.             if (this.mixDuration > 0) {
  9300.                 this.mixTime = 0;
  9301.                 this.previous = this.current;
  9302.                 this.previousTime = this.currentTime;
  9303.                 this.previousLoop = this.currentLoop;
  9304.             }
  9305.         }
  9306.         this.current = animation;
  9307.         this.currentLoop = loop;
  9308.         this.currentTime = 0;
  9309.     },
  9310.     /** @see #setAnimation(Animation, Boolean) */
  9311.     setAnimationByName: function (animationName, loop) {
  9312.         var animation = this.data.skeletonData.findAnimation(animationName);
  9313.         if (!animation) throw "Animation not found: " + animationName;
  9314.         this.setAnimation(animation, loop);
  9315.     },
  9316.     /** Set the current animation. Any queued animations are cleared and the current animation time is set to 0.
  9317.      * @param animation May be null. */
  9318.     setAnimation: function (animation, loop) {
  9319.         this.queue.length = 0;
  9320.         this._setAnimation(animation, loop);
  9321.     },
  9322.     /** @see #addAnimation(Animation, Boolean, Number) */
  9323.     addAnimationByName: function (animationName, loop, delay) {
  9324.         var animation = this.data.skeletonData.findAnimation(animationName);
  9325.         if (!animation) throw "Animation not found: " + animationName;
  9326.         this.addAnimation(animation, loop, delay);
  9327.     },
  9328.     /** Adds an animation to be played delay seconds after the current or last queued animation.
  9329.      * @param delay May be <= 0 to use duration of previous animation minus any mix duration plus the negative delay. */
  9330.     addAnimation: function (animation, loop, delay) {
  9331.         var entry = {};
  9332.         entry.animation = animation;
  9333.         entry.loop = loop;
  9334.  
  9335.         if (!delay || delay <= 0) {
  9336.             var previousAnimation = this.queue.length == 0 ? this.current : this.queue[this.queue.length - 1].animation;
  9337.             if (previousAnimation != null)
  9338.                 delay = previousAnimation.duration - this.data.getMix(previousAnimation, animation) + (delay || 0);
  9339.             else
  9340.                 delay = 0;
  9341.         }
  9342.         entry.delay = delay;
  9343.  
  9344.         this.queue.push(entry);
  9345.     },
  9346.     /** Returns true if no animation is set or if the current time is greater than the animation duration, regardless of looping. */
  9347.     isComplete: function () {
  9348.         return !this.current || this.currentTime >= this.current.duration;
  9349.     }
  9350. };
  9351.  
  9352. spine.SkeletonJson = function (attachmentLoader) {
  9353.     this.attachmentLoader = attachmentLoader;
  9354. };
  9355. spine.SkeletonJson.prototype = {
  9356.     scale: 1,
  9357.     readSkeletonData: function (root) {
  9358.         var skeletonData = new spine.SkeletonData();
  9359.  
  9360.         // Bones.
  9361.         var bones = root["bones"];
  9362.         for (var i = 0, n = bones.length; i < n; i++) {
  9363.             var boneMap = bones[i];
  9364.             var parent = null;
  9365.             if (boneMap["parent"]) {
  9366.                 parent = skeletonData.findBone(boneMap["parent"]);
  9367.                 if (!parent) throw "Parent bone not found: " + boneMap["parent"];
  9368.             }
  9369.             var boneData = new spine.BoneData(boneMap["name"], parent);
  9370.             boneData.length = (boneMap["length"] || 0) * this.scale;
  9371.             boneData.x = (boneMap["x"] || 0) * this.scale;
  9372.             boneData.y = (boneMap["y"] || 0) * this.scale;
  9373.             boneData.rotation = (boneMap["rotation"] || 0);
  9374.             boneData.scaleX = boneMap["scaleX"] || 1;
  9375.             boneData.scaleY = boneMap["scaleY"] || 1;
  9376.             skeletonData.bones.push(boneData);
  9377.         }
  9378.  
  9379.         // Slots.
  9380.         var slots = root["slots"];
  9381.         for (var i = 0, n = slots.length; i < n; i++) {
  9382.             var slotMap = slots[i];
  9383.             var boneData = skeletonData.findBone(slotMap["bone"]);
  9384.             if (!boneData) throw "Slot bone not found: " + slotMap["bone"];
  9385.             var slotData = new spine.SlotData(slotMap["name"], boneData);
  9386.  
  9387.             var color = slotMap["color"];
  9388.             if (color) {
  9389.                 slotData.r = spine.SkeletonJson.toColor(color, 0);
  9390.                 slotData.g = spine.SkeletonJson.toColor(color, 1);
  9391.                 slotData.b = spine.SkeletonJson.toColor(color, 2);
  9392.                 slotData.a = spine.SkeletonJson.toColor(color, 3);
  9393.             }
  9394.  
  9395.             slotData.attachmentName = slotMap["attachment"];
  9396.  
  9397.             skeletonData.slots.push(slotData);
  9398.         }
  9399.  
  9400.         // Skins.
  9401.         var skins = root["skins"];
  9402.         for (var skinName in skins) {
  9403.             if (!skins.hasOwnProperty(skinName)) continue;
  9404.             var skinMap = skins[skinName];
  9405.             var skin = new spine.Skin(skinName);
  9406.             for (var slotName in skinMap) {
  9407.                 if (!skinMap.hasOwnProperty(slotName)) continue;
  9408.                 var slotIndex = skeletonData.findSlotIndex(slotName);
  9409.                 var slotEntry = skinMap[slotName];
  9410.                 for (var attachmentName in slotEntry) {
  9411.                     if (!slotEntry.hasOwnProperty(attachmentName)) continue;
  9412.                     var attachment = this.readAttachment(skin, attachmentName, slotEntry[attachmentName]);
  9413.                     if (attachment != null) skin.addAttachment(slotIndex, attachmentName, attachment);
  9414.                 }
  9415.             }
  9416.             skeletonData.skins.push(skin);
  9417.             if (skin.name == "default") skeletonData.defaultSkin = skin;
  9418.         }
  9419.  
  9420.         // Animations.
  9421.         var animations = root["animations"];
  9422.         for (var animationName in animations) {
  9423.             if (!animations.hasOwnProperty(animationName)) continue;
  9424.             this.readAnimation(animationName, animations[animationName], skeletonData);
  9425.         }
  9426.  
  9427.         return skeletonData;
  9428.     },
  9429.     readAttachment: function (skin, name, map) {
  9430.         name = map["name"] || name;
  9431.  
  9432.         var type = spine.AttachmentType[map["type"] || "region"];
  9433.  
  9434.         if (type == spine.AttachmentType.region) {
  9435.             var attachment = new spine.RegionAttachment();
  9436.             attachment.x = (map["x"] || 0) * this.scale;
  9437.             attachment.y = (map["y"] || 0) * this.scale;
  9438.             attachment.scaleX = map["scaleX"] || 1;
  9439.             attachment.scaleY = map["scaleY"] || 1;
  9440.             attachment.rotation = map["rotation"] || 0;
  9441.             attachment.width = (map["width"] || 32) * this.scale;
  9442.             attachment.height = (map["height"] || 32) * this.scale;
  9443.             attachment.updateOffset();
  9444.  
  9445.             attachment.rendererObject = {};
  9446.             attachment.rendererObject.name = name;
  9447.             attachment.rendererObject.scale = {};
  9448.             attachment.rendererObject.scale.x = attachment.scaleX;
  9449.             attachment.rendererObject.scale.y = attachment.scaleY;
  9450.             attachment.rendererObject.rotation = -attachment.rotation * Math.PI / 180;
  9451.             return attachment;
  9452.         }
  9453.  
  9454.             throw "Unknown attachment type: " + type;
  9455.     },
  9456.  
  9457.     readAnimation: function (name, map, skeletonData) {
  9458.         var timelines = [];
  9459.         var duration = 0;
  9460.  
  9461.         var bones = map["bones"];
  9462.         for (var boneName in bones) {
  9463.             if (!bones.hasOwnProperty(boneName)) continue;
  9464.             var boneIndex = skeletonData.findBoneIndex(boneName);
  9465.             if (boneIndex == -1) throw "Bone not found: " + boneName;
  9466.             var boneMap = bones[boneName];
  9467.  
  9468.             for (var timelineName in boneMap) {
  9469.                 if (!boneMap.hasOwnProperty(timelineName)) continue;
  9470.                 var values = boneMap[timelineName];
  9471.                 if (timelineName == "rotate") {
  9472.                     var timeline = new spine.RotateTimeline(values.length);
  9473.                     timeline.boneIndex = boneIndex;
  9474.  
  9475.                     var frameIndex = 0;
  9476.                     for (var i = 0, n = values.length; i < n; i++) {
  9477.                         var valueMap = values[i];
  9478.                         timeline.setFrame(frameIndex, valueMap["time"], valueMap["angle"]);
  9479.                         spine.SkeletonJson.readCurve(timeline, frameIndex, valueMap);
  9480.                         frameIndex++;
  9481.                     }
  9482.                     timelines.push(timeline);
  9483.                     duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 2 - 2]);
  9484.  
  9485.                 } else if (timelineName == "translate" || timelineName == "scale") {
  9486.                     var timeline;
  9487.                     var timelineScale = 1;
  9488.                     if (timelineName == "scale")
  9489.                         timeline = new spine.ScaleTimeline(values.length);
  9490.                     else {
  9491.                         timeline = new spine.TranslateTimeline(values.length);
  9492.                         timelineScale = this.scale;
  9493.                     }
  9494.                     timeline.boneIndex = boneIndex;
  9495.  
  9496.                     var frameIndex = 0;
  9497.                     for (var i = 0, n = values.length; i < n; i++) {
  9498.                         var valueMap = values[i];
  9499.                         var x = (valueMap["x"] || 0) * timelineScale;
  9500.                         var y = (valueMap["y"] || 0) * timelineScale;
  9501.                         timeline.setFrame(frameIndex, valueMap["time"], x, y);
  9502.                         spine.SkeletonJson.readCurve(timeline, frameIndex, valueMap);
  9503.                         frameIndex++;
  9504.                     }
  9505.                     timelines.push(timeline);
  9506.                     duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 3 - 3]);
  9507.  
  9508.                 } else
  9509.                     throw "Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")";
  9510.             }
  9511.         }
  9512.         var slots = map["slots"];
  9513.         for (var slotName in slots) {
  9514.             if (!slots.hasOwnProperty(slotName)) continue;
  9515.             var slotMap = slots[slotName];
  9516.             var slotIndex = skeletonData.findSlotIndex(slotName);
  9517.  
  9518.             for (var timelineName in slotMap) {
  9519.                 if (!slotMap.hasOwnProperty(timelineName)) continue;
  9520.                 var values = slotMap[timelineName];
  9521.                 if (timelineName == "color") {
  9522.                     var timeline = new spine.ColorTimeline(values.length);
  9523.                     timeline.slotIndex = slotIndex;
  9524.  
  9525.                     var frameIndex = 0;
  9526.                     for (var i = 0, n = values.length; i < n; i++) {
  9527.                         var valueMap = values[i];
  9528.                         var color = valueMap["color"];
  9529.                         var r = spine.SkeletonJson.toColor(color, 0);
  9530.                         var g = spine.SkeletonJson.toColor(color, 1);
  9531.                         var b = spine.SkeletonJson.toColor(color, 2);
  9532.                         var a = spine.SkeletonJson.toColor(color, 3);
  9533.                         timeline.setFrame(frameIndex, valueMap["time"], r, g, b, a);
  9534.                         spine.SkeletonJson.readCurve(timeline, frameIndex, valueMap);
  9535.                         frameIndex++;
  9536.                     }
  9537.                     timelines.push(timeline);
  9538.                     duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 5 - 5]);
  9539.  
  9540.                 } else if (timelineName == "attachment") {
  9541.                     var timeline = new spine.AttachmentTimeline(values.length);
  9542.                     timeline.slotIndex = slotIndex;
  9543.  
  9544.                     var frameIndex = 0;
  9545.                     for (var i = 0, n = values.length; i < n; i++) {
  9546.                         var valueMap = values[i];
  9547.                         timeline.setFrame(frameIndex++, valueMap["time"], valueMap["name"]);
  9548.                     }
  9549.                     timelines.push(timeline);
  9550.                         duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]);
  9551.  
  9552.                 } else
  9553.                     throw "Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")";
  9554.             }
  9555.         }
  9556.         skeletonData.animations.push(new spine.Animation(name, timelines, duration));
  9557.     }
  9558. };
  9559. spine.SkeletonJson.readCurve = function (timeline, frameIndex, valueMap) {
  9560.     var curve = valueMap["curve"];
  9561.     if (!curve) return;
  9562.     if (curve == "stepped")
  9563.         timeline.curves.setStepped(frameIndex);
  9564.     else if (curve instanceof Array)
  9565.         timeline.curves.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]);
  9566. };
  9567. spine.SkeletonJson.toColor = function (hexString, colorIndex) {
  9568.     if (hexString.length != 8) throw "Color hexidecimal length must be 8, recieved: " + hexString;
  9569.     return parseInt(hexString.substring(colorIndex * 2, 2), 16) / 255;
  9570. };
  9571.  
  9572. spine.Atlas = function (atlasText, textureLoader) {
  9573.     this.textureLoader = textureLoader;
  9574.     this.pages = [];
  9575.     this.regions = [];
  9576.  
  9577.     var reader = new spine.AtlasReader(atlasText);
  9578.     var tuple = [];
  9579.     tuple.length = 4;
  9580.     var page = null;
  9581.     while (true) {
  9582.         var line = reader.readLine();
  9583.         if (line == null) break;
  9584.         line = reader.trim(line);
  9585.         if (line.length == 0)
  9586.             page = null;
  9587.         else if (!page) {
  9588.             page = new spine.AtlasPage();
  9589.             page.name = line;
  9590.  
  9591.             page.format = spine.Atlas.Format[reader.readValue()];
  9592.  
  9593.             reader.readTuple(tuple);
  9594.             page.minFilter = spine.Atlas.TextureFilter[tuple[0]];
  9595.             page.magFilter = spine.Atlas.TextureFilter[tuple[1]];
  9596.  
  9597.             var direction = reader.readValue();
  9598.             page.uWrap = spine.Atlas.TextureWrap.clampToEdge;
  9599.             page.vWrap = spine.Atlas.TextureWrap.clampToEdge;
  9600.             if (direction == "x")
  9601.                 page.uWrap = spine.Atlas.TextureWrap.repeat;
  9602.             else if (direction == "y")
  9603.                 page.vWrap = spine.Atlas.TextureWrap.repeat;
  9604.             else if (direction == "xy")
  9605.                 page.uWrap = page.vWrap = spine.Atlas.TextureWrap.repeat;
  9606.  
  9607.             textureLoader.load(page, line);
  9608.  
  9609.             this.pages.push(page);
  9610.  
  9611.         } else {
  9612.             var region = new spine.AtlasRegion();
  9613.             region.name = line;
  9614.             region.page = page;
  9615.  
  9616.             region.rotate = reader.readValue() == "true";
  9617.  
  9618.             reader.readTuple(tuple);
  9619.             var x = parseInt(tuple[0]);
  9620.             var y = parseInt(tuple[1]);
  9621.  
  9622.             reader.readTuple(tuple);
  9623.             var width = parseInt(tuple[0]);
  9624.             var height = parseInt(tuple[1]);
  9625.  
  9626.             region.u = x / page.width;
  9627.             region.v = y / page.height;
  9628.             if (region.rotate) {
  9629.                 region.u2 = (x + height) / page.width;
  9630.                 region.v2 = (y + width) / page.height;
  9631.             } else {
  9632.                 region.u2 = (x + width) / page.width;
  9633.                 region.v2 = (y + height) / page.height;
  9634.             }
  9635.             region.x = x;
  9636.             region.y = y;
  9637.             region.width = Math.abs(width);
  9638.             region.height = Math.abs(height);
  9639.  
  9640.             if (reader.readTuple(tuple) == 4) { // split is optional
  9641.                 region.splits = [parseInt(tuple[0]), parseInt(tuple[1]), parseInt(tuple[2]), parseInt(tuple[3])];
  9642.  
  9643.                 if (reader.readTuple(tuple) == 4) { // pad is optional, but only present with splits
  9644.                     region.pads = [parseInt(tuple[0]), parseInt(tuple[1]), parseInt(tuple[2]), parseInt(tuple[3])];
  9645.  
  9646.                     reader.readTuple(tuple);
  9647.                 }
  9648.             }
  9649.  
  9650.             region.originalWidth = parseInt(tuple[0]);
  9651.             region.originalHeight = parseInt(tuple[1]);
  9652.  
  9653.             reader.readTuple(tuple);
  9654.             region.offsetX = parseInt(tuple[0]);
  9655.             region.offsetY = parseInt(tuple[1]);
  9656.  
  9657.             region.index = parseInt(reader.readValue());
  9658.  
  9659.             this.regions.push(region);
  9660.         }
  9661.     }
  9662. };
  9663. spine.Atlas.prototype = {
  9664.     findRegion: function (name) {
  9665.         var regions = this.regions;
  9666.         for (var i = 0, n = regions.length; i < n; i++)
  9667.             if (regions[i].name == name) return regions[i];
  9668.         return null;
  9669.     },
  9670.     dispose: function () {
  9671.         var pages = this.pages;
  9672.         for (var i = 0, n = pages.length; i < n; i++)
  9673.             this.textureLoader.unload(pages[i].rendererObject);
  9674.     },
  9675.     updateUVs: function (page) {
  9676.         var regions = this.regions;
  9677.         for (var i = 0, n = regions.length; i < n; i++) {
  9678.             var region = regions[i];
  9679.             if (region.page != page) continue;
  9680.             region.u = region.x / page.width;
  9681.             region.v = region.y / page.height;
  9682.             if (region.rotate) {
  9683.                 region.u2 = (region.x + region.height) / page.width;
  9684.                 region.v2 = (region.y + region.width) / page.height;
  9685.             } else {
  9686.                 region.u2 = (region.x + region.width) / page.width;
  9687.                 region.v2 = (region.y + region.height) / page.height;
  9688.             }
  9689.         }
  9690.     }
  9691. };
  9692.  
  9693. spine.Atlas.Format = {
  9694.     alpha: 0,
  9695.     intensity: 1,
  9696.     luminanceAlpha: 2,
  9697.     rgb565: 3,
  9698.     rgba4444: 4,
  9699.     rgb888: 5,
  9700.     rgba8888: 6
  9701. };
  9702.  
  9703. spine.Atlas.TextureFilter = {
  9704.     nearest: 0,
  9705.     linear: 1,
  9706.     mipMap: 2,
  9707.     mipMapNearestNearest: 3,
  9708.     mipMapLinearNearest: 4,
  9709.     mipMapNearestLinear: 5,
  9710.     mipMapLinearLinear: 6
  9711. };
  9712.  
  9713. spine.Atlas.TextureWrap = {
  9714.     mirroredRepeat: 0,
  9715.     clampToEdge: 1,
  9716.     repeat: 2
  9717. };
  9718.  
  9719. spine.AtlasPage = function () {};
  9720. spine.AtlasPage.prototype = {
  9721.     name: null,
  9722.     format: null,
  9723.     minFilter: null,
  9724.     magFilter: null,
  9725.     uWrap: null,
  9726.     vWrap: null,
  9727.     rendererObject: null,
  9728.     width: 0,
  9729.     height: 0
  9730. };
  9731.  
  9732. spine.AtlasRegion = function () {};
  9733. spine.AtlasRegion.prototype = {
  9734.     page: null,
  9735.     name: null,
  9736.     x: 0, y: 0,
  9737.     width: 0, height: 0,
  9738.     u: 0, v: 0, u2: 0, v2: 0,
  9739.     offsetX: 0, offsetY: 0,
  9740.     originalWidth: 0, originalHeight: 0,
  9741.     index: 0,
  9742.     rotate: false,
  9743.     splits: null,
  9744.     pads: null,
  9745. };
  9746.  
  9747. spine.AtlasReader = function (text) {
  9748.     this.lines = text.split(/\r\n|\r|\n/);
  9749. };
  9750. spine.AtlasReader.prototype = {
  9751.     index: 0,
  9752.     trim: function (value) {
  9753.         return value.replace(/^\s+|\s+$/g, "");
  9754.     },
  9755.     readLine: function () {
  9756.         if (this.index >= this.lines.length) return null;
  9757.         return this.lines[this.index++];
  9758.     },
  9759.     readValue: function () {
  9760.         var line = this.readLine();
  9761.         var colon = line.indexOf(":");
  9762.         if (colon == -1) throw "Invalid line: " + line;
  9763.         return this.trim(line.substring(colon + 1));
  9764.     },
  9765.     /** Returns the number of tuple values read (2 or 4). */
  9766.     readTuple: function (tuple) {
  9767.         var line = this.readLine();
  9768.         var colon = line.indexOf(":");
  9769.         if (colon == -1) throw "Invalid line: " + line;
  9770.         var i = 0, lastMatch= colon + 1;
  9771.         for (; i < 3; i++) {
  9772.             var comma = line.indexOf(",", lastMatch);
  9773.             if (comma == -1) {
  9774.                 if (i == 0) throw "Invalid line: " + line;
  9775.                 break;
  9776.             }
  9777.             tuple[i] = this.trim(line.substr(lastMatch, comma - lastMatch));
  9778.             lastMatch = comma + 1;
  9779.         }
  9780.         tuple[i] = this.trim(line.substring(lastMatch));
  9781.         return i + 1;
  9782.     }
  9783. }
  9784.  
  9785. spine.AtlasAttachmentLoader = function (atlas) {
  9786.     this.atlas = atlas;
  9787. }
  9788. spine.AtlasAttachmentLoader.prototype = {
  9789.     newAttachment: function (skin, type, name) {
  9790.         switch (type) {
  9791.         case spine.AttachmentType.region:
  9792.             var region = this.atlas.findRegion(name);
  9793.             if (!region) throw "Region not found in atlas: " + name + " (" + type + ")";
  9794.             var attachment = new spine.RegionAttachment(name);
  9795.             attachment.rendererObject = region;
  9796.             attachment.setUVs(region.u, region.v, region.u2, region.v2, region.rotate);
  9797.             attachment.regionOffsetX = region.offsetX;
  9798.             attachment.regionOffsetY = region.offsetY;
  9799.             attachment.regionWidth = region.width;
  9800.             attachment.regionHeight = region.height;
  9801.             attachment.regionOriginalWidth = region.originalWidth;
  9802.             attachment.regionOriginalHeight = region.originalHeight;
  9803.             return attachment;
  9804.         }
  9805.         throw "Unknown attachment type: " + type;
  9806.     }
  9807. }
  9808.  
  9809. PIXI.AnimCache = {};
  9810. spine.Bone.yDown = true;
  9811.  
  9812. /**
  9813.  * @author Mat Groves http://matgroves.com/ @Doormat23
  9814.  */
  9815.  
  9816.  
  9817. /**
  9818.  * This object is one that will allow you to specify custom rendering functions based on render type
  9819.  *
  9820.  * @class CustomRenderable
  9821.  * @extends DisplayObject
  9822.  * @constructor
  9823.  */
  9824. PIXI.CustomRenderable = function()
  9825. {
  9826.     PIXI.DisplayObject.call( this );
  9827.    
  9828.     this.renderable = true;
  9829. }
  9830.  
  9831. // constructor
  9832. PIXI.CustomRenderable.prototype = Object.create( PIXI.DisplayObject.prototype );
  9833. PIXI.CustomRenderable.prototype.constructor = PIXI.CustomRenderable;
  9834.  
  9835. /**
  9836.  * If this object is being rendered by a CanvasRenderer it will call this callback
  9837.  *
  9838.  * @method renderCanvas
  9839.  * @param renderer {CanvasRenderer} The renderer instance
  9840.  */
  9841. PIXI.CustomRenderable.prototype.renderCanvas = function(renderer)
  9842. {
  9843.     // override!
  9844. }
  9845.  
  9846. /**
  9847.  * If this object is being rendered by a WebGLRenderer it will call this callback to initialize
  9848.  *
  9849.  * @method initWebGL
  9850.  * @param renderer {WebGLRenderer} The renderer instance
  9851.  */
  9852. PIXI.CustomRenderable.prototype.initWebGL = function(renderer)
  9853. {
  9854.     // override!
  9855. }
  9856.  
  9857. /**
  9858.  * If this object is being rendered by a WebGLRenderer it will call this callback
  9859.  *
  9860.  * @method renderWebGL
  9861.  * @param renderer {WebGLRenderer} The renderer instance
  9862.  */
  9863. PIXI.CustomRenderable.prototype.renderWebGL = function(renderGroup, projectionMatrix)
  9864. {
  9865.     // not sure if both needed? but ya have for now!
  9866.     // override!
  9867. }
  9868.  
  9869.  
  9870. /**
  9871.  * @author Mat Groves http://matgroves.com/ @Doormat23
  9872.  */
  9873.  
  9874. PIXI.BaseTextureCache = {};
  9875. PIXI.texturesToUpdate = [];
  9876. PIXI.texturesToDestroy = [];
  9877.  
  9878. /**
  9879.  * A texture stores the information that represents an image. All textures have a base texture
  9880.  *
  9881.  * @class BaseTexture
  9882.  * @uses EventTarget
  9883.  * @constructor
  9884.  * @param source {String} the source object (image or canvas)
  9885.  */
  9886. PIXI.BaseTexture = function(source)
  9887. {
  9888.     PIXI.EventTarget.call( this );
  9889.  
  9890.     /**
  9891.      * [read-only] The width of the base texture set when the image has loaded
  9892.      *
  9893.      * @property width
  9894.      * @type Number
  9895.      * @readOnly
  9896.      */
  9897.     this.width = 100;
  9898.  
  9899.     /**
  9900.      * [read-only] The height of the base texture set when the image has loaded
  9901.      *
  9902.      * @property height
  9903.      * @type Number
  9904.      * @readOnly
  9905.      */
  9906.     this.height = 100;
  9907.  
  9908.     /**
  9909.      * [read-only] Describes if the base texture has loaded or not
  9910.      *
  9911.      * @property hasLoaded
  9912.      * @type Boolean
  9913.      * @readOnly
  9914.      */
  9915.     this.hasLoaded = false;
  9916.  
  9917.     /**
  9918.      * The source that is loaded to create the texture
  9919.      *
  9920.      * @property source
  9921.      * @type Image
  9922.      */
  9923.     this.source = source;
  9924.  
  9925.     if(!source)return;
  9926.  
  9927.     if(this.source instanceof Image || this.source instanceof HTMLImageElement)
  9928.     {
  9929.         if(this.source.complete)
  9930.         {
  9931.             this.hasLoaded = true;
  9932.             this.width = this.source.width;
  9933.             this.height = this.source.height;
  9934.  
  9935.             PIXI.texturesToUpdate.push(this);
  9936.         }
  9937.         else
  9938.         {
  9939.  
  9940.             var scope = this;
  9941.             this.source.onload = function(){
  9942.  
  9943.                 scope.hasLoaded = true;
  9944.                 scope.width = scope.source.width;
  9945.                 scope.height = scope.source.height;
  9946.  
  9947.                 // add it to somewhere...
  9948.                 PIXI.texturesToUpdate.push(scope);
  9949.                 scope.dispatchEvent( { type: 'loaded', content: scope } );
  9950.             }
  9951.             //  this.image.src = imageUrl;
  9952.         }
  9953.     }
  9954.     else
  9955.     {
  9956.         this.hasLoaded = true;
  9957.         this.width = this.source.width;
  9958.         this.height = this.source.height;
  9959.  
  9960.         PIXI.texturesToUpdate.push(this);
  9961.     }
  9962.  
  9963.     this._powerOf2 = false;
  9964. }
  9965.  
  9966. PIXI.BaseTexture.prototype.constructor = PIXI.BaseTexture;
  9967.  
  9968. /**
  9969.  * Destroys this base texture
  9970.  *
  9971.  * @method destroy
  9972.  */
  9973. PIXI.BaseTexture.prototype.destroy = function()
  9974. {
  9975.     if(this.source instanceof Image)
  9976.     {
  9977.         this.source.src = null;
  9978.     }
  9979.     this.source = null;
  9980.     PIXI.texturesToDestroy.push(this);
  9981. }
  9982.  
  9983. /**
  9984.  * Helper function that returns a base texture based on an image url
  9985.  * If the image is not in the base texture cache it will be  created and loaded
  9986.  *
  9987.  * @static
  9988.  * @method fromImage
  9989.  * @param imageUrl {String} The image url of the texture
  9990.  * @return BaseTexture
  9991.  */
  9992. PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin)
  9993. {
  9994.     var baseTexture = PIXI.BaseTextureCache[imageUrl];
  9995.     if(!baseTexture)
  9996.     {
  9997.         // new Image() breaks tex loading in some versions of Chrome.
  9998.         // See https://code.google.com/p/chromium/issues/detail?id=238071
  9999.         var image = new Image();//document.createElement('img');
  10000.         if (crossorigin)
  10001.         {
  10002.             image.crossOrigin = '';
  10003.         }
  10004.         image.src = imageUrl;
  10005.         baseTexture = new PIXI.BaseTexture(image);
  10006.         PIXI.BaseTextureCache[imageUrl] = baseTexture;
  10007.     }
  10008.  
  10009.     return baseTexture;
  10010. }
  10011.  
  10012. /**
  10013.  * @author Mat Groves http://matgroves.com/ @Doormat23
  10014.  */
  10015.  
  10016. PIXI.TextureCache = {};
  10017. PIXI.FrameCache = {};
  10018.  
  10019. /**
  10020.  * A texture stores the information that represents an image or part of an image. It cannot be added
  10021.  * to the display list directly. To do this use PIXI.Sprite. If no frame is provided then the whole image is used
  10022.  *
  10023.  * @class Texture
  10024.  * @uses EventTarget
  10025.  * @constructor
  10026.  * @param baseTexture {BaseTexture} The base texture source to create the texture from
  10027.  * @param frame {Rectangle} The rectangle frame of the texture to show
  10028.  */
  10029. PIXI.Texture = function(baseTexture, frame)
  10030. {
  10031.     PIXI.EventTarget.call( this );
  10032.  
  10033.     if(!frame)
  10034.     {
  10035.         this.noFrame = true;
  10036.         frame = new PIXI.Rectangle(0,0,1,1);
  10037.     }
  10038.  
  10039.     if(baseTexture instanceof PIXI.Texture)
  10040.         baseTexture = baseTexture.baseTexture;
  10041.  
  10042.     /**
  10043.      * The base texture of this texture
  10044.      *
  10045.      * @property baseTexture
  10046.      * @type BaseTexture
  10047.      */
  10048.     this.baseTexture = baseTexture;
  10049.  
  10050.     /**
  10051.      * The frame specifies the region of the base texture that this texture uses
  10052.      *
  10053.      * @property frame
  10054.      * @type Rectangle
  10055.      */
  10056.     this.frame = frame;
  10057.  
  10058.     /**
  10059.      * The trim point
  10060.      *
  10061.      * @property trim
  10062.      * @type Point
  10063.      */
  10064.     this.trim = new PIXI.Point();
  10065.  
  10066.     this.scope = this;
  10067.  
  10068.     if(baseTexture.hasLoaded)
  10069.     {
  10070.         if(this.noFrame)frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height);
  10071.         //console.log(frame)
  10072.  
  10073.         this.setFrame(frame);
  10074.     }
  10075.     else
  10076.     {
  10077.         var scope = this;
  10078.         baseTexture.addEventListener( 'loaded', function(){ scope.onBaseTextureLoaded()} );
  10079.     }
  10080. }
  10081.  
  10082. PIXI.Texture.prototype.constructor = PIXI.Texture;
  10083.  
  10084. /**
  10085.  * Called when the base texture is loaded
  10086.  *
  10087.  * @method onBaseTextureLoaded
  10088.  * @param event
  10089.  * @private
  10090.  */
  10091. PIXI.Texture.prototype.onBaseTextureLoaded = function(event)
  10092. {
  10093.     var baseTexture = this.baseTexture;
  10094.     baseTexture.removeEventListener( 'loaded', this.onLoaded );
  10095.  
  10096.     if(this.noFrame)this.frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height);
  10097.     this.noFrame = false;
  10098.     this.width = this.frame.width;
  10099.     this.height = this.frame.height;
  10100.  
  10101.     this.scope.dispatchEvent( { type: 'update', content: this } );
  10102. }
  10103.  
  10104. /**
  10105.  * Destroys this texture
  10106.  *
  10107.  * @method destroy
  10108.  * @param destroyBase {Boolean} Whether to destroy the base texture as well
  10109.  */
  10110. PIXI.Texture.prototype.destroy = function(destroyBase)
  10111. {
  10112.     if(destroyBase)this.baseTexture.destroy();
  10113. }
  10114.  
  10115. /**
  10116.  * Specifies the rectangle region of the baseTexture
  10117.  *
  10118.  * @method setFrame
  10119.  * @param frame {Rectangle} The frame of the texture to set it to
  10120.  */
  10121. PIXI.Texture.prototype.setFrame = function(frame)
  10122. {
  10123.     this.frame = frame;
  10124.     this.width = frame.width;
  10125.     this.height = frame.height;
  10126.  
  10127.     if(frame.x + frame.width > this.baseTexture.width || frame.y + frame.height > this.baseTexture.height)
  10128.     {
  10129.         throw new Error("Texture Error: frame does not fit inside the base Texture dimensions " + this);
  10130.     }
  10131.  
  10132.     this.updateFrame = true;
  10133.  
  10134.     PIXI.Texture.frameUpdates.push(this);
  10135.     //this.dispatchEvent( { type: 'update', content: this } );
  10136. }
  10137.  
  10138. /**
  10139.  * Helper function that returns a texture based on an image url
  10140.  * If the image is not in the texture cache it will be  created and loaded
  10141.  *
  10142.  * @static
  10143.  * @method fromImage
  10144.  * @param imageUrl {String} The image url of the texture
  10145.  * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
  10146.  * @return Texture
  10147.  */
  10148. PIXI.Texture.fromImage = function(imageUrl, crossorigin)
  10149. {
  10150.     var texture = PIXI.TextureCache[imageUrl];
  10151.  
  10152.     if(!texture)
  10153.     {
  10154.         texture = new PIXI.Texture(PIXI.BaseTexture.fromImage(imageUrl, crossorigin));
  10155.         PIXI.TextureCache[imageUrl] = texture;
  10156.     }
  10157.  
  10158.     return texture;
  10159. }
  10160.  
  10161. /**
  10162.  * Helper function that returns a texture based on a frame id
  10163.  * If the frame id is not in the texture cache an error will be thrown
  10164.  *
  10165.  * @static
  10166.  * @method fromFrame
  10167.  * @param frameId {String} The frame id of the texture
  10168.  * @return Texture
  10169.  */
  10170. PIXI.Texture.fromFrame = function(frameId)
  10171. {
  10172.     var texture = PIXI.TextureCache[frameId];
  10173.     if(!texture)throw new Error("The frameId '"+ frameId +"' does not exist in the texture cache " + this);
  10174.     return texture;
  10175. }
  10176.  
  10177. /**
  10178.  * Helper function that returns a texture based on a canvas element
  10179.  * If the canvas is not in the texture cache it will be  created and loaded
  10180.  *
  10181.  * @static
  10182.  * @method fromCanvas
  10183.  * @param canvas {Canvas} The canvas element source of the texture
  10184.  * @return Texture
  10185.  */
  10186. PIXI.Texture.fromCanvas = function(canvas)
  10187. {
  10188.     var baseTexture = new PIXI.BaseTexture(canvas);
  10189.     return new PIXI.Texture(baseTexture);
  10190. }
  10191.  
  10192.  
  10193. /**
  10194.  * Adds a texture to the textureCache.
  10195.  *
  10196.  * @static
  10197.  * @method addTextureToCache
  10198.  * @param texture {Texture}
  10199.  * @param id {String} the id that the texture will be stored against.
  10200.  */
  10201. PIXI.Texture.addTextureToCache = function(texture, id)
  10202. {
  10203.     PIXI.TextureCache[id] = texture;
  10204. }
  10205.  
  10206. /**
  10207.  * Remove a texture from the textureCache.
  10208.  *
  10209.  * @static
  10210.  * @method removeTextureFromCache
  10211.  * @param id {String} the id of the texture to be removed
  10212.  * @return {Texture} the texture that was removed
  10213.  */
  10214. PIXI.Texture.removeTextureFromCache = function(id)
  10215. {
  10216.     var texture = PIXI.TextureCache[id]
  10217.     PIXI.TextureCache[id] = null;
  10218.     return texture;
  10219. }
  10220.  
  10221. // this is more for webGL.. it contains updated frames..
  10222. PIXI.Texture.frameUpdates = [];
  10223.  
  10224.  
  10225. /**
  10226.  * @author Mat Groves http://matgroves.com/ @Doormat23
  10227.  */
  10228.  
  10229. /**
  10230.  A RenderTexture is a special texture that allows any pixi displayObject to be rendered to it.
  10231.  
  10232.  __Hint__: All DisplayObjects (exmpl. Sprites) that renders on RenderTexture should be preloaded.
  10233.  Otherwise black rectangles will be drawn instead.  
  10234.  
  10235.  RenderTexture takes snapshot of DisplayObject passed to render method. If DisplayObject is passed to render method, position and rotation of it will be ignored. For example:
  10236.  
  10237.     var renderTexture = new PIXI.RenderTexture(800, 600);
  10238.     var sprite = PIXI.Sprite.fromImage("spinObj_01.png");
  10239.     sprite.position.x = 800/2;
  10240.     sprite.position.y = 600/2;
  10241.     sprite.anchor.x = 0.5;
  10242.     sprite.anchor.y = 0.5;
  10243.     renderTexture.render(sprite);
  10244.  
  10245.  Sprite in this case will be rendered to 0,0 position. To render this sprite at center DisplayObjectContainer should be used:
  10246.  
  10247.     var doc = new PIXI.DisplayObjectContainer();
  10248.     doc.addChild(sprite);
  10249.     renderTexture.render(doc);  // Renders to center of renderTexture
  10250.  
  10251.  @class RenderTexture
  10252.  @extends Texture
  10253.  @constructor
  10254.  @param width {Number} The width of the render texture
  10255.  @param height {Number} The height of the render texture
  10256.  */
  10257. PIXI.RenderTexture = function(width, height)
  10258. {
  10259.     PIXI.EventTarget.call( this );
  10260.  
  10261.     this.width = width || 100;
  10262.     this.height = height || 100;
  10263.  
  10264.     this.indetityMatrix = PIXI.mat3.create();
  10265.  
  10266.     this.frame = new PIXI.Rectangle(0, 0, this.width, this.height);
  10267.  
  10268.     if(PIXI.gl)
  10269.     {
  10270.         this.initWebGL();
  10271.     }
  10272.     else
  10273.     {
  10274.         this.initCanvas();
  10275.     }
  10276. }
  10277.  
  10278. PIXI.RenderTexture.prototype = Object.create( PIXI.Texture.prototype );
  10279. PIXI.RenderTexture.prototype.constructor = PIXI.RenderTexture;
  10280.  
  10281. /**
  10282.  * Initializes the webgl data for this texture
  10283.  *
  10284.  * @method initWebGL
  10285.  * @private
  10286.  */
  10287. PIXI.RenderTexture.prototype.initWebGL = function()
  10288. {
  10289.     var gl = PIXI.gl;
  10290.     this.glFramebuffer = gl.createFramebuffer();
  10291.  
  10292.     gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
  10293.  
  10294.     this.glFramebuffer.width = this.width;
  10295.     this.glFramebuffer.height = this.height;   
  10296.  
  10297.     this.baseTexture = new PIXI.BaseTexture();
  10298.  
  10299.     this.baseTexture.width = this.width;
  10300.     this.baseTexture.height = this.height;
  10301.  
  10302.     this.baseTexture._glTexture = gl.createTexture();
  10303.     gl.bindTexture(gl.TEXTURE_2D, this.baseTexture._glTexture);
  10304.  
  10305.     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA,  this.width,  this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
  10306.  
  10307.     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  10308.     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  10309.     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  10310.     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  10311.  
  10312.     this.baseTexture.isRender = true;
  10313.  
  10314.     gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
  10315.     gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.baseTexture._glTexture, 0);
  10316.  
  10317.     // create a projection matrix..
  10318.     this.projection = new PIXI.Point(this.width/2 , -this.height/2);
  10319.  
  10320.     // set the correct render function..
  10321.     this.render = this.renderWebGL;
  10322. }
  10323.  
  10324.  
  10325. PIXI.RenderTexture.prototype.resize = function(width, height)
  10326. {
  10327.  
  10328.     this.width = width;
  10329.     this.height = height;
  10330.    
  10331.     if(PIXI.gl)
  10332.     {
  10333.         this.projection.x = this.width/2
  10334.         this.projection.y = -this.height/2;
  10335.    
  10336.         var gl = PIXI.gl;
  10337.         gl.bindTexture(gl.TEXTURE_2D, this.baseTexture._glTexture);
  10338.         gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA,  this.width,  this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
  10339.     }
  10340.     else
  10341.     {
  10342.        
  10343.         this.frame.width = this.width
  10344.         this.frame.height = this.height;
  10345.         this.renderer.resize(this.width, this.height);
  10346.     }
  10347. }
  10348.  
  10349. /**
  10350.  * Initializes the canvas data for this texture
  10351.  *
  10352.  * @method initCanvas
  10353.  * @private
  10354.  */
  10355. PIXI.RenderTexture.prototype.initCanvas = function()
  10356. {
  10357.     this.renderer = new PIXI.CanvasRenderer(this.width, this.height, null, 0);
  10358.  
  10359.     this.baseTexture = new PIXI.BaseTexture(this.renderer.view);
  10360.     this.frame = new PIXI.Rectangle(0, 0, this.width, this.height);
  10361.  
  10362.     this.render = this.renderCanvas;
  10363. }
  10364.  
  10365. /**
  10366.  * This function will draw the display object to the texture.
  10367.  *
  10368.  * @method renderWebGL
  10369.  * @param displayObject {DisplayObject} The display object to render this texture on
  10370.  * @param clear {Boolean} If true the texture will be cleared before the displayObject is drawn
  10371.  * @private
  10372.  */
  10373. PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, position, clear)
  10374. {
  10375.     var gl = PIXI.gl;
  10376.  
  10377.     // enable the alpha color mask..
  10378.     gl.colorMask(true, true, true, true);
  10379.  
  10380.     gl.viewport(0, 0, this.width, this.height);
  10381.  
  10382.     gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
  10383.  
  10384.     if(clear)
  10385.     {
  10386.         gl.clearColor(0,0,0, 0);    
  10387.         gl.clear(gl.COLOR_BUFFER_BIT);
  10388.     }
  10389.  
  10390.     // THIS WILL MESS WITH HIT TESTING!
  10391.     var children = displayObject.children;
  10392.  
  10393.     //TODO -? create a new one??? dont think so!
  10394.     var originalWorldTransform = displayObject.worldTransform;
  10395.     displayObject.worldTransform = PIXI.mat3.create();//sthis.indetityMatrix;
  10396.     // modify to flip...
  10397.     displayObject.worldTransform[4] = -1;
  10398.     displayObject.worldTransform[5] = this.projection.y * -2;
  10399.  
  10400.     if(position)
  10401.     {
  10402.         displayObject.worldTransform[2] = position.x;
  10403.         displayObject.worldTransform[5] -= position.y;
  10404.     }
  10405.    
  10406.     PIXI.visibleCount++;
  10407.     displayObject.vcount = PIXI.visibleCount;
  10408.    
  10409.     for(var i=0,j=children.length; i<j; i++)
  10410.     {
  10411.         children[i].updateTransform(); 
  10412.     }
  10413.  
  10414.     var renderGroup = displayObject.__renderGroup;
  10415.  
  10416.     if(renderGroup)
  10417.     {
  10418.         if(displayObject == renderGroup.root)
  10419.         {
  10420.             renderGroup.render(this.projection, this.glFramebuffer);
  10421.         }
  10422.         else
  10423.         {
  10424.             renderGroup.renderSpecific(displayObject, this.projection, this.glFramebuffer);
  10425.         }
  10426.     }
  10427.     else
  10428.     {
  10429.         if(!this.renderGroup)this.renderGroup = new PIXI.WebGLRenderGroup(gl);
  10430.         this.renderGroup.setRenderable(displayObject);
  10431.         this.renderGroup.render(this.projection, this.glFramebuffer);
  10432.     }
  10433.    
  10434.     displayObject.worldTransform = originalWorldTransform;
  10435. }
  10436.  
  10437.  
  10438. /**
  10439.  * This function will draw the display object to the texture.
  10440.  *
  10441.  * @method renderCanvas
  10442.  * @param displayObject {DisplayObject} The display object to render this texture on
  10443.  * @param clear {Boolean} If true the texture will be cleared before the displayObject is drawn
  10444.  * @private
  10445.  */
  10446. PIXI.RenderTexture.prototype.renderCanvas = function(displayObject, position, clear)
  10447. {
  10448.     var children = displayObject.children;
  10449.  
  10450.     displayObject.worldTransform = PIXI.mat3.create();
  10451.    
  10452.     if(position)
  10453.     {
  10454.         displayObject.worldTransform[2] = position.x;
  10455.         displayObject.worldTransform[5] = position.y;
  10456.     }
  10457.    
  10458.  
  10459.     for(var i=0,j=children.length; i<j; i++)
  10460.     {
  10461.         children[i].updateTransform(); 
  10462.     }
  10463.  
  10464.     if(clear)this.renderer.context.clearRect(0,0, this.width, this.height);
  10465.    
  10466.     this.renderer.renderDisplayObject(displayObject);
  10467.    
  10468.     this.renderer.context.setTransform(1,0,0,1,0,0);
  10469.    
  10470.  
  10471.   //  PIXI.texturesToUpdate.push(this.baseTexture);
  10472. }
  10473.  
  10474. /**
  10475.  * @author Mat Groves http://matgroves.com/ @Doormat23
  10476.  */
  10477.  
  10478. /**
  10479.  * A Class that loads a bunch of images / sprite sheet / bitmap font files. Once the
  10480.  * assets have been loaded they are added to the PIXI Texture cache and can be accessed
  10481.  * easily through PIXI.Texture.fromImage() and PIXI.Sprite.fromImage()
  10482.  * When all items have been loaded this class will dispatch a "onLoaded" event
  10483.  * As each individual item is loaded this class will dispatch a "onProgress" event
  10484.  *
  10485.  * @class AssetLoader
  10486.  * @constructor
  10487.  * @uses EventTarget
  10488.  * @param {Array<String>} assetURLs an array of image/sprite sheet urls that you would like loaded
  10489.  *      supported. Supported image formats include "jpeg", "jpg", "png", "gif". Supported
  10490.  *      sprite sheet data formats only include "JSON" at this time. Supported bitmap font
  10491.  *      data formats include "xml" and "fnt".
  10492.  * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
  10493.  */
  10494. PIXI.AssetLoader = function(assetURLs, crossorigin)
  10495. {
  10496.     PIXI.EventTarget.call(this);
  10497.  
  10498.     /**
  10499.      * The array of asset URLs that are going to be loaded
  10500.      *
  10501.      * @property assetURLs
  10502.      * @type Array<String>
  10503.      */
  10504.     this.assetURLs = assetURLs;
  10505.  
  10506.     /**
  10507.      * Whether the requests should be treated as cross origin
  10508.      *
  10509.      * @property crossorigin
  10510.      * @type Boolean
  10511.      */
  10512.     this.crossorigin = crossorigin;
  10513.  
  10514.     /**
  10515.      * Maps file extension to loader types
  10516.      *
  10517.      * @property loadersByType
  10518.      * @type Object
  10519.      */
  10520.     this.loadersByType = {
  10521.         "jpg":  PIXI.ImageLoader,
  10522.         "jpeg": PIXI.ImageLoader,
  10523.         "png":  PIXI.ImageLoader,
  10524.         "gif":  PIXI.ImageLoader,
  10525.         "json": PIXI.JsonLoader,
  10526.         "anim": PIXI.SpineLoader,
  10527.         "xml":  PIXI.BitmapFontLoader,
  10528.         "fnt":  PIXI.BitmapFontLoader
  10529.     };
  10530.  
  10531.  
  10532. };
  10533.  
  10534. /**
  10535.  * Fired when an item has loaded
  10536.  * @event onProgress
  10537.  */
  10538.  
  10539. /**
  10540.  * Fired when all the assets have loaded
  10541.  * @event onComplete
  10542.  */
  10543.  
  10544. // constructor
  10545. PIXI.AssetLoader.prototype.constructor = PIXI.AssetLoader;
  10546.  
  10547. /**
  10548.  * Starts loading the assets sequentially
  10549.  *
  10550.  * @method load
  10551.  */
  10552. PIXI.AssetLoader.prototype.load = function()
  10553. {
  10554.     var scope = this;
  10555.  
  10556.     this.loadCount = this.assetURLs.length;
  10557.  
  10558.     for (var i=0; i < this.assetURLs.length; i++)
  10559.     {
  10560.         var fileName = this.assetURLs[i];
  10561.         var fileType = fileName.split(".").pop().toLowerCase();
  10562.  
  10563.         var loaderClass = this.loadersByType[fileType];
  10564.         if(!loaderClass)
  10565.             throw new Error(fileType + " is an unsupported file type");
  10566.  
  10567.         var loader = new loaderClass(fileName, this.crossorigin);
  10568.  
  10569.         loader.addEventListener("loaded", function()
  10570.         {
  10571.             scope.onAssetLoaded();
  10572.         });
  10573.         loader.load();
  10574.     }
  10575. };
  10576.  
  10577. /**
  10578.  * Invoked after each file is loaded
  10579.  *
  10580.  * @method onAssetLoaded
  10581.  * @private
  10582.  */
  10583. PIXI.AssetLoader.prototype.onAssetLoaded = function()
  10584. {
  10585.     this.loadCount--;
  10586.     this.dispatchEvent({type: "onProgress", content: this});
  10587.     if(this.onProgress) this.onProgress();
  10588.  
  10589.     if(this.loadCount == 0)
  10590.     {
  10591.         this.dispatchEvent({type: "onComplete", content: this});
  10592.         if(this.onComplete) this.onComplete();
  10593.     }
  10594. };
  10595.  
  10596.  
  10597. /**
  10598.  * @author Mat Groves http://matgroves.com/ @Doormat23
  10599.  */
  10600.  
  10601. /**
  10602.  * The json file loader is used to load in JSON data and parsing it
  10603.  * When loaded this class will dispatch a "loaded" event
  10604.  * If load failed this class will dispatch a "error" event
  10605.  *
  10606.  * @class JsonLoader
  10607.  * @uses EventTarget
  10608.  * @constructor
  10609.  * @param url {String} The url of the JSON file
  10610.  * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
  10611.  */
  10612. PIXI.JsonLoader = function (url, crossorigin) {
  10613.     PIXI.EventTarget.call(this);
  10614.  
  10615.     /**
  10616.      * The url of the bitmap font data
  10617.      *
  10618.      * @property url
  10619.      * @type String
  10620.      */
  10621.     this.url = url;
  10622.  
  10623.     /**
  10624.      * Whether the requests should be treated as cross origin
  10625.      *
  10626.      * @property crossorigin
  10627.      * @type Boolean
  10628.      */
  10629.     this.crossorigin = crossorigin;
  10630.  
  10631.     /**
  10632.      * [read-only] The base url of the bitmap font data
  10633.      *
  10634.      * @property baseUrl
  10635.      * @type String
  10636.      * @readOnly
  10637.      */
  10638.     this.baseUrl = url.replace(/[^\/]*$/, "");
  10639.  
  10640.     /**
  10641.      * [read-only] Whether the data has loaded yet
  10642.      *
  10643.      * @property loaded
  10644.      * @type Boolean
  10645.      * @readOnly
  10646.      */
  10647.     this.loaded = false;
  10648.  
  10649. };
  10650.  
  10651. // constructor
  10652. PIXI.JsonLoader.prototype.constructor = PIXI.JsonLoader;
  10653.  
  10654. /**
  10655.  * Loads the JSON data
  10656.  *
  10657.  * @method load
  10658.  */
  10659. PIXI.JsonLoader.prototype.load = function () {
  10660.     this.ajaxRequest = new AjaxRequest();
  10661.     var scope = this;
  10662.     this.ajaxRequest.onreadystatechange = function () {
  10663.         scope.onJSONLoaded();
  10664.     };
  10665.  
  10666.     this.ajaxRequest.open("GET", this.url, true);
  10667.     if (this.ajaxRequest.overrideMimeType) this.ajaxRequest.overrideMimeType("application/json");
  10668.     this.ajaxRequest.send(null);
  10669. };
  10670.  
  10671. /**
  10672.  * Invoke when JSON file is loaded
  10673.  *
  10674.  * @method onJSONLoaded
  10675.  * @private
  10676.  */
  10677. PIXI.JsonLoader.prototype.onJSONLoaded = function () {
  10678.     if (this.ajaxRequest.readyState == 4) {
  10679.         if (this.ajaxRequest.status == 200 || window.location.href.indexOf("http") == -1) {
  10680.             this.json = JSON.parse(this.ajaxRequest.responseText);
  10681.  
  10682.             if(this.json.frames)
  10683.             {
  10684.                 // sprite sheet
  10685.                 var scope = this;
  10686.                 var textureUrl = this.baseUrl + this.json.meta.image;
  10687.                 var image = new PIXI.ImageLoader(textureUrl, this.crossorigin);
  10688.                 var frameData = this.json.frames;
  10689.  
  10690.                 this.texture = image.texture.baseTexture;
  10691.                 image.addEventListener("loaded", function (event) {
  10692.                     scope.onLoaded();
  10693.                 });
  10694.  
  10695.                 for (var i in frameData) {
  10696.                     var rect = frameData[i].frame;
  10697.                     if (rect) {
  10698.                         PIXI.TextureCache[i] = new PIXI.Texture(this.texture, {
  10699.                             x: rect.x,
  10700.                             y: rect.y,
  10701.                             width: rect.w,
  10702.                             height: rect.h
  10703.                         });
  10704.                         if (frameData[i].trimmed) {
  10705.                             //var realSize = frameData[i].spriteSourceSize;
  10706.                             PIXI.TextureCache[i].realSize = frameData[i].spriteSourceSize;
  10707.                             PIXI.TextureCache[i].trim.x = 0; // (realSize.x / rect.w)
  10708.                             // calculate the offset!
  10709.                         }
  10710.                     }
  10711.                 }
  10712.  
  10713.                 image.load();
  10714.  
  10715.             }
  10716.             else if(this.json.bones)
  10717.             {
  10718.                 // spine animation
  10719.                 var spineJsonParser = new spine.SkeletonJson();
  10720.                 var skeletonData = spineJsonParser.readSkeletonData(this.json);
  10721.                 PIXI.AnimCache[this.url] = skeletonData;
  10722.                 this.onLoaded();
  10723.             }
  10724.             else
  10725.             {
  10726.                 this.onLoaded();
  10727.             }
  10728.         }
  10729.         else
  10730.         {
  10731.             this.onError();
  10732.         }
  10733.     }
  10734. };
  10735.  
  10736. /**
  10737.  * Invoke when json file loaded
  10738.  *
  10739.  * @method onLoaded
  10740.  * @private
  10741.  */
  10742. PIXI.JsonLoader.prototype.onLoaded = function () {
  10743.     this.loaded = true;
  10744.     this.dispatchEvent({
  10745.         type: "loaded",
  10746.         content: this
  10747.     });
  10748. };
  10749.  
  10750. /**
  10751.  * Invoke when error occured
  10752.  *
  10753.  * @method onError
  10754.  * @private
  10755.  */
  10756. PIXI.JsonLoader.prototype.onError = function () {
  10757.     this.dispatchEvent({
  10758.         type: "error",
  10759.         content: this
  10760.     });
  10761. };
  10762. /**
  10763.  * @author Mat Groves http://matgroves.com/ @Doormat23
  10764.  */
  10765.  
  10766. /**
  10767.  * The sprite sheet loader is used to load in JSON sprite sheet data
  10768.  * To generate the data you can use http://www.codeandweb.com/texturepacker and publish the "JSON" format
  10769.  * There is a free version so thats nice, although the paid version is great value for money.
  10770.  * It is highly recommended to use Sprite sheets (also know as texture atlas") as it means sprite"s can be batched and drawn together for highly increased rendering speed.
  10771.  * Once the data has been loaded the frames are stored in the PIXI texture cache and can be accessed though PIXI.Texture.fromFrameId() and PIXI.Sprite.fromFromeId()
  10772.  * This loader will also load the image file that the Spritesheet points to as well as the data.
  10773.  * When loaded this class will dispatch a "loaded" event
  10774.  *
  10775.  * @class SpriteSheetLoader
  10776.  * @uses EventTarget
  10777.  * @constructor
  10778.  * @param url {String} The url of the sprite sheet JSON file
  10779.  * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
  10780.  */
  10781.  
  10782. PIXI.SpriteSheetLoader = function (url, crossorigin) {
  10783.     /*
  10784.      * i use texture packer to load the assets..
  10785.      * http://www.codeandweb.com/texturepacker
  10786.      * make sure to set the format as "JSON"
  10787.      */
  10788.     PIXI.EventTarget.call(this);
  10789.  
  10790.     /**
  10791.      * The url of the bitmap font data
  10792.      *
  10793.      * @property url
  10794.      * @type String
  10795.      */
  10796.     this.url = url;
  10797.  
  10798.     /**
  10799.      * Whether the requests should be treated as cross origin
  10800.      *
  10801.      * @property crossorigin
  10802.      * @type Boolean
  10803.      */
  10804.     this.crossorigin = crossorigin;
  10805.  
  10806.     /**
  10807.      * [read-only] The base url of the bitmap font data
  10808.      *
  10809.      * @property baseUrl
  10810.      * @type String
  10811.      * @readOnly
  10812.      */
  10813.     this.baseUrl = url.replace(/[^\/]*$/, "");
  10814.  
  10815.     /**
  10816.      * The texture being loaded
  10817.      *
  10818.      * @property texture
  10819.      * @type Texture
  10820.      */
  10821.     this.texture = null;
  10822.  
  10823.     /**
  10824.      * The frames of the sprite sheet
  10825.      *
  10826.      * @property frames
  10827.      * @type Object
  10828.      */
  10829.     this.frames = {};
  10830. };
  10831.  
  10832. // constructor
  10833. PIXI.SpriteSheetLoader.prototype.constructor = PIXI.SpriteSheetLoader;
  10834.  
  10835. /**
  10836.  * This will begin loading the JSON file
  10837.  *
  10838.  * @method load
  10839.  */
  10840. PIXI.SpriteSheetLoader.prototype.load = function () {
  10841.     var scope = this;
  10842.     var jsonLoader = new PIXI.JsonLoader(this.url, this.crossorigin);
  10843.     jsonLoader.addEventListener("loaded", function (event) {
  10844.         scope.json = event.content.json;
  10845.         scope.onJSONLoaded();
  10846.     });
  10847.     jsonLoader.load();
  10848. };
  10849.  
  10850. /**
  10851.  * Invoke when JSON file is loaded
  10852.  *
  10853.  * @method onJSONLoaded
  10854.  * @private
  10855.  */
  10856. PIXI.SpriteSheetLoader.prototype.onJSONLoaded = function () {
  10857.     var scope = this;
  10858.     var textureUrl = this.baseUrl + this.json.meta.image;
  10859.     var image = new PIXI.ImageLoader(textureUrl, this.crossorigin);
  10860.     var frameData = this.json.frames;
  10861.  
  10862.     this.texture = image.texture.baseTexture;
  10863.     image.addEventListener("loaded", function (event) {
  10864.         scope.onLoaded();
  10865.     });
  10866.  
  10867.     for (var i in frameData) {
  10868.         var rect = frameData[i].frame;
  10869.         if (rect) {
  10870.             PIXI.TextureCache[i] = new PIXI.Texture(this.texture, {
  10871.                 x: rect.x,
  10872.                 y: rect.y,
  10873.                 width: rect.w,
  10874.                 height: rect.h
  10875.             });
  10876.             if (frameData[i].trimmed) {
  10877.                 //var realSize = frameData[i].spriteSourceSize;
  10878.                 PIXI.TextureCache[i].realSize = frameData[i].spriteSourceSize;
  10879.                 PIXI.TextureCache[i].trim.x = 0; // (realSize.x / rect.w)
  10880.                 // calculate the offset!
  10881.             }
  10882.         }
  10883.     }
  10884.  
  10885.     image.load();
  10886. };
  10887. /**
  10888.  * Invoke when all files are loaded (json and texture)
  10889.  *
  10890.  * @method onLoaded
  10891.  * @private
  10892.  */
  10893. PIXI.SpriteSheetLoader.prototype.onLoaded = function () {
  10894.     this.dispatchEvent({
  10895.         type: "loaded",
  10896.         content: this
  10897.     });
  10898. };
  10899.  
  10900. /**
  10901.  * @author Mat Groves http://matgroves.com/ @Doormat23
  10902.  */
  10903.  
  10904. /**
  10905.  * The image loader class is responsible for loading images file formats ("jpeg", "jpg", "png" and "gif")
  10906.  * Once the image has been loaded it is stored in the PIXI texture cache and can be accessed though PIXI.Texture.fromFrameId() and PIXI.Sprite.fromFromeId()
  10907.  * When loaded this class will dispatch a 'loaded' event
  10908.  *
  10909.  * @class ImageLoader
  10910.  * @uses EventTarget
  10911.  * @constructor
  10912.  * @param url {String} The url of the image
  10913.  * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
  10914.  */
  10915. PIXI.ImageLoader = function(url, crossorigin)
  10916. {
  10917.     PIXI.EventTarget.call(this);
  10918.  
  10919.     /**
  10920.      * The texture being loaded
  10921.      *
  10922.      * @property texture
  10923.      * @type Texture
  10924.      */
  10925.     this.texture = PIXI.Texture.fromImage(url, crossorigin);
  10926.  
  10927.     /**
  10928.      * if the image is loaded with loadFramedSpriteSheet
  10929.      * frames will contain the sprite sheet frames
  10930.      *
  10931.      */
  10932.     this.frames = [];
  10933. };
  10934.  
  10935. // constructor
  10936. PIXI.ImageLoader.prototype.constructor = PIXI.ImageLoader;
  10937.  
  10938. /**
  10939.  * Loads image or takes it from cache
  10940.  *
  10941.  * @method load
  10942.  */
  10943. PIXI.ImageLoader.prototype.load = function()
  10944. {
  10945.     if(!this.texture.baseTexture.hasLoaded)
  10946.     {
  10947.         var scope = this;
  10948.         this.texture.baseTexture.addEventListener("loaded", function()
  10949.         {
  10950.             scope.onLoaded();
  10951.         });
  10952.     }
  10953.     else
  10954.     {
  10955.         this.onLoaded();
  10956.     }
  10957. };
  10958.  
  10959. /**
  10960.  * Invoked when image file is loaded or it is already cached and ready to use
  10961.  *
  10962.  * @method onLoaded
  10963.  * @private
  10964.  */
  10965. PIXI.ImageLoader.prototype.onLoaded = function()
  10966. {
  10967.     this.dispatchEvent({type: "loaded", content: this});
  10968. };
  10969.  
  10970. /**
  10971.  * Loads image and split it to uniform sized frames
  10972.  *
  10973.  *
  10974.  * @method loadFramedSpriteSheet
  10975.  * @param frameWidth {Number} with of each frame
  10976.  * @param frameHeight {Number} height of each frame
  10977.  * @param textureName {String} if given, the frames will be cached in <textureName>-<ord> format
  10978.  */
  10979. PIXI.ImageLoader.prototype.loadFramedSpriteSheet = function(frameWidth, frameHeight, textureName)
  10980. {
  10981.     this.frames = [];
  10982.     var cols = Math.floor(this.texture.width / frameWidth);
  10983.     var rows = Math.floor(this.texture.height / frameHeight);
  10984.  
  10985.     var i=0;
  10986.     for (var y=0; y<rows; y++)
  10987.     {
  10988.         for (var x=0; x<cols; x++,i++)
  10989.         {
  10990.             var texture = new PIXI.Texture(this.texture, {
  10991.                 x: x*frameWidth,
  10992.                 y: y*frameHeight,
  10993.                 width: frameWidth,
  10994.                 height: frameHeight
  10995.             });
  10996.  
  10997.             this.frames.push(texture);
  10998.             if (textureName) PIXI.TextureCache[textureName+'-'+i] = texture;
  10999.         }
  11000.     }
  11001.  
  11002.     if(!this.texture.baseTexture.hasLoaded)
  11003.     {
  11004.         var scope = this;
  11005.         this.texture.baseTexture.addEventListener("loaded", function() {
  11006.             scope.onLoaded();
  11007.         });
  11008.     }
  11009.     else
  11010.     {
  11011.         this.onLoaded();
  11012.     }
  11013. };
  11014. /**
  11015.  * @author Mat Groves http://matgroves.com/ @Doormat23
  11016.  */
  11017.  
  11018. /**
  11019.  * The xml loader is used to load in XML bitmap font data ("xml" or "fnt")
  11020.  * To generate the data you can use http://www.angelcode.com/products/bmfont/
  11021.  * This loader will also load the image file as the data.
  11022.  * When loaded this class will dispatch a "loaded" event
  11023.  *
  11024.  * @class BitmapFontLoader
  11025.  * @uses EventTarget
  11026.  * @constructor
  11027.  * @param url {String} The url of the sprite sheet JSON file
  11028.  * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
  11029.  */
  11030. PIXI.BitmapFontLoader = function(url, crossorigin)
  11031. {
  11032.     /*
  11033.      * i use texture packer to load the assets..
  11034.      * http://www.codeandweb.com/texturepacker
  11035.      * make sure to set the format as "JSON"
  11036.      */
  11037.     PIXI.EventTarget.call(this);
  11038.  
  11039.     /**
  11040.      * The url of the bitmap font data
  11041.      *
  11042.      * @property url
  11043.      * @type String
  11044.      */
  11045.     this.url = url;
  11046.  
  11047.     /**
  11048.      * Whether the requests should be treated as cross origin
  11049.      *
  11050.      * @property crossorigin
  11051.      * @type Boolean
  11052.      */
  11053.     this.crossorigin = crossorigin;
  11054.  
  11055.     /**
  11056.      * [read-only] The base url of the bitmap font data
  11057.      *
  11058.      * @property baseUrl
  11059.      * @type String
  11060.      * @readOnly
  11061.      */
  11062.     this.baseUrl = url.replace(/[^\/]*$/, "");
  11063.  
  11064.     /**
  11065.      * [read-only] The texture of the bitmap font
  11066.      *
  11067.      * @property baseUrl
  11068.      * @type String
  11069.      */
  11070.     this.texture = null;
  11071. };
  11072.  
  11073. // constructor
  11074. PIXI.BitmapFontLoader.prototype.constructor = PIXI.BitmapFontLoader;
  11075.  
  11076. /**
  11077.  * Loads the XML font data
  11078.  *
  11079.  * @method load
  11080.  */
  11081. PIXI.BitmapFontLoader.prototype.load = function()
  11082. {
  11083.     this.ajaxRequest = new XMLHttpRequest();
  11084.     var scope = this;
  11085.     this.ajaxRequest.onreadystatechange = function()
  11086.     {
  11087.         scope.onXMLLoaded();
  11088.     };
  11089.  
  11090.     this.ajaxRequest.open("GET", this.url, true);
  11091.     if (this.ajaxRequest.overrideMimeType) this.ajaxRequest.overrideMimeType("application/xml");
  11092.     this.ajaxRequest.send(null)
  11093. };
  11094.  
  11095. /**
  11096.  * Invoked when XML file is loaded, parses the data
  11097.  *
  11098.  * @method onXMLLoaded
  11099.  * @private
  11100.  */
  11101. PIXI.BitmapFontLoader.prototype.onXMLLoaded = function()
  11102. {
  11103.     if (this.ajaxRequest.readyState == 4)
  11104.     {
  11105.         if (this.ajaxRequest.status == 200 || window.location.href.indexOf("http") == -1)
  11106.         {
  11107.             var textureUrl = this.baseUrl + this.ajaxRequest.responseXML.getElementsByTagName("page")[0].attributes.getNamedItem("file").nodeValue;
  11108.             var image = new PIXI.ImageLoader(textureUrl, this.crossorigin);
  11109.             this.texture = image.texture.baseTexture;
  11110.  
  11111.             var data = {};
  11112.             var info = this.ajaxRequest.responseXML.getElementsByTagName("info")[0];
  11113.             var common = this.ajaxRequest.responseXML.getElementsByTagName("common")[0];
  11114.             data.font = info.attributes.getNamedItem("face").nodeValue;
  11115.             data.size = parseInt(info.attributes.getNamedItem("size").nodeValue, 10);
  11116.             data.lineHeight = parseInt(common.attributes.getNamedItem("lineHeight").nodeValue, 10);
  11117.             data.chars = {};
  11118.  
  11119.             //parse letters
  11120.             var letters = this.ajaxRequest.responseXML.getElementsByTagName("char");
  11121.  
  11122.             for (var i = 0; i < letters.length; i++)
  11123.             {
  11124.                 var charCode = parseInt(letters[i].attributes.getNamedItem("id").nodeValue, 10);
  11125.  
  11126.                 var textureRect = new PIXI.Rectangle(
  11127.                     parseInt(letters[i].attributes.getNamedItem("x").nodeValue, 10),
  11128.                     parseInt(letters[i].attributes.getNamedItem("y").nodeValue, 10),
  11129.                     parseInt(letters[i].attributes.getNamedItem("width").nodeValue, 10),
  11130.                     parseInt(letters[i].attributes.getNamedItem("height").nodeValue, 10)
  11131.                 );
  11132.  
  11133.                 data.chars[charCode] = {
  11134.                     xOffset: parseInt(letters[i].attributes.getNamedItem("xoffset").nodeValue, 10),
  11135.                     yOffset: parseInt(letters[i].attributes.getNamedItem("yoffset").nodeValue, 10),
  11136.                     xAdvance: parseInt(letters[i].attributes.getNamedItem("xadvance").nodeValue, 10),
  11137.                     kerning: {},
  11138.                     texture: PIXI.TextureCache[charCode] = new PIXI.Texture(this.texture, textureRect)
  11139.  
  11140.                 };
  11141.             }
  11142.  
  11143.             //parse kernings
  11144.             var kernings = this.ajaxRequest.responseXML.getElementsByTagName("kerning");
  11145.             for (i = 0; i < kernings.length; i++)
  11146.             {
  11147.                var first = parseInt(kernings[i].attributes.getNamedItem("first").nodeValue, 10);
  11148.                var second = parseInt(kernings[i].attributes.getNamedItem("second").nodeValue, 10);
  11149.                var amount = parseInt(kernings[i].attributes.getNamedItem("amount").nodeValue, 10);
  11150.  
  11151.                 data.chars[second].kerning[first] = amount;
  11152.  
  11153.             }
  11154.  
  11155.             PIXI.BitmapText.fonts[data.font] = data;
  11156.  
  11157.             var scope = this;
  11158.             image.addEventListener("loaded", function() {
  11159.                 scope.onLoaded();
  11160.             });
  11161.             image.load();
  11162.         }
  11163.     }
  11164. };
  11165.  
  11166. /**
  11167.  * Invoked when all files are loaded (xml/fnt and texture)
  11168.  *
  11169.  * @method onLoaded
  11170.  * @private
  11171.  */
  11172. PIXI.BitmapFontLoader.prototype.onLoaded = function()
  11173. {
  11174.     this.dispatchEvent({type: "loaded", content: this});
  11175. };
  11176.  
  11177. /**
  11178.  * @author Mat Groves http://matgroves.com/ @Doormat23
  11179.  * based on pixi impact spine implementation made by Eemeli Kelokorpi (@ekelokorpi) https://github.com/ekelokorpi
  11180.  *
  11181.  * Awesome JS run time provided by EsotericSoftware
  11182.  * https://github.com/EsotericSoftware/spine-runtimes
  11183.  *
  11184.  */
  11185.  
  11186. /**
  11187.  * The Spine loader is used to load in JSON spine data
  11188.  * To generate the data you need to use http://esotericsoftware.com/ and export the "JSON" format
  11189.  * Due to a clash of names  You will need to change the extension of the spine file from *.json to *.anim for it to load
  11190.  * See example 12 (http://www.goodboydigital.com/pixijs/examples/12/) to see a working example and check out the source
  11191.  * You will need to generate a sprite sheet to accompany the spine data
  11192.  * When loaded this class will dispatch a "loaded" event
  11193.  *
  11194.  * @class Spine
  11195.  * @uses EventTarget
  11196.  * @constructor
  11197.  * @param url {String} The url of the JSON file
  11198.  * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
  11199.  */
  11200. PIXI.SpineLoader = function(url, crossorigin)
  11201. {
  11202.     PIXI.EventTarget.call(this);
  11203.  
  11204.     /**
  11205.      * The url of the bitmap font data
  11206.      *
  11207.      * @property url
  11208.      * @type String
  11209.      */
  11210.     this.url = url;
  11211.  
  11212.     /**
  11213.      * Whether the requests should be treated as cross origin
  11214.      *
  11215.      * @property crossorigin
  11216.      * @type Boolean
  11217.      */
  11218.     this.crossorigin = crossorigin;
  11219.  
  11220.     /**
  11221.      * [read-only] Whether the data has loaded yet
  11222.      *
  11223.      * @property loaded
  11224.      * @type Boolean
  11225.      * @readOnly
  11226.      */
  11227.     this.loaded = false;
  11228. }
  11229.  
  11230. PIXI.SpineLoader.prototype.constructor = PIXI.SpineLoader;
  11231.  
  11232. /**
  11233.  * Loads the JSON data
  11234.  *
  11235.  * @method load
  11236.  */
  11237. PIXI.SpineLoader.prototype.load = function () {
  11238.  
  11239.     var scope = this;
  11240.     var jsonLoader = new PIXI.JsonLoader(this.url, this.crossorigin);
  11241.     jsonLoader.addEventListener("loaded", function (event) {
  11242.         scope.json = event.content.json;
  11243.         scope.onJSONLoaded();
  11244.     });
  11245.     jsonLoader.load();
  11246. };
  11247.  
  11248. /**
  11249.  * Invoke when JSON file is loaded
  11250.  *
  11251.  * @method onJSONLoaded
  11252.  * @private
  11253.  */
  11254. PIXI.SpineLoader.prototype.onJSONLoaded = function (event) {
  11255.     var spineJsonParser = new spine.SkeletonJson();
  11256.     var skeletonData = spineJsonParser.readSkeletonData(this.json);
  11257.  
  11258.     PIXI.AnimCache[this.url] = skeletonData;
  11259.  
  11260.     this.onLoaded();
  11261. };
  11262.  
  11263. /**
  11264.  * Invoke when JSON file is loaded
  11265.  *
  11266.  * @method onLoaded
  11267.  * @private
  11268.  */
  11269. PIXI.SpineLoader.prototype.onLoaded = function () {
  11270.     this.loaded = true;
  11271.     this.dispatchEvent({type: "loaded", content: this});
  11272. };
  11273.  
  11274.  
  11275. /**
  11276.  * @author Mat Groves http://matgroves.com/ @Doormat23
  11277.  */
  11278.  
  11279.  
  11280. /**
  11281.  * This is the base class for  creating a pixi.js filter. Currently only webGL supports filters.
  11282.  * If you want to make a custom filter this should be your base class.
  11283.  * @class AbstractFilter
  11284.  * @constructor
  11285.  * @param fragmentSrc
  11286.  * @param unifroms  
  11287.  */
  11288. PIXI.AbstractFilter = function(fragmentSrc, unifroms)
  11289. {
  11290.     /**
  11291.     * An array of passes - some filters contain a few steps this array simply stores the steps in a liniear fashion.
  11292.     * For example the blur filter has two passes blurX and blurY.
  11293.     * @property passes
  11294.     * @type Array an array of filter objects
  11295.     * @private
  11296.     */
  11297.     this.passes = [this];
  11298.  
  11299.  
  11300.     this.dirty = true;
  11301.     this.padding = 0;
  11302.  
  11303.     /**
  11304.     @property uniforms
  11305.     @private
  11306.     */
  11307.     this.uniforms = unifroms || {};
  11308.    
  11309.     this.fragmentSrc = fragmentSrc || [];
  11310. }
  11311.  
  11312.  
  11313. /**
  11314.  * @author Mat Groves http://matgroves.com/ @Doormat23
  11315.  */
  11316.  
  11317. /**
  11318.  *
  11319.  * The ColorMatrixFilter class lets you apply a 4x4 matrix transformation on the RGBA
  11320.  * color and alpha values of every pixel on your displayObject to produce a result
  11321.  * with a new set of RGBA color and alpha values. Its pretty powerful!
  11322.  * @class ColorMatrixFilter
  11323.  * @contructor
  11324.  */
  11325. PIXI.ColorMatrixFilter = function()
  11326. {
  11327.     PIXI.AbstractFilter.call( this );
  11328.    
  11329.     this.passes = [this];
  11330.    
  11331.     // set the uniforms
  11332.     this.uniforms = {
  11333.         matrix: {type: 'mat4', value: [1,0,0,0,
  11334.                                        0,1,0,0,
  11335.                                        0,0,1,0,
  11336.                                        0,0,0,1]},
  11337.     };
  11338.    
  11339.     this.fragmentSrc = [
  11340.       "precision mediump float;",
  11341.       "varying vec2 vTextureCoord;",
  11342.       "varying float vColor;",
  11343.       "uniform float invert;",
  11344.       "uniform mat4 matrix;",
  11345.       "uniform sampler2D uSampler;",
  11346.       "void main(void) {",
  11347.         "gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;",
  11348.         "gl_FragColor = gl_FragColor * vColor;",
  11349.       "}"
  11350.     ];
  11351.    
  11352. }
  11353.  
  11354. PIXI.ColorMatrixFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
  11355. PIXI.ColorMatrixFilter.prototype.constructor = PIXI.ColorMatrixFilter;
  11356.  
  11357. /**
  11358.  * Sets the matrix of the color matrix filter
  11359.  *
  11360.  * @property matrix
  11361.  * @type Array and array of 26 numbers
  11362.  * @default [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]
  11363.  */
  11364. Object.defineProperty(PIXI.ColorMatrixFilter.prototype, 'matrix', {
  11365.     get: function() {
  11366.         return this.uniforms.matrix.value;
  11367.     },
  11368.     set: function(value) {
  11369.         this.uniforms.matrix.value = value;
  11370.     }
  11371. });
  11372. /**
  11373.  * @author Mat Groves http://matgroves.com/ @Doormat23
  11374.  */
  11375.  
  11376.  
  11377. /**
  11378.  *
  11379.  * This turns your displayObjects to black and white.
  11380.  * @class GreyFilter
  11381.  * @contructor
  11382.  */
  11383. PIXI.GreyFilter = function()
  11384. {
  11385.     PIXI.AbstractFilter.call( this );
  11386.    
  11387.     this.passes = [this];
  11388.    
  11389.     // set the uniforms
  11390.     this.uniforms = {
  11391.         grey: {type: 'f', value: 1},
  11392.     };
  11393.    
  11394.     this.fragmentSrc = [
  11395.       "precision mediump float;",
  11396.       "varying vec2 vTextureCoord;",
  11397.       "varying float vColor;",
  11398.       "uniform sampler2D uSampler;",
  11399.       "uniform float grey;",
  11400.       "void main(void) {",
  11401.         "gl_FragColor = texture2D(uSampler, vTextureCoord);",
  11402.         "gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), grey);",
  11403.         "gl_FragColor = gl_FragColor * vColor;",
  11404.       "}"
  11405.     ];
  11406. }
  11407.  
  11408. PIXI.GreyFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
  11409. PIXI.GreyFilter.prototype.constructor = PIXI.GreyFilter;
  11410.  
  11411. /**
  11412. The strength of the grey. 1 will make the object black and white, 0 will make the object its normal color
  11413. @property grey
  11414. */
  11415. Object.defineProperty(PIXI.GreyFilter.prototype, 'grey', {
  11416.     get: function() {
  11417.         return this.uniforms.grey.value;
  11418.     },
  11419.     set: function(value) {
  11420.         this.uniforms.grey.value = value;
  11421.     }
  11422. });
  11423.  
  11424. /**
  11425.  * @author Mat Groves http://matgroves.com/ @Doormat23
  11426.  */
  11427.  
  11428.  
  11429. /**
  11430.  *
  11431.  * The DisplacementFilter class uses the pixel values from the specified texture (called the displacement map) to perform a displacement of an object.
  11432.  * You can use this filter to apply all manor of crazy warping effects
  11433.  * Currently the r property of the texture is used offset the x and the g propery of the texture is used to offset the y.
  11434.  * @class DisplacementFilter
  11435.  * @contructor
  11436.  * @param texture {Texture} The texture used for the displacemtent map * must be power of 2 texture at the moment
  11437.  */
  11438. PIXI.DisplacementFilter = function(texture)
  11439. {
  11440.     PIXI.AbstractFilter.call( this );
  11441.    
  11442.     this.passes = [this];
  11443.     texture.baseTexture._powerOf2 = true;
  11444.  
  11445.     // set the uniforms
  11446.     //console.log()
  11447.     this.uniforms = {
  11448.         displacementMap: {type: 'sampler2D', value:texture},
  11449.         scale:           {type: 'f2', value:{x:30, y:30}},
  11450.         offset:          {type: 'f2', value:{x:0, y:0}},
  11451.         mapDimensions:   {type: 'f2', value:{x:1, y:5112}},
  11452.         dimensions:   {type: 'f4', value:[0,0,0,0]}
  11453.     };
  11454.    
  11455.  
  11456.     if(texture.baseTexture.hasLoaded)
  11457.     {
  11458.         this.uniforms.mapDimensions.value.x = texture.width;
  11459.         this.uniforms.mapDimensions.value.y = texture.height;
  11460.     }
  11461.     else
  11462.     {
  11463.         this.boundLoadedFunction = this.onTextureLoaded.bind(this);
  11464.  
  11465.         texture.baseTexture.on("loaded", this.boundLoadedFunction);
  11466.     }
  11467.  
  11468.     this.fragmentSrc = [
  11469.       "precision mediump float;",
  11470.       "varying vec2 vTextureCoord;",
  11471.       "varying float vColor;",
  11472.       "uniform sampler2D displacementMap;",
  11473.       "uniform sampler2D uSampler;",
  11474.       "uniform vec2 scale;",
  11475.       "uniform vec2 offset;",
  11476.       "uniform vec4 dimensions;",
  11477.       "uniform vec2 mapDimensions;",// = vec2(256.0, 256.0);",
  11478.      // "const vec2 textureDimensions = vec2(750.0, 750.0);",
  11479.      
  11480.       "void main(void) {",
  11481.         "vec2 mapCords = vTextureCoord.xy;",
  11482. //      "mapCords -= ;",
  11483.         "mapCords += (dimensions.zw + offset)/ dimensions.xy ;",
  11484.         "mapCords.y *= -1.0;",
  11485.         "mapCords.y += 1.0;",
  11486.         "vec2 matSample = texture2D(displacementMap, mapCords).xy;",
  11487.         "matSample -= 0.5;",     
  11488.         "matSample *= scale;",
  11489.         "matSample /= mapDimensions;",
  11490.         "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x + matSample.x, vTextureCoord.y + matSample.y));",
  11491.         "gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb, 1.0);",
  11492.         "vec2 cord = vTextureCoord;",
  11493.        
  11494.         //"gl_FragColor =  texture2D(displacementMap, cord);",
  11495.         "gl_FragColor = gl_FragColor * vColor;",
  11496.        
  11497.       "}"
  11498.     ];
  11499.    
  11500. }
  11501.  
  11502. PIXI.DisplacementFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
  11503. PIXI.DisplacementFilter.prototype.constructor = PIXI.DisplacementFilter;
  11504.  
  11505. PIXI.DisplacementFilter.prototype.onTextureLoaded = function()
  11506. {
  11507.    
  11508.     this.uniforms.mapDimensions.value.x = this.uniforms.displacementMap.value.width;
  11509.     this.uniforms.mapDimensions.value.y = this.uniforms.displacementMap.value.height;
  11510.  
  11511.     this.uniforms.displacementMap.value.baseTexture.off("loaded", this.boundLoadedFunction)
  11512.  
  11513. }
  11514.  
  11515. /**
  11516.  * The texture used for the displacemtent map * must be power of 2 texture at the moment
  11517.  *
  11518.  * @property map
  11519.  * @type Texture
  11520.  */
  11521. Object.defineProperty(PIXI.DisplacementFilter.prototype, 'map', {
  11522.     get: function() {
  11523.         return this.uniforms.displacementMap.value;
  11524.     },
  11525.     set: function(value) {
  11526.         this.uniforms.displacementMap.value = value;
  11527.     }
  11528. });
  11529.  
  11530. /**
  11531.  * The multiplier used to scale the displacement result from the map calculation.
  11532.  *
  11533.  * @property scale
  11534.  * @type Point
  11535.  */
  11536. Object.defineProperty(PIXI.DisplacementFilter.prototype, 'scale', {
  11537.     get: function() {
  11538.         return this.uniforms.scale.value;
  11539.     },
  11540.     set: function(value) {
  11541.         this.uniforms.scale.value = value;
  11542.     }
  11543. });
  11544.  
  11545. /**
  11546.  * The offset used to move the displacement map.
  11547.  *
  11548.  * @property offset
  11549.  * @type Point
  11550.  */
  11551. Object.defineProperty(PIXI.DisplacementFilter.prototype, 'offset', {
  11552.     get: function() {
  11553.         return this.uniforms.offset.value;
  11554.     },
  11555.     set: function(value) {
  11556.         this.uniforms.offset.value = value;
  11557.     }
  11558. });
  11559. /**
  11560.  * @author Mat Groves http://matgroves.com/ @Doormat23
  11561.  */
  11562.  
  11563. /**
  11564.  *
  11565.  * This filter applies a pixlate effect making display objects appear "blocky"
  11566.  * @class PixelateFilter
  11567.  * @contructor
  11568.  */
  11569. PIXI.PixelateFilter = function()
  11570. {
  11571.     PIXI.AbstractFilter.call( this );
  11572.  
  11573.     this.passes = [this];
  11574.    
  11575.     // set the uniforms
  11576.     this.uniforms = {
  11577.         invert: {type: 'f', value: 0},
  11578.         dimensions: {type: 'f4', value:new Float32Array([10000, 100, 10, 10])},
  11579.         pixelSize: {type: 'f2', value:{x:10, y:10}},
  11580.     };
  11581.  
  11582.     this.fragmentSrc = [
  11583.       "precision mediump float;",
  11584.       "varying vec2 vTextureCoord;",
  11585.       "varying float vColor;",
  11586.       "uniform vec2 testDim;",
  11587.       "uniform vec4 dimensions;",
  11588.       "uniform vec2 pixelSize;",
  11589.       "uniform sampler2D uSampler;",
  11590.       "void main(void) {",
  11591.         "vec2 coord = vTextureCoord;",
  11592.  
  11593.         "vec2 size = dimensions.xy/pixelSize;",
  11594.  
  11595.         "vec2 color = floor( ( vTextureCoord * size ) ) / size + pixelSize/dimensions.xy * 0.5;",
  11596.         "gl_FragColor = texture2D(uSampler, color);",
  11597.       "}"
  11598.     ];
  11599.    
  11600.  
  11601. }
  11602.  
  11603. PIXI.PixelateFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
  11604. PIXI.PixelateFilter.prototype.constructor = PIXI.PixelateFilter;
  11605.  
  11606. /**
  11607.  *
  11608.  * This a point that describes the size of the blocs. x is the width of the block and y is the the height
  11609.  * @property size
  11610.  * @type Point
  11611.  */
  11612. Object.defineProperty(PIXI.PixelateFilter.prototype, 'size', {
  11613.     get: function() {
  11614.         return this.uniforms.pixelSize.value;
  11615.     },
  11616.     set: function(value) {
  11617.         this.dirty = true;
  11618.         this.uniforms.pixelSize.value = value;
  11619.     }
  11620. });
  11621. /**
  11622.  * @author Mat Groves http://matgroves.com/ @Doormat23
  11623.  */
  11624.  
  11625.  
  11626.  
  11627. PIXI.BlurXFilter = function()
  11628. {
  11629.     PIXI.AbstractFilter.call( this );
  11630.    
  11631.     this.passes = [this];
  11632.    
  11633.     // set the uniforms
  11634.     this.uniforms = {
  11635.         blur: {type: 'f', value: 1/512},
  11636.     };
  11637.    
  11638.     this.fragmentSrc = [
  11639.       "precision mediump float;",
  11640.       "varying vec2 vTextureCoord;",
  11641.       "varying float vColor;",
  11642.       "uniform float blur;",
  11643.       "uniform sampler2D uSampler;",
  11644.         "void main(void) {",
  11645.         "vec4 sum = vec4(0.0);",
  11646.  
  11647.         "sum += texture2D(uSampler, vec2(vTextureCoord.x - 4.0*blur, vTextureCoord.y)) * 0.05;",
  11648.         "sum += texture2D(uSampler, vec2(vTextureCoord.x - 3.0*blur, vTextureCoord.y)) * 0.09;",
  11649.         "sum += texture2D(uSampler, vec2(vTextureCoord.x - 2.0*blur, vTextureCoord.y)) * 0.12;",
  11650.         "sum += texture2D(uSampler, vec2(vTextureCoord.x - blur, vTextureCoord.y)) * 0.15;",
  11651.         "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y)) * 0.16;",
  11652.         "sum += texture2D(uSampler, vec2(vTextureCoord.x + blur, vTextureCoord.y)) * 0.15;",
  11653.         "sum += texture2D(uSampler, vec2(vTextureCoord.x + 2.0*blur, vTextureCoord.y)) * 0.12;",
  11654.         "sum += texture2D(uSampler, vec2(vTextureCoord.x + 3.0*blur, vTextureCoord.y)) * 0.09;",
  11655.         "sum += texture2D(uSampler, vec2(vTextureCoord.x + 4.0*blur, vTextureCoord.y)) * 0.05;",
  11656.      
  11657.         "gl_FragColor = sum;",
  11658.  
  11659.       "}"
  11660.     ];
  11661. }
  11662.  
  11663. PIXI.BlurXFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
  11664. PIXI.BlurXFilter.prototype.constructor = PIXI.BlurXFilter;
  11665.  
  11666.  
  11667. Object.defineProperty(PIXI.BlurXFilter.prototype, 'blur', {
  11668.     get: function() {
  11669.         return this.uniforms.blur.value / (1/7000);
  11670.     },
  11671.     set: function(value) {
  11672.    
  11673.         this.dirty = true;
  11674.         this.uniforms.blur.value = (1/7000) * value;
  11675.     }
  11676. });
  11677.  
  11678. /**
  11679.  * @author Mat Groves http://matgroves.com/ @Doormat23
  11680.  */
  11681.  
  11682.  
  11683.  
  11684. PIXI.BlurYFilter = function()
  11685. {
  11686.     PIXI.AbstractFilter.call( this );
  11687.    
  11688.     this.passes = [this];
  11689.    
  11690.     // set the uniforms
  11691.     this.uniforms = {
  11692.         blur: {type: 'f', value: 1/512},
  11693.     };
  11694.    
  11695.     this.fragmentSrc = [
  11696.       "precision mediump float;",
  11697.       "varying vec2 vTextureCoord;",
  11698.       "varying float vColor;",
  11699.       "uniform float blur;",
  11700.       "uniform sampler2D uSampler;",
  11701.         "void main(void) {",
  11702.         "vec4 sum = vec4(0.0);",
  11703.  
  11704.         "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 4.0*blur)) * 0.05;",
  11705.         "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 3.0*blur)) * 0.09;",
  11706.         "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 2.0*blur)) * 0.12;",
  11707.         "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - blur)) * 0.15;",
  11708.         "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y)) * 0.16;",
  11709.         "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + blur)) * 0.15;",
  11710.         "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 2.0*blur)) * 0.12;",
  11711.         "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 3.0*blur)) * 0.09;",
  11712.         "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 4.0*blur)) * 0.05;",
  11713.      
  11714.         "gl_FragColor = sum;",
  11715.  
  11716.       "}"
  11717.     ];
  11718. }
  11719.  
  11720. PIXI.BlurYFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
  11721. PIXI.BlurYFilter.prototype.constructor = PIXI.BlurYFilter;
  11722.  
  11723. Object.defineProperty(PIXI.BlurYFilter.prototype, 'blur', {
  11724.     get: function() {
  11725.         return this.uniforms.blur.value / (1/7000);
  11726.     },
  11727.     set: function(value) {
  11728.         //this.padding = value;
  11729.         this.uniforms.blur.value = (1/7000) * value;
  11730.     }
  11731. });
  11732.  
  11733. /**
  11734.  * @author Mat Groves http://matgroves.com/ @Doormat23
  11735.  */
  11736.  
  11737.  
  11738. /**
  11739.  *
  11740.  * The BlurFilter applies a Gaussian blur to an object.
  11741.  * The strength of the blur can be set for x- and y-axis separately (always relative to the stage).
  11742.  *
  11743.  * @class BlurFilter
  11744.  * @contructor
  11745.  */
  11746. PIXI.BlurFilter = function()
  11747. {
  11748.    
  11749.     this.blurXFilter = new PIXI.BlurXFilter();
  11750.     this.blurYFilter = new PIXI.BlurYFilter();
  11751.  
  11752.     this.passes =[this.blurXFilter, this.blurYFilter];
  11753.    
  11754. }
  11755.  
  11756. /**
  11757.  * Sets the strength of both the blurX and blurY properties simultaneously
  11758.  *
  11759.  * @property blur
  11760.  * @type Number the strength of the blur
  11761.  * @default 2
  11762.  */
  11763. Object.defineProperty(PIXI.BlurFilter.prototype, 'blur', {
  11764.     get: function() {
  11765.         return this.blurXFilter.blur;
  11766.     },
  11767.     set: function(value) {
  11768.         this.blurXFilter.blur = this.blurYFilter.blur = value;
  11769.     }
  11770. });
  11771.  
  11772. /**
  11773.  * Sets the strength of the blurX property simultaneously
  11774.  *
  11775.  * @property blurX
  11776.  * @type Number the strength of the blurX
  11777.  * @default 2
  11778.  */
  11779. Object.defineProperty(PIXI.BlurFilter.prototype, 'blurX', {
  11780.     get: function() {
  11781.         return this.blurXFilter.blur;
  11782.     },
  11783.     set: function(value) {
  11784.         this.blurXFilter.blur = value;
  11785.     }
  11786. });
  11787.  
  11788. /**
  11789.  * Sets the strength of the blurX property simultaneously
  11790.  *
  11791.  * @property blurY
  11792.  * @type Number the strength of the blurY
  11793.  * @default 2
  11794.  */
  11795. Object.defineProperty(PIXI.BlurFilter.prototype, 'blurY', {
  11796.     get: function() {
  11797.         return this.blurYFilter.blur;
  11798.     },
  11799.     set: function(value) {
  11800.         this.blurYFilter.blur = value;
  11801.     }
  11802. });
  11803.  
  11804. /**
  11805.  * @author Mat Groves http://matgroves.com/ @Doormat23
  11806.  */
  11807.  
  11808. /**
  11809.  *
  11810.  * This inverts your displayObjects colors.
  11811.  * @class InvertFilter
  11812.  * @contructor
  11813.  */
  11814. PIXI.InvertFilter = function()
  11815. {
  11816.     PIXI.AbstractFilter.call( this );
  11817.    
  11818.     this.passes = [this];
  11819.    
  11820.     // set the uniforms
  11821.     this.uniforms = {
  11822.         invert: {type: 'f', value: 1},
  11823.     };
  11824.    
  11825.     this.fragmentSrc = [
  11826.       "precision mediump float;",
  11827.       "varying vec2 vTextureCoord;",
  11828.       "varying float vColor;",
  11829.       "uniform float invert;",
  11830.       "uniform sampler2D uSampler;",
  11831.       "void main(void) {",
  11832.         "gl_FragColor = texture2D(uSampler, vTextureCoord);",
  11833.         "gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);",
  11834.         //"gl_FragColor.rgb = gl_FragColor.rgb  * gl_FragColor.a;",
  11835.         "gl_FragColor = gl_FragColor * vColor;",
  11836.       "}"
  11837.     ];
  11838.    
  11839. }
  11840.  
  11841. PIXI.InvertFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
  11842. PIXI.InvertFilter.prototype.constructor = PIXI.InvertFilter;
  11843.  
  11844. /**
  11845. The strength of the invert. 1 will fully invert the colors, 0 will make the object its normal color
  11846. @property invert
  11847. */
  11848. Object.defineProperty(PIXI.InvertFilter.prototype, 'invert', {
  11849.     get: function() {
  11850.         return this.uniforms.invert.value;
  11851.     },
  11852.     set: function(value) {
  11853.         this.uniforms.invert.value = value;
  11854.     }
  11855. });
  11856. /**
  11857. /**
  11858.  * @author Mat Groves http://matgroves.com/ @Doormat23
  11859.  */
  11860.  
  11861.  
  11862. /**
  11863.  *
  11864.  * This applies a sepia effect to your displayObjects.
  11865.  * @class SepiaFilter
  11866.  * @contructor
  11867.  */
  11868. PIXI.SepiaFilter = function()
  11869. {
  11870.     PIXI.AbstractFilter.call( this );
  11871.    
  11872.     this.passes = [this];
  11873.    
  11874.     // set the uniforms
  11875.     this.uniforms = {
  11876.         sepia: {type: 'f', value: 1},
  11877.     };
  11878.    
  11879.     this.fragmentSrc = [
  11880.       "precision mediump float;",
  11881.       "varying vec2 vTextureCoord;",
  11882.       "varying float vColor;",
  11883.       "uniform float sepia;",
  11884.       "uniform sampler2D uSampler;",
  11885.            
  11886.       "const mat3 sepiaMatrix = mat3(0.3588, 0.7044, 0.1368, 0.2990, 0.5870, 0.1140, 0.2392, 0.4696, 0.0912);",
  11887.       "void main(void) {",
  11888.         "gl_FragColor = texture2D(uSampler, vTextureCoord);",
  11889.         "gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);",
  11890.         "gl_FragColor = gl_FragColor * vColor;",
  11891.       "}"
  11892.     ];
  11893.    
  11894. }
  11895.  
  11896. PIXI.SepiaFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
  11897. PIXI.SepiaFilter.prototype.constructor = PIXI.SepiaFilter;
  11898.  
  11899. /**
  11900. The strength of the sepia. 1 will apply the full sepia effect, 0 will make the object its normal color
  11901. @property sepia
  11902. */
  11903. Object.defineProperty(PIXI.SepiaFilter.prototype, 'sepia', {
  11904.     get: function() {
  11905.         return this.uniforms.sepia.value;
  11906.     },
  11907.     set: function(value) {
  11908.         this.uniforms.sepia.value = value;
  11909.     }
  11910. });
  11911.  
  11912. /**
  11913.  * @author Mat Groves http://matgroves.com/ @Doormat23
  11914.  */
  11915.  
  11916. /**
  11917.  *
  11918.  * This filter applies a pixlate effect making display objects appear "blocky"
  11919.  * @class PixelateFilter
  11920.  * @contructor
  11921.  */
  11922. PIXI.TwistFilter = function()
  11923. {
  11924.     PIXI.AbstractFilter.call( this );
  11925.  
  11926.     this.passes = [this];
  11927.    
  11928.     // set the uniforms
  11929.     this.uniforms = {
  11930.         radius: {type: 'f', value:0.5},
  11931.         angle: {type: 'f', value:5},
  11932.         offset: {type: 'f2', value:{x:0.5, y:0.5}},
  11933.     };
  11934.  
  11935.     this.fragmentSrc = [
  11936.       "precision mediump float;",
  11937.       "varying vec2 vTextureCoord;",
  11938.       "varying float vColor;",
  11939.       "uniform vec4 dimensions;",
  11940.       "uniform sampler2D uSampler;",
  11941.      
  11942.       "uniform float radius;",
  11943.       "uniform float angle;",
  11944.       "uniform vec2 offset;",
  11945.  
  11946.       "void main(void) {",
  11947.         "vec2 coord = vTextureCoord - offset;",
  11948.         "float distance = length(coord);",
  11949.        
  11950.         "if (distance < radius){",
  11951.  
  11952.             "float ratio = (radius - distance) / radius;",
  11953.             "float angleMod = ratio * ratio * angle;",
  11954.             "float s = sin(angleMod);",
  11955.             "float c = cos(angleMod);",
  11956.             "coord = vec2(coord.x * c - coord.y * s, coord.x * s + coord.y * c);",
  11957.  
  11958.         "}",
  11959.  
  11960.         "gl_FragColor = texture2D(uSampler, coord+offset);",
  11961.       "}"
  11962.     ];
  11963. }
  11964.  
  11965. PIXI.TwistFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
  11966. PIXI.TwistFilter.prototype.constructor = PIXI.TwistFilter;
  11967.  
  11968. /**
  11969.  *
  11970.  * This point describes the the offset of the twist
  11971.  * @property size
  11972.  * @type Point
  11973.  */
  11974. Object.defineProperty(PIXI.TwistFilter.prototype, 'offset', {
  11975.     get: function() {
  11976.         return this.uniforms.offset.value;
  11977.     },
  11978.     set: function(value) {
  11979.         this.dirty = true;
  11980.         this.uniforms.offset.value = value;
  11981.     }
  11982. });
  11983.  
  11984. /**
  11985.  *
  11986.  * This radius describes size of the twist
  11987.  * @property size
  11988.  * @type Number
  11989.  */
  11990. Object.defineProperty(PIXI.TwistFilter.prototype, 'radius', {
  11991.     get: function() {
  11992.         return this.uniforms.radius.value;
  11993.     },
  11994.     set: function(value) {
  11995.         this.dirty = true;
  11996.         this.uniforms.radius.value = value;
  11997.     }
  11998. });
  11999.  
  12000. /**
  12001.  *
  12002.  * This radius describes angle of the twist
  12003.  * @property angle
  12004.  * @type Number
  12005.  */
  12006. Object.defineProperty(PIXI.TwistFilter.prototype, 'angle', {
  12007.     get: function() {
  12008.         return this.uniforms.angle.value;
  12009.     },
  12010.     set: function(value) {
  12011.         this.dirty = true;
  12012.         this.uniforms.angle.value = value;
  12013.     }
  12014. });
  12015. /**
  12016.  * @author Mat Groves http://matgroves.com/ @Doormat23
  12017.  */
  12018.  
  12019.  
  12020. /**
  12021.  *
  12022.  * This turns your displayObjects to black and white.
  12023.  * @class GreyFilter
  12024.  * @contructor
  12025.  */
  12026. PIXI.ColorStepFilter = function()
  12027. {
  12028.     PIXI.AbstractFilter.call( this );
  12029.    
  12030.     this.passes = [this];
  12031.    
  12032.     // set the uniforms
  12033.     this.uniforms = {
  12034.         step: {type: 'f', value: 5},
  12035.     };
  12036.    
  12037.     this.fragmentSrc = [
  12038.       "precision mediump float;",
  12039.       "varying vec2 vTextureCoord;",
  12040.       "varying float vColor;",
  12041.       "uniform sampler2D uSampler;",
  12042.       "uniform float step;",
  12043.       "void main(void) {",
  12044.         "vec4 color = texture2D(uSampler, vTextureCoord);",
  12045.         "color = floor(color * step) / step;",
  12046.         "gl_FragColor = color * vColor;",
  12047.       "}"
  12048.     ];
  12049. }
  12050.  
  12051. PIXI.ColorStepFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
  12052. PIXI.ColorStepFilter.prototype.constructor = PIXI.ColorStepFilter;
  12053.  
  12054. /**
  12055. The number of steps.
  12056. @property step
  12057. */
  12058. Object.defineProperty(PIXI.ColorStepFilter.prototype, 'step', {
  12059.     get: function() {
  12060.         return this.uniforms.step.value;
  12061.     },
  12062.     set: function(value) {
  12063.         this.uniforms.step.value = value;
  12064.     }
  12065. });
  12066.  
  12067. /**
  12068.  * @author Mat Groves http://matgroves.com/ @Doormat23
  12069.  * original filter: https://github.com/evanw/glfx.js/blob/master/src/filters/fun/dotscreen.js
  12070.  */
  12071.  
  12072. /**
  12073.  *
  12074.  * This filter applies a pixlate effect making display objects appear "blocky"
  12075.  * @class PixelateFilter
  12076.  * @contructor
  12077.  */
  12078. PIXI.DotScreenFilter = function()
  12079. {
  12080.     PIXI.AbstractFilter.call( this );
  12081.  
  12082.     this.passes = [this];
  12083.    
  12084.     // set the uniforms
  12085.     this.uniforms = {
  12086.         scale: {type: 'f', value:1},
  12087.         angle: {type: 'f', value:5},
  12088.         dimensions:   {type: 'f4', value:[0,0,0,0]}
  12089.     };
  12090.  
  12091.     this.fragmentSrc = [
  12092.       "precision mediump float;",
  12093.       "varying vec2 vTextureCoord;",
  12094.       "varying float vColor;",
  12095.       "uniform vec4 dimensions;",
  12096.       "uniform sampler2D uSampler;",
  12097.  
  12098.         "uniform float angle;",
  12099.         "uniform float scale;",
  12100.  
  12101.         "float pattern() {",
  12102.             "float s = sin(angle), c = cos(angle);",
  12103.             "vec2 tex = vTextureCoord * dimensions.xy;",
  12104.             "vec2 point = vec2(",
  12105.                 "c * tex.x - s * tex.y,",
  12106.                 "s * tex.x + c * tex.y",
  12107.             ") * scale;",
  12108.             "return (sin(point.x) * sin(point.y)) * 4.0;",
  12109.         "}",
  12110.  
  12111.         "void main() {",
  12112.             "vec4 color = texture2D(uSampler, vTextureCoord);",
  12113.             "float average = (color.r + color.g + color.b) / 3.0;",
  12114.             "gl_FragColor = vec4(vec3(average * 10.0 - 5.0 + pattern()), color.a);",
  12115.         "}",
  12116.     ];
  12117. }
  12118.  
  12119. PIXI.DotScreenFilter.prototype = Object.create( PIXI.DotScreenFilter.prototype );
  12120. PIXI.DotScreenFilter.prototype.constructor = PIXI.DotScreenFilter;
  12121.  
  12122. /**
  12123.  *
  12124.  * This describes the the scale
  12125.  * @property scale
  12126.  * @type Number
  12127.  */
  12128. Object.defineProperty(PIXI.DotScreenFilter.prototype, 'scale', {
  12129.     get: function() {
  12130.         return this.uniforms.scale.value;
  12131.     },
  12132.     set: function(value) {
  12133.         this.dirty = true;
  12134.         this.uniforms.scale.value = value;
  12135.     }
  12136. });
  12137.  
  12138. /**
  12139.  *
  12140.  * This radius describes angle
  12141.  * @property angle
  12142.  * @type Number
  12143.  */
  12144. Object.defineProperty(PIXI.DotScreenFilter.prototype, 'angle', {
  12145.     get: function() {
  12146.         return this.uniforms.angle.value;
  12147.     },
  12148.     set: function(value) {
  12149.         this.dirty = true;
  12150.         this.uniforms.angle.value = value;
  12151.     }
  12152. });
  12153. /**
  12154.  * @author Mat Groves http://matgroves.com/ @Doormat23
  12155.  */
  12156.  
  12157.  
  12158.  
  12159. PIXI.CrossHatchFilter = function()
  12160. {
  12161.     PIXI.AbstractFilter.call( this );
  12162.    
  12163.     this.passes = [this];
  12164.    
  12165.     // set the uniforms
  12166.     this.uniforms = {
  12167.         blur: {type: 'f', value: 1/512},
  12168.     };
  12169.    
  12170.     this.fragmentSrc = [
  12171.       "precision mediump float;",
  12172.       "varying vec2 vTextureCoord;",
  12173.       "varying float vColor;",
  12174.       "uniform float blur;",
  12175.       "uniform sampler2D uSampler;",
  12176.         "void main(void) {",
  12177.        
  12178.        
  12179.         "    float lum = length(texture2D(uSampler, vTextureCoord.xy).rgb);",
  12180.         "     ",
  12181.         "    gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);",
  12182.         "     ",
  12183.         "    if (lum < 1.00) {",
  12184.         "        if (mod(gl_FragCoord.x + gl_FragCoord.y, 10.0) == 0.0) {",
  12185.         "            gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);",
  12186.         "        }",
  12187.         "    }",
  12188.         "     ",
  12189.         "    if (lum < 0.75) {",
  12190.         "        if (mod(gl_FragCoord.x - gl_FragCoord.y, 10.0) == 0.0) {",
  12191.         "            gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);",
  12192.         "        }",
  12193.         "    }",
  12194.         "     ",
  12195.         "    if (lum < 0.50) {",
  12196.         "        if (mod(gl_FragCoord.x + gl_FragCoord.y - 5.0, 10.0) == 0.0) {",
  12197.         "            gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);",
  12198.         "        }",
  12199.         "    }",
  12200.         "     ",
  12201.         "    if (lum < 0.3) {",
  12202.         "        if (mod(gl_FragCoord.x - gl_FragCoord.y - 5.0, 10.0) == 0.0) {",
  12203.         "            gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);",
  12204.         "        }",
  12205.         "    }",
  12206.         "}"
  12207.     ];
  12208. }
  12209.  
  12210. PIXI.CrossHatchFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
  12211. PIXI.CrossHatchFilter.prototype.constructor = PIXI.BlurYFilter;
  12212.  
  12213. Object.defineProperty(PIXI.CrossHatchFilter.prototype, 'blur', {
  12214.     get: function() {
  12215.         return this.uniforms.blur.value / (1/7000);
  12216.     },
  12217.     set: function(value) {
  12218.         //this.padding = value;
  12219.         this.uniforms.blur.value = (1/7000) * value;
  12220.     }
  12221. });
  12222.  
  12223. /**
  12224.  * @author Mat Groves http://matgroves.com/ @Doormat23
  12225.  */
  12226.  
  12227.  
  12228.  
  12229. PIXI.RGBSplitFilter = function()
  12230. {
  12231.     PIXI.AbstractFilter.call( this );
  12232.    
  12233.     this.passes = [this];
  12234.    
  12235.     // set the uniforms
  12236.     this.uniforms = {
  12237.         red: {type: 'f2', value: {x:20, y:20}},
  12238.         green: {type: 'f2', value: {x:-20, y:20}},
  12239.         blue: {type: 'f2', value: {x:20, y:-20}},
  12240.         dimensions:   {type: 'f4', value:[0,0,0,0]}
  12241.     };
  12242.    
  12243.     this.fragmentSrc = [
  12244.       "precision mediump float;",
  12245.       "varying vec2 vTextureCoord;",
  12246.       "varying float vColor;",
  12247.       "uniform vec2 red;",
  12248.       "uniform vec2 green;",
  12249.       "uniform vec2 blue;",
  12250.       "uniform vec4 dimensions;",
  12251.       "uniform sampler2D uSampler;",
  12252.         "void main(void) {",
  12253.           "gl_FragColor.r = texture2D(uSampler, vTextureCoord + red/dimensions.xy).r;",
  12254.           "gl_FragColor.g = texture2D(uSampler, vTextureCoord + green/dimensions.xy).g;",
  12255.           "gl_FragColor.b = texture2D(uSampler, vTextureCoord + blue/dimensions.xy).b;",
  12256.           "gl_FragColor.a = texture2D(uSampler, vTextureCoord).a;",
  12257.       "}"
  12258.     ];
  12259. }
  12260.  
  12261. PIXI.RGBSplitFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
  12262. PIXI.RGBSplitFilter.prototype.constructor = PIXI.RGBSplitFilter;
  12263.  
  12264. Object.defineProperty(PIXI.RGBSplitFilter.prototype, 'angle', {
  12265.     get: function() {
  12266.         return this.uniforms.blur.value / (1/7000);
  12267.     },
  12268.     set: function(value) {
  12269.         //this.padding = value;
  12270.         this.uniforms.blur.value = (1/7000) * value;
  12271.     }
  12272. });
  12273.  
  12274. /**
  12275.  * @author Mat Groves http://matgroves.com/ @Doormat23
  12276.  */
  12277.  
  12278.     if (typeof exports !== 'undefined') {
  12279.         if (typeof module !== 'undefined' && module.exports) {
  12280.             exports = module.exports = PIXI;
  12281.         }
  12282.         exports.PIXI = PIXI;
  12283.     } else if (typeof define !== 'undefined' && define.amd) {
  12284.         define(PIXI);
  12285.     } else {
  12286.         root.PIXI = PIXI;
  12287.         window['PIXI'] = PIXI;
  12288.     }
  12289. }).call(this);
Add Comment
Please, Sign In to add comment