00001
00002 #include "revolt.h"
00003 #include "level.h"
00004 #include "camera.h"
00005 #include "input.h"
00006 #include "geom.h"
00007 #include "text.h"
00008 #include "main.h"
00009 #include "light.h"
00010 #include "draw.h"
00011 #include "visibox.h"
00012 #include "instance.h"
00013 #include "drawobj.h"
00014 #include "newcoll.h"
00015 #include "mirror.h"
00016 #include "registry.h"
00017
00018
00019
00020 long InstanceNum;
00021 INSTANCE *CurrentInstance;
00022 INSTANCE Instances[MAX_INSTANCES];
00023 long InstanceModelNum;
00024 INSTANCE_MODELS *InstanceModels;
00025
00026 static char InstanceAxis = 0, InstanceAxisType = 0, InstanceRgbType = TRUE;
00027 static unsigned char LastModel;
00028
00029
00030
00031 static char *InstanceAxisNames[] = {
00032 "X Y",
00033 "X Z",
00034 "Z Y",
00035 "X",
00036 "Y",
00037 "Z",
00038 };
00039
00040 static char *InstanceAxisTypeNames[] = {
00041 "Camera",
00042 "World",
00043 };
00044
00046
00048
00049 void LoadInstances(char *file)
00050 {
00051 long i, j;
00052 FILE *fp;
00053 FILE_INSTANCE fin;
00054
00055
00056
00057 fp = fopen(file, "rb");
00058
00059
00060
00061 if (!fp)
00062 {
00063 fp = fopen(file, "wb");
00064 if (!fp) return;
00065 i = 0;
00066 fwrite(&i, sizeof(i), 1, fp);
00067 fclose(fp);
00068 fp = fopen(file, "rb");
00069 if (!fp) return;
00070 }
00071
00072
00073
00074 fread(&InstanceNum, sizeof(InstanceNum), 1, fp);
00075
00076 for (i = 0 ; i < InstanceNum ; i++)
00077 {
00078
00079
00080
00081 fread(&fin, sizeof(fin), 1, fp);
00082
00083 if (EditMode == EDIT_INSTANCES)
00084 {
00085 VecMulScalar(&fin.WorldPos, EditScale);
00086 }
00087
00088
00089
00090 fin.Name[MAX_INSTANCE_FILENAME - 1] = 0;
00091 for (j = 0 ; j < InstanceModelNum ; j++)
00092 {
00093 if (!strcmp(fin.Name, InstanceModels[j].Name))
00094 {
00095 Instances[i].Model = (char)j;
00096 break;
00097 }
00098 }
00099
00100
00101
00102 if (j == InstanceModelNum)
00103 {
00104 i--;
00105 InstanceNum--;
00106 continue;
00107 }
00108
00109
00110
00111 Instances[i].r = fin.r;
00112 Instances[i].g = fin.g;
00113 Instances[i].b = fin.b;
00114 Instances[i].Priority = fin.Priority;
00115 Instances[i].Flag = fin.Flag;
00116 Instances[i].EnvRGB = fin.EnvRGB;
00117 Instances[i].LodBias = fin.LodBias;
00118 Instances[i].WorldPos = fin.WorldPos;
00119 Instances[i].WorldMatrix = fin.WorldMatrix;
00120
00121
00122
00123 if (!(Instances[i].Flag & INSTANCE_SET_MODEL_RGB))
00124 {
00125 Instances[i].r = 0;
00126 Instances[i].g = 0;
00127 Instances[i].b = 0;
00128 Instances[i].Flag |= INSTANCE_SET_MODEL_RGB;
00129 }
00130
00131
00132
00133 SetInstanceBoundingBoxes(&Instances[i]);
00134 AllocOneInstanceRGB(&Instances[i]);
00135
00136
00137
00138 if ((Instances[i].MirrorFlag = GetMirrorPlane(&Instances[i].WorldPos)))
00139 Instances[i].MirrorHeight = MirrorHeight;
00140 }
00141
00142
00143
00144 fclose(fp);
00145 }
00146
00148
00150
00151 void SaveInstances(char *file)
00152 {
00153 long i;
00154 FILE *fp;
00155 FILE_INSTANCE finst;
00156 INSTANCE *inst;
00157 char bak[256];
00158
00159
00160
00161 memcpy(bak, file, strlen(file) - 3);
00162 wsprintf(bak + strlen(file) - 3, "fi-");
00163 remove(bak);
00164 rename(file, bak);
00165
00166
00167
00168 fp = fopen(file, "wb");
00169 if (!fp) return;
00170
00171
00172
00173 fwrite(&InstanceNum, sizeof(InstanceNum), 1, fp);
00174
00175
00176
00177 inst = Instances;
00178 for (i = 0 ; i < InstanceNum ; i++, inst++)
00179 {
00180
00181
00182
00183 memcpy(finst.Name, InstanceModels[inst->Model].Name, MAX_INSTANCE_FILENAME);
00184
00185 finst.r = inst->r;
00186 finst.g = inst->g;
00187 finst.b = inst->b;
00188 finst.Priority = inst->Priority;
00189 finst.Flag = inst->Flag;
00190 finst.EnvRGB = inst->EnvRGB;
00191 finst.LodBias = inst->LodBias;
00192 finst.WorldPos = inst->WorldPos;
00193 finst.WorldMatrix = inst->WorldMatrix;
00194
00195
00196
00197 fwrite(&finst, sizeof(finst), 1, fp);
00198 }
00199
00200
00201
00202 Box("Saved Instance File:", file, MB_OK);
00203 fclose(fp);
00204 }
00205
00207
00209
00210 void EditInstances(void)
00211 {
00212 long i, flag;
00213 INSTANCE *inst, *ninst;
00214 VEC vec, vec2;
00215 MAT mat, mat2;
00216 VEC r, u, l, r2, u2, l2;
00217 MODEL_RGB *rgb;
00218 float xrad, yrad, sx, sy, ndist, dist;
00219
00220
00221
00222 if (CAM_MainCamera->Type != CAM_EDIT)
00223 {
00224 CurrentInstance = NULL;
00225 return;
00226 }
00227
00228
00229
00230 if (MouseRight)
00231 {
00232 RotMatrixZYX(&mat, (float)-Mouse.lY / 3072, -(float)Mouse.lX / 3072, 0);
00233 MulMatrix(&CAM_MainCamera->WMatrix, &mat, &mat2);
00234 CopyMatrix(&mat2, &CAM_MainCamera->WMatrix);
00235
00236 CAM_MainCamera->WMatrix.m[RY] = 0;
00237 NormalizeVector(&CAM_MainCamera->WMatrix.mv[X]);
00238 CrossProduct(&CAM_MainCamera->WMatrix.mv[Z], &CAM_MainCamera->WMatrix.mv[X], &CAM_MainCamera->WMatrix.mv[Y]);
00239 NormalizeVector(&CAM_MainCamera->WMatrix.mv[Y]);
00240 CrossProduct(&CAM_MainCamera->WMatrix.mv[X], &CAM_MainCamera->WMatrix.mv[Y], &CAM_MainCamera->WMatrix.mv[Z]);
00241 }
00242
00243
00244
00245 if (Keys[DIK_LCONTROL] && Keys[DIK_F4] && !LastKeys[DIK_F4])
00246 {
00247 SaveInstances(GetLevelFilename("fin", FILENAME_MAKE_BODY | FILENAME_GAME_SETTINGS));
00248 }
00249
00250
00251
00252 if (!CurrentInstance && Keys[DIK_RETURN] && !LastKeys[DIK_RETURN])
00253 {
00254 ninst = NULL;
00255 ndist = 99999;
00256
00257 inst = Instances;
00258 for (i = 0 ; i < InstanceNum ; i++, inst++)
00259 {
00260 RotTransVector(&ViewMatrix, &ViewTrans, &inst->WorldPos, &vec);
00261
00262 if (vec.v[Z] < RenderSettings.NearClip || vec.v[Z] >= RenderSettings.FarClip) continue;
00263
00264 sx = vec.v[X] * RenderSettings.GeomPers / vec.v[Z] + REAL_SCREEN_XHALF;
00265 sy = vec.v[Y] * RenderSettings.GeomPers / vec.v[Z] + REAL_SCREEN_YHALF;
00266
00267 xrad = (InstanceModels[inst->Model].Models[0].Radius * RenderSettings.GeomPers) / vec.v[Z];
00268 yrad = (InstanceModels[inst->Model].Models[0].Radius * RenderSettings.GeomPers) / vec.v[Z];
00269
00270 if (MouseXpos > sx - xrad && MouseXpos < sx + xrad && MouseYpos > sy - yrad && MouseYpos < sy + yrad)
00271 {
00272 dist = (float)sqrt((sx - MouseXpos) * (sx - MouseXpos) + (sy - MouseYpos) * (sy - MouseYpos));
00273 if (dist < ndist)
00274 {
00275 ninst = inst;
00276 ndist = dist;
00277 }
00278 }
00279 }
00280 if (ninst)
00281 {
00282 CurrentInstance = ninst;
00283 return;
00284 }
00285 }
00286
00287
00288
00289 if (Keys[DIK_INSERT] && !LastKeys[DIK_INSERT])
00290 {
00291 if ((inst = AllocInstance()))
00292 {
00293 vec.v[X] = 0;
00294 vec.v[Y] = 0;
00295 vec.v[Z] = 256;
00296 RotVector(&CAM_MainCamera->WMatrix, &vec, &vec2);
00297 AddVector(&CAM_MainCamera->WPos, &vec2, &inst->WorldPos);
00298
00299 RotMatrixZYX(&inst->WorldMatrix, 0, 0, 0);
00300
00301 inst->r = 0;
00302 inst->g = 0;
00303 inst->b = 0;
00304 inst->EnvRGB = 0x808080;
00305 inst->Model = LastModel;
00306 inst->Priority = FALSE;
00307 inst->LodBias = 1024;
00308 inst->Flag = INSTANCE_SET_MODEL_RGB;
00309
00310 SetInstanceBoundingBoxes(inst);
00311 AllocOneInstanceRGB(inst);
00312
00313 CurrentInstance = inst;
00314 }
00315 }
00316
00317
00318
00319 if (!CurrentInstance) return;
00320
00321
00322
00323 LastModel = CurrentInstance->Model;
00324
00325
00326
00327 if ((CurrentInstance->MirrorFlag = GetMirrorPlane(&CurrentInstance->WorldPos)))
00328 CurrentInstance->MirrorHeight = MirrorHeight;
00329
00330
00331
00332 if (Keys[DIK_RETURN] && !LastKeys[DIK_RETURN])
00333 {
00334 CurrentInstance = NULL;
00335 return;
00336 }
00337
00338
00339
00340 SetInstanceBoundingBoxes(CurrentInstance);
00341
00342
00343
00344 if (Keys[DIK_DELETE] && !LastKeys[DIK_DELETE])
00345 {
00346 FreeOneInstanceRGB(CurrentInstance);
00347 FreeInstance(CurrentInstance);
00348 CurrentInstance = NULL;
00349 return;
00350 }
00351
00352
00353
00354 if (Keys[DIK_TAB] && !LastKeys[DIK_TAB])
00355 {
00356 if (Keys[DIK_LSHIFT]) InstanceAxis--;
00357 else InstanceAxis++;
00358 if (InstanceAxis == -1) InstanceAxis = 5;
00359 if (InstanceAxis == 6) InstanceAxis = 0;
00360 }
00361
00362
00363
00364 if (Keys[DIK_LALT] && !LastKeys[DIK_LALT])
00365 InstanceAxisType ^= 1;
00366
00367
00368
00369 if (Keys[DIK_LSHIFT]) LastKeys[DIK_NUMPADMINUS] = LastKeys[DIK_NUMPADPLUS] = 0;
00370
00371 if (Keys[DIK_NUMPADMINUS] && !LastKeys[DIK_NUMPADMINUS] && CurrentInstance->Model)
00372 {
00373 FreeOneInstanceRGB(CurrentInstance);
00374 CurrentInstance->Model--;
00375 AllocOneInstanceRGB(CurrentInstance);
00376 }
00377
00378 if (Keys[DIK_NUMPADPLUS] && !LastKeys[DIK_NUMPADPLUS] && CurrentInstance->Model < InstanceModelNum - 1)
00379 {
00380 FreeOneInstanceRGB(CurrentInstance);
00381 CurrentInstance->Model++;
00382 AllocOneInstanceRGB(CurrentInstance);
00383 }
00384
00385
00386
00387 if (Keys[DIK_NUMPADSLASH] && !LastKeys[DIK_NUMPADSLASH]) CurrentInstance->Priority = FALSE;
00388 if (Keys[DIK_NUMPADSTAR] && !LastKeys[DIK_NUMPADSTAR]) CurrentInstance->Priority = TRUE;
00389
00390
00391
00392 if (Keys[DIK_NUMPADENTER] && !LastKeys[DIK_NUMPADENTER]) CurrentInstance->Flag ^= INSTANCE_ENV;
00393
00394
00395
00396 if (Keys[DIK_H] && !LastKeys[DIK_H])
00397 {
00398 FreeOneInstanceRGB(CurrentInstance);
00399 CurrentInstance->Flag ^= INSTANCE_HIDE;
00400 AllocOneInstanceRGB(CurrentInstance);
00401 }
00402
00403
00404
00405 if (Keys[DIK_M] && !LastKeys[DIK_M]) CurrentInstance->Flag ^= INSTANCE_NO_MIRROR;
00406
00407
00408
00409 if (Keys[DIK_SPACE] && !LastKeys[DIK_SPACE]) InstanceRgbType ^= TRUE;
00410
00411
00412
00413 if (Keys[DIK_L] && !LastKeys[DIK_L]) CurrentInstance->Flag ^= INSTANCE_NO_FILE_LIGHTS;
00414
00415
00416
00417 if (!InstanceRgbType)
00418 {
00419 rgb = (MODEL_RGB*)&CurrentInstance->EnvRGB;
00420
00421 if (Keys[DIK_LSHIFT]) LastKeys[DIK_P] = LastKeys[DIK_SEMICOLON] = LastKeys[DIK_LBRACKET] = LastKeys[DIK_APOSTROPHE] = LastKeys[DIK_RBRACKET] = LastKeys[DIK_BACKSLASH] = 0;
00422
00423 if (Keys[DIK_P] && !LastKeys[DIK_P] && rgb->r < 255) rgb->r++;
00424 if (Keys[DIK_SEMICOLON] && !LastKeys[DIK_SEMICOLON] && rgb->r) rgb->r--;
00425
00426 if (Keys[DIK_LBRACKET] && !LastKeys[DIK_LBRACKET] && rgb->g < 255) rgb->g++;
00427 if (Keys[DIK_APOSTROPHE] && !LastKeys[DIK_APOSTROPHE] && rgb->g) rgb->g--;
00428
00429 if (Keys[DIK_RBRACKET] && !LastKeys[DIK_RBRACKET] && rgb->b < 255) rgb->b++;
00430 if (Keys[DIK_BACKSLASH] && !LastKeys[DIK_BACKSLASH] && rgb->b) rgb->b--;
00431 }
00432
00433
00434
00435 if (InstanceRgbType)
00436 {
00437 flag = FALSE;
00438
00439 if (Keys[DIK_LSHIFT]) LastKeys[DIK_P] = LastKeys[DIK_SEMICOLON] = LastKeys[DIK_LBRACKET] = LastKeys[DIK_APOSTROPHE] = LastKeys[DIK_RBRACKET] = LastKeys[DIK_BACKSLASH] = 0;
00440
00441 if (Keys[DIK_P] && !LastKeys[DIK_P] && CurrentInstance->r < 127) CurrentInstance->r++, flag = TRUE;
00442 if (Keys[DIK_SEMICOLON] && !LastKeys[DIK_SEMICOLON] && CurrentInstance->r > -128) CurrentInstance->r--, flag = TRUE;
00443
00444 if (Keys[DIK_LBRACKET] && !LastKeys[DIK_LBRACKET] && CurrentInstance->g < 127) CurrentInstance->g++, flag = TRUE;
00445 if (Keys[DIK_APOSTROPHE] && !LastKeys[DIK_APOSTROPHE] && CurrentInstance->g > -128) CurrentInstance->g--, flag = TRUE;
00446
00447 if (Keys[DIK_RBRACKET] && !LastKeys[DIK_RBRACKET] && CurrentInstance->b < 127) CurrentInstance->b++, flag = TRUE;
00448 if (Keys[DIK_BACKSLASH] && !LastKeys[DIK_BACKSLASH] && CurrentInstance->b > -128) CurrentInstance->b--, flag = TRUE;
00449
00450 if (flag)
00451 {
00452 FreeOneInstanceRGB(CurrentInstance);
00453 AllocOneInstanceRGB(CurrentInstance);
00454 }
00455 }
00456
00457
00458
00459 if (Keys[DIK_MINUS]) CurrentInstance->LodBias -= TimeFactor * 4;
00460 if (Keys[DIK_EQUALS]) CurrentInstance->LodBias += TimeFactor * 4;
00461
00462 if (CurrentInstance->LodBias < 64) CurrentInstance->LodBias = 64;
00463 if (CurrentInstance->LodBias > 8192) CurrentInstance->LodBias = 8192;
00464
00465
00466
00467 if (MouseLeft && !MouseLastLeft && Keys[DIK_LSHIFT])
00468 {
00469 if ((inst = AllocInstance()))
00470 {
00471 memcpy(inst, CurrentInstance, sizeof(INSTANCE));
00472 CurrentInstance = inst;
00473 return;
00474 }
00475 }
00476
00477
00478
00479 if (MouseLeft)
00480 {
00481 RotTransVector(&ViewMatrix, &ViewTrans, &CurrentInstance->WorldPos, &vec);
00482
00483 switch (InstanceAxis)
00484 {
00485 case INSTANCE_AXIS_XY:
00486 vec.v[X] = MouseXrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditXrel;
00487 vec.v[Y] = MouseYrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditYrel;
00488 vec.v[Z] = CameraEditZrel;
00489 break;
00490 case INSTANCE_AXIS_XZ:
00491 vec.v[X] = MouseXrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditXrel;
00492 vec.v[Y] = CameraEditYrel;
00493 vec.v[Z] = -MouseYrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditZrel;
00494 break;
00495 case INSTANCE_AXIS_ZY:
00496 vec.v[X] = CameraEditXrel;
00497 vec.v[Y] = MouseYrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditYrel;
00498 vec.v[Z] = MouseXrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditZrel;
00499 break;
00500 case INSTANCE_AXIS_X:
00501 vec.v[X] = MouseXrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditXrel;
00502 vec.v[Y] = CameraEditYrel;
00503 vec.v[Z] = CameraEditZrel;
00504 break;
00505 case INSTANCE_AXIS_Y:
00506 vec.v[X] = CameraEditXrel;
00507 vec.v[Y] = MouseYrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditYrel;
00508 vec.v[Z] = CameraEditZrel;
00509 break;
00510 case INSTANCE_AXIS_Z:
00511 vec.v[X] = CameraEditXrel;
00512 vec.v[Y] = CameraEditYrel;
00513 vec.v[Z] = -MouseYrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditZrel;
00514 break;
00515 }
00516
00517 if (InstanceAxisType == 1)
00518 {
00519 SetVector(&vec2, vec.v[X], vec.v[Y], vec.v[Z]);
00520 }
00521 else
00522 {
00523 RotVector(&CAM_MainCamera->WMatrix, &vec, &vec2);
00524 }
00525
00526 CurrentInstance->WorldPos.v[X] += vec2.v[X];
00527 CurrentInstance->WorldPos.v[Y] += vec2.v[Y];
00528 CurrentInstance->WorldPos.v[Z] += vec2.v[Z];
00529 }
00530
00531
00532
00533 vec.v[X] = vec.v[Y] = vec.v[Z] = 0;
00534
00535 if (Keys[DIK_NUMPAD7]) vec.v[X] -= 0.005f;
00536 if (Keys[DIK_NUMPAD4]) vec.v[X] += 0.005f;
00537 if (Keys[DIK_NUMPAD8]) vec.v[Y] -= 0.005f;
00538 if (Keys[DIK_NUMPAD5]) vec.v[Y] += 0.005f;
00539 if (Keys[DIK_NUMPAD9]) vec.v[Z] -= 0.005f;
00540 if (Keys[DIK_NUMPAD6]) vec.v[Z] += 0.005f;
00541
00542 if (Keys[DIK_NUMPAD1] && !LastKeys[DIK_NUMPAD1]) vec.v[X] += 0.25f;
00543 if (Keys[DIK_NUMPAD2] && !LastKeys[DIK_NUMPAD2]) vec.v[Y] += 0.25f;
00544 if (Keys[DIK_NUMPAD3] && !LastKeys[DIK_NUMPAD3]) vec.v[Z] += 0.25f;
00545
00546 if (Keys[DIK_NUMPAD0]) CopyMatrix(&IdentityMatrix, &CurrentInstance->WorldMatrix);
00547
00548 RotMatrixZYX(&mat, vec.v[X], vec.v[Y], vec.v[Z]);
00549
00550 if (InstanceAxisType)
00551 {
00552 MulMatrix(&mat, &CurrentInstance->WorldMatrix, &mat2);
00553 CopyMatrix(&mat2, &CurrentInstance->WorldMatrix);
00554 NormalizeMatrix(&CurrentInstance->WorldMatrix);
00555 }
00556 else if (vec.v[X] || vec.v[Y] || vec.v[Z])
00557 {
00558 RotVector(&ViewMatrix, &CurrentInstance->WorldMatrix.mv[X], &r);
00559 RotVector(&ViewMatrix, &CurrentInstance->WorldMatrix.mv[Y], &u);
00560 RotVector(&ViewMatrix, &CurrentInstance->WorldMatrix.mv[Z], &l);
00561
00562 RotVector(&mat, &r, &r2);
00563 RotVector(&mat, &u, &u2);
00564 RotVector(&mat, &l, &l2);
00565
00566 RotVector(&CAM_MainCamera->WMatrix, &r2, &CurrentInstance->WorldMatrix.mv[X]);
00567 RotVector(&CAM_MainCamera->WMatrix, &u2, &CurrentInstance->WorldMatrix.mv[Y]);
00568 RotVector(&CAM_MainCamera->WMatrix, &l2, &CurrentInstance->WorldMatrix.mv[Z]);
00569
00570 NormalizeMatrix(&CurrentInstance->WorldMatrix);
00571 }
00572 }
00573
00575
00577
00578 INSTANCE *AllocInstance(void)
00579 {
00580
00581
00582
00583 if (InstanceNum >= MAX_INSTANCES)
00584 return NULL;
00585
00586
00587
00588 return &Instances[InstanceNum++];
00589 }
00590
00592
00594
00595 void FreeInstance(INSTANCE *inst)
00596 {
00597 long idx, i;
00598
00599
00600
00601 idx = (long)(inst - Instances);
00602
00603
00604
00605 for (i = idx ; i < InstanceNum - 1; i++)
00606 {
00607 Instances[i] = Instances[i + 1];
00608 }
00609
00610
00611
00612 InstanceNum--;
00613 }
00614
00616
00618
00619 void DrawInstances(void)
00620 {
00621 short flag;
00622 long i, lod, visflag, lit;
00623 float z, flod;
00624 MODEL *model;
00625 INSTANCE *inst;
00626 POLY_RGB *savergb;
00627
00628
00629
00630 inst = Instances;
00631 for (i = 0 ; i < InstanceNum ; i++, inst++)
00632 {
00633
00634
00635
00636 if ((inst->Flag & INSTANCE_HIDE) && !RenderSettings.Mirror)
00637 continue;
00638
00639
00640
00641 if (!RenderSettings.Instance && !inst->Priority && !(inst->Flag & INSTANCE_HIDE))
00642 continue;
00643
00644
00645
00646 if (inst->VisiMask & CamVisiMask)
00647 continue;
00648
00649
00650
00651 flag = MODEL_PLAIN;
00652
00653
00654
00655 model = InstanceModels[inst->Model].Models;
00656
00657 visflag = TestSphereToFrustum(&inst->WorldPos, model->Radius, &z);
00658 if (visflag == SPHERE_OUT) continue;
00659 if (visflag == SPHERE_IN) flag |= MODEL_DONOTCLIP;
00660
00661
00662
00663 flod = z / inst->LodBias - 1;
00664 if (flod < 0) flod = 0;
00665 FTOL(flod, lod);
00666 if (lod > InstanceModels[inst->Model].Count - 1) lod = InstanceModels[inst->Model].Count - 1;
00667
00668
00669
00670 model += lod;
00671
00672
00673
00674 savergb = model->PolyRGB;
00675 model->PolyRGB = inst->rgb[lod];
00676
00677
00678
00679 if (z + model->Radius > RenderSettings.FogStart && DxState.Fog)
00680 {
00681 ModelVertFog = (inst->WorldPos.v[1] - RenderSettings.VertFogStart) * RenderSettings.VertFogMul;
00682 if (ModelVertFog < 0) ModelVertFog = 0;
00683 if (ModelVertFog > 255) ModelVertFog = 255;
00684
00685 flag |= MODEL_FOG;
00686 FOG_ON();
00687 }
00688
00689
00690
00691 if (!(inst->Flag & INSTANCE_HIDE))
00692 {
00693 if (EditMode == EDIT_LIGHTS || EditMode == EDIT_INSTANCES)
00694 lit = CheckInstanceLightEdit(inst, model->Radius);
00695 else
00696 lit = CheckInstanceLight(inst, model->Radius);
00697
00698 if (lit)
00699 {
00700 flag |= MODEL_LIT;
00701 AddModelLight(model, &inst->WorldPos, &inst->WorldMatrix);
00702 }
00703 }
00704
00705
00706
00707 if (inst->Flag & INSTANCE_ENV)
00708 {
00709 flag |= MODEL_ENV;
00710 SetEnvStatic(&inst->WorldPos, &inst->WorldMatrix, inst->EnvRGB, 0.0f, 0.0f, 1.0f);
00711 }
00712
00713
00714
00715 if (!(inst->Flag & INSTANCE_NO_MIRROR) && inst->MirrorFlag && RenderSettings.Mirror)
00716 {
00717 if (ViewCameraPos.v[Y] < inst->MirrorHeight)
00718 {
00719 MirrorHeight = inst->MirrorHeight;
00720 flag |= MODEL_MIRROR;
00721 }
00722 }
00723
00724
00725
00726 CheckModelMeshFx(model, &inst->WorldMatrix, &inst->WorldPos, &flag);
00727
00728
00729
00730 DrawModel(model, &inst->WorldMatrix, &inst->WorldPos, flag);
00731
00732
00733
00734 if (flag & MODEL_FOG)
00735 FOG_OFF();
00736
00737
00738
00739 model->PolyRGB = savergb;
00740 }
00741 }
00742
00744
00746
00747 void DisplayInstanceInfo(INSTANCE *inst)
00748 {
00749 char buf[128];
00750
00751
00752
00753 DumpText(450, 0, 8, 16, 0xffff00, InstanceModels[inst->Model].Name);
00754
00755
00756
00757 wsprintf(buf, "High priority: %s", inst->Priority ? "Yes" : "No");
00758 DumpText(450, 24, 8, 16, 0x00ffff, buf);
00759
00760
00761
00762 wsprintf(buf, "Env %s", inst->Flag & INSTANCE_ENV ? "On" : "Off");
00763 DumpText(450, 48, 8, 16, 0xff00ff, buf);
00764
00765
00766
00767 wsprintf(buf, "LOD Bias %d", (long)inst->LodBias);
00768 DumpText(450, 72, 8, 16, 0xffff00, buf);
00769
00770
00771
00772 wsprintf(buf, "Env RGB %d %d %d", ((MODEL_RGB*)&inst->EnvRGB)->r, ((MODEL_RGB*)&inst->EnvRGB)->g, ((MODEL_RGB*)&inst->EnvRGB)->b);
00773 DumpText(450, 96, 8, 16, 0x00ff00, buf);
00774
00775
00776
00777 wsprintf(buf, "Model RGB %d %d %d", inst->r, inst->g, inst->b);
00778 DumpText(450, 120, 8, 16, 0x00ffff, buf);
00779
00780
00781
00782 wsprintf(buf, "Axis %s - %s", InstanceAxisNames[InstanceAxis], InstanceAxisTypeNames[InstanceAxisType]);
00783 DumpText(450, 144, 8, 16, 0xff0000, buf);
00784
00785
00786
00787 wsprintf(buf, "RGB Type: %s", InstanceRgbType? "Model" : "Env");
00788 DumpText(450, 168, 8, 16, 0xffff00, buf);
00789
00790
00791
00792 wsprintf(buf, "Mirror Hide: %s", inst->Flag & INSTANCE_HIDE? "Yes" : "No");
00793 DumpText(450, 192, 8, 16, 0x00ff00, buf);
00794
00795
00796
00797 wsprintf(buf, "Mirror: %s", inst->Flag & INSTANCE_NO_MIRROR? "No" : "Yes");
00798 DumpText(450, 216, 8, 16, 0x00ffff, buf);
00799
00800
00801
00802 wsprintf(buf, "Fixed lights: %s", inst->Flag & INSTANCE_NO_FILE_LIGHTS? "No" : "Yes");
00803 DumpText(450, 240, 8, 16, 0xff0000, buf);
00804
00805
00806
00807 TEXTUREFILTER_ON();
00808 ZBUFFER_ON();
00809 ZWRITE_ON();
00810
00811 if (InstanceAxisType)
00812 DrawAxis(&IdentityMatrix, &CurrentInstance->WorldPos);
00813 else
00814 DrawAxis(&CAM_MainCamera->WMatrix, &CurrentInstance->WorldPos);
00815
00816 BeginTextState();
00817 }
00818
00820
00822
00823 void LoadInstanceModels(void)
00824 {
00825 long i;
00826 WIN32_FIND_DATA data;
00827 HANDLE handle;
00828 FILE *fp;
00829 char buf[256];
00830 char names[MAX_INSTANCE_MODELS][16];
00831
00832
00833
00834 InstanceModelNum = 0;
00835 InstanceModels = NULL;
00836
00837
00838
00839 wsprintf(buf, "levels\\%s\\*.prm", LevelInf[GameSettings.Level].Dir);
00840 handle = FindFirstFile(buf, &data);
00841 if (handle == INVALID_HANDLE_VALUE)
00842 return;
00843
00844
00845
00846 while (TRUE)
00847 {
00848
00849
00850
00851 if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && InstanceModelNum < MAX_INSTANCE_MODELS)
00852 {
00853 for (i = 0 ; i < (long)strlen(data.cFileName) - 4 ; i++) data.cFileName[i] = toupper(data.cFileName[i]);
00854 data.cFileName[i] = 0;
00855 memcpy(names[InstanceModelNum], data.cFileName, 16);
00856 InstanceModelNum++;
00857 }
00858
00859
00860
00861 if (!FindNextFile(handle, &data))
00862 break;
00863 }
00864
00865
00866
00867 FindClose(handle);
00868
00869
00870
00871 InstanceModels = (INSTANCE_MODELS*)malloc(sizeof(INSTANCE_MODELS) * InstanceModelNum);
00872 if (!InstanceModels)
00873 {
00874 Box("ERROR", "Can't alloc memory for instance models!", MB_OK);
00875 QuitGame = TRUE;
00876 return;
00877 }
00878
00879
00880
00881 for (i = 0 ; i < InstanceModelNum ; i++)
00882 {
00883 memcpy(InstanceModels[i].Name, names[i], MAX_INSTANCE_FILENAME);
00884 InstanceModels[i].Name[MAX_INSTANCE_FILENAME - 1] = 0;
00885 wsprintf(buf, "levels\\%s\\%s.prm", LevelInf[GameSettings.Level].Dir, names[i]);
00886 InstanceModels[i].Count = LoadModel(buf, InstanceModels[i].Models, 0, MAX_INSTANCE_LOD, LOADMODEL_OFFSET_TPAGE, LevelInf[GameSettings.Level].InstanceRGBper);
00887
00888
00889 wsprintf(buf, "levels\\%s\\%s.ncp", LevelInf[GameSettings.Level].Dir, names[i]);
00890 if ((fp = fopen(buf, "rb")) != NULL) {
00891 InstanceModels[i].CollPoly = LoadNewCollPolys(fp, &InstanceModels[i].NCollPolys);
00892 fclose(fp);
00893 } else {
00894 InstanceModels[i].CollPoly = NULL;
00895 InstanceModels[i].NCollPolys = 0;
00896 }
00897
00898 }
00899 }
00900
00902
00904
00905 void FreeInstanceModels(void)
00906 {
00907 long i;
00908
00909 for (i = 0 ; i < InstanceModelNum ; i++)
00910 {
00911 DestroyCollPolys(InstanceModels[i].CollPoly);
00912 InstanceModels[i].CollPoly = NULL;
00913 InstanceModels[i].NCollPolys = 0;
00914 FreeModel(InstanceModels[i].Models, InstanceModels[i].Count);
00915 }
00916
00917 free(InstanceModels);
00918 }
00919
00921
00923
00924 void FreeInstanceRGBs(void)
00925 {
00926 long i;
00927
00928 for (i = 0 ; i < InstanceNum ; i++)
00929 {
00930 FreeOneInstanceRGB(&Instances[i]);
00931 }
00932 }
00933
00935
00937
00938 void FreeOneInstanceRGB(INSTANCE *inst)
00939 {
00940 long i;
00941
00942 for (i = 0 ; i < InstanceModels[inst->Model].Count ; i++)
00943 {
00944 free(inst->rgb[i]);
00945 }
00946 }
00947
00949
00951
00952 void AllocOneInstanceRGB(INSTANCE *inst)
00953 {
00954 long i, j, k, col;
00955 MODEL *model;
00956
00957
00958
00959 for (i = 0 ; i < InstanceModels[inst->Model].Count ; i++)
00960 {
00961
00962
00963
00964 model = &InstanceModels[inst->Model].Models[i];
00965 inst->rgb[i] = (POLY_RGB*)malloc(sizeof(POLY_RGB) * model->PolyNum);
00966 if (!inst->rgb[i])
00967 {
00968 Box("ERROR", "Can't alloc memory for Instance RGB", MB_OK);
00969 QuitGame = TRUE;
00970 return;
00971 }
00972
00973
00974
00975 for (j = 0 ; j < model->PolyNum ; j++)
00976 {
00977 for (k = 0 ; k < 4 ; k++)
00978 {
00979 if (inst->Flag & INSTANCE_HIDE)
00980 {
00981 *(long*)&inst->rgb[i][j].rgb[k] = LevelInf[GameSettings.Level].FogColor;
00982 }
00983 else
00984 {
00985 inst->rgb[i][j].rgb[k].a = model->PolyRGB[j].rgb[k].a;
00986
00987 col = model->PolyRGB[j].rgb[k].r * (inst->r + 128) / 128;
00988 if (col > 255) col = 255;
00989 inst->rgb[i][j].rgb[k].r = (unsigned char)col;
00990
00991 col = model->PolyRGB[j].rgb[k].g * (inst->g + 128) / 128;
00992 if (col > 255) col = 255;
00993 inst->rgb[i][j].rgb[k].g = (unsigned char)col;
00994
00995 col = model->PolyRGB[j].rgb[k].b * (inst->b + 128) / 128;
00996 if (col > 255) col = 255;
00997 inst->rgb[i][j].rgb[k].b = (unsigned char)col;
00998 }
00999 }
01000 }
01001 }
01002 }
01003
01005
01007
01008 void SetInstanceBoundingBoxes(INSTANCE *inst)
01009 {
01010 long j;
01011 MODEL *model;
01012 VEC vec;
01013
01014
01015
01016 model = InstanceModels[inst->Model].Models;
01017
01018
01019
01020 inst->Box.Xmin = inst->Box.Ymin = inst->Box.Zmin = 999999;
01021 inst->Box.Xmax = inst->Box.Ymax = inst->Box.Zmax = -999999;
01022
01023 for (j = 0 ; j < model->VertNum ; j++)
01024 {
01025 RotTransVector(&inst->WorldMatrix, &inst->WorldPos, (VEC*)&model->VertPtr[j].x, &vec);
01026
01027 if (vec.v[X] < inst->Box.Xmin) inst->Box.Xmin = vec.v[X];
01028 if (vec.v[X] > inst->Box.Xmax) inst->Box.Xmax = vec.v[X];
01029 if (vec.v[Y] < inst->Box.Ymin) inst->Box.Ymin = vec.v[Y];
01030 if (vec.v[Y] > inst->Box.Ymax) inst->Box.Ymax = vec.v[Y];
01031 if (vec.v[Z] < inst->Box.Zmin) inst->Box.Zmin = vec.v[Z];
01032 if (vec.v[Z] > inst->Box.Zmax) inst->Box.Zmax = vec.v[Z];
01033 }
01034
01035
01036
01037 inst->VisiMask = SetObjectVisiMask(&inst->Box);
01038 }
01039
01040
01041
01043
01044
01045
01047
01048 void BuildInstanceCollPolys()
01049 {
01050 int iInst, iPoly, nInstCollPolys;
01051 INSTANCE *instance;
01052 INSTANCE_MODELS *instModel;
01053 NEWCOLLPOLY *worldPoly, *instModelPoly;
01054
01055 COL_NInstanceCollPolys = 0;
01056
01057 for (iInst = 0; iInst < InstanceNum; iInst++) {
01058 instance = &Instances[iInst];
01059
01060 if (!instance->Priority && !RenderSettings.Instance)
01061 continue;
01062
01063 COL_NInstanceCollPolys += InstanceModels[instance->Model].NCollPolys;
01064
01065 }
01066
01067
01068 COL_InstanceCollPoly = CreateCollPolys(COL_NInstanceCollPolys);
01069
01070
01071 nInstCollPolys = 0;
01072 for (iInst = 0; iInst < InstanceNum; iInst++) {
01073 instance = &Instances[iInst];
01074
01075 if (!instance->Priority && !RenderSettings.Instance)
01076 continue;
01077
01078 instModel = &InstanceModels[instance->Model];
01079
01080
01081 instance->CollPoly = &COL_InstanceCollPoly[nInstCollPolys];
01082 instance->NCollPolys = instModel->NCollPolys;
01083
01084
01085
01086 for (iPoly = 0; iPoly < instModel->NCollPolys; iPoly++) {
01087 worldPoly = &COL_InstanceCollPoly[nInstCollPolys++];
01088 instModelPoly = &instModel->CollPoly[iPoly];
01089
01090 worldPoly->Type = instModelPoly->Type;
01091 worldPoly->Material = instModelPoly->Material;
01092 RotTransPlane(&instModelPoly->Plane, &instance->WorldMatrix, &instance->WorldPos, &worldPoly->Plane);
01093 RotTransPlane(&instModelPoly->EdgePlane[0], &instance->WorldMatrix, &instance->WorldPos, &worldPoly->EdgePlane[0]);
01094 RotTransPlane(&instModelPoly->EdgePlane[1], &instance->WorldMatrix, &instance->WorldPos, &worldPoly->EdgePlane[1]);
01095 RotTransPlane(&instModelPoly->EdgePlane[2], &instance->WorldMatrix, &instance->WorldPos, &worldPoly->EdgePlane[2]);
01096 if (instModelPoly->Type == QUAD) {
01097 RotTransPlane(&instModelPoly->EdgePlane[3], &instance->WorldMatrix, &instance->WorldPos, &worldPoly->EdgePlane[3]);
01098 }
01099
01100 RotTransBBox(&instModelPoly->BBox, &instance->WorldMatrix, &instance->WorldPos, &worldPoly->BBox);
01101
01102 }
01103 }
01104
01105 }
01106