awayjs-display
Version:
AwayJS displaylist classes
583 lines (505 loc) • 26.6 kB
text/typescript
import BitmapImage2D from "awayjs-core/lib/image/BitmapImage2D";
import Matrix from "awayjs-core/lib/geom/Matrix";
import MathConsts from "awayjs-core/lib/geom/MathConsts";
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 Graphics from "../graphics/Graphics";
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 GraphicsFactoryHelper from "../draw/GraphicsFactoryHelper";
import GraphicsStrokeStyle from "../draw/GraphicsStrokeStyle";
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>
*/
class GraphicsFactoryStrokes
{
public static draw_pathes(targetGraphic:Graphics){
var len=targetGraphic.queued_stroke_pathes.length;
var contour_commands:Array<Array<number> >;
var contour_data:Array<Array<number> >;
var strokeStyle:GraphicsStrokeStyle;
var one_path:GraphicsPath;
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 final_vert_list:Array<number> = [];
var final_vert_cnt:number=0;
var lastPoint:Point=new Point();
var start_point:Point=new Point();
var end_point:Point=new Point();
var start_left:Point=new Point();
var start_right:Point=new Point();
var ctr_left:Point=new Point();
var ctr_right:Point=new Point();
var ctr_left2:Point=new Point();
var ctr_right2:Point=new Point();
var end_left:Point=new Point();
var end_right:Point=new Point();
var tmp_point:Point=new Point();
var tmp_point2:Point=new Point();
var tmp_point3:Point=new Point();
var closed:boolean=false;
var last_dir_vec:Point=new Point();
var cp=0;
for(cp=0; cp<len; cp++){
one_path = targetGraphic.queued_stroke_pathes[cp];
contour_commands = one_path.commands;
contour_data = one_path.data;
strokeStyle = one_path.stroke();
var tessVerts:Array<number>=[];
for(k=0; k<contour_commands.length; k++) {
commands = contour_commands[k];
data = contour_data[k];
vert_cnt = 0;
data_cnt = 0;
var new_dir:number=0;
var dir_delta:number=0;
var last_direction:number=0;
var tmp_dir_point:Point=new Point();
closed = true;
if((data[0] != data[data.length-2]) || (data[1] != data[data.length-1]))
closed = false;
else{
last_dir_vec.x = data[data.length-2]-data[data.length-4];
last_dir_vec.y = data[data.length-1]-data[data.length-3];
last_dir_vec.normalize();
last_direction = Math.atan2(last_dir_vec.y, last_dir_vec.x) * MathConsts.RADIANS_TO_DEGREES;
//console.log("Path is closed, we set initial direction: "+last_direction);
}
data_cnt=0;
lastPoint.x=data[data_cnt++];
lastPoint.y=data[data_cnt++];
var new_cmds:Array<number>=[];
var new_pnts:Array<Point>=[];
var new_cmds_cnt=0;
var new_pnts_cnt=0;
var prev_normal:Point = new Point();
var le_point:Point = new Point();
var curve_end_point:Point = new Point();
var ri_point:Point = new Point();
var ctr_point:Point = new Point();
prev_normal.x = -1*last_dir_vec.y;
prev_normal.y = last_dir_vec.x;
for (i = 1; i < commands.length; i++) {
if (commands[i]==GraphicsPathCommand.MOVE_TO) {
console.log("ERROR ! ONLY THE FIRST COMMAND FOR A CONTOUR IS ALLOWED TO BE A 'MOVE_TO' COMMAND");
continue;
}
//console.log("");
//console.log("segment "+i+"lastPoint x = "+lastPoint.x+" y = "+lastPoint.y)
end_point = new Point(data[data_cnt++], data[data_cnt++]);
//console.log("segment "+i+"end_point x = "+end_point.x+" y = "+end_point.y)
if (commands[i]==GraphicsPathCommand.CURVE_TO) {
curve_end_point = new Point(data[data_cnt++], data[data_cnt++]);
//console.log("segment "+i+"curve_end_point x = "+curve_end_point.x+" y = "+curve_end_point.y)
}
//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;
}
last_direction = new_dir;
//console.log("segment "+i+" direction: "+dir_delta);
// rotate direction around 90 degree
tmp_point.x = -1 * tmp_dir_point.y;
tmp_point.y = tmp_dir_point.x;
ri_point = new Point(lastPoint.x + (tmp_point.x * strokeStyle.half_thickness), lastPoint.y + (tmp_point.y * strokeStyle.half_thickness));
le_point = new Point(lastPoint.x - (tmp_point.x * strokeStyle.half_thickness), lastPoint.y - (tmp_point.y * strokeStyle.half_thickness));
var add_segment:boolean=false;
// check if this is the first segment, and the path is not closed
// in this case, we can just set the points to the contour points
if((i==1)&&(!closed)){
//console.log("segment "+i+"Path is not closed, we can just add the first segment")
add_segment=true;
}
else{
// we need to figure out if we need to add a joint or not
if ((dir_delta==0)||(dir_delta==180)){
// check if this and the prev segment was a line. if yes, than they can be merged
if ((i!=1) && (commands[i]== GraphicsPathCommand.LINE_TO) && (new_cmds[new_cmds.length-1]==GraphicsPathCommand.LINE_TO)){
//console.log("straight line can be merged in prev straight line");
add_segment=false;
}
// if not we can just add the contour points
else{
add_segment=true;
}
}
if (dir_delta==180){
console.log("path goes straight back (180�). DO we need to handle this edge case different ? !")
}
else if (dir_delta!=0) {
add_segment=true;
var half_angle:number=(180-(dir_delta));
if(dir_delta<0){
half_angle=(-180-(dir_delta));
}
half_angle= half_angle * -0.5 * MathConsts.DEGREES_TO_RADIANS;
var distance:number=strokeStyle.half_thickness / Math.sin(half_angle);
tmp_point2.x = tmp_dir_point.x * Math.cos(half_angle) + tmp_dir_point.y * Math.sin(half_angle);
tmp_point2.y = tmp_dir_point.y * Math.cos(half_angle) - tmp_dir_point.x * Math.sin(half_angle);
tmp_point2.normalize();
var merged_pnt_ri:Point = new Point(lastPoint.x - (tmp_point2.x * distance), lastPoint.y - (tmp_point2.y * distance));
var merged_pnt_le:Point = new Point(lastPoint.x + (tmp_point2.x * distance), lastPoint.y + (tmp_point2.y * distance));
if (dir_delta > 0){
ri_point = merged_pnt_ri;
var contour_le:Point = new Point(lastPoint.x - (tmp_point.x * strokeStyle.half_thickness), lastPoint.y - (tmp_point.y * strokeStyle.half_thickness));
var contour_prev_le:Point = new Point(lastPoint.x - (prev_normal.x * strokeStyle.half_thickness), lastPoint.y - (prev_normal.y * strokeStyle.half_thickness));
le_point=contour_le;
}
else{
le_point = merged_pnt_le;
var contour_ri:Point = new Point(lastPoint.x + (tmp_point.x * strokeStyle.half_thickness), lastPoint.y + (tmp_point.y * strokeStyle.half_thickness));
var contour_prev_ri:Point = new Point(lastPoint.x + (prev_normal.x * strokeStyle.half_thickness), lastPoint.y + (prev_normal.y * strokeStyle.half_thickness));
ri_point=contour_ri;
}
var addJoints:boolean=true;
if (strokeStyle.jointstyle==JointStyle.MITER){
var distance_miter:number = (Math.sqrt((distance*distance)-(strokeStyle.half_thickness*strokeStyle.half_thickness))/strokeStyle.half_thickness);
if(distance_miter<=strokeStyle.miter_limit){
addJoints=false;
ri_point = merged_pnt_ri;
le_point = merged_pnt_le;
}
else{
if (dir_delta > 0){
contour_le.x = contour_le.x-(tmp_dir_point.x*(strokeStyle.miter_limit*strokeStyle.half_thickness));
contour_le.y = contour_le.y-(tmp_dir_point.y*(strokeStyle.miter_limit*strokeStyle.half_thickness));
tmp_point3.x=prev_normal.y*-1;
tmp_point3.y=prev_normal.x;
contour_prev_le.x = contour_prev_le.x-(tmp_point3.x*(strokeStyle.miter_limit*strokeStyle.half_thickness));
contour_prev_le.y = contour_prev_le.y-(tmp_point3.y*(strokeStyle.miter_limit*strokeStyle.half_thickness));
}
else{
contour_ri.x = contour_ri.x-(tmp_dir_point.x*(strokeStyle.miter_limit*strokeStyle.half_thickness));
contour_ri.y = contour_ri.y-(tmp_dir_point.y*(strokeStyle.miter_limit*strokeStyle.half_thickness));
tmp_point3.x=prev_normal.y*-1;
tmp_point3.y=prev_normal.x;
contour_prev_ri.x = contour_prev_ri.x-(tmp_point3.x*(strokeStyle.miter_limit*strokeStyle.half_thickness));
contour_prev_ri.y = contour_prev_ri.y-(tmp_point3.y*(strokeStyle.miter_limit*strokeStyle.half_thickness));
}
}
}
if(addJoints) {
new_cmds[new_cmds_cnt++]=(strokeStyle.jointstyle!=JointStyle.ROUND)? GraphicsPathCommand.BUILD_JOINT : GraphicsPathCommand.BUILD_ROUND_JOINT;
if (dir_delta > 0) {
new_pnts[new_pnts_cnt++] = merged_pnt_ri;
new_pnts[new_pnts_cnt++] = contour_prev_le;
new_pnts[new_pnts_cnt++] = contour_le;
}
else {
new_pnts[new_pnts_cnt++] = contour_prev_ri;
new_pnts[new_pnts_cnt++] = merged_pnt_le;
new_pnts[new_pnts_cnt++] = contour_ri;
}
if(strokeStyle.jointstyle==JointStyle.ROUND){
new_pnts[new_pnts_cnt++] = new Point(lastPoint.x - (tmp_point2.x * Math.abs(distance)), lastPoint.y - (tmp_point2.y * Math.abs(distance)));
if (dir_delta > 0) {
new_pnts[new_pnts_cnt++] = contour_prev_le;
new_pnts[new_pnts_cnt++] = contour_le;
}
else {
new_pnts[new_pnts_cnt++] = contour_prev_ri;
new_pnts[new_pnts_cnt++] = contour_ri;
}
}
}
}
}
prev_normal.x = tmp_point.x;
prev_normal.y = tmp_point.y;
if(add_segment){
if (commands[i]== GraphicsPathCommand.LINE_TO) {
new_cmds[new_cmds_cnt++] = GraphicsPathCommand.LINE_TO;
new_pnts[new_pnts_cnt++] = ri_point;
new_pnts[new_pnts_cnt++] = le_point;
}
else if (commands[i]== GraphicsPathCommand.CURVE_TO) {
tmp_dir_point.x = curve_end_point.x - end_point.x;
tmp_dir_point.y = curve_end_point.y - end_point.y;
tmp_dir_point.normalize();
new_dir = Math.atan2(tmp_dir_point.y, tmp_dir_point.x) * MathConsts.RADIANS_TO_DEGREES;
dir_delta = new_dir - last_direction;
last_direction = new_dir;
tmp_point.x = -1 * tmp_dir_point.y;
tmp_point.y = tmp_dir_point.x;
if((dir_delta!=0)&&(dir_delta!=180)){
new_cmds[new_cmds_cnt++] = GraphicsPathCommand.CURVE_TO;
new_pnts[new_pnts_cnt++] = ri_point;
new_pnts[new_pnts_cnt++] = le_point;
new_pnts[new_pnts_cnt++] = new Point(lastPoint.x, lastPoint.y);
new_pnts[new_pnts_cnt++] = new Point(end_point.x, end_point.y);
new_pnts[new_pnts_cnt++] = curve_end_point;
}
else{
new_cmds[new_cmds_cnt++] = GraphicsPathCommand.LINE_TO;
new_pnts[new_pnts_cnt++] = ri_point;
new_pnts[new_pnts_cnt++] = le_point;
}
prev_normal.x = tmp_point.x;
prev_normal.y = tmp_point.y;
lastPoint = curve_end_point;
}
}
if (commands[i]== GraphicsPathCommand.LINE_TO) {
lastPoint = end_point;
}
if(i==commands.length-1){
if (!closed) {
new_cmds[new_cmds_cnt++] = GraphicsPathCommand.NO_OP;
new_pnts[new_pnts_cnt++] = new Point(lastPoint.x + (tmp_point.x * strokeStyle.half_thickness), lastPoint.y + (tmp_point.y * strokeStyle.half_thickness));
new_pnts[new_pnts_cnt++] = new Point(lastPoint.x - (tmp_point.x * strokeStyle.half_thickness), lastPoint.y - (tmp_point.y * strokeStyle.half_thickness));
}
else{
new_cmds[new_cmds_cnt++] = GraphicsPathCommand.NO_OP;
new_pnts[new_pnts_cnt++] = new_pnts[0];
new_pnts[new_pnts_cnt++] = new_pnts[1];
}
}
}
// first we draw all the curves:
new_cmds_cnt=0;
new_pnts_cnt=0;
for (i = 0; i < new_cmds.length; i++) {
if(new_cmds[i]==GraphicsPathCommand.LINE_TO){
new_pnts_cnt+=2;
}
else if(new_cmds[i]==GraphicsPathCommand.CURVE_TO){
start_right = new_pnts[new_pnts_cnt++];
start_left = new_pnts[new_pnts_cnt++];
start_point = new_pnts[new_pnts_cnt++];
ctr_point = new_pnts[new_pnts_cnt++];
end_point = new_pnts[new_pnts_cnt++];
end_right = new_pnts[new_pnts_cnt];
end_left = new_pnts[new_pnts_cnt+1];
// get the directional vector for the first part of the curve
tmp_dir_point.x = ctr_point.x - start_point.x;
tmp_dir_point.y = ctr_point.y - start_point.y;
tmp_point3.x = ctr_point.x - start_point.x;
tmp_point3.y = ctr_point.y - start_point.y;
var length1:number =tmp_point3.length;
tmp_dir_point.normalize();
// get the directional vector for the second part of the curve
tmp_point2.x = end_point.x - ctr_point.x;
tmp_point2.y = end_point.y - ctr_point.y;
var length2:number =tmp_point2.length;
tmp_point2.normalize();
var length_calc:number = 0.5 - ((length2-length1)/length1)*0.5;
if(length1>length2){
length_calc = 0.5 + ((length1-length2)/length2)*0.5;
}
// get angle to positive x-axis for both dir-vectors, than get the difference between those
var angle_1:number=Math.atan2(tmp_dir_point.y, tmp_dir_point.x) * MathConsts.RADIANS_TO_DEGREES;
var angle_2:number=Math.atan2(tmp_point2.y, tmp_point2.x) * MathConsts.RADIANS_TO_DEGREES;
dir_delta=angle_2-angle_1;
if(dir_delta>180){
dir_delta-=360;
}
if(dir_delta<-180){
dir_delta+=360;
}
if(dir_delta==0){
console.log("This is not a curve, we can just draw it like a straight line");
}
//console.log("segment : '"+i+"' direction:"+dir_delta);
var dirNumber:number=1;
if(dir_delta<0){
dirNumber=-1;
}
var half_angle:number=dir_delta*0.5*MathConsts.DEGREES_TO_RADIANS;
var lengthpos:number=Math.abs(length1*Math.sin(half_angle));
var distance:number=strokeStyle.half_thickness / Math.sin(half_angle);
tmp_point3.x = tmp_point2.x * Math.cos(half_angle) + tmp_point2.y * Math.sin(half_angle);
tmp_point3.y = tmp_point2.y * Math.cos(half_angle) - tmp_point2.x * Math.sin(half_angle);
tmp_point3.normalize();
var merged_pnt_ri:Point = new Point(ctr_point.x - (tmp_point3.x * distance), ctr_point.y - (tmp_point3.y * distance));
var merged_pnt_le:Point = new Point(ctr_point.x + (tmp_point3.x * distance), ctr_point.y + (tmp_point3.y * distance));
var curve_x:number = GraphicsFactoryHelper.getQuadricBezierPosition(0.5, start_point.x, ctr_point.x, end_point.x);
var curve_y:number = GraphicsFactoryHelper.getQuadricBezierPosition(0.5, start_point.y, ctr_point.y, end_point.y);
var curve_2x:number = GraphicsFactoryHelper.getQuadricBezierPosition(0.501, start_point.x, ctr_point.x, end_point.x);
var curve_2y:number = GraphicsFactoryHelper.getQuadricBezierPosition(0.501, start_point.y, ctr_point.y, end_point.y);
tmp_point3.x = -1*(curve_y - curve_2y);
tmp_point3.y = curve_x - curve_2x;
tmp_point3.normalize();
//GraphicsFactoryHelper.drawPoint(curve_x,curve_y, final_vert_list);
// move the point on the curve to use correct thickness
ctr_right.x = curve_x +(dirNumber * tmp_point3.x * strokeStyle.half_thickness);
ctr_right.y = curve_y +(dirNumber * tmp_point3.y * strokeStyle.half_thickness);
ctr_left.x = curve_x -(dirNumber * tmp_point3.x * strokeStyle.half_thickness);
ctr_left.y = curve_y -(dirNumber * tmp_point3.y * strokeStyle.half_thickness);
//GraphicsFactoryHelper.drawPoint(ctr_right.x, ctr_right.y , final_vert_list);
//GraphicsFactoryHelper.drawPoint(ctr_left.x, ctr_left.y , final_vert_list);
// calculate the actual controlpoints
ctr_right.x = ctr_right.x * 2 - start_right.x/2 - end_right.x/2;
ctr_right.y = ctr_right.y * 2 - start_right.y/2 - end_right.y/2;
ctr_left.x = ctr_left.x * 2 - start_left.x/2 - end_left.x/2;
ctr_left.y = ctr_left.y * 2 - start_left.y/2 - end_left.y/2;
//ctr_right=merged_pnt_ri;
//ctr_left=merged_pnt_le;
/*
// controlpoints version2:
tmp_dir_point.x = start_left.x-start_right.x;
tmp_dir_point.y = start_left.y-start_right.y;
tmp_point2.x = end_left.x-end_right.x;
tmp_point2.y = end_left.y-end_right.y;
ctr_right.x = ctr_point.x-(tmp_dir_point.x/2);
ctr_right.y = ctr_point.y-(tmp_dir_point.y/2);
var new_end_ri:Point = new Point(end_point.x+(tmp_dir_point.x/2), end_point.y+(tmp_dir_point.y/2));
ctr_left.x = ctr_point.x+(tmp_dir_point.x/2);
ctr_left.y = ctr_point.y+(tmp_dir_point.y/2);
var new_end_le:Point = new Point(end_point.x-(tmp_dir_point.x/2), end_point.y-(tmp_dir_point.y/2));
*/
/*
GraphicsFactoryHelper.drawPoint(start_right.x, start_right.y , final_vert_list);
GraphicsFactoryHelper.drawPoint(start_left.x, start_left.y , final_vert_list);
GraphicsFactoryHelper.drawPoint(ctr_right.x, ctr_right.y , final_vert_list);
GraphicsFactoryHelper.drawPoint(ctr_left.x, ctr_left.y , final_vert_list);
GraphicsFactoryHelper.drawPoint(end_right.x, end_right.y , final_vert_list);
GraphicsFactoryHelper.drawPoint(end_left.x, end_left.y , final_vert_list);
*/
var subdivided:Array<number> = [];
var subdivided2:Array<number> = [];
GraphicsFactoryHelper.subdivideCurve(start_right.x, start_right.y, ctr_right.x, ctr_right.y, end_right.x, end_right.y, start_left.x, start_left.y, ctr_left.x, ctr_left.y, end_left.x, end_left.y, subdivided, subdivided2);
if(dir_delta>0) {
for (var sc:number = 0; sc < subdivided.length / 6; sc++) {
// right curved
// concave curves:
GraphicsFactoryHelper.addTriangle(subdivided[sc * 6], subdivided[sc * 6 + 1], subdivided[sc * 6 + 2], subdivided[sc * 6 + 3], subdivided[sc * 6 + 4], subdivided[sc * 6 + 5], 1, final_vert_list);
// fills
GraphicsFactoryHelper.addTriangle(subdivided2[sc * 6], subdivided2[sc * 6 + 1], subdivided[sc * 6], subdivided[sc * 6 + 1], subdivided[sc * 6 + 2], subdivided[sc * 6 + 3], 0, final_vert_list);
GraphicsFactoryHelper.addTriangle(subdivided2[sc * 6], subdivided2[sc * 6 + 1], subdivided2[sc * 6 + 4], subdivided2[sc * 6 + 5], subdivided[sc * 6 + 2], subdivided[sc * 6 + 3], 0, final_vert_list);
GraphicsFactoryHelper.addTriangle(subdivided2[sc * 6 + 4], subdivided2[sc * 6 + 5], subdivided[sc * 6 + 2], subdivided[sc * 6 + 3], subdivided[sc * 6 + 4], subdivided[sc * 6 + 5], 0, final_vert_list);
// convex curves:
GraphicsFactoryHelper.addTriangle(subdivided2[sc * 6], subdivided2[sc * 6 + 1], subdivided2[sc * 6 + 2], subdivided2[sc * 6 + 3], subdivided2[sc * 6 + 4], subdivided2[sc * 6 + 5], -1, final_vert_list);
}
}
else {
for (var sc:number = 0; sc < subdivided.length / 6; sc++) {
// left curved
// convex curves:
GraphicsFactoryHelper.addTriangle(subdivided[sc * 6], subdivided[sc * 6 + 1], subdivided[sc * 6 + 2], subdivided[sc * 6 + 3], subdivided[sc * 6 + 4], subdivided[sc * 6 + 5], -1, final_vert_list);
// fills
GraphicsFactoryHelper.addTriangle(subdivided[sc * 6], subdivided[sc * 6 + 1], subdivided2[sc * 6], subdivided2[sc * 6 + 1], subdivided2[sc * 6 + 2], subdivided2[sc * 6 + 3], 0, final_vert_list);
GraphicsFactoryHelper.addTriangle(subdivided[sc * 6], subdivided[sc * 6 + 1], subdivided[sc * 6 + 4], subdivided[sc * 6 + 5], subdivided2[sc * 6 + 2], subdivided2[sc * 6 + 3], 0, final_vert_list);
GraphicsFactoryHelper.addTriangle(subdivided[sc * 6 + 4], subdivided[sc * 6 + 5], subdivided2[sc * 6 + 2], subdivided2[sc * 6 + 3], subdivided2[sc * 6 + 4], subdivided2[sc * 6 + 5], 0, final_vert_list);
// concave curves:
GraphicsFactoryHelper.addTriangle(subdivided2[sc * 6], subdivided2[sc * 6 + 1], subdivided2[sc * 6 + 2], subdivided2[sc * 6 + 3], subdivided2[sc * 6 + 4], subdivided2[sc * 6 + 5], 1, final_vert_list);
}
}
}
else if(new_cmds[i]>=GraphicsPathCommand.BUILD_JOINT) {
new_pnts_cnt+=3;
//GraphicsFactoryHelper.addTriangle(start_right.x, start_right.y, start_left.x, start_left.y, end_right.x, end_right.y, 0, final_vert_list);
if(new_cmds[i]==GraphicsPathCommand.BUILD_ROUND_JOINT) {
end_left = new_pnts[new_pnts_cnt++];// concave curves:
start_right = new_pnts[new_pnts_cnt++];
start_left = new_pnts[new_pnts_cnt++];
//console.log("add round tri");
GraphicsFactoryHelper.addTriangle(start_right.x, start_right.y, end_left.x, end_left.y,start_left.x, start_left.y, -1, final_vert_list);
}
}
}
// now we draw all the normal triangles.
// we do it in 2 steps, to prevent curves cut anything out of underlying normal tris
new_cmds_cnt=0;
new_pnts_cnt=0;
for (i = 0; i < new_cmds.length; i++) {
if(new_cmds[i]==GraphicsPathCommand.LINE_TO){
start_right = new_pnts[new_pnts_cnt++];
start_left = new_pnts[new_pnts_cnt++];
end_right = new_pnts[new_pnts_cnt];
end_left = new_pnts[new_pnts_cnt+1];
GraphicsFactoryHelper.addTriangle(start_right.x, start_right.y, start_left.x, start_left.y, end_right.x, end_right.y, 0, final_vert_list);
GraphicsFactoryHelper.addTriangle(start_left.x, start_left.y, end_left.x, end_left.y, end_right.x, end_right.y, 0, final_vert_list);
}
else if(new_cmds[i]==GraphicsPathCommand.CURVE_TO){
new_pnts_cnt+=5;
}
else if(new_cmds[i]>=GraphicsPathCommand.BUILD_JOINT) {
end_right = new_pnts[new_pnts_cnt++];
start_right = new_pnts[new_pnts_cnt++];
start_left = new_pnts[new_pnts_cnt++];
GraphicsFactoryHelper.addTriangle(start_right.x, start_right.y, start_left.x, start_left.y, end_right.x, end_right.y, 0, final_vert_list);
if(new_cmds[i]==GraphicsPathCommand.BUILD_ROUND_JOINT) {
new_pnts_cnt+=3;
}
}
}
if (!closed){
last_dir_vec.x = data[2] - data[0];
last_dir_vec.y = data[3] - data[1];
last_dir_vec.normalize();
GraphicsFactoryHelper.createCap(data[0], data[1], new_pnts[0], new_pnts[1], last_dir_vec, strokeStyle.capstyle, -1, strokeStyle.half_thickness, final_vert_list);
last_dir_vec.x = data[data.length-2] - data[data.length-4];
last_dir_vec.y = data[data.length-1] - data[data.length-3];
last_dir_vec.normalize();
GraphicsFactoryHelper.createCap(data[data.length-2], data[data.length-1], new_pnts[new_pnts.length-2], new_pnts[new_pnts.length-1], last_dir_vec, strokeStyle.capstyle, 1, strokeStyle.half_thickness, final_vert_list);
/*
last_dir_vec.x = data[data.length-2] - data[data.length-4];
last_dir_vec.y = data[data.length-1] - data[data.length-3];
last_dir_vec.normalize();
GraphicsFactoryHelper.createCap(data[data.length-2], data[data.length-1], contour_points[contour_points.length-1], contour_points[contour_points.length-2], last_dir_vec, strokeStyle.capstyle, -1, strokeStyle.half_thickness, final_vert_list);
*/
}
}
//console.log("final_vert_cnt "+(final_vert_cnt/5));
// todo: handle material / submesh settings, and check if a material / submesh already exists for this settings
var attributesView:AttributesView = new AttributesView(Float32Array, 5);
attributesView.set(final_vert_list);
var attributesBuffer:AttributesBuffer = attributesView.buffer;
attributesView.dispose();
var elements:TriangleElements = new TriangleElements(attributesBuffer);
elements.setPositions(new Float2Attributes(attributesBuffer));
elements.setCustomAttributes("curves", new Float3Attributes(attributesBuffer));
//elements.setUVs(new Float2Attributes(attributesBuffer));
//curve_sub_geom.setUVs(new Float2Attributes(attributesBuffer));
var material:MaterialBase = DefaultMaterialManager.getDefaultMaterial();
material.bothSides = true;
material.useColorTransform = true;
material.curves = true;
targetGraphic.addGraphic(elements, material);
}
targetGraphic.queued_stroke_pathes.length=0;
}
}
export default GraphicsFactoryStrokes;