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 #include "q_shared.hpp"
00027 #include "splines.h"
00028
00029 extern "C" {
00030 int FS_Write( const void *buffer, int len, fileHandle_t h );
00031 int FS_ReadFile( const char *qpath, void **buffer );
00032 void FS_FreeFile( void *buffer );
00033 fileHandle_t FS_FOpenFileWrite( const char *filename );
00034 void FS_FCloseFile( fileHandle_t f );
00035 }
00036
00037 float Q_fabs( float f ) {
00038 int tmp = * ( int * ) &f;
00039 tmp &= 0x7FFFFFFF;
00040 return * ( float * ) &tmp;
00041 }
00042
00043
00044
00045
00046
00047
00048
00049 idCameraDef splineList;
00050 idCameraDef *g_splineList = &splineList;
00051
00052 idVec3_t idSplineList::zero(0,0,0);
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
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 void idSplineList::buildSpline() {
00183
00184 clearSpline();
00185 for(int i = 3; i < controlPoints.Num(); i++) {
00186 for (float tension = 0.0f; tension < 1.001f; tension += granularity) {
00187 float x = 0;
00188 float y = 0;
00189 float z = 0;
00190 for (int j = 0; j < 4; j++) {
00191 x += controlPoints[i - (3 - j)]->x * calcSpline(j, tension);
00192 y += controlPoints[i - (3 - j)]->y * calcSpline(j, tension);
00193 z += controlPoints[i - (3 - j)]->z * calcSpline(j, tension);
00194 }
00195 splinePoints.Append(new idVec3_t(x, y, z));
00196 }
00197 }
00198 dirty = false;
00199
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 float idSplineList::totalDistance() {
00261
00262 if (controlPoints.Num() == 0) {
00263 return 0.0;
00264 }
00265
00266 if (dirty) {
00267 buildSpline();
00268 }
00269
00270 float dist = 0.0;
00271 idVec3_t temp;
00272 int count = splinePoints.Num();
00273 for(int i = 1; i < count; i++) {
00274 temp = *splinePoints[i-1];
00275 temp -= *splinePoints[i];
00276 dist += temp.Length();
00277 }
00278 return dist;
00279 }
00280
00281 void idSplineList::initPosition(long bt, long totalTime) {
00282
00283 if (dirty) {
00284 buildSpline();
00285 }
00286
00287 if (splinePoints.Num() == 0) {
00288 return;
00289 }
00290
00291 baseTime = bt;
00292 time = totalTime;
00293
00294
00295 splineTime.Clear();
00296 splineTime.Append(bt);
00297 double dist = totalDistance();
00298 double distSoFar = 0.0;
00299 idVec3_t temp;
00300 int count = splinePoints.Num();
00301
00302 for(int i = 1; i < count; i++) {
00303 temp = *splinePoints[i-1];
00304 temp -= *splinePoints[i];
00305 distSoFar += temp.Length();
00306 double percent = distSoFar / dist;
00307 percent *= totalTime;
00308 splineTime.Append(percent + bt);
00309 }
00310 assert(splineTime.Num() == splinePoints.Num());
00311 activeSegment = 0;
00312 }
00313
00314
00315
00316 float idSplineList::calcSpline(int step, float tension) {
00317 switch(step) {
00318 case 0: return (pow(1 - tension, 3)) / 6;
00319 case 1: return (3 * pow(tension, 3) - 6 * pow(tension, 2) + 4) / 6;
00320 case 2: return (-3 * pow(tension, 3) + 3 * pow(tension, 2) + 3 * tension + 1) / 6;
00321 case 3: return pow(tension, 3) / 6;
00322 }
00323 return 0.0;
00324 }
00325
00326
00327
00328 void idSplineList::updateSelection(const idVec3_t &move) {
00329 if (selected) {
00330 dirty = true;
00331 VectorAdd(*selected, move, *selected);
00332 }
00333 }
00334
00335
00336 void idSplineList::setSelectedPoint(idVec3_t *p) {
00337 if (p) {
00338 p->Snap();
00339 for(int i = 0; i < controlPoints.Num(); i++) {
00340 if (*p == *controlPoints[i]) {
00341 selected = controlPoints[i];
00342 }
00343 }
00344 } else {
00345 selected = NULL;
00346 }
00347 }
00348
00349 const idVec3_t *idSplineList::getPosition(long t) {
00350 static idVec3_t interpolatedPos;
00351
00352
00353 int count = splineTime.Num();
00354 if (count == 0) {
00355 return &zero;
00356 }
00357
00358 Com_Printf("Time: %d\n", t);
00359 assert(splineTime.Num() == splinePoints.Num());
00360
00361 while (activeSegment < count) {
00362 if (splineTime[activeSegment] >= t) {
00363 if (activeSegment > 0 && activeSegment < count - 1) {
00364 double timeHi = splineTime[activeSegment + 1];
00365 double timeLo = splineTime[activeSegment - 1];
00366 double percent = (timeHi - t) / (timeHi - timeLo);
00367
00368 idVec3_t v1 = *splinePoints[activeSegment-1];
00369 idVec3_t v2 = *splinePoints[activeSegment+1];
00370 v2 *= (1.0 - percent);
00371 v1 *= percent;
00372 v2 += v1;
00373 interpolatedPos = v2;
00374 return &interpolatedPos;
00375 }
00376 return splinePoints[activeSegment];
00377 } else {
00378 activeSegment++;
00379 }
00380 }
00381 return splinePoints[count-1];
00382 }
00383
00384 void idSplineList::parse(const char *(*text) ) {
00385 const char *token;
00386
00387 do {
00388 token = Com_Parse( text );
00389
00390 if ( !token[0] ) {
00391 break;
00392 }
00393 if ( !Q_stricmp (token, "}") ) {
00394 break;
00395 }
00396
00397 do {
00398
00399 if ( !token[0] || !Q_stricmp (token, "(") || !Q_stricmp(token, "}")) {
00400 break;
00401 }
00402
00403 Com_UngetToken();
00404 idStr key = Com_ParseOnLine(text);
00405 const char *token = Com_Parse(text);
00406 if (Q_stricmp(key.c_str(), "granularity") == 0) {
00407 granularity = atof(token);
00408 } else if (Q_stricmp(key.c_str(), "name") == 0) {
00409 name = token;
00410 }
00411 token = Com_Parse(text);
00412
00413 } while (1);
00414
00415 if ( !Q_stricmp (token, "}") ) {
00416 break;
00417 }
00418
00419 Com_UngetToken();
00420
00421 idVec3_t point;
00422 Com_Parse1DMatrix( text, 3, point );
00423 addPoint(point.x, point.y, point.z);
00424 } while (1);
00425
00426
00427
00428 dirty = true;
00429 }
00430
00431 void idSplineList::write(fileHandle_t file, const char *p) {
00432 idStr s = va("\t\t%s {\n", p);
00433 FS_Write(s.c_str(), s.length(), file);
00434
00435
00436 s = va("\t\t\tgranularity %f\n", granularity);
00437 FS_Write(s.c_str(), s.length(), file);
00438 int count = controlPoints.Num();
00439 for (int i = 0; i < count; i++) {
00440 s = va("\t\t\t( %f %f %f )\n", controlPoints[i]->x, controlPoints[i]->y, controlPoints[i]->z);
00441 FS_Write(s.c_str(), s.length(), file);
00442 }
00443 s = "\t\t}\n";
00444 FS_Write(s.c_str(), s.length(), file);
00445 }
00446
00447
00448 void idCameraDef::getActiveSegmentInfo(int segment, idVec3_t &origin, idVec3_t &direction, float *fov) {
00449 #if 0
00450 if (!cameraSpline.validTime()) {
00451 buildCamera();
00452 }
00453 double d = (double)segment / numSegments();
00454 getCameraInfo(d * totalTime * 1000, origin, direction, fov);
00455 #endif
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 }
00483
00484 bool idCameraDef::getCameraInfo(long time, idVec3_t &origin, idVec3_t &direction, float *fv) {
00485
00486
00487 if ((time - startTime) / 1000 > totalTime) {
00488 return false;
00489 }
00490
00491
00492 for (int i = 0; i < events.Num(); i++) {
00493 if (time >= startTime + events[i]->getTime() && !events[i]->getTriggered()) {
00494 events[i]->setTriggered(true);
00495 if (events[i]->getType() == idCameraEvent::EVENT_TARGET) {
00496 setActiveTargetByName(events[i]->getParam());
00497 getActiveTarget()->start(startTime + events[i]->getTime());
00498
00499 } else if (events[i]->getType() == idCameraEvent::EVENT_TRIGGER) {
00500
00501
00502
00503
00504
00505
00506 } else if (events[i]->getType() == idCameraEvent::EVENT_FOV) {
00507
00508 } else if (events[i]->getType() == idCameraEvent::EVENT_STOP) {
00509 return false;
00510 }
00511 }
00512 }
00513
00514 origin = *cameraPosition->getPosition(time);
00515
00516 *fv = fov.getFOV(time);
00517
00518 idVec3_t temp = origin;
00519
00520 int numTargets = targetPositions.Num();
00521 if (numTargets == 0) {
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 } else {
00535 temp = *getActiveTarget()->getPosition(time);
00536 }
00537
00538 temp -= origin;
00539 temp.Normalize();
00540 direction = temp;
00541
00542 return true;
00543 }
00544
00545 bool idCameraDef::waitEvent(int index) {
00546
00547
00548
00549
00550
00551 return false;
00552 }
00553
00554
00555 #define NUM_CCELERATION_SEGS 10
00556 #define CELL_AMT 5
00557
00558 void idCameraDef::buildCamera() {
00559 int i;
00560
00561 idList<float> waits;
00562 idList<int> targets;
00563
00564 totalTime = baseTime;
00565 cameraPosition->setTime(totalTime * 1000);
00566
00567
00568 for (i = 0; i < events.Num(); i++) {
00569
00570 events[i]->setTriggered(false);
00571 switch (events[i]->getType()) {
00572 case idCameraEvent::EVENT_TARGET : {
00573 targets.Append(i);
00574 break;
00575 }
00576 case idCameraEvent::EVENT_WAIT : {
00577 waits.Append(atof(events[i]->getParam()));
00578 cameraPosition->addVelocity(events[i]->getTime(), atof(events[i]->getParam()) * 1000, 0);
00579 break;
00580 }
00581 case idCameraEvent::EVENT_TARGETWAIT : {
00582
00583 break;
00584 }
00585 case idCameraEvent::EVENT_SPEED : {
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616 }
00617 default: break;
00618 }
00619 }
00620
00621
00622 for (i = 0; i < waits.Num(); i++) {
00623 totalTime += waits[i];
00624 }
00625
00626
00627
00628 long timeSoFar = 0;
00629 long total = (int)(totalTime * 1000);
00630 for (i = 0; i < targets.Num(); i++) {
00631 long t;
00632 if (i < targets.Num() - 1) {
00633 t = events[targets[i+1]]->getTime();
00634 } else {
00635 t = total - timeSoFar;
00636 }
00637
00638 setActiveTargetByName(events[targets[i]]->getParam());
00639 getActiveTarget()->setTime(t);
00640 timeSoFar += t;
00641 }
00642
00643
00644 }
00645
00646 void idCameraDef::startCamera(long t) {
00647 buildCamera();
00648 cameraPosition->start(t);
00649
00650
00651
00652 startTime = t;
00653 cameraRunning = true;
00654 }
00655
00656
00657 void idCameraDef::parse(const char *(*text) ) {
00658
00659 const char *token;
00660 do {
00661 token = Com_Parse( text );
00662
00663 if ( !token[0] ) {
00664 break;
00665 }
00666 if ( !Q_stricmp (token, "}") ) {
00667 break;
00668 }
00669
00670 if (Q_stricmp(token, "time") == 0) {
00671 baseTime = Com_ParseFloat(text);
00672 }
00673
00674 if (Q_stricmp(token, "camera_fixed") == 0) {
00675 cameraPosition = new idFixedPosition();
00676 cameraPosition->parse(text);
00677 }
00678
00679 if (Q_stricmp(token, "camera_interpolated") == 0) {
00680 cameraPosition = new idInterpolatedPosition();
00681 cameraPosition->parse(text);
00682 }
00683
00684 if (Q_stricmp(token, "camera_spline") == 0) {
00685 cameraPosition = new idSplinePosition();
00686 cameraPosition->parse(text);
00687 }
00688
00689 if (Q_stricmp(token, "target_fixed") == 0) {
00690 idFixedPosition *pos = new idFixedPosition();
00691 pos->parse(text);
00692 targetPositions.Append(pos);
00693 }
00694
00695 if (Q_stricmp(token, "target_interpolated") == 0) {
00696 idInterpolatedPosition *pos = new idInterpolatedPosition();
00697 pos->parse(text);
00698 targetPositions.Append(pos);
00699 }
00700
00701 if (Q_stricmp(token, "target_spline") == 0) {
00702 idSplinePosition *pos = new idSplinePosition();
00703 pos->parse(text);
00704 targetPositions.Append(pos);
00705 }
00706
00707 if (Q_stricmp(token, "fov") == 0) {
00708 fov.parse(text);
00709 }
00710
00711 if (Q_stricmp(token, "event") == 0) {
00712 idCameraEvent *event = new idCameraEvent();
00713 event->parse(text);
00714 addEvent(event);
00715 }
00716
00717
00718 } while (1);
00719
00720 Com_UngetToken();
00721 Com_MatchToken( text, "}" );
00722
00723 }
00724
00725 qboolean idCameraDef::load(const char *filename) {
00726 char *buf;
00727 const char *buf_p;
00728
00729 FS_ReadFile( filename, (void **)&buf );
00730 if ( !buf ) {
00731 return qfalse;
00732 }
00733
00734 clear();
00735 Com_BeginParseSession( filename );
00736 buf_p = buf;
00737 parse(&buf_p);
00738 Com_EndParseSession();
00739 FS_FreeFile( buf );
00740
00741 return qtrue;
00742 }
00743
00744 void idCameraDef::save(const char *filename) {
00745 fileHandle_t file = FS_FOpenFileWrite(filename);
00746 if (file) {
00747 int i;
00748 idStr s = "cameraPathDef { \n";
00749 FS_Write(s.c_str(), s.length(), file);
00750 s = va("\ttime %f\n", baseTime);
00751 FS_Write(s.c_str(), s.length(), file);
00752
00753 cameraPosition->write(file, va("camera_%s",cameraPosition->typeStr()));
00754
00755 for (i = 0; i < numTargets(); i++) {
00756 targetPositions[i]->write(file, va("target_%s", targetPositions[i]->typeStr()));
00757 }
00758
00759 for (i = 0; i < events.Num(); i++) {
00760 events[i]->write(file, "event");
00761 }
00762
00763 fov.write(file, "fov");
00764
00765 s = "}\n";
00766 FS_Write(s.c_str(), s.length(), file);
00767 }
00768 FS_FCloseFile(file);
00769 }
00770
00771 int idCameraDef::sortEvents(const void *p1, const void *p2) {
00772 idCameraEvent *ev1 = (idCameraEvent*)(p1);
00773 idCameraEvent *ev2 = (idCameraEvent*)(p2);
00774
00775 if (ev1->getTime() > ev2->getTime()) {
00776 return -1;
00777 }
00778 if (ev1->getTime() < ev2->getTime()) {
00779 return 1;
00780 }
00781 return 0;
00782 }
00783
00784 void idCameraDef::addEvent(idCameraEvent *event) {
00785 events.Append(event);
00786
00787
00788 }
00789 void idCameraDef::addEvent(idCameraEvent::eventType t, const char *param, long time) {
00790 addEvent(new idCameraEvent(t, param, time));
00791 buildCamera();
00792 }
00793
00794
00795 const char *idCameraEvent::eventStr[] = {
00796 "NA",
00797 "WAIT",
00798 "TARGETWAIT",
00799 "SPEED",
00800 "TARGET",
00801 "SNAPTARGET",
00802 "FOV",
00803 "SCRIPT",
00804 "TRIGGER",
00805 "STOP"
00806 };
00807
00808 void idCameraEvent::parse(const char *(*text) ) {
00809 const char *token;
00810 Com_MatchToken( text, "{" );
00811 do {
00812 token = Com_Parse( text );
00813
00814 if ( !token[0] ) {
00815 break;
00816 }
00817 if ( !strcmp (token, "}") ) {
00818 break;
00819 }
00820
00821
00822 do {
00823
00824 if ( !token[0] || !strcmp (token, "(") || !strcmp(token, "}")) {
00825 break;
00826 }
00827
00828 Com_UngetToken();
00829 idStr key = Com_ParseOnLine(text);
00830 const char *token = Com_Parse(text);
00831 if (Q_stricmp(key.c_str(), "type") == 0) {
00832 type = static_cast<idCameraEvent::eventType>(atoi(token));
00833 } else if (Q_stricmp(key.c_str(), "param") == 0) {
00834 paramStr = token;
00835 } else if (Q_stricmp(key.c_str(), "time") == 0) {
00836 time = atoi(token);
00837 }
00838 token = Com_Parse(text);
00839
00840 } while (1);
00841
00842 if ( !strcmp (token, "}") ) {
00843 break;
00844 }
00845
00846 } while (1);
00847
00848 Com_UngetToken();
00849 Com_MatchToken( text, "}" );
00850 }
00851
00852 void idCameraEvent::write(fileHandle_t file, const char *name) {
00853 idStr s = va("\t%s {\n", name);
00854 FS_Write(s.c_str(), s.length(), file);
00855 s = va("\t\ttype %d\n", static_cast<int>(type));
00856 FS_Write(s.c_str(), s.length(), file);
00857 s = va("\t\tparam %s\n", paramStr.c_str());
00858 FS_Write(s.c_str(), s.length(), file);
00859 s = va("\t\ttime %d\n", time);
00860 FS_Write(s.c_str(), s.length(), file);
00861 s = "\t}\n";
00862 FS_Write(s.c_str(), s.length(), file);
00863 }
00864
00865
00866 const char *idCameraPosition::positionStr[] = {
00867 "Fixed",
00868 "Interpolated",
00869 "Spline",
00870 };
00871
00872
00873
00874 const idVec3_t *idInterpolatedPosition::getPosition(long t) {
00875 static idVec3_t interpolatedPos;
00876
00877 float velocity = getVelocity(t);
00878 float timePassed = t - lastTime;
00879 lastTime = t;
00880
00881
00882 timePassed /= 1000;
00883
00884 float distToTravel = timePassed *= velocity;
00885
00886 idVec3_t temp = startPos;
00887 temp -= endPos;
00888 float distance = temp.Length();
00889
00890 distSoFar += distToTravel;
00891 float percent = (float)(distSoFar) / distance;
00892
00893 if (percent > 1.0) {
00894 percent = 1.0;
00895 } else if (percent < 0.0) {
00896 percent = 0.0;
00897 }
00898
00899
00900
00901
00902 idVec3_t v1 = startPos;
00903 idVec3_t v2 = endPos;
00904 v1 *= (1.0 - percent);
00905 v2 *= percent;
00906 v1 += v2;
00907 interpolatedPos = v1;
00908 return &interpolatedPos;
00909 }
00910
00911
00912 void idCameraFOV::parse(const char *(*text) ) {
00913 const char *token;
00914 Com_MatchToken( text, "{" );
00915 do {
00916 token = Com_Parse( text );
00917
00918 if ( !token[0] ) {
00919 break;
00920 }
00921 if ( !strcmp (token, "}") ) {
00922 break;
00923 }
00924
00925
00926 do {
00927
00928 if ( !token[0] || !strcmp (token, "(") || !strcmp(token, "}")) {
00929 break;
00930 }
00931
00932 Com_UngetToken();
00933 idStr key = Com_ParseOnLine(text);
00934 const char *token = Com_Parse(text);
00935 if (Q_stricmp(key.c_str(), "fov") == 0) {
00936 fov = atof(token);
00937 } else if (Q_stricmp(key.c_str(), "startFOV") == 0) {
00938 startFOV = atof(token);
00939 } else if (Q_stricmp(key.c_str(), "endFOV") == 0) {
00940 endFOV = atof(token);
00941 } else if (Q_stricmp(key.c_str(), "time") == 0) {
00942 time = atoi(token);
00943 }
00944 token = Com_Parse(text);
00945
00946 } while (1);
00947
00948 if ( !strcmp (token, "}") ) {
00949 break;
00950 }
00951
00952 } while (1);
00953
00954 Com_UngetToken();
00955 Com_MatchToken( text, "}" );
00956 }
00957
00958 bool idCameraPosition::parseToken(const char *key, const char *(*text)) {
00959 const char *token = Com_Parse(text);
00960 if (Q_stricmp(key, "time") == 0) {
00961 time = atol(token);
00962 return true;
00963 } else if (Q_stricmp(key, "type") == 0) {
00964 type = static_cast<idCameraPosition::positionType>(atoi(token));
00965 return true;
00966 } else if (Q_stricmp(key, "velocity") == 0) {
00967 long t = atol(token);
00968 token = Com_Parse(text);
00969 long d = atol(token);
00970 token = Com_Parse(text);
00971 float s = atof(token);
00972 addVelocity(t, d, s);
00973 return true;
00974 } else if (Q_stricmp(key, "baseVelocity") == 0) {
00975 baseVelocity = atof(token);
00976 return true;
00977 } else if (Q_stricmp(key, "name") == 0) {
00978 name = token;
00979 return true;
00980 } else if (Q_stricmp(key, "time") == 0) {
00981 time = atoi(token);
00982 return true;
00983 }
00984 Com_UngetToken();
00985 return false;
00986 }
00987
00988
00989
00990 void idFixedPosition::parse(const char *(*text) ) {
00991 const char *token;
00992 Com_MatchToken( text, "{" );
00993 do {
00994 token = Com_Parse( text );
00995
00996 if ( !token[0] ) {
00997 break;
00998 }
00999 if ( !strcmp (token, "}") ) {
01000 break;
01001 }
01002
01003
01004 do {
01005
01006 if ( !token[0] || !strcmp (token, "(") || !strcmp(token, "}")) {
01007 break;
01008 }
01009
01010 Com_UngetToken();
01011 idStr key = Com_ParseOnLine(text);
01012
01013 const char *token = Com_Parse(text);
01014 if (Q_stricmp(key.c_str(), "pos") == 0) {
01015 Com_UngetToken();
01016 Com_Parse1DMatrix( text, 3, pos );
01017 } else {
01018 Com_UngetToken();
01019 idCameraPosition::parseToken(key.c_str(), text);
01020 }
01021 token = Com_Parse(text);
01022
01023 } while (1);
01024
01025 if ( !strcmp (token, "}") ) {
01026 break;
01027 }
01028
01029 } while (1);
01030
01031 Com_UngetToken();
01032 Com_MatchToken( text, "}" );
01033 }
01034
01035 void idInterpolatedPosition::parse(const char *(*text) ) {
01036 const char *token;
01037 Com_MatchToken( text, "{" );
01038 do {
01039 token = Com_Parse( text );
01040
01041 if ( !token[0] ) {
01042 break;
01043 }
01044 if ( !strcmp (token, "}") ) {
01045 break;
01046 }
01047
01048
01049 do {
01050
01051 if ( !token[0] || !strcmp (token, "(") || !strcmp(token, "}")) {
01052 break;
01053 }
01054
01055 Com_UngetToken();
01056 idStr key = Com_ParseOnLine(text);
01057
01058 const char *token = Com_Parse(text);
01059 if (Q_stricmp(key.c_str(), "startPos") == 0) {
01060 Com_UngetToken();
01061 Com_Parse1DMatrix( text, 3, startPos );
01062 } else if (Q_stricmp(key.c_str(), "endPos") == 0) {
01063 Com_UngetToken();
01064 Com_Parse1DMatrix( text, 3, endPos );
01065 } else {
01066 Com_UngetToken();
01067 idCameraPosition::parseToken(key.c_str(), text);
01068 }
01069 token = Com_Parse(text);
01070
01071 } while (1);
01072
01073 if ( !strcmp (token, "}") ) {
01074 break;
01075 }
01076
01077 } while (1);
01078
01079 Com_UngetToken();
01080 Com_MatchToken( text, "}" );
01081 }
01082
01083
01084 void idSplinePosition::parse(const char *(*text) ) {
01085 const char *token;
01086 Com_MatchToken( text, "{" );
01087 do {
01088 token = Com_Parse( text );
01089
01090 if ( !token[0] ) {
01091 break;
01092 }
01093 if ( !strcmp (token, "}") ) {
01094 break;
01095 }
01096
01097
01098 do {
01099
01100 if ( !token[0] || !strcmp (token, "(") || !strcmp(token, "}")) {
01101 break;
01102 }
01103
01104 Com_UngetToken();
01105 idStr key = Com_ParseOnLine(text);
01106
01107 const char *token = Com_Parse(text);
01108 if (Q_stricmp(key.c_str(), "target") == 0) {
01109 target.parse(text);
01110 } else {
01111 Com_UngetToken();
01112 idCameraPosition::parseToken(key.c_str(), text);
01113 }
01114 token = Com_Parse(text);
01115
01116 } while (1);
01117
01118 if ( !strcmp (token, "}") ) {
01119 break;
01120 }
01121
01122 } while (1);
01123
01124 Com_UngetToken();
01125 Com_MatchToken( text, "}" );
01126 }
01127
01128
01129
01130 void idCameraFOV::write(fileHandle_t file, const char *p) {
01131 idStr s = va("\t%s {\n", p);
01132 FS_Write(s.c_str(), s.length(), file);
01133
01134 s = va("\t\tfov %f\n", fov);
01135 FS_Write(s.c_str(), s.length(), file);
01136
01137 s = va("\t\tstartFOV %f\n", startFOV);
01138 FS_Write(s.c_str(), s.length(), file);
01139
01140 s = va("\t\tendFOV %f\n", endFOV);
01141 FS_Write(s.c_str(), s.length(), file);
01142
01143 s = va("\t\ttime %i\n", time);
01144 FS_Write(s.c_str(), s.length(), file);
01145
01146 s = "\t}\n";
01147 FS_Write(s.c_str(), s.length(), file);
01148 }
01149
01150
01151 void idCameraPosition::write(fileHandle_t file, const char *p) {
01152
01153 idStr s = va("\t\ttime %i\n", time);
01154 FS_Write(s.c_str(), s.length(), file);
01155
01156 s = va("\t\ttype %i\n", static_cast<int>(type));
01157 FS_Write(s.c_str(), s.length(), file);
01158
01159 s = va("\t\tname %s\n", name.c_str());
01160 FS_Write(s.c_str(), s.length(), file);
01161
01162 s = va("\t\tbaseVelocity %f\n", baseVelocity);
01163 FS_Write(s.c_str(), s.length(), file);
01164
01165 for (int i = 0; i < velocities.Num(); i++) {
01166 s = va("\t\tvelocity %i %i %f\n", velocities[i]->startTime, velocities[i]->time, velocities[i]->speed);
01167 FS_Write(s.c_str(), s.length(), file);
01168 }
01169
01170 }
01171
01172 void idFixedPosition::write(fileHandle_t file, const char *p) {
01173 idStr s = va("\t%s {\n", p);
01174 FS_Write(s.c_str(), s.length(), file);
01175 idCameraPosition::write(file, p);
01176 s = va("\t\tpos ( %f %f %f )\n", pos.x, pos.y, pos.z);
01177 FS_Write(s.c_str(), s.length(), file);
01178 s = "\t}\n";
01179 FS_Write(s.c_str(), s.length(), file);
01180 }
01181
01182 void idInterpolatedPosition::write(fileHandle_t file, const char *p) {
01183 idStr s = va("\t%s {\n", p);
01184 FS_Write(s.c_str(), s.length(), file);
01185 idCameraPosition::write(file, p);
01186 s = va("\t\tstartPos ( %f %f %f )\n", startPos.x, startPos.y, startPos.z);
01187 FS_Write(s.c_str(), s.length(), file);
01188 s = va("\t\tendPos ( %f %f %f )\n", endPos.x, endPos.y, endPos.z);
01189 FS_Write(s.c_str(), s.length(), file);
01190 s = "\t}\n";
01191 FS_Write(s.c_str(), s.length(), file);
01192 }
01193
01194 void idSplinePosition::write(fileHandle_t file, const char *p) {
01195 idStr s = va("\t%s {\n", p);
01196 FS_Write(s.c_str(), s.length(), file);
01197 idCameraPosition::write(file, p);
01198 target.write(file, "target");
01199 s = "\t}\n";
01200 FS_Write(s.c_str(), s.length(), file);
01201 }
01202
01203 void idCameraDef::addTarget(const char *name, idCameraPosition::positionType type) {
01204
01205 idCameraPosition *pos = newFromType(type);
01206 if (pos) {
01207 pos->setName(name);
01208 targetPositions.Append(pos);
01209 activeTarget = numTargets()-1;
01210 if (activeTarget == 0) {
01211
01212 addEvent(idCameraEvent::EVENT_TARGET, name, 0);
01213 }
01214 }
01215 }
01216
01217
01218
01219 idCameraDef camera;
01220
01221 extern "C" {
01222 qboolean loadCamera(const char *name) {
01223 camera.clear();
01224 return static_cast<qboolean>(camera.load(name));
01225 }
01226
01227 qboolean getCameraInfo(int time, float *origin, float*angles) {
01228 idVec3_t dir, org;
01229 org[0] = origin[0];
01230 org[1] = origin[1];
01231 org[2] =