#include "pageflipmath_p.h"
#include <QtCore/qmath.h>
#include <string.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
PageFlipMath::PageFlipMath()
{
m_showPageReverse = false;
m_startCorner = BottomRight;
memset(vertices, 0, sizeof(vertices));
memset(pageCount, 0, sizeof(pageCount));
}
PageFlipMath::~PageFlipMath()
{
}
void PageFlipMath::drawPage(int page) const
{
if (page < 0 || page >= 4 || pageCount[page] == 0)
return;
glDrawArrays(GL_TRIANGLE_FAN, page * 5, pageCount[page]);
}
void PageFlipMath::drawOutline(int page) const
{
if (page < 0 || page >= 4 || pageCount[page] == 0)
return;
glDrawArrays(GL_LINE_LOOP, page * 5, pageCount[page]);
}
void PageFlipMath::compute(qreal t)
{
int page, vertex;
if (m_startCorner < VerticalBottomRight)
flip(m_pageRect.width() - 1, m_pageRect.height() - 1, t);
else
flip(m_pageRect.height() - 1, m_pageRect.width() - 1, t);
switch (m_startCorner) {
case BottomRight: break;
case TopRight:
for (page = 0; page < 4; ++page) {
for (vertex = 0; vertex < pageCount[page]; ++vertex) {
vertices[page][vertex][1]
= m_pageRect.height() - 1 - vertices[page][vertex][1];
vertices[page][vertex][3]
= 1.0f - vertices[page][vertex][3];
}
}
break;
case BottomLeft:
for (page = 0; page < 4; ++page) {
for (vertex = 0; vertex < pageCount[page]; ++vertex) {
vertices[page][vertex][0]
= m_pageRect.width() - 1 - vertices[page][vertex][0];
vertices[page][vertex][0] -= m_pageRect.width();
vertices[page][vertex][2]
= 1.0f - vertices[page][vertex][2];
}
}
break;
case TopLeft:
for (page = 0; page < 4; ++page) {
for (vertex = 0; vertex < pageCount[page]; ++vertex) {
vertices[page][vertex][0]
= m_pageRect.width() - 1 - vertices[page][vertex][0];
vertices[page][vertex][0] -= m_pageRect.width();
vertices[page][vertex][1]
= m_pageRect.height() - 1 - vertices[page][vertex][1];
vertices[page][vertex][2]
= 1.0f - vertices[page][vertex][2];
vertices[page][vertex][3]
= 1.0f - vertices[page][vertex][3];
}
}
break;
case BottomLeftOnePage:
for (page = 1; page < 4; ++page) {
for (vertex = 0; vertex < pageCount[page]; ++vertex) {
vertices[page][vertex][0]
= m_pageRect.width() - 1 - vertices[page][vertex][0];
vertices[page][vertex][2]
= 1.0f - vertices[page][vertex][2];
}
}
break;
case TopLeftOnePage:
for (page = 1; page < 4; ++page) {
for (vertex = 0; vertex < pageCount[page]; ++vertex) {
vertices[page][vertex][0]
= m_pageRect.width() - 1 - vertices[page][vertex][0];
vertices[page][vertex][1]
= m_pageRect.height() - 1 - vertices[page][vertex][1];
vertices[page][vertex][2]
= 1.0f - vertices[page][vertex][2];
vertices[page][vertex][3]
= 1.0f - vertices[page][vertex][3];
}
}
break;
case VerticalBottomRight:
for (page = 0; page < 4; ++page) {
for (vertex = 0; vertex < pageCount[page]; ++vertex) {
qSwap(vertices[page][vertex][0], vertices[page][vertex][1]);
vertices[page][vertex][0]
= m_pageRect.width() - 1 - vertices[page][vertex][0];
vertices[page][vertex][1]
= m_pageRect.height() - 1 - vertices[page][vertex][1];
qSwap(vertices[page][vertex][2], vertices[page][vertex][3]);
vertices[page][vertex][2]
= 1.0f - vertices[page][vertex][2];
vertices[page][vertex][3]
= 1.0f - vertices[page][vertex][3];
}
}
break;
case VerticalTopRight:
for (page = 0; page < 4; ++page) {
for (vertex = 0; vertex < pageCount[page]; ++vertex) {
qSwap(vertices[page][vertex][0], vertices[page][vertex][1]);
vertices[page][vertex][0]
= m_pageRect.width() - 1 - vertices[page][vertex][0];
qSwap(vertices[page][vertex][2], vertices[page][vertex][3]);
vertices[page][vertex][2]
= 1.0f - vertices[page][vertex][2];
}
}
break;
case VerticalBottomLeft:
for (page = 0; page < 4; ++page) {
for (vertex = 0; vertex < pageCount[page]; ++vertex) {
qSwap(vertices[page][vertex][0], vertices[page][vertex][1]);
vertices[page][vertex][1]
= m_pageRect.height() - 1 - vertices[page][vertex][1];
qSwap(vertices[page][vertex][2], vertices[page][vertex][3]);
vertices[page][vertex][3]
= 1.0f - vertices[page][vertex][3];
}
}
break;
case VerticalTopLeft:
for (page = 0; page < 4; ++page) {
for (vertex = 0; vertex < pageCount[page]; ++vertex) {
qSwap(vertices[page][vertex][0], vertices[page][vertex][1]);
qSwap(vertices[page][vertex][2], vertices[page][vertex][3]);
}
}
break;
}
for (page = 0; page < 4; ++page) {
for (vertex = 0; vertex < pageCount[page]; ++vertex) {
vertices[page][vertex][0] += m_pageRect.x();
vertices[page][vertex][1]
= m_pageRect.y() +
(m_pageRect.height() - 1 - vertices[page][vertex][1]);
}
}
if (m_showPageReverse) {
if (m_startCorner < VerticalBottomRight) {
for (int vertex = 0; vertex < pageCount[2]; ++vertex)
vertices[2][vertex][2] = 1.0f - vertices[2][vertex][2];
} else {
for (int vertex = 0; vertex < pageCount[2]; ++vertex)
vertices[2][vertex][3] = 1.0f - vertices[2][vertex][3];
}
}
}
void PageFlipMath::flip(qreal pageWidth, qreal pageHeight, qreal t)
{
if (t <= 0.0f) {
pageCount[0] = 4;
pageCount[1] = 4;
pageCount[2] = 0;
pageCount[3] = 0;
vertices[0][0][0] = -pageWidth;
vertices[0][0][1] = 0.0f;
vertices[0][0][2] = 0.0f;
vertices[0][0][3] = 0.0f;
vertices[0][0][4] = 0.0f;
vertices[0][1][0] = 0.0f;
vertices[0][1][1] = 0.0f;
vertices[0][1][2] = 1.0f;
vertices[0][1][3] = 0.0f;
vertices[0][1][4] = 1.0f;
vertices[0][2][0] = 0.0f;
vertices[0][2][1] = pageHeight;
vertices[0][2][2] = 1.0f;
vertices[0][2][3] = 1.0f;
vertices[0][2][4] = 1.0f;
vertices[0][3][0] = -pageWidth;
vertices[0][3][1] = pageHeight;
vertices[0][3][2] = 0.0f;
vertices[0][3][3] = 1.0f;
vertices[0][3][4] = 0.0f;
vertices[1][0][0] = 0.0f;
vertices[1][0][1] = 0.0f;
vertices[1][0][2] = 0.0f;
vertices[1][0][3] = 0.0f;
vertices[1][0][4] = 1.0f;
vertices[1][1][0] = pageWidth;
vertices[1][1][1] = 0.0f;
vertices[1][1][2] = 1.0f;
vertices[1][1][3] = 0.0f;
vertices[1][1][4] = 0.0f;
vertices[1][2][0] = pageWidth;
vertices[1][2][1] = pageHeight;
vertices[1][2][2] = 1.0f;
vertices[1][2][3] = 1.0f;
vertices[1][2][4] = 0.0f;
vertices[1][3][0] = 0.0f;
vertices[1][3][1] = pageHeight;
vertices[1][3][2] = 0.0f;
vertices[1][3][3] = 1.0f;
vertices[1][3][4] = 1.0f;
return;
} else if (t >= 1.0f) {
pageCount[0] = 0;
pageCount[1] = 0;
pageCount[2] = 4;
pageCount[3] = 4;
vertices[2][0][0] = -pageWidth;
vertices[2][0][1] = 0.0f;
vertices[2][0][2] = 0.0f;
vertices[2][0][3] = 0.0f;
vertices[2][0][4] = 0.0f;
vertices[2][1][0] = 0.0f;
vertices[2][1][1] = 0.0f;
vertices[2][1][2] = 1.0f;
vertices[2][1][3] = 0.0f;
vertices[2][1][4] = 1.0f;
vertices[2][2][0] = 0.0f;
vertices[2][2][1] = pageHeight;
vertices[2][2][2] = 1.0f;
vertices[2][2][3] = 1.0f;
vertices[2][2][4] = 1.0f;
vertices[2][3][0] = -pageWidth;
vertices[2][3][1] = pageHeight;
vertices[2][3][2] = 0.0f;
vertices[2][3][3] = 1.0f;
vertices[2][3][4] = 0.0f;
vertices[3][0][0] = 0.0f;
vertices[3][0][1] = 0.0f;
vertices[3][0][2] = 0.0f;
vertices[3][0][3] = 0.0f;
vertices[3][0][4] = 1.0f;
vertices[3][1][0] = pageWidth;
vertices[3][1][1] = 0.0f;
vertices[3][1][2] = 1.0f;
vertices[3][1][3] = 0.0f;
vertices[3][1][4] = 0.0f;
vertices[3][2][0] = pageWidth;
vertices[3][2][1] = pageHeight;
vertices[3][2][2] = 1.0f;
vertices[3][2][3] = 1.0f;
vertices[3][2][4] = 0.0f;
vertices[3][3][0] = 0.0f;
vertices[3][3][1] = pageHeight;
vertices[3][3][2] = 0.0f;
vertices[3][3][3] = 1.0f;
vertices[3][3][4] = 1.0f;
return;
}
pageCount[0] = 4;
vertices[0][0][0] = -pageWidth;
vertices[0][0][1] = 0.0f;
vertices[0][0][2] = 0.0f;
vertices[0][0][3] = 0.0f;
vertices[0][0][4] = 0.0f;
vertices[0][1][0] = 0.0f;
vertices[0][1][1] = 0.0f;
vertices[0][1][2] = 1.0f;
vertices[0][1][3] = 0.0f;
vertices[0][1][4] = 1.0f;
vertices[0][2][0] = 0.0f;
vertices[0][2][1] = pageHeight;
vertices[0][2][2] = 1.0f;
vertices[0][2][3] = 1.0f;
vertices[0][2][4] = 1.0f;
vertices[0][3][0] = -pageWidth;
vertices[0][3][1] = pageHeight;
vertices[0][3][2] = 0.0f;
vertices[0][3][3] = 1.0f;
vertices[0][3][4] = 0.0f;
qreal angle = (M_PI / 4.0f) * (1.0f + t);
qreal cosAngle = qCos(angle);
qreal sinAngle = qSin(angle);
qreal cosAngle2 = qCos(angle * 2.0f);
qreal sinAngle2 = qSin(angle * 2.0f);
qreal refx = pageWidth * (1.0f - t);
qreal refy = 0.0f;
qreal d = pageWidth - refx;
qreal k = (pageHeight * cosAngle) / sinAngle;
if (k >= d) {
qreal intx = pageWidth;
qreal inty = refy + (d * sinAngle) / cosAngle;
qreal oppx = refx + d * cosAngle2;
qreal oppy = refy + d * sinAngle2;
qreal texa = 1.0f - (d * sinAngle) / (pageHeight * cosAngle);
qreal texb = d / pageWidth;
vertices[2][0][0] = intx;
vertices[2][0][1] = inty;
vertices[2][0][2] = 0.0f;
vertices[2][0][3] = 1.0f - texa;
vertices[2][0][4] = 1.0f;
vertices[2][1][0] = oppx;
vertices[2][1][1] = oppy;
vertices[2][1][2] = 0.0f;
vertices[2][1][3] = 0.0f;
vertices[2][1][4] = 1.0f - texb;
vertices[2][2][0] = refx;
vertices[2][2][1] = refy;
vertices[2][2][2] = texb;
vertices[2][2][3] = 0.0f;
vertices[2][2][4] = 1.0f;
pageCount[2] = 3;
vertices[3][0][0] = intx;
vertices[3][0][1] = inty;
vertices[3][0][2] = 1.0f;
vertices[3][0][3] = 1.0f - texa;
vertices[3][0][4] = 1.0f;
vertices[3][1][0] = refx;
vertices[3][1][1] = refy;
vertices[3][1][2] = 1.0f - texb;
vertices[3][1][3] = 0.0f;
vertices[3][1][4] = 1.0f;
vertices[3][2][0] = pageWidth;
vertices[3][2][1] = 0.0f;
vertices[3][2][2] = 1.0f;
vertices[3][2][3] = 0.0f;
vertices[3][2][4] = 1.0f - texb;
pageCount[3] = 3;
vertices[1][0][0] = 0.0f;
vertices[1][0][1] = 0.0f;
vertices[1][0][2] = 0.0f;
vertices[1][0][3] = 0.0f;
vertices[1][0][4] = 1.0f;
vertices[1][1][0] = pageWidth - d;
vertices[1][1][1] = 0.0f;
vertices[1][1][2] = 1.0f - texb;
vertices[1][1][3] = 0.0f;
vertices[1][1][4] = texb;
vertices[1][2][0] = intx;
vertices[1][2][1] = inty;
vertices[1][2][2] = 1.0f;
vertices[1][2][3] = 1.0f - texa;
vertices[1][2][4] = 0.0f;
vertices[1][3][0] = pageWidth;
vertices[1][3][1] = pageHeight;
vertices[1][3][2] = 1.0f;
vertices[1][3][3] = 1.0f;
vertices[1][3][4] = 0.0f;
vertices[1][4][0] = 0.0f;
vertices[1][4][1] = pageHeight;
vertices[1][4][2] = 0.0f;
vertices[1][4][3] = 1.0f;
vertices[1][4][4] = 1.0f;
pageCount[1] = 5;
} else {
qreal intx = refx + (pageHeight * cosAngle) / sinAngle;
qreal inty = pageHeight;
qreal e = pageWidth - intx;
qreal opprefx = refx + d * cosAngle2;
qreal opprefy = refy + d * sinAngle2;
qreal oppintx = intx + e * cosAngle2;
qreal oppinty = inty + e * sinAngle2;
qreal texa = e / pageWidth;
qreal texb = d / pageWidth;
vertices[2][0][0] = intx;
vertices[2][0][1] = inty;
vertices[2][0][2] = texa;
vertices[2][0][3] = 1.0f;
vertices[2][0][4] = 1.0f;
vertices[2][1][0] = oppintx;
vertices[2][1][1] = oppinty;
vertices[2][1][2] = 0.0f;
vertices[2][1][3] = 1.0f;
vertices[2][1][4] = 1.0f - texa;
vertices[2][2][0] = opprefx;
vertices[2][2][1] = opprefy;
vertices[2][2][2] = 0.0f;
vertices[2][2][3] = 0.0f;
vertices[2][2][4] = 1.0f - texb;
vertices[2][3][0] = refx;
vertices[2][3][1] = refy;
vertices[2][3][2] = texb;
vertices[2][3][3] = 0.0f;
vertices[2][3][4] = 1.0f;
pageCount[2] = 4;
vertices[3][0][0] = intx;
vertices[3][0][1] = inty;
vertices[3][0][2] = 1.0f - texa;
vertices[3][0][3] = 1.0f;
vertices[3][0][4] = 1.0f;
vertices[3][1][0] = refx;
vertices[3][1][1] = refy;
vertices[3][1][2] = 1.0f - texb;
vertices[3][1][3] = 0.0f;
vertices[3][1][4] = 1.0f;
vertices[3][2][0] = pageWidth;
vertices[3][2][1] = 0.0f;
vertices[3][2][2] = 1.0f;
vertices[3][2][3] = 0.0f;
vertices[3][2][4] = 1.0f - texb;
vertices[3][3][0] = pageWidth;
vertices[3][3][1] = pageHeight;
vertices[3][3][2] = 1.0f;
vertices[3][3][3] = 1.0f;
vertices[3][3][4] = 1.0f - texa;
pageCount[3] = 4;
vertices[1][0][0] = 0.0f;
vertices[1][0][1] = 0.0f;
vertices[1][0][2] = 0.0f;
vertices[1][0][3] = 0.0f;
vertices[1][0][4] = 1.0f;
vertices[1][1][0] = pageWidth - d;
vertices[1][1][1] = 0.0f;
vertices[1][1][2] = 1.0f - texb;
vertices[1][1][3] = 0.0f;
vertices[1][1][4] = texb;
vertices[1][2][0] = pageWidth - e;
vertices[1][2][1] = pageHeight;
vertices[1][2][2] = 1.0f - texa;
vertices[1][2][3] = 1.0f;
vertices[1][2][4] = texa;
vertices[1][3][0] = 0.0f;
vertices[1][3][1] = pageHeight;
vertices[1][3][2] = 0.0f;
vertices[1][3][3] = 1.0f;
vertices[1][3][4] = 1.0f;
pageCount[1] = 4;
}
}