00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 #ifndef WIN32
00085 #include "x3d.h"
00086 #include "X3DBuffer.h"
00087 #endif
00088
00089 #ifdef WIN32
00090
00091 unsigned long x3d_main(float *longitude, float *latitude, float *psi,
00092 const char *string) { return 0L; }
00093 void x3d_terminate() { }
00094 void x3d_get_position(float *longitude, float *latitude, float *psi) { }
00095 int x3d_dispatch_event(unsigned long event) { return 0; }
00096 void x3d_set_display(unsigned long display) { }
00097 void x3d_update() { }
00098
00099 #else
00100
00101
00102 #include <stdio.h>
00103 #include <math.h>
00104 #include <string.h>
00105 #include <stdlib.h>
00106 #include <X11/Xlib.h>
00107 #include <X11/Xatom.h>
00108 #include <X11/Xutil.h>
00109 #include <X11/X.h>
00110
00111
00112 extern Color *colors;
00113 extern point *points;
00114 extern segment *segs;
00115 extern polygon *polys;
00116
00117 extern int currPoint, currSeg, currPoly;
00118
00119 static polygon **list;
00120 static point *bounds;
00121 static int quitApplication = 0;
00122 static Display *gDisplay = NULL;
00123 static Ginfo *gGInfo = NULL;
00124 static Oinfo *gOInfo = NULL;
00125
00126 static int gRedDiv, gGreenDiv, gBlueDiv, gRedShift, gGreenShift, gBlueShift;
00127
00128
00129
00130 static void sort(list1, numPolys)
00131 polygon **list1;
00132 int numPolys;
00133
00134
00135
00136 {
00137 polygon **v0, **v1, **v2, **v3, **v4, **v5, **v6, *poly;
00138 register int stackIndex, stackNotSet, length, start, end, high;
00139 float dist;
00140 int numPoints;
00141 StackElement stack[MAXSTACK];
00142 point **Point, **lastPoint;
00143
00144 v0 = list1;
00145 v1 = &(list1[numPolys]);
00146
00147
00148
00149 while(v0 < v1){
00150 poly = *v0;
00151 numPoints = poly->numPoints;
00152 Point = poly->points;
00153 lastPoint = Point + numPoints;
00154 dist = 0.0;
00155
00156 do{
00157 dist += (*Point)->dist;
00158 Point++;
00159 }while(Point < lastPoint);
00160
00161 poly->dist = dist / ((float)numPoints);
00162 v0++;
00163 }
00164
00165
00166
00167 stackIndex = 1;
00168 stackNotSet = 0;
00169 start = 0;
00170 end = numPolys - 1;
00171
00172
00173
00174 while(stackIndex){
00175
00176 if(stackNotSet){
00177 start = stack[stackIndex].start;
00178 end = stack[stackIndex].end;
00179 }
00180
00181 stackIndex--;
00182 stackNotSet = 1;
00183 length = end - start;
00184
00185
00186
00187 if(length > STOP){
00188 v1 = &(list1[start]);
00189 v2 = &(list1[start + (length / 4)]);
00190 v3 = &(list1[start + (length / 2)]);
00191 v4 = &(list1[start + ((length * 3) / 4)]);
00192 v5 = &(list1[end]);
00193 v6 = v1;
00194
00195 median5(v1,v2,v3,v4,v5)
00196
00197 *v0 = *v3;
00198 *v3 = *v6;
00199 *v6 = *v0;
00200
00201 v1 = &(list1[start + 1]);
00202 v2 = &(list1[end]);
00203
00204
00205
00206 dist = (*v6)->dist;
00207 while((*v2)->dist < dist) v2--;
00208 while((*v1)->dist > dist) v1++;
00209
00210 v5 = v0;
00211
00212 while(v1 < v2){
00213
00214 *v5 = *v2;
00215 *v2 = *v1;
00216
00217 v5 = v1;
00218
00219 do{
00220 v2--;
00221 }while(((*v2)->dist < dist) && (v1 < v2));
00222 if (v2 <= v1) break;
00223
00224 do{
00225 v1++;
00226 }while(((*v1)->dist > dist) && (v1 < v2));
00227 if (v2 <= v1) break;
00228 }
00229
00230 v2 = v1 - 1;
00231
00232 *v5 = *v2;
00233 *v2 = *v6;
00234 *v6 = *v0;
00235
00236 high = v2 - list1;
00237
00238
00239
00240 if((high - start) > (end - high)){
00241 stack[++stackIndex].start = start;
00242 stack[stackIndex].end = high - 1;
00243 ++stackIndex;
00244 start = high + 1;
00245 stackNotSet = 0;
00246 }else{
00247 stack[++stackIndex].start = high + 1;
00248 stack[stackIndex].end = end;
00249 ++stackIndex;
00250 end = high - 1;
00251 stackNotSet = 0;
00252 }
00253 }
00254 }
00255
00256
00257
00258 v2 = list1;
00259 v3 = &(list1[numPolys - 1]);
00260 v4 = v2 + 1;
00261
00262 while(v4 <= v3){
00263
00264 *v0 = *v4;
00265 v1 = v4 - 1;
00266
00267 while((v1 >= v2) && ((*v1)->dist < (*v0)->dist)){
00268 *(v1 + 1) = *v1;
00269 v1--;
00270 }
00271
00272 *(v1 + 1) = *v0;
00273 v4++;
00274 }
00275 }
00276
00277
00278
00279 static void Rotate(points1, cx, cy, cz, sx, sy, sz)
00280 anglePoint *points1;
00281 double cx, cy, cz, sx, sy, sz;
00282
00283
00284
00285 {
00286 int index1;
00287 double x, y, z, t;
00288
00289 for(index1 = 0; index1 < 2; index1++){
00290 x = points1[index1].x;
00291 y = points1[index1].y;
00292 z = points1[index1].z;
00293
00294 t = x * cz + y * sz;
00295 y = y * cz - x * sz;
00296 x = t;
00297
00298 points1[index1].y = y * cx + z * sx;
00299
00300 z = z * cx - y * sx;
00301
00302 points1[index1].x = x * cy + z * sy;
00303 points1[index1].z = z * cy - x * sy;
00304 }
00305 }
00306
00307
00308
00309 static double DotProduct(x1, Y1, x2, y2)
00310 double x1, Y1, x2, y2;
00311
00312
00313
00314 {
00315 double temp;
00316
00317 if((x1 == 0.0 && Y1 == 0.0)){
00318 return 1.0;
00319 }
00320
00321 temp = sqrt(x1 * x1 + Y1 * Y1);
00322 x1 = x1 / temp;
00323 Y1 = Y1 / temp;
00324
00325 temp = x1 * x2 + Y1 * y2;
00326
00327 if(temp > 1.0)
00328 temp = fmod(temp, 1.0);
00329
00330 if(temp < -1.0)
00331 temp = -fmod(-temp, 1.0);
00332
00333 return(temp);
00334 }
00335
00336
00337
00338 static void CalculateAngles(X, Y, Z, X1, Y1, Z1)
00339 double *X, *Y, *Z;
00340 double X1, Y1, Z1;
00341
00342
00343
00344
00345 {
00346 anglePoint points1[2];
00347
00348 points1[0].x = 0.0; points1[0].y = 0.0; points1[0].z = 1.0;
00349 points1[1].x = 1.0; points1[1].y = 0.0; points1[1].z = 0.0;
00350
00351 Rotate(points1, cos(*X), cos(*Y), cos(*Z), sin(*X), sin(*Y), sin(*Z));
00352 Rotate(points1, cos(X1), cos(Y1), cos(Z1), sin(X1), sin(Y1), sin(Z1));
00353
00354 *Y = acos(DotProduct(points1[0].x, points1[0].z, 0.0, 1.0));
00355
00356 if(points1[0].x < 0.0)
00357 *Y = -*Y;
00358
00359 Rotate(points1, 1.0, cos(-*Y), 1.0, 0.0, sin(-*Y), 0.0);
00360 *X = acos(DotProduct(points1[0].y, points1[0].z, 0.0, 1.0));
00361
00362 if(points1[0].y < 0.0)
00363 *X = -*X;
00364
00365 Rotate(points1, cos(-*X), 1.0, 1.0, sin(-*X), 0.0, 0.0);
00366 *Z = acos(DotProduct(points1[1].x, points1[1].y, 1.0, 0.0));
00367
00368 if(!(points1[1].y < 0.0))
00369 *Z = -*Z;
00370 }
00371
00372
00373
00374 static void DrawLogo(g, x, y)
00375 Ginfo *g;
00376 int x, y;
00377
00378
00379
00380 {
00381 int hUnit, vUnit;
00382 _XPoint points1[512];
00383 void *ptrp = points1;
00384
00385 hUnit = XTextWidth(g->font, LONGESTSTRING, strlen(LONGESTSTRING)) /
00386 strlen(LONGESTSTRING);
00387 vUnit = FONTHEIGHT(g->font);
00388
00389
00390
00391 points1[0].x = 9 * hUnit + x; points1[0].y = 1 * vUnit + y;
00392 points1[1].x = 9 * hUnit + vUnit + x; points1[1].y = 1 * vUnit + y;
00393 points1[2].x = 14 * hUnit + vUnit + x; points1[2].y = 6 * vUnit + y;
00394 points1[3].x = 14 * hUnit + x; points1[3].y = 6 * vUnit + y;
00395
00396 XFillPolygon(g->dpy, g->helpWin, g->helpGc, ptrp, 4, Convex,
00397 CoordModeOrigin);
00398
00399 points1[0].x = 14 * hUnit + vUnit + x; points1[0].y = 1 * vUnit + y;
00400 points1[1].x = 14 * hUnit + x; points1[1].y = 1 * vUnit + y;
00401 points1[2].x = 9 * hUnit + x; points1[2].y = 6 * vUnit + y;
00402 points1[3].x = 9 * hUnit + vUnit + x; points1[3].y = 6 * vUnit + y;
00403
00404 XFillPolygon(g->dpy, g->helpWin, g->helpGc, ptrp, 4, Convex,
00405 CoordModeOrigin);
00406
00407
00408
00409 points1[0].x = 18 * hUnit + x; points1[0].y = 1 * vUnit + y;
00410 points1[1].x = 22 * hUnit + x; points1[1].y = 1 * vUnit + y;
00411 points1[2].x = 23 * hUnit + x; points1[2].y = 2 * vUnit + y;
00412 points1[3].x = 18 * hUnit + x; points1[3].y = 2 * vUnit + y;
00413
00414 XFillPolygon(g->dpy, g->helpWin, g->helpGc, ptrp, 4, Convex,
00415 CoordModeOrigin);
00416
00417 points1[0].x = 23 * hUnit - vUnit + x; points1[0].y = 2 * vUnit + y;
00418 points1[1].x = 23 * hUnit + x; points1[1].y = 2 * vUnit + y;
00419 points1[2].x = 23 * hUnit + x; points1[2].y = 3 * vUnit + y;
00420 points1[3].x = 23 * hUnit - vUnit + x; points1[3].y = 4 * vUnit + y;
00421
00422 XFillPolygon(g->dpy, g->helpWin, g->helpGc, ptrp, 4, Convex,
00423 CoordModeOrigin);
00424
00425 points1[0].x = 23 * hUnit - vUnit + x; points1[0].y = 3 * vUnit + y;
00426 points1[1].x = 23 * hUnit + x; points1[1].y = 4 * vUnit + y;
00427 points1[2].x = 23 * hUnit + x; points1[2].y = 5 * vUnit + y;
00428 points1[3].x = 23 * hUnit - vUnit + x; points1[3].y = 5 * vUnit + y;
00429
00430 XFillPolygon(g->dpy, g->helpWin, g->helpGc, ptrp, 4, Convex,
00431 CoordModeOrigin);
00432
00433 points1[0].x = 18 * hUnit + x; points1[0].y = 5 * vUnit + y;
00434 points1[1].x = 23 * hUnit + x; points1[1].y = 5 * vUnit + y;
00435 points1[2].x = 22 * hUnit + x; points1[2].y = 6 * vUnit + y;
00436 points1[3].x = 18 * hUnit + x; points1[3].y = 6 * vUnit + y;
00437
00438 XFillPolygon(g->dpy, g->helpWin, g->helpGc, ptrp, 4, Convex,
00439 CoordModeOrigin);
00440
00441 points1[0].x = 19 * hUnit + x; points[0].y = 3 * vUnit + y;
00442 points1[1].x = 23 * hUnit - vUnit + x; points1[1].y = 3 * vUnit + y;
00443 points1[2].x = 23 * hUnit - vUnit + x; points1[2].y = 4 * vUnit + y;
00444 points1[3].x = 19 * hUnit + x; points1[3].y = 4 * vUnit + y;
00445
00446 XFillPolygon(g->dpy, g->helpWin, g->helpGc, ptrp, 4, Convex,
00447 CoordModeOrigin);
00448
00449
00450
00451 points1[0].x = 26 * hUnit + x; points1[0].y = 1 * vUnit + y;
00452 points1[1].x = 30 * hUnit + x; points1[1].y = 1 * vUnit + y;
00453 points1[2].x = 30 * hUnit + vUnit + x; points1[2].y = 2 * vUnit + y;
00454 points1[3].x = 26 * hUnit + x; points1[3].y = 2 * vUnit + y;
00455
00456 XFillPolygon(g->dpy, g->helpWin, g->helpGc, ptrp, 4, Convex,
00457 CoordModeOrigin);
00458
00459 points1[0].x = 26 * hUnit + x; points1[0].y = 5 * vUnit + y;
00460 points1[1].x = 30 * hUnit + vUnit + x; points1[1].y = 5 * vUnit + y;
00461 points1[2].x = 30 * hUnit + x; points1[2].y = 6 * vUnit + y;
00462 points1[3].x = 26 * hUnit + x; points1[3].y = 6 * vUnit + y;
00463
00464 XFillPolygon(g->dpy, g->helpWin, g->helpGc, ptrp, 4, Convex,
00465 CoordModeOrigin);
00466
00467 points1[0].x = 26 * hUnit + x; points1[0].y = 1 * vUnit + y;
00468 points1[1].x = 26 * hUnit + vUnit + x; points1[1].y = 1 * vUnit + y;
00469 points1[2].x = 26 * hUnit + vUnit + x; points1[2].y = 6 * vUnit + y;
00470 points1[3].x = 26 * hUnit + x; points1[3].y = 6 * vUnit + y;
00471
00472 XFillPolygon(g->dpy, g->helpWin, g->helpGc, ptrp, 4, Convex,
00473 CoordModeOrigin);
00474
00475 points1[0].x = 30 * hUnit + x; points1[0].y = 2 * vUnit + y;
00476 points1[1].x = 30 * hUnit + vUnit + x; points1[1].y = 2 * vUnit + y;
00477 points1[2].x = 30 * hUnit + vUnit + x; points1[2].y = 5 * vUnit + y;
00478 points1[3].x = 30 * hUnit + x; points1[3].y = 5 * vUnit + y;
00479
00480 XFillPolygon(g->dpy, g->helpWin, g->helpGc, ptrp, 4, Convex,
00481 CoordModeOrigin);
00482 }
00483
00484
00485
00486 static void DisplayMenu(g)
00487 Ginfo *g;
00488
00489
00490
00491 {
00492 int x = 5, y = 5;
00493
00494 XSetFont(g->dpy, g->helpGc, g->font->fid );
00495
00496 XSetWindowBackground(g->dpy, g->helpWin, g->black);
00497 XSetForeground(g->dpy, g->helpGc, g->white);
00498 XSetBackground(g->dpy, g->helpGc, g->black);
00499
00500 XSetStipple(g->dpy, g->helpGc, g->stipple[NUMSTIPPLES / 3]);
00501 XSetFillStyle(g->dpy, g->helpGc, FillOpaqueStippled);
00502
00503 DrawLogo(g, (XTextWidth(g->font, LONGESTSTRING, strlen(LONGESTSTRING)) /
00504 (int)strlen(LONGESTSTRING)) / 2, FONTHEIGHT(g->font) / 3);
00505
00506 XSetFillStyle(g->dpy, g->helpGc, FillSolid);
00507
00508 DrawLogo(g, 0, 0);
00509
00510 HelpPrint(g,x,y,"");
00511 HelpPrint(g,x,y,"");
00512 HelpPrint(g,x,y,"");
00513 HelpPrint(g,x,y,"");
00514 HelpPrint(g,x,y,"");
00515 HelpPrint(g,x,y,"");
00516 HelpPrint(g,x,y,"");
00517 HelpPrint(g,x,y," VERSION 2.2");
00518 HelpPrint(g,x,y,"");
00519 HelpPrint(g,x,y," CONTROLS SUMMARY");
00520 HelpPrint(g,x,y,"");
00521 HelpPrint(g,x,y," QUIT q Q");
00522 HelpPrint(g,x,y," WIREFRAME MODE w W");
00523 HelpPrint(g,x,y," HIDDEN LINE MODE e E");
00524 HelpPrint(g,x,y," HIDDEN SURFACE MODE r R");
00525 HelpPrint(g,x,y," MOVE OBJECT DOWN u U");
00526 HelpPrint(g,x,y," MOVE OBJECT UP i I");
00527 HelpPrint(g,x,y," TOGGLE CONTROLS STYLE o O");
00528 HelpPrint(g,x,y," TOGGLE STEREO DISPLAY s S");
00529 HelpPrint(g,x,y," TOGGLE BLUE STEREO VIEW d D");
00530 HelpPrint(g,x,y," TOGGLE DOUBLE BUFFER f F");
00531 HelpPrint(g,x,y," MOVE OBJECT RIGHT h H");
00532 HelpPrint(g,x,y," MOVE OBJECT BACKWARD j J");
00533 HelpPrint(g,x,y," MOVE OBJECT FOREWARD k K");
00534 HelpPrint(g,x,y," MOVE OBJECT LEFT l L");
00535 HelpPrint(g,x,y," TOGGLE HELP MENU m M");
00536 HelpPrint(g,x,y," ROTATE ABOUT X x X a A");
00537 HelpPrint(g,x,y," ROTATE ABOUT Y y Y b B");
00538 HelpPrint(g,x,y," ROTATE ABOUT Z z Z c C");
00539 HelpPrint(g,x,y," AUTOROTATE ABOUT X 1 2 3");
00540 HelpPrint(g,x,y," AUTOROTATE ABOUT Y 4 5 6");
00541 HelpPrint(g,x,y," AUTOROTATE ABOUT Z 7 8 9");
00542 HelpPrint(g,x,y," ADJUST FOCUS [ ] { }");
00543 HelpPrint(g,x,y,"");
00544 HelpPrint(g,x,y," POINTER MOVEMENT WITH LEFT BUTTON :");
00545 HelpPrint(g,x,y,"");
00546 HelpPrint(g,x,y," ROTATE OBJECT ABOUT X Vertical");
00547 HelpPrint(g,x,y," ROTATE OBJECT ABOUT Z Horizontal");
00548 }
00549
00550
00551
00552 static void ResetPurpleRectangle(XL, YL, XH, YH, g)
00553 int XL, YL, XH, YH;
00554 Ginfo *g;
00555
00556
00557
00558 {
00559 g->redSegments[3].x1 = (XL + MARGIN);
00560 g->blueSegments[3].x1 = (XL + MARGIN);
00561 g->redSegments[3].y1 = (YL + MARGIN);
00562 g->blueSegments[3].y1 = (YL + MARGIN);
00563 g->redSegments[3].x2 = (XH - MARGIN);
00564 g->blueSegments[3].x2 = (XH - MARGIN);
00565 g->redSegments[3].y2 = (YL + MARGIN);
00566 g->blueSegments[3].y2 = (YL + MARGIN);
00567 g->redSegments[2].x1 = (XH - MARGIN);
00568 g->blueSegments[2].x1 = (XH - MARGIN);
00569 g->redSegments[2].y1 = (YH - MARGIN);
00570 g->blueSegments[2].y1 = (YH - MARGIN);
00571 g->redSegments[2].x2 = (XL + MARGIN);
00572 g->blueSegments[2].x2 = (XL + MARGIN);
00573 g->redSegments[2].y2 = (YH - MARGIN);
00574 g->blueSegments[2].y2 = (YH - MARGIN);
00575 g->redSegments[1].x1 = (XH - MARGIN);
00576 g->blueSegments[1].x1 = (XH - MARGIN);
00577 g->redSegments[1].y1 = (YL + MARGIN);
00578 g->blueSegments[1].y1 = (YL + MARGIN);
00579 g->redSegments[1].x2 = (XH - MARGIN);
00580 g->blueSegments[1].x2 = (XH - MARGIN);
00581 g->redSegments[1].y2 = (YH - MARGIN);
00582 g->blueSegments[1].y2 = (YH - MARGIN);
00583 g->redSegments[0].x1 = (XL + MARGIN);
00584 g->blueSegments[0].x1 = (XL + MARGIN);
00585 g->redSegments[0].y1 = (YL + MARGIN);
00586 g->blueSegments[0].y1 = (YL + MARGIN);
00587 g->redSegments[0].x2 = (XL + MARGIN);
00588 g->blueSegments[0].x2 = (XL + MARGIN);
00589 g->redSegments[0].y2 = (YH - MARGIN);
00590 g->blueSegments[0].y2 = (YH - MARGIN);
00591 }
00592
00593
00594
00595 static void OneBitSetColors(g)
00596 Ginfo *g;
00597
00598
00599
00600 {
00601 int index1;
00602 Color *color;
00603 int numColors;
00604
00605 color = g->colors;
00606 numColors = g->numColors;
00607
00608
00609
00610 for(index1 = 0; index1 < numColors; index1++){
00611 color[index1].value = 1;
00612
00613
00614
00615 color[index1].stipple =(int)((double)NUMSTIPPLES *
00616 ((double)sqrt((double)(
00617 (double)color[index1].red * (double)color[index1].red +
00618 (double)color[index1].green * (double)color[index1].green +
00619 (double)color[index1].blue * (double)color[index1].blue))
00620 / MAXCOLORDIST));
00621 }
00622 }
00623
00624
00625
00626 static void EightBitSetColors(g)
00627 Ginfo *g;
00628
00629
00630
00631 {
00632 Color *colors1;
00633 int numColors;
00634 int colorIndex = 0;
00635 int index1, index2, redIndex, blueIndex, greenIndex;
00636 XColor c;
00637
00638 colors1 = g->colors;
00639 numColors = g->numColors;
00640
00641
00642
00643 colors1[numColors].red = 0;
00644 colors1[numColors].green = 0;
00645 colors1[numColors].blue = 0;
00646
00647
00648
00649 colors1[numColors + 1].red = 255;
00650 colors1[numColors + 1].green = 0;
00651 colors1[numColors + 1].blue = 0;
00652
00653
00654
00655 colors1[numColors + 2].red = 0;
00656 colors1[numColors + 2].green = 0;
00657 colors1[numColors + 2].blue = 255;
00658
00659
00660
00661 colors1[numColors + 3].red = 255;
00662 colors1[numColors + 3].green = 0;
00663 colors1[numColors + 3].blue = 255;
00664
00665
00666
00667 for(index1 = 0; index1 < 256; index1++){
00668 c.red = 0;
00669 c.green = 0;
00670 c.blue = 0;
00671 c.flags = DoRed | DoGreen | DoBlue;
00672 c.pixel = 255;
00673 c.pad = 0;
00674 g->cmapColors[0][index1] = c;
00675 g->cmapColors[1][index1] = c;
00676 g->cmapColors[2][index1] = c;
00677 }
00678
00679 if(numColors <= BUFFER_CMAP){
00680
00681 colorIndex= numColors + 3;
00682 index1 = 15;
00683
00684
00685
00686 while((index1 > 0) && (colorIndex >= 0)){
00687 c.red = colors1[colorIndex].red << 8;
00688 c.green = colors1[colorIndex].green << 8;
00689 c.blue = colors1[colorIndex].blue << 8;
00690 c.flags = DoRed | DoGreen | DoBlue;
00691
00692 colors1[colorIndex].value = index1 * 16 + index1;
00693
00694 colors1[colorIndex].stipple =(int)((double)NUMSTIPPLES *
00695 ((double)sqrt((double)(
00696 (double)colors1[colorIndex].red * (double)colors1[colorIndex].red +
00697 (double)colors1[colorIndex].green * (double)colors1[colorIndex].green +
00698 (double)colors1[colorIndex].blue * (double)colors1[colorIndex].blue))
00699 / MAXCOLORDIST));
00700
00701 for(index2 = 1; index2 < 16; index2++){
00702 c.pixel = index2 * 16 + index1;
00703 g->cmapColors[0][index2 * 16 + index1] = c;
00704
00705 c.pixel = index1 * 16 + index2;
00706 g->cmapColors[1][index1 * 16 + index2] = c;
00707 }
00708
00709 index1--;
00710 colorIndex--;
00711 }
00712 }else{
00713
00714
00715
00716 for(index1 = 0; index1 < 4; index1++){
00717 c.red = colors1[numColors + index1].red << 8;
00718 c.green = colors1[numColors + index1].green << 8;
00719 c.blue = colors1[numColors + index1].blue << 8;
00720 c.flags = DoRed | DoGreen | DoBlue;
00721 c.pixel = 12 + index1;
00722 g->cmapColors[0][12 + index1] = c;
00723 g->cmapColors[1][12 + index1] = c;
00724 colors1[numColors + index1].value = c.pixel;
00725 }
00726
00727 if(numColors <= MAX_COLORS){
00728 colorIndex = 0;
00729 index1 = 9;
00730 index2 = 0;
00731
00732
00733
00734 while(colorIndex < numColors){
00735 if((index1 < 12) || (index1 > 15)){
00736 c.red = colors1[colorIndex].red << 8;
00737 c.green = colors1[colorIndex].green << 8;
00738 c.blue = colors1[colorIndex].blue << 8;
00739 c.flags = DoRed | DoGreen | DoBlue;
00740 c.pixel = index1;
00741 g->cmapColors[0][index1] = c;
00742 g->cmapColors[1][index1] = c;
00743 colors1[colorIndex].value = index1;
00744
00745 colors1[colorIndex].stipple =(int)((double)NUMSTIPPLES *
00746 ((double)sqrt((double)(
00747 (double)colors1[colorIndex].red *
00748 (double)colors1[colorIndex].red +
00749 (double)colors1[colorIndex].green *
00750 (double)colors1[colorIndex].green +
00751 (double)colors1[colorIndex].blue *
00752 (double)colors1[colorIndex].blue))
00753 / MAXCOLORDIST));
00754
00755 colorIndex++;
00756 }
00757 index1++;
00758 }
00759 }else{
00760 index1 = 17;
00761 index2 = 0;
00762 redIndex = 0;
00763 greenIndex = 0;
00764 blueIndex = 0;
00765
00766
00767
00768 while(blueIndex < MAXVALUE){
00769 c.red = (redIndex * VALUESCALE) << 8;
00770 c.green = (greenIndex * VALUESCALE) << 8;
00771 c.blue = (blueIndex * VALUESCALE) << 8;
00772 c.flags = DoRed | DoGreen | DoBlue;
00773 c.pixel = index1;
00774 g->cmapColors[0][index1] = c;
00775 g->cmapColors[1][index1] = c;
00776
00777 redIndex++;
00778
00779 if(redIndex >= MAXVALUE){
00780 redIndex = 0;
00781 greenIndex++;
00782 }
00783
00784 if(greenIndex >= MAXVALUE){
00785 greenIndex = 0;
00786 blueIndex++;
00787 }
00788 index1++;
00789 }
00790
00791 for(index1 = 0; index1 < numColors; index1++){
00792 colors1[index1].value = colors1[index1].red * 36 +
00793 colors1[index1].green * 6 + colors1[index1].blue + 17;
00794
00795 colors1[colorIndex].stipple =(int)((double)NUMSTIPPLES *
00796 ((double)sqrt((double)(
00797 (double)colors1[colorIndex].red *
00798 (double)colors1[colorIndex].red +
00799 (double)colors1[colorIndex].green *
00800 (double)colors1[colorIndex].green +
00801 (double)colors1[colorIndex].blue *
00802 (double)colors1[colorIndex].blue))
00803 / MAXCOLORDIST));
00804
00805 }
00806 }
00807 }
00808
00809
00810
00811 index1 = 0;
00812 for(redIndex = 0; redIndex < 4; redIndex++){
00813 for(blueIndex = 0; blueIndex < 4; blueIndex++){
00814 if(redIndex != blueIndex){
00815 g->wireframeColors[0][index1] =
00816 g->cmapColors[0][(redIndex + 12) * 16 + (blueIndex + 12)];
00817 g->wireframeColors[1][index1] =
00818 g->cmapColors[1][(redIndex + 12) * 16 + (blueIndex + 12)];
00819 index1++;
00820 }
00821 }
00822 }
00823
00824
00825
00826 for(index1 = 13; index1 < 256; index1++){
00827 g->wireframeColors[0][index1] = g->wireframeColors[0][3];
00828 g->wireframeColors[1][index1] = g->wireframeColors[1][3];
00829 }
00830
00831
00832
00833 for(redIndex = 0; redIndex < 15; redIndex++){
00834 for(blueIndex = 0; blueIndex < 15; blueIndex++){
00835 c.red = (redIndex * 17) << 8;
00836 c.green = 0;
00837 c.blue = (blueIndex * 17) << 8;
00838 c.flags = DoRed | DoGreen | DoBlue;
00839 c.pixel = (redIndex + 1) * 16 + (blueIndex + 1);
00840 g->cmapColors[2][c.pixel] = c;
00841 }
00842 }
00843
00844
00845
00846 for(index1 = 0; index1 < numColors; index1++){
00847 colorIndex = (int)((double)15 *
00848 ((double)sqrt((double)((double)colors1[index1].red *
00849 (double)colors1[index1].red + (double)colors1[index1].green *
00850 (double)colors1[index1].green + (double)colors1[index1].blue *
00851 (double)colors1[index1].blue)) / MAXCOLORDIST));
00852
00853 colors1[index1].stereoColor = (colorIndex + 1) * 16 + (colorIndex + 1);
00854 }
00855
00856
00857
00858 g->stereoBlack = (0 + 1) * 16 + (0 + 1);
00859 g->redMask = BUFFER0;
00860 g->blueMask = BUFFER1;
00861 g->Black = colors1[numColors].value;
00862 g->Red = colors1[numColors + 1].value;
00863 g->Blue = colors1[numColors + 2].value;
00864 g->Purple = colors1[numColors + 3].value;
00865 }
00866
00867
00868 static void TrueColorSetColors(g)
00869 Ginfo *g;
00870
00871
00872
00873 {
00874 int index1, colorValue;
00875 Color *colors1;
00876 int numColors;
00877
00878
00879
00880
00881
00882
00883
00884
00885 colors1 = g->colors;
00886 numColors = g->numColors;
00887
00888 for(index1 = 0; index1 < numColors; index1++){
00889
00890
00891
00892 colors1[index1].value =
00893 (colors1[index1].red >> gRedDiv) << gRedShift |
00894 (colors1[index1].green >> gGreenDiv) << gGreenShift |
00895 (colors1[index1].blue >> gBlueDiv) << gBlueShift;
00896
00897
00898
00899 colors1[index1].stipple =(int)((double)NUMSTIPPLES *
00900 ((double)sqrt((double)(
00901 (double)colors1[index1].red * (double)colors1[index1].red +
00902 (double)colors1[index1].green * (double)colors1[index1].green +
00903 (double)colors1[index1].blue * (double)colors1[index1].blue))
00904 / MAXCOLORDIST));
00905
00906
00907
00908 colorValue= (int)((double)(255 >> gRedDiv) *
00909 ((double)sqrt((double)((double)colors1[index1].red *
00910 (double)colors1[index1].red + (double)colors1[index1].green *
00911 (double)colors1[index1].green + (double)colors1[index1].blue *
00912 (double)colors1[index1].blue)) / MAXCOLORDIST));
00913
00914 colors1[index1].stereoColor = (colorValue << gRedShift) |
00915 (colorValue << gBlueShift);
00916 }
00917
00918
00919
00920 g->stereoBlack = 0;
00921 g->redMask = (255 >> gRedDiv) << gRedShift;
00922 g->blueMask = (255 >> gBlueDiv) << gBlueShift;
00923 g->Black = 0;
00924 g->Red = (255 >> gRedDiv) << gRedShift;
00925 g->Blue = (255 >> gBlueDiv) << gBlueShift;
00926 g->Purple = g->Red | g->Blue;
00927 }
00928
00929
00930 char title[80];
00931 Atom wm_protocols[2];
00932
00933 static void InitDisplay(o, g, parent)
00934 Oinfo *o;
00935 Ginfo *g;
00936 Window parent;
00937
00938
00939
00940
00941 {
00942 static int stipples[NUMSTIPPLES][NUMSTIPPLES * 2 + 1] = {
00943 {0},
00944 {1, 1, 1},
00945 {2, 0, 2, 2, 1},
00946 {3, 1, 0, 1, 2, 3, 1},
00947 {4, 0, 1, 0, 3, 2, 1, 2, 3},
00948 {5, 0, 0, 0, 2, 2, 0, 2, 3, 3, 2},
00949 {6, 0, 2, 1, 1, 1, 3, 2, 0, 3, 1, 3, 3},
00950 {7, 0, 1, 0, 3, 1, 0, 1, 1, 2, 2, 3, 1, 3, 3},
00951 {8, 0, 1, 0, 3, 1, 0, 1, 2, 2, 1, 2, 3, 3, 0, 3, 2},
00952 {9, 0, 0, 0, 2, 1, 2, 1, 3, 2, 0, 2, 1, 2, 3, 3, 1, 3, 2},
00953 {10,0, 0, 0, 1, 0, 3, 1, 0, 1, 2, 2, 1, 2, 2, 2, 3, 3, 0, 3, 2},
00954 {11,0, 1, 0, 3, 1, 0, 1, 1, 1, 2, 1, 3, 2, 1, 2, 2, 3, 0, 3, 2, 3, 3},
00955 {12,0, 0, 0, 2, 1, 0, 1, 1, 1, 2, 1, 3, 2, 1, 2, 3, 3, 0, 3, 1, 3, 2, 3, 3},
00956 {13,0, 0, 0, 2, 0, 3, 1, 0, 1, 1, 1, 2, 2, 0, 2, 2, 2, 3, 3, 0, 3, 1, 3, 2,
00957 3, 3},
00958 {14,0, 0, 0, 1, 0, 2, 0, 3, 1, 0, 1, 1, 1, 3, 2, 1, 2, 2, 2, 3, 3, 0, 3, 1,
00959 3, 2, 3, 3},
00960 {15,0, 0, 0, 1, 0, 2, 0, 3, 1, 0, 1, 2, 1, 3, 2, 0, 2, 1, 2, 2, 2, 3, 3, 0,
00961 3, 1, 3, 2, 3, 3},
00962 {16,0, 0, 0, 1, 0, 2, 0, 3, 1, 0, 1, 1, 1, 2, 1, 3, 2, 0, 2, 1, 2, 2, 2, 3,
00963 3, 0, 3, 1, 3, 2, 3, 3}
00964 };
00965
00966 char bits[(STIPPLESIZE * STIPPLESIZE) / BITSPERBYTE];
00967
00968 GC temp_gc;
00969 XColor oldColormap[MAXCOLORS];
00970 XWindowAttributes attributes;
00971 XSetWindowAttributes attribs;
00972 XWMHints wmhint;
00973 int index1, index2, screen;
00974 Visual *vis;
00975 XSizeHints sizehint;
00976 int x, y, NUMCOLORS;
00977 unsigned int width, height, numSegments;
00978 int useroot = 0;
00979
00980 if (gDisplay)
00981 useroot = 1;
00982
00983
00984 numSegments = o->numSegs;
00985
00986 if((g->redColors = (long *)calloc(1, (numSegments + 4) * (sizeof(long))))
00987 == NULL){
00988 (void)fprintf(stderr, "Unable to allocate memory for redColors\n"); return;}
00989
00990 if((g->redSegments = (XSegment *)calloc(1, (numSegments + 4) *
00991 (sizeof(XSegment)))) == NULL){
00992 (void)fprintf(stderr, "Unable to allocate memory for redSegments\n"); return;}
00993
00994 if((g->blueSegments = (XSegment *)calloc(1, (numSegments + 4) *
00995 sizeof(XSegment))) == (XSegment *)NULL){
00996 (void)fprintf(stderr, "Unable to allocate memory for blueSegments\n"); return;}
00997
00998
00999
01000 if (!useroot)
01001 g->dpy = XOpenDisplay(g->DisplayName);
01002 else
01003 g->dpy = gDisplay;
01004 if(g->dpy == NULL){
01005 fprintf(stderr, "Cannot connect to server\n");
01006 return;
01007 }
01008
01009 screen = DefaultScreen(g->dpy);
01010 g->black = (long)BlackPixel(g->dpy, screen);
01011 g->white = (long)WhitePixel(g->dpy, screen);
01012
01013
01014
01015 g->requestSize = XMaxRequestSize(g->dpy) / REQUESTFACTOR;
01016 g->dpyX = DisplayWidth(g->dpy, screen);
01017 g->dpyY = DisplayHeight(g->dpy, screen);
01018 g->winX = g->dpyX / 2;
01019 g->winY = g->dpyY / 2 ;
01020 g->mono = g->ColorSelect = g->oldPointerX = g->oldPointerY = 0;
01021 g->Block = 1;
01022 g->Relative = 0;
01023
01024
01025
01026 if((g->font = XLoadQueryFont(g->dpy, FONT)) == NULL){
01027 fprintf(stderr, "Unable to load font: %s ... trying fixed\n", FONT);
01028
01029 if((g->font = XLoadQueryFont(g->dpy, FIXED)) == NULL){
01030 fprintf(stderr, "Unable to load font: %s\n", FIXED);
01031 return;
01032 }
01033 }
01034
01035 if((g->titleFont = XLoadQueryFont(g->dpy, TITLEFONT)) == NULL){
01036 fprintf(stderr, "Unable to load font: %s ... trying fixed\n", TITLEFONT);
01037
01038 if((g->titleFont = XLoadQueryFont(g->dpy, FIXED)) == NULL){
01039 fprintf(stderr, "Unable to load font: %s\n", FIXED);
01040 return;
01041 }
01042 }
01043
01044 if((g->boldFont = XLoadQueryFont(g->dpy, BOLDFONT)) == NULL){
01045 fprintf(stderr, "Unable to load font: %s ... trying fixed\n", BOLDFONT);
01046
01047 if((g->boldFont = XLoadQueryFont(g->dpy, FIXED)) == NULL){
01048 fprintf(stderr, "Unable to load font: %s\n", FIXED);
01049 return;
01050 }
01051 }
01052
01053
01054
01055 gRedDiv = gGreenDiv = gBlueDiv = gRedShift = gGreenShift = gBlueShift = -1;
01056 g->depth = DefaultDepth(g->dpy, screen);
01057
01058 vis = DefaultVisual(g->dpy, screen);
01059 if (g->depth > EIGHT && vis->class == TrueColor) {
01060 int i;
01061 for (i = 0; i < (int)sizeof(vis->blue_mask)*8; i++) {
01062 if (gBlueShift == -1 && ((vis->blue_mask >> i) & 1))
01063 gBlueShift = i;
01064 if ((vis->blue_mask >> i) == 1) {
01065 gBlueDiv = 8 - i - 1 + gBlueShift;
01066 break;
01067 }
01068 }
01069 for (i = 0; i < (int)sizeof(vis->green_mask)*8; i++) {
01070 if (gGreenShift == -1 && ((vis->green_mask >> i) & 1))
01071 gGreenShift = i;
01072 if ((vis->green_mask >> i) == 1) {
01073 gGreenDiv = 8 - i - 1 + gGreenShift;
01074 break;
01075 }
01076 }
01077 for (i = 0; i < (int)sizeof(vis->red_mask)*8; i++) {
01078 if (gRedShift == -1 && ((vis->red_mask >> i) & 1))
01079 gRedShift = i;
01080 if ((vis->red_mask >> i) == 1) {
01081 gRedDiv = 8 - i - 1 + gRedShift;
01082 break;
01083 }
01084 }
01085
01086
01087
01088
01089 } else if (g->depth > EIGHT)
01090 g->depth = EIGHT;
01091
01092 g->pix = XCreatePixmap(g->dpy, RootWindow(g->dpy,screen), g->winX,
01093 g->winY, g->depth);
01094
01095
01096
01097
01098
01099
01100 g->helpWinX =XTextWidth(g->font, LONGESTSTRING, strlen(LONGESTSTRING));
01101 g->helpWinY = FONTHEIGHT(g->font) * HELPLINES;
01102
01103 g->helpWin = XCreateSimpleWindow(g->dpy, RootWindow(g->dpy, screen), 0, 0,
01104 g->helpWinX, g->helpWinY, 0, 0, 0);
01105
01106 if (parent)
01107 g->win = XCreateSimpleWindow(g->dpy, parent, 0, 0,
01108 g->winX, g->winY, 0, 0, 0);
01109 else
01110 g->win = XCreateSimpleWindow(g->dpy, RootWindow(g->dpy,screen), 0, 0,
01111 g->winX, g->winY, 0, 0, 0);
01112
01113
01114
01115 if(g->Geometry && !useroot){
01116
01117 x = 0;
01118 y = 0;
01119 width = g->winX;
01120 height = g->winY;
01121 sizehint.flags = USPosition | USSize;
01122
01123 XParseGeometry(g->Geometry, &x, &y, &width, &height);
01124
01125 sizehint.x = x;
01126 sizehint.y = y;
01127 sizehint.width = width;
01128 sizehint.height = height;
01129 g->winX = width;
01130 g->winY = height;
01131
01132 XResizeWindow(g->dpy, g->win, width, height);
01133 XSetNormalHints(g->dpy, g->win, &sizehint);
01134 }
01135
01136
01137
01138 g->winH = (int)(g->winX / 2.0);
01139 g->winV = (int)(g->winY / 2.0);
01140
01141
01142
01143 g->gc = XCreateGC(g->dpy, g->win, 0x0, NULL);
01144 g->helpGc = XCreateGC(g->dpy, g->helpWin, 0x0, NULL);
01145
01146
01147
01148 for(index1 = 0; index1 < NUMSTIPPLES; index1++){
01149 g->stipple[index1]= XCreateBitmapFromData(g->dpy, g->win, bits,
01150 STIPPLESIZE, STIPPLESIZE);
01151 temp_gc = XCreateGC(g->dpy, g->stipple[index1], 0x0, NULL);
01152 XSetForeground(g->dpy, temp_gc, 0);
01153 XFillRectangle(g->dpy, g->stipple[index1], temp_gc, 0, 0, STIPPLESIZE,
01154 STIPPLESIZE);
01155 XSetForeground(g->dpy, temp_gc, 1);
01156 for(index2 = 0; index2 < stipples[index1][0]; index2++){
01157 XDrawPoint(g->dpy, g->stipple[index1], temp_gc,
01158 stipples[index1][index2 * 2 + 1], stipples[index1][index2 * 2 + 2]);
01159 }
01160 XFreeGC(g->dpy, temp_gc);
01161 }
01162
01163 if (!useroot) {
01164
01165
01166 XSetInputFocus(g->dpy, PointerRoot, RevertToNone, CurrentTime);
01167
01168
01169
01170
01171
01172
01173
01174 wmhint.input = True;
01175 wmhint.flags = InputHint;
01176 XSetWMHints(g->dpy,g->win,&wmhint);
01177 }
01178
01179
01180
01181 attribs.backing_store = NotUseful;
01182 XChangeWindowAttributes(g->dpy, g->win, CWBackingStore, &attribs);
01183
01184
01185
01186 XSelectInput(g->dpy, g->win, ButtonPressMask | ButtonReleaseMask |
01187 KeyPressMask | Button1MotionMask | Button2MotionMask |
01188 StructureNotifyMask | ExposureMask | ColormapChangeMask);
01189
01190 XSelectInput(g->dpy, g->helpWin, ButtonPressMask | ButtonReleaseMask |
01191 KeyPressMask | Button1MotionMask | Button2MotionMask |
01192 StructureNotifyMask | ExposureMask | ColormapChangeMask);
01193
01194 if (!useroot) {
01195
01196
01197 XSetGraphicsExposures(g->dpy, g->gc, 0);
01198
01199
01200
01201 XStoreName(g->dpy, g->win, title);
01202 XStoreName(g->dpy, g->helpWin, "ROOT://X3D/Help");
01203
01204 }
01205
01206
01207 XSetWindowBackground(g->dpy, g->win, g->black);
01208
01209 if(g->depth == ONE){
01210 OneBitSetColors(g);
01211 }
01212
01213 if(g->depth > EIGHT){
01214 TrueColorSetColors(g);
01215 }
01216
01217 if(g->depth == EIGHT){
01218
01219 NUMCOLORS = 256;
01220
01221
01222
01223 g->colormap = XCreateColormap(g->dpy, g->win, DefaultVisual(g->dpy,
01224 screen), AllocAll);
01225
01226
01227
01228 XGetWindowAttributes(g->dpy, RootWindow(g->dpy,screen), &attributes);
01229
01230
01231
01232
01233 for(index1 = 0; index1 < NUMCOLORS; index1++)
01234 oldColormap[index1].pixel = index1;
01235
01236 XQueryColors(g->dpy, attributes.colormap, oldColormap, NUMCOLORS);
01237 XStoreColors(g->dpy, g->colormap, oldColormap, NUMCOLORS);
01238
01239
01240
01241 EightBitSetColors(g);
01242
01243
01244
01245 XStoreColors(g->dpy, g->colormap, g->cmapColors[0], 256);
01246 XSetWindowColormap(g->dpy, g->helpWin, g->colormap);
01247 XSetWindowColormap(g->dpy, g->win, g->colormap);
01248 }
01249
01250
01251
01252 ResetPurpleRectangle(0, 0, g->winX, g->winY, g);
01253
01254
01255 if (!useroot) {
01256
01257
01258
01259
01260 wm_protocols[0] = XInternAtom (g->dpy, "WM_DELETE_WINDOW", False);
01261 wm_protocols[1] = XInternAtom (g->dpy, "WM_SAVE_YOURSELF", False);
01262 XSetWMProtocols (g->dpy, g->win, wm_protocols, 2);
01263 }
01264
01265
01266
01267
01268 XMapWindow(g->dpy, g->win);
01269 if (!useroot) DisplayMenu(g);
01270 }
01271
01272
01273
01274 static int CheckEvent(Display *display, XEvent *event, char *arg)
01275
01276
01277
01278
01279
01280 {
01281 if (display || arg) { }
01282
01283 if(event == NULL){
01284 fprintf(stderr, "WARNING: Null event in CheckEvent()!!\n");
01285 return 0;
01286 }
01287
01288 if((event->type == MotionNotify) || (event->type == KeyPress) ||
01289 (event->type == ConfigureNotify) || (event->type == Expose) ||
01290 (event->type == ColormapNotify) || (event->type == ClientMessage))
01291 return 1;
01292
01293 return 0;
01294 }
01295
01296
01297
01298 static void GetInput(xevent, pointerX, pointerY, command, same, g)
01299 XEvent *xevent;
01300 int *pointerX, *pointerY;
01301 char *command;
01302 int *same;
01303 Ginfo *g;
01304
01305
01306
01307
01308
01309
01310 {
01311 XEvent event;
01312 XSizeHints sizehint;
01313 int numEvents;
01314 char string[TMPSTRLEN];
01315
01316
01317
01318 *command = '\0';
01319
01320 if (!xevent) {
01321
01322 do{
01323 string[0] = '\0';
01324
01325
01326
01327 numEvents = XEventsQueued(g->dpy, QueuedAfterReading);
01328
01329
01330
01331 if((numEvents == 0) && (g->Block)){
01332
01333
01334
01335 XIfEvent(g->dpy, &event, CheckEvent, NULL);
01336 numEvents = 1;
01337 }else{
01338
01339
01340
01341 if(numEvents)
01342 XNextEvent(g->dpy,&event);
01343 }
01344
01345 }while((numEvents == 0) && (g->Block));
01346
01347 } else {
01348 event = *xevent;
01349 numEvents = 1;
01350 }
01351
01352
01353
01354 while(numEvents){
01355
01356 switch(event.type){
01357
01358 case MotionNotify :
01359 if(numEvents == 1){
01360 *pointerX = (int)event.xmotion.x;
01361 *pointerY = (int)event.xmotion.y;
01362 }
01363 break;
01364
01365 case KeyPress :
01366 if(numEvents == 1){
01367 XLookupString(&event.xkey,string,TMPSTRLEN,NULL,NULL);
01368 *command = string[0];
01369 }
01370 break;
01371
01372 case ConfigureNotify :
01373
01374 if(event.xconfigure.window == g->win){
01375
01376 g->winX = event.xconfigure.width;
01377 g->winY = event.xconfigure.height;
01378 g->winH = (int)(g->winX / 2.0);
01379 g->winV = (int)(g->winY / 2.0);
01380 ResetPurpleRectangle(0, 0, g->winX, g->winY, g);
01381 sizehint.flags = USSize | USPosition;
01382 sizehint.width = g->winX;
01383 sizehint.height = g->winY;
01384 XSetNormalHints(g->dpy, g->win, &sizehint);
01385
01386
01387
01388 XFreePixmap(g->dpy, g->pix);
01389
01390 g->pix = XCreatePixmap(g->dpy, g->win, g->winX, g->winY,
01391 g->depth);
01392
01393 }
01394 if(event.xconfigure.window == g->helpWin){
01395 DisplayMenu(g);
01396 }
01397 g->modeChanged = 1;
01398 *same = 0;
01399 break;
01400
01401 case Expose :
01402 if(event.xexpose.window == g->helpWin){
01403 DisplayMenu(g);
01404 }
01405 *same = 0;
01406 break;
01407
01408 case MapNotify :
01409
01410 if(event.xmap.window == g->helpWin){
01411
01412 sizehint.flags = USPosition | USSize;
01413 XSetNormalHints(g->dpy, g->helpWin, &sizehint);
01414
01415 DisplayMenu(g);
01416 }
01417 g->modeChanged = 1;
01418 *same = 0;
01419 break;
01420
01421 case ColormapNotify :
01422
01423 if(event.xcolormap.colormap == g->colormap){
01424
01425 if(event.xcolormap.state == ColormapUninstalled){
01426 g->mono = 1;
01427 }else{
01428 g->mono = 0;
01429 }
01430
01431 g->modeChanged = 1;
01432 *same = 0;
01433 }
01434 break;
01435
01436 case ClientMessage:
01437 if (event.xclient.data.l[0] == (long)wm_protocols[0])
01438
01439 {
01440
01441
01442
01443
01444
01445 quitApplication = 1;
01446 }
01447 else if (event.xclient.data.l[0] == (long)wm_protocols[1])
01448
01449 {
01450
01451 }
01452 break;
01453
01454
01455 default:
01456 break;
01457 }
01458
01459 numEvents--;
01460 if(numEvents)
01461 XNextEvent(g->dpy,&event);
01462 }
01463 }
01464
01465
01466 float deltaMove = 0;
01467
01468 static
01469 int UpdatePosition(event, o, g)
01470 XEvent *event;
01471 Oinfo *o;
01472 Ginfo *g;
01473
01474
01475
01476
01477
01478
01479 {
01480 int same, pointerX, pointerY, dx, dy;
01481 char command;
01482 double X, Y, Z;
01483
01484 X = Y = Z = 0.0;
01485
01486 same = 1;
01487
01488 pointerX = g->oldPointerX;
01489 pointerY = g->oldPointerY;
01490
01491 while(same) {
01492
01493
01494
01495
01496
01497
01498
01499
01500 if((o->dX) || (o->dY) || (o->dZ)){
01501 same = 0;
01502 g->Block = 0;
01503 }else
01504 g->Block = 1;
01505
01506
01507
01508 GetInput(event, &pointerX, &pointerY, &command, &same, g);
01509
01510
01511
01512
01513
01514
01515
01516
01517 switch(command){
01518 case ' ' : break;
01519
01520 case 'm' :
01521 case 'M' : same = 0; g->helpMenu = !g->helpMenu;
01522
01523
01524
01525
01526
01527
01528
01529 break;
01530
01531 case 's' :
01532 case 'S' : same = 0; g->stereo = !g->stereo; g->modeChanged = 1;
01533 break;
01534
01535 case 'd' :
01536 case 'D' : same = 0; g->stereoBlue = !g->stereoBlue; g->modeChanged = 1;
01537 break;
01538
01539 case 'f' :
01540 case 'F' : same = 0; g->buffer = !g->buffer; g->modeChanged = 1;
01541 break;
01542
01543 case 'o' :
01544 case 'O' : same = 0; g->Relative = !g->Relative; break;
01545
01546 case 'w' :
01547 case 'W' : same = 0; g->renderMode = WIREFRAME; g->modeChanged = 1;
01548 break;
01549
01550 case 'e' :
01551 case 'E' : if(o->numPolys) {
01552 same = 0; g->renderMode = HIDDENLINE; g->modeChanged = 1;
01553 }
01554 break;
01555
01556 case 'r' :
01557 case 'R' : if(o->numPolys) {
01558 same = 0; g->renderMode = SOLID; g->modeChanged = 1;
01559 }
01560 break;
01561
01562 case 'l' : same = 0; o->tX -= deltaMove; break;
01563 case 'j' : same = 0; o->tY -= deltaMove; break;
01564 case 'k' : same = 0; o->tY += deltaMove; break;
01565 case 'h' : same = 0; o->tX += deltaMove; break;
01566 case 'i' : same = 0; o->tZ += deltaMove; break;
01567 case 'u' : same = 0; o->tZ -= deltaMove; break;
01568 case 'L' : same = 0; o->tX -= 5*deltaMove; break;
01569 case 'J' : same = 0; o->tY -= 5*deltaMove; break;
01570 case 'K' : same = 0; o->tY += 5*deltaMove; break;
01571 case 'H' : same = 0; o->tX += 5*deltaMove; break;
01572 case 'I' : same = 0; o->tZ += 5*deltaMove; break;
01573 case 'U' : same = 0; o->tZ -= 5*deltaMove; break;
01574 case '1' : same = 0; o->dX += 0.02; break;
01575 case '2' : same = 0; o->dX = 0.0 ; break;
01576 case '3' : same = 0; o->dX -= 0.02; break;
01577 case '4' : same = 0; o->dY -= 0.02; break;
01578 case '5' : same = 0; o->dY = 0.0 ; break;
01579 case '6' : same = 0; o->dY += 0.02; break;
01580 case '7' : same = 0; o->dZ += 0.02; break;
01581 case '8' : same = 0; o->dZ = 0.0 ; break;
01582 case '9' : same = 0; o->dZ -= 0.02; break;
01583 case 'x' : same = 0; X -= 0.03; break;
01584 case 'X' : same = 0; X += 0.03; break;
01585 case 'y' : same = 0; Y += 0.03; break;
01586 case 'Y' : same = 0; Y -= 0.03; break;
01587 case 'z' : same = 0; Z -= 0.03; break;
01588 case 'Z' : same = 0; Z += 0.03; break;
01589 case 'a' : same = 0; X -= 0.05; break;
01590 case 'A' : same = 0; X += 0.05; break;
01591 case 'b' : same = 0; Y += 0.05; break;
01592 case 'B' : same = 0; Y -= 0.05; break;
01593 case 'c' : same = 0; Z -= 0.05; break;
01594 case 'C' : same = 0; Z += 0.05; break;
01595 case '[' : same = 0;
01596 o->focus += 0.1;
01597 if((o->focus > 1.8))
01598 o->focus = 1.8;
01599 break;
01600 case ']' : same = 0;
01601 o->focus -= 0.1;
01602 if((o->focus < -0.8))
01603 o->focus = -0.8;
01604 break;
01605 case '{' : same = 0; o->BViewpointX -= 4.0; break;
01606 case '}' : same = 0; o->BViewpointX += 4.0; break;
01607
01608 case 'q' :
01609 case 'Q' : return(1);
01610
01611 default : {
01612
01613
01614
01615
01616
01617 dx = pointerX - g->oldPointerX;
01618 dy = pointerY - g->oldPointerY;
01619
01620 if((dy * dy <= SMALLMOVEMENT) &&
01621 (dx * dx <= SMALLMOVEMENT)){
01622
01623
01624
01625
01626 X -= (dy * POINTERRATIO);
01627 Z -= (dx * POINTERRATIO);
01628 same = 0;
01629 }
01630
01631 g->oldPointerY = pointerY;
01632 g->oldPointerX = pointerX;
01633 }
01634 }
01635 }
01636
01637
01638 X = fmod(X + o->dX, TWOPI);
01639 Y = fmod(Y + o->dY, TWOPI);
01640 Z = fmod(Z + o->dZ, TWOPI);
01641
01642
01643
01644 if(g->Relative){
01645 o->X = fmod(X + o->X, TWOPI);
01646 o->Y = fmod(Y + o->Y, TWOPI);
01647 o->Z = fmod(Z + o->Z, TWOPI);
01648 }else{
01649 CalculateAngles(&(o->X), &(o->Y), &(o->Z), X, Y, Z);
01650 }
01651
01652 return quitApplication;
01653 }
01654
01655
01656
01657 static int clipSegment(pX, pY, qX, qY, Pclip, Qclip, H, V)
01658 float *pX, *pY, *qX, *qY;
01659 int Pclip, Qclip;
01660 float H,V;
01661
01662
01663
01664 {
01665 register float PX, PY, QX, QY, dx, dy;
01666
01667 PX = *pX; QX = *qX;
01668 PY = *pY; QY = *qY;
01669
01670 dx = QX - PX;
01671 dy = QY - PY;
01672
01673
01674
01675
01676
01677
01678 switch(Pclip){
01679
01680 case 1 :
01681 clipWithTop(PX, PY, dx, dy, V)
01682 if((PX < -H) || (PX > H))
01683 return 0;
01684 break;
01685
01686 case 2 :
01687 clipWithBottom(PX, PY, dx, dy, V)
01688 if((PX < -H) || (PX > H))
01689 return 0;
01690 break;
01691
01692 case 4 :
01693 clipWithLeftSide(PX, PY, dx, dy, H)
01694 if((PY < -V) || (PY > V))
01695 return 0;
01696 break;
01697
01698 case 5 :
01699 clipWithTop(PX, PY, dx, dy, V)
01700 if((PX < -H) || (PX > H)){
01701 clipWithLeftSide(PX, PY, dx, dy, H)
01702 if((PY < -V) || (PY > V))
01703 return 0;
01704 }
01705 break;
01706
01707 case 6 :
01708 clipWithBottom(PX, PY, dx, dy, V)
01709 if((PX < -H) || (PX > H)){
01710 clipWithLeftSide(PX, PY, dx, dy, H)
01711 if((PY < -V) || (PY > V))
01712 return 0;
01713 }
01714 break;
01715
01716 case 8 :
01717 clipWithRightSide(PX, PY, dx, dy, H)
01718 if((PY < -V) || (PY > V))
01719 return 0;
01720 break;
01721
01722 case 9 :
01723 clipWithTop(PX, PY, dx, dy, V)
01724 if((PX < -H) || (PX > H)){
01725 clipWithRightSide(PX, PY, dx, dy, H)
01726 if((PY < -V) || (PY > V))
01727 return 0;
01728 }
01729 break;
01730
01731 case 10 :
01732 clipWithBottom(PX, PY, dx, dy, V)
01733 if((PX < -H) || (PX > H)){
01734 clipWithRightSide(PX, PY, dx, dy, H)
01735 if((PY < -V) || (PY > V))
01736 return 0;
01737 }
01738 break;
01739
01740 }
01741
01742
01743
01744 switch(Qclip){
01745
01746 case 1 :
01747 clipWithTop(QX, QY, dx, dy, V)
01748 break;
01749
01750 case 2 :
01751 clipWithBottom(QX, QY, dx, dy, V)
01752 break;
01753
01754 case 4 :
01755 clipWithLeftSide(QX, QY, dx, dy, H)
01756 break;
01757
01758 case 5 :
01759 clipWithTop(QX, QY, dx, dy, V)
01760 if(QX < -H)
01761 clipWithLeftSide(QX, QY, dx, dy, H)
01762 break;
01763
01764 case 6 :
01765 clipWithBottom(QX, QY, dx, dy, V)
01766 if(QX < -H)
01767 clipWithLeftSide(QX, QY, dx, dy, H)
01768 break;
01769
01770 case 8 :
01771 clipWithRightSide(QX, QY, dx, dy, H)
01772 break;
01773
01774 case 9 :
01775 clipWithTop(QX, QY, dx, dy, V)
01776 if(QX > H)
01777 clipWithRightSide(QX, QY, dx, dy, H)
01778 break;
01779
01780 case 10 :
01781 clipWithBottom(QX, QY, dx, dy, V)
01782 if(QX > H)
01783 clipWithRightSide(QX, QY, dx, dy, H)
01784 break;
01785
01786 case 21 :
01787 clipWithTop(QX, QY, dx, dy, V)
01788 if(QX < -H)
01789 clipWithLeftSide(QX, QY, dx, dy, H)
01790 break;
01791
01792 case 22 :
01793 clipWithBottom(QX, QY, dx, dy, V)
01794 if(QX < -H)
01795 clipWithLeftSide(QX, QY, dx, dy, H)
01796 break;
01797
01798 case 23 :
01799 if(QY < PY)
01800 clipWithTop(QX, QY, dx, dy, V)
01801 else
01802 clipWithBottom(QX, QY, dx, dy, V)
01803 if(QX < -H)
01804 clipWithLeftSide(QX, QY, dx, dy, H)
01805 break;
01806
01807 case 25 :
01808 clipWithTop(QX, QY, dx, dy, V)
01809 if(QX > H)
01810 clipWithRightSide(QX, QY, dx, dy, H)
01811 break;
01812
01813 case 26 :
01814 clipWithBottom(QX, QY, dx, dy, V)
01815 if(QX > H)
01816 clipWithRightSide(QX, QY, dx, dy, H)
01817 break;
01818
01819 case 27 :
01820 if(QY < PY)
01821 clipWithTop(QX, QY, dx, dy, V)
01822 else
01823 clipWithBottom(QX, QY, dx, dy, V)
01824 if(QX > H)
01825 clipWithRightSide(QX, QY, dx, dy, H)
01826 break;
01827
01828 case 29 :
01829 if(QX < PX)
01830 clipWithRightSide(QX, QY, dx, dy, H)
01831 else
01832 clipWithLeftSide(QX, QY, dx, dy, H)
01833 if(QY > V)
01834 clipWithTop(QX, QY, dx, dy, V)
01835 break;
01836
01837 case 30 :
01838 if(QX < PX)
01839 clipWithRightSide(QX, QY, dx, dy, H)
01840 else
01841 clipWithLeftSide(QX, QY, dx, dy, H)
01842 if(QY < -V)
01843 clipWithBottom(QX, QY, dx, dy, V)
01844 break;
01845
01846 case 31 :
01847 if(QX < PX)
01848 clipWithRightSide(QX, QY, dx, dy, H)
01849 else
01850 clipWithLeftSide(QX, QY, dx, dy, H)
01851
01852 if((QY < -V) || (QY > V)) {
01853 if(*qY < PY)
01854 clipWithTop(QX, QY, dx, dy, V)
01855 else
01856 clipWithBottom(QX, QY, dx, dy, V)
01857 }
01858 break;
01859
01860 }
01861
01862 *pX = PX; *qX = QX;
01863 *pY = PY; *qY = QY;
01864 return 1;
01865 }
01866
01867
01868
01869 static void clip(o, g)
01870 Oinfo *o;
01871 Ginfo *g;
01872
01873
01874
01875 {
01876 register int PClipFlags, QClipFlags, Pclip, Qclip, Tclip;
01877 register float H, V;
01878 register short pX, pY, qX, qY;
01879 float PX, PY, QX, QY;
01880 segment *seg, *lastSeg;
01881 point *P, *Q, *T;
01882 XSegment *red, *blue;
01883 long *redCol;
01884
01885 lastSeg = &(o->segs[o->numSegs]);
01886 seg = o->segs;
01887
01888 H = (float)g->winH;
01889 V = (float)g->winV;
01890
01891 red = &(g->redSegments[g->numberRed]);
01892 redCol = &(g->redColors[g->numRedColors]);
01893
01894 if((g->mono) || ((g->stereo) && (!(g->stereoBlue))) ||
01895 ((g->renderMode == WIREFRAME) && (!g->stereo))){
01896
01897 if(o->objClip){
01898
01899
01900
01901 while(seg < lastSeg){
01902
01903 P = seg->P;
01904 if (P == 0) continue;
01905 PClipFlags = P->ClipFlags;
01906 Q = seg->Q;
01907 if (Q == 0) continue;
01908 QClipFlags = Q->ClipFlags;
01909
01910
01911
01912 if((PClipFlags | QClipFlags) == 0){
01913 if (seg->color) *redCol = seg->color->value;
01914 else *redCol = 0;
01915 redCol++;
01916 ((xsegment *)red)->P = P->R;
01917 ((xsegment *)red)->Q = Q->R;
01918 red++;
01919 }else{
01920
01921
01922
01923
01924
01925
01926 Pclip = (PClipFlags & RBmask) | ((PClipFlags & RLeftRight) >> 3);
01927 Qclip = (QClipFlags & RBmask) | ((QClipFlags & RLeftRight) >> 3);
01928
01929 if((Qclip | Pclip) == 0){
01930
01931 if (seg->color) *redCol = seg->color->value;
01932 else *redCol = 0;
01933 redCol++;
01934 red->x1 = P->R.x;
01935 red->y1 = P->R.y;
01936 red->x2 = Q->R.x;
01937 red->y2 = Q->R.y;
01938 red++;
01939
01940 }else{
01941
01942 if((Qclip & Pclip) == 0){
01943
01944
01945
01946
01947 if((Pclip > Qclip) || (Pclip & Behind)){
01948 T = P; P = Q; Q = T;
01949 Tclip = Pclip; Pclip = Qclip; Qclip = Tclip;
01950 }
01951
01952 PX = P->RX - H; PY = -(P->Y - V);
01953 QX = Q->RX - H; QY = -(Q->Y - V);
01954
01955 if(clipSegment(&PX, &PY, &QX, &QY, Pclip, Qclip, H, V)){
01956
01957 if (seg->color) *redCol = seg->color->value;
01958 else *redCol = 0;
01959 redCol++;
01960 red->x1 = (short)(PX + H);
01961 red->y1 = (short)(V - PY);
01962 red->x2 = (short)(QX + H);
01963 red->y2 = (short)(V - QY);
01964 red++;
01965
01966 }
01967 }
01968 }
01969 }
01970 seg++;
01971 }
01972 }else{
01973
01974
01975
01976 if((g->renderMode == WIREFRAME) && (g->stereo)){
01977 while(seg < lastSeg){
01978 ((xsegment *)red)->P = seg->P->R;
01979 ((xsegment *)red)->Q = seg->Q->R;
01980 red++;
01981 seg++;
01982 }
01983 }else{
01984 while(seg < lastSeg){
01985
01986 if (seg->color) *redCol = seg->color->value;
01987 else {*redCol = 0; break;}
01988 redCol++;
01989 ((xsegment *)red)->P = seg->P->R;
01990 ((xsegment *)red)->Q = seg->Q->R;
01991 red++;
01992 seg++;
01993 }
01994 }
01995 }
01996 }else{
01997 blue = &(g->blueSegments[g->numberBlue]);
01998
01999 if(o->objClip){
02000 while(seg < lastSeg){
02001
02002 P = seg->P; Q = seg->Q;
02003 PClipFlags = P->ClipFlags;
02004 QClipFlags = Q->ClipFlags;
02005
02006
02007
02008 if((PClipFlags | QClipFlags) == 0){
02009
02010 pX = P->R.x; pY = P->R.y;
02011 qX = Q->R.x; qY = Q->R.y;
02012 red->x1 = pX;
02013 red->y1 = pY;
02014 red->x2 = qX;
02015 red->y2 = qY;
02016 red++;
02017 pX = P->sBX; qX = Q->sBX;
02018 blue->x1 = pX;
02019 blue->y1 = pY;
02020 blue->x2 = qX;
02021 blue->y2 = qY;
02022 blue++;
02023
02024 }else{
02025
02026
02027
02028
02029
02030
02031 Pclip = (PClipFlags & RBmask) | ((PClipFlags & RLeftRight) >> 3);
02032 Qclip = (QClipFlags & RBmask) | ((QClipFlags & RLeftRight) >> 3);
02033
02034 if((Qclip | Pclip) == 0){
02035
02036 red->x1 = P->R.x;
02037 red->y1 = P->R.y;
02038 red->x2 = Q->R.x;
02039 red->y2 = Q->R.y;
02040 red++;
02041
02042 }else{
02043
02044 if((Qclip & Pclip) == 0){
02045
02046
02047
02048
02049 if((Pclip > Qclip) || (Pclip & Behind)){
02050 T = P; P = Q; Q = T;
02051 Tclip = Pclip; Pclip = Qclip; Qclip = Tclip;
02052 }
02053
02054 PX = P->RX - H; PY = -(P->Y - V);
02055 QX = Q->RX - H; QY = -(Q->Y - V);
02056
02057 if(clipSegment(&PX, &PY, &QX, &QY, Pclip, Qclip, H, V)){
02058
02059 red->x1 = (short)(PX + H);
02060 red->y1 = (short)(V - PY);
02061 red->x2 = (short)(QX + H);
02062 red->y2 = (short)(V - QY);
02063 red++;
02064
02065 }
02066
02067 }
02068 }
02069
02070
02071
02072 PClipFlags = P->ClipFlags;
02073 QClipFlags = Q->ClipFlags;
02074
02075
02076
02077
02078 Pclip = (PClipFlags & Rmask);
02079 Qclip = (QClipFlags & Rmask);
02080
02081 if((Qclip | Pclip) == 0){
02082
02083 blue->x1 = P->sBX;
02084 blue->y1 = P->R.y;
02085 blue->x2 = Q->sBX;
02086 blue->y2 = Q->R.y;
02087 blue++;
02088
02089 }else{
02090 if((Qclip & Pclip) == 0){
02091
02092
02093
02094
02095 if((Pclip > Qclip) || (Pclip & Behind)){
02096 T = P; P = Q; Q = T;
02097 Tclip = Pclip; Pclip = Qclip; Qclip = Tclip;
02098 }
02099
02100
02101
02102
02103 PX = P->BX - H; PY = -(P->Y - V);
02104 QX = Q->BX - H; QY = -(Q->Y - V);
02105
02106 if(clipSegment(&PX, &PY, &QX, &QY, Pclip, Qclip, H, V)){
02107
02108 blue->x1 = (short)(PX + H);
02109 blue->y1 = (short)(V - PY);
02110 blue->x2 = (short)(QX + H);
02111 blue->y2 = (short)(V - QY);
02112 blue++;
02113
02114 }
02115 }
02116 }
02117 }
02118 seg++;
02119 }
02120 }else{
02121
02122
02123
02124 while(seg < lastSeg){
02125 P = seg->P; Q = seg->Q;
02126 pX = P->R.x; pY = P->R.y;
02127 qX = Q->R.x; qY = Q->R.y;
02128 red->x1 = pX;
02129 red->y1 = pY;
02130 red->x2 = qX;
02131 red->y2 = qY;
02132 red++;
02133 pX = P->sBX; qX = Q->sBX;
02134 blue->x1 = pX;
02135 blue->y1 = pY;
02136 blue->x2 = qX;
02137 blue->y2 = qY;
02138 blue++;
02139 seg++;
02140 }
02141
02142 }
02143
02144 g->numberBlue = blue - g->blueSegments;
02145 }
02146
02147 g->numRedColors = redCol - g->redColors;
02148 g->numberRed = red - g->redSegments;
02149 }
02150
02151
02152 #ifdef USE_INTS
02153
02154
02155
02156 #define REDROTATE \
02157 r8 = p0->x + c16; \
02158 r5 = p0->y + c17; \
02159 r2 = ((r8 * c5 + r5 * c6) >> SHIFT); \
02160 r7 = ((r5 * c5 - r8 * c6) >> SHIFT); \
02161 r8 = p0->z + c18; \
02162 r5 = ((r7 * c3 + r8 * c4) >> SHIFT) + c12; \
02163 r6 = ((r8 * c3 - r7 * c4) >> SHIFT); \
02164 r7 = c7 + ((((r6 * c1 - r2 * c2) >> SHIFT) + c13) * c0) / r5; \
02165 r8 = c9 - ((((r2 * c1 + r6 * c2) >> SHIFT) + c11) * c0) / r5; \
02166 r5 = (c0 * 8192) / r5
02167
02168
02169
02170 #define STEREOROTATE \
02171 r8 = p0->x + c16; \
02172 r5 = p0->y + c17; \
02173 r2 = ((r8 * c5 + r5 * c6) >> SHIFT); \
02174 r7 = ((r5 * c5 - r8 * c6) >> SHIFT); \
02175 r8 = p0->z + c18; \
02176 r5 = ((r7 * c3 + r8 * c4) >> SHIFT) + c12; \
02177 r6 = ((r8 * c3 - r7 * c4) >> SHIFT); \
02178 r7 = c7 + ((((r6 * c1 - r2 * c2) >> SHIFT) + c13) * c0) / r5; \
02179 r8 = c9 - ((((r2 * c1 + r6 * c2) >> SHIFT) + c11) * c0) / r5; \
02180 r9 = r8 - c15 - (c0 * c14) / r5; \
02181 r5 = (c0 * 8192) / r5
02182
02183 #else
02184
02185
02186
02187 #define REDROTATE \
02188 r8 = p0->x + c16; \
02189 r5 = p0->y + c17; \
02190 r2 = r8 * c5 + r5 * c6; \
02191 r7 = r5 * c5 - r8 * c6; \
02192 r8 = p0->z + c18; \
02193 r5 = c0 / (r7 * c3 + r8 * c4 + c12); \
02194 r6 = r8 * c3 - r7 * c4; \
02195 r7 = c7 + (r6 * c1 - r2 * c2 + c13) * r5; \
02196 r8 = c9 - (r2 * c1 + r6 * c2 + c11) * r5
02197
02198 #define STEREOROTATE \
02199 REDROTATE; \
02200 r9 = r8 - c15 - r5 * c14
02201
02202 #endif
02203
02204
02205
02206
02207 #define REDCLIPFLAGS \
02208 (r5 > 0) * ALLmask ^ ((r7 < 0) | (r7 > c10) << ClipWithBottom | \
02209 (r8 > c8) << RClipWithRight | (r8 < 0) << RClipWithLeft)
02210
02211
02212
02213 #define STEREOCLIPFLAGS \
02214 (r5 > 0) * ALLmask ^ ((r7 < 0) | (r7 > c10) << ClipWithBottom | \
02215 (r8 > c8) << RClipWithRight | (r8 < 0) << RClipWithLeft | \
02216 (r9 > c8) << BClipWithRight | (r9 < 0) << BClipWithLeft)
02217
02218
02219
02220 static void rotate(o, g)
02221 Oinfo *o;
02222 Ginfo *g;
02223
02224
02225
02226 {
02227 register number r2,r5,r6,r7,r8,r9;
02228 register point *p0;
02229 register number c1,c2,c3,c4,c5,c6;
02230 register point *p1;
02231 register number c0,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c18;
02232 register int objClip;
02233 register short RX, BX;
02234
02235 p0 = o->bounds; p1 = &(o->bounds[NUMBOUNDS]); c0 = (number)o->viewpointY;
02236 c1 = (number)(cos(o->Y) * TRIG_ADJ); c2 = (number)(sin(o->Y) * TRIG_ADJ);
02237 c3 = (number)(cos(o->X) * TRIG_ADJ); c4 = (number)(sin(o->X) * TRIG_ADJ);
02238 c5 = (number)(cos(o->Z) * TRIG_ADJ); c6 = (number)(sin(o->Z) * TRIG_ADJ);
02239 c7 = (number)g->winH; c8 = (number)(2.0 * g->winH);
02240 c9 = (number)g->winV; c10 = (number)(2.0 * g->winV);
02241 c11 = (number)o->tX; c12 = (number)(o->tY - o->viewpointY);
02242 c13 = (number)o->tZ; c14 = (number)o->BViewpointX;
02243 c15 = (number)(o->BViewpointX * o->focus); c16 = (number)-o->oX;
02244 c17 = (number)-o->oY; c18 = (number)-o->oZ;
02245
02246 objClip = 0;
02247 o->Hmin2 = o->Hmin1; o->Vmin2 = o->Vmin1;
02248 o->Hmax2 = o->Hmax1; o->Vmax2 = o->Vmax1;
02249 o->Hmin1 = o->Hmin; o->Vmin1 = o->Vmin;
02250 o->Hmax1 = o->Hmax; o->Vmax1 = o->Vmax;
02251 o->Hmin = c8; o->Vmin = c10;
02252 o->Hmax = 0; o->Vmax = 0;
02253
02254
02255
02256 while(p0 != p1){
02257 STEREOROTATE;
02258
02259 if(STEREOCLIPFLAGS)
02260 objClip = 1;
02261
02262 if((int)r7 < o->Vmin){ o->Vmin = (int)r7; }
02263 if((int)r7 > o->Vmax){ o->Vmax = (int)r7; }
02264
02265 if((int)r8 < o->Hmin){ o->Hmin = (int)r8; }
02266 if((int)r8 > o->Hmax){ o->Hmax = (int)r8; }
02267
02268 if((g->stereo) && (g->stereoBlue)){
02269 if((int)r9 < o->Hmin){ o->Hmin = (int)r9; }
02270 if((int)r9 > o->Hmax){ o->Hmax = (int)r9; }
02271 }
02272
02273 p0++;
02274 }
02275
02276
02277
02278 if((g->modeChanged) || (objClip)){
02279 o->Hmin = o->Hmin1 = o->Hmin2 = 0;
02280 o->Vmin = o->Vmin1 = o->Vmin2 = 0;
02281 o->Hmax = o->Hmax1 = o->Hmax2 = g->winX;
02282 o->Vmax = o->Vmax1 = o->Vmax2 = g->winY;
02283 }else{
02284 if(o->Hmin < 0){o->Hmin = 0;}
02285 if(o->Vmin < 0){o->Vmin = 0;}
02286 if(o->Hmax > c8){o->Hmax = c8;}
02287 if(o->Vmax > c10){o->Vmax = c10;}
02288
02289 if(o->Hmin1 < o->Hmin2){o->Hmin2 = o->Hmin1;}
02290 if(o->Vmin1 < o->Vmin2){o->Vmin2 = o->Vmin1;}
02291 if(o->Hmax1 > o->Hmax2){o->Hmax2 = o->Hmax1;}
02292 if(o->Vmax1 > o->Vmax2){o->Vmax2 = o->Vmax1;}
02293 }
02294
02295 o->fillX = o->Hmin2; o->fillY = o->Vmin2;
02296 o->fillWidth = o->Hmax2 - o->Hmin2 + 1;
02297 o->fillHeight = o->Vmax2 - o->Vmin2 + 1;
02298
02299 if(o->Hmin < o->Hmin2){o->Hmin2 = o->Hmin;}
02300 if(o->Vmin < o->Vmin2){o->Vmin2 = o->Vmin;}
02301 if(o->Hmax > o->Hmax2){o->Hmax2 = o->Hmax;}
02302 if(o->Vmax > o->Vmax2){o->Vmax2 = o->Vmax;}
02303
02304 o->copyX = o->Hmin2; o->copyY = o->Vmin2;
02305 o->copyWidth = o->Hmax2 - o->Hmin2 + 1;
02306 o->copyHeight = o->Vmax2 - o->Vmin2 + 1;
02307
02308 o->objClip = objClip;
02309 p0 = o->points;
02310 p1 = &(o->points[o->numPoints]);
02311
02312 if(objClip){
02313
02314
02315
02316 if((g->stereo) && (g->stereoBlue)){
02317 if(g->renderMode == WIREFRAME){
02318 while(p0 != p1){
02319 STEREOROTATE;
02320 p0->Y = (float)r7; p0->R.y = (short)r7;
02321 p0->RX = (float)r8; p0->R.x = (short)r8;
02322 p0->BX = (float)r9; p0->sBX = (short)r9;
02323 p0->ClipFlags = STEREOCLIPFLAGS;
02324 p0++;
02325 }
02326 }else{
02327
02328 while(p0 != p1){
02329 STEREOROTATE;
02330 p0->dist = (float)r5;
02331 p0->Y = (float)r7; p0->R.y = (short)r7;
02332 p0->RX = (float)r8; p0->R.x = (short)r8;
02333 p0->BX = (float)r9; p0->sBX = (short)r9;
02334 p0->ClipFlags = STEREOCLIPFLAGS;
02335 p0++;
02336 }
02337 }
02338 }else{
02339 if(g->renderMode == WIREFRAME){
02340 while(p0 != p1){
02341 REDROTATE;
02342 p0->Y = (float)r7; p0->R.y = (short)r7;
02343 p0->RX = (float)r8; p0->R.x = (short)r8;
02344 p0->ClipFlags = REDCLIPFLAGS;
02345 p0++;
02346 }
02347 }else{
02348
02349 while(p0 != p1){
02350 REDROTATE;
02351 p0->dist = (float)r5;
02352 p0->Y = (float)r7; p0->R.y = (short)r7;
02353 p0->RX = (float)r8; p0->R.x = (short)r8;
02354 p0->ClipFlags = REDCLIPFLAGS;
02355 p0++;
02356 }
02357 }
02358 }
02359 }else{
02360
02361
02362
02363 if((g->stereo) && (g->stereoBlue)){
02364 if(g->renderMode == WIREFRAME){
02365 while(p0 != p1){
02366 STEREOROTATE;
02367 p0->R.y = (short)r7;
02368 p0->R.x = (short)r8;
02369 p0->sBX = (short)r9;
02370 p0++;
02371 }
02372 }else{
02373
02374 while(p0 != p1){
02375 STEREOROTATE;
02376 p0->dist = (float)r5;
02377 p0->R.y = (short)r7;
02378
02379 RX = r8;
02380 p0->R.x = (float)RX;
02381
02382 BX = r9;
02383 p0->sBX = (float)BX;
02384
02385 p0++;
02386 }
02387 }
02388 }else{
02389 if(g->renderMode == WIREFRAME){
02390 while(p0 != p1){
02391 REDROTATE;
02392 p0->R.y = (short)r7;
02393 p0->R.x = (short)r8;
02394 p0++;
02395 }
02396 }else{
02397
02398 while(p0 != p1){
02399 REDROTATE;
02400 p0->dist = (float)r5;
02401
02402 p0->R.y = (short)r7;
02403 RX = (short)r8;
02404 p0->R.x = (float)RX;
02405
02406 p0++;
02407 }
02408 }
02409 }
02410 }
02411 }
02412
02413
02414
02415
02416 static void DrawSegments(display, win, gc, segs1, numSegs, g)
02417 Display *display;
02418 Window win;
02419 GC gc;
02420 XSegment segs1[];
02421 int numSegs;
02422 Ginfo *g;
02423
02424
02425
02426
02427 {
02428 int requestSize, evenAmount, remainder1, index1;
02429
02430 requestSize = g->requestSize;
02431 evenAmount = (numSegs / requestSize) * requestSize;
02432 remainder1 = numSegs - evenAmount;
02433
02434 index1 = 0;
02435
02436 while(index1 < evenAmount){
02437 XDrawSegments(display, win, gc, &segs1[index1], requestSize);
02438 index1 += requestSize;
02439 }
02440
02441 if(remainder1 > 0)
02442 XDrawSegments(display, win, gc, &segs1[index1], remainder1);
02443 }
02444
02445
02446
02447 static void DrawLines(o, g, mode)
02448 Oinfo *o;
02449 Ginfo *g;
02450 int mode;
02451
02452
02453
02454 {
02455 Drawable dest;
02456 long lastColor;
02457 int lastChange, index1;
02458
02459 dest = g->dest;
02460
02461 switch(mode){
02462
02463 case BW:
02464 XSetForeground(g->dpy, g->gc, g->black);
02465 XFillRectangle(g->dpy, dest, g->gc, o->fillX, o->fillY,
02466 o->fillWidth, o->fillHeight);
02467 XSetForeground(g->dpy, g->gc, g->white);
02468 DrawSegments (g->dpy, dest, g->gc, g->redSegments, g->numberRed, g);
02469 break;
02470
02471 case STEREO:
02472
02473 XSetForeground(g->dpy, g->gc, (long)g->Black);
02474 XFillRectangle(g->dpy, dest, g->gc, o->fillX, o->fillY,
02475 o->fillWidth, o->fillHeight);
02476
02477 XSetForeground(g->dpy, g->gc, (long)g->Red);
02478 DrawSegments(g->dpy, dest, g->gc, g->redSegments, g->numberRed, g);
02479
02480 if(g->stereoBlue){
02481
02482 XSetFunction (g->dpy, g->gc, GXor);
02483
02484 XSetForeground(g->dpy, g->gc, (long)g->Blue);
02485 DrawSegments(g->dpy, dest, g->gc, g->blueSegments, g->numberBlue,
02486 g);
02487
02488 XSetFunction (g->dpy, g->gc, GXcopy);
02489 }
02490
02491 break;
02492
02493 case COLOR:
02494
02495 XSetForeground(g->dpy, g->gc, g->Black);
02496 XFillRectangle(g->dpy, dest, g->gc, o->fillX, o->fillY,
02497 o->fillWidth, o->fillHeight);
02498
02499 lastChange = 4;
02500 lastColor = g->redColors[lastChange];
02501
02502 for(index1 = 5; index1 < g->numberRed; index1++){
02503 if(g->redColors[index1] != lastColor){
02504 XSetForeground(g->dpy, g->gc, lastColor);
02505 DrawSegments(g->dpy, dest, g->gc, &(g->redSegments[lastChange]),
02506 index1 - lastChange, g);
02507 lastChange = index1;
02508 lastColor = g->redColors[lastChange];
02509 }
02510 }
02511
02512 XSetForeground(g->dpy, g->gc, lastColor);
02513 DrawSegments(g->dpy, dest, g->gc, &(g->redSegments[lastChange]),
02514 g->numberRed - lastChange, g);
02515
02516 break;
02517
02518 default:
02519 break;
02520 }
02521 }
02522
02523
02524
02525 static void DrawHiddenLines(o, g, mode)
02526 Oinfo *o;
02527 Ginfo *g;
02528 int mode;
02529
02530
02531
02532 {
02533 register int index1, npoints, numPolys;
02534 register polygon *poly, **list1;
02535 register point **pointPtr, **lastPointPtr;
02536 Drawable dest;
02537
02538 _XPoint points1[512], *XPointPtr;
02539 void *ptrp = points1;
02540 dest = g->dest;
02541 numPolys = o->numPolys;
02542 list1 = o->list;
02543
02544 sort(list1, numPolys);
02545
02546 switch(mode){
02547
02548 case BW:
02549
02550 XSetForeground(g->dpy, g->gc, g->black);
02551 XFillRectangle(g->dpy, dest, g->gc, o->fillX, o->fillY,
02552 o->fillWidth, o->fillHeight);
02553
02554 for(index1 = 0; index1 < numPolys; index1++){
02555
02556 poly = list1[index1];
02557 XPointPtr = points1;
02558 npoints = poly->numPoints;
02559 pointPtr = poly->points;
02560 lastPointPtr = &(poly->points[npoints]);
02561
02562 while(pointPtr < lastPointPtr){
02563 *XPointPtr = (*pointPtr)->R;
02564 XPointPtr++;
02565 pointPtr++;
02566 }
02567
02568 XSetForeground(g->dpy, g->gc, g->black);
02569 XFillPolygon(g->dpy, dest, g->gc, ptrp, npoints, Convex,
02570 CoordModeOrigin);
02571 points1[npoints] = points1[0];
02572 XSetForeground(g->dpy, g->gc, g->white);
02573 XDrawLines(g->dpy, dest, g->gc, ptrp, npoints + 1,
02574 CoordModeOrigin);
02575 }
02576
02577 XSetFillStyle(g->dpy, g->gc, FillSolid);
02578 break;
02579
02580 case STEREO:
02581
02582 XSetForeground(g->dpy, g->gc, g->stereoBlack);
02583 XFillRectangle(g->dpy, dest, g->gc, o->fillX, o->fillY,
02584 o->fillWidth, o->fillHeight);
02585
02586 XSetPlaneMask(g->dpy, g->gc, g->redMask);
02587
02588 for(index1 = 0; index1 < numPolys; index1++){
02589 poly = list1[index1];
02590 XPointPtr = points1;
02591 npoints = poly->numPoints;
02592 pointPtr = poly->points;
02593 lastPointPtr = &(poly->points[npoints]);
02594
02595 while(pointPtr < lastPointPtr){
02596 *XPointPtr = (*pointPtr)->R;
02597 XPointPtr++;
02598 pointPtr++;
02599 }
02600
02601 XSetForeground(g->dpy, g->gc, g->stereoBlack);
02602 XFillPolygon(g->dpy, dest, g->gc, ptrp, npoints, Convex,
02603 CoordModeOrigin);
02604 points1[npoints] = points1[0];
02605 XSetForeground(g->dpy, g->gc, poly->color->stereoColor);
02606 XDrawLines(g->dpy, dest, g->gc, ptrp, npoints + 1,
02607 CoordModeOrigin);
02608 }
02609
02610 if(g->stereoBlue){
02611 XSetPlaneMask(g->dpy, g->gc, g->blueMask);
02612
02613 for(index1 = 0; index1 < numPolys; index1++){
02614 poly = list1[index1];
02615 XPointPtr = points1;
02616 npoints = poly->numPoints;
02617 pointPtr = poly->points;
02618 lastPointPtr = &(poly->points[npoints]);
02619
02620 while(pointPtr < lastPointPtr){
02621 XPointPtr->x = (*pointPtr)->sBX;
02622 XPointPtr->y = (*pointPtr)->R.y;
02623 XPointPtr++;
02624 pointPtr++;
02625 }
02626
02627 XSetForeground(g->dpy, g->gc, g->stereoBlack);
02628 XFillPolygon(g->dpy, dest, g->gc, ptrp, npoints, Convex,
02629 CoordModeOrigin);
02630 points1[npoints] = points1[0];
02631 XSetForeground(g->dpy, g->gc, poly->color->stereoColor);
02632 XDrawLines(g->dpy, dest, g->gc, ptrp, npoints + 1,
02633 CoordModeOrigin);
02634 }
02635 }
02636 XSetPlaneMask(g->dpy, g->gc, AllPlanes);
02637 break;
02638
02639 case COLOR:
02640
02641 XSetForeground(g->dpy, g->gc, g->Black);
02642 XFillRectangle(g->dpy, dest, g->gc, o->fillX, o->fillY,
02643 o->fillWidth, o->fillHeight);
02644
02645 for(index1 = 0; index1 < numPolys; index1++){
02646 poly = list1[index1];
02647 XPointPtr = points1;
02648 npoints = poly->numPoints;
02649 pointPtr = poly->points;
02650 lastPointPtr = &(poly->points[npoints]);
02651
02652 while(pointPtr < lastPointPtr){
02653 *XPointPtr = (*pointPtr)->R;
02654 XPointPtr++;
02655 pointPtr++;
02656 }
02657
02658 XSetForeground(g->dpy, g->gc, g->Black);
02659 XFillPolygon(g->dpy, dest, g->gc, ptrp, npoints, Convex,
02660 CoordModeOrigin);
02661
02662 points1[npoints] = points1[0];
02663 XSetForeground(g->dpy, g->gc, poly->color->value);
02664 XDrawLines(g->dpy, dest, g->gc, ptrp, npoints + 1,
02665 CoordModeOrigin);
02666 }
02667
02668 break;
02669
02670 default:
02671 break;
02672 }
02673 }
02674
02675
02676
02677 static void DrawPolys(o, g, mode)
02678 Oinfo *o;
02679 Ginfo *g;
02680 int mode;
02681
02682
02683
02684 {
02685 register int index1, npoints, numPolys;
02686 register polygon *poly, **list1;
02687 register point **pointPtr, **lastPointPtr;
02688 Drawable dest;
02689 _XPoint points1[512], *XPointPtr;
02690 long lastColor;
02691
02692 void *ptrp = points1;
02693 dest = g->dest;
02694 numPolys = o->numPolys;
02695 list1 = o->list;
02696
02697 sort(list1, numPolys);
02698
02699 switch(mode){
02700
02701 case BW:
02702
02703 XSetForeground(g->dpy, g->gc, g->black);
02704 XFillRectangle(g->dpy, dest, g->gc, o->fillX, o->fillY,
02705 o->fillWidth, o->fillHeight);
02706 XSetForeground(g->dpy, g->gc, g->white);
02707 XSetBackground(g->dpy, g->gc, g->black);
02708 XSetFillStyle(g->dpy, g->gc, FillOpaqueStippled);
02709
02710 for(index1 = 0; index1 < numPolys; index1++){
02711
02712 poly = list1[index1];
02713 XPointPtr = points1;
02714 XSetStipple(g->dpy, g->gc, g->stipple[poly->color->stipple]);
02715 npoints = poly->numPoints;
02716 pointPtr = poly->points;
02717 lastPointPtr = &(poly->points[npoints]);
02718
02719 while(pointPtr < lastPointPtr){
02720 *XPointPtr = (*pointPtr)->R;
02721 XPointPtr++;
02722 pointPtr++;
02723 }
02724
02725 XFillPolygon(g->dpy, dest, g->gc, ptrp, npoints, Convex,
02726 CoordModeOrigin);
02727 }
02728
02729 XSetFillStyle(g->dpy, g->gc, FillSolid);
02730 break;
02731
02732 case STEREO:
02733
02734 XSetForeground(g->dpy, g->gc, g->stereoBlack);
02735 XFillRectangle(g->dpy, dest, g->gc, o->fillX, o->fillY,
02736 o->fillWidth, o->fillHeight);
02737 lastColor = g->stereoBlack;
02738
02739 XSetPlaneMask(g->dpy, g->gc, g->redMask);
02740
02741 for(index1 = 0; index1 < numPolys; index1++){
02742 poly = list1[index1];
02743 XPointPtr = points1;
02744 if(poly->color->stereoColor != lastColor){
02745 XSetForeground(g->dpy, g->gc, poly->color->stereoColor);
02746 lastColor = poly->color->stereoColor;
02747 }
02748 npoints = poly->numPoints;
02749 pointPtr = poly->points;
02750 lastPointPtr = &(poly->points[npoints]);
02751
02752 while(pointPtr < lastPointPtr){
02753 *XPointPtr = (*pointPtr)->R;
02754 XPointPtr++;
02755 pointPtr++;
02756 }
02757
02758 XFillPolygon(g->dpy, dest, g->gc, ptrp, npoints, Convex,
02759 CoordModeOrigin);
02760 }
02761
02762 if(g->stereoBlue){
02763 XSetPlaneMask(g->dpy, g->gc, g->blueMask);
02764
02765 for(index1 = 0; index1 < numPolys; index1++){
02766 poly = list1[index1];
02767 XPointPtr = points1;
02768 if(poly->color->stereoColor != lastColor){
02769 XSetForeground(g->dpy, g->gc, poly->color->stereoColor);
02770 lastColor = poly->color->stereoColor;
02771 }
02772 npoints = poly->numPoints;
02773 pointPtr = poly->points;
02774 lastPointPtr = &(poly->points[npoints]);
02775
02776 while(pointPtr < lastPointPtr){
02777 XPointPtr->x = (*pointPtr)->sBX;
02778 XPointPtr->y = (*pointPtr)->R.y;
02779 XPointPtr++;
02780 pointPtr++;
02781 }
02782
02783 XFillPolygon(g->dpy, dest, g->gc, ptrp, npoints, Convex,
02784 CoordModeOrigin);
02785 }
02786 }
02787 XSetPlaneMask(g->dpy, g->gc, AllPlanes);
02788 break;
02789
02790 case COLOR:
02791
02792 XSetForeground(g->dpy, g->gc, g->Black);
02793 XFillRectangle(g->dpy, dest, g->gc, o->fillX, o->fillY,
02794 o->fillWidth, o->fillHeight);
02795 lastColor = g->Black;
02796
02797 for(index1 = 0; index1 < numPolys; index1++){
02798 poly = list1[index1];
02799 XPointPtr = points1;
02800 if(poly->color->value != lastColor){
02801 XSetForeground(g->dpy, g->gc, poly->color->value);
02802 lastColor = poly->color->value;
02803 }
02804 npoints = poly->numPoints;
02805 pointPtr = poly->points;
02806 lastPointPtr = &(poly->points[npoints]);
02807
02808 while(pointPtr < lastPointPtr){
02809 *XPointPtr = (*pointPtr)->R;
02810 XPointPtr++;
02811 pointPtr++;
02812 }
02813
02814 XFillPolygon(g->dpy, dest, g->gc, ptrp, npoints, Convex,
02815 CoordModeOrigin);
02816 }
02817
02818 break;
02819
02820 default:
02821 break;
02822 }
02823 }
02824
02825
02826
02827 static void BeginImage(Oinfo *o, Ginfo *g)
02828
02829
02830
02831 {
02832
02833
02834 if (o) { }
02835 if(g->modeChanged){
02836 XSetPlaneMask(g->dpy, g->gc, AllPlanes);
02837 if((g->mono) || (g->depth == ONE)){
02838 XSetForeground(g->dpy, g->gc, g->black);
02839 }else{
02840 if(g->stereo){
02841 XSetForeground(g->dpy, g->gc, (long)g->Black);
02842 }else{
02843 XSetForeground(g->dpy, g->gc, g->Black);
02844 }
02845 }
02846
02847 XFillRectangle(g->dpy, g->pix, g->gc, 0, 0, g->winX, g->winY);
02848 XFillRectangle(g->dpy, g->win, g->gc, 0, 0, g->winX, g->winY);
02849 }
02850
02851 if(g->buffer){
02852 if((g->mono) || (g->depth != EIGHT)){
02853 g->dest = g->pix;
02854 }else{
02855 if((g->numColors > BUFFER_CMAP) || (((g->renderMode == SOLID) ||
02856 (g->renderMode == HIDDENLINE)) && (g->stereo))){
02857 g->dest = g->pix;
02858 }else{
02859 g->dest = g->win;
02860
02861 if(g->ColorSelect){
02862 XSetPlaneMask(g->dpy, g->gc, BUFFER1);
02863 }else{
02864 XSetPlaneMask(g->dpy, g->gc, BUFFER0);
02865 }
02866 }
02867 }
02868 }else{
02869 g->dest = g->win;
02870 }
02871 }
02872
02873
02874
02875 static void DrawObject(o, g)
02876 Oinfo *o;
02877 Ginfo *g;
02878
02879
02880
02881
02882 {
02883
02884
02885
02886 rotate(o, g);
02887
02888
02889
02890 clip(o, g);
02891
02892
02893
02894 switch(g->renderMode){
02895
02896 case WIREFRAME:
02897 if((g->mono) || (g->depth == ONE)){
02898 DrawLines(o, g, BW);
02899 }else{
02900 if(g->stereo){
02901 DrawLines(o, g, STEREO);
02902 }else{
02903 DrawLines(o, g, COLOR);
02904 }
02905 }
02906 break;
02907
02908 case HIDDENLINE:
02909 if((g->mono) || (g->depth == ONE)){
02910 DrawHiddenLines(o, g, BW);
02911 }else{
02912 if(g->stereo){
02913 DrawHiddenLines(o, g, STEREO);
02914 }else{
02915 DrawHiddenLines(o, g, COLOR);
02916 }
02917 }
02918 break;
02919
02920 case SOLID:
02921 if((g->mono) || (g->depth == ONE)){
02922 DrawPolys(o, g, BW);
02923 }else{
02924 if(g->stereo){
02925 DrawPolys(o, g, STEREO);
02926 }else{
02927 DrawPolys(o, g, COLOR);
02928 }
02929 }
02930 break;
02931
02932 default :
02933 fprintf(stderr, "Unknown Render Mode!\n");
02934 return;
02935 break;
02936 }
02937
02938
02939
02940 g->numberRed = 4;
02941 g->numberBlue = 4;
02942 g->numRedColors = 4;
02943 g->modeChanged = 0;
02944 }
02945
02946
02947
02948 static void EndImage(o, g)
02949 Oinfo *o;
02950 Ginfo *g;
02951
02952
02953
02954 {
02955
02956
02957
02958 if((g->depth == EIGHT) && (!(g->mono)) && (g->numColors <= BUFFER_CMAP) &&
02959 (!((g->stereo) && (g->renderMode == HIDDENLINE))) &&
02960 (!((g->stereo) && (g->renderMode == SOLID)))){
02961 g->ColorSelect = !g->ColorSelect;
02962
02963 if((g->stereo) && (g->renderMode == WIREFRAME) && (!(g->modeChanged))){
02964 XStoreColors(g->dpy, g->colormap, g->wireframeColors[g->ColorSelect],
02965 12);
02966 }else{
02967 XStoreColors(g->dpy, g->colormap, g->cmapColors[g->ColorSelect], 256);
02968 }
02969 }else{
02970
02971
02972
02973 if(g->depth == EIGHT){
02974 if(((g->renderMode == SOLID) || (g->renderMode == HIDDENLINE))
02975 && (g->stereo)){
02976 XStoreColors(g->dpy, g->colormap, g->cmapColors[2], 256);
02977 }else{
02978 XStoreColors(g->dpy, g->colormap, g->cmapColors[g->ColorSelect],
02979 256);
02980 }
02981 }
02982
02983
02984
02985 if(g->buffer){
02986 XCopyArea(g->dpy, g->pix, g->win, g->gc, o->copyX, o->copyY,
02987 o->copyWidth, o->copyHeight, o->copyX, o->copyY);
02988 }
02989 }
02990
02991 XFlush(g->dpy);
02992 }
02993
02994
02995
02996
02997 void MakePolygonArray()
02998
02999
03000
03001 {
03002
03003
03004
03005
03006
03007 int index1, index2, i;
03008 point *prevPoint;
03009 segment *tmpSeg;
03010
03011
03012 if (gSize3D.numPolys) {
03013
03014 list = (polygon **) calloc(gSize3D.numPolys+1, sizeof(polygon *));
03015 if(!list){
03016 puts("Unable to allocate memory for pointer list !");
03017 return;
03018 }
03019 }
03020
03021 else list = (polygon **) calloc(2, sizeof(polygon *));
03022
03023 for(i = 0; i < gSize3D.numPolys; i++)
03024 list[i] = &(polys[i]);
03025
03026
03027
03028
03029
03030
03031 for(index1 = 0; index1 < gSize3D.numPolys; index1++) {
03032
03033 index2 = 0;
03034
03035 if((list[index1]->segs[0]->P == list[index1]->segs[1]->P) ||
03036 (list[index1]->segs[0]->P == list[index1]->segs[1]->Q)) {
03037 prevPoint = list[index1]->segs[0]->Q;
03038 }
03039 else{
03040 prevPoint = list[index1]->segs[0]->P;
03041 }
03042
03043 while(index2 < list[index1]->numSegs){
03044
03045 tmpSeg = list[index1]->segs[index2];
03046
03047 if(tmpSeg->P == prevPoint){
03048 prevPoint = tmpSeg->Q;
03049 }
03050 else{
03051 prevPoint = tmpSeg->P;
03052 }
03053
03054
03055
03056
03057
03058 if(prevPoint->numPolys == 0){
03059 if((prevPoint->polys = (polygon **)calloc(1, sizeof(polygon *)))== NULL){
03060 puts("Unable to allocate memory for point polygons !");
03061 return;
03062 }
03063 }
03064 else {
03065 if((prevPoint->polys = (polygon **)realloc(prevPoint->polys,
03066 (prevPoint->numPolys + 1) * sizeof(polygon *))) == NULL){
03067 puts("Unable to allocate memory for point polygons !");
03068 return;
03069 }
03070 }
03071 prevPoint->polys[prevPoint->numPolys] = &(polys[index1]);
03072 prevPoint->numPolys++;
03073
03074
03075
03076
03077
03078 if(polys[index1].numPoints == 0){
03079 if((polys[index1].points = (point **)calloc(1, sizeof(point *)))== NULL){
03080 puts("Unable to allocate memory for polygon points !");
03081 return;
03082 }
03083 }
03084 else {
03085 if((polys[index1].points = (point **) realloc(
03086 polys[index1].points, (polys[index1].numPoints + 1) *
03087 sizeof(point *))) == NULL){
03088 puts("Unable to allocate memory for point polygons !");
03089 return;
03090 }
03091 }
03092
03093 polys[index1].points[polys[index1].numPoints] = prevPoint;
03094 polys[index1].numPoints++;
03095
03096 index2++;
03097 }
03098 }
03099 }
03100
03101
03102
03103
03104
03105
03106
03107 unsigned long
03108 x3d_main(longitude, latitude, psi, string, parent)
03109 float *longitude;
03110 float *latitude;
03111 float *psi;
03112 char *string;
03113 Window parent;
03114 {
03115 Ginfo *g = NULL;
03116 Oinfo *o = NULL;
03117 int i, j;
03118 FILE *fp;
03119 int export = 0;
03120 char filename[80], *indx;
03121
03122 float xMin, yMin, zMin, xMax, yMax, zMax, correctionFactor;
03123 float xCenter, yCenter, zCenter;
03124 float xRange, zRange;
03125
03126 quitApplication = 0;
03127
03128 if((o = (Oinfo *) calloc(1, sizeof(Oinfo))) == NULL){
03129 (void) fprintf(stderr, "Unable to allocate memory for Object\n");
03130 return 0L;
03131 }
03132 gOInfo = o;
03133
03134 if((g = (Ginfo *) calloc(1, sizeof(Ginfo))) == NULL){
03135 (void) fprintf(stderr, "Unable to allocate memory for Ginfo\n");
03136 return 0L;
03137 }
03138 gGInfo = g;
03139
03140 indx = NULL;
03141 strcpy(title, "ROOT://X3D");
03142
03143
03144
03145
03146 if (!strcmp(string, "help")) {
03147 puts("**** x3d QUICK HELP **************************************\n");
03148 puts(" QUIT q Q MOVE OBJECT DOWN u U" );
03149 puts(" TOGGLE CONTROLS STYLE o O MOVE OBJECT UP i I" );
03150 puts(" TOGGLE STEREO DISPLAY s S MOVE OBJECT RIGHT h H" );
03151 puts(" TOGGLE BLUE STEREO VIEW d D MOVE OBJECT BACKWARD j J" );
03152 puts(" TOGGLE DOUBLE BUFFER f F MOVE OBJECT FOREWARD k K" );
03153 puts(" TOGGLE HELP MENU m M MOVE OBJECT LEFT l L" );
03154 puts(" ROTATE ABOUT X x X a A AUTOROTATE ABOUT X 1 2 3" );
03155 puts(" ROTATE ABOUT Y y Y b B AUTOROTATE ABOUT Y 4 5 6" );
03156 puts(" ROTATE ABOUT Z z Z c C AUTOROTATE ABOUT Z 7 8 9\n");
03157 puts(" ADJUST FOCUS [ ] { } HIDDEN LINE MODE e E" );
03158 puts(" WIREFRAME MODE w W HIDDEN SURFACE MODE r R\n");
03159 puts(" POINTER MOVEMENT WITH LEFT BUTTON :\n");
03160 puts(" ROTATE OBJECT ABOUT X Vertical" );
03161 puts(" ROTATE OBJECT ABOUT Z Horizontal\n");
03162
03163 return 0L;
03164 }
03165 else if ((indx = (char *) strstr(string, "hull:")) != NULL) {
03166 strcpy (filename, indx + 5);
03167 if (strlen(filename)) export = 1;
03168 }
03169 else if ((indx = (char *) strstr(string, "java:")) != NULL) {
03170 strcpy (filename, indx + 5);
03171 if (strlen(filename)) export = 2;
03172 }
03173 else if (string) {
03174 strcat(title, "/");
03175 strcat(title, string);
03176 }
03177
03178 switch( export ) {
03179 case 1:
03180
03181 if (gSize3D.numPolys) {
03182 fp = fopen (filename, "w");
03183 if (fp != NULL) {
03184 for (i = 0; i < gSize3D.numPolys; i++) {
03185 fprintf (fp, "\n# polygon No. %d color ( R G B )\n", i);
03186 fprintf (fp, "%5d%5d%5d\n\n", polys[i].color->red, polys[i].color->green, polys[i].color->blue);
03187 for (j = 0; j < polys[i].numSegs; j++) {
03188 fprintf (fp, "%20.6f%20.6f%20.6f\n", polys[i].segs[j]->P->x, polys[i].segs[j]->P->y, polys[i].segs[j]->P->z);
03189 }
03190 }
03191 fclose (fp);
03192 }
03193 }
03194 else puts ("Can't export (number of polygons=0)");
03195 break;
03196
03197 case 2:
03198
03199 if( gSize3D.numSegs ) {
03200 fp = fopen( filename, "w" );
03201 if( fp != NULL ) {
03202 for( i = 0; i < gSize3D.numSegs; i++ ) {
03203 fprintf( fp, "v %20.6f%20.6f%20.6f\n", segs[i].P->x, segs[i].P->y, segs[i].P->z);
03204 fprintf( fp, "v %20.6f%20.6f%20.6f\n", segs[i].Q->x, segs[i].Q->y, segs[i].Q->z);
03205 fprintf( fp, "l %6d%6d\n", i*2+1, i*2+2 );
03206 }
03207 fclose (fp);
03208 }
03209 }
03210 break;
03211
03212 default:
03213 break;
03214 }
03215
03216
03217
03218
03219
03220 xMin = yMin = zMin = 999999;
03221 xMax = yMax = zMax = -999999;
03222
03223 for (i = 0; i < gSize3D.numPoints; i++) {
03224 xMin = xMin <= points[i].x ? xMin : points[i].x;
03225 xMax = xMax >= points[i].x ? xMax : points[i].x;
03226
03227 yMin = yMin <= points[i].y ? yMin : points[i].y;
03228 yMax = yMax >= points[i].y ? yMax : points[i].y;
03229
03230 zMin = zMin <= points[i].z ? zMin : points[i].z;
03231 zMax = zMax >= points[i].z ? zMax : points[i].z;
03232 }
03233
03234
03235
03236
03237
03238 xRange = fabs(xMax - xMin);
03239 zRange = fabs(zMax - zMin);
03240
03241 xCenter = (xMax + xMin) / 2.0;
03242 yCenter = (yMax + yMin) / 2.0;
03243 zCenter = (zMax + zMin) / 2.0;
03244
03245
03246
03247
03248 correctionFactor = 6000.0 / (xRange > zRange ? xRange : zRange);
03249
03250 for (i = 0; i < gSize3D.numPoints; i++) {
03251 points[i].x = (points[i].x - xCenter) * correctionFactor;
03252 points[i].y = (points[i].y - yCenter) * correctionFactor;
03253 points[i].z = (points[i].z - zCenter) * correctionFactor;
03254 }
03255
03256 deltaMove = (float) (xRange >= zRange ? xRange : zRange) / 20.0 * correctionFactor;
03257
03258
03259
03260
03261
03262 bounds = NULL;
03263 bounds = (point *) calloc(8, sizeof(point));
03264
03265 if (!bounds)
03266 (void) fprintf(stderr, "Unable to allocate memory for bounding cube.\n");
03267
03268 xMin = (xMin - xCenter) * correctionFactor;
03269 xMax = (xMax - xCenter) * correctionFactor;
03270 yMin = (yMin - yCenter) * correctionFactor;
03271 yMax = (yMax - yCenter) * correctionFactor;
03272 zMin = (zMin - zCenter) * correctionFactor;
03273 zMax = (zMax - zCenter) * correctionFactor;
03274
03275 if (bounds) {
03276 bounds[0].x = xMin; bounds[0].y = yMin; bounds[0].z = zMin;
03277 bounds[1].x = xMin; bounds[1].y = yMin; bounds[1].z = zMax;
03278 bounds[2].x = xMin; bounds[2].y = yMax; bounds[2].z = zMin;
03279 bounds[3].x = xMin; bounds[3].y = yMax; bounds[3].z = zMax;
03280 bounds[4].x = xMax; bounds[4].y = yMin; bounds[4].z = zMin;
03281 bounds[5].x = xMax; bounds[5].y = yMin; bounds[5].z = zMax;
03282 bounds[6].x = xMax; bounds[6].y = yMax; bounds[6].z = zMin;
03283 bounds[7].x = xMax; bounds[7].y = yMax; bounds[7].z = zMax;
03284 }
03285
03286
03287
03288
03289
03290 MakePolygonArray();
03291
03292 g->Geometry = "800x600";
03293 g->DisplayName = NULL;
03294 g->renderMode = WIREFRAME;
03295 g->buffer = 1;
03296 g->mono = 0;
03297 g->stereo = 0;
03298 g->stereoBlue = 1;
03299 g->colors = colors;
03300 g->numColors = 28;
03301 g->win = 0;
03302 o->points = points;
03303 o->numPoints = gSize3D.numPoints;
03304 o->segs = segs;
03305 o->numSegs = gSize3D.numSegs;
03306 o->polys = polys;
03307 o->numPolys = gSize3D.numPolys;
03308 o->list = list;
03309 o->bounds = bounds;
03310
03311
03312 if (!export && bounds) {
03313
03314
03315
03316 o->BViewpointX = 100.0;
03317 o->viewpointY = -650.0;
03318 o->tX = 640.0;
03319 o->tY = 6000.0;
03320 o->tZ = 490.0;
03321 o->oX = 0.0;
03322 o->oY = 0.0;
03323 o->oZ = 0.0;
03324 o->X = (double) (*latitude);
03325 o->Y = (double) (*psi);
03326 o->Z = (double) (*longitude);
03327 o->dX = 0.0;
03328 o->dY = 0.0;
03329 o->dZ = 0.0;
03330 o->focus = 0.2;
03331
03332
03333
03334
03335
03336 InitDisplay(o, g, parent);
03337
03338 return g->win;
03339 }
03340 return 0;
03341 }
03342
03343 void x3d_update()
03344 {
03345 Ginfo *g = gGInfo;
03346 Oinfo *o = gOInfo;
03347
03348 BeginImage(o, g);
03349 DrawObject(o, g);
03350 EndImage(o, g);
03351 }
03352
03353 int x3d_dispatch_event(unsigned long evnt)
03354 {
03355
03356 XEvent *event = (XEvent *)evnt;
03357 Ginfo *g = gGInfo;
03358 Oinfo *o = gOInfo;
03359
03360 UpdatePosition(event, o, g);
03361
03362 x3d_update();
03363
03364 return 1;
03365 }
03366
03367 void x3d_get_position(float *longitude, float *latitude, float *psi)
03368 {
03369 Oinfo *o = gOInfo;
03370
03371
03372 *latitude = (float) (o->X);
03373 *psi = (float) (o->Y);
03374 *longitude = (float) (o->Z);
03375 }
03376
03377 void x3d_terminate()
03378 {
03379 int i;
03380 Ginfo *g = gGInfo;
03381 Oinfo *o = gOInfo;
03382
03383 if (g->win) {
03384
03385 XDestroyWindow(g->dpy, g->win);
03386 XDestroyWindow(g->dpy, g->helpWin);
03387
03388
03389 XFreeGC(g->dpy, g->gc);
03390 XFreeGC(g->dpy, g->helpGc);
03391
03392
03393 XFreePixmap(g->dpy, g->pix);
03394
03395
03396
03397 if (!gDisplay) {
03398 XSetCloseDownMode(g->dpy, DestroyAll);
03399 XCloseDisplay(g->dpy);
03400 }
03401
03402
03403 if (g->redColors) free (g->redColors);
03404 if (g->redSegments) free (g->redSegments);
03405 if (g->blueSegments) free (g->blueSegments);
03406 if (o) free (o);
03407 if (g) free (g);
03408
03409 }
03410
03411
03412
03413
03414 currPoint = currSeg = currPoly = 0;
03415
03416 for (i = 0; i < gSize3D.numPolys; i++) {
03417
03418
03419
03420
03421
03422
03423 if (polys[i].points) free (polys[i].points);
03424 }
03425
03426 for (i = 0; i < gSize3D.numSegs; i++)
03427 if (segs[i].polys) free (segs[i].polys);
03428
03429 for (i = 0; i < gSize3D.numPoints; i++)
03430 if (points[i].segs) free (points[i].segs);
03431
03432 if (points) free (points);
03433 if (colors) free (colors);
03434 if (segs) free (segs);
03435 if (polys) free (polys);
03436 if (list) free (list);
03437 if (bounds) free (bounds);
03438 }
03439
03440 void x3d_set_display(unsigned long disp)
03441 {
03442 gDisplay = (Display*) disp;
03443 }
03444
03445 int x3d_exec_command(int pointerX, int pointerY, char command)
03446
03447
03448
03449
03450
03451
03452 {
03453 int same, dx, dy;
03454 double X, Y, Z;
03455
03456 Ginfo *g = gGInfo;
03457 Oinfo *o = gOInfo;
03458
03459 X = Y = Z = 0.0;
03460
03461 same = 1;
03462
03463
03464
03465
03466
03467
03468
03469
03470 g->Block = 1;
03471
03472
03473
03474
03475 switch(command){
03476 case ' ' : break;
03477
03478 case 'm' :
03479 case 'M' : same = 0; g->helpMenu = !g->helpMenu;
03480
03481
03482
03483
03484
03485
03486
03487 break;
03488
03489 case 's' :
03490 case 'S' : same = 0; g->stereo = !g->stereo; g->modeChanged = 1;
03491 break;
03492
03493 case 'd' :
03494 case 'D' : same = 0; g->stereoBlue = !g->stereoBlue; g->modeChanged = 1;
03495 break;
03496
03497 case 'f' :
03498 case 'F' : same = 0; g->buffer = !g->buffer; g->modeChanged = 1;
03499 break;
03500
03501 case 'o' :
03502 case 'O' : same = 0; g->Relative = !g->Relative; break;
03503
03504 case 'w' :
03505 case 'W' : same = 0; g->renderMode = WIREFRAME; g->modeChanged = 1;
03506 break;
03507
03508 case 'e' :
03509 case 'E' : if(o->numPolys) {
03510 same = 0; g->renderMode = HIDDENLINE; g->modeChanged = 1;
03511 }
03512 break;
03513
03514 case 'r' :
03515 case 'R' : if(o->numPolys) {
03516 same = 0; g->renderMode = SOLID; g->modeChanged = 1;
03517 }
03518 break;
03519
03520 case 'l' : same = 0; o->tX -= deltaMove; break;
03521 case 'j' : same = 0; o->tY -= deltaMove; break;
03522 case 'k' : same = 0; o->tY += deltaMove; break;
03523 case 'h' : same = 0; o->tX += deltaMove; break;
03524 case 'i' : same = 0; o->tZ += deltaMove; break;
03525 case 'u' : same = 0; o->tZ -= deltaMove; break;
03526 case 'L' : same = 0; o->tX -= 5*deltaMove; break;
03527 case 'J' : same = 0; o->tY -= 5*deltaMove; break;
03528 case 'K' : same = 0; o->tY += 5*deltaMove; break;
03529 case 'H' : same = 0; o->tX += 5*deltaMove; break;
03530 case 'I' : same = 0; o->tZ += 5*deltaMove; break;
03531 case 'U' : same = 0; o->tZ -= 5*deltaMove; break;
03532 case '1' : same = 0; o->dX += 0.02; break;
03533 case '2' : same = 0; o->dX = 0.0 ; break;
03534 case '3' : same = 0; o->dX -= 0.02; break;
03535 case '4' : same = 0; o->dY -= 0.02; break;
03536 case '5' : same = 0; o->dY = 0.0 ; break;
03537 case '6' : same = 0; o->dY += 0.02; break;
03538 case '7' : same = 0; o->dZ += 0.02; break;
03539 case '8' : same = 0; o->dZ = 0.0 ; break;
03540 case '9' : same = 0; o->dZ -= 0.02; break;
03541 case 'x' : same = 0; X -= 0.03; break;
03542 case 'X' : same = 0; X += 0.03; break;
03543 case 'y' : same = 0; Y += 0.03; break;
03544 case 'Y' : same = 0; Y -= 0.03; break;
03545 case 'z' : same = 0; Z -= 0.03; break;
03546 case 'Z' : same = 0; Z += 0.03; break;
03547 case 'a' : same = 0; X -= 0.05; break;
03548 case 'A' : same = 0; X += 0.05; break;
03549 case 'b' : same = 0; Y += 0.05; break;
03550 case 'B' : same = 0; Y -= 0.05; break;
03551 case 'c' : same = 0; Z -= 0.05; break;
03552 case 'C' : same = 0; Z += 0.05; break;
03553 case '[' : same = 0;
03554 o->focus += 0.1;
03555 if((o->focus > 1.8))
03556 o->focus = 1.8;
03557 break;
03558 case ']' : same = 0;
03559 o->focus -= 0.1;
03560 if((o->focus < -0.8))
03561 o->focus = -0.8;
03562 break;
03563 case '{' : same = 0; o->BViewpointX -= 4.0; break;
03564 case '}' : same = 0; o->BViewpointX += 4.0; break;
03565
03566 case 'q' :
03567 case 'Q' : return(1);
03568
03569 default : {
03570
03571
03572
03573
03574
03575 dx = pointerX - g->oldPointerX;
03576 dy = pointerY - g->oldPointerY;
03577
03578 if((dy * dy <= SMALLMOVEMENT) &&
03579 (dx * dx <= SMALLMOVEMENT)){
03580
03581
03582
03583
03584 X -= (dy * POINTERRATIO);
03585 Z -= (dx * POINTERRATIO);
03586 same = 0;
03587 }
03588 g->oldPointerY = pointerY;
03589 g->oldPointerX = pointerX;
03590 }
03591 }
03592
03593
03594
03595
03596 X = fmod(X + o->dX, TWOPI);
03597 Y = fmod(Y + o->dY, TWOPI);
03598 Z = fmod(Z + o->dZ, TWOPI);
03599
03600
03601
03602 if(g->Relative){
03603 o->X = fmod(X + o->X, TWOPI);
03604 o->Y = fmod(Y + o->Y, TWOPI);
03605 o->Z = fmod(Z + o->Z, TWOPI);
03606 }else{
03607 CalculateAngles(&(o->X), &(o->Y), &(o->Z), X, Y, Z);
03608 }
03609
03610 x3d_update();
03611
03612 return quitApplication;
03613 }
03614
03615 #endif