splines.h (20759B)
1 /* 2 =========================================================================== 3 Copyright (C) 1999-2005 Id Software, Inc. 4 5 This file is part of Quake III Arena source code. 6 7 Quake III Arena source code is free software; you can redistribute it 8 and/or modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 2 of the License, 10 or (at your option) any later version. 11 12 Quake III Arena source code is distributed in the hope that it will be 13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with Foobar; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 =========================================================================== 21 */ 22 #ifndef __SPLINES_H 23 #define __SPLINES_H 24 25 extern "C" { 26 #ifdef Q3RADIANT 27 #include "../qgl.h" 28 #else 29 //#include "../renderer/qgl.h" 30 #endif 31 } 32 #include "util_list.h" 33 #include "util_str.h" 34 #include "math_vector.h" 35 36 typedef int fileHandle_t; 37 38 //extern void glBox(idVec3_t &color, idVec3_t &point, float size); 39 //extern void glLabeledPoint(idVec3_t &color, idVec3_t &point, float size, const char *label); 40 41 static vec4_t blue(0, 0, 1, 1); 42 static vec4_t red(1, 0, 0, 1); 43 44 class idPointListInterface { 45 public: 46 idPointListInterface() { 47 selectedPoints.Clear(); 48 } 49 virtual ~idPointListInterface() {} 50 51 virtual int numPoints() { 52 return 0; 53 } 54 55 virtual void addPoint(const float x, const float y, const float z) {} 56 virtual void addPoint(const idVec3_t &v) {} 57 virtual void removePoint(int index) {} 58 virtual idVec3_t *getPoint(int index) { return NULL; } 59 60 int selectPointByRay(float ox, float oy, float oz, float dx, float dy, float dz, bool single) { 61 idVec3_t origin(ox, oy, oz); 62 idVec3_t dir(dx, dy, dz); 63 return selectPointByRay(origin, dir, single); 64 } 65 66 int selectPointByRay(const idVec3_t origin, const idVec3_t direction, bool single) { 67 int i, besti, count; 68 float d, bestd; 69 idVec3_t temp, temp2; 70 71 // find the point closest to the ray 72 besti = -1; 73 bestd = 8; 74 count = numPoints(); 75 76 for (i=0; i < count; i++) { 77 temp = *getPoint(i); 78 temp2 = temp; 79 temp -= origin; 80 d = DotProduct(temp, direction); 81 __VectorMA (origin, d, direction, temp); 82 temp2 -= temp; 83 d = temp2.Length(); 84 if (d <= bestd) { 85 bestd = d; 86 besti = i; 87 } 88 } 89 90 if (besti >= 0) { 91 selectPoint(besti, single); 92 } 93 94 return besti; 95 } 96 97 int isPointSelected(int index) { 98 int count = selectedPoints.Num(); 99 for (int i = 0; i < count; i++) { 100 if (selectedPoints[i] == index) { 101 return i; 102 } 103 } 104 return -1; 105 } 106 107 int selectPoint(int index, bool single) { 108 if (index >= 0 && index < numPoints()) { 109 if (single) { 110 deselectAll(); 111 } else { 112 if (isPointSelected(index) >= 0) { 113 selectedPoints.Remove(index); 114 } 115 } 116 return selectedPoints.Append(index); 117 } 118 return -1; 119 } 120 121 void selectAll() { 122 selectedPoints.Clear(); 123 for (int i = 0; i < numPoints(); i++) { 124 selectedPoints.Append(i); 125 } 126 } 127 128 void deselectAll() { 129 selectedPoints.Clear(); 130 } 131 132 virtual void updateSelection(float x, float y, float z) { 133 idVec3_t move(x, y, z); 134 updateSelection(move); 135 } 136 137 virtual void updateSelection(const idVec3_t &move) { 138 int count = selectedPoints.Num(); 139 for (int i = 0; i < count; i++) { 140 *getPoint(selectedPoints[i]) += move; 141 } 142 } 143 /* 144 void drawSelection() { 145 int count = selectedPoints.Num(); 146 for (int i = 0; i < count; i++) { 147 glBox(red, *getPoint(selectedPoints[i]), 4); 148 } 149 } 150 */ 151 protected: 152 idList<int> selectedPoints; 153 154 }; 155 156 157 class idSplineList { 158 159 public: 160 161 idSplineList() { 162 clear(); 163 } 164 165 idSplineList(const char *p) { 166 clear(); 167 name = p; 168 }; 169 170 ~idSplineList() { 171 clear(); 172 }; 173 174 void clearControl() { 175 for (int i = 0; i < controlPoints.Num(); i++) { 176 delete controlPoints[i]; 177 } 178 controlPoints.Clear(); 179 } 180 181 void clearSpline() { 182 for (int i = 0; i < splinePoints.Num(); i++) { 183 delete splinePoints[i]; 184 } 185 splinePoints.Clear(); 186 } 187 188 void parse(const char *(*text)); 189 void write(fileHandle_t file, const char *name); 190 191 void clear() { 192 clearControl(); 193 clearSpline(); 194 splineTime.Clear(); 195 selected = NULL; 196 dirty = true; 197 activeSegment = 0; 198 granularity = 0.025; 199 pathColor.set(1.0, 0.5, 0.0); 200 controlColor.set(0.7, 0.0, 1.0); 201 segmentColor.set(0.0, 0.0, 1.0); 202 activeColor.set(1.0, 0.0, 0.0); 203 } 204 205 void initPosition(long startTime, long totalTime); 206 const idVec3_t *getPosition(long time); 207 208 209 // void draw(bool editMode); 210 void addToRenderer(); 211 212 void setSelectedPoint(idVec3_t *p); 213 idVec3_t *getSelectedPoint() { 214 return selected; 215 } 216 217 void addPoint(const idVec3_t &v) { 218 controlPoints.Append(new idVec3_t(v)); 219 dirty = true; 220 } 221 222 void addPoint(float x, float y, float z) { 223 controlPoints.Append(new idVec3_t(x, y, z)); 224 dirty = true; 225 } 226 227 void updateSelection(const idVec3_t &move); 228 229 void startEdit() { 230 editMode = true; 231 } 232 233 void stopEdit() { 234 editMode = false; 235 } 236 237 void buildSpline(); 238 239 void setGranularity(float f) { 240 granularity = f; 241 } 242 243 float getGranularity() { 244 return granularity; 245 } 246 247 int numPoints() { 248 return controlPoints.Num(); 249 } 250 251 idVec3_t *getPoint(int index) { 252 assert(index >= 0 && index < controlPoints.Num()); 253 return controlPoints[index]; 254 } 255 256 idVec3_t *getSegmentPoint(int index) { 257 assert(index >= 0 && index < splinePoints.Num()); 258 return splinePoints[index]; 259 } 260 261 262 void setSegmentTime(int index, int time) { 263 assert(index >= 0 && index < splinePoints.Num()); 264 splineTime[index] = time; 265 } 266 267 double getSegmentTime(int index) { 268 assert(index >= 0 && index < splinePoints.Num()); 269 return splineTime[index]; 270 } 271 void addSegmentTime(int index, int time) { 272 assert(index >= 0 && index < splinePoints.Num()); 273 splineTime[index] += time; 274 } 275 276 float totalDistance(); 277 278 static idVec3_t zero; 279 280 int getActiveSegment() { 281 return activeSegment; 282 } 283 284 void setActiveSegment(int i) { 285 //assert(i >= 0 && (splinePoints.Num() > 0 && i < splinePoints.Num())); 286 activeSegment = i; 287 } 288 289 int numSegments() { 290 return splinePoints.Num(); 291 } 292 293 void setColors(idVec3_t &path, idVec3_t &segment, idVec3_t &control, idVec3_t &active) { 294 pathColor = path; 295 segmentColor = segment; 296 controlColor = control; 297 activeColor = active; 298 } 299 300 const char *getName() { 301 return name.c_str(); 302 } 303 304 void setName(const char *p) { 305 name = p; 306 } 307 308 bool validTime() { 309 if (dirty) { 310 buildSpline(); 311 } 312 // gcc doesn't allow static casting away from bools 313 // why? I've no idea... 314 return (bool)(splineTime.Num() > 0 && splineTime.Num() == splinePoints.Num()); 315 } 316 317 void setTime(long t) { 318 time = t; 319 } 320 321 void setBaseTime(long t) { 322 baseTime = t; 323 } 324 325 protected: 326 idStr name; 327 float calcSpline(int step, float tension); 328 idList<idVec3_t*> controlPoints; 329 idList<idVec3_t*> splinePoints; 330 idList<double> splineTime; 331 idVec3_t *selected; 332 idVec3_t pathColor, segmentColor, controlColor, activeColor; 333 float granularity; 334 bool editMode; 335 bool dirty; 336 int activeSegment; 337 long baseTime; 338 long time; 339 friend class idCamera; 340 }; 341 342 // time in milliseconds 343 // velocity where 1.0 equal rough walking speed 344 struct idVelocity { 345 idVelocity(long start, long duration, float s) { 346 startTime = start; 347 time = duration; 348 speed = s; 349 } 350 long startTime; 351 long time; 352 float speed; 353 }; 354 355 // can either be a look at or origin position for a camera 356 // 357 class idCameraPosition : public idPointListInterface { 358 public: 359 360 virtual void clear() { 361 editMode = false; 362 for (int i = 0; i < velocities.Num(); i++) { 363 delete velocities[i]; 364 velocities[i] = NULL; 365 } 366 velocities.Clear(); 367 } 368 369 idCameraPosition(const char *p) { 370 name = p; 371 } 372 373 idCameraPosition() { 374 time = 0; 375 name = "position"; 376 } 377 378 idCameraPosition(long t) { 379 time = t; 380 } 381 382 virtual ~idCameraPosition() { 383 clear(); 384 } 385 386 387 // this can be done with RTTI syntax but i like the derived classes setting a type 388 // makes serialization a bit easier to see 389 // 390 enum positionType { 391 FIXED = 0x00, 392 INTERPOLATED, 393 SPLINE, 394 POSITION_COUNT 395 }; 396 397 398 virtual void start(long t) { 399 startTime = t; 400 } 401 402 long getTime() { 403 return time; 404 } 405 406 virtual void setTime(long t) { 407 time = t; 408 } 409 410 float getVelocity(long t) { 411 long check = t - startTime; 412 for (int i = 0; i < velocities.Num(); i++) { 413 if (check >= velocities[i]->startTime && check <= velocities[i]->startTime + velocities[i]->time) { 414 return velocities[i]->speed; 415 } 416 } 417 return baseVelocity; 418 } 419 420 void addVelocity(long start, long duration, float speed) { 421 velocities.Append(new idVelocity(start, duration, speed)); 422 } 423 424 virtual const idVec3_t *getPosition(long t) { 425 assert(true); 426 return NULL; 427 } 428 429 // virtual void draw(bool editMode) {}; 430 431 virtual void parse(const char *(*text)) {}; 432 virtual void write(fileHandle_t file, const char *name); 433 virtual bool parseToken(const char *key, const char *(*text)); 434 435 const char *getName() { 436 return name.c_str(); 437 } 438 439 void setName(const char *p) { 440 name = p; 441 } 442 443 virtual void startEdit() { 444 editMode = true; 445 } 446 447 virtual void stopEdit() { 448 editMode = false; 449 } 450 451 // virtual void draw() {}; 452 453 const char *typeStr() { 454 return positionStr[static_cast<int>(type)]; 455 } 456 457 void calcVelocity(float distance) { 458 float secs = (float)time / 1000; 459 baseVelocity = distance / secs; 460 } 461 462 protected: 463 static const char* positionStr[POSITION_COUNT]; 464 long startTime; 465 long time; 466 idCameraPosition::positionType type; 467 idStr name; 468 bool editMode; 469 idList<idVelocity*> velocities; 470 float baseVelocity; 471 }; 472 473 class idFixedPosition : public idCameraPosition { 474 public: 475 476 void init() { 477 pos.Zero(); 478 type = idCameraPosition::FIXED; 479 } 480 481 idFixedPosition() : idCameraPosition() { 482 init(); 483 } 484 485 idFixedPosition(idVec3_t p) : idCameraPosition() { 486 init(); 487 pos = p; 488 } 489 490 virtual void addPoint(const idVec3_t &v) { 491 pos = v; 492 } 493 494 virtual void addPoint(const float x, const float y, const float z) { 495 pos.set(x, y, z); 496 } 497 498 499 ~idFixedPosition() { 500 } 501 502 virtual const idVec3_t *getPosition(long t) { 503 return &pos; 504 } 505 506 void parse(const char *(*text)); 507 void write(fileHandle_t file, const char *name); 508 509 virtual int numPoints() { 510 return 1; 511 } 512 513 virtual idVec3_t *getPoint(int index) { 514 if (index != 0) { 515 assert(true); 516 }; 517 return &pos; 518 } 519 /* 520 virtual void draw(bool editMode) { 521 glLabeledPoint(blue, pos, (editMode) ? 5 : 3, "Fixed point"); 522 } 523 */ 524 protected: 525 idVec3_t pos; 526 }; 527 528 class idInterpolatedPosition : public idCameraPosition { 529 public: 530 531 void init() { 532 type = idCameraPosition::INTERPOLATED; 533 first = true; 534 startPos.Zero(); 535 endPos.Zero(); 536 } 537 538 idInterpolatedPosition() : idCameraPosition() { 539 init(); 540 } 541 542 idInterpolatedPosition(idVec3_t start, idVec3_t end, long time) : idCameraPosition(time) { 543 init(); 544 startPos = start; 545 endPos = end; 546 } 547 548 ~idInterpolatedPosition() { 549 } 550 551 virtual const idVec3_t *getPosition(long t); 552 553 void parse(const char *(*text)); 554 void write(fileHandle_t file, const char *name); 555 556 virtual int numPoints() { 557 return 2; 558 } 559 560 virtual idVec3_t *getPoint(int index) { 561 assert(index >= 0 && index < 2); 562 if (index == 0) { 563 return &startPos; 564 } 565 return &endPos; 566 } 567 568 virtual void addPoint(const float x, const float y, const float z) { 569 if (first) { 570 startPos.set(x, y, z); 571 first = false; 572 } else { 573 endPos.set(x, y, z); 574 first = true; 575 } 576 } 577 578 virtual void addPoint(const idVec3_t &v) { 579 if (first) { 580 startPos = v; 581 first = false; 582 } else { 583 endPos = v; 584 first = true; 585 } 586 } 587 /* 588 virtual void draw(bool editMode) { 589 glLabeledPoint(blue, startPos, (editMode) ? 5 : 3, "Start interpolated"); 590 glLabeledPoint(blue, endPos, (editMode) ? 5 : 3, "End interpolated"); 591 qglBegin(GL_LINES); 592 qglVertex3fv(startPos); 593 qglVertex3fv(endPos); 594 qglEnd(); 595 } 596 */ 597 virtual void start(long t) { 598 idCameraPosition::start(t); 599 lastTime = startTime; 600 distSoFar = 0.0; 601 idVec3_t temp = startPos; 602 temp -= endPos; 603 calcVelocity(temp.Length()); 604 } 605 606 protected: 607 bool first; 608 idVec3_t startPos; 609 idVec3_t endPos; 610 long lastTime; 611 float distSoFar; 612 }; 613 614 class idSplinePosition : public idCameraPosition { 615 public: 616 617 void init() { 618 type = idCameraPosition::SPLINE; 619 } 620 621 idSplinePosition() : idCameraPosition() { 622 init(); 623 } 624 625 idSplinePosition(long time) : idCameraPosition(time) { 626 init(); 627 } 628 629 ~idSplinePosition() { 630 } 631 632 virtual void start(long t) { 633 idCameraPosition::start(t); 634 target.initPosition(t, time); 635 calcVelocity(target.totalDistance()); 636 } 637 638 virtual const idVec3_t *getPosition(long t) { 639 return target.getPosition(t); 640 } 641 642 //virtual const idVec3_t *getPosition(long t) const { 643 644 void addControlPoint(idVec3_t &v) { 645 target.addPoint(v); 646 } 647 648 void parse(const char *(*text)); 649 void write(fileHandle_t file, const char *name); 650 651 virtual int numPoints() { 652 return target.numPoints(); 653 } 654 655 virtual idVec3_t *getPoint(int index) { 656 return target.getPoint(index); 657 } 658 659 virtual void addPoint(const idVec3_t &v) { 660 target.addPoint(v); 661 } 662 663 virtual void addPoint(const float x, const float y, const float z) { 664 target.addPoint(x, y, z); 665 } 666 667 /* virtual void draw(bool editMode) { 668 target.draw(editMode); 669 } 670 */ 671 virtual void updateSelection(const idVec3_t &move) { 672 idCameraPosition::updateSelection(move); 673 target.buildSpline(); 674 } 675 676 protected: 677 idSplineList target; 678 }; 679 680 class idCameraFOV { 681 public: 682 683 idCameraFOV() { 684 time = 0; 685 fov = 90; 686 } 687 688 idCameraFOV(int v) { 689 time = 0; 690 fov = v; 691 } 692 693 idCameraFOV(int s, int e, long t) { 694 startFOV = s; 695 endFOV = e; 696 time = t; 697 } 698 699 700 ~idCameraFOV(){} 701 702 void setFOV(float f) { 703 fov = f; 704 } 705 706 float getFOV(long t) { 707 if (time) { 708 assert(startTime); 709 float percent = t / startTime; 710 float temp = startFOV - endFOV; 711 temp *= percent; 712 fov = startFOV + temp; 713 } 714 return fov; 715 } 716 717 void start(long t) { 718 startTime = t; 719 } 720 721 void parse(const char *(*text)); 722 void write(fileHandle_t file, const char *name); 723 724 protected: 725 float fov; 726 float startFOV; 727 float endFOV; 728 int startTime; 729 int time; 730 }; 731 732 733 734 735 class idCameraEvent { 736 public: 737 enum eventType { 738 EVENT_NA = 0x00, 739 EVENT_WAIT, 740 EVENT_TARGETWAIT, 741 EVENT_SPEED, 742 EVENT_TARGET, 743 EVENT_SNAPTARGET, 744 EVENT_FOV, 745 EVENT_SCRIPT, 746 EVENT_TRIGGER, 747 EVENT_STOP, 748 EVENT_COUNT 749 }; 750 751 static const char* eventStr[EVENT_COUNT]; 752 753 idCameraEvent() { 754 paramStr = ""; 755 type = EVENT_NA; 756 time = 0; 757 } 758 759 idCameraEvent(eventType t, const char *param, long n) { 760 type = t; 761 paramStr = param; 762 time = n; 763 } 764 765 ~idCameraEvent() {}; 766 767 eventType getType() { 768 return type; 769 } 770 771 const char *typeStr() { 772 return eventStr[static_cast<int>(type)]; 773 } 774 775 const char *getParam() { 776 return paramStr.c_str(); 777 } 778 779 long getTime() { 780 return time; 781 } 782 783 void setTime(long n) { 784 time = n; 785 } 786 787 void parse(const char *(*text)); 788 void write(fileHandle_t file, const char *name); 789 790 void setTriggered(bool b) { 791 triggered = b; 792 } 793 794 bool getTriggered() { 795 return triggered; 796 } 797 798 protected: 799 eventType type; 800 idStr paramStr; 801 long time; 802 bool triggered; 803 804 }; 805 806 class idCameraDef { 807 public: 808 809 void clear() { 810 currentCameraPosition = 0; 811 cameraRunning = false; 812 lastDirection.Zero(); 813 baseTime = 30; 814 activeTarget = 0; 815 name = "camera01"; 816 fov.setFOV(90); 817 int i; 818 for (i = 0; i < targetPositions.Num(); i++) { 819 delete targetPositions[i]; 820 } 821 for (i = 0; i < events.Num(); i++) { 822 delete events[i]; 823 } 824 delete cameraPosition; 825 cameraPosition = NULL; 826 events.Clear(); 827 targetPositions.Clear(); 828 } 829 830 idCameraPosition *startNewCamera(idCameraPosition::positionType type) { 831 clear(); 832 if (type == idCameraPosition::SPLINE) { 833 cameraPosition = new idSplinePosition(); 834 } else if (type == idCameraPosition::INTERPOLATED) { 835 cameraPosition = new idInterpolatedPosition(); 836 } else { 837 cameraPosition = new idFixedPosition(); 838 } 839 return cameraPosition; 840 } 841 842 idCameraDef() { 843 clear(); 844 } 845 846 ~idCameraDef() { 847 clear(); 848 } 849 850 void addEvent(idCameraEvent::eventType t, const char *param, long time); 851 852 void addEvent(idCameraEvent *event); 853 854 static int sortEvents(const void *p1, const void *p2); 855 856 int numEvents() { 857 return events.Num(); 858 } 859 860 idCameraEvent *getEvent(int index) { 861 assert(index >= 0 && index < events.Num()); 862 return events[index]; 863 } 864 865 void parse(const char *(*text)); 866 qboolean load(const char *filename); 867 void save(const char *filename); 868 869 void buildCamera(); 870 871 //idSplineList *getcameraPosition() { 872 // return &cameraPosition; 873 //} 874 875 static idCameraPosition *newFromType(idCameraPosition::positionType t) { 876 switch (t) { 877 case idCameraPosition::FIXED : return new idFixedPosition(); 878 case idCameraPosition::INTERPOLATED : return new idInterpolatedPosition(); 879 case idCameraPosition::SPLINE : return new idSplinePosition(); 880 default: 881 break; 882 }; 883 return NULL; 884 } 885 886 void addTarget(const char *name, idCameraPosition::positionType type); 887 888 idCameraPosition *getActiveTarget() { 889 if (targetPositions.Num() == 0) { 890 addTarget(NULL, idCameraPosition::FIXED); 891 } 892 return targetPositions[activeTarget]; 893 } 894 895 idCameraPosition *getActiveTarget(int index) { 896 if (targetPositions.Num() == 0) { 897 addTarget(NULL, idCameraPosition::FIXED); 898 return targetPositions[0]; 899 } 900 return targetPositions[index]; 901 } 902 903 int numTargets() { 904 return targetPositions.Num(); 905 } 906 907 908 void setActiveTargetByName(const char *name) { 909 for (int i = 0; i < targetPositions.Num(); i++) { 910 if (Q_stricmp(name, targetPositions[i]->getName()) == 0) { 911 setActiveTarget(i); 912 return; 913 } 914 } 915 } 916 917 void setActiveTarget(int index) { 918 assert(index >= 0 && index < targetPositions.Num()); 919 activeTarget = index; 920 } 921 922 void setRunning(bool b) { 923 cameraRunning = b; 924 } 925 926 void setBaseTime(float f) { 927 baseTime = f; 928 } 929 930 float getBaseTime() { 931 return baseTime; 932 } 933 934 float getTotalTime() { 935 return totalTime; 936 } 937 938 void startCamera(long t); 939 void stopCamera() { 940 cameraRunning = true; 941 } 942 void getActiveSegmentInfo(int segment, idVec3_t &origin, idVec3_t &direction, float *fv); 943 944 bool getCameraInfo(long time, idVec3_t &origin, idVec3_t &direction, float *fv); 945 bool getCameraInfo(long time, float *origin, float *direction, float *fv) { 946 idVec3_t org, dir; 947 org[0] = origin[0]; 948 org[1] = origin[1]; 949 org[2] = origin[2]; 950 dir[0] = direction[0]; 951 dir[1] = direction[1]; 952 dir[2] = direction[2]; 953 bool b = getCameraInfo(time, org, dir, fv); 954 origin[0] = org[0]; 955 origin[1] = org[1]; 956 origin[2] = org[2]; 957 direction[0] = dir[0]; 958 direction[1] = dir[1]; 959 direction[2] = dir[2]; 960 return b; 961 } 962 /* 963 void draw(bool editMode) { 964 // gcc doesn't allow casting away from bools 965 // why? I've no idea... 966 if (cameraPosition) { 967 cameraPosition->draw((bool)((editMode || cameraRunning) && cameraEdit)); 968 int count = targetPositions.Num(); 969 for (int i = 0; i < count; i++) { 970 targetPositions[i]->draw((bool)((editMode || cameraRunning) && i == activeTarget && !cameraEdit)); 971 } 972 } 973 } 974 */ 975 /* 976 int numSegments() { 977 if (cameraEdit) { 978 return cameraPosition.numSegments(); 979 } 980 return getTargetSpline()->numSegments(); 981 } 982 983 int getActiveSegment() { 984 if (cameraEdit) { 985 return cameraPosition.getActiveSegment(); 986 } 987 return getTargetSpline()->getActiveSegment(); 988 } 989 990 void setActiveSegment(int i) { 991 if (cameraEdit) { 992 cameraPosition.setActiveSegment(i); 993 } else { 994 getTargetSpline()->setActiveSegment(i); 995 } 996 } 997 */ 998 int numPoints() { 999 if (cameraEdit) { 1000 return cameraPosition->numPoints(); 1001 } 1002 return getActiveTarget()->numPoints(); 1003 } 1004 1005 const idVec3_t *getPoint(int index) { 1006 if (cameraEdit) { 1007 return cameraPosition->getPoint(index); 1008 } 1009 return getActiveTarget()->getPoint(index); 1010 } 1011 1012 void stopEdit() { 1013 editMode = false; 1014 if (cameraEdit) { 1015 cameraPosition->stopEdit(); 1016 } else { 1017 getActiveTarget()->stopEdit(); 1018 } 1019 } 1020 1021 void startEdit(bool camera) { 1022 cameraEdit = camera; 1023 if (camera) { 1024 cameraPosition->startEdit(); 1025 for (int i = 0; i < targetPositions.Num(); i++) { 1026 targetPositions[i]->stopEdit(); 1027 } 1028 } else { 1029 getActiveTarget()->startEdit(); 1030 cameraPosition->stopEdit(); 1031 } 1032 editMode = true; 1033 } 1034 1035 bool waitEvent(int index); 1036 1037 const char *getName() { 1038 return name.c_str(); 1039 } 1040 1041 void setName(const char *p) { 1042 name = p; 1043 } 1044 1045 idCameraPosition *getPositionObj() { 1046 if (cameraPosition == NULL) { 1047 cameraPosition = new idFixedPosition(); 1048 } 1049 return cameraPosition; 1050 } 1051 1052 protected: 1053 idStr name; 1054 int currentCameraPosition; 1055 idVec3_t lastDirection; 1056 bool cameraRunning; 1057 idCameraPosition *cameraPosition; 1058 idList<idCameraPosition*> targetPositions; 1059 idList<idCameraEvent*> events; 1060 idCameraFOV fov; 1061 int activeTarget; 1062 float totalTime; 1063 float baseTime; 1064 long startTime; 1065 1066 bool cameraEdit; 1067 bool editMode; 1068 }; 1069 1070 extern bool g_splineMode; 1071 1072 extern idCameraDef *g_splineList; 1073 1074 1075 #endif