|
|
261920 |
|
|
|
261920 |
#include <math.h></math.h>
|
|
|
261920 |
#include <gl gl.h=""></gl>
|
|
|
261920 |
#include <helianthus.h></helianthus.h>
|
|
|
261920 |
|
|
|
261920 |
|
|
|
261920 |
#include "matrix.inc.h"
|
|
|
261920 |
|
|
|
261920 |
|
|
|
261920 |
typedef struct {
|
|
|
261920 |
int colors[6];
|
|
|
261920 |
Matrix position;
|
|
|
261920 |
Vector3 mousePos[6];
|
|
|
261920 |
} Cube;
|
|
|
261920 |
|
|
|
261920 |
|
|
|
261920 |
const double colors[7][4] = {
|
|
|
261920 |
{ 0.25, 0.25, 0.25, 1 }, // gray
|
|
|
261920 |
{ 1 , 1 , 1 , 1 }, // white
|
|
|
261920 |
{ 0 , 0.5 , 0 , 1 }, // green
|
|
|
261920 |
{ 1 , 0.5 , 0 , 1 }, // orange
|
|
|
261920 |
{ 1 , 1 , 0 , 1 }, // yellow
|
|
|
261920 |
{ 0 , 0 , 1 , 1 }, // blue
|
|
|
261920 |
{ 1 , 0 , 0 , 1 }, // red
|
|
|
261920 |
};
|
|
|
261920 |
|
|
|
261920 |
Cube cubes[27];
|
|
|
261920 |
|
|
|
261920 |
Matrix position;
|
|
|
261920 |
double mx, my;
|
|
|
261920 |
|
|
|
261920 |
int turning;
|
|
|
261920 |
Vector3 turnAxis;
|
|
|
261920 |
double turnLayer;
|
|
|
261920 |
double turnAngle;
|
|
|
261920 |
|
|
|
261920 |
|
|
|
261920 |
void randomTurn() {
|
|
|
261920 |
vector3Set(&turnAxis, 0, 0, 0);
|
|
|
261920 |
turnAxis.a[randomNumber(0, 2)] = randomNumber(0, 1)*2 - 1;
|
|
|
261920 |
turnLayer = randomNumber(-1, 1);
|
|
|
261920 |
turnAngle = 0;
|
|
|
261920 |
turning = TRUE;
|
|
|
261920 |
}
|
|
|
261920 |
|
|
|
261920 |
|
|
|
261920 |
void captureMouse(Vector3 *position, double z) {
|
|
|
261920 |
vector3Set(position, 0, 0, 100);
|
|
|
261920 |
|
|
|
261920 |
double mx = mouseX();
|
|
|
261920 |
double my = mouseY();
|
|
|
261920 |
double w = windowGetWidth();
|
|
|
261920 |
double h = windowGetHeight();
|
|
|
261920 |
|
|
|
261920 |
mx = mx/w*2 - 1;
|
|
|
261920 |
my = 1 - my/h*2;
|
|
|
261920 |
Vector4 p0, p1;
|
|
|
261920 |
vector4Set(&p0, mx, my, -1, 1);
|
|
|
261920 |
vector4Set(&p1, mx, my, 1, 1);
|
|
|
261920 |
|
|
|
261920 |
Matrix back, transform, projection, modelview;
|
|
|
261920 |
glGetDoublev(GL_PROJECTION_MATRIX, projection.a);
|
|
|
261920 |
glGetDoublev(GL_MODELVIEW_MATRIX, modelview.a);
|
|
|
261920 |
matrixMultMatrix(&transform, &modelview, &projection);
|
|
|
261920 |
matrixInvert(&back, &transform);
|
|
|
261920 |
|
|
|
261920 |
vector4MultMatrix(&p0, &p0, &back);
|
|
|
261920 |
vector4MultMatrix(&p1, &p1, &back);
|
|
|
261920 |
if (fabs(p0.w) <= 1e-6 || fabs(p1.w) <= 1e-6)
|
|
|
261920 |
return;
|
|
|
261920 |
vector4PespectiveDivide(&p0, &p0);
|
|
|
261920 |
vector4PespectiveDivide(&p1, &p1);
|
|
|
261920 |
|
|
|
261920 |
double dz = p1.z - p0.z;
|
|
|
261920 |
if (fabs(dz) <= 1e-6)
|
|
|
261920 |
return;
|
|
|
261920 |
|
|
|
261920 |
double l = (z - p0.z)/dz;
|
|
|
261920 |
double x = (p1.x - p0.x)*l + p0.x;
|
|
|
261920 |
double y = (p1.y - p0.y)*l + p0.y;
|
|
|
261920 |
|
|
|
261920 |
vector4Set(&p0, x, y, z, 1);
|
|
|
261920 |
vector4MultMatrix(&p0, &p0, &transform);
|
|
|
261920 |
if (fabs(p0.w) <= 1e-6)
|
|
|
261920 |
return;
|
|
|
261920 |
vector4PespectiveDivide(&p0, &p0);
|
|
|
261920 |
vector3Set(position, x, y, p0.z);
|
|
|
261920 |
}
|
|
|
261920 |
|
|
|
261920 |
|
|
|
261920 |
void drawCube(Cube *cube) {
|
|
|
261920 |
const double s = 0.5;
|
|
|
261920 |
const double ss = 0.8*s;
|
|
|
261920 |
const double sq2 = sqrt(2);
|
|
|
261920 |
const double sq3 = sqrt(3);
|
|
|
261920 |
|
|
|
261920 |
glPushMatrix();
|
|
|
261920 |
if (turning && fabs(vector3Dot(&cube->position.ow.xyz, &turnAxis) - turnLayer) < 0.5)
|
|
|
261920 |
glRotated(turnAngle, turnAxis.x, turnAxis.y, turnAxis.z);
|
|
|
261920 |
glMultMatrixd(cube->position.a);
|
|
|
261920 |
|
|
|
261920 |
for(int i = 0; i < 6; ++i) {
|
|
|
261920 |
glColor4dv(colors[cube->colors[i]]);
|
|
|
261920 |
glBegin(GL_QUADS);
|
|
|
261920 |
glNormal3d(0, 0, -1);
|
|
|
261920 |
glVertex3d(-ss, -ss, -s);
|
|
|
261920 |
glVertex3d(-ss, ss, -s);
|
|
|
261920 |
glVertex3d( ss, ss, -s);
|
|
|
261920 |
glVertex3d( ss, -ss, -s);
|
|
|
261920 |
glEnd();
|
|
|
261920 |
|
|
|
261920 |
glColor4dv(colors[0]);
|
|
|
261920 |
glBegin(GL_QUADS);
|
|
|
261920 |
glNormal3d(-sq2, 0, -sq2);
|
|
|
261920 |
glVertex3d(-s, -ss, -ss);
|
|
|
261920 |
glVertex3d(-s, ss, -ss);
|
|
|
261920 |
glVertex3d(-ss, ss, -s);
|
|
|
261920 |
glVertex3d(-ss, -ss, -s);
|
|
|
261920 |
glNormal3d(0, -sq2, -sq2);
|
|
|
261920 |
glVertex3d(-ss, -s, -ss);
|
|
|
261920 |
glVertex3d(-ss, -ss, -s);
|
|
|
261920 |
glVertex3d( ss, -ss, -s);
|
|
|
261920 |
glVertex3d( ss, -s, -ss);
|
|
|
261920 |
glEnd();
|
|
|
261920 |
|
|
|
261920 |
glBegin(GL_TRIANGLES);
|
|
|
261920 |
glNormal3d(-sq3, -sq3, -sq3);
|
|
|
261920 |
glVertex3d(-ss, -ss, -s);
|
|
|
261920 |
glVertex3d(-ss, -s, -ss);
|
|
|
261920 |
glVertex3d(-s, -ss, -ss);
|
|
|
261920 |
glEnd();
|
|
|
261920 |
if (i == 0) {
|
|
|
261920 |
glBegin(GL_TRIANGLES);
|
|
|
261920 |
glNormal3d(-sq3, sq3, -sq3);
|
|
|
261920 |
glVertex3d(-s, ss, -ss);
|
|
|
261920 |
glVertex3d(-ss, s, -ss);
|
|
|
261920 |
glVertex3d(-ss, ss, -s);
|
|
|
261920 |
glEnd();
|
|
|
261920 |
}
|
|
|
261920 |
if (i == 1) {
|
|
|
261920 |
glBegin(GL_TRIANGLES);
|
|
|
261920 |
glNormal3d(sq3, -sq3, -sq3);
|
|
|
261920 |
glVertex3d(s, -ss, -ss);
|
|
|
261920 |
glVertex3d(ss, -s, -ss);
|
|
|
261920 |
glVertex3d(ss, -ss, -s);
|
|
|
261920 |
glEnd();
|
|
|
261920 |
}
|
|
|
261920 |
|
|
|
261920 |
glRotated(90, i%2, -((i+1)%2), 0);
|
|
|
261920 |
}
|
|
|
261920 |
glPopMatrix();
|
|
|
261920 |
}
|
|
|
261920 |
|
|
|
261920 |
|
|
|
261920 |
void init() {
|
|
|
261920 |
background(colorByName("black"));
|
|
|
261920 |
|
|
|
261920 |
Cube *c = cubes;
|
|
|
261920 |
for(int ix = -1; ix <= 1; ++ix)
|
|
|
261920 |
for(int iy = -1; iy <= 1; ++iy)
|
|
|
261920 |
for(int iz = -1; iz <= 1; ++iz, ++c) {
|
|
|
261920 |
if (iz < 0) c->colors[0] = 0+1;
|
|
|
261920 |
if (ix > 0) c->colors[1] = 1+1;
|
|
|
261920 |
if (iy > 0) c->colors[2] = 2+1;
|
|
|
261920 |
if (iz > 0) c->colors[3] = 3+1;
|
|
|
261920 |
if (ix < 0) c->colors[4] = 4+1;
|
|
|
261920 |
if (iy < 0) c->colors[5] = 5+1;
|
|
|
261920 |
c->position.ox.x = c->position.oy.y = c->position.oz.z = c->position.ow.w = 1;
|
|
|
261920 |
c->position.ow.x = ix;
|
|
|
261920 |
c->position.ow.y = iy;
|
|
|
261920 |
c->position.ow.z = iz;
|
|
|
261920 |
}
|
|
|
261920 |
|
|
|
261920 |
matrixSetIdentity(&position);
|
|
|
261920 |
randomTurn();
|
|
|
261920 |
}
|
|
|
261920 |
|
|
|
261920 |
|
|
|
261920 |
void draw() {
|
|
|
261920 |
saveState();
|
|
|
261920 |
|
|
|
261920 |
if (mouseDown("right")) {
|
|
|
261920 |
double ay = mouseX() - mx;
|
|
|
261920 |
double ax = mouseY() - my;
|
|
|
261920 |
Matrix rotation;
|
|
|
261920 |
matrixSetRotation(&rotation, ax, 1, 0, 0);
|
|
|
261920 |
matrixMultMatrix(&position, &position, &rotation);
|
|
|
261920 |
matrixSetRotation(&rotation, ay, 0, 1, 0);
|
|
|
261920 |
matrixMultMatrix(&position, &position, &rotation);
|
|
|
261920 |
}
|
|
|
261920 |
if (mouseDown("middle")) {
|
|
|
261920 |
double az = mouseX() - mx;
|
|
|
261920 |
Matrix rotation;
|
|
|
261920 |
matrixSetRotation(&rotation, az, 0, 0, 1);
|
|
|
261920 |
matrixMultMatrix(&position, &position, &rotation);
|
|
|
261920 |
}
|
|
|
261920 |
mx = mouseX(); my = mouseY();
|
|
|
261920 |
|
|
|
261920 |
if (turning) {
|
|
|
261920 |
turnAngle += windowGetFrameTime()*90;
|
|
|
261920 |
if (turnAngle > 90) {
|
|
|
261920 |
turnAngle = 90;
|
|
|
261920 |
Matrix turningMatrix;
|
|
|
261920 |
matrixSetRotation(&turningMatrix, turnAngle, turnAxis.x, turnAxis.y, turnAxis.z);
|
|
|
261920 |
for(int i = 0; i < 27; ++i) {
|
|
|
261920 |
if (fabs(vector3Dot(&cubes[i].position.ow.xyz, &turnAxis) - turnLayer) < 0.5)
|
|
|
261920 |
matrixMultMatrix(&cubes[i].position, &cubes[i].position, &turningMatrix);
|
|
|
261920 |
}
|
|
|
261920 |
turning = FALSE;
|
|
|
261920 |
randomTurn();
|
|
|
261920 |
}
|
|
|
261920 |
}
|
|
|
261920 |
|
|
|
261920 |
glClear(GL_DEPTH_BUFFER_BIT);
|
|
|
261920 |
glEnable(GL_DEPTH_TEST);
|
|
|
261920 |
glEnable(GL_CULL_FACE);
|
|
|
261920 |
glEnable(GL_COLOR_MATERIAL);
|
|
|
261920 |
glEnable(GL_LIGHTING);
|
|
|
261920 |
glEnable(GL_LIGHT0);
|
|
|
261920 |
|
|
|
261920 |
Matrix perspective;
|
|
|
261920 |
matrixSetPerspective(&perspective, 100.0, windowGetWidth()/(double)windowGetHeight(), 0.01, 100);
|
|
|
261920 |
glMatrixMode(GL_PROJECTION);
|
|
|
261920 |
glLoadMatrixd(perspective.a);
|
|
|
261920 |
glMatrixMode(GL_MODELVIEW);
|
|
|
261920 |
glLoadIdentity();
|
|
|
261920 |
glTranslated(0, 0, -5);
|
|
|
261920 |
glMultMatrixd(position.a);
|
|
|
261920 |
|
|
|
261920 |
for(int i = 0; i < 27; ++i)
|
|
|
261920 |
drawCube(&cubes[i]);
|
|
|
261920 |
|
|
|
261920 |
glDisable(GL_DEPTH_TEST);
|
|
|
261920 |
restoreState();
|
|
|
261920 |
}
|
|
|
261920 |
|
|
|
261920 |
|
|
|
261920 |
int main() {
|
|
|
261920 |
windowSetVariableFrameRate();
|
|
|
261920 |
windowSetResizable(TRUE);
|
|
|
261920 |
windowSetInit(&init);
|
|
|
261920 |
windowSetDraw(&draw);
|
|
|
261920 |
windowRun();
|
|
|
261920 |
}
|
|
|
261920 |
|