// ================================================================================================= // // Starling Framework // Copyright Gamua GmbH. All Rights Reserved. // // This program is free software. You can redistribute and/or modify it // in accordance with the terms of the accompanying license agreement. // // ================================================================================================= package starling.display { import flash.geom.Point; import flash.geom.Rectangle; import starling.core.starling_internal; import starling.geom.Polygon; import starling.rendering.IndexData; import starling.rendering.Painter; import starling.rendering.VertexData; import starling.rendering.VertexDataFormat; import starling.styles.MeshStyle; import starling.textures.Texture; import starling.utils.MatrixUtil; import starling.utils.MeshUtil; import starling.utils.execute; use namespace starling_internal; /** The base class for all tangible (non-container) display objects, spawned up by a number * of triangles. * *
Since Starling uses Stage3D for rendering, all rendered objects must be constructed * from triangles. A mesh stores the information of its triangles through VertexData and * IndexData structures. The default format stores position, color and texture coordinates * for each vertex.
* *How a mesh is rendered depends on its style. Per default, this is an instance
* of the MeshStyle base class; however, subclasses may extend its behavior
* to add support for color transformations, normal mapping, etc.
MeshStyle will be created
* for you. Note that the format of the vertex data will be matched to the
* given style right away. */
public function Mesh(vertexData:VertexData, indexData:IndexData, style:MeshStyle=null)
{
if (vertexData == null) throw new ArgumentError("VertexData must not be null");
if (indexData == null) throw new ArgumentError("IndexData must not be null");
_vertexData = vertexData;
_indexData = indexData;
setStyle(style, false);
}
/** @inheritDoc */
override public function dispose():void
{
_vertexData.clear();
_indexData.clear();
super.dispose();
}
/** @inheritDoc */
override public function hitTest(localPoint:Point):DisplayObject
{
if (!visible || !touchable || !hitTestMask(localPoint)) return null;
else return MeshUtil.containsPoint(_vertexData, _indexData, localPoint) ? this : null;
}
/** @inheritDoc */
override public function getBounds(targetSpace:DisplayObject, out:Rectangle=null):Rectangle
{
return MeshUtil.calculateBounds(_vertexData, this, targetSpace, out);
}
/** @inheritDoc */
override public function render(painter:Painter):void
{
if (_pixelSnapping)
MatrixUtil.snapToPixels(painter.state.modelviewMatrix, painter.pixelSize);
painter.batchMesh(this);
}
/** Sets the style that is used to render the mesh. Styles (which are always subclasses of
* MeshStyle) provide a means to completely modify the way a mesh is rendered.
* For example, they may add support for color transformations or normal mapping.
*
* When assigning a new style, the vertex format will be changed to fit it.
* Do not use the same style instance on multiple objects! Instead, make use of
* style.clone() to assign an identical style to multiple meshes.
null, the default
* style will be created.
* @param mergeWithPredecessor if enabled, all attributes of the previous style will be
* be copied to the new one, if possible.
* @see #defaultStyle
* @see #defaultStyleFactory
*/
public function setStyle(meshStyle:MeshStyle=null, mergeWithPredecessor:Boolean=true):void
{
if (meshStyle == null) meshStyle = createDefaultMeshStyle();
else if (meshStyle == _style) return;
else if (meshStyle.target) meshStyle.target.setStyle();
if (_style)
{
if (mergeWithPredecessor) meshStyle.copyFrom(_style);
_style.setTarget(null);
}
_style = meshStyle;
_style.setTarget(this, _vertexData, _indexData);
}
private function createDefaultMeshStyle():MeshStyle
{
var meshStyle:MeshStyle;
if (sDefaultStyleFactory != null)
{
if (sDefaultStyleFactory.length == 0) meshStyle = sDefaultStyleFactory();
else meshStyle = sDefaultStyleFactory(this);
}
if (meshStyle == null)
meshStyle = new sDefaultStyle() as MeshStyle;
return meshStyle;
}
/** This method is called whenever the mesh's vertex data was changed.
* The base implementation simply forwards to setRequiresRedraw. */
public function setVertexDataChanged():void
{
setRequiresRedraw();
}
/** This method is called whenever the mesh's index data was changed.
* The base implementation simply forwards to setRequiresRedraw. */
public function setIndexDataChanged():void
{
setRequiresRedraw();
}
// vertex manipulation
/** The position of the vertex at the specified index, in the mesh's local coordinate
* system.
*
* Only modify the position of a vertex if you know exactly what you're doing, as
* some classes might not work correctly when their vertices are moved. E.g. the
* Quad class expects its vertices to spawn up a perfectly rectangular
* area; some of its optimized methods won't work correctly if that premise is no longer
* fulfilled or the original bounds change.
setRequiresRedraw. */
protected function get vertexData():VertexData { return _vertexData; }
/** The index data describing how the vertices are interconnected.
* Any change requires a call to setRequiresRedraw. */
protected function get indexData():IndexData { return _indexData; }
/** The style that is used to render the mesh. Styles (which are always subclasses of
* MeshStyle) provide a means to completely modify the way a mesh is rendered.
* For example, they may add support for color transformations or normal mapping.
*
* The setter will simply forward the assignee to setStyle(value).
null, if there is none). */
public function get texture():Texture { return _style.texture; }
public function set texture(value:Texture):void { _style.texture = value; }
/** Changes the color of all vertices to the same value.
* The getter simply returns the color of the first vertex. */
public function get color():uint { return _style.color; }
public function set color(value:uint):void { _style.color = value; }
/** The smoothing filter that is used for the texture.
* @default bilinear */
public function get textureSmoothing():String { return _style.textureSmoothing; }
public function set textureSmoothing(value:String):void { _style.textureSmoothing = value; }
/** Indicates if pixels at the edges will be repeated or clamped. Only works for
* power-of-two textures; for a solution that works with all kinds of textures,
* see Image.tileGrid. @default false */
public function get textureRepeat():Boolean { return _style.textureRepeat; }
public function set textureRepeat(value:Boolean):void { _style.textureRepeat = value; }
/** Controls whether or not the instance snaps to the nearest pixel. This can prevent the
* object from looking blurry when it's not exactly aligned with the pixels of the screen.
* @default false */
public function get pixelSnapping():Boolean { return _pixelSnapping; }
public function set pixelSnapping(value:Boolean):void { _pixelSnapping = value; }
/** The total number of vertices in the mesh. */
public function get numVertices():int { return _vertexData.numVertices; }
/** The total number of indices referencing vertices. */
public function get numIndices():int { return _indexData.numIndices; }
/** The total number of triangles in this mesh.
* (In other words: the number of indices divided by three.) */
public function get numTriangles():int { return _indexData.numTriangles; }
/** The format used to store the vertices. */
public function get vertexFormat():VertexDataFormat { return _style.vertexFormat; }
// static properties
/** The default style used for meshes if no specific style is provided. The default is
* starling.rendering.MeshStyle, and any assigned class must be a subclass
* of the same. */
public static function get defaultStyle():Class { return sDefaultStyle; }
public static function set defaultStyle(value:Class):void
{
sDefaultStyle = value;
}
/** A factory method that is used to create the 'MeshStyle' for a mesh if no specific
* style is provided. That's useful if you are creating a hierarchy of objects, all
* of which need to have a certain style. Different to the defaultStyle
* property, this method allows plugging in custom logic and passing arguments to the
* constructor. Return null to fall back to the default behavior (i.e.
* to instantiate defaultStyle). The mesh-parameter is optional
* and may be omitted.
*
*