Skip to content

Instantly share code, notes, and snippets.

@profelis
Created July 28, 2012 13:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save profelis/3193372 to your computer and use it in GitHub Desktop.
Save profelis/3193372 to your computer and use it in GitHub Desktop.
ND2D Scale9Sprite
package deep.nd2d.display
{
import de.nulldesign.nd2d.display.Camera2D;
import de.nulldesign.nd2d.display.Sprite2D;
import de.nulldesign.nd2d.geom.Face;
import de.nulldesign.nd2d.geom.UV;
import de.nulldesign.nd2d.geom.Vertex;
import de.nulldesign.nd2d.materials.Sprite2DMaterial;
import de.nulldesign.nd2d.materials.texture.Texture2D;
import deep.nd2d.materials.ScaleSpriteMaterial;
import flash.display3D.Context3D;
import flash.geom.Rectangle;
/**
* @author Dima Granetchi <system.grand@gmail.com>, <deep@e-citrus.ru>
*/
public class AScaleGUISprite2D extends GUISprite2D
{
protected var _sliceRect:Rectangle;
protected var invalidGrid:Boolean = false;
protected var invalidUV:Boolean = false;
protected var _scale9Material:ScaleSpriteMaterial;
protected var uvList:Vector.<UV>;
protected var vertexList:Vector.<Vertex>;
protected var stepX:int;
protected var stepY:int;
public function AScaleGUISprite2D(texture:Texture2D, sliceRect:Rectangle)
{
super();
setMaterial(new ScaleSpriteMaterial());
setTexture(texture);
this.sliceRect = sliceRect;
}
override protected function rebuildGeometry():void
{
faceList = new Vector.<Face>();
vertexList = new Vector.<Vertex>();
uvList = new Vector.<UV>();
var ar:Array = [];
var uv:Array = [];
var sx:Number = 1 / stepX;
var sy:Number = 1 / stepY;
for (i = 0; i <= stepX; i++)
{
ar.push([]);
uv.push([]);
for (j = 0; j <= stepY; j++)
{
var x:Number = i * sx;
var y:Number = j * sy;
var v:Vertex = new Vertex(x, y, 0.0);
vertexList.push(v);
ar[i].push(v);
var u:UV = new UV(x, y);
uvList.push(u);
uv[i].push(u);
}
}
for (var i:int = 1, m:int = ar.length; i < m; i++)
{
for (var j:int = 1, n:int = ar[i].length; j < n; j++)
{
faceList.push(new Face(ar[i - 1][j - 1], ar[i - 1][j], ar[i][j], uv[i - 1][j - 1], uv[i - 1][j], uv[i][j]));
faceList.push(new Face(ar[i - 1][j - 1], ar[i][j], ar[i][j - 1], uv[i - 1][j - 1], uv[i][j], uv[i][j - 1]));
}
}
}
override public function setMaterial(value:Sprite2DMaterial):void
{
_scale9Material = value as ScaleSpriteMaterial;
super.setMaterial(value);
}
override public function setTexture(value:Texture2D):void
{
var w:Number = _width;
var h:Number = _height;
if (texture)
{
var bw:Number = texture.bitmapWidth;
var bh:Number = texture.bitmapHeight;
}
super.setTexture(value);
if (w == w && h == h)
{
_width = w;
_height = h;
}
var invalid:Boolean = value && (bw != value.bitmapWidth || bh != value.bitmapHeight);
invalidUV ||= invalid;
invalidGrid ||= invalid;
}
override public function set width(value:Number):void
{
_width = value;
invalidGrid = true;
}
override public function set height(value:Number):void
{
_height = value;
invalidGrid = true;
}
public function get sliceRect():Rectangle
{
return _sliceRect;
}
public function set sliceRect(value:Rectangle):void
{
if (!_sliceRect || !_sliceRect.equals(value))
{
_sliceRect = value;
invalidUV = true;
invalidGrid = true;
}
}
override protected function draw(context:Context3D, camera:Camera2D):void
{
if (texture)
{
if (invalidUV) updateUV();
if (invalidGrid) updateGrid();
}
super.draw(context, camera);
}
override public function get numTris():uint
{
return faceList.length;
}
protected function updateUV():void
{
if (_scale9Material) _scale9Material.rescale();
else material.handleDeviceLoss();
var cols:Array = stepX == 1 ? [0, texture.bitmapWidth] : [0, _sliceRect.left, _sliceRect.right, texture.bitmapWidth];
var rows:Array = stepY == 1 ? [0, texture.bitmapHeight] : [0, _sliceRect.top, _sliceRect.bottom, texture.bitmapHeight];
var sx:Number = 1 / texture.textureWidth;
var sy:Number = 1 / texture.textureHeight;
for (var i:int = 0; i <= stepX; i++)
{
for (var j:int = 0; j <= stepY; j++)
{
var u:UV = uvList[i * (stepY+1) + j];
u.u = cols[i] * sx;
u.v = rows[j] * sy;
}
}
invalidUV = false;
}
protected function updateGrid():void
{
if (_scale9Material) _scale9Material.rescale();
else material.handleDeviceLoss();
var cols:Array = stepX == 1 ? [0, _width] : [0, _sliceRect.left, _width - texture.bitmapWidth + _sliceRect.right, _width];
var rows:Array = stepY == 1 ? [0, _height] : [0, _sliceRect.top, _height - texture.bitmapHeight + _sliceRect.bottom, _height];
var sx:Number = 2 / texture.textureWidth;
var sy:Number = 2 / texture.textureHeight;
for (var i:int = 0; i <= stepX; i++)
{
for (var j:int = 0; j <= stepY; j++)
{
var v:Vertex = vertexList[i * (stepY+1) + j];
v.x = (cols[i]) * sx;
v.y = (rows[j]) * sy;
}
}
invalidGrid = false;
}
override public function dispose():void
{
super.dispose();
_scale9Material = null;
uvList = null;
vertexList = null;
}
}
}
package deep.nd2d.display
{
import de.nulldesign.nd2d.display.Sprite2D;
import de.nulldesign.nd2d.geom.Face;
import de.nulldesign.nd2d.materials.texture.Texture2D;
import flash.geom.Rectangle;
import flash.utils.Dictionary;
/**
* @author Dima Granetchi <system.grand@gmail.com>, <deep@e-citrus.ru>
*/
public class GUISprite2D extends Sprite2D
{
public function GUISprite2D(textureObject:Texture2D = null)
{
super(textureObject);
rebuildGeometry();
}
protected function rebuildGeometry():void
{
var verts:Dictionary = new Dictionary(true);
for each (var f:Face in faceList)
{
if (!verts[f.v1])
{
f.v1.x += 1;
f.v1.y += 1;
verts[f.v1] = true;
}
if (!verts[f.v2])
{
f.v2.x += 1;
f.v2.y += 1;
verts[f.v2] = true;
}
if (!verts[f.v3])
{
f.v3.x += 1;
f.v3.y += 1;
verts[f.v3] = true;
}
}
}
override protected function hitTest():Boolean {
var res:Boolean = !(isNaN(_width) || isNaN(_height)) &&
(_mouseX >= 0 && _mouseY >= 0 && _mouseX <= _width && _mouseY <= _height);
if(res && usePixelPerfectHitTest && texture.bitmap) {
var xCoord:Number = _mouseX;
var yCoord:Number = _mouseY;
if(spriteSheet) {
var rect:Rectangle = spriteSheet.getDimensionForFrame();
xCoord += rect.x;
yCoord += rect.y;
}
return (texture.bitmap.getPixel32(xCoord, yCoord) >> 24 & 0xFF) > 0;
}
return res;
}
}
}
package deep.nd2d.materials.texture
{
import de.nulldesign.nd2d.materials.texture.Texture2D;
import de.nulldesign.nd2d.materials.texture.TextureOption;
import de.nulldesign.nd2d.utils.TextureHelper;
import flash.display.BitmapData;
import flash.display3D.Context3D;
import flash.display3D.Context3DTextureFormat;
import flash.display3D.textures.Texture;
import flash.geom.Point;
import flash.geom.Rectangle;
/**
* @author Dima Granetchi <system.grand@gmail.com>, <deep@e-citrus.ru>
*/
public class GUITexture2D extends Texture2D
{
public function GUITexture2D(autoCleanUpResources:Boolean = false)
{
super(autoCleanUpResources);
}
public static function textureFromBitmapData(bitmap:BitmapData, autoCleanUpResources:Boolean = false):Texture2D
{
var t:GUITexture2D = new GUITexture2D(autoCleanUpResources);
if (bitmap)
{
t.bitmap = bitmap;
t.bitmapWidth = bitmap.width;
t.bitmapHeight = bitmap.height;
var dimensions:Point = TextureHelper.getTextureDimensionsFromBitmap(bitmap);
t.textureWidth = dimensions.x;
t.textureHeight = dimensions.y;
t.hasPremultipliedAlpha = true
}
return t;
}
override public function getTexture(context:Context3D):Texture
{
if (!texture)
{
if (compressedBitmap)
{
texture = TextureHelper.generateTextureFromByteArray(context, compressedBitmap);
}
else if (bitmap)
{
var options:uint = textureOptions;
var useMipMapping:Boolean = (options & TextureOption.MIPMAP_LINEAR) + (options & TextureOption.MIPMAP_NEAREST) > 0;
texture = generateTextureFromBitmap(context, bitmap, useMipMapping);
}
else
{
texture = context.createTexture(textureWidth, textureHeight, Context3DTextureFormat.BGRA, true);
}
if (autoCleanUpResources)
{
if (bitmap)
{
bitmap.dispose();
bitmap = null;
}
compressedBitmap = null;
}
}
return texture;
}
public static function generateTextureFromBitmap(context:Context3D, bmp:BitmapData, useMipMaps:Boolean):Texture
{
var textureDimensions:Point = TextureHelper.getTextureDimensionsFromBitmap(bmp);
var newBmp:BitmapData = new BitmapData(textureDimensions.x, textureDimensions.y, true, 0x00000000);
var sourceRect:Rectangle = new Rectangle(0, 0, bmp.width, bmp.height);
var destPoint:Point = new Point(0, 0);
newBmp.copyPixels(bmp, sourceRect, destPoint);
var texture:Texture = context.createTexture(textureDimensions.x, textureDimensions.y, Context3DTextureFormat.BGRA, false);
if (useMipMaps)
{
TextureHelper.uploadTextureWithMipmaps(texture, newBmp);
}
else
{
texture.uploadFromBitmapData(newBmp);
}
return texture;
}
}
}
package deep.nd2d.display
{
import de.nulldesign.nd2d.display.Camera2D;
import de.nulldesign.nd2d.display.Sprite2D;
import de.nulldesign.nd2d.geom.Face;
import de.nulldesign.nd2d.geom.UV;
import de.nulldesign.nd2d.geom.Vertex;
import de.nulldesign.nd2d.materials.Sprite2DMaterial;
import de.nulldesign.nd2d.materials.texture.Texture2D;
import deep.nd2d.materials.ScaleSpriteMaterial;
import flash.display3D.Context3D;
import flash.geom.Point;
import flash.geom.Rectangle;
/**
* @author Dima Granetchi <system.grand@gmail.com>, <deep@e-citrus.ru>
*/
public class Scale3HSprite2D extends AScaleGUISprite2D
{
public function Scale3HSprite2D(texture:Texture2D, sliceRect:Rectangle)
{
stepX = 3;
stepY = 1;
super(texture, sliceRect);
}
}
}
package deep.nd2d.display
{
import de.nulldesign.nd2d.display.Camera2D;
import de.nulldesign.nd2d.display.Sprite2D;
import de.nulldesign.nd2d.geom.Face;
import de.nulldesign.nd2d.geom.UV;
import de.nulldesign.nd2d.geom.Vertex;
import de.nulldesign.nd2d.materials.Sprite2DMaterial;
import de.nulldesign.nd2d.materials.texture.Texture2D;
import deep.nd2d.materials.ScaleSpriteMaterial;
import flash.display3D.Context3D;
import flash.geom.Point;
import flash.geom.Rectangle;
/**
* @author Dima Granetchi <system.grand@gmail.com>, <deep@e-citrus.ru>
*/
public class Scale3VSprite2D extends AScaleGUISprite2D
{
public function Scale3VSprite2D(texture:Texture2D, sliceRect:Rectangle)
{
stepX = 1;
stepY = 3;
super(texture, sliceRect);
}
}
}
package deep.nd2d.display
{
import de.nulldesign.nd2d.display.Camera2D;
import de.nulldesign.nd2d.display.Sprite2D;
import de.nulldesign.nd2d.geom.Face;
import de.nulldesign.nd2d.geom.UV;
import de.nulldesign.nd2d.geom.Vertex;
import de.nulldesign.nd2d.materials.Sprite2DMaterial;
import de.nulldesign.nd2d.materials.texture.Texture2D;
import deep.nd2d.materials.ScaleSpriteMaterial;
import flash.display3D.Context3D;
import flash.geom.Rectangle;
/**
* @author Dima Granetchi <system.grand@gmail.com>, <deep@e-citrus.ru>
*/
public class Scale9Sprite2D extends AScaleGUISprite2D
{
public function Scale9Sprite2D(texture:Texture2D, sliceRect:Rectangle)
{
stepX = 3;
stepY = 3;
super(texture, sliceRect);
}
}
}
package deep.nd2d.materials
{
import de.nulldesign.nd2d.materials.Sprite2DMaterial;
/**
* @author Dima Granetchi <system.grand@gmail.com>, <deep@e-citrus.ru>
*/
public class ScaleSpriteMaterial extends Sprite2DMaterial
{
public function ScaleSpriteMaterial()
{
super()
}
public function rescale():void
{
vertexBuffer = null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment