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