/* =========================================================================== 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 . 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 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 controlPoints; idList splinePoints; idList 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(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 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(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 targetPositions; idList 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__ */