rodrigolopezpeker

Genome2D > GShapeUtils (vertices from objects)

Jan 15th, 2014
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.  * Code by rodrigolopezpeker (aka 7interactive™) on 1/15/14 7:47 PM.
  3.  */
  4. package ar.com.rodrigolopezpeker.genome.utils {
  5. import com.genome2d.components.renderables.GSimpleShape;
  6. import com.genome2d.core.GNode;
  7. import com.genome2d.core.GNodeFactory;
  8. import com.genome2d.core.Genome2D;
  9. import com.genome2d.textures.GTexture;
  10. import com.genome2d.textures.factories.GTextureFactory;
  11.  
  12. import flash.display.BitmapData;
  13. import flash.display.DisplayObject;
  14. import flash.display.Graphics;
  15. import flash.geom.Point;
  16.  
  17. import nape.geom.GeomPoly;
  18. import nape.geom.GeomPolyList;
  19. import nape.geom.GeomVertexIterator;
  20. import nape.geom.MarchingSquares;
  21. import nape.geom.Vec2;
  22.  
  23. public class GShapeUtils {
  24.     private static const DEFAULT_POINT:Point = new Point();
  25.     private static const DEFAULT_CONFIGURATION:Object =
  26.     {granularity: 8, quality: 2, simplification: 1.5, alphaThreshold: 0x80, offsetPosition: DEFAULT_POINT };
  27.     public static var DEFAULT_TEXTURE:GTexture;
  28.  
  29.     /**
  30.      * Utility class, no constructor.
  31.      */
  32.     public function GShapeUtils() {}
  33.  
  34.     public static function parseGSimpleShape(pDisplay:*, pConf:Object = null, pParentNode:GNode = null):GSimpleShape {
  35.         if (!pConf) pConf = {};
  36.         // create default texture.
  37.         if (!DEFAULT_TEXTURE && Genome2D.getInstance().isInitialized()) {
  38.             DEFAULT_TEXTURE = GTextureFactory.createFromColor('__gshapeutils_tx', 0xffffff, 4, 4);
  39.         }
  40.         // default missing props.
  41.         for (var p:String in DEFAULT_CONFIGURATION) if (!pConf.hasOwnProperty(p)) pConf[p] = DEFAULT_CONFIGURATION[p];
  42.         if (!pConf.hasOwnProperty('texture')) {
  43.             pConf.texture = DEFAULT_TEXTURE;
  44.         } else if (pConf.texture is String) {
  45.             pConf.texture = GTexture.getTextureById(pConf.texture);
  46.         }
  47.         var vert:Vector.<Number>;
  48.         if (pDisplay is DisplayObject) {
  49.             vert = getVerticesDisplayObject(pDisplay as DisplayObject, pConf.offsetPosition, pConf.granularity, pConf.quality, pConf.simplification);
  50.         } else if (pDisplay is BitmapData) {
  51.             vert = getVerticesFromBitmap(pDisplay as BitmapData, pConf.offsetPosition, pConf.alphaThreshold, pConf.granularity, pConf.quality, pConf.simplification);
  52.         } else if (pDisplay is Graphics) {
  53.  
  54.         }
  55.         var uvs:Vector.<Number> = new Vector.<Number>(vert.length, true);
  56.         var shape:GSimpleShape = GNodeFactory.createNodeWithComponent(GSimpleShape) as GSimpleShape;
  57.         shape.setTexture(pConf.texture);
  58.         shape.init(vert, uvs);
  59.         if (pParentNode) pParentNode.addChild(shape.node);
  60.         return shape;
  61.     }
  62.  
  63.  
  64.     public static function getVerticesDisplayObject(mc:DisplayObject, offsetPosition:Point = null, granularity:Number = 8, quality:int = 2, simplification:Number = 1.5):Vector.<Number> {
  65.         var mcIso:DisplayObjectIso = new DisplayObjectIso(mc);
  66.         if (!mc.stage || !mc.parent) {
  67.             trace('Flash requires an object to be on stage for hitTestPoint used by the iso-function to work correctly. Also the displayObject needs a parent! SIGH.');
  68.             return null;
  69.         }
  70.         if (!offsetPosition) offsetPosition = DEFAULT_POINT;
  71.         var granularityVec:Vec2 = Vec2.weak(granularity, granularity);
  72.         var polys:GeomPolyList = MarchingSquares.run(mcIso, mcIso.bounds, granularityVec, quality);
  73.         var vertices:Vector.<Number> = new Vector.<Number>();
  74.         polys.foreach(function (p:GeomPoly):void {
  75.             var qolys:GeomPolyList = p.simplify(simplification).triangularDecomposition(true);
  76.             qolys.foreach(function (p:GeomPoly):void {
  77.                 var it:GeomVertexIterator = p.iterator();
  78.                 while (it.hasNext()) {
  79.                     var v:Vec2 = it.next();
  80.                     vertices.push(v.x - offsetPosition.x, v.y - offsetPosition.y);
  81.                 }
  82.             });
  83.         });
  84.         polys.clear();
  85.         return vertices;
  86.     }
  87.  
  88.     public static function getVerticesFromBitmap(bd:BitmapData, offsetPosition:Point = null, alphaThresold:Number = 0x80, granularity:Number = 8, quality:int = 2, simplification:Number = 1.5):Vector.<Number> {
  89.         var bitmapIso:BitmapDataIso = new BitmapDataIso(bd, alphaThresold);
  90.         // offset coordinates to pivot!
  91.         if (!offsetPosition) offsetPosition = DEFAULT_POINT;
  92.         var granularityVec:Vec2 = Vec2.weak(granularity, granularity);
  93.         var polys:GeomPolyList = MarchingSquares.run(bitmapIso, bitmapIso.bounds, granularityVec, quality);
  94.         var vertices:Vector.<Number> = new Vector.<Number>();
  95.         polys.foreach(function (p:GeomPoly):void {
  96.             var qolys:GeomPolyList = p.simplify(simplification).triangularDecomposition(true);
  97.             qolys.foreach(function (p:GeomPoly):void {
  98.                 var it:GeomVertexIterator = p.iterator();
  99.                 while (it.hasNext()) {
  100.                     var v:Vec2 = it.next();
  101.                     vertices.push(v.x - offsetPosition.x, v.y - offsetPosition.y);
  102.                 }
  103.             });
  104.         });
  105.         polys.clear();
  106.         return vertices;
  107.     }
  108. }
  109. }
  110.  
  111. import flash.display.Bitmap;
  112. import flash.display.BitmapData;
  113. import flash.display.DisplayObject;
  114.  
  115. import nape.geom.AABB;
  116. import nape.geom.IsoFunction;
  117.  
  118. class DisplayObjectIso implements IsoFunction {
  119.     public var displayObject:DisplayObject;
  120.     public var bounds:AABB;
  121.  
  122.     public function DisplayObjectIso(displayObject:DisplayObject):void {
  123.         this.displayObject = displayObject;
  124.         // important to have a parent!
  125.         this.bounds = AABB.fromRect(displayObject.getBounds(displayObject.parent));
  126.     }
  127.  
  128.     public function iso(x:Number, y:Number):Number {
  129.         // Best we can really do with a generic DisplayObject
  130.         // is to return a binary value {-1, 1} depending on
  131.         // if the sample point is in or out side.
  132.         var hit:Boolean = displayObject.hitTestPoint(x, y, true);
  133.         return hit ? -1 : 1;
  134.     }
  135. }
  136.  
  137. class BitmapDataIso implements IsoFunction {
  138.     public var bitmap:BitmapData;
  139.     public var alphaThreshold:Number;
  140.     public var bounds:AABB;
  141.  
  142.     public function BitmapDataIso(bitmap:BitmapData, alphaThreshold:Number = 0x80):void {
  143.         this.bitmap = bitmap;
  144.         this.alphaThreshold = alphaThreshold;
  145.         bounds = new AABB(0, 0, bitmap.width, bitmap.height);
  146.     }
  147.  
  148.     public function iso(x:Number, y:Number):Number {
  149.         // Take 4 nearest pixels to interpolate linearly.
  150.         // This gives us a smooth iso-function for which
  151.         // we can use a lower quality in MarchingSquares for
  152.         // the root finding.
  153.         var ix:int = int(x);
  154.         var iy:int = int(y);
  155.         //clamp in-case of numerical inaccuracies
  156.         if (ix < 0) ix = 0;
  157.         if (iy < 0) iy = 0;
  158.         if (ix >= bitmap.width)  ix = bitmap.width - 1;
  159.         if (iy >= bitmap.height) iy = bitmap.height - 1;
  160.  
  161.         // iso-function values at each pixel centre.
  162.         var a11:Number = alphaThreshold - (bitmap.getPixel32(ix, iy) >>> 24);
  163.         var a12:Number = alphaThreshold - (bitmap.getPixel32(ix + 1, iy) >>> 24);
  164.         var a21:Number = alphaThreshold - (bitmap.getPixel32(ix, iy + 1) >>> 24);
  165.         var a22:Number = alphaThreshold - (bitmap.getPixel32(ix + 1, iy + 1) >>> 24);
  166.  
  167.         // Bilinear interpolation for sample point (x,y)
  168.         var fx:Number = x - ix;
  169.         var fy:Number = y - iy;
  170.         return a11 * (1 - fx) * (1 - fy) + a12 * fx * (1 - fy) + a21 * (1 - fx) * fy + a22 * fx * fy;
  171.     }
  172. }
Advertisement
Add Comment
Please, Sign In to add comment