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