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