Skip to content

Commit

Permalink
Canvas: Replace Vector with Array
Browse files Browse the repository at this point in the history
Moar speed!
  • Loading branch information
Dimensionscape committed Jul 10, 2024
1 parent 1163b16 commit 53bbeec
Show file tree
Hide file tree
Showing 2 changed files with 1,352 additions and 1,347 deletions.
208 changes: 103 additions & 105 deletions src/starling/display/Canvas.hx
Original file line number Diff line number Diff line change
Expand Up @@ -7,72 +7,72 @@
// in accordance with the terms of the accompanying license agreement.
//
// =================================================================================================

package starling.display;

import openfl.geom.Point;
import openfl.Vector;

import openfl.Array;
import starling.geom.Polygon;
import starling.rendering.IndexData;
import starling.rendering.VertexData;
import starling.utils.ArrayUtil;

/** A display object supporting basic vector drawing functionality. In its current state,
/** A display object supporting basic Array drawing functionality. In its current state,
* the main use of this class is to provide a range of forms that can be used as masks.
*/
class Canvas extends DisplayObjectContainer
{
@:noCompletion private var __polygons:Vector<Polygon>;
@:noCompletion private var __fillColor:UInt;
@:noCompletion private var __fillAlpha:Float;

/** Creates a new (empty) Canvas. Call one or more of the 'draw' methods to add content. */
public function new()
{
super();

__polygons = new Vector<Polygon>();
__fillColor = 0xffffff;
__fillAlpha = 1.0;
touchGroup = true;
}

/** @inheritDoc */
public override function dispose():Void
{
__polygons.length = 0;
super.dispose();
}

/** @inheritDoc */
public override function hitTest(localPoint:Point):DisplayObject
{
if (!visible || !touchable || !hitTestMask(localPoint)) return null;

// we could also use the standard hit test implementation, but the polygon class can
// do that much more efficiently (it contains custom implementations for circles, etc).

var len:Int = __polygons.length;
for (i in 0...len)
if (__polygons[i].containsPoint(localPoint)) return this;

return null;
}

/** Draws a circle.
class Canvas extends DisplayObjectContainer {
@:noCompletion private var __polygons:Array<Polygon>;
@:noCompletion private var __fillColor:UInt;
@:noCompletion private var __fillAlpha:Float;

/** Creates a new (empty) Canvas. Call one or more of the 'draw' methods to add content. */
public function new() {
super();

__polygons = new Array<Polygon>();
__fillColor = 0xffffff;
__fillAlpha = 1.0;
touchGroup = true;
}

/** @inheritDoc */
public override function dispose():Void {
#if (haxe_ver >= 4.0)
__polygons.resize(0);
#else
ArrayUtil.resize(__polygons, 0);
#end
super.dispose();
}

/** @inheritDoc */
public override function hitTest(localPoint:Point):DisplayObject {
if (!visible || !touchable || !hitTestMask(localPoint))
return null;

// we could also use the standard hit test implementation, but the polygon class can
// do that much more efficiently (it contains custom implementations for circles, etc).

var len:Int = __polygons.length;
for (i in 0...len)
if (__polygons[i].containsPoint(localPoint))
return this;

return null;
}

/** Draws a circle.
*
* @param x x-coordinate of center point
* @param y y-coordinate of center point
* @param radius radius of circle
* @param numSides the number of lines used to draw the circle.
* If you don't pass anything, Starling will pick a reasonable value.
*/
public function drawCircle(x:Float, y:Float, radius:Float, numSides:Int = -1):Void
{
__appendPolygon(Polygon.createCircle(x, y, radius, numSides));
}
public function drawCircle(x:Float, y:Float, radius:Float, numSides:Int = -1):Void {
__appendPolygon(Polygon.createCircle(x, y, radius, numSides));
}

/** Draws an ellipse.
/** Draws an ellipse.
*
* @param x x-coordinate of bounding box
* @param y y-coordinate of bounding box
Expand All @@ -81,59 +81,57 @@ class Canvas extends DisplayObjectContainer
* @param numSides the number of lines used to draw the ellipse.
* If you don't pass anything, Starling will pick a reasonable value.
*/
public function drawEllipse(x:Float, y:Float, width:Float, height:Float, numSides:Int = -1):Void
{
var radiusX:Float = width / 2.0;
var radiusY:Float = height / 2.0;

__appendPolygon(Polygon.createEllipse(x + radiusX, y + radiusY, radiusX, radiusY, numSides));
}

/** Draws a rectangle. */
public function drawRectangle(x:Float, y:Float, width:Float, height:Float):Void
{
__appendPolygon(Polygon.createRectangle(x, y, width, height));
}

/** Draws an arbitrary polygon. */
public function drawPolygon(polygon:Polygon):Void
{
__appendPolygon(polygon);
}

/** Specifies a simple one-color fill that subsequent calls to drawing methods
* (such as <code>drawCircle()</code>) will use. */
public function beginFill(color:UInt=0xffffff, alpha:Float=1.0):Void
{
__fillColor = color;
__fillAlpha = alpha;
}

/** Resets the color to 'white' and alpha to '1'. */
public function endFill():Void
{
__fillColor = 0xffffff;
__fillAlpha = 1.0;
}

/** Removes all existing vertices. */
public function clear():Void
{
removeChildren(0, -1, true);
__polygons.length = 0;
}

@:noCompletion private function __appendPolygon(polygon:Polygon):Void
{
var vertexData:VertexData = new VertexData();
var indexData:IndexData = new IndexData(polygon.numTriangles * 3);

polygon.triangulate(indexData);
polygon.copyToVertexData(vertexData);

vertexData.colorize("color", __fillColor, __fillAlpha);

addChild(new Mesh(vertexData, indexData));
__polygons[__polygons.length] = polygon;
}
}
public function drawEllipse(x:Float, y:Float, width:Float, height:Float, numSides:Int = -1):Void {
var radiusX:Float = width / 2.0;
var radiusY:Float = height / 2.0;

__appendPolygon(Polygon.createEllipse(x + radiusX, y + radiusY, radiusX, radiusY, numSides));
}

/** Draws a rectangle. */
public function drawRectangle(x:Float, y:Float, width:Float, height:Float):Void {
__appendPolygon(Polygon.createRectangle(x, y, width, height));
}

/** Draws an arbitrary polygon. */
public function drawPolygon(polygon:Polygon):Void {
__appendPolygon(polygon);
}

/** Specifies a simple one-color fill that subsequent calls to drawing methods
* (such as <code>drawCircle()</code>) will use. */
public function beginFill(color:UInt = 0xffffff, alpha:Float = 1.0):Void {
__fillColor = color;
__fillAlpha = alpha;
}

/** Resets the color to 'white' and alpha to '1'. */
public function endFill():Void {
__fillColor = 0xffffff;
__fillAlpha = 1.0;
}

/** Removes all existing vertices. */
public function clear():Void {
removeChildren(0, -1, true);

#if (haxe_ver >= 4.0)
__polygons.resize(0);
#else
ArrayUtil.resize(__polygons, 0);
#end
}

@:noCompletion private function __appendPolygon(polygon:Polygon):Void {
var vertexData:VertexData = new VertexData();
var indexData:IndexData = new IndexData(polygon.numTriangles * 3);

polygon.triangulate(indexData);
polygon.copyToVertexData(vertexData);

vertexData.colorize("color", __fillColor, __fillAlpha);

addChild(new Mesh(vertexData, indexData));
__polygons[__polygons.length] = polygon;
}
}
Loading

0 comments on commit 53bbeec

Please sign in to comment.