mirror of
https://github.com/UberGames/GtkRadiant.git
synced 2024-11-23 04:12:06 +00:00
1111 lines
20 KiB
C++
1111 lines
20 KiB
C++
#ifndef __SPLINES_H
|
|
#define __SPLINES_H
|
|
|
|
#define GTKRADIANT
|
|
|
|
#ifndef CAMERA_PLUGIN
|
|
#ifdef GTKRADIANT
|
|
#include "misc_def.h"
|
|
#include "igl_to_qgl.h"
|
|
#endif
|
|
#endif
|
|
|
|
#include "util_list.h"
|
|
#include "util_str.h"
|
|
#include "math_vector.h"
|
|
|
|
typedef int fileHandle_t;
|
|
|
|
extern void glBox( idVec3 &color, idVec3 &point, float size );
|
|
extern void glLabeledPoint( idVec3 &color, idVec3 &point, float size, const char *label );
|
|
|
|
static idVec4 blue( 0, 0, 1, 1 );
|
|
static idVec4 red( 1, 0, 0, 1 );
|
|
|
|
class idPointListInterface {
|
|
public:
|
|
idPointListInterface() {
|
|
selectedPoints.Clear();
|
|
};
|
|
virtual ~idPointListInterface() {};
|
|
|
|
virtual int numPoints() {
|
|
return 0;
|
|
}
|
|
|
|
virtual void addPoint( const float x, const float y, const float z ) {}
|
|
virtual void addPoint( const idVec3 &v ) {}
|
|
virtual void removePoint( int index ) {}
|
|
virtual idVec3 *getPoint( int index ) { return NULL; }
|
|
|
|
int selectPointByRay( float ox, float oy, float oz, float dx, float dy, float dz, bool single ) {
|
|
idVec3 origin( ox, oy, oz );
|
|
idVec3 dir( dx, dy, dz );
|
|
return selectPointByRay( origin, dir, single );
|
|
}
|
|
|
|
int selectPointByRay( const idVec3 origin, const idVec3 direction, bool single ) {
|
|
int i, besti, count;
|
|
float d, bestd;
|
|
idVec3 temp, temp2;
|
|
|
|
// find the point closest to the ray
|
|
besti = -1;
|
|
bestd = 8;
|
|
count = numPoints();
|
|
|
|
for ( i = 0; i < count; i++ ) {
|
|
temp = *getPoint( i );
|
|
temp2 = temp;
|
|
temp -= origin;
|
|
d = DotProduct( temp, direction );
|
|
__VectorMA( origin, d, direction, temp );
|
|
temp2 -= temp;
|
|
d = temp2.Length();
|
|
if ( d <= bestd ) {
|
|
bestd = d;
|
|
besti = i;
|
|
}
|
|
}
|
|
|
|
if ( besti >= 0 ) {
|
|
selectPoint( besti, single );
|
|
}
|
|
|
|
return besti;
|
|
}
|
|
|
|
int isPointSelected( int index ) {
|
|
int count = selectedPoints.Num();
|
|
for ( int i = 0; i < count; i++ ) {
|
|
if ( selectedPoints[i] == index ) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int selectPoint( int index, bool single ) {
|
|
if ( index >= 0 && index < numPoints() ) {
|
|
if ( single ) {
|
|
deselectAll();
|
|
}
|
|
else {
|
|
if ( isPointSelected( index ) >= 0 ) {
|
|
selectedPoints.Remove( index );
|
|
}
|
|
}
|
|
return selectedPoints.Append( index );
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void selectAll() {
|
|
selectedPoints.Clear();
|
|
for ( int i = 0; i < numPoints(); i++ ) {
|
|
selectedPoints.Append( i );
|
|
}
|
|
}
|
|
|
|
void deselectAll() {
|
|
selectedPoints.Clear();
|
|
}
|
|
|
|
int numSelectedPoints();
|
|
|
|
idVec3 *getSelectedPoint( int index ) {
|
|
assert( index >= 0 && index < numSelectedPoints() );
|
|
return getPoint( selectedPoints[index] );
|
|
}
|
|
|
|
virtual void updateSelection( float x, float y, float z ) {
|
|
idVec3 move( x, y, z );
|
|
updateSelection( move );
|
|
}
|
|
|
|
virtual void updateSelection( const idVec3 &move ) {
|
|
int count = selectedPoints.Num();
|
|
for ( int i = 0; i < count; i++ ) {
|
|
*getPoint( selectedPoints[i] ) += move;
|
|
}
|
|
}
|
|
|
|
void drawSelection() {
|
|
int count = selectedPoints.Num();
|
|
for ( int i = 0; i < count; i++ ) {
|
|
glBox( red, *getPoint( selectedPoints[i] ), 4 );
|
|
}
|
|
}
|
|
|
|
protected:
|
|
idList<int> selectedPoints;
|
|
|
|
};
|
|
|
|
|
|
class idSplineList {
|
|
|
|
public:
|
|
|
|
idSplineList() {
|
|
clear();
|
|
}
|
|
|
|
idSplineList( const char *p ) {
|
|
clear();
|
|
name = p;
|
|
};
|
|
|
|
~idSplineList() {
|
|
clear();
|
|
};
|
|
|
|
void clearControl() {
|
|
for ( int i = 0; i < controlPoints.Num(); i++ ) {
|
|
delete controlPoints[i];
|
|
}
|
|
controlPoints.Clear();
|
|
}
|
|
|
|
void clearSpline() {
|
|
for ( int i = 0; i < splinePoints.Num(); i++ ) {
|
|
delete splinePoints[i];
|
|
}
|
|
splinePoints.Clear();
|
|
}
|
|
|
|
void parse( const char *( *text ) );
|
|
void write( fileHandle_t file, const char *name );
|
|
|
|
void clear() {
|
|
clearControl();
|
|
clearSpline();
|
|
splineTime.Clear();
|
|
selected = NULL;
|
|
dirty = true;
|
|
activeSegment = 0;
|
|
granularity = 0.025f;
|
|
pathColor.set( 1.0f, 0.5f, 0.0f );
|
|
controlColor.set( 0.7f, 0.0f, 1.0f );
|
|
segmentColor.set( 0.0f, 0.0f, 1.0f );
|
|
activeColor.set( 1.0f, 0.0f, 0.0f );
|
|
}
|
|
|
|
void initPosition( long startTime, long totalTime );
|
|
const idVec3 *getPosition( long time );
|
|
|
|
|
|
void draw( bool editMode );
|
|
void addToRenderer();
|
|
|
|
void setSelectedPoint( idVec3 *p );
|
|
idVec3 *getSelectedPoint() {
|
|
return selected;
|
|
}
|
|
|
|
void addPoint( const idVec3 &v ) {
|
|
controlPoints.Append( new idVec3( v ) );
|
|
dirty = true;
|
|
}
|
|
|
|
void addPoint( float x, float y, float z ) {
|
|
controlPoints.Append( new idVec3( x, y, z ) );
|
|
dirty = true;
|
|
}
|
|
|
|
void updateSelection( const idVec3 &move );
|
|
|
|
void startEdit() {
|
|
editMode = true;
|
|
}
|
|
|
|
void stopEdit() {
|
|
editMode = false;
|
|
}
|
|
|
|
void buildSpline();
|
|
|
|
void setGranularity( float f ) {
|
|
granularity = f;
|
|
}
|
|
|
|
float getGranularity() {
|
|
return granularity;
|
|
}
|
|
|
|
int numPoints() {
|
|
return controlPoints.Num();
|
|
}
|
|
|
|
idVec3 *getPoint( int index ) {
|
|
assert( index >= 0 && index < controlPoints.Num() );
|
|
return controlPoints[index];
|
|
}
|
|
|
|
idVec3 *getSegmentPoint( int index ) {
|
|
assert( index >= 0 && index < splinePoints.Num() );
|
|
return splinePoints[index];
|
|
}
|
|
|
|
|
|
void setSegmentTime( int index, int time ) {
|
|
assert( index >= 0 && index < splinePoints.Num() );
|
|
splineTime[index] = time;
|
|
}
|
|
|
|
int getSegmentTime( int index ) {
|
|
assert( index >= 0 && index < splinePoints.Num() );
|
|
return (int)splineTime[index];
|
|
}
|
|
void addSegmentTime( int index, int time ) {
|
|
assert( index >= 0 && index < splinePoints.Num() );
|
|
splineTime[index] += time;
|
|
}
|
|
|
|
float totalDistance();
|
|
|
|
static idVec3 zero;
|
|
|
|
int getActiveSegment() {
|
|
return activeSegment;
|
|
}
|
|
|
|
void setActiveSegment( int i ) {
|
|
//assert(i >= 0 && (splinePoints.Num() > 0 && i < splinePoints.Num()));
|
|
activeSegment = i;
|
|
}
|
|
|
|
int numSegments() {
|
|
return splinePoints.Num();
|
|
}
|
|
|
|
void setColors( idVec3 &path, idVec3 &segment, idVec3 &control, idVec3 &active ) {
|
|
pathColor = path;
|
|
segmentColor = segment;
|
|
controlColor = control;
|
|
activeColor = active;
|
|
}
|
|
|
|
const char *getName() {
|
|
return name.c_str();
|
|
}
|
|
|
|
void setName( const char *p ) {
|
|
name = p;
|
|
}
|
|
|
|
bool validTime() {
|
|
if ( dirty ) {
|
|
buildSpline();
|
|
}
|
|
// gcc doesn't allow static casting away from bools
|
|
// why? I've no idea...
|
|
return (bool)( splineTime.Num() > 0 && splineTime.Num() == splinePoints.Num() );
|
|
}
|
|
|
|
void setTime( long t ) {
|
|
time = t;
|
|
}
|
|
|
|
void setBaseTime( long t ) {
|
|
baseTime = t;
|
|
}
|
|
|
|
protected:
|
|
idStr name;
|
|
float calcSpline( int step, float tension );
|
|
idList<idVec3*> controlPoints;
|
|
idList<idVec3*> splinePoints;
|
|
idList<double> splineTime;
|
|
idVec3 *selected;
|
|
idVec3 pathColor, segmentColor, controlColor, activeColor;
|
|
float granularity;
|
|
bool editMode;
|
|
bool dirty;
|
|
int activeSegment;
|
|
long baseTime;
|
|
long time;
|
|
friend class idCamera;
|
|
};
|
|
|
|
// time in milliseconds
|
|
// velocity where 1.0 equal rough walking speed
|
|
struct idVelocity {
|
|
idVelocity( long start, long duration, float s ) {
|
|
startTime = start;
|
|
time = duration;
|
|
speed = s;
|
|
}
|
|
long startTime;
|
|
long time;
|
|
float speed;
|
|
};
|
|
|
|
// can either be a look at or origin position for a camera
|
|
//
|
|
class idCameraPosition : public idPointListInterface {
|
|
public:
|
|
|
|
virtual void clearVelocities() {
|
|
for ( int i = 0; i < velocities.Num(); i++ ) {
|
|
delete velocities[i];
|
|
velocities[i] = NULL;
|
|
}
|
|
velocities.Clear();
|
|
}
|
|
|
|
virtual void clear() {
|
|
editMode = false;
|
|
clearVelocities();
|
|
}
|
|
|
|
idCameraPosition( const char *p ) {
|
|
name = p;
|
|
}
|
|
|
|
idCameraPosition() {
|
|
time = 0;
|
|
name = "position";
|
|
}
|
|
|
|
idCameraPosition( long t ) {
|
|
time = t;
|
|
}
|
|
|
|
virtual ~idCameraPosition() {
|
|
clear();
|
|
}
|
|
|
|
|
|
// this can be done with RTTI syntax but i like the derived classes setting a type
|
|
// makes serialization a bit easier to see
|
|
//
|
|
enum positionType {
|
|
FIXED = 0x00,
|
|
INTERPOLATED,
|
|
SPLINE,
|
|
POSITION_COUNT
|
|
};
|
|
|
|
|
|
virtual void start( long t ) {
|
|
startTime = t;
|
|
}
|
|
|
|
long getTime() {
|
|
return time;
|
|
}
|
|
|
|
virtual void setTime( long t ) {
|
|
time = t;
|
|
}
|
|
|
|
float getBaseVelocity() {
|
|
return baseVelocity;
|
|
}
|
|
|
|
float getVelocity( long t ) {
|
|
long check = t - startTime;
|
|
for ( int i = 0; i < velocities.Num(); i++ ) {
|
|
if ( check >= velocities[i]->startTime && check <= velocities[i]->startTime + velocities[i]->time ) {
|
|
return velocities[i]->speed;
|
|
}
|
|
}
|
|
return baseVelocity;
|
|
}
|
|
|
|
void addVelocity( long start, long duration, float speed ) {
|
|
velocities.Append( new idVelocity( start, duration, speed ) );
|
|
}
|
|
|
|
virtual const idVec3 *getPosition( long t ) {
|
|
assert( true );
|
|
return NULL;
|
|
}
|
|
|
|
virtual void draw( bool editMode ) {};
|
|
|
|
virtual void parse( const char *( *text ) ) {};
|
|
virtual void write( fileHandle_t file, const char *name );
|
|
virtual bool parseToken( const char *key, const char *( *text ) );
|
|
|
|
const char *getName() {
|
|
return name.c_str();
|
|
}
|
|
|
|
void setName( const char *p ) {
|
|
name = p;
|
|
}
|
|
|
|
virtual void startEdit() {
|
|
editMode = true;
|
|
}
|
|
|
|
virtual void stopEdit() {
|
|
editMode = false;
|
|
}
|
|
|
|
virtual void draw() {};
|
|
|
|
const char *typeStr() {
|
|
return positionStr[static_cast<int>( type )];
|
|
}
|
|
|
|
void calcVelocity( float distance ) {
|
|
float secs = (float)time / 1000;
|
|
baseVelocity = distance / secs;
|
|
}
|
|
|
|
protected:
|
|
static const char* positionStr[POSITION_COUNT];
|
|
long startTime;
|
|
long time;
|
|
idCameraPosition::positionType type;
|
|
idStr name;
|
|
bool editMode;
|
|
idList<idVelocity*> velocities;
|
|
float baseVelocity;
|
|
};
|
|
|
|
class idFixedPosition : public idCameraPosition {
|
|
public:
|
|
|
|
void init() {
|
|
pos.Zero();
|
|
type = idCameraPosition::FIXED;
|
|
}
|
|
|
|
idFixedPosition() : idCameraPosition() {
|
|
init();
|
|
}
|
|
|
|
idFixedPosition( idVec3 p ) : idCameraPosition() {
|
|
init();
|
|
pos = p;
|
|
}
|
|
|
|
virtual void addPoint( const idVec3 &v ) {
|
|
pos = v;
|
|
}
|
|
|
|
virtual void addPoint( const float x, const float y, const float z ) {
|
|
pos.set( x, y, z );
|
|
}
|
|
|
|
|
|
~idFixedPosition() {
|
|
}
|
|
|
|
virtual const idVec3 *getPosition( long t ) {
|
|
return &pos;
|
|
}
|
|
|
|
void parse( const char *( *text ) );
|
|
void write( fileHandle_t file, const char *name );
|
|
|
|
virtual int numPoints() {
|
|
return 1;
|
|
}
|
|
|
|
virtual idVec3 *getPoint( int index ) {
|
|
if ( index != 0 ) {
|
|
assert( true );
|
|
}
|
|
;
|
|
return &pos;
|
|
}
|
|
|
|
virtual void draw( bool editMode ) {
|
|
glLabeledPoint( blue, pos, ( editMode ) ? 5 : 3, "Fixed point" );
|
|
}
|
|
|
|
protected:
|
|
idVec3 pos;
|
|
};
|
|
|
|
class idInterpolatedPosition : public idCameraPosition {
|
|
public:
|
|
|
|
void init() {
|
|
type = idCameraPosition::INTERPOLATED;
|
|
first = true;
|
|
startPos.Zero();
|
|
endPos.Zero();
|
|
}
|
|
|
|
idInterpolatedPosition() : idCameraPosition() {
|
|
init();
|
|
}
|
|
|
|
idInterpolatedPosition( idVec3 start, idVec3 end, long time ) : idCameraPosition( time ) {
|
|
init();
|
|
startPos = start;
|
|
endPos = end;
|
|
}
|
|
|
|
~idInterpolatedPosition() {
|
|
}
|
|
|
|
virtual const idVec3 *getPosition( long t );
|
|
|
|
void parse( const char *( *text ) );
|
|
void write( fileHandle_t file, const char *name );
|
|
|
|
virtual int numPoints() {
|
|
return 2;
|
|
}
|
|
|
|
virtual idVec3 *getPoint( int index ) {
|
|
assert( index >= 0 && index < 2 );
|
|
if ( index == 0 ) {
|
|
return &startPos;
|
|
}
|
|
return &endPos;
|
|
}
|
|
|
|
virtual void addPoint( const float x, const float y, const float z ) {
|
|
if ( first ) {
|
|
startPos.set( x, y, z );
|
|
first = false;
|
|
}
|
|
else {
|
|
endPos.set( x, y, z );
|
|
first = true;
|
|
}
|
|
}
|
|
|
|
virtual void addPoint( const idVec3 &v ) {
|
|
if ( first ) {
|
|
startPos = v;
|
|
first = false;
|
|
}
|
|
else {
|
|
endPos = v;
|
|
first = true;
|
|
}
|
|
}
|
|
|
|
virtual void draw( bool editMode ) {
|
|
glLabeledPoint( blue, startPos, ( editMode ) ? 5 : 3, "Start interpolated" );
|
|
glLabeledPoint( blue, endPos, ( editMode ) ? 5 : 3, "End interpolated" );
|
|
qglBegin( GL_LINES );
|
|
qglVertex3fv( startPos );
|
|
qglVertex3fv( endPos );
|
|
qglEnd();
|
|
}
|
|
|
|
virtual void start( long t ) {
|
|
idCameraPosition::start( t );
|
|
lastTime = startTime;
|
|
distSoFar = 0.0;
|
|
idVec3 temp = startPos;
|
|
temp -= endPos;
|
|
calcVelocity( temp.Length() );
|
|
}
|
|
|
|
protected:
|
|
bool first;
|
|
idVec3 startPos;
|
|
idVec3 endPos;
|
|
long lastTime;
|
|
float distSoFar;
|
|
};
|
|
|
|
class idSplinePosition : public idCameraPosition {
|
|
public:
|
|
|
|
void init() {
|
|
type = idCameraPosition::SPLINE;
|
|
}
|
|
|
|
idSplinePosition() : idCameraPosition() {
|
|
init();
|
|
}
|
|
|
|
idSplinePosition( long time ) : idCameraPosition( time ) {
|
|
init();
|
|
}
|
|
|
|
~idSplinePosition() {
|
|
}
|
|
|
|
virtual void start( long t ) {
|
|
idCameraPosition::start( t );
|
|
target.initPosition( t, time );
|
|
lastTime = startTime;
|
|
distSoFar = 0.0;
|
|
calcVelocity( target.totalDistance() );
|
|
}
|
|
|
|
//virtual const idVec3 *getPosition(long t) {
|
|
// return target.getPosition(t);
|
|
//}
|
|
virtual const idVec3 *getPosition( long t );
|
|
|
|
|
|
//virtual const idVec3 *getPosition(long t) const {
|
|
|
|
void addControlPoint( idVec3 &v ) {
|
|
target.addPoint( v );
|
|
}
|
|
|
|
void parse( const char *( *text ) );
|
|
void write( fileHandle_t file, const char *name );
|
|
|
|
virtual int numPoints() {
|
|
return target.numPoints();
|
|
}
|
|
|
|
virtual idVec3 *getPoint( int index ) {
|
|
return target.getPoint( index );
|
|
}
|
|
|
|
virtual void addPoint( const idVec3 &v ) {
|
|
target.addPoint( v );
|
|
}
|
|
|
|
virtual void addPoint( const float x, const float y, const float z ) {
|
|
target.addPoint( x, y, z );
|
|
}
|
|
|
|
virtual void draw( bool editMode ) {
|
|
target.draw( editMode );
|
|
}
|
|
|
|
virtual void updateSelection( const idVec3 &move ) {
|
|
idCameraPosition::updateSelection( move );
|
|
target.buildSpline();
|
|
}
|
|
|
|
protected:
|
|
idSplineList target;
|
|
long lastTime;
|
|
float distSoFar;
|
|
};
|
|
|
|
class idCameraFOV {
|
|
public:
|
|
|
|
idCameraFOV() {
|
|
time = 0;
|
|
length = 0;
|
|
fov = 90;
|
|
}
|
|
|
|
idCameraFOV( int v ) {
|
|
time = 0;
|
|
length = 0;
|
|
fov = v;
|
|
}
|
|
|
|
idCameraFOV( int s, int e, long t ) {
|
|
startFOV = s;
|
|
endFOV = e;
|
|
length = t;
|
|
}
|
|
|
|
|
|
~idCameraFOV(){}
|
|
|
|
void setFOV( float f ) {
|
|
fov = f;
|
|
}
|
|
|
|
float getFOV( long t ) {
|
|
if ( length ) {
|
|
float percent = ( t - startTime ) / length;
|
|
if ( percent < 0.0 ) {
|
|
percent = 0.0;
|
|
}
|
|
else if ( percent > 1.0 ) {
|
|
percent = 1.0;
|
|
}
|
|
float temp = endFOV - startFOV;
|
|
temp *= percent;
|
|
fov = startFOV + temp;
|
|
|
|
if ( percent == 1.0 ) {
|
|
length = 0.0;
|
|
}
|
|
}
|
|
return fov;
|
|
}
|
|
|
|
void start( long t ) {
|
|
startTime = t;
|
|
}
|
|
|
|
void reset( float startfov, float endfov, int start, float len ) {
|
|
startFOV = startfov;
|
|
endFOV = endfov;
|
|
startTime = start;
|
|
length = len * 1000;
|
|
}
|
|
|
|
void parse( const char *( *text ) );
|
|
void write( fileHandle_t file, const char *name );
|
|
|
|
protected:
|
|
float fov;
|
|
float startFOV;
|
|
float endFOV;
|
|
int startTime;
|
|
int time;
|
|
float length;
|
|
};
|
|
|
|
|
|
|
|
|
|
class idCameraEvent {
|
|
public: // parameters
|
|
enum eventType {
|
|
EVENT_NA = 0x00,
|
|
EVENT_WAIT, //
|
|
EVENT_TARGETWAIT, //
|
|
EVENT_SPEED, //
|
|
EVENT_TARGET, // char(name)
|
|
EVENT_SNAPTARGET, //
|
|
EVENT_FOV, // int(time), int(targetfov)
|
|
EVENT_CMD, //
|
|
EVENT_TRIGGER, //
|
|
EVENT_STOP, //
|
|
EVENT_CAMERA, //
|
|
EVENT_FADEOUT, // int(time)
|
|
EVENT_FADEIN, // int(time)
|
|
EVENT_FEATHER, //
|
|
EVENT_COUNT
|
|
};
|
|
|
|
static const char* eventStr[EVENT_COUNT];
|
|
|
|
idCameraEvent() {
|
|
paramStr = "";
|
|
type = EVENT_NA;
|
|
time = 0;
|
|
}
|
|
|
|
idCameraEvent( eventType t, const char *param, long n ) {
|
|
type = t;
|
|
paramStr = param;
|
|
time = n;
|
|
}
|
|
|
|
~idCameraEvent() {};
|
|
|
|
eventType getType() {
|
|
return type;
|
|
}
|
|
|
|
const char *typeStr() {
|
|
return eventStr[static_cast<int>( type )];
|
|
}
|
|
|
|
const char *getParam() {
|
|
return paramStr.c_str();
|
|
}
|
|
|
|
long getTime() {
|
|
return time;
|
|
}
|
|
|
|
void setTime( long n ) {
|
|
time = n;
|
|
}
|
|
|
|
void parse( const char *( *text ) );
|
|
void write( fileHandle_t file, const char *name );
|
|
|
|
void setTriggered( bool b ) {
|
|
triggered = b;
|
|
}
|
|
|
|
bool getTriggered() {
|
|
return triggered;
|
|
}
|
|
|
|
protected:
|
|
eventType type;
|
|
idStr paramStr;
|
|
long time;
|
|
bool triggered;
|
|
|
|
};
|
|
|
|
class idCameraDef {
|
|
public:
|
|
|
|
void clear() {
|
|
currentCameraPosition = 0;
|
|
cameraRunning = false;
|
|
lastDirection.Zero();
|
|
baseTime = 30;
|
|
activeTarget = 0;
|
|
name = "camera01";
|
|
fov.setFOV( 90 );
|
|
int i;
|
|
for ( i = 0; i < targetPositions.Num(); i++ ) {
|
|
delete targetPositions[i];
|
|
}
|
|
for ( i = 0; i < events.Num(); i++ ) {
|
|
delete events[i];
|
|
}
|
|
delete cameraPosition;
|
|
cameraPosition = NULL;
|
|
events.Clear();
|
|
targetPositions.Clear();
|
|
}
|
|
|
|
idCameraPosition *startNewCamera( idCameraPosition::positionType type ) {
|
|
clear();
|
|
if ( type == idCameraPosition::SPLINE ) {
|
|
cameraPosition = new idSplinePosition();
|
|
}
|
|
else if ( type == idCameraPosition::INTERPOLATED ) {
|
|
cameraPosition = new idInterpolatedPosition();
|
|
}
|
|
else {
|
|
cameraPosition = new idFixedPosition();
|
|
}
|
|
return cameraPosition;
|
|
}
|
|
|
|
idCameraDef() {
|
|
cameraPosition = NULL;
|
|
clear();
|
|
}
|
|
|
|
~idCameraDef() {
|
|
clear();
|
|
}
|
|
|
|
void addEvent( idCameraEvent::eventType t, const char *param, long time );
|
|
|
|
void addEvent( idCameraEvent *event );
|
|
|
|
void removeEvent( int index );
|
|
|
|
static int sortEvents( const void *p1, const void *p2 );
|
|
|
|
int numEvents() {
|
|
return events.Num();
|
|
}
|
|
|
|
idCameraEvent *getEvent( int index ) {
|
|
assert( index >= 0 && index < events.Num() );
|
|
return events[index];
|
|
}
|
|
|
|
void parse( const char *( *text ) );
|
|
bool load( const char *filename );
|
|
void save( const char *filename );
|
|
|
|
void buildCamera();
|
|
|
|
//idSplineList *getcameraPosition() {
|
|
// return &cameraPosition;
|
|
//}
|
|
|
|
static idCameraPosition *newFromType( idCameraPosition::positionType t ) {
|
|
switch ( t ) {
|
|
case idCameraPosition::FIXED: return new idFixedPosition();
|
|
case idCameraPosition::INTERPOLATED: return new idInterpolatedPosition();
|
|
case idCameraPosition::SPLINE: return new idSplinePosition();
|
|
default:
|
|
break;
|
|
};
|
|
return NULL;
|
|
}
|
|
|
|
void addTarget( const char *name, idCameraPosition::positionType type );
|
|
|
|
idCameraPosition *getActiveTarget() {
|
|
if ( targetPositions.Num() == 0 ) {
|
|
addTarget( NULL, idCameraPosition::FIXED );
|
|
}
|
|
return targetPositions[activeTarget];
|
|
}
|
|
|
|
idCameraPosition *getActiveTarget( int index ) {
|
|
if ( targetPositions.Num() == 0 ) {
|
|
addTarget( NULL, idCameraPosition::FIXED );
|
|
return targetPositions[0];
|
|
}
|
|
return targetPositions[index];
|
|
}
|
|
|
|
int numTargets() {
|
|
return targetPositions.Num();
|
|
}
|
|
|
|
|
|
void setActiveTargetByName( const char *name ) {
|
|
for ( int i = 0; i < targetPositions.Num(); i++ ) {
|
|
if ( Q_stricmp( name, targetPositions[i]->getName() ) == 0 ) {
|
|
setActiveTarget( i );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void setActiveTarget( int index ) {
|
|
assert( index >= 0 && index < targetPositions.Num() );
|
|
activeTarget = index;
|
|
}
|
|
|
|
void setRunning( bool b ) {
|
|
cameraRunning = b;
|
|
}
|
|
|
|
void setBaseTime( float f ) {
|
|
baseTime = f;
|
|
}
|
|
|
|
float getBaseTime() {
|
|
return baseTime;
|
|
}
|
|
|
|
float getTotalTime() {
|
|
return totalTime;
|
|
}
|
|
|
|
void startCamera( long t );
|
|
void stopCamera() {
|
|
cameraRunning = true;
|
|
}
|
|
void getActiveSegmentInfo( int segment, idVec3 &origin, idVec3 &direction, float *fv );
|
|
|
|
bool getCameraInfo( long time, idVec3 &origin, idVec3 &direction, float *fv );
|
|
bool getCameraInfo( long time, float *origin, float *direction, float *fv ) {
|
|
idVec3 org, dir;
|
|
org[0] = origin[0];
|
|
org[1] = origin[1];
|
|
org[2] = origin[2];
|
|
dir[0] = direction[0];
|
|
dir[1] = direction[1];
|
|
dir[2] = direction[2];
|
|
bool b = getCameraInfo( time, org, dir, fv );
|
|
origin[0] = org[0];
|
|
origin[1] = org[1];
|
|
origin[2] = org[2];
|
|
direction[0] = dir[0];
|
|
direction[1] = dir[1];
|
|
direction[2] = dir[2];
|
|
return b;
|
|
}
|
|
|
|
void draw( bool editMode ) {
|
|
// gcc doesn't allow casting away from bools
|
|
// why? I've no idea...
|
|
if ( cameraPosition ) {
|
|
cameraPosition->draw( (bool)( ( editMode || cameraRunning ) && cameraEdit ) );
|
|
int count = targetPositions.Num();
|
|
for ( int i = 0; i < count; i++ ) {
|
|
targetPositions[i]->draw( (bool)( ( editMode || cameraRunning ) && i == activeTarget && !cameraEdit ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
int numSegments() {
|
|
if (cameraEdit) {
|
|
return cameraPosition.numSegments();
|
|
}
|
|
return getTargetSpline()->numSegments();
|
|
}
|
|
|
|
int getActiveSegment() {
|
|
if (cameraEdit) {
|
|
return cameraPosition.getActiveSegment();
|
|
}
|
|
return getTargetSpline()->getActiveSegment();
|
|
}
|
|
|
|
void setActiveSegment(int i) {
|
|
if (cameraEdit) {
|
|
cameraPosition.setActiveSegment(i);
|
|
} else {
|
|
getTargetSpline()->setActiveSegment(i);
|
|
}
|
|
}
|
|
*/
|
|
int numPoints() {
|
|
if ( cameraEdit ) {
|
|
return cameraPosition->numPoints();
|
|
}
|
|
return getActiveTarget()->numPoints();
|
|
}
|
|
|
|
const idVec3 *getPoint( int index ) {
|
|
if ( cameraEdit ) {
|
|
return cameraPosition->getPoint( index );
|
|
}
|
|
return getActiveTarget()->getPoint( index );
|
|
}
|
|
|
|
void stopEdit() {
|
|
editMode = false;
|
|
if ( cameraEdit ) {
|
|
cameraPosition->stopEdit();
|
|
}
|
|
else {
|
|
getActiveTarget()->stopEdit();
|
|
}
|
|
}
|
|
|
|
void startEdit( bool camera ) {
|
|
cameraEdit = camera;
|
|
if ( camera ) {
|
|
cameraPosition->startEdit();
|
|
for ( int i = 0; i < targetPositions.Num(); i++ ) {
|
|
targetPositions[i]->stopEdit();
|
|
}
|
|
}
|
|
else {
|
|
getActiveTarget()->startEdit();
|
|
cameraPosition->stopEdit();
|
|
}
|
|
editMode = true;
|
|
}
|
|
|
|
bool waitEvent( int index );
|
|
|
|
const char *getName() {
|
|
return name.c_str();
|
|
}
|
|
|
|
void setName( const char *p ) {
|
|
name = p;
|
|
}
|
|
|
|
idCameraPosition *getPositionObj() {
|
|
if ( cameraPosition == NULL ) {
|
|
cameraPosition = new idFixedPosition();
|
|
}
|
|
return cameraPosition;
|
|
}
|
|
|
|
protected:
|
|
idStr name;
|
|
int currentCameraPosition;
|
|
idVec3 lastDirection;
|
|
bool cameraRunning;
|
|
idCameraPosition *cameraPosition;
|
|
idList<idCameraPosition*> targetPositions;
|
|
idList<idCameraEvent*> events;
|
|
idCameraFOV fov;
|
|
int activeTarget;
|
|
float totalTime;
|
|
float baseTime;
|
|
long startTime;
|
|
|
|
bool cameraEdit;
|
|
bool editMode;
|
|
};
|
|
|
|
extern bool g_splineMode;
|
|
|
|
extern idCameraDef *g_splineList;
|
|
|
|
|
|
#endif
|