2 Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 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.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31 #include "util_list.h"
33 #include "math_vector.h"
35 typedef int fileHandle_t;
37 extern void glBox( idVec3 &color, idVec3 &point, float size );
38 extern void glLabeledPoint( idVec3 &color, idVec3 &point, float size, const char *label );
40 static idVec4 blue( 0, 0, 1, 1 );
41 static idVec4 red( 1, 0, 0, 1 );
43 class idPointListInterface {
45 idPointListInterface() {
46 selectedPoints.Clear();
48 virtual ~idPointListInterface() {};
50 virtual int numPoints() {
54 virtual void addPoint( const float x, const float y, const float z ) {}
55 virtual void addPoint( const idVec3 &v ) {}
56 virtual void removePoint( int index ) {}
57 virtual idVec3 *getPoint( int index ) { return NULL; }
59 int selectPointByRay( float ox, float oy, float oz, float dx, float dy, float dz, bool single ) {
60 idVec3 origin( ox, oy, oz );
61 idVec3 dir( dx, dy, dz );
62 return selectPointByRay( origin, dir, single );
65 int selectPointByRay( const idVec3 origin, const idVec3 direction, bool single ) {
70 // find the point closest to the ray
75 for ( i = 0; i < count; i++ ) {
76 temp = *getPoint( i );
79 d = DotProduct( temp, direction );
80 __VectorMA( origin, d, direction, temp );
90 selectPoint( besti, single );
96 int isPointSelected( int index ) {
97 int count = selectedPoints.Num();
98 for ( int i = 0; i < count; i++ ) {
99 if ( selectedPoints[i] == index ) {
106 int selectPoint( int index, bool single ) {
107 if ( index >= 0 && index < numPoints() ) {
112 if ( isPointSelected( index ) >= 0 ) {
113 selectedPoints.Remove( index );
116 return selectedPoints.Append( index );
122 selectedPoints.Clear();
123 for ( int i = 0; i < numPoints(); i++ ) {
124 selectedPoints.Append( i );
129 selectedPoints.Clear();
132 int numSelectedPoints();
134 idVec3 *getSelectedPoint( int index ) {
135 assert( index >= 0 && index < numSelectedPoints() );
136 return getPoint( selectedPoints[index] );
139 virtual void updateSelection( float x, float y, float z ) {
140 idVec3 move( x, y, z );
141 updateSelection( move );
144 virtual void updateSelection( const idVec3 &move ) {
145 int count = selectedPoints.Num();
146 for ( int i = 0; i < count; i++ ) {
147 *getPoint( selectedPoints[i] ) += move;
151 void drawSelection() {
152 int count = selectedPoints.Num();
153 for ( int i = 0; i < count; i++ ) {
154 glBox( red, *getPoint( selectedPoints[i] ), 4 );
159 idList<int> selectedPoints;
172 idSplineList( const char *p ) {
181 void clearControl() {
182 for ( int i = 0; i < controlPoints.Num(); i++ ) {
183 delete controlPoints[i];
185 controlPoints.Clear();
189 for ( int i = 0; i < splinePoints.Num(); i++ ) {
190 delete splinePoints[i];
192 splinePoints.Clear();
195 void parse( const char *( *text ) );
196 void write( fileHandle_t file, const char *name );
205 granularity = 0.025f;
206 pathColor.set( 1.0f, 0.5f, 0.0f );
207 controlColor.set( 0.7f, 0.0f, 1.0f );
208 segmentColor.set( 0.0f, 0.0f, 1.0f );
209 activeColor.set( 1.0f, 0.0f, 0.0f );
212 void initPosition( long startTime, long totalTime );
213 const idVec3 *getPosition( long time );
216 void draw( bool editMode );
217 void addToRenderer();
219 void setSelectedPoint( idVec3 *p );
220 idVec3 *getSelectedPoint() {
224 void addPoint( const idVec3 &v ) {
225 controlPoints.Append( new idVec3( v ) );
229 void addPoint( float x, float y, float z ) {
230 controlPoints.Append( new idVec3( x, y, z ) );
234 void updateSelection( const idVec3 &move );
246 void setGranularity( float f ) {
250 float getGranularity() {
255 return controlPoints.Num();
258 idVec3 *getPoint( int index ) {
259 assert( index >= 0 && index < controlPoints.Num() );
260 return controlPoints[index];
263 idVec3 *getSegmentPoint( int index ) {
264 assert( index >= 0 && index < splinePoints.Num() );
265 return splinePoints[index];
269 void setSegmentTime( int index, int time ) {
270 assert( index >= 0 && index < splinePoints.Num() );
271 splineTime[index] = time;
274 int getSegmentTime( int index ) {
275 assert( index >= 0 && index < splinePoints.Num() );
276 return (int)splineTime[index];
278 void addSegmentTime( int index, int time ) {
279 assert( index >= 0 && index < splinePoints.Num() );
280 splineTime[index] += time;
283 float totalDistance();
287 int getActiveSegment() {
288 return activeSegment;
291 void setActiveSegment( int i ) {
292 //assert(i >= 0 && (splinePoints.Num() > 0 && i < splinePoints.Num()));
297 return splinePoints.Num();
300 void setColors( idVec3 &path, idVec3 &segment, idVec3 &control, idVec3 &active ) {
302 segmentColor = segment;
303 controlColor = control;
304 activeColor = active;
307 const char *getName() {
311 void setName( const char *p ) {
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() );
324 void setTime( long t ) {
328 void setBaseTime( long t ) {
334 float calcSpline( int step, float tension );
335 idList<idVec3*> controlPoints;
336 idList<idVec3*> splinePoints;
337 idList<double> splineTime;
339 idVec3 pathColor, segmentColor, controlColor, activeColor;
346 friend class idCamera;
349 // time in milliseconds
350 // velocity where 1.0 equal rough walking speed
352 idVelocity( long start, long duration, float s ) {
362 // can either be a look at or origin position for a camera
364 class idCameraPosition : public idPointListInterface {
367 virtual void clearVelocities() {
368 for ( int i = 0; i < velocities.Num(); i++ ) {
369 delete velocities[i];
370 velocities[i] = NULL;
375 virtual void clear() {
380 idCameraPosition( const char *p ) {
389 idCameraPosition( long t ) {
393 virtual ~idCameraPosition() {
398 // this can be done with RTTI syntax but i like the derived classes setting a type
399 // makes serialization a bit easier to see
409 virtual void start( long t ) {
417 virtual void setTime( long t ) {
421 float getBaseVelocity() {
425 float getVelocity( long t ) {
426 long check = t - startTime;
427 for ( int i = 0; i < velocities.Num(); i++ ) {
428 if ( check >= velocities[i]->startTime && check <= velocities[i]->startTime + velocities[i]->time ) {
429 return velocities[i]->speed;
435 void addVelocity( long start, long duration, float speed ) {
436 velocities.Append( new idVelocity( start, duration, speed ) );
439 virtual const idVec3 *getPosition( long t ) {
444 virtual void draw( bool editMode ) {};
446 virtual void parse( const char *( *text ) ) {};
447 virtual void write( fileHandle_t file, const char *name );
448 virtual bool parseToken( const char *key, const char *( *text ) );
450 const char *getName() {
454 void setName( const char *p ) {
458 virtual void startEdit() {
462 virtual void stopEdit() {
466 virtual void draw() {};
468 const char *typeStr() {
469 return positionStr[static_cast<int>( type )];
472 void calcVelocity( float distance ) {
473 float secs = (float)time / 1000;
474 baseVelocity = distance / secs;
478 static const char* positionStr[POSITION_COUNT];
481 idCameraPosition::positionType type;
484 idList<idVelocity*> velocities;
488 class idFixedPosition : public idCameraPosition {
493 type = idCameraPosition::FIXED;
496 idFixedPosition() : idCameraPosition() {
500 idFixedPosition( idVec3 p ) : idCameraPosition() {
505 virtual void addPoint( const idVec3 &v ) {
509 virtual void addPoint( const float x, const float y, const float z ) {
517 virtual const idVec3 *getPosition( long t ) {
521 void parse( const char *( *text ) );
522 void write( fileHandle_t file, const char *name );
524 virtual int numPoints() {
528 virtual idVec3 *getPoint( int index ) {
536 virtual void draw( bool editMode ) {
537 glLabeledPoint( blue, pos, ( editMode ) ? 5 : 3, "Fixed point" );
544 class idInterpolatedPosition : public idCameraPosition {
548 type = idCameraPosition::INTERPOLATED;
554 idInterpolatedPosition() : idCameraPosition() {
558 idInterpolatedPosition( idVec3 start, idVec3 end, long time ) : idCameraPosition( time ) {
564 ~idInterpolatedPosition() {
567 virtual const idVec3 *getPosition( long t );
569 void parse( const char *( *text ) );
570 void write( fileHandle_t file, const char *name );
572 virtual int numPoints() {
576 virtual idVec3 *getPoint( int index ) {
577 assert( index >= 0 && index < 2 );
584 virtual void addPoint( const float x, const float y, const float z ) {
586 startPos.set( x, y, z );
590 endPos.set( x, y, z );
595 virtual void addPoint( const idVec3 &v ) {
606 virtual void draw( bool editMode ) {
607 glLabeledPoint( blue, startPos, ( editMode ) ? 5 : 3, "Start interpolated" );
608 glLabeledPoint( blue, endPos, ( editMode ) ? 5 : 3, "End interpolated" );
610 glVertex3fv( startPos );
611 glVertex3fv( endPos );
615 virtual void start( long t ) {
616 idCameraPosition::start( t );
617 lastTime = startTime;
619 idVec3 temp = startPos;
621 calcVelocity( temp.Length() );
632 class idSplinePosition : public idCameraPosition {
636 type = idCameraPosition::SPLINE;
639 idSplinePosition() : idCameraPosition() {
643 idSplinePosition( long time ) : idCameraPosition( time ) {
647 ~idSplinePosition() {
650 virtual void start( long t ) {
651 idCameraPosition::start( t );
652 target.initPosition( t, time );
653 lastTime = startTime;
655 calcVelocity( target.totalDistance() );
658 //virtual const idVec3 *getPosition(long t) {
659 // return target.getPosition(t);
661 virtual const idVec3 *getPosition( long t );
664 //virtual const idVec3 *getPosition(long t) const {
666 void addControlPoint( idVec3 &v ) {
667 target.addPoint( v );
670 void parse( const char *( *text ) );
671 void write( fileHandle_t file, const char *name );
673 virtual int numPoints() {
674 return target.numPoints();
677 virtual idVec3 *getPoint( int index ) {
678 return target.getPoint( index );
681 virtual void addPoint( const idVec3 &v ) {
682 target.addPoint( v );
685 virtual void addPoint( const float x, const float y, const float z ) {
686 target.addPoint( x, y, z );
689 virtual void draw( bool editMode ) {
690 target.draw( editMode );
693 virtual void updateSelection( const idVec3 &move ) {
694 idCameraPosition::updateSelection( move );
695 target.buildSpline();
713 idCameraFOV( int v ) {
719 idCameraFOV( int s, int e, long t ) {
728 void setFOV( float f ) {
732 float getFOV( long t ) {
734 float percent = ( t - startTime ) / length;
735 if ( percent < 0.0 ) {
738 else if ( percent > 1.0 ) {
741 float temp = endFOV - startFOV;
743 fov = startFOV + temp;
745 if ( percent == 1.0 ) {
752 void start( long t ) {
756 void reset( float startfov, float endfov, int start, float len ) {
763 void parse( const char *( *text ) );
764 void write( fileHandle_t file, const char *name );
778 class idCameraEvent {
779 public: // parameters
785 EVENT_TARGET, // char(name)
787 EVENT_FOV, // int(time), int(targetfov)
792 EVENT_FADEOUT, // int(time)
793 EVENT_FADEIN, // int(time)
798 static const char* eventStr[EVENT_COUNT];
806 idCameraEvent( eventType t, const char *param, long n ) {
814 eventType getType() {
818 const char *typeStr() {
819 return eventStr[static_cast<int>( type )];
822 const char *getParam() {
823 return paramStr.c_str();
830 void setTime( long n ) {
834 void parse( const char *( *text ) );
835 void write( fileHandle_t file, const char *name );
837 void setTriggered( bool b ) {
841 bool getTriggered() {
857 currentCameraPosition = 0;
858 cameraRunning = false;
859 lastDirection.Zero();
865 for ( i = 0; i < targetPositions.Num(); i++ ) {
866 delete targetPositions[i];
868 for ( i = 0; i < events.Num(); i++ ) {
871 delete cameraPosition;
872 cameraPosition = NULL;
874 targetPositions.Clear();
877 idCameraPosition *startNewCamera( idCameraPosition::positionType type ) {
879 if ( type == idCameraPosition::SPLINE ) {
880 cameraPosition = new idSplinePosition();
882 else if ( type == idCameraPosition::INTERPOLATED ) {
883 cameraPosition = new idInterpolatedPosition();
886 cameraPosition = new idFixedPosition();
888 return cameraPosition;
892 cameraPosition = NULL;
900 void addEvent( idCameraEvent::eventType t, const char *param, long time );
902 void addEvent( idCameraEvent *event );
904 void removeEvent( int index );
906 static int sortEvents( const void *p1, const void *p2 );
912 idCameraEvent *getEvent( int index ) {
913 assert( index >= 0 && index < events.Num() );
914 return events[index];
917 void parse( const char *( *text ) );
918 bool load( const char *filename );
919 void save( const char *filename );
923 //idSplineList *getcameraPosition() {
924 // return &cameraPosition;
927 static idCameraPosition *newFromType( idCameraPosition::positionType t ) {
929 case idCameraPosition::FIXED: return new idFixedPosition();
930 case idCameraPosition::INTERPOLATED: return new idInterpolatedPosition();
931 case idCameraPosition::SPLINE: return new idSplinePosition();
938 void addTarget( const char *name, idCameraPosition::positionType type );
940 idCameraPosition *getActiveTarget() {
941 if ( targetPositions.Num() == 0 ) {
942 addTarget( NULL, idCameraPosition::FIXED );
944 return targetPositions[activeTarget];
947 idCameraPosition *getActiveTarget( int index ) {
948 if ( targetPositions.Num() == 0 ) {
949 addTarget( NULL, idCameraPosition::FIXED );
950 return targetPositions[0];
952 return targetPositions[index];
956 return targetPositions.Num();
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 );
969 void setActiveTarget( int index ) {
970 assert( index >= 0 && index < targetPositions.Num() );
971 activeTarget = index;
974 void setRunning( bool b ) {
978 void setBaseTime( float f ) {
982 float getBaseTime() {
986 float getTotalTime() {
990 void startCamera( long t );
992 cameraRunning = true;
994 void getActiveSegmentInfo( int segment, idVec3 &origin, idVec3 &direction, float *fv );
996 bool getCameraInfo( long time, idVec3 &origin, idVec3 &direction, float *fv );
997 bool getCameraInfo( long time, float *origin, float *direction, float *fv ) {
1002 dir[0] = direction[0];
1003 dir[1] = direction[1];
1004 dir[2] = direction[2];
1005 bool b = getCameraInfo( time, org, dir, fv );
1009 direction[0] = dir[0];
1010 direction[1] = dir[1];
1011 direction[2] = dir[2];
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 ) );
1030 return cameraPosition.numSegments();
1032 return getTargetSpline()->numSegments();
1035 int getActiveSegment() {
1037 return cameraPosition.getActiveSegment();
1039 return getTargetSpline()->getActiveSegment();
1042 void setActiveSegment(int i) {
1044 cameraPosition.setActiveSegment(i);
1046 getTargetSpline()->setActiveSegment(i);
1052 return cameraPosition->numPoints();
1054 return getActiveTarget()->numPoints();
1057 const idVec3 *getPoint( int index ) {
1059 return cameraPosition->getPoint( index );
1061 return getActiveTarget()->getPoint( index );
1067 cameraPosition->stopEdit();
1070 getActiveTarget()->stopEdit();
1074 void startEdit( bool camera ) {
1075 cameraEdit = camera;
1077 cameraPosition->startEdit();
1078 for ( int i = 0; i < targetPositions.Num(); i++ ) {
1079 targetPositions[i]->stopEdit();
1083 getActiveTarget()->startEdit();
1084 cameraPosition->stopEdit();
1089 bool waitEvent( int index );
1091 const char *getName() {
1092 return name.c_str();
1095 void setName( const char *p ) {
1099 idCameraPosition *getPositionObj() {
1100 if ( cameraPosition == NULL ) {
1101 cameraPosition = new idFixedPosition();
1103 return cameraPosition;
1108 int currentCameraPosition;
1109 idVec3 lastDirection;
1111 idCameraPosition *cameraPosition;
1112 idList<idCameraPosition*> targetPositions;
1113 idList<idCameraEvent*> events;
1124 extern bool g_splineMode;
1126 extern idCameraDef *g_splineList;