9 #include "igl_to_qgl.h"
13 #include "util_list.h"
15 #include "math_vector.h"
17 typedef int fileHandle_t;
19 extern void glBox( idVec3 &color, idVec3 &point, float size );
20 extern void glLabeledPoint( idVec3 &color, idVec3 &point, float size, const char *label );
22 static idVec4 blue( 0, 0, 1, 1 );
23 static idVec4 red( 1, 0, 0, 1 );
25 class idPointListInterface {
27 idPointListInterface() {
28 selectedPoints.Clear();
30 virtual ~idPointListInterface() {};
32 virtual int numPoints() {
36 virtual void addPoint( const float x, const float y, const float z ) {}
37 virtual void addPoint( const idVec3 &v ) {}
38 virtual void removePoint( int index ) {}
39 virtual idVec3 *getPoint( int index ) { return NULL; }
41 int selectPointByRay( float ox, float oy, float oz, float dx, float dy, float dz, bool single ) {
42 idVec3 origin( ox, oy, oz );
43 idVec3 dir( dx, dy, dz );
44 return selectPointByRay( origin, dir, single );
47 int selectPointByRay( const idVec3 origin, const idVec3 direction, bool single ) {
52 // find the point closest to the ray
57 for ( i = 0; i < count; i++ ) {
58 temp = *getPoint( i );
61 d = DotProduct( temp, direction );
62 __VectorMA( origin, d, direction, temp );
72 selectPoint( besti, single );
78 int isPointSelected( int index ) {
79 int count = selectedPoints.Num();
80 for ( int i = 0; i < count; i++ ) {
81 if ( selectedPoints[i] == index ) {
88 int selectPoint( int index, bool single ) {
89 if ( index >= 0 && index < numPoints() ) {
94 if ( isPointSelected( index ) >= 0 ) {
95 selectedPoints.Remove( index );
98 return selectedPoints.Append( index );
104 selectedPoints.Clear();
105 for ( int i = 0; i < numPoints(); i++ ) {
106 selectedPoints.Append( i );
111 selectedPoints.Clear();
114 int numSelectedPoints();
116 idVec3 *getSelectedPoint( int index ) {
117 assert( index >= 0 && index < numSelectedPoints() );
118 return getPoint( selectedPoints[index] );
121 virtual void updateSelection( float x, float y, float z ) {
122 idVec3 move( x, y, z );
123 updateSelection( move );
126 virtual void updateSelection( const idVec3 &move ) {
127 int count = selectedPoints.Num();
128 for ( int i = 0; i < count; i++ ) {
129 *getPoint( selectedPoints[i] ) += move;
133 void drawSelection() {
134 int count = selectedPoints.Num();
135 for ( int i = 0; i < count; i++ ) {
136 glBox( red, *getPoint( selectedPoints[i] ), 4 );
141 idList<int> selectedPoints;
154 idSplineList( const char *p ) {
163 void clearControl() {
164 for ( int i = 0; i < controlPoints.Num(); i++ ) {
165 delete controlPoints[i];
167 controlPoints.Clear();
171 for ( int i = 0; i < splinePoints.Num(); i++ ) {
172 delete splinePoints[i];
174 splinePoints.Clear();
177 void parse( const char *( *text ) );
178 void write( fileHandle_t file, const char *name );
187 granularity = 0.025f;
188 pathColor.set( 1.0f, 0.5f, 0.0f );
189 controlColor.set( 0.7f, 0.0f, 1.0f );
190 segmentColor.set( 0.0f, 0.0f, 1.0f );
191 activeColor.set( 1.0f, 0.0f, 0.0f );
194 void initPosition( long startTime, long totalTime );
195 const idVec3 *getPosition( long time );
198 void draw( bool editMode );
199 void addToRenderer();
201 void setSelectedPoint( idVec3 *p );
202 idVec3 *getSelectedPoint() {
206 void addPoint( const idVec3 &v ) {
207 controlPoints.Append( new idVec3( v ) );
211 void addPoint( float x, float y, float z ) {
212 controlPoints.Append( new idVec3( x, y, z ) );
216 void updateSelection( const idVec3 &move );
228 void setGranularity( float f ) {
232 float getGranularity() {
237 return controlPoints.Num();
240 idVec3 *getPoint( int index ) {
241 assert( index >= 0 && index < controlPoints.Num() );
242 return controlPoints[index];
245 idVec3 *getSegmentPoint( int index ) {
246 assert( index >= 0 && index < splinePoints.Num() );
247 return splinePoints[index];
251 void setSegmentTime( int index, int time ) {
252 assert( index >= 0 && index < splinePoints.Num() );
253 splineTime[index] = time;
256 int getSegmentTime( int index ) {
257 assert( index >= 0 && index < splinePoints.Num() );
258 return (int)splineTime[index];
260 void addSegmentTime( int index, int time ) {
261 assert( index >= 0 && index < splinePoints.Num() );
262 splineTime[index] += time;
265 float totalDistance();
269 int getActiveSegment() {
270 return activeSegment;
273 void setActiveSegment( int i ) {
274 //assert(i >= 0 && (splinePoints.Num() > 0 && i < splinePoints.Num()));
279 return splinePoints.Num();
282 void setColors( idVec3 &path, idVec3 &segment, idVec3 &control, idVec3 &active ) {
284 segmentColor = segment;
285 controlColor = control;
286 activeColor = active;
289 const char *getName() {
293 void setName( const char *p ) {
301 // gcc doesn't allow static casting away from bools
302 // why? I've no idea...
303 return (bool)( splineTime.Num() > 0 && splineTime.Num() == splinePoints.Num() );
306 void setTime( long t ) {
310 void setBaseTime( long t ) {
316 float calcSpline( int step, float tension );
317 idList<idVec3*> controlPoints;
318 idList<idVec3*> splinePoints;
319 idList<double> splineTime;
321 idVec3 pathColor, segmentColor, controlColor, activeColor;
328 friend class idCamera;
331 // time in milliseconds
332 // velocity where 1.0 equal rough walking speed
334 idVelocity( long start, long duration, float s ) {
344 // can either be a look at or origin position for a camera
346 class idCameraPosition : public idPointListInterface {
349 virtual void clearVelocities() {
350 for ( int i = 0; i < velocities.Num(); i++ ) {
351 delete velocities[i];
352 velocities[i] = NULL;
357 virtual void clear() {
362 idCameraPosition( const char *p ) {
371 idCameraPosition( long t ) {
375 virtual ~idCameraPosition() {
380 // this can be done with RTTI syntax but i like the derived classes setting a type
381 // makes serialization a bit easier to see
391 virtual void start( long t ) {
399 virtual void setTime( long t ) {
403 float getBaseVelocity() {
407 float getVelocity( long t ) {
408 long check = t - startTime;
409 for ( int i = 0; i < velocities.Num(); i++ ) {
410 if ( check >= velocities[i]->startTime && check <= velocities[i]->startTime + velocities[i]->time ) {
411 return velocities[i]->speed;
417 void addVelocity( long start, long duration, float speed ) {
418 velocities.Append( new idVelocity( start, duration, speed ) );
421 virtual const idVec3 *getPosition( long t ) {
426 virtual void draw( bool editMode ) {};
428 virtual void parse( const char *( *text ) ) {};
429 virtual void write( fileHandle_t file, const char *name );
430 virtual bool parseToken( const char *key, const char *( *text ) );
432 const char *getName() {
436 void setName( const char *p ) {
440 virtual void startEdit() {
444 virtual void stopEdit() {
448 virtual void draw() {};
450 const char *typeStr() {
451 return positionStr[static_cast<int>( type )];
454 void calcVelocity( float distance ) {
455 float secs = (float)time / 1000;
456 baseVelocity = distance / secs;
460 static const char* positionStr[POSITION_COUNT];
463 idCameraPosition::positionType type;
466 idList<idVelocity*> velocities;
470 class idFixedPosition : public idCameraPosition {
475 type = idCameraPosition::FIXED;
478 idFixedPosition() : idCameraPosition() {
482 idFixedPosition( idVec3 p ) : idCameraPosition() {
487 virtual void addPoint( const idVec3 &v ) {
491 virtual void addPoint( const float x, const float y, const float z ) {
499 virtual const idVec3 *getPosition( long t ) {
503 void parse( const char *( *text ) );
504 void write( fileHandle_t file, const char *name );
506 virtual int numPoints() {
510 virtual idVec3 *getPoint( int index ) {
518 virtual void draw( bool editMode ) {
519 glLabeledPoint( blue, pos, ( editMode ) ? 5 : 3, "Fixed point" );
526 class idInterpolatedPosition : public idCameraPosition {
530 type = idCameraPosition::INTERPOLATED;
536 idInterpolatedPosition() : idCameraPosition() {
540 idInterpolatedPosition( idVec3 start, idVec3 end, long time ) : idCameraPosition( time ) {
546 ~idInterpolatedPosition() {
549 virtual const idVec3 *getPosition( long t );
551 void parse( const char *( *text ) );
552 void write( fileHandle_t file, const char *name );
554 virtual int numPoints() {
558 virtual idVec3 *getPoint( int index ) {
559 assert( index >= 0 && index < 2 );
566 virtual void addPoint( const float x, const float y, const float z ) {
568 startPos.set( x, y, z );
572 endPos.set( x, y, z );
577 virtual void addPoint( const idVec3 &v ) {
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 );
597 virtual void start( long t ) {
598 idCameraPosition::start( t );
599 lastTime = startTime;
601 idVec3 temp = startPos;
603 calcVelocity( temp.Length() );
614 class idSplinePosition : public idCameraPosition {
618 type = idCameraPosition::SPLINE;
621 idSplinePosition() : idCameraPosition() {
625 idSplinePosition( long time ) : idCameraPosition( time ) {
629 ~idSplinePosition() {
632 virtual void start( long t ) {
633 idCameraPosition::start( t );
634 target.initPosition( t, time );
635 lastTime = startTime;
637 calcVelocity( target.totalDistance() );
640 //virtual const idVec3 *getPosition(long t) {
641 // return target.getPosition(t);
643 virtual const idVec3 *getPosition( long t );
646 //virtual const idVec3 *getPosition(long t) const {
648 void addControlPoint( idVec3 &v ) {
649 target.addPoint( v );
652 void parse( const char *( *text ) );
653 void write( fileHandle_t file, const char *name );
655 virtual int numPoints() {
656 return target.numPoints();
659 virtual idVec3 *getPoint( int index ) {
660 return target.getPoint( index );
663 virtual void addPoint( const idVec3 &v ) {
664 target.addPoint( v );
667 virtual void addPoint( const float x, const float y, const float z ) {
668 target.addPoint( x, y, z );
671 virtual void draw( bool editMode ) {
672 target.draw( editMode );
675 virtual void updateSelection( const idVec3 &move ) {
676 idCameraPosition::updateSelection( move );
677 target.buildSpline();
695 idCameraFOV( int v ) {
701 idCameraFOV( int s, int e, long t ) {
710 void setFOV( float f ) {
714 float getFOV( long t ) {
716 float percent = ( t - startTime ) / length;
717 if ( percent < 0.0 ) {
720 else if ( percent > 1.0 ) {
723 float temp = endFOV - startFOV;
725 fov = startFOV + temp;
727 if ( percent == 1.0 ) {
734 void start( long t ) {
738 void reset( float startfov, float endfov, int start, float len ) {
745 void parse( const char *( *text ) );
746 void write( fileHandle_t file, const char *name );
760 class idCameraEvent {
761 public: // parameters
767 EVENT_TARGET, // char(name)
769 EVENT_FOV, // int(time), int(targetfov)
774 EVENT_FADEOUT, // int(time)
775 EVENT_FADEIN, // int(time)
780 static const char* eventStr[EVENT_COUNT];
788 idCameraEvent( eventType t, const char *param, long n ) {
796 eventType getType() {
800 const char *typeStr() {
801 return eventStr[static_cast<int>( type )];
804 const char *getParam() {
805 return paramStr.c_str();
812 void setTime( long n ) {
816 void parse( const char *( *text ) );
817 void write( fileHandle_t file, const char *name );
819 void setTriggered( bool b ) {
823 bool getTriggered() {
839 currentCameraPosition = 0;
840 cameraRunning = false;
841 lastDirection.Zero();
847 for ( i = 0; i < targetPositions.Num(); i++ ) {
848 delete targetPositions[i];
850 for ( i = 0; i < events.Num(); i++ ) {
853 delete cameraPosition;
854 cameraPosition = NULL;
856 targetPositions.Clear();
859 idCameraPosition *startNewCamera( idCameraPosition::positionType type ) {
861 if ( type == idCameraPosition::SPLINE ) {
862 cameraPosition = new idSplinePosition();
864 else if ( type == idCameraPosition::INTERPOLATED ) {
865 cameraPosition = new idInterpolatedPosition();
868 cameraPosition = new idFixedPosition();
870 return cameraPosition;
874 cameraPosition = NULL;
882 void addEvent( idCameraEvent::eventType t, const char *param, long time );
884 void addEvent( idCameraEvent *event );
886 void removeEvent( int index );
888 static int sortEvents( const void *p1, const void *p2 );
894 idCameraEvent *getEvent( int index ) {
895 assert( index >= 0 && index < events.Num() );
896 return events[index];
899 void parse( const char *( *text ) );
900 bool load( const char *filename );
901 void save( const char *filename );
905 //idSplineList *getcameraPosition() {
906 // return &cameraPosition;
909 static idCameraPosition *newFromType( idCameraPosition::positionType t ) {
911 case idCameraPosition::FIXED: return new idFixedPosition();
912 case idCameraPosition::INTERPOLATED: return new idInterpolatedPosition();
913 case idCameraPosition::SPLINE: return new idSplinePosition();
920 void addTarget( const char *name, idCameraPosition::positionType type );
922 idCameraPosition *getActiveTarget() {
923 if ( targetPositions.Num() == 0 ) {
924 addTarget( NULL, idCameraPosition::FIXED );
926 return targetPositions[activeTarget];
929 idCameraPosition *getActiveTarget( int index ) {
930 if ( targetPositions.Num() == 0 ) {
931 addTarget( NULL, idCameraPosition::FIXED );
932 return targetPositions[0];
934 return targetPositions[index];
938 return targetPositions.Num();
942 void setActiveTargetByName( const char *name ) {
943 for ( int i = 0; i < targetPositions.Num(); i++ ) {
944 if ( Q_stricmp( name, targetPositions[i]->getName() ) == 0 ) {
945 setActiveTarget( i );
951 void setActiveTarget( int index ) {
952 assert( index >= 0 && index < targetPositions.Num() );
953 activeTarget = index;
956 void setRunning( bool b ) {
960 void setBaseTime( float f ) {
964 float getBaseTime() {
968 float getTotalTime() {
972 void startCamera( long t );
974 cameraRunning = true;
976 void getActiveSegmentInfo( int segment, idVec3 &origin, idVec3 &direction, float *fv );
978 bool getCameraInfo( long time, idVec3 &origin, idVec3 &direction, float *fv );
979 bool getCameraInfo( long time, float *origin, float *direction, float *fv ) {
984 dir[0] = direction[0];
985 dir[1] = direction[1];
986 dir[2] = direction[2];
987 bool b = getCameraInfo( time, org, dir, fv );
991 direction[0] = dir[0];
992 direction[1] = dir[1];
993 direction[2] = dir[2];
997 void draw( bool editMode ) {
998 // gcc doesn't allow casting away from bools
999 // why? I've no idea...
1000 if ( cameraPosition ) {
1001 cameraPosition->draw( (bool)( ( editMode || cameraRunning ) && cameraEdit ) );
1002 int count = targetPositions.Num();
1003 for ( int i = 0; i < count; i++ ) {
1004 targetPositions[i]->draw( (bool)( ( editMode || cameraRunning ) && i == activeTarget && !cameraEdit ) );
1012 return cameraPosition.numSegments();
1014 return getTargetSpline()->numSegments();
1017 int getActiveSegment() {
1019 return cameraPosition.getActiveSegment();
1021 return getTargetSpline()->getActiveSegment();
1024 void setActiveSegment(int i) {
1026 cameraPosition.setActiveSegment(i);
1028 getTargetSpline()->setActiveSegment(i);
1034 return cameraPosition->numPoints();
1036 return getActiveTarget()->numPoints();
1039 const idVec3 *getPoint( int index ) {
1041 return cameraPosition->getPoint( index );
1043 return getActiveTarget()->getPoint( index );
1049 cameraPosition->stopEdit();
1052 getActiveTarget()->stopEdit();
1056 void startEdit( bool camera ) {
1057 cameraEdit = camera;
1059 cameraPosition->startEdit();
1060 for ( int i = 0; i < targetPositions.Num(); i++ ) {
1061 targetPositions[i]->stopEdit();
1065 getActiveTarget()->startEdit();
1066 cameraPosition->stopEdit();
1071 bool waitEvent( int index );
1073 const char *getName() {
1074 return name.c_str();
1077 void setName( const char *p ) {
1081 idCameraPosition *getPositionObj() {
1082 if ( cameraPosition == NULL ) {
1083 cameraPosition = new idFixedPosition();
1085 return cameraPosition;
1090 int currentCameraPosition;
1091 idVec3 lastDirection;
1093 idCameraPosition *cameraPosition;
1094 idList<idCameraPosition*> targetPositions;
1095 idList<idCameraEvent*> events;
1106 extern bool g_splineMode;
1108 extern idCameraDef *g_splineList;