1 /*
2 File: PolyCube.cpp
3 Description: PolyCube management
4 Program: BlockOut
5 Author: Jean-Luc PONS
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 */
17
18 #include "PolyCube.h"
19 #include <math.h>
20
21 #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
22
23 #define DIR_OX 1
24 #define DIR_OY 2
25 #define DIR_OZ 3
26
27 const EDGE edgeOrg[] = {
28
29 {{0,1,0} , {1,1,0} , DIR_OX} , // 0
30 {{1,1,0} , {1,0,0} , DIR_OY} , // 1
31 {{0,0,0} , {1,0,0} , DIR_OX} , // 2
32 {{0,1,0} , {0,0,0} , DIR_OY} , // 3
33
34 {{0,1,0} , {0,1,1} , DIR_OZ} , // 4
35 {{1,1,0} , {1,1,1} , DIR_OZ} , // 5
36 {{1,0,0} , {1,0,1} , DIR_OZ} , // 6
37 {{0,0,0} , {0,0,1} , DIR_OZ} , // 7
38
39 {{0,1,1} , {1,1,1} , DIR_OX} , // 8
40 {{1,1,1} , {1,0,1} , DIR_OY} , // 9
41 {{0,0,1} , {1,0,1} , DIR_OX} , // 10
42 {{0,1,1} , {0,0,1} , DIR_OY} // 11
43
44 };
45
46 //-----------------------------------------------------------------------------
47
PolyCube()48 PolyCube::PolyCube() {
49
50 lineList = 0;
51 ghostList = 0;
52 bigEdgeList = 0;
53 nbCube = 0;
54 hScore = 0;
55 lScore = 0;
56 isFlat = FALSE;
57 isBasic = FALSE;
58 hasGhost = FALSE;
59 nbOrientation = 0;
60 hasGhost = FALSE;
61 edges = (EDGE *)malloc(MAX_CUBE*12*sizeof(EDGE));
62 allRot = (ORIENTATION *)malloc(24*sizeof(ORIENTATION));
63
64 }
65
66 //-----------------------------------------------------------------------------
67
~PolyCube()68 PolyCube::~PolyCube() {
69 free(edges);
70 free(allRot);
71 }
72
73 //-----------------------------------------------------------------------------
74
SetInfo(int highScore,int lowScore,BOOL flat,BOOL basic)75 void PolyCube::SetInfo(int highScore,int lowScore,BOOL flat,BOOL basic) {
76
77 hScore = highScore;
78 lScore = lowScore;
79 isFlat = flat;
80 isBasic = basic;
81
82 }
83
84 //-----------------------------------------------------------------------------
85
AddCube(int x,int y,int z)86 void PolyCube::AddCube(int x,int y,int z) {
87
88 if( nbCube<MAX_CUBE ) {
89 cubes[nbCube].x = x;
90 cubes[nbCube].y = y;
91 cubes[nbCube].z = z;
92 nbCube++;
93 }
94
95 }
96
97 //-----------------------------------------------------------------------------
98
AddOrientation(int r0,int r1,int r2)99 void PolyCube::AddOrientation(int r0,int r1,int r2) {
100 allRot[nbOrientation].r0 = r0;
101 allRot[nbOrientation].r1 = r1;
102 allRot[nbOrientation].r2 = r2;
103 nbOrientation++;
104 }
105
106 //-----------------------------------------------------------------------------
107
GetOrientationAt(int idx)108 ORIENTATION *PolyCube::GetOrientationAt(int idx) {
109 return &(allRot[idx]);
110 }
111
112 //-----------------------------------------------------------------------------
GetNbOrientation()113 int PolyCube::GetNbOrientation() {
114 return nbOrientation;
115 }
116
117 //-----------------------------------------------------------------------------
118
GetHighScore()119 int PolyCube::GetHighScore() {
120
121 return hScore;
122
123 }
124
125 //-----------------------------------------------------------------------------
126
GetLowScore()127 int PolyCube::GetLowScore() {
128
129 return lScore;
130
131 }
132
133 //-----------------------------------------------------------------------------
134
IsInSet(int set)135 BOOL PolyCube::IsInSet(int set) {
136
137 switch(set) {
138 case BLOCKSET_EXTENDED:
139 return TRUE;
140 case BLOCKSET_BASIC:
141 return isBasic;
142 case BLOCKSET_FLAT:
143 return isFlat;
144 }
145
146 return FALSE;
147
148 }
149
150 //-----------------------------------------------------------------------------
151
GetNbCube()152 int PolyCube::GetNbCube() {
153
154 return nbCube;
155
156 }
157
158 //-----------------------------------------------------------------------------
159
GetWidth()160 int PolyCube::GetWidth() {
161 int maxW = 0;
162 for(int i=0;i<nbCube;i++)
163 if(cubes[i].x > maxW) maxW = cubes[i].x;
164 return maxW + 1;
165 }
166
167 //-----------------------------------------------------------------------------
168
GetHeight()169 int PolyCube::GetHeight() {
170 int maxH = 0;
171 for(int i=0;i<nbCube;i++)
172 if(cubes[i].y > maxH) maxH = cubes[i].y;
173 return maxH + 1;
174 }
175
176 //-----------------------------------------------------------------------------
177
GetDepth()178 int PolyCube::GetDepth() {
179 int maxD = 0;
180 for(int i=0;i<nbCube;i++)
181 if(cubes[i].z > maxD) maxD = cubes[i].z;
182 return maxD + 1;
183 }
184
185 //-----------------------------------------------------------------------------
186
GetMaxDim()187 int PolyCube::GetMaxDim() {
188 int w = GetWidth();
189 int h = GetHeight();
190 int d = GetDepth();
191 int maxDim = w;
192 if( h > maxDim ) maxDim = h;
193 if( d > maxDim ) maxDim = d;
194 return maxDim;
195 }
196
197 //-----------------------------------------------------------------------------
198
InitRotationCenter()199 void PolyCube::InitRotationCenter() {
200
201 // Emulate "BlockOut original" rotation center
202 iCenter.x = GetWidth() - 1;
203 iCenter.y = 1;
204 iCenter.z = GetDepth() - 1;
205
206 center.x = iCenter.x * cubeSide + origin.x;
207 center.y = iCenter.y * cubeSide + origin.y;
208 center.z = iCenter.z * cubeSide + origin.z;
209
210 }
211 //-----------------------------------------------------------------------------
212
EdgeExist(EDGE e)213 BOOL PolyCube::EdgeExist(EDGE e) {
214
215 BOOL found = FALSE;
216 int i = 0;
217 while(i<nbEdge && !found) {
218 found = EdgeEqual(edges[i],e);
219 if(!found) i++;
220 }
221 return found;
222
223 }
224
225 //-----------------------------------------------------------------------------
226
GetEdgesAtCorner(int x,int y,int z,int * nb,int * direction)227 void PolyCube::GetEdgesAtCorner(int x,int y,int z,int *nb,int *direction) {
228
229 int vx,vy,vz;
230
231 for(int i=0;i<nbEdge;i++) {
232
233 EDGE e = edges[i];
234 vx=0; vy=0; vz=0;
235
236 if( (e.p1.x == x && e.p1.y == y && e.p1.z == z) ) {
237 vx = e.p1.x - e.p2.x;
238 vy = e.p1.y - e.p2.y;
239 vz = e.p1.z - e.p2.z;
240 }
241
242 if( (e.p2.x == x && e.p2.y == y && e.p2.z == z) ) {
243 vx = e.p2.x - e.p1.x;
244 vy = e.p2.y - e.p1.y;
245 vz = e.p2.z - e.p1.z;
246 }
247
248 if( vx ) {
249 if( vx<0 ) direction[*nb] = -DIR_OX;
250 else direction[*nb] = DIR_OX;
251 *nb=*nb+1;
252 } else if( vy ) {
253 if( vy<0 ) direction[*nb] = -DIR_OY;
254 else direction[*nb] = DIR_OY;
255 *nb=*nb+1;
256 } else if( vz ) {
257 if( vz<0 ) direction[*nb] = -DIR_OZ;
258 else direction[*nb] = DIR_OZ;
259 *nb=*nb+1;
260 }
261
262 }
263
264 }
265
266 //-----------------------------------------------------------------------------
267
IsPermut(int d1,int d2,int d3,int * dir)268 BOOL PolyCube::IsPermut(int d1,int d2,int d3,int *dir) {
269
270 return (d1==dir[0] && d2==dir[1] && d3==dir[2]) ||
271 (d1==dir[0] && d2==dir[2] && d3==dir[1]) ||
272 (d1==dir[1] && d2==dir[0] && d3==dir[2]) ||
273 (d1==dir[1] && d2==dir[2] && d3==dir[0]) ||
274 (d1==dir[2] && d2==dir[1] && d3==dir[0]) ||
275 (d1==dir[2] && d2==dir[0] && d3==dir[1]);
276
277 }
278
279 //-----------------------------------------------------------------------------
280
GetCornerAt(int x,int y,int z,VERTEX * o)281 BOOL PolyCube::GetCornerAt(int x,int y,int z,VERTEX *o) {
282
283 int direction[8]; // 4 should be the max
284 int nbDir=0;
285
286 GetEdgesAtCorner(x,y,z,&nbDir,direction);
287 if( nbDir==3 ) {
288 if( IsPermut(-DIR_OX,+DIR_OY,-DIR_OZ,direction) ) {
289 o->x = -1.0f; o->y = 1.0f; o->z = -1.0f;
290 return TRUE;
291 } else if( IsPermut(+DIR_OX,+DIR_OY,-DIR_OZ,direction) ) {
292 o->x = 1.0f; o->y = 1.0f; o->z = -1.0f;
293 return TRUE;
294 } else if( IsPermut(+DIR_OX,-DIR_OY,-DIR_OZ,direction) ) {
295 o->x = 1.0f; o->y = -1.0f; o->z = -1.0f;
296 return TRUE;
297 } else if( IsPermut(-DIR_OX,-DIR_OY,-DIR_OZ,direction) ) {
298 o->x = -1.0f; o->y = -1.0f; o->z = -1.0f;
299 return TRUE;
300 } else if( IsPermut(-DIR_OX,+DIR_OY,+DIR_OZ,direction) ) {
301 o->x = -1.0f; o->y = 1.0f; o->z = 1.0f;
302 return TRUE;
303 } else if( IsPermut(+DIR_OX,+DIR_OY,+DIR_OZ,direction) ) {
304 o->x = 1.0f; o->y = 1.0f; o->z = 1.0f;
305 return TRUE;
306 } else if( IsPermut(+DIR_OX,-DIR_OY,+DIR_OZ,direction) ) {
307 o->x = 1.0f; o->y = -1.0f; o->z = 1.0f;
308 return TRUE;
309 } else if( IsPermut(-DIR_OX,-DIR_OY,+DIR_OZ,direction) ) {
310 o->x = -1.0f; o->y = -1.0f; o->z = 1.0f;
311 return TRUE;
312 }
313 }
314
315 return FALSE;
316
317 }
318
319 //-----------------------------------------------------------------------------
320
EdgeEqual(EDGE e1,EDGE e2)321 BOOL PolyCube::EdgeEqual(EDGE e1,EDGE e2) {
322
323 return ((e1.p1.x == e2.p1.x && e1.p1.y == e2.p1.y && e1.p1.z == e2.p1.z) &&
324 (e1.p2.x == e2.p2.x && e1.p2.y == e2.p2.y && e1.p2.z == e2.p2.z) ) ||
325 ((e1.p1.x == e2.p2.x && e1.p1.y == e2.p2.y && e1.p1.z == e2.p2.z) &&
326 (e1.p2.x == e2.p1.x && e1.p2.y == e2.p1.y && e1.p2.z == e2.p1.z) );
327
328 }
329
330 //-----------------------------------------------------------------------------
331
Create(float cSide,VERTEX org,int ghost,float wEdge)332 int PolyCube::Create(float cSide,VERTEX org,int ghost,float wEdge) {
333
334 int hr;
335
336 cubeSide = cSide;
337 origin = org;
338 hasBigEdge = (wEdge!=0.0f);
339
340 // Create edge
341
342 nbEdge = 0;
343 for(int i=0;i<nbCube;i++) {
344 for(int j=0;j<12;j++) {
345 if( IsEdgeVisible(i,j) ) {
346
347 EDGE e;
348 e.p1.x = cubes[i].x + edgeOrg[j].p1.x;
349 e.p1.y = cubes[i].y + edgeOrg[j].p1.y;
350 e.p1.z = cubes[i].z + edgeOrg[j].p1.z;
351
352 e.p2.x = cubes[i].x + edgeOrg[j].p2.x;
353 e.p2.y = cubes[i].y + edgeOrg[j].p2.y;
354 e.p2.z = cubes[i].z + edgeOrg[j].p2.z;
355
356 e.orientation = edgeOrg[j].orientation;
357
358 if(!EdgeExist(e)) edges[nbEdge++] = e;
359
360 }
361 }
362 }
363
364 if(!hasBigEdge) {
365 hr = CreateLineEdge();
366 if(!hr) return GL_FAIL;
367 } else {
368 hr = CreateCylinderEdges(wEdge*cubeSide);
369 if(!hr) return GL_FAIL;
370 }
371
372
373 // Init material
374 memset (&whiteMaterial, 0, sizeof (GLMATERIAL));
375 whiteMaterial.Diffuse.r = 1.0f;
376 whiteMaterial.Diffuse.g = 1.0f;
377 whiteMaterial.Diffuse.b = 1.0f;
378 whiteMaterial.Ambient.r = 1.0f;
379 whiteMaterial.Ambient.g = 1.0f;
380 whiteMaterial.Ambient.b = 1.0f;
381
382 memset (&redMaterial, 0, sizeof (GLMATERIAL));
383 redMaterial.Diffuse.r = 1.0f;
384 redMaterial.Diffuse.g = 0.0f;
385 redMaterial.Diffuse.b = 0.0f;
386 redMaterial.Ambient.r = 1.0f;
387 redMaterial.Ambient.g = 0.0f;
388 redMaterial.Ambient.b = 0.0f;
389
390 memset (&ghostMaterial, 0, sizeof (GLMATERIAL));
391
392 memset (&grayMaterial, 0, sizeof (GLMATERIAL));
393 grayMaterial.Diffuse.r = 0.8f;
394 grayMaterial.Diffuse.g = 0.8f;
395 grayMaterial.Diffuse.b = 0.8f;
396 grayMaterial.Ambient.r = 0.5f;
397 grayMaterial.Ambient.g = 0.5f;
398 grayMaterial.Ambient.b = 0.5f;
399 grayMaterial.Specular.r = 1.0f;
400 grayMaterial.Specular.g = 1.0f;
401 grayMaterial.Specular.b = 1.0f;
402 grayMaterial.Power = 20.0f;
403
404 InitRotationCenter();
405
406 // Ghost
407 hasGhost = (ghost!=0);
408 if( hasGhost ) {
409 if( !CreateGhost(ghost) ) return GL_FAIL;
410 }
411
412 return GL_OK;
413 }
414
415 //-----------------------------------------------------------------------------
416
CreateLineEdge()417 int PolyCube::CreateLineEdge() {
418
419 lineList = glGenLists(1);
420 glNewList(lineList,GL_COMPILE);
421 glBegin(GL_LINES);
422
423 for(int i=0;i<nbEdge;i++) {
424
425 glVertex3f( (float)(edges[i].p1.x) * cubeSide + origin.x,
426 (float)(edges[i].p1.y) * cubeSide + origin.y,
427 (float)(edges[i].p1.z) * cubeSide + origin.z);
428
429 glVertex3f( (float)(edges[i].p2.x) * cubeSide + origin.x,
430 (float)(edges[i].p2.y) * cubeSide + origin.y,
431 (float)(edges[i].p2.z) * cubeSide + origin.z);
432
433 }
434
435 glEnd();
436 glEndList();
437
438 return GL_OK;
439 }
440
441 //-----------------------------------------------------------------------------
442
CreateCylinderEdges(float wEdge)443 int PolyCube::CreateCylinderEdges(float wEdge) {
444
445 CORNER corner[40];
446 int nbCorner=0;
447 int nbDiv = 6;
448 VERTEX oV;
449
450 // Compute corner, node where 3 edges intersect
451 for(int i=0;i<=GetWidth();i++) {
452 for(int j=0;j<=GetHeight();j++) {
453 for(int k=0;k<=GetDepth();k++) {
454 if( GetCornerAt(i,j,k,&oV) ) {
455 corner[nbCorner].p.x = (float)i * cubeSide + origin.x;
456 corner[nbCorner].p.y = (float)j * cubeSide + origin.y;
457 corner[nbCorner].p.z = (float)k * cubeSide + origin.z;
458 corner[nbCorner].o = oV;
459 nbCorner++;
460 }
461 }
462 }
463 }
464
465 bigEdgeList = glGenLists(1);
466 glNewList(bigEdgeList,GL_COMPILE);
467
468 // Edge cylinder
469 glBegin(GL_QUADS);
470
471 for(int i=0;i<nbEdge;i++) {
472
473 float x1c = (float)(edges[i].p1.x) * cubeSide + origin.x;
474 float y1c = (float)(edges[i].p1.y) * cubeSide + origin.y;
475 float z1c = (float)(edges[i].p1.z) * cubeSide + origin.z;
476
477 float x2c = (float)(edges[i].p2.x) * cubeSide + origin.x;
478 float y2c = (float)(edges[i].p2.y) * cubeSide + origin.y;
479 float z2c = (float)(edges[i].p2.z) * cubeSide + origin.z;
480
481 for(int j=0;j<nbDiv;j++) {
482
483 float x,y,z,nx,ny,nz;
484 float x2,y2,z2,nx2,ny2,nz2;
485 float angle = (float)j/(float)nbDiv * 2.0f * PI;
486 float angle2 = (float)(j+1)/(float)nbDiv * 2.0f * PI;
487
488 // Create vertex
489 switch(edges[i].orientation) {
490
491 case DIR_OX:
492 nx = 0.0;
493 ny = cosf(angle);
494 nz = sinf(angle);
495 nx2 = 0.0;
496 ny2 = cosf(angle2);
497 nz2 = sinf(angle2);
498 break;
499
500 case DIR_OY:
501 nx = cosf(angle);
502 ny = 0.0;
503 nz = sinf(angle);
504 nx2 = cosf(angle2);
505 ny2 = 0.0;
506 nz2 = sinf(angle2);
507 break;
508
509 case DIR_OZ:
510 nx = cosf(angle);
511 ny = sinf(angle);
512 nz = 0.0;
513 nx2 = cosf(angle2);
514 ny2 = sinf(angle2);
515 nz2 = 0.0;
516 break;
517
518 }
519
520 x = wEdge * nx;
521 y = wEdge * ny;
522 z = wEdge * nz;
523 x2 = wEdge * nx2;
524 y2 = wEdge * ny2;
525 z2 = wEdge * nz2;
526
527 glNormal3f(nx,ny,nz);
528 glVertex3f(x1c + x,y1c + y,z1c + z);
529
530 glNormal3f(nx,ny,nz);
531 glVertex3f(x2c + x,y2c + y,z2c + z);
532
533 glNormal3f(nx2,ny2,nz2);
534 glVertex3f(x2c + x2,y2c + y2,z2c + z2);
535
536 glNormal3f(nx2,ny2,nz2);
537 glVertex3f(x1c + x2,y1c + y2,z1c + z2);
538
539 }
540
541 }
542
543 glEnd();
544
545 // Corner
546
547 glBegin(GL_TRIANGLES);
548
549 for(int i=0;i<nbCorner;i++) {
550
551 glNormal3f(0.0f,0.0f,corner[i].o.z);
552 glVertex3f(corner[i].p.x,corner[i].p.y,corner[i].p.z+wEdge*corner[i].o.z);
553
554 glNormal3f(corner[i].o.x,0.0f,0.0f);
555 glVertex3f(corner[i].p.x+wEdge*corner[i].o.x,corner[i].p.y,corner[i].p.z);
556
557 glNormal3f(0.0f,corner[i].o.y,0.0f);
558 glVertex3f(corner[i].p.x,corner[i].p.y+wEdge*corner[i].o.y,corner[i].p.z);
559
560 //--
561
562 glNormal3f(0.0f,0.0f,corner[i].o.z);
563 glVertex3f(corner[i].p.x,corner[i].p.y,corner[i].p.z+wEdge*corner[i].o.z);
564
565 glNormal3f(0.0f,corner[i].o.y,0.0f);
566 glVertex3f(corner[i].p.x,corner[i].p.y+wEdge*corner[i].o.y,corner[i].p.z);
567
568 glNormal3f(corner[i].o.x,0.0f,0.0f);
569 glVertex3f(corner[i].p.x+wEdge*corner[i].o.x,corner[i].p.y,corner[i].p.z);
570
571 }
572
573 glEnd();
574 glEndList();
575
576 return GL_OK;
577
578 }
579
580
581 //-----------------------------------------------------------------------------
582
gV(int cubeIdx,int x,int y,int z,float nx,float ny,float nz)583 void PolyCube::gV(int cubeIdx,int x,int y,int z,float nx,float ny,float nz) {
584
585 glNormal3f(nx,ny,nz);
586 glVertex3f((cubes[cubeIdx].x+x) * cubeSide + origin.x,
587 (cubes[cubeIdx].y+y) * cubeSide + origin.y,
588 (cubes[cubeIdx].z+z) * cubeSide + origin.z);
589
590 }
591
592 //-----------------------------------------------------------------------------
593
CreateGhost(int value)594 int PolyCube::CreateGhost(int value) {
595
596 // Create face
597
598 ghostList = glGenLists(1);
599 glNewList(ghostList,GL_COMPILE);
600 glBegin(GL_QUADS);
601
602 for(int i=0;i<nbCube;i++) {
603
604 // Face 0
605 if( IsFaceVisible(i,0) ) {
606 gV(i,0,0,0, 0.0f,0.0f,-1.0f);
607 gV(i,0,1,0, 0.0f,0.0f,-1.0f);
608 gV(i,1,1,0, 0.0f,0.0f,-1.0f);
609 gV(i,1,0,0, 0.0f,0.0f,-1.0f);
610 }
611
612 // Face 1
613 if( IsFaceVisible(i,1) ) {
614 gV(i,0,0,1, -1.0f,0.0f,0.0f);
615 gV(i,0,1,1, -1.0f,0.0f,0.0f);
616 gV(i,0,1,0, -1.0f,0.0f,0.0f);
617 gV(i,0,0,0, -1.0f,0.0f,0.0f);
618 }
619
620 // Face 2
621 if( IsFaceVisible(i,2) ) {
622 gV(i,1,0,1, 0.0f,0.0f,1.0f);
623 gV(i,1,1,1, 0.0f,0.0f,1.0f);
624 gV(i,0,1,1, 0.0f,0.0f,1.0f);
625 gV(i,0,0,1, 0.0f,0.0f,1.0f);
626 }
627
628 // Face 3
629 if( IsFaceVisible(i,3) ) {
630 gV(i,1,0,0, 1.0f,0.0f,0.0f);
631 gV(i,1,1,0, 1.0f,0.0f,0.0f);
632 gV(i,1,1,1, 1.0f,0.0f,0.0f);
633 gV(i,1,0,1, 1.0f,0.0f,0.0f);
634 }
635
636 // Face 4
637 if( IsFaceVisible(i,4) ) {
638 gV(i,0,1,0, 0.0f,1.0f,0.0f);
639 gV(i,0,1,1, 0.0f,1.0f,0.0f);
640 gV(i,1,1,1, 0.0f,1.0f,0.0f);
641 gV(i,1,1,0, 0.0f,1.0f,0.0f);
642 }
643
644 // Face 5
645 if( IsFaceVisible(i,5) ) {
646 gV(i,1,0,0, 0.0f,-1.0f,0.0f);
647 gV(i,1,0,1, 0.0f,-1.0f,0.0f);
648 gV(i,0,0,1, 0.0f,-1.0f,0.0f);
649 gV(i,0,0,0, 0.0f,-1.0f,0.0f);
650 }
651
652 }
653
654 glEnd();
655 glEndList();
656
657 // Ghost material
658 float trans = ((float)value / (float)FTRANS_MAX) * 0.4f;
659
660 ghostMaterial.Diffuse.r = 0.5f;
661 ghostMaterial.Diffuse.g = 0.5f;
662 ghostMaterial.Diffuse.b = 0.5f;
663 ghostMaterial.Diffuse.a = trans;
664 ghostMaterial.Ambient.r = 0.5f;
665 ghostMaterial.Ambient.g = 0.5f;
666 ghostMaterial.Ambient.b = 0.5f;
667 ghostMaterial.Ambient.a = trans;
668
669 return GL_OK;
670
671 }
672
673 //-----------------------------------------------------------------------------
674
CopyCube(BLOCKITEM * c,int * nb)675 void PolyCube::CopyCube(BLOCKITEM *c,int *nb) {
676
677 for(int i=0;i<nbCube;i++) {
678 c[i] = cubes[i];
679 }
680 *nb = nbCube;
681
682 }
683
684 //-----------------------------------------------------------------------------
685
GetRCenter()686 VERTEX PolyCube::GetRCenter() {
687
688 return center;
689
690 }
691
692 //-----------------------------------------------------------------------------
693
GetICenter()694 BLOCKITEM PolyCube::GetICenter() {
695
696 return iCenter;
697
698 }
699
700 //-----------------------------------------------------------------------------
701
FindCube(int x,int y,int z)702 BOOL PolyCube::FindCube(int x,int y,int z) {
703
704 BOOL found = FALSE;
705 int i = 0;
706 while(i<nbCube && !found) {
707 found = (cubes[i].x == x) && (cubes[i].y == y) && (cubes[i].z == z);
708 if(!found) i++;
709 }
710
711 return found;
712
713 }
714
715 //-----------------------------------------------------------------------------
716
IsFaceVisible(int cubeIdx,int face)717 BOOL PolyCube::IsFaceVisible(int cubeIdx,int face) {
718
719 int x = cubes[cubeIdx].x;
720 int y = cubes[cubeIdx].y;
721 int z = cubes[cubeIdx].z;
722
723 switch(face) {
724 case 0:
725 return !FindCube(x,y,z-1);
726 break;
727 case 1:
728 return !FindCube(x-1,y,z);
729 break;
730 case 2:
731 return !FindCube(x,y,z+1);
732 break;
733 case 3:
734 return !FindCube(x+1,y,z);
735 break;
736 case 4:
737 return !FindCube(x,y+1,z);
738 break;
739 case 5:
740 return !FindCube(x,y-1,z);
741 break;
742 }
743
744 return FALSE;
745
746 }
747
748 //-----------------------------------------------------------------------------
749
IsEdgeVisible(int cubeIdx,int edge)750 BOOL PolyCube::IsEdgeVisible(int cubeIdx,int edge) {
751
752 int nb = 0;
753 BOOL e1,e2,e3;
754
755 int x = cubes[cubeIdx].x;
756 int y = cubes[cubeIdx].y;
757 int z = cubes[cubeIdx].z;
758
759 switch(edge) {
760
761 case 0:
762 e1 = FindCube(x,y,z-1);e2 = FindCube(x,y+1,z-1);e3 = FindCube(x,y+1,z);
763 break;
764 case 1:
765 e1 = FindCube(x,y,z-1);e2 = FindCube(x+1,y,z-1);e3 = FindCube(x+1,y,z);
766 break;
767 case 2:
768 e1 = FindCube(x,y,z-1);e2 = FindCube(x,y-1,z-1);e3 = FindCube(x,y-1,z);
769 break;
770 case 3:
771 e1 = FindCube(x,y,z-1);e2 = FindCube(x-1,y,z-1);e3 = FindCube(x-1,y,z);
772 break;
773
774 case 4:
775 e1 = FindCube(x,y+1,z);e2 = FindCube(x-1,y+1,z);e3 = FindCube(x-1,y,z);
776 break;
777 case 5:
778 e1 = FindCube(x,y+1,z);e2 = FindCube(x+1,y+1,z);e3 = FindCube(x+1,y,z);
779 break;
780 case 6:
781 e1 = FindCube(x+1,y,z);e2 = FindCube(x+1,y-1,z);e3 = FindCube(x,y-1,z);
782 break;
783 case 7:
784 e1 = FindCube(x,y-1,z);e2 = FindCube(x-1,y-1,z);e3 = FindCube(x-1,y,z);
785 break;
786
787 case 8:
788 e1 = FindCube(x,y+1,z);e2 = FindCube(x,y+1,z+1);e3 = FindCube(x,y,z+1);
789 break;
790 case 9:
791 e1 = FindCube(x+1,y,z);e2 = FindCube(x+1,y,z+1);e3 = FindCube(x,y,z+1);
792 break;
793 case 10:
794 e1 = FindCube(x,y-1,z);e2 = FindCube(x,y-1,z+1);e3 = FindCube(x,y,z+1);
795 break;
796 case 11:
797 e1 = FindCube(x-1,y,z);e2 = FindCube(x-1,y,z+1);e3 = FindCube(x,y,z+1);
798 break;
799
800 }
801
802 return !( (!e1 && !e2 && e3) || (e1 && !e2 && !e3) || (e1 && e2 && e3) );
803
804 }
805
806 //-----------------------------------------------------------------------------
807
Render(BOOL redMode)808 void PolyCube::Render(BOOL redMode) {
809
810 glEnable(GL_LIGHTING);
811 glDisable(GL_DEPTH_TEST);
812 glDisable(GL_TEXTURE_2D);
813
814 if( hasGhost ) {
815
816 // Alpha texture
817 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
818 glEnable(GL_BLEND);
819 GLApplication::SetMaterial(&ghostMaterial);
820
821 // Draw back face first
822 glEnable(GL_CULL_FACE);
823 glCullFace(GL_FRONT);
824 glCallList(ghostList);
825
826 // Draw front face
827 glCullFace(GL_BACK);
828 glCallList(ghostList);
829
830 }
831
832 glDisable(GL_TEXTURE_2D);
833 glDisable(GL_LIGHTING);
834 glDisable(GL_BLEND);
835 glDisable(GL_CULL_FACE);
836
837 // Draw the polycube
838 if( hasBigEdge ) {
839
840 if(redMode)
841 GLApplication::SetMaterial (&redMaterial);
842 else
843 GLApplication::SetMaterial (&grayMaterial);
844
845 glEnable(GL_DEPTH_TEST);
846 glEnable(GL_LIGHTING);
847 glCallList(bigEdgeList);
848 glDisable(GL_LIGHTING);
849 glDisable(GL_DEPTH_TEST);
850
851 } else {
852
853 if(redMode)
854 GLApplication::SetMaterial (&redMaterial);
855 else
856 GLApplication::SetMaterial (&whiteMaterial);
857
858 glCallList(lineList);
859
860 }
861
862 }
863
864 //-----------------------------------------------------------------------------
865
InvalidateDeviceObjects()866 void PolyCube::InvalidateDeviceObjects() {
867
868 DELETE_LIST(lineList);
869 DELETE_LIST(ghostList);
870 DELETE_LIST(bigEdgeList);
871 nbCube = 0;
872 nbOrientation = 0;
873
874 }
875