void CurveNode::calcVertexes(const VertexDataPtr& pVertexData, Pixel32 color) { updateLines(); pVertexData->appendPos(m_LeftCurve[0], glm::vec2(m_TC1,1), color); pVertexData->appendPos(m_RightCurve[0], glm::vec2(m_TC2,0), color); for (unsigned i = 0; i < m_LeftCurve.size()-1; ++i) { float ratio = i/float(m_LeftCurve.size()); float tc = (1-ratio)*m_TC1+ratio*m_TC2; pVertexData->appendPos(m_LeftCurve[i+1], glm::vec2(tc,1), color); pVertexData->appendPos(m_RightCurve[i+1], glm::vec2(tc,0), color); pVertexData->appendQuadIndexes((i+1)*2, i*2, (i+1)*2+1, i*2+1); } }
void PolygonNode::calcFillVertexes(const VertexDataPtr& pVertexData, Pixel32 color) { if (getNumDifferentPts(m_Pts) < 3) { return; } // Remove duplicate points vector<glm::vec2> pts; vector<unsigned int> holeIndexes; pts.reserve(m_Pts.size()); if (glm::distance2(m_Pts[0], m_Pts[m_Pts.size()-1]) > 0.1) { pts.push_back(m_Pts[0]); } for (unsigned i = 1; i < m_Pts.size(); ++i) { if (glm::distance2(m_Pts[i], m_Pts[i-1]) > 0.1) { pts.push_back(m_Pts[i]); } } if (m_Holes.size() > 0) { for (unsigned int i = 0; i < m_Holes.size(); i++) { //loop over collection holeIndexes.push_back(pts.size()); for (unsigned int j = 0; j < m_Holes[i].size(); j++) { //loop over vector pts.push_back(m_Holes[i][j]); } } } if (color.getA() > 0) { glm::vec2 minCoord = pts[0]; glm::vec2 maxCoord = pts[0]; for (unsigned i = 1; i < pts.size(); ++i) { if (pts[i].x < minCoord.x) { minCoord.x = pts[i].x; } if (pts[i].x > maxCoord.x) { maxCoord.x = pts[i].x; } if (pts[i].y < minCoord.y) { minCoord.y = pts[i].y; } if (pts[i].y > maxCoord.y) { maxCoord.y = pts[i].y; } } vector<unsigned int> triIndexes; triangulatePolygon(triIndexes, pts, holeIndexes); for (unsigned i = 0; i < pts.size(); ++i) { glm::vec2 texCoord = calcFillTexCoord(pts[i], minCoord, maxCoord); pVertexData->appendPos(pts[i], texCoord, color); } for (unsigned i = 0; i < triIndexes.size(); i+=3) { pVertexData->appendTriIndexes(triIndexes[i], triIndexes[i+1], triIndexes[i+2]); } } }
void RectNode::calcFillVertexes(const VertexDataPtr& pVertexData, Pixel32 color) { glm::vec2 pivot = m_Rect.tl+m_Rect.size()/2.f; glm::vec2 p1 = m_Rect.tl; glm::vec2 p2(m_Rect.tl.x, m_Rect.br.y); glm::vec2 p3 = m_Rect.br; glm::vec2 p4(m_Rect.br.x, m_Rect.tl.y); glm::vec2 rp1 = getRotatedPivot(p1, m_Angle, pivot); glm::vec2 rp2 = getRotatedPivot(p2, m_Angle, pivot); glm::vec2 rp3 = getRotatedPivot(p3, m_Angle, pivot); glm::vec2 rp4 = getRotatedPivot(p4, m_Angle, pivot); pVertexData->appendPos(rp1, getFillTexCoord1(), color); glm::vec2 blTexCoord = glm::vec2(getFillTexCoord1().x, getFillTexCoord2().y); pVertexData->appendPos(rp2, blTexCoord, color); pVertexData->appendPos(rp3, getFillTexCoord2(), color); glm::vec2 trTexCoord = glm::vec2(getFillTexCoord2().x, getFillTexCoord1().y); pVertexData->appendPos(rp4, trTexCoord, color); pVertexData->appendQuadIndexes(1, 0, 2, 3); }
void VectorNode::calcPolyLine(const vector<glm::vec2>& origPts, const vector<float>& origTexCoords, bool bIsClosed, LineJoin lineJoin, const VertexDataPtr& pVertexData, Pixel32 color) { vector<glm::vec2> pts; pts.reserve(origPts.size()); vector<float> texCoords; texCoords.reserve(origPts.size()); pts.push_back(origPts[0]); texCoords.push_back(origTexCoords[0]); for (unsigned i = 1; i < origPts.size(); ++i) { if (glm::distance2(origPts[i], origPts[i-1]) > 0.1) { pts.push_back(origPts[i]); texCoords.push_back(origTexCoords[i]); } } if (bIsClosed) { texCoords.push_back(origTexCoords[origTexCoords.size()-1]); } int numPts = pts.size(); // Create array of wide lines. vector<WideLine> lines; lines.reserve(numPts-1); for (int i = 0; i < numPts-1; ++i) { lines.push_back(WideLine(pts[i], pts[i+1], m_StrokeWidth)); } if (bIsClosed) { lines.push_back(WideLine(pts[numPts-1], pts[0], m_StrokeWidth)); } // First points if (bIsClosed) { WideLine lastLine = lines[lines.size()-1]; glm::vec2 pli = getLineLineIntersection(lastLine.pl0, lastLine.dir, lines[0].pl0, lines[0].dir); glm::vec2 pri = getLineLineIntersection(lastLine.pr0, lastLine.dir, lines[0].pr0, lines[0].dir); Triangle tri(lastLine.pl1, lines[0].pl0, pri); if (tri.isClockwise()) { if (!LineSegment(lastLine.pr0, lastLine.pr1).isPointOver(pri) && !LineSegment(lines[0].pr0, lines[0].pr1).isPointOver(pri)) { pri = lines[0].pr1; } } else { if (!LineSegment(lastLine.pl0, lastLine.pl1).isPointOver(pli) && !LineSegment(lines[0].pl0, lines[0].pl1).isPointOver(pli)) { pli = lines[0].pl1; } } float curTC = texCoords[0]; switch (lineJoin) { case LJ_MITER: pVertexData->appendPos(pli, glm::vec2(curTC,1), color); pVertexData->appendPos(pri, glm::vec2(curTC,0), color); break; case LJ_BEVEL: { if (tri.isClockwise()) { pVertexData->appendPos(lines[0].pl0, glm::vec2(curTC,1), color); pVertexData->appendPos(pri, glm::vec2(curTC,0), color); } else { pVertexData->appendPos(pli, glm::vec2(curTC,1), color); pVertexData->appendPos(lines[0].pr0, glm::vec2(curTC,0), color); } } break; default: AVG_ASSERT(false); break; } } else { pVertexData->appendPos(lines[0].pl0, glm::vec2(texCoords[0],1), color); pVertexData->appendPos(lines[0].pr0, glm::vec2(texCoords[0],0), color); } // All complete line segments unsigned numNormalSegments; if (bIsClosed) { numNormalSegments = pts.size(); } else { numNormalSegments = pts.size()-2; } for (unsigned i = 0; i < numNormalSegments; ++i) { const WideLine* pLine1 = &(lines[i]); const WideLine* pLine2; if (i == pts.size()-1) { pLine2 = &(lines[0]); } else { pLine2 = &(lines[i+1]); } glm::vec2 pli = getLineLineIntersection(pLine1->pl0, pLine1->dir, pLine2->pl0, pLine2->dir); glm::vec2 pri = getLineLineIntersection(pLine1->pr0, pLine1->dir, pLine2->pr0, pLine2->dir); Triangle tri(pLine1->pl1, pLine2->pl0, pri); if (tri.isClockwise()) { if (!LineSegment(pLine1->pr0, pLine1->pr1).isPointOver(pri) && !LineSegment(pLine2->pr0, pLine2->pr1).isPointOver(pri)) { pri = pLine2->pr1; } } else { if (!LineSegment(pLine1->pl0, pLine1->pl1).isPointOver(pli) && !LineSegment(pLine2->pl0, pLine2->pl1).isPointOver(pli)) { pli = pLine2->pl1; } } int curVertex = pVertexData->getNumVerts(); float curTC = texCoords[i+1]; switch (lineJoin) { case LJ_MITER: pVertexData->appendPos(pli, glm::vec2(curTC,1), color); pVertexData->appendPos(pri, glm::vec2(curTC,0), color); pVertexData->appendQuadIndexes( curVertex-1, curVertex-2, curVertex+1, curVertex); break; case LJ_BEVEL: { float TC0; float TC1; if (tri.isClockwise()) { calcBevelTC(*pLine1, *pLine2, true, texCoords, i+1, TC0, TC1); pVertexData->appendPos(pLine1->pl1, glm::vec2(TC0,1), color); pVertexData->appendPos(pLine2->pl0, glm::vec2(TC1,1), color); pVertexData->appendPos(pri, glm::vec2(curTC,0), color); pVertexData->appendQuadIndexes( curVertex-1, curVertex-2, curVertex+2, curVertex); pVertexData->appendTriIndexes( curVertex, curVertex+1, curVertex+2); } else { calcBevelTC(*pLine1, *pLine2, false, texCoords, i+1, TC0, TC1); pVertexData->appendPos(pLine1->pr1, glm::vec2(TC0,0), color); pVertexData->appendPos(pli, glm::vec2(curTC,1), color); pVertexData->appendPos(pLine2->pr0, glm::vec2(TC1,0), color); pVertexData->appendQuadIndexes( curVertex-2, curVertex-1, curVertex+1, curVertex); pVertexData->appendTriIndexes( curVertex, curVertex+1, curVertex+2); } } break; default: AVG_ASSERT(false); } } // Last segment (PolyLine only) if (!bIsClosed) { int curVertex = pVertexData->getNumVerts(); float curTC = texCoords[numPts-1]; pVertexData->appendPos(lines[numPts-2].pl1, glm::vec2(curTC,1), color); pVertexData->appendPos(lines[numPts-2].pr1, glm::vec2(curTC,0), color); pVertexData->appendQuadIndexes(curVertex-1, curVertex-2, curVertex+1, curVertex); } }