Пример #1
0
void VertexData::appendVertexData(const VertexDataPtr& pVertexes)
{
    int oldNumVerts = m_NumVerts;
    int oldNumIndexes = m_NumIndexes;
    m_NumVerts += pVertexes->getNumVerts();
    m_NumIndexes += pVertexes->getNumIndexes();
    if (m_NumVerts > m_ReserveVerts || m_NumIndexes > m_ReserveIndexes) {
        grow();
    }

    memcpy(&(m_pVertexData[oldNumVerts]), pVertexes->m_pVertexData, 
            pVertexes->getNumVerts()*sizeof(Vertex));
    int numIndexes = pVertexes->getNumIndexes();
    for (int i=0; i<numIndexes; ++i) {
        m_pIndexData[oldNumIndexes+i] = pVertexes->m_pIndexData[i] + oldNumVerts;
    }
    m_bDataChanged = true;
}
Пример #2
0
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);
    }
}