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 }