awayjs-display
Version:
AwayJS displaylist classes
343 lines (317 loc) • 14.8 kB
text/typescript
import {BitmapImage2D} from "awayjs-core/lib/image/BitmapImage2D";
import {Matrix} from "awayjs-core/lib/geom/Matrix";
import {CapsStyle} from "../draw/CapsStyle";
import {GradientType} from "../draw/GradientType";
import {GraphicsPathWinding} from "../draw/GraphicsPathWinding";
import {IGraphicsData} from "../draw/IGraphicsData";
import {InterpolationMethod} from "../draw/InterpolationMethod";
import {JointStyle} from "../draw/JointStyle";
import {LineScaleMode} from "../draw/LineScaleMode";
import {TriangleCulling} from "../draw/TriangleCulling";
import {SpreadMethod} from "../draw/SpreadMethod";
import {Style} from "../base/Style";
import {Graphics} from "../graphics/Graphics";
import {Graphic} from "../graphics/Graphic";
import {GraphicsPath} from "../draw/GraphicsPath";
import {GraphicsPathCommand} from "../draw/GraphicsPathCommand";
import {DefaultMaterialManager} from "../managers/DefaultMaterialManager";
import {MovieClip} from "../display/MovieClip";
import {Point} from "awayjs-core/lib/geom/Point";
import {AttributesBuffer} from "awayjs-core/lib/attributes/AttributesBuffer";
import {AttributesView} from "awayjs-core/lib/attributes/AttributesView";
import {Sprite} from "../display/Sprite";
import {Float3Attributes} from "awayjs-core/lib/attributes/Float3Attributes";
import {Float2Attributes} from "awayjs-core/lib/attributes/Float2Attributes";
import {MathConsts} from "awayjs-core/lib/geom/MathConsts";
import {GraphicsFactoryHelper} from "../draw/GraphicsFactoryHelper";
import {PartialImplementationError} from "awayjs-core/lib/errors/PartialImplementationError";
import {TriangleElements} from "../graphics/TriangleElements";
import {MaterialBase} from "../materials/MaterialBase";
/**
* The Graphics class contains a set of methods that you can use to create a
* vector shape. Display objects that support drawing include Sprite and Shape
* objects. Each of these classes includes a <code>graphics</code> property
* that is a Graphics object. The following are among those helper functions
* provided for ease of use: <code>drawRect()</code>,
* <code>drawRoundRect()</code>, <code>drawCircle()</code>, and
* <code>drawEllipse()</code>.
*
* <p>You cannot create a Graphics object directly from ActionScript code. If
* you call <code>new Graphics()</code>, an exception is thrown.</p>
*
* <p>The Graphics class is final; it cannot be subclassed.</p>
*/
export class GraphicsFactoryFills
{
public static draw_pathes(targetGraphic:Graphics) {
var len=targetGraphic.queued_fill_pathes.length;
var cp=0;
for(cp=0; cp<len; cp++){
var one_path:GraphicsPath = targetGraphic.queued_fill_pathes[cp];
//one_path.finalizeContour();
var contour_commands:Array<Array<number> > = one_path.commands;
var contour_data:Array<Array<number> > = one_path.data;
var commands:Array<number>;
var data:Array<number>;
var i:number = 0;
var k:number = 0;
var vert_cnt:number = 0;
var data_cnt:number = 0;
var draw_direction:number = 0;
var contours_vertices:Array<Array<number>> = [[]];
var final_vert_list:Array<number> = [];
var final_vert_cnt:number = 0;
var lastPoint:Point = new Point();
var last_dir_vec:Point=new Point();
var end_point:Point=new Point();
for (k = 0; k < contour_commands.length; k++) {
contours_vertices.push([]);
vert_cnt = 0;
data_cnt = 0;
commands = contour_commands[k];
data = contour_data[k];
draw_direction = 0;
var new_dir:number=0;
var new_dir_1:number=0;
var new_dir_2:number=0;
var dir_delta:number=0;
var last_direction:number=0;
var tmp_dir_point:Point=new Point();
if((data[0] != data[data.length-2]) || (data[1] != data[data.length-1])){
data[data.length]==data[0];
data[data.length]==data[1];
}
lastPoint.x = data[0];
lastPoint.y = data[1];
if(commands[1]==GraphicsPathCommand.LINE_TO){
last_dir_vec.x = data[2]-lastPoint.x;
last_dir_vec.y = data[3]-lastPoint.y;
}
else if(commands[1]==GraphicsPathCommand.CURVE_TO){
last_dir_vec.x = data[4]-lastPoint.x;
last_dir_vec.y = data[5]-lastPoint.y;
}
data_cnt=2;
last_dir_vec.normalize();
last_direction = Math.atan2(last_dir_vec.y, last_dir_vec.x) * MathConsts.RADIANS_TO_DEGREES;
for (i = 1; i < commands.length; i++) {
end_point = new Point(data[data_cnt++], data[data_cnt++]);
if (commands[i]==GraphicsPathCommand.MOVE_TO) {
console.log("ERROR ! ONLY THE FIRST COMMAND FOR A CONTOUR IS ALLOWED TO BE A 'MOVE_TO' COMMAND");
}
else if (commands[i]==GraphicsPathCommand.CURVE_TO) {
end_point = new Point(data[data_cnt++], data[data_cnt++]);
}
//get the directional vector and the direction for this segment
tmp_dir_point.x = end_point.x - lastPoint.x;
tmp_dir_point.y = end_point.y - lastPoint.y;
tmp_dir_point.normalize();
new_dir = Math.atan2(tmp_dir_point.y, tmp_dir_point.x) * MathConsts.RADIANS_TO_DEGREES;
// get the difference in angle to the last segment
dir_delta = new_dir - last_direction;
if(dir_delta>180){
dir_delta-=360;
}
if(dir_delta<-180){
dir_delta+=360;
}
draw_direction += dir_delta;
last_direction = new_dir;
lastPoint.x = end_point.x;
lastPoint.y = end_point.y;
}
lastPoint.x = data[0];
lastPoint.y = data[1];
data_cnt=2;
contours_vertices[contours_vertices.length - 1][vert_cnt++] = lastPoint.x;
contours_vertices[contours_vertices.length - 1][vert_cnt++] = lastPoint.y;
//console.log("Draw directions complete: "+draw_direction);
for (i = 1; i < commands.length; i++) {
switch (commands[i]) {
case GraphicsPathCommand.MOVE_TO:
console.log("ERROR ! ONLY THE FIRST COMMAND FOR A CONTOUR IS ALLOWED TO BE A 'MOVE_TO' COMMAND");
break;
case GraphicsPathCommand.LINE_TO:
lastPoint.x = data[data_cnt++];
lastPoint.y = data[data_cnt++];
contours_vertices[contours_vertices.length - 1][vert_cnt++] = lastPoint.x;
contours_vertices[contours_vertices.length - 1][vert_cnt++] = lastPoint.y;
break;
case GraphicsPathCommand.CURVE_TO:
var control_x:number = data[data_cnt++];
var control_y:number = data[data_cnt++];
var end_x:number = data[data_cnt++];
var end_y:number = data[data_cnt++];
tmp_dir_point.x = control_x - lastPoint.x;
tmp_dir_point.y = control_y - lastPoint.y;
tmp_dir_point.normalize();
new_dir_1 = Math.atan2(tmp_dir_point.y, tmp_dir_point.x) * MathConsts.RADIANS_TO_DEGREES;
tmp_dir_point.x = end_x - lastPoint.x;
tmp_dir_point.y = end_y - lastPoint.y;
tmp_dir_point.normalize();
new_dir_2 = Math.atan2(tmp_dir_point.y, tmp_dir_point.x) * MathConsts.RADIANS_TO_DEGREES;
// get the difference in angle to the last segment
var curve_direction:number = new_dir_2 - new_dir_1;
if(curve_direction>180){
curve_direction-=360;
}
if(curve_direction<-180){
curve_direction+=360;
}
if((curve_direction==0)&&(curve_direction==180)&&(curve_direction==-180)){
lastPoint.x = end_x;
lastPoint.y = end_y;
contours_vertices[contours_vertices.length - 1][vert_cnt++] = lastPoint.x;
contours_vertices[contours_vertices.length - 1][vert_cnt++] = lastPoint.y;
break;
}
var curve_attr_1 = -1;
if (draw_direction < 0) {
if (curve_direction > 0) {
//convex
//console.log("convex");
curve_attr_1 = 1;
contours_vertices[contours_vertices.length - 1][vert_cnt++] = control_x;
contours_vertices[contours_vertices.length - 1][vert_cnt++] = control_y;
}
contours_vertices[contours_vertices.length - 1][vert_cnt++] = end_x;
contours_vertices[contours_vertices.length - 1][vert_cnt++] = end_y;
}
else {
if (curve_direction < 0) {
//convex
//console.log("convex");
curve_attr_1 = 1;
contours_vertices[contours_vertices.length - 1][vert_cnt++] = control_x;
contours_vertices[contours_vertices.length - 1][vert_cnt++] = control_y;
}
contours_vertices[contours_vertices.length - 1][vert_cnt++] = end_x;
contours_vertices[contours_vertices.length - 1][vert_cnt++] = end_y;
}
if (GraphicsFactoryHelper.isClockWiseXY(end_x, end_y, control_x, control_y, lastPoint.x, lastPoint.y)) {
final_vert_list[final_vert_cnt++] = end_x;
final_vert_list[final_vert_cnt++] = end_y;
final_vert_list[final_vert_cnt++] = curve_attr_1;
final_vert_list[final_vert_cnt++] = 1.0;
final_vert_list[final_vert_cnt++] = 1.0;
final_vert_list[final_vert_cnt++] = 1.0;
final_vert_list[final_vert_cnt++] = 0.0;
final_vert_list[final_vert_cnt++] = control_x;
final_vert_list[final_vert_cnt++] = control_y;
final_vert_list[final_vert_cnt++] = curve_attr_1;
final_vert_list[final_vert_cnt++] = 0.5;
final_vert_list[final_vert_cnt++] = 0.0;
final_vert_list[final_vert_cnt++] = 1.0;
final_vert_list[final_vert_cnt++] = 0.0;
final_vert_list[final_vert_cnt++] = lastPoint.x;
final_vert_list[final_vert_cnt++] = lastPoint.y;
final_vert_list[final_vert_cnt++] = curve_attr_1;
final_vert_list[final_vert_cnt++] = 0.0;
final_vert_list[final_vert_cnt++] = 0.0;
final_vert_list[final_vert_cnt++] = 1.0;
final_vert_list[final_vert_cnt++] = 0.0;
}
else {
final_vert_list[final_vert_cnt++] = lastPoint.x;
final_vert_list[final_vert_cnt++] = lastPoint.y;
final_vert_list[final_vert_cnt++] = curve_attr_1;
final_vert_list[final_vert_cnt++] = 1.0;
final_vert_list[final_vert_cnt++] = 1.0;
final_vert_list[final_vert_cnt++] = 1.0;
final_vert_list[final_vert_cnt++] = 0.0;
final_vert_list[final_vert_cnt++] = control_x;
final_vert_list[final_vert_cnt++] = control_y;
final_vert_list[final_vert_cnt++] = curve_attr_1;
final_vert_list[final_vert_cnt++] = 0.5;
final_vert_list[final_vert_cnt++] = 0.0;
final_vert_list[final_vert_cnt++] = 1.0;
final_vert_list[final_vert_cnt++] = 0.0;
final_vert_list[final_vert_cnt++] = end_x;
final_vert_list[final_vert_cnt++] = end_y;
final_vert_list[final_vert_cnt++] = curve_attr_1;
final_vert_list[final_vert_cnt++] = 0.0;
final_vert_list[final_vert_cnt++] = 0.0;
final_vert_list[final_vert_cnt++] = 1.0;
final_vert_list[final_vert_cnt++] = 0.0;
}
lastPoint.x = end_x;
lastPoint.y = end_y;
break;
case GraphicsPathCommand.CUBIC_CURVE:
//todo
break;
}
}
}
var verts:Array<number> = [];
var all_verts:Array<Point> = [];
var vertIndicess:Array<number> = [];
var elems:Array<number> = [];
for (k = 0; k < contours_vertices.length; k++) {
var vertices = contours_vertices[k];
//for (i = 0; i < vertices.length / 2; ++i)
//console.log("vert collected" + i + " = " + vertices[i * 2] + " / " + vertices[i * 2 + 1]);
var verticesF32 = new Float32Array(vertices);
//var verticesF32 = new Float32Array([0,0, 100,0, 100,100, 0,100]);
//console.log("in vertices", vertices);
//var tess = new TESS();
if (GraphicsFactoryHelper._tess_obj == null) {
console.log("No libtess2 tesselator available.\nMake it available using Graphics._tess_obj=new TESS();");
return;
}
GraphicsFactoryHelper._tess_obj.addContour(verticesF32, 2, 8, vertices.length / 2);
}
GraphicsFactoryHelper._tess_obj.tesselate(0/*TESS.WINDING_ODD*/, 0/*TESS.ELEMENT_POLYGONS*/, 3, 2, null);
//console.log("out vertices", Graphics._tess_obj.getVertices());
verts = GraphicsFactoryHelper._tess_obj.getVertices();
elems = GraphicsFactoryHelper._tess_obj.getElements();
//console.log("out elements", Graphics._tess_obj.getElements());
var numVerts:number = verts.length / 2;
var numElems:number = elems.length / 3;
for (i = 0; i < numVerts; ++i)
all_verts.push(new Point(verts[i * 2], verts[i * 2 + 1]));
for (i = 0; i < numElems; ++i) {
var p1 = elems[i * 3];
var p2 = elems[i * 3 + 1];
var p3 = elems[i * 3 + 2];
final_vert_list[final_vert_cnt++] = all_verts[p3].x;
final_vert_list[final_vert_cnt++] = all_verts[p3].y;
final_vert_list[final_vert_cnt++] = 1;
final_vert_list[final_vert_cnt++] = 2.0;
final_vert_list[final_vert_cnt++] = 0.0;
final_vert_list[final_vert_cnt++] = 1.0;
final_vert_list[final_vert_cnt++] = 0.0;
final_vert_list[final_vert_cnt++] = all_verts[p2].x;
final_vert_list[final_vert_cnt++] = all_verts[p2].y;
final_vert_list[final_vert_cnt++] = 1;
final_vert_list[final_vert_cnt++] = 2.0;
final_vert_list[final_vert_cnt++] = 0.0;
final_vert_list[final_vert_cnt++] = 1.0;
final_vert_list[final_vert_cnt++] = 0.0;
final_vert_list[final_vert_cnt++] = all_verts[p1].x;
final_vert_list[final_vert_cnt++] = all_verts[p1].y;
final_vert_list[final_vert_cnt++] = 1;
final_vert_list[final_vert_cnt++] = 2.0;
final_vert_list[final_vert_cnt++] = 0.0;
final_vert_list[final_vert_cnt++] = 1.0;
final_vert_list[final_vert_cnt++] = 0.0;
}
//for (i = 0; i < final_vert_list.length/7; ++i)
// console.log("final verts "+i+" = "+final_vert_list[i*7]+" / "+final_vert_list[i*7+1]);
var attributesView:AttributesView = new AttributesView(Float32Array, 7);
attributesView.set(final_vert_list);
var attributesBuffer:AttributesBuffer = attributesView.attributesBuffer;
attributesView.dispose();
var elements:TriangleElements = new TriangleElements(attributesBuffer);
elements.setPositions(new Float2Attributes(attributesBuffer));
elements.setCustomAttributes("curves", new Float3Attributes(attributesBuffer));
elements.setUVs(new Float2Attributes(attributesBuffer));
var material:MaterialBase = DefaultMaterialManager.getDefaultMaterial();
material.bothSides = true;
material.useColorTransform = true;
material.curves = true;
var thisGraphic:Graphic=targetGraphic.addGraphic(elements, material);
}
targetGraphic.queued_fill_pathes.length=0;
}
}