00001
00002 #include "revolt.h"
00003 #include "editcam.h"
00004 #include "main.h"
00005 #include "model.h"
00006 #include "geom.h"
00007 #include "text.h"
00008 #include "camera.h"
00009 #include "input.h"
00010 #include "level.h"
00011
00012
00013
00014 EDIT_CAM_NODE *CurrentEditCamNode = NULL;
00015
00016 static MODEL EditCamNodeModel[CAMNODE_NTYPES];
00017 static long EditCamNodeNum;
00018 static EDIT_CAM_NODE *EditCamNode;
00019 static long EditCamNodeAxis, EditCamNodeAxisType;
00020 static EDIT_CAM_NODE *LastEditCamNode = NULL;
00021
00022 static long MaxEditCamNodeID = -1;
00023
00024 static char *EditCamNodeModelNames[CAMNODE_NTYPES] = {
00025 "edit\\camnode.m",
00026 "models\\football.m",
00027 };
00028
00029
00030
00031
00032 static char *EditCamNodeAxisNames[] = {
00033 "X Y",
00034 "X Z",
00035 "Z Y",
00036 "X",
00037 "Y",
00038 "Z",
00039 };
00040
00041 static char *EditCamNodeAxisTypeNames[] = {
00042 "Camera",
00043 "World",
00044 };
00045
00046 char *CamNodeTypeText[] = {
00047 "Monorail",
00048 "Static",
00049 };
00050
00052
00054
00055 void InitEditCamNodes(void)
00056 {
00057 EditCamNode = (EDIT_CAM_NODE*)malloc(sizeof(EDIT_CAM_NODE) * MAX_EDIT_CAM_NODES);
00058 MaxEditCamNodeID = -1;
00059 if (!EditCamNode)
00060 {
00061 Box(NULL, "Can't alloc memory for edit camera nodes!", MB_OK);
00062 QuitGame = TRUE;
00063 }
00064 }
00065
00067
00069
00070 void KillEditCamNodes(void)
00071 {
00072 free(EditCamNode);
00073 }
00074
00076
00078
00079 void LoadEditCamNodeModels(void)
00080 {
00081 int iModel;
00082
00083 for (iModel = 0; iModel < CAMNODE_NTYPES; iModel++) {
00084 LoadModel(EditCamNodeModelNames[iModel], &EditCamNodeModel[iModel], -1, 1, LOADMODEL_FORCE_TPAGE, 100);
00085 }
00086 }
00087
00089
00091
00092 void FreeEditCamNodeModels(void)
00093 {
00094 int iModel;
00095
00096 for (iModel = 0; iModel < CAMNODE_NTYPES; iModel++) {
00097 FreeModel(&EditCamNodeModel[iModel], 1);
00098 }
00099 }
00100
00102
00104
00105 void LoadEditCamNodes(char *file)
00106 {
00107 long i;
00108 FILE *fp;
00109 FILE_CAM_NODE fnode;
00110
00111
00112
00113 fp = fopen(file, "rb");
00114
00115
00116
00117 if (!fp)
00118 {
00119 fp = fopen(file, "wb");
00120 if (!fp) return;
00121 i = 0;
00122 fwrite(&i, sizeof(i), 1, fp);
00123 fclose(fp);
00124 fp = fopen(file, "rb");
00125 if (!fp) return;
00126 }
00127
00128
00129
00130 fread(&EditCamNodeNum, sizeof(EditCamNodeNum), 1, fp);
00131
00132 for (i = 0 ; i < EditCamNodeNum ; i++)
00133 {
00134
00135
00136
00137 fread(&fnode, sizeof(fnode), 1, fp);
00138
00139 fnode.x = (long)((float)fnode.x * EditScale);
00140 fnode.y = (long)((float)fnode.y * EditScale);
00141 fnode.z = (long)((float)fnode.z * EditScale);
00142
00143
00144
00145 EditCamNode[i].Type = fnode.Type;
00146 EditCamNode[i].ZoomFactor = fnode.ZoomFactor;
00147
00148 EditCamNode[i].Pos.v[X] = (float)fnode.x / 65536;
00149 EditCamNode[i].Pos.v[Y] = (float)fnode.y / 65536;
00150 EditCamNode[i].Pos.v[Z] = (float)fnode.z / 65536;
00151
00152 if (fnode.Link != -1)
00153 {
00154 EditCamNode[i].Link = &EditCamNode[fnode.Link];
00155 }
00156 else
00157 {
00158 EditCamNode[i].Link = NULL;
00159 }
00160
00161 if (fnode.ID == -1) {
00162 EditCamNode[i].ID = ++MaxEditCamNodeID;
00163 } else {
00164 EditCamNode[i].ID = fnode.ID;
00165 MaxEditCamNodeID = Max(MaxEditCamNodeID, fnode.ID);
00166 }
00167 }
00168
00169
00170
00171 fclose(fp);
00172 }
00173
00175
00177
00178 void SaveEditCamNodes(char *file)
00179 {
00180 long i;
00181 FILE *fp;
00182 FILE_CAM_NODE fnode;
00183 char bak[256];
00184
00185
00186
00187 memcpy(bak, file, strlen(file) - 3);
00188 wsprintf(bak + strlen(file) - 3, "ca-");
00189 remove(bak);
00190 rename(file, bak);
00191
00192
00193
00194 fp = fopen(file, "wb");
00195 if (!fp) return;
00196
00197
00198
00199 fwrite(&EditCamNodeNum, sizeof(EditCamNodeNum), 1, fp);
00200
00201
00202
00203 for (i = 0 ; i < EditCamNodeNum ; i++)
00204 {
00205
00206
00207
00208 fnode.Type = EditCamNode[i].Type;
00209 fnode.ZoomFactor = EditCamNode[i].ZoomFactor;
00210
00211 fnode.x = (long)(EditCamNode[i].Pos.v[X] * 65536);
00212 fnode.y = (long)(EditCamNode[i].Pos.v[Y] * 65536);
00213 fnode.z = (long)(EditCamNode[i].Pos.v[Z] * 65536);
00214
00215 if (EditCamNode[i].Link)
00216 {
00217 fnode.Link = (long)(EditCamNode[i].Link - EditCamNode);
00218 }
00219 else
00220 {
00221 fnode.Link = -1;
00222 }
00223
00224 fnode.ID = EditCamNode[i].ID;
00225
00226
00227
00228 fwrite(&fnode, sizeof(fnode), 1, fp);
00229 }
00230
00231
00232
00233 Box("Saved camera node File:", file, MB_OK);
00234 fclose(fp);
00235 }
00236
00238
00240 extern VEC CAM_NodeCamPos;
00241 void DrawEditCamNodes(void)
00242 {
00243 long i;
00244 VEC pos;
00245 char buf[128];
00246 EDIT_CAM_NODE *node;
00247
00248
00249
00250 node = EditCamNode;
00251 for (i = 0 ; i < EditCamNodeNum ; i++, node++)
00252 {
00253
00254
00255
00256 if (LastEditCamNode != &EditCamNode[i] || (FrameCount & 4))
00257 DrawModel(&EditCamNodeModel[node->Type], &IdentityMatrix, &node->Pos, MODEL_PLAIN);
00258
00259
00260
00261 if (node->Link)
00262 {
00263 DrawLine(&node->Pos, &node->Link->Pos, 0xffff00, 0xffff00);
00264 }
00265
00266
00267
00268 if (CurrentEditCamNode == node)
00269 {
00270 if (EditCamNodeAxisType)
00271 DrawAxis(&IdentityMatrix, &node->Pos);
00272 else
00273 DrawAxis(&CAM_MainCamera->WMatrix, &node->Pos);
00274 }
00275
00276
00277
00278 wsprintf(buf, "%d", EditCamNode[i].ID);
00279 RotTransVector(&ViewMatrix, &ViewTrans, &EditCamNode[i].Pos, &pos);
00280 pos.v[X] -= strlen(buf) * 4.0f;
00281 pos.v[Y] -= 48.0f;
00282
00283 if (pos.v[Z] > RenderSettings.NearClip)
00284 DumpText3D(&pos, 8, 16, 0xffff00, buf);
00285
00286 }
00287
00288
00289
00290
00291 }
00292
00294
00296
00297 void DisplayCamNodeInfo(EDIT_CAM_NODE *node)
00298 {
00299 char buf[128];
00300
00301
00302
00303 wsprintf(buf, "Type %s", CamNodeTypeText[node->Type]);
00304 DumpText(450, 0, 8, 16, 0xff0000, buf);
00305
00306
00307
00308 wsprintf(buf, "Zoom %d", node->ZoomFactor);
00309 DumpText(450, 24, 8, 16, 0x00ff00, buf);
00310
00311
00312
00313 wsprintf(buf, "Axis %s - %s", EditCamNodeAxisNames[EditCamNodeAxis], EditCamNodeAxisTypeNames[EditCamNodeAxisType]);
00314 DumpText(450, 48, 8, 16, 0x0000ff, buf);
00315
00316
00317
00318 wsprintf(buf, "Pos %d %d %d", (long)node->Pos.v[X], (long)node->Pos.v[Y], (long)node->Pos.v[Z]);
00319 DumpText(450, 72, 8, 16, 0xffffff, buf);
00320
00321
00322
00323 wsprintf(buf, "ID %d", node->ID);
00324 DumpText(450, 96, 8, 16, 0x00ff00, buf);
00325
00326 }
00327
00329
00331
00332 void EditCamNodes(void)
00333 {
00334 long i;
00335 VEC vec, vec2;
00336 float z, sx, sy, rad;
00337 MAT mat, mat2;
00338 EDIT_CAM_NODE *nnode, *node;
00339 FILE *fp;
00340
00341
00342
00343 if (CAM_MainCamera->Type != CAM_EDIT)
00344 {
00345 CurrentEditCamNode = NULL;
00346 return;
00347 }
00348
00349
00350
00351 if (MouseRight)
00352 {
00353 RotMatrixZYX(&mat, (float)-Mouse.lY / 3072, -(float)Mouse.lX / 3072, 0);
00354 MulMatrix(&CAM_MainCamera->WMatrix, &mat, &mat2);
00355 CopyMatrix(&mat2, &CAM_MainCamera->WMatrix);
00356
00357 CAM_MainCamera->WMatrix.m[RY] = 0;
00358 NormalizeVector(&CAM_MainCamera->WMatrix.mv[X]);
00359 CrossProduct(&CAM_MainCamera->WMatrix.mv[Z], &CAM_MainCamera->WMatrix.mv[X], &CAM_MainCamera->WMatrix.mv[Y]);
00360 NormalizeVector(&CAM_MainCamera->WMatrix.mv[Y]);
00361 CrossProduct(&CAM_MainCamera->WMatrix.mv[X], &CAM_MainCamera->WMatrix.mv[Y], &CAM_MainCamera->WMatrix.mv[Z]);
00362 }
00363
00364
00365
00366 if (Keys[DIK_LCONTROL] && Keys[DIK_F4] && !LastKeys[DIK_F4])
00367 {
00368 SaveEditCamNodes(GetLevelFilename("cam", FILENAME_MAKE_BODY | FILENAME_GAME_SETTINGS));
00369 if ((fp = fopen(GetLevelFilename("cam", FILENAME_MAKE_BODY), "rb")) != NULL)
00370 {
00371 CAM_NCameraNodes = LoadCameraNodes(fp);
00372 fclose(fp);
00373 }
00374 }
00375
00376
00377
00378 if ((Keys[DIK_RETURN] && !LastKeys[DIK_RETURN]) || (Keys[DIK_BACKSPACE] && !LastKeys[DIK_BACKSPACE]))
00379 {
00380 nnode = NULL;
00381 z = RenderSettings.FarClip;
00382
00383 node = EditCamNode;
00384 for (i = 0 ; i < EditCamNodeNum ; i++, node++)
00385 {
00386 RotTransVector(&ViewMatrix, &ViewTrans, &node->Pos, &vec);
00387
00388 if (vec.v[Z] < RenderSettings.NearClip || vec.v[Z] >= RenderSettings.FarClip) continue;
00389
00390 sx = vec.v[X] * RenderSettings.GeomPers / vec.v[Z] + REAL_SCREEN_XHALF;
00391 sy = vec.v[Y] * RenderSettings.GeomPers / vec.v[Z] + REAL_SCREEN_YHALF;
00392
00393 rad = 32 * RenderSettings.GeomPers / vec.v[Z];
00394
00395 if (MouseXpos > sx - rad && MouseXpos < sx + rad && MouseYpos > sy - rad && MouseYpos < sy + rad)
00396 {
00397 if (vec.v[Z] < z)
00398 {
00399 nnode = node;
00400 z = vec.v[Z];
00401 }
00402 }
00403 }
00404 if (nnode)
00405 {
00406 if (Keys[DIK_RETURN])
00407 CurrentEditCamNode = nnode;
00408 else
00409 LastEditCamNode = nnode;
00410 return;
00411 }
00412 }
00413
00414
00415
00416 if (Keys[DIK_INSERT] && !LastKeys[DIK_INSERT])
00417 {
00418 if ((node = AllocEditCamNode()))
00419 {
00420 vec.v[X] = 0;
00421 vec.v[Y] = 0;
00422 vec.v[Z] = 512;
00423 RotVector(&CAM_MainCamera->WMatrix, &vec, &vec2);
00424 AddVector(&CAM_MainCamera->WPos, &vec2, &node->Pos);
00425
00426 node->Type = 0;
00427 node->ZoomFactor = 500;
00428
00429 node->Link = NULL;
00430
00431 node->ID = ++MaxEditCamNodeID;
00432
00433 CurrentEditCamNode = node;
00434 }
00435 }
00436
00437
00438
00439 if (!CurrentEditCamNode) return;
00440
00441
00442
00443 if (Keys[DIK_RETURN] && !LastKeys[DIK_RETURN])
00444 {
00445 CurrentEditCamNode = NULL;
00446 return;
00447 }
00448
00449
00450
00451 if (Keys[DIK_DELETE] && !LastKeys[DIK_DELETE])
00452 {
00453 FreeEditCamNode(CurrentEditCamNode);
00454 CurrentEditCamNode = NULL;
00455 return;
00456 }
00457
00458
00459
00460 if (Keys[DIK_TAB] && !LastKeys[DIK_TAB])
00461 {
00462 if (Keys[DIK_LSHIFT]) EditCamNodeAxis--;
00463 else EditCamNodeAxis++;
00464 if (EditCamNodeAxis == -1) EditCamNodeAxis = 5;
00465 if (EditCamNodeAxis == 6) EditCamNodeAxis = 0;
00466 }
00467
00468
00469
00470 if (Keys[DIK_LALT] && !LastKeys[DIK_LALT])
00471 EditCamNodeAxisType ^= 1;
00472
00473
00474
00475 if (Keys[DIK_NUMPADENTER] && !LastKeys[DIK_NUMPADENTER])
00476 CurrentEditCamNode->Type ^= 1;
00477
00478
00479
00480 if (Keys[DIK_NUMPADSLASH] && !LastKeys[DIK_NUMPADSLASH])
00481 CurrentEditCamNode->ZoomFactor -= 50;
00482
00483 if (Keys[DIK_NUMPADSTAR] && !LastKeys[DIK_NUMPADSTAR])
00484 CurrentEditCamNode->ZoomFactor += 50;
00485
00486 if (CurrentEditCamNode->ZoomFactor < -1000) CurrentEditCamNode->ZoomFactor = -1000;
00487 if (CurrentEditCamNode->ZoomFactor > 1000) CurrentEditCamNode->ZoomFactor = 1000;
00488
00489
00490
00491 if (Keys[DIK_NUMPADPLUS] && !LastKeys[DIK_NUMPADPLUS] && LastEditCamNode && LastEditCamNode != CurrentEditCamNode)
00492 {
00493 CurrentEditCamNode->Link = LastEditCamNode;
00494 LastEditCamNode->Link = CurrentEditCamNode;
00495 CurrentEditCamNode->Type = LastEditCamNode->Type = CAMNODE_MONORAIL;
00496 }
00497
00498
00499
00500 if (Keys[DIK_NUMPADMINUS] && !LastKeys[DIK_NUMPADMINUS] && LastEditCamNode && CurrentEditCamNode != LastEditCamNode)
00501 {
00502 CurrentEditCamNode->Link = NULL;
00503 LastEditCamNode->Link = NULL;
00504 CurrentEditCamNode->Type = LastEditCamNode->Type = CAMNODE_STATIC;
00505 }
00506
00507
00508
00509 if (MouseLeft)
00510 {
00511 RotTransVector(&ViewMatrix, &ViewTrans, &CurrentEditCamNode->Pos, &vec);
00512
00513 switch (EditCamNodeAxis)
00514 {
00515 case EDIT_CAM_NODE_AXIS_XY:
00516 vec.v[X] = MouseXrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditXrel;
00517 vec.v[Y] = MouseYrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditYrel;
00518 vec.v[Z] = CameraEditZrel;
00519 break;
00520 case EDIT_CAM_NODE_AXIS_XZ:
00521 vec.v[X] = MouseXrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditXrel;
00522 vec.v[Y] = CameraEditYrel;
00523 vec.v[Z] = -MouseYrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditZrel;
00524 break;
00525 case EDIT_CAM_NODE_AXIS_ZY:
00526 vec.v[X] = CameraEditXrel;
00527 vec.v[Y] = MouseYrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditYrel;
00528 vec.v[Z] = MouseXrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditZrel;
00529 break;
00530 case EDIT_CAM_NODE_AXIS_X:
00531 vec.v[X] = MouseXrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditXrel;
00532 vec.v[Y] = CameraEditYrel;
00533 vec.v[Z] = CameraEditZrel;
00534 break;
00535 case EDIT_CAM_NODE_AXIS_Y:
00536 vec.v[X] = CameraEditXrel;
00537 vec.v[Y] = MouseYrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditYrel;
00538 vec.v[Z] = CameraEditZrel;
00539 break;
00540 case EDIT_CAM_NODE_AXIS_Z:
00541 vec.v[X] = CameraEditXrel;
00542 vec.v[Y] = CameraEditYrel;
00543 vec.v[Z] = -MouseYrel * vec.v[Z] / RenderSettings.GeomPers + CameraEditZrel;
00544 break;
00545 }
00546
00547 if (EditCamNodeAxisType == 1)
00548 {
00549 SetVector(&vec2, vec.v[X], vec.v[Y], vec.v[Z]);
00550 }
00551 else
00552 {
00553 RotVector(&CAM_MainCamera->WMatrix, &vec, &vec2);
00554 }
00555
00556 CurrentEditCamNode->Pos.v[X] += vec2.v[X];
00557 CurrentEditCamNode->Pos.v[Y] += vec2.v[Y];
00558 CurrentEditCamNode->Pos.v[Z] += vec2.v[Z];
00559 }
00560 }
00561
00563
00565
00566 EDIT_CAM_NODE *AllocEditCamNode(void)
00567 {
00568
00569
00570
00571 if (EditCamNodeNum >= MAX_EDIT_CAM_NODES)
00572 return NULL;
00573
00574
00575
00576 return &EditCamNode[EditCamNodeNum++];
00577 }
00578
00580
00582
00583 void FreeEditCamNode(EDIT_CAM_NODE *node)
00584 {
00585 long idx, i;
00586
00587
00588
00589 for (i = 0 ; i < EditCamNodeNum ; i++)
00590 {
00591 if (EditCamNode[i].Link == node)
00592 {
00593 EditCamNode[i].Link = NULL;
00594 EditCamNode[i].Type = CAMNODE_STATIC;
00595
00596 }
00597 }
00598
00599
00600
00601 idx = (long)(node - EditCamNode);
00602
00603
00604
00605 for (i = idx ; i < EditCamNodeNum - 1; i++)
00606 {
00607 EditCamNode[i] = EditCamNode[i + 1];
00608 }
00609
00610
00611
00612 EditCamNodeNum--;
00613
00614
00615
00616 for (i = 0 ; i < EditCamNodeNum ; i++)
00617 {
00618 if (EditCamNode[i].Link > node) EditCamNode[i].Link--;
00619 }
00620 }