Vertex[] shapeAndGradVerts = new Vertex[shapeVertsCopy.length + gradientRectVerts.length];
System.arraycopy(shapeVertsCopy, 0, shapeAndGradVerts, 0, shapeVertsCopy.length);
System.arraycopy(gradientRectVerts, 0, shapeAndGradVerts, shapeVertsCopy.length, gradientRectVerts.length);
//Create a temporary polygon with the roated vertices to calc BBox
MTPolygon inverseRotatedShape = new MTPolygon(shapeAndGradVerts, pa);
//Calculate a bounding rectangle from the rotated shape
BoundsZPlaneRectangle inverseRotatedBounds = new BoundsZPlaneRectangle(inverseRotatedShape);
Vector3D[] invBoundsVecs = inverseRotatedBounds.getVectorsLocal();
//logger.debug("Gradient Rectangle width: " + gradientRectWidth);
//Get the positions where the offsets are on the gradient vector
// float bBoxWidth = invBoundsVecs[1].x - invBoundsVecs[0].x;
// logger.debug("BBox width: " + bBoxWidth);
// float w = bBoxWidth/*/100*/;
List<Float> xStops = new ArrayList<Float>();
//- Go through stops
//- multiply stop offsets with bbox width to get the position on gradient vector
//logger.debug("->Gradient Vector stop positions:");
for(Stop stop : stops){
float offsetStopPosition = gradientRectWidth * stop.offset; //position auf gradient vector, stop(0) = vP1.x + offest
xStops.add(offsetStopPosition);
//logger.debug(" Offset-Stop-Position: " + offsetStopPosition);
}
//Calc new gradient polygon vertices with vertices at the stop locations
Vertex[] newBounds = new Vertex[(xStops.size()-1) * 4];
for (int i = 0; i < xStops.size()-1; i++) {
float offset = xStops.get(i);
Color stopColor = stops.get(i).color;
float nextOffset = xStops.get(i+1);
Color nextStopColor = stops.get(i+1).color;
newBounds[i*4] = new Vertex(vP1.x + offset, invBoundsVecs[0].y,0, stopColor.getRed(), stopColor.getGreen(), stopColor.getBlue(), stopColor.getAlpha());
newBounds[i*4+1] = new Vertex(vP1.x + nextOffset, invBoundsVecs[0].y,0, nextStopColor.getRed(), nextStopColor.getGreen(), nextStopColor.getBlue(), nextStopColor.getAlpha());
newBounds[i*4+2] = new Vertex(vP1.x + nextOffset, invBoundsVecs[2].y,0, nextStopColor.getRed(), nextStopColor.getGreen(), nextStopColor.getBlue(), nextStopColor.getAlpha());
newBounds[i*4+3] = new Vertex(vP1.x + offset, invBoundsVecs[2].y,0, stopColor.getRed(), stopColor.getGreen(), stopColor.getBlue(), stopColor.getAlpha());
}
//Put gradient rectangle quads into a list
List<Vertex> gradientRectQuads = new ArrayList<Vertex>();
for (int i = 0; i < newBounds.length; i++) {
Vertex vertex = newBounds[i];
gradientRectQuads.add(vertex);
}
/* Bounding shape with gradient rectangle inside (can also overlap outlines)
invBoundsVecs[0] invBoundsVecs[1]
| _______________ |
| |_____| |
| | G | |
| vp1|____>|vp2 |
|____|_____|____|
*/
//Calc rectangle bands (quads) to fill the gradient shape with the gradVect end colors if the gradient vector is smaller than the shape to draw
List<Vertex> leftQuad = new ArrayList<Vertex>();
if (vP1.x > invBoundsVecs[0].x){
//upper left of bounding rect
Vertex v1 = new Vertex(invBoundsVecs[0].x, invBoundsVecs[0].y, 0, newBounds[0].getR(), newBounds[0].getG(), newBounds[0].getB(), newBounds[0].getA());
//first stop on gradient vector upper
Vertex v2 = new Vertex(newBounds[0].x, newBounds[0].y, 0, newBounds[0].getR(), newBounds[0].getG(), newBounds[0].getB(), newBounds[0].getA());
//first stop on gradient vector lower
Vertex v3 = new Vertex(newBounds[3].x, newBounds[3].y, 0, newBounds[3].getR(), newBounds[3].getG(), newBounds[3].getB(), newBounds[3].getA());
//down left of bounding rect
Vertex v4 = new Vertex(invBoundsVecs[3].x, invBoundsVecs[3].y, 0, newBounds[0].getR(), newBounds[0].getG(), newBounds[0].getB(), newBounds[0].getA());
leftQuad.add(v1);
leftQuad.add(v2);
leftQuad.add(v3);
leftQuad.add(v4);
}
//Add Right quad if gradient rectangle is smaler than overall bounds
List<Vertex> rightQuad = new ArrayList<Vertex>();
if (vP2.x < invBoundsVecs[1].x){
Vertex gradientRectUpperRight = newBounds[newBounds.length-3];
Vertex gradientRectLowerRight = newBounds[newBounds.length-2];
Vertex v1 = new Vertex(gradientRectUpperRight.x, gradientRectUpperRight.y, 0, gradientRectUpperRight.getR(), gradientRectUpperRight.getG(), gradientRectUpperRight.getB(), gradientRectUpperRight.getA());
Vertex v2 = new Vertex(invBoundsVecs[1].x, invBoundsVecs[1].y, 0, gradientRectUpperRight.getR(), gradientRectUpperRight.getG(), gradientRectUpperRight.getB(), gradientRectUpperRight.getA());
Vertex v3 = new Vertex(invBoundsVecs[2].x, invBoundsVecs[2].y, 0, gradientRectUpperRight.getR(), gradientRectUpperRight.getG(), gradientRectUpperRight.getB(), gradientRectUpperRight.getA());
Vertex v4 = new Vertex(gradientRectLowerRight.x, gradientRectLowerRight.y, 0, gradientRectUpperRight.getR(), gradientRectUpperRight.getG(), gradientRectUpperRight.getB(), gradientRectUpperRight.getA());
rightQuad.add(v1);
rightQuad.add(v2);
rightQuad.add(v3);
rightQuad.add(v4);
}
//Create new array for gradient shape with all quads inside
List<Vertex> allGradientShapeVerts = new ArrayList<Vertex>();
allGradientShapeVerts.addAll(leftQuad);
allGradientShapeVerts.addAll(gradientRectQuads);
allGradientShapeVerts.addAll(rightQuad);
newBounds = allGradientShapeVerts.toArray(new Vertex[allGradientShapeVerts.size()]);
//Rotate the vectors of the calculated bounding rect back to the original angle
newBounds = (Vertex[]) Vector3D.rotateZVectorArray(newBounds, testShape.getCenterPointLocal(), gradAngle);
//Create gradient shape to paint over the real shape
MTPolygon p = new MTPolygon(newBounds,pa);
p.setNoStroke(true);
p.setPickable(false);
p.setStrokeWeight(testShape.getStrokeWeight());
p.setFillDrawMode(GL.GL_QUADS);
//Use displaylist by default for gradientshape
p.generateAndUseDisplayLists();
FillPaint gradStencil = new FillPaint(gl, p);
return gradStencil;
}