/*
* =====================================================================================
*
* Filename: viewer.cpp
*
* Description: View multi-z-buffer views
*
* Version: 1.0
* Created: 23/02/2011 08:31:52
* Revision: none
* Compiler: gcc
*
* Author: John Ryland (jryland), jryland@xiaofrog.com
* Company: InvertedLogic
*
* =====================================================================================
*/
#include <viewer.h>
#include <QMatrix4x4>
Viewer::Viewer(QWidget *parent) : QWidget(parent)
{
for (int f = 0; f < 6; f++)
{
QImage img(QString("side_%1_.png").arg(f));
unsigned int *data = (unsigned int *)img.bits();
for (int i = 0; i < 256*256; i++)
{
//if ( data[i] & 0x00ffffff )
{
face[f][i] = data[i] & 0xff;
}
//else
{
//face[f][i] = 0xff;
}
}
}
angle = 0;
startTimer(1);
}
Viewer::~Viewer()
{
}
void Viewer::timerEvent(QTimerEvent *event)
{
repaint();
}
#include <time.h>
float calcFPS()
{
static unsigned lastTick = clock();
unsigned currTick = clock();
unsigned tickDiff=currTick-lastTick;
lastTick = currTick;
return (float)(CLOCKS_PER_SEC) / (float)(tickDiff); // Inverse
}
void Viewer::paintEvent(QPaintEvent *pe)
{
QPainter p(this);
angle += 15;
QImage output( 256, 256, QImage::Format_ARGB32 );
unsigned int *data = (unsigned int *)output.bits();
/*
int sideX[6];
int sideY[6];
int sideZ[6];
int sideDX[6];
int sideDY[6];
int sideDZ[6];
int sideIncX[6];
int sideIncY[6];
int sideIncZ[6];
sideX[0] = 128;
sideY[0] = 0;
sideZ[0] = -128;
sideDX[0] = -1;
sideDY[0] = 0;
sideDZ[0] = 1;
sideIncX[0] = 1;
sideIncY[0] = 0;
sideIncZ[0] = 1;
// y = y
sideX[1] = 128;
sideZ[1] = -128;
sideDX[1] = -1;
sideDZ[1] = 1;
sideIncX[1] = 1;
sideIncZ[1] = 1;
sideX[2] = 128;
sideZ[2] = -128;
sideDX[2] = -1;
sideDZ[2] = 1;
sideIncX[2] = 1;
sideIncZ[2] = 1;
sideX[3] = 128;
sideZ[3] = -128;
sideDX[3] = -1;
sideDZ[3] = 1;
sideIncX[3] = 1;
sideIncZ[3] = 1;
sideX[4] = 128;
sideZ[4] = -128;
sideDX[4] = -1;
sideDZ[4] = 1;
sideIncX[4] = 1;
sideIncZ[4] = 1;
sideX[5] = 128;
sideZ[5] = -128;
sideDX[5] = -1;
sideDZ[5] = 1;
sideIncX[5] = 1;
sideIncZ[5] = 1;
*/
// At the moment this is orthographic, but shouldn't be hard to modify that
QMatrix4x4 invViewSpace;
invViewSpace.translate( 128, 128, 128 );
invViewSpace.rotate( angle, 0, 1, 0 );
invViewSpace.rotate( angle + 30, 1, 0, 0 );
invViewSpace.rotate( angle - 30, 0, 0, 1 );
invViewSpace.translate( -128, -128, -128 );
for (int y = 0; y < 256; y++)
{
QVector3D pntA(0, y, -10);
pntA = invViewSpace.map(pntA);
QVector3D pntB(256, y, -10);
pntB = invViewSpace.map(pntB);
QVector3D dxpnt1 = (pntB - pntA) / 256.0f;
QVector3D pntC(0, y, 256);
pntC = invViewSpace.map(pntC);
QVector3D pntD(256, y, 256);
pntD = invViewSpace.map(pntD);
QVector3D dxpnt2 = (pntD - pntC) / 256.0f;
int ipntA[3];
int ipntC[3];
short int idPntA[3];
short int idPntC[3];
const float scaleUp = 256.0f;//65536.0f;
const int iScaleUp = 256;//65536;
const int shiftDown = 8;//16;
ipntA[0] = pntA.x() * scaleUp;
ipntA[1] = pntA.y() * scaleUp;
ipntA[2] = pntA.z() * scaleUp;
ipntC[0] = pntC.x() * scaleUp;
ipntC[1] = pntC.y() * scaleUp;
ipntC[2] = pntC.z() * scaleUp;
idPntA[0] = dxpnt1.x() * scaleUp;
idPntA[1] = dxpnt1.y() * scaleUp;
idPntA[2] = dxpnt1.z() * scaleUp;
idPntC[0] = dxpnt2.x() * scaleUp;
idPntC[1] = dxpnt2.y() * scaleUp;
idPntC[2] = dxpnt2.z() * scaleUp;
for (int x = 0; x < 256; x++)
{
data[y*256+x] = 0xff000000;
bool inside = false;
/*
QVector3D pnt = pntA;//(x, y, 0);
pntA += dxpnt1;
QVector3D pnt2 = pntC;//(x, y, 0);
pntC += dxpnt2;
*/
int ipnt[3];
int ipnt2[3];
short int idpnt[3];
for (int i = 0; i < 3; i++)
{
ipnt[i] = ipntA[i];
ipnt2[i] = ipntC[i];
ipntA[i] += idPntA[i];
ipntC[i] += idPntC[i];
idpnt[i] = (ipnt2[i] - ipnt[i]) / 256;
}
/*
QVector3D pnt(x, y, 0);
pnt = invViewSpace.map(pnt);
QVector3D pnt2(x, y, 256);
pnt2 = invViewSpace.map(pnt2);
*/
/*
QVector3D dpnt = (pnt2 - pnt) / 256.0f;
int px = pnt.x();
int py = pnt.y();
int pz = pnt.z();
*/
int px, py, pz;
int c = -10;
for (int j = 0; j < 3; j++)
{
int cnt = 1;
if ( ipnt[j] < 0 )
{
if ( idpnt[j] > 0 ) {
cnt = -ipnt[j] / idpnt[j];
}
}
else if ( ipnt[j] > 256*iScaleUp )
{
if ( idpnt[j] < 0 ) {
cnt = (ipnt[j] - 256*iScaleUp) / -idpnt[j];
}
}
for (int i = 0; i < 3; i++)
ipnt[i] += (cnt - 1) * idpnt[i];
c += cnt - 1;
}
int iterations = 512;
for (int j = 0; j < 3; j++)
{
if ( idpnt[j] > 0 )
{
int its = (256*iScaleUp - ipnt[j]) / idpnt[j];
if ( its < 512 )
{
iterations = its;
}
}
else if ( idpnt[j] < 0 )
{
int its = ipnt[j] / -idpnt[j];
if ( its < 512 )
{
iterations = its;
}
}
}
//for (int z = -10; z <= 256; z++)
for (int z = 0; z <= iterations; z++)
{
/*
pnt += dpnt;
px = pnt.x();
py = pnt.y();
pz = pnt.z();
*/
px = ipnt[0] >> shiftDown;// / 65536;
py = ipnt[1] >> shiftDown;// / 65536;
pz = ipnt[2] >> shiftDown;/// 65536;
while ( z <= iterations && py <= face[3][pz * 256 + px] )
{
for (int i = 0; i < 3; i++)
ipnt[i] += idpnt[i];
px = ipnt[0] >> shiftDown;// / 65536;
py = ipnt[1] >> shiftDown;// / 65536;
pz = ipnt[2] >> shiftDown;/// 65536;
z++;
}
while ( z <= iterations && pz <= face[2][(256 - py) * 256 + px] )
{
for (int i = 0; i < 3; i++)
ipnt[i] += idpnt[i];
px = ipnt[0] >> shiftDown;// / 65536;
py = ipnt[1] >> shiftDown;// / 65536;
pz = ipnt[2] >> shiftDown;/// 65536;
z++;
}
while ( z <= iterations && px <= face[0][(256 - py) * 256 + (256 - pz)] )
{
for (int i = 0; i < 3; i++)
ipnt[i] += idpnt[i];
px = ipnt[0] >> shiftDown;// / 65536;
py = ipnt[1] >> shiftDown;// / 65536;
pz = ipnt[2] >> shiftDown;/// 65536;
z++;
}
while ( z <= iterations && (256 - py) <= face[1][(256 - pz) * 256 + px] )
{
for (int i = 0; i < 3; i++)
ipnt[i] += idpnt[i];
px = ipnt[0] >> shiftDown;// / 65536;
py = ipnt[1] >> shiftDown;// / 65536;
pz = ipnt[2] >> shiftDown;/// 65536;
z++;
}
while ( z <= iterations && (256 - px) <= face[4][(256 - py) * 256 + pz] )
{
for (int i = 0; i < 3; i++)
ipnt[i] += idpnt[i];
px = ipnt[0] >> shiftDown;// / 65536;
py = ipnt[1] >> shiftDown;// / 65536;
pz = ipnt[2] >> shiftDown;/// 65536;
z++;
}
while ( z <= iterations && (256 - pz) <= face[5][(256 - py) * 256 + (256 - px)] )
{
for (int i = 0; i < 3; i++)
ipnt[i] += idpnt[i];
px = ipnt[0] >> shiftDown;// / 65536;
py = ipnt[1] >> shiftDown;// / 65536;
pz = ipnt[2] >> shiftDown;/// 65536;
z++;
}
/*
if ( px > 0 && px < 256 &&
py > 0 && py < 256 &&
pz > 0 && pz < 256 )
*/
{
// inside = true;
int i3 = (256 - px);
int i4 = (256 - pz);
int i5 = (256 - py);
int j1 = i5 * 256;
int j2 = i4 * 256;
int j3 = pz * 256;
// (65536+256) - ((ipnt[1] >> 8) & ~0xFF) - (ipnt[2] >> 16);
if (
( px > face[0][j1 + i4] )
&& ( i5 > face[1][j2 + px] )
&& ( pz > face[2][j1 + px] )
&& ( py > face[3][j3 + px] )
&& ( i3 > face[4][j1 + pz] )
&& ( i4 > face[5][j1 + i3] )
)
{
//int c = z;//128;
int col = z + c;//128;
data[(y<<8)+x] = 0xff000000 | (col << 16) | (col << 8) | col;
break;
}
}
/*
else
{
if (inside)
{
continue;
}
}
*/
for (int i = 0; i < 3; i++)
ipnt[i] += idpnt[i];
}
}
}
/*
for (int i = 0; i < 256*256; i++)
{
unsigned char z = face[0][i];
data[i] = 0xff000000 | (z << 16) | (z << 8) | z;
}
*/
p.drawImage(0, 0, output);
p.setPen( Qt::green );
p.drawText( 10, 30, QString("fps: %1").arg(calcFPS()) );
}
void Viewer::mouseMoveEvent(QMouseEvent *me)
{
}
void Viewer::mouseClickEvent(QMouseEvent *me)
{
}