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