00001
00002 #include "revolt.h"
00003 #include "camera.h"
00004 #ifdef _PC
00005 #include "input.h"
00006 #endif
00007 #include "main.h"
00008 #include "geom.h"
00009 #ifdef _PC
00010 #include "text.h"
00011 #include "dx.h"
00012 #include "draw.h"
00013 #include "instance.h"
00014 #endif
00015 #include "level.h"
00016 #include "visibox.h"
00017 #include "editai.h"
00018
00019
00020
00021 VISIMASK CamVisiMask;
00022 long CubeVisiBoxCount;
00023 PERM_VISIBOX CubeVisiBox[VISIBOX_MAX];
00024 VISIBOX *CurrentVisiBox;
00025 long VisiPerPoly = TRUE;
00026
00027 static PERM_VISIBOX CamVisiBox[VISIBOX_MAX];
00028 static PERM_VISIBOX_HEADER CubeVisiBoxHeader[VISIBOX_MAX_ID];
00029 static PERM_VISIBOX *TestVisiBox[VISIBOX_MAX];
00030 static VISIBOX VisiBox[VISIBOX_MAX];
00031 static char BigID = TRUE;
00032 static char LastVisiID = 0;
00033 static char CurrentVisiSide = 0;
00034 static char ForceID = 0;
00035 static char VisiAxis = 0;
00036 static char VisiAxisType = 0;
00037 static long VisiboxSemi = 0x40000000;
00038 static long CamVisiBoxCount, TestVisiBoxCount;
00039
00040 #ifdef _PC
00041
00042
00043 static char *VisiBoxNames[] = {
00044 "Camera",
00045 "Cubes",
00046 };
00047
00048 static char *VisiAxisNames[] = {
00049 "X Y",
00050 "X Z",
00051 "Z Y",
00052 "X",
00053 "Y",
00054 "Z",
00055 };
00056
00057 static char *VisiAxisTypeNames[] = {
00058 "Camera",
00059 "World",
00060 };
00061 #endif
00062
00064
00066
00067 void InitVisiBoxes(void)
00068 {
00069 short i;
00070
00071 for (i = 0 ; i < VISIBOX_MAX ; i++) VisiBox[i].Flag = 0;
00072 }
00073
00075
00077
00078 VISIBOX *AllocVisiBox(void)
00079 {
00080 short i;
00081
00082
00083
00084 for (i = 0 ; i < VISIBOX_MAX ; i++) if (!VisiBox[i].Flag)
00085 {
00086 return &VisiBox[i];
00087 }
00088
00089
00090
00091 return NULL;
00092 }
00093
00095
00097
00098 void FreeVisiBox(VISIBOX *visibox)
00099 {
00100 visibox->Flag = 0;
00101 }
00102
00104
00106
00107 #ifdef _PC
00108 void LoadVisiBoxes(char *file)
00109 {
00110 long i;
00111 FILE *fp;
00112 VISIBOX *vb, fvb;
00113
00114
00115
00116 fp = fopen(file, "rb");
00117
00118
00119
00120 if (!fp)
00121 {
00122 fp = fopen(file, "wb");
00123 if (!fp) return;
00124 i = 0;
00125 fwrite(&i, sizeof(i), 1, fp);
00126 fclose(fp);
00127 fp = fopen(file, "rb");
00128 if (!fp) return;
00129 }
00130
00131
00132
00133 fread(&i, sizeof(i), 1, fp);
00134
00135 for ( ; i ; i--)
00136 {
00137
00138
00139
00140 vb = AllocVisiBox();
00141 if (!vb) break;
00142
00143
00144
00145 fread(&fvb, sizeof(fvb), 1, fp);
00146
00147 if (EditMode == EDIT_VISIBOXES)
00148 {
00149 fvb.xmin *= EditScale;
00150 fvb.xmax *= EditScale;
00151 fvb.ymin *= EditScale;
00152 fvb.ymax *= EditScale;
00153 fvb.zmin *= EditScale;
00154 fvb.zmax *= EditScale;
00155 }
00156
00157 vb->Flag = fvb.Flag;
00158 vb->ID = fvb.ID;
00159
00160 vb->xmin = fvb.xmin;
00161 vb->xmax = fvb.xmax;
00162 vb->ymin = fvb.ymin;
00163 vb->ymax = fvb.ymax;
00164 vb->zmin = fvb.zmin;
00165 vb->zmax = fvb.zmax;
00166 }
00167
00168
00169
00170 fclose(fp);
00171 }
00172 #else
00173 #ifdef _N64
00174 void LoadVisiBoxes(FIL_ID file)
00175 {
00176 long ii;
00177 FIL *fp;
00178 VISIBOX *vb, fvb;
00179
00180
00181
00182 fp = FFS_Open(file);
00183
00184
00185
00186 if (!fp)
00187 {
00188 return;
00189 }
00190
00191
00192
00193 FFS_Read(&ii, sizeof(ii), fp);
00194
00195 for ( ; ii ; ii--)
00196 {
00197
00198
00199
00200 vb = AllocVisiBox();
00201 if (!vb) break;
00202
00203
00204
00205 FFS_Read(&fvb, sizeof(fvb), fp);
00206
00207 vb->Flag = fvb.Flag;
00208 vb->ID = fvb.ID;
00209
00210 vb->xmin = fvb.xmin;
00211 vb->xmax = fvb.xmax;
00212 vb->ymin = fvb.ymin;
00213 vb->ymax = fvb.ymax;
00214 vb->zmin = fvb.zmin;
00215 vb->zmax = fvb.zmax;
00216 }
00217
00218
00219
00220 FFS_Close(fp);
00221 }
00222 #endif
00223 #endif
00224
00225 #ifdef _PC
00227 // save visiboxes //
00229
00230 void SaveVisiBoxes(char *file)
00231 {
00232 long num, i;
00233 FILE *fp;
00234 VISIBOX *vb, fvb;
00235 char bak[256];
00236
00237
00238
00239 memcpy(bak, file, strlen(file) - 3);
00240 wsprintf(bak + strlen(file) - 3, "vi-");
00241 remove(bak);
00242 rename(file, bak);
00243
00244
00245
00246 fp = fopen(file, "wb");
00247 if (!fp) return;
00248
00249
00250
00251 for (i = num = 0 ; i < VISIBOX_MAX ; i++) if (VisiBox[i].Flag) num++;
00252
00253
00254
00255 fwrite(&num, sizeof(num), 1, fp);
00256
00257
00258
00259 vb = VisiBox;
00260 for (i = 0 ; i < VISIBOX_MAX ; i++, vb++) if (vb->Flag)
00261 {
00262 fvb.Flag = vb->Flag;
00263 fvb.ID = vb->ID;
00264
00265 fvb.xmin = vb->xmin;
00266 fvb.xmax = vb->xmax;
00267 fvb.ymin = vb->ymin;
00268 fvb.ymax = vb->ymax;
00269 fvb.zmin = vb->zmin;
00270 fvb.zmax = vb->zmax;
00271
00272 fwrite(&fvb, sizeof(fvb), 1, fp);
00273 }
00274
00275
00276
00277 Box("Saved Visibox File:", file, MB_OK);
00278 fclose(fp);
00279 }
00280
00282
00284
00285 void EditVisiBoxes(void)
00286 {
00287 short i, n;
00288 VEC vec, vec2;
00289 float z, sx, sy, xrad, yrad, add;
00290 VISIBOX *vb;
00291 MAT mat, mat2;
00292 FILE *fp;
00293
00294
00295
00296 if (Keys[DIK_1] && !LastKeys[DIK_1]) BigID = !BigID;
00297
00298
00299
00300 if (Keys[DIK_2] && !LastKeys[DIK_2]) ForceID = !ForceID;
00301
00302
00303
00304 if (CAM_MainCamera->Type != CAM_EDIT)
00305 {
00306 CurrentVisiBox = NULL;
00307 return;
00308 }
00309
00310
00311
00312 if (MouseRight)
00313 {
00314 RotMatrixZYX(&mat, (float)-Mouse.lY / 3072, -(float)Mouse.lX / 3072, 0);
00315 MulMatrix(&CAM_MainCamera->WMatrix, &mat, &mat2);
00316 CopyMatrix(&mat2, &CAM_MainCamera->WMatrix);
00317
00318 CAM_MainCamera->WMatrix.m[RY] = 0;
00319 NormalizeVector(&CAM_MainCamera->WMatrix.mv[X]);
00320 CrossProduct(&CAM_MainCamera->WMatrix.mv[Z], &CAM_MainCamera->WMatrix.mv[X], &CAM_MainCamera->WMatrix.mv[Y]);
00321 NormalizeVector(&CAM_MainCamera->WMatrix.mv[Y]);
00322 CrossProduct(&CAM_MainCamera->WMatrix.mv[X], &CAM_MainCamera->WMatrix.mv[Y], &CAM_MainCamera->WMatrix.mv[Z]);
00323 }
00324
00325
00326
00327 if (Keys[DIK_LCONTROL] && Keys[DIK_F4] && !LastKeys[DIK_F4])
00328 {
00329 SaveVisiBoxes(GetLevelFilename("vis", FILENAME_MAKE_BODY | FILENAME_GAME_SETTINGS));
00330 if ((fp = fopen(GetLevelFilename("cam", FILENAME_MAKE_BODY), "rb")) != NULL)
00331 {
00332 CAM_NCameraNodes = LoadCameraNodes(fp);
00333 fclose(fp);
00334 }
00335 }
00336
00337
00338
00339 if (!CurrentVisiBox && Keys[DIK_RETURN] && !LastKeys[DIK_RETURN])
00340 {
00341 n = -1;
00342 z = RenderSettings.FarClip;
00343
00344 for (i = 0 ; i < VISIBOX_MAX ; i++) if (VisiBox[i].Flag)
00345 {
00346 vec2.v[X] = (VisiBox[i].xmin + VisiBox[i].xmax) / 2;
00347 vec2.v[Y] = (VisiBox[i].ymin + VisiBox[i].ymax) / 2;
00348 vec2.v[Z] = (VisiBox[i].zmin + VisiBox[i].zmax) / 2;
00349
00350 RotTransVector(&ViewMatrix, &ViewTrans, &vec2, &vec);
00351
00352 if (vec.v[Z] < RenderSettings.NearClip || vec.v[Z] >= RenderSettings.FarClip) continue;
00353
00354 sx = vec.v[X] * RenderSettings.GeomPers / vec.v[Z] + REAL_SCREEN_XHALF;
00355 sy = vec.v[Y] * RenderSettings.GeomPers / vec.v[Z] + REAL_SCREEN_YHALF;
00356
00357 xrad = (32 * RenderSettings.GeomPers) / vec.v[Z];
00358 yrad = (32 * RenderSettings.GeomPers) / vec.v[Z];
00359
00360 if (MouseXpos > sx - xrad && MouseXpos < sx + xrad && MouseYpos > sy - yrad && MouseYpos < sy + yrad)
00361 {
00362 if (vec.v[Z] < z)
00363 {
00364 n = i;
00365 z = vec.v[Z];
00366 }
00367 }
00368 }
00369 if (n != -1)
00370 {
00371 CurrentVisiBox = &VisiBox[n];
00372 return;
00373 }
00374 }
00375
00376
00377
00378 if (Keys[DIK_INSERT] && !LastKeys[DIK_INSERT])
00379 {
00380 if ((vb = AllocVisiBox()))
00381 {
00382 vec.v[X] = 0;
00383 vec.v[Y] = 0;
00384 vec.v[Z] = 256;
00385 RotVector(&CAM_MainCamera->WMatrix, &vec, &vec2);
00386 AddVector(&vec2, &CAM_MainCamera->WPos, &vec);
00387
00388 vb->xmin = vec.v[X] - 64;
00389 vb->xmax = vec.v[X] + 64;
00390 vb->ymin = vec.v[Y] - 64;
00391 vb->ymax = vec.v[Y] + 64;
00392 vb->zmin = vec.v[Z] - 64;
00393 vb->zmax = vec.v[Z] + 64;
00394
00395 vb->Flag = VISIBOX_CAMERA;
00396 vb->ID = LastVisiID;
00397
00398 CurrentVisiBox = vb;
00399 }
00400 }
00401
00402
00403
00404 if (!CurrentVisiBox) return;
00405
00406
00407
00408 if (!(FrameCount & 15))
00409 {
00410 SetPermVisiBoxes();
00411
00412 for (i = 0 ; i < InstanceNum ; i++)
00413 Instances[i].VisiMask = SetObjectVisiMask(&Instances[i].Box);
00414 }
00415
00416
00417
00418 LastVisiID = CurrentVisiBox->ID;
00419
00420
00421
00422 if (Keys[DIK_RETURN] && !LastKeys[DIK_RETURN])
00423 {
00424 CurrentVisiBox = NULL;
00425 return;
00426 }
00427
00428
00429
00430 if (Keys[DIK_DELETE] && !LastKeys[DIK_DELETE])
00431 {
00432 FreeVisiBox(CurrentVisiBox);
00433 CurrentVisiBox = NULL;
00434 return;
00435 }
00436
00437
00438
00439 if (Keys[DIK_NUMPADENTER] && !LastKeys[DIK_NUMPADENTER])
00440 {
00441 CurrentVisiBox->Flag ^= 3;
00442 }
00443
00444
00445
00446 if (Keys[DIK_NUMPADMINUS] && !LastKeys[DIK_NUMPADMINUS])
00447 CurrentVisiBox->ID--;
00448 if (Keys[DIK_NUMPADPLUS] && !LastKeys[DIK_NUMPADPLUS])
00449 CurrentVisiBox->ID++;
00450
00451 CurrentVisiBox->ID &= 63;
00452
00453
00454
00455 if (Keys[DIK_SPACE] && !LastKeys[DIK_SPACE])
00456 CurrentVisiSide = (CurrentVisiSide + 1) % 6;
00457
00458
00459
00460 if (Keys[DIK_TAB] && !LastKeys[DIK_TAB])
00461 {
00462 if (Keys[DIK_LSHIFT]) VisiAxis--;
00463 else VisiAxis++;
00464 if (VisiAxis == -1) VisiAxis = 5;
00465 if (VisiAxis == 6) VisiAxis = 0;
00466 }
00467
00468
00469
00470 if (Keys[DIK_LALT] && !LastKeys[DIK_LALT])
00471 VisiAxisType ^= 1;
00472
00473
00474
00475 if (Keys[DIK_EQUALS] && VisiboxSemi < 0xff000000) VisiboxSemi += 0x01000000;
00476 if (Keys[DIK_MINUS] && VisiboxSemi) VisiboxSemi -= 0x01000000;
00477
00478
00479
00480 if (MouseLeft)
00481 {
00482 vec2.v[X] = (CurrentVisiBox->xmin + CurrentVisiBox->xmax) / 2;
00483 vec2.v[Y] = (CurrentVisiBox->ymin + CurrentVisiBox->ymax) / 2;
00484 vec2.v[Z] = (CurrentVisiBox->zmin + CurrentVisiBox->zmax) / 2;
00485 RotTransVector(&ViewMatrix, &ViewTrans, &vec2, &vec);
00486
00487 switch (VisiAxis)
00488 {
00489 case VISI_AXIS_XY:
00490 vec.v[X] = MouseXrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditXrel;
00491 vec.v[Y] = MouseYrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditYrel;
00492 vec.v[Z] = CameraEditZrel;
00493 break;
00494 case VISI_AXIS_XZ:
00495 vec.v[X] = MouseXrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditXrel;
00496 vec.v[Y] = CameraEditYrel;
00497 vec.v[Z] = -MouseYrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditZrel;
00498 break;
00499 case VISI_AXIS_ZY:
00500 vec.v[X] = CameraEditXrel;
00501 vec.v[Y] = MouseYrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditYrel;
00502 vec.v[Z] = MouseXrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditZrel;
00503 break;
00504 case VISI_AXIS_X:
00505 vec.v[X] = MouseXrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditXrel;
00506 vec.v[Y] = CameraEditYrel;
00507 vec.v[Z] = CameraEditZrel;
00508 break;
00509 case VISI_AXIS_Y:
00510 vec.v[X] = CameraEditXrel;
00511 vec.v[Y] = MouseYrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditYrel;
00512 vec.v[Z] = CameraEditZrel;
00513 break;
00514 case VISI_AXIS_Z:
00515 vec.v[X] = CameraEditXrel;
00516 vec.v[Y] = CameraEditYrel;
00517 vec.v[Z] = -MouseYrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditZrel;
00518 break;
00519 }
00520
00521 if (VisiAxisType == 1)
00522 {
00523 SetVector(&vec2, vec.v[X], vec.v[Y], vec.v[Z]);
00524 }
00525 else
00526 {
00527 RotVector(&CAM_MainCamera->WMatrix, &vec, &vec2);
00528 }
00529
00530 CurrentVisiBox->xmin += vec2.v[X];
00531 CurrentVisiBox->xmax += vec2.v[X];
00532 CurrentVisiBox->ymin += vec2.v[Y];
00533 CurrentVisiBox->ymax += vec2.v[Y];
00534 CurrentVisiBox->zmin += vec2.v[Z];
00535 CurrentVisiBox->zmax += vec2.v[Z];
00536 }
00537
00538
00539
00540 add = 0;
00541 if (Keys[DIK_NUMPADSTAR])
00542 add = 8 * TimeFactor;
00543 if (Keys[DIK_NUMPADSLASH])
00544 add = -8 * TimeFactor;
00545
00546 if (Keys[DIK_LCONTROL]) add *= 4;
00547
00548 if (add)
00549 {
00550 if (Keys[DIK_LSHIFT])
00551 {
00552 if (CurrentVisiBox->xmin - add < CurrentVisiBox->xmax)
00553 {
00554 CurrentVisiBox->xmin -= add;
00555 CurrentVisiBox->xmax += add;
00556 }
00557
00558 if (CurrentVisiBox->ymin - add < CurrentVisiBox->ymax)
00559 {
00560 CurrentVisiBox->ymin -= add;
00561 CurrentVisiBox->ymax += add;
00562 }
00563
00564 if (CurrentVisiBox->zmin - add < CurrentVisiBox->zmax)
00565 {
00566 CurrentVisiBox->zmin -= add;
00567 CurrentVisiBox->zmax += add;
00568 }
00569 }
00570 else
00571 {
00572 switch (CurrentVisiSide)
00573 {
00574 case 0:
00575 CurrentVisiBox->xmin += add;
00576 if (CurrentVisiBox->xmin >= CurrentVisiBox->xmax)
00577 CurrentVisiBox->xmin = CurrentVisiBox->xmax - 8;
00578 break;
00579 case 1:
00580 CurrentVisiBox->xmax += add;
00581 if (CurrentVisiBox->xmax <= CurrentVisiBox->xmin)
00582 CurrentVisiBox->xmax = CurrentVisiBox->xmin + 8;
00583 break;
00584 case 2:
00585 CurrentVisiBox->ymin += add;
00586 if (CurrentVisiBox->ymin >= CurrentVisiBox->ymax)
00587 CurrentVisiBox->ymin = CurrentVisiBox->ymax - 8;
00588 break;
00589 case 3:
00590 CurrentVisiBox->ymax += add;
00591 if (CurrentVisiBox->ymax <= CurrentVisiBox->ymin)
00592 CurrentVisiBox->ymax = CurrentVisiBox->ymin + 8;
00593 break;
00594 case 4:
00595 CurrentVisiBox->zmin += add;
00596 if (CurrentVisiBox->zmin >= CurrentVisiBox->zmax)
00597 CurrentVisiBox->zmin = CurrentVisiBox->zmax - 8;
00598 break;
00599 case 5:
00600 CurrentVisiBox->zmax += add;
00601 if (CurrentVisiBox->zmax <= CurrentVisiBox->zmin)
00602 CurrentVisiBox->zmax = CurrentVisiBox->zmin + 8;
00603 break;
00604 }
00605 }
00606 }
00607 }
00608
00610
00612
00613 void DisplayVisiBoxInfo(VISIBOX *visibox)
00614 {
00615 char buf[128];
00616
00617
00618
00619 DumpText(450, 0, 8, 16, 0xffff00, VisiBoxNames[visibox->Flag - 1]);
00620
00621
00622
00623 wsprintf(buf, "ID %d", (short)visibox->ID);
00624 DumpText(450, 24, 8, 16, 0x00ff00, buf);
00625
00626
00627
00628 wsprintf(buf, "Axis %s - %s", VisiAxisNames[VisiAxis], VisiAxisTypeNames[VisiAxisType]);
00629 DumpText(450, 48, 8, 16, 0xff00ff, buf);
00630 }
00631
00633
00635
00636 void DisplayCamVisiMask(void)
00637 {
00638 unsigned long i;
00639 VISIMASK mask;
00640 short y;
00641 char buf[128];
00642
00643
00644
00645 if (BigID)
00646 DumpText(0, 32, 8, 16, 0xff00ff, "Big Brothers");
00647
00648
00649
00650 if (ForceID)
00651 DumpText(0, 48, 8, 16, 0xff00ff, "Locked Camera");
00652
00653
00654
00655 mask = CamVisiMask;
00656 y = 64;
00657
00658 for (i = 0 ; i < VISIBOX_MAX_ID ; i++, mask >>= 1) if (mask & 1)
00659 {
00660 wsprintf(buf, "%d", i);
00661 DumpText(0, y, 8, 16, 0xffffff, buf);
00662 y += 16;
00663 }
00664 }
00665
00667
00669
00670 void DrawVisiBoxes(void)
00671 {
00672 long i, j;
00673 VISIBOX *vb;
00674 float xmin, xmax, ymin, ymax, zmin, zmax, size;
00675 VEC vec, vec2;
00676 long col[6];
00677 char buf[128];
00678
00679
00680
00681 for (i = 0 ; i < CAM_NCameraNodes ; i++)
00682 {
00683 DrawModel(&EditAiNodeModel[0], &IdentityMatrix, &CAM_CameraNode[i].Pos, MODEL_PLAIN);
00684 }
00685
00686
00687
00688 ALPHA_SRC(D3DBLEND_SRCALPHA);
00689 ALPHA_DEST(D3DBLEND_INVSRCALPHA);
00690 WIREFRAME_OFF();
00691 ZWRITE_ON();
00692
00693
00694
00695 vb = VisiBox;
00696 for (i = 0 ; i < VISIBOX_MAX ; i++, vb++) if (vb->Flag)
00697 {
00698
00699
00700
00701 if (vb == CurrentVisiBox || (CurrentVisiBox && vb->ID == CurrentVisiBox->ID && BigID))
00702 {
00703 xmin = vb->xmin;
00704 xmax = vb->xmax;
00705 ymin = vb->ymin;
00706 ymax = vb->ymax;
00707 zmin = vb->zmin;
00708 zmax = vb->zmax;
00709
00710 col[2] = 0xff0000 | VisiboxSemi;
00711 col[1] = 0x00ff00 | VisiboxSemi;
00712 col[0] = 0x0000ff | VisiboxSemi;
00713 col[4] = 0xffff00 | VisiboxSemi;
00714 col[3] = 0x00ffff | VisiboxSemi;
00715 col[5] = 0xff00ff | VisiboxSemi;
00716
00717 if (vb == CurrentVisiBox)
00718 col[CurrentVisiSide] = rand() | VisiboxSemi;
00719
00720 ZBUFFER_ON();
00721 ALPHA_ON();
00722 DrawBoundingBox(xmin, xmax, ymin, ymax, zmin, zmax, col[0], col[1], col[2], col[3], col[4], col[5]);
00723 }
00724
00725
00726
00727 else
00728 {
00729 vec.v[X] = (vb->xmin + vb->xmax) / 2;
00730 vec.v[Y] = (vb->ymin + vb->ymax) / 2;
00731 vec.v[Z] = (vb->zmin + vb->zmax) / 2;
00732
00733 xmin = vec.v[X] - 32;
00734 xmax = vec.v[X] + 32;
00735 ymin = vec.v[Y] - 32;
00736 ymax = vec.v[Y] + 32;
00737 zmin = vec.v[Z] - 32;
00738 zmax = vec.v[Z] + 32;
00739
00740 for (j = 0 ; j < 6 ; j++)
00741 col[j] = 0xff0000 | VisiboxSemi;
00742
00743 ZBUFFER_OFF();
00744 ALPHA_ON();
00745 DrawBoundingBox(xmin, xmax, ymin, ymax, zmin, zmax, col[0], col[1], col[2], col[3], col[4], col[5]);
00746 }
00747
00748
00749
00750 if (vb != CurrentVisiBox)
00751 {
00752 ZBUFFER_OFF();
00753 ALPHA_OFF();
00754
00755 if (CurrentVisiBox && vb->ID == CurrentVisiBox->ID)
00756 size = 128;
00757 else
00758 size = 32;
00759
00760 vec.v[X] = (vb->xmin + vb->xmax) / 2;
00761 vec.v[Y] = (vb->ymin + vb->ymax) / 2;
00762 vec.v[Z] = (vb->zmin + vb->zmax) / 2;
00763
00764 wsprintf(buf, "%s %d", VisiBoxNames[vb->Flag - 1], vb->ID);
00765 RotTransVector(&ViewMatrix, &ViewTrans, &vec, &vec2);
00766 vec2.v[X] -= size * 4;
00767 vec2.v[Y] -= size;
00768
00769 if (vec2.v[Z] > RenderSettings.NearClip)
00770 DumpText3D(&vec2, size, size * 2, 0xffffff, buf);
00771 }
00772 }
00773
00774
00775
00776 if (CurrentVisiBox)
00777 {
00778 ZBUFFER_OFF();
00779 ALPHA_OFF();
00780
00781 vec.v[X] = (CurrentVisiBox->xmin + CurrentVisiBox->xmax) / 2;
00782 vec.v[Y] = (CurrentVisiBox->ymin + CurrentVisiBox->ymax) / 2;
00783 vec.v[Z] = (CurrentVisiBox->zmin + CurrentVisiBox->zmax) / 2;
00784
00785 if (VisiAxisType)
00786 DrawAxis(&IdentityMatrix, &vec);
00787 else
00788 DrawAxis(&CAM_MainCamera->WMatrix, &vec);
00789 }
00790
00791
00792
00793 WIREFRAME_ON();
00794 ZBUFFER_ON();
00795 ALPHA_OFF();
00796 }
00797 #endif
00798
00800
00802
00803 void SetPermVisiBoxes(void)
00804 {
00805 long i, j, k, l;
00806 float xmin, xmax, ymin, ymax, zmin, zmax;
00807 VISIBOX *vb;
00808 PERM_VISIBOX *camvb, *cubevb, swap;
00809 CUBE_HEADER *cube;
00810 #ifdef _PC
00811 WORLD_POLY *poly;
00812 WORLD_VERTEX **vert;
00813 #endif
00814
00815
00816 vb = VisiBox;
00817 CamVisiBoxCount = 0;
00818 CubeVisiBoxCount = 0;
00819 camvb = CamVisiBox;
00820 cubevb = CubeVisiBox;
00821
00822 for (i = 0 ; i < VISIBOX_MAX ; i++, vb++)
00823 {
00824 if (vb->Flag & VISIBOX_CAMERA)
00825 {
00826 camvb->ID = vb->ID;
00827 camvb->Mask = (VISIMASK)1 << camvb->ID;
00828 camvb->xmin = vb->xmin;
00829 camvb->xmax = vb->xmax;
00830 camvb->ymin = vb->ymin;
00831 camvb->ymax = vb->ymax;
00832 camvb->zmin = vb->zmin;
00833 camvb->zmax = vb->zmax;
00834
00835 CamVisiBoxCount++;
00836 camvb++;
00837 }
00838 if (vb->Flag & VISIBOX_CUBE)
00839 {
00840 cubevb->ID = vb->ID;
00841 cubevb->Mask = (VISIMASK)1 << cubevb->ID;
00842 cubevb->xmin = vb->xmin;
00843 cubevb->xmax = vb->xmax;
00844 cubevb->ymin = vb->ymin;
00845 cubevb->ymax = vb->ymax;
00846 cubevb->zmin = vb->zmin;
00847 cubevb->zmax = vb->zmax;
00848
00849 CubeVisiBoxCount++;
00850 cubevb++;
00851 }
00852 }
00853
00854
00855
00856 if (CubeVisiBoxCount > 1)
00857 {
00858 for (i = CubeVisiBoxCount - 1 ; i ; i--) for (j = 0 ; j < i ; j++)
00859 {
00860 if (CubeVisiBox[j].Mask > CubeVisiBox[j + 1].Mask)
00861 {
00862 swap = CubeVisiBox[j];
00863 CubeVisiBox[j] = CubeVisiBox[j + 1];
00864 CubeVisiBox[j + 1] = swap;
00865 }
00866 }
00867 }
00868
00869
00870
00871 for (i = 0 ; i < VISIBOX_MAX_ID ; i++)
00872 {
00873 CubeVisiBoxHeader[i].Count = 0;
00874 for (j = 0 ; j < CubeVisiBoxCount ; j++)
00875 {
00876 if (CubeVisiBox[j].Mask == ((VISIMASK)1 << i))
00877 {
00878 CubeVisiBoxHeader[i].VisiBoxes = &CubeVisiBox[j];
00879 while (j < CubeVisiBoxCount && CubeVisiBox[j].Mask == ((VISIMASK)1 << i))
00880 {
00881 j++;
00882 CubeVisiBoxHeader[i].Count++;
00883 }
00884 break;
00885 }
00886 }
00887 }
00888
00889
00890
00891 #ifndef _N64
00892 cube = World.Cube;
00893 for (i = 0 ; i < World.CubeNum ; i++, cube++)
00894 #else
00895 cube = World->Cube;
00896 for (i = 0 ; i < World->CubeNum ; i++, cube++)
00897 #endif
00898 {
00899
00900
00901
00902 cube->VisiMask = 0;
00903
00904 #ifdef _PC
00905 poly = cube->Model.PolyPtr;
00906 for (j = 0 ; j < cube->Model.PolyNum ; j++, poly++) poly->VisiMask = 0;
00907 #endif
00908
00909
00910 cubevb = CubeVisiBox;
00911 for (j = 0 ; j < CubeVisiBoxCount ; j++, cubevb++)
00912 {
00913
00914
00915
00916 if (cube->Xmin >= cubevb->xmin && cube->Xmax <= cubevb->xmax &&
00917 cube->Ymin >= cubevb->ymin && cube->Ymax <= cubevb->ymax &&
00918 cube->Zmin >= cubevb->zmin && cube->Zmax <= cubevb->zmax)
00919 {
00920 cube->VisiMask |= cubevb->Mask;
00921 }
00922
00923 #ifdef _PC
00924
00925
00926 else if (VisiPerPoly && cube->Xmax >= cubevb->xmin && cube->Xmin <= cubevb->xmax &&
00927 cube->Ymax >= cubevb->ymin && cube->Ymin <= cubevb->ymax &&
00928 cube->Zmax >= cubevb->zmin && cube->Zmin <= cubevb->zmax)
00929 {
00930 poly = cube->Model.PolyPtr;
00931 for (k = 0 ; k < cube->Model.PolyNum ; k++, poly++)
00932 {
00933 xmin = ymin = zmin = 999999;
00934 xmax = ymax = zmax = -999999;
00935 vert = &poly->v0;
00936
00937 for (l = 0 ; l < 3 + (poly->Type & 1) ; l++, vert++)
00938 {
00939 if ((*vert)->x < xmin) xmin = (*vert)->x;
00940 if ((*vert)->x > xmax) xmax = (*vert)->x;
00941 if ((*vert)->y < ymin) ymin = (*vert)->y;
00942 if ((*vert)->y > ymax) ymax = (*vert)->y;
00943 if ((*vert)->z < zmin) zmin = (*vert)->z;
00944 if ((*vert)->z > zmax) zmax = (*vert)->z;
00945 }
00946
00947 if (xmin >= cubevb->xmin && xmax <= cubevb->xmax &&
00948 ymin >= cubevb->ymin && ymax <= cubevb->ymax &&
00949 zmin >= cubevb->zmin && zmax <= cubevb->zmax)
00950 {
00951 poly->VisiMask |= cubevb->Mask;
00952 }
00953 }
00954 }
00955 #endif
00956 }
00957 }
00958 }
00959
00961
00963
00964 VISIMASK SetObjectVisiMask(BOUNDING_BOX *box)
00965 {
00966 long i;
00967 VISIMASK mask = 0;
00968
00969 for (i = 0 ; i < CubeVisiBoxCount ; i++)
00970 {
00971 if (box->Xmin < CubeVisiBox[i].xmin || box->Xmax > CubeVisiBox[i].xmax ||
00972 box->Ymin < CubeVisiBox[i].ymin || box->Ymax > CubeVisiBox[i].ymax ||
00973 box->Zmin < CubeVisiBox[i].zmin || box->Zmax > CubeVisiBox[i].zmax)
00974 continue;
00975
00976 mask |= CubeVisiBox[i].Mask;
00977 }
00978 return mask;
00979 }
00980
00982
00984
00985 char TestObjectVisiboxes(BOUNDING_BOX *box)
00986 {
00987 long i;
00988
00989
00990
00991 for (i = 0 ; i < TestVisiBoxCount ; i++)
00992 {
00993 if (box->Xmin >= TestVisiBox[i]->xmin && box->Xmax <= TestVisiBox[i]->xmax &&
00994 box->Ymin >= TestVisiBox[i]->ymin && box->Ymax <= TestVisiBox[i]->ymax &&
00995 box->Zmin >= TestVisiBox[i]->zmin && box->Zmax <= TestVisiBox[i]->zmax)
00996 return TRUE;
00997 }
00998
00999
01000
01001 return FALSE;
01002 }
01003
01005
01007
01008 void SetCameraVisiMask(VEC *pos)
01009 {
01010 long i, j;
01011 PERM_VISIBOX *cvb;
01012
01013
01014
01015 if (ForceID) return;
01016
01017
01018
01019 TestVisiBoxCount = 0;
01020 CamVisiMask = 0;
01021 cvb = CamVisiBox;
01022
01023 for (i = 0 ; i < CamVisiBoxCount ; i++, cvb++)
01024 {
01025
01026
01027
01028 if (pos->v[X] < cvb->xmin || pos->v[X] > cvb->xmax ||
01029 pos->v[Y] < cvb->ymin || pos->v[Y] > cvb->ymax ||
01030 pos->v[Z] < cvb->zmin || pos->v[Z] > cvb->zmax)
01031 continue;
01032
01033
01034
01035 CamVisiMask |= cvb->Mask;
01036
01037
01038
01039 for (j = 0 ; j < CubeVisiBoxHeader[cvb->ID].Count ; j++)
01040 {
01041 TestVisiBox[TestVisiBoxCount] = &CubeVisiBoxHeader[cvb->ID].VisiBoxes[j];
01042 TestVisiBoxCount++;
01043 }
01044 }
01045 }