400 lines
14 KiB
C
400 lines
14 KiB
C
|
/*
|
||
|
===========================================================================
|
||
|
|
||
|
Doom 3 GPL Source Code
|
||
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||
|
|
||
|
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
|
||
|
|
||
|
Doom 3 Source Code is free software: you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation, either version 3 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
Doom 3 Source Code is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
In addition, the Doom 3 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 Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
||
|
|
||
|
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.
|
||
|
|
||
|
===========================================================================
|
||
|
*/
|
||
|
|
||
|
#ifndef __SPLINES_H__
|
||
|
#define __SPLINES_H__
|
||
|
|
||
|
extern void glBox(idVec4 &color, idVec3 &point, float size);
|
||
|
extern void glLabeledPoint(idVec4 &color, idVec3 &point, float size, const char *label);
|
||
|
|
||
|
|
||
|
class idPointListInterface {
|
||
|
public:
|
||
|
idPointListInterface() { selectedPoints.Clear(); };
|
||
|
~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 numSelectedPoints() { return selectedPoints.Num(); }
|
||
|
idVec3 * getSelectedPoint( int index );
|
||
|
int selectPointByRay( const idVec3 &origin, const idVec3 &direction, bool single );
|
||
|
int isPointSelected( int index );
|
||
|
int selectPoint( int index, bool single );
|
||
|
void selectAll();
|
||
|
void deselectAll();
|
||
|
virtual void updateSelection( const idVec3 &move );
|
||
|
void drawSelection();
|
||
|
|
||
|
protected:
|
||
|
idList<int> selectedPoints;
|
||
|
};
|
||
|
|
||
|
|
||
|
class idSplineList {
|
||
|
friend class idCamera;
|
||
|
|
||
|
public:
|
||
|
|
||
|
idSplineList() { clear(); }
|
||
|
idSplineList( const char *p ) { clear(); name = p; }
|
||
|
~idSplineList() { clear(); }
|
||
|
|
||
|
void clearControl();
|
||
|
void clearSpline();
|
||
|
void parse( idParser *src );
|
||
|
void write( idFile *f, const char *name );
|
||
|
|
||
|
void clear();
|
||
|
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 splineTime[index]; }
|
||
|
void addSegmentTime(int index, int time) { assert(index >= 0 && index < splinePoints.Num()); splineTime[index] += time; }
|
||
|
float totalDistance();
|
||
|
|
||
|
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(idVec4 &path, idVec4 &segment, idVec4 &control, idVec4 &active);
|
||
|
|
||
|
const char * getName() { return name.c_str(); }
|
||
|
void setName( const char *p ) { name = p; }
|
||
|
|
||
|
bool validTime();
|
||
|
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;
|
||
|
idVec4 pathColor, segmentColor, controlColor, activeColor;
|
||
|
float granularity;
|
||
|
bool editMode;
|
||
|
bool dirty;
|
||
|
int activeSegment;
|
||
|
long baseTime;
|
||
|
long time;
|
||
|
};
|
||
|
|
||
|
// 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:
|
||
|
|
||
|
idCameraPosition() { time = 0; name = "position"; }
|
||
|
idCameraPosition( const char *p ) { name = p; }
|
||
|
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 clearVelocities();
|
||
|
virtual void clear() { editMode = false; time = 5000; clearVelocities(); }
|
||
|
virtual void start( long t ) { startTime = t; }
|
||
|
long getTime() { return time; }
|
||
|
virtual void setTime(long t) { time = t; }
|
||
|
float getVelocity( long t );
|
||
|
float getBaseVelocity() { return baseVelocity; }
|
||
|
void addVelocity( long start, long duration, float speed ) { velocities.Append(new idVelocity(start, duration, speed)); }
|
||
|
virtual const idVec3 *getPosition( long t ) { return NULL; }
|
||
|
virtual void draw( bool editMode ) {};
|
||
|
virtual void parse( idParser *src ) {};
|
||
|
virtual void write( idFile *f, const char *name);
|
||
|
virtual bool parseToken( const idStr &key, idParser *src );
|
||
|
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;
|
||
|
positionType type;
|
||
|
idStr name;
|
||
|
bool editMode;
|
||
|
idList<idVelocity*> velocities;
|
||
|
float baseVelocity;
|
||
|
};
|
||
|
|
||
|
class idFixedPosition : public idCameraPosition {
|
||
|
public:
|
||
|
|
||
|
idFixedPosition() : idCameraPosition() { init(); }
|
||
|
idFixedPosition(idVec3 p) : idCameraPosition() { init(); pos = p; }
|
||
|
~idFixedPosition() { }
|
||
|
|
||
|
void init() { pos.Zero(); type = idCameraPosition::FIXED; }
|
||
|
|
||
|
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); }
|
||
|
virtual const idVec3 *getPosition( long t ) { return &pos; }
|
||
|
void parse( idParser *src );
|
||
|
void write( idFile *f, const char *name );
|
||
|
virtual int numPoints() { return 1; }
|
||
|
virtual idVec3 * getPoint( int index ) { assert( index == 0 ); return &pos; }
|
||
|
virtual void draw( bool editMode ) { glLabeledPoint(colorBlue, pos, (editMode) ? 5 : 3, "Fixed point"); }
|
||
|
|
||
|
protected:
|
||
|
idVec3 pos;
|
||
|
};
|
||
|
|
||
|
class idInterpolatedPosition : public idCameraPosition {
|
||
|
public:
|
||
|
idInterpolatedPosition() : idCameraPosition() { init(); }
|
||
|
idInterpolatedPosition( idVec3 start, idVec3 end, long time ) : idCameraPosition(time) { init(); startPos = start; endPos = end; }
|
||
|
~idInterpolatedPosition() { }
|
||
|
|
||
|
void init() { type = idCameraPosition::INTERPOLATED; first = true; startPos.Zero(); endPos.Zero(); }
|
||
|
|
||
|
virtual const idVec3 *getPosition(long t);
|
||
|
void parse( idParser *src );
|
||
|
void write( idFile *f, const char *name );
|
||
|
virtual int numPoints() { return 2; }
|
||
|
virtual idVec3 * getPoint( int index );
|
||
|
virtual void addPoint( const float x, const float y, const float z );
|
||
|
virtual void addPoint( const idVec3 &v );
|
||
|
virtual void draw( bool editMode );
|
||
|
virtual void start( long t );
|
||
|
|
||
|
protected:
|
||
|
bool first;
|
||
|
idVec3 startPos;
|
||
|
idVec3 endPos;
|
||
|
long lastTime;
|
||
|
float distSoFar;
|
||
|
};
|
||
|
|
||
|
class idSplinePosition : public idCameraPosition {
|
||
|
public:
|
||
|
|
||
|
idSplinePosition() : idCameraPosition() { init(); }
|
||
|
idSplinePosition( long time ) : idCameraPosition( time ) { init(); }
|
||
|
~idSplinePosition() { }
|
||
|
|
||
|
void init() { type = idCameraPosition::SPLINE; }
|
||
|
virtual void start( long t );
|
||
|
virtual const idVec3 *getPosition( long t );
|
||
|
void addControlPoint( idVec3 &v ) { target.addPoint(v); }
|
||
|
void parse( idParser *src );
|
||
|
void write( idFile *f, 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 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; fov = 90; }
|
||
|
idCameraFOV( int v ) { time = 0; fov = v; }
|
||
|
idCameraFOV( int s, int e, long t ) { startFOV = s; endFOV = e; time = t; }
|
||
|
~idCameraFOV() { }
|
||
|
|
||
|
void SetFOV( float f ) { fov = f; }
|
||
|
float GetFOV( long t );
|
||
|
void start( long t ) { startTime = t; }
|
||
|
void reset( float startfov, float endfov, int start, int len );
|
||
|
void parse( idParser *src );
|
||
|
void write( idFile *f, const char *name );
|
||
|
|
||
|
protected:
|
||
|
float fov;
|
||
|
float startFOV;
|
||
|
float endFOV;
|
||
|
int startTime;
|
||
|
int time;
|
||
|
int length;
|
||
|
};
|
||
|
|
||
|
class idCameraEvent {
|
||
|
public:
|
||
|
enum eventType {
|
||
|
EVENT_NA = 0x00,
|
||
|
EVENT_WAIT,
|
||
|
EVENT_TARGETWAIT,
|
||
|
EVENT_SPEED,
|
||
|
EVENT_TARGET,
|
||
|
EVENT_SNAPTARGET,
|
||
|
EVENT_FOV,
|
||
|
EVENT_CMD,
|
||
|
EVENT_TRIGGER,
|
||
|
EVENT_STOP,
|
||
|
EVENT_CAMERA,
|
||
|
EVENT_FADEOUT,
|
||
|
EVENT_FADEIN,
|
||
|
EVENT_FEATHER,
|
||
|
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( idParser *src );
|
||
|
void write( idFile *f, const char *name );
|
||
|
void setTriggered( bool b ) { triggered = b; }
|
||
|
bool getTriggered() { return triggered; }
|
||
|
|
||
|
static const char * eventStr[EVENT_COUNT];
|
||
|
|
||
|
protected:
|
||
|
eventType type;
|
||
|
idStr paramStr;
|
||
|
long time;
|
||
|
bool triggered;
|
||
|
|
||
|
};
|
||
|
|
||
|
class idCameraDef {
|
||
|
public:
|
||
|
idCameraDef() { cameraPosition = NULL; clear(); }
|
||
|
~idCameraDef() { clear(); }
|
||
|
|
||
|
void clear();
|
||
|
idCameraPosition * startNewCamera(idCameraPosition::positionType type);
|
||
|
void addEvent( idCameraEvent::eventType t, const char *param, long time );
|
||
|
void addEvent( idCameraEvent *event );
|
||
|
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( idParser *src );
|
||
|
bool load( const char *filename );
|
||
|
void save( const char *filename );
|
||
|
void buildCamera();
|
||
|
|
||
|
void addTarget( const char *name, idCameraPosition::positionType type );
|
||
|
|
||
|
idCameraPosition * getActiveTarget();
|
||
|
idCameraPosition * getActiveTarget( int index );
|
||
|
int numTargets() { return targetPositions.Num(); }
|
||
|
void setActiveTargetByName(const char *name);
|
||
|
void setActiveTarget( int 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);
|
||
|
void draw( bool editMode );
|
||
|
int numPoints();
|
||
|
const idVec3 * getPoint( int index );
|
||
|
void stopEdit();
|
||
|
void startEdit( bool camera );
|
||
|
bool waitEvent( int index );
|
||
|
const char * getName() { return name.c_str(); }
|
||
|
void setName( const char *p ) { name = p; }
|
||
|
idCameraPosition * getPositionObj();
|
||
|
|
||
|
static idCameraPosition *newFromType( idCameraPosition::positionType t );
|
||
|
|
||
|
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 /* !__SPLINES_H__ */
|