9 #include "igl_to_qgl.h"
13 #include "util_list.h"
15 #include "math_vector.h"
17 typedef int fileHandle_t;
19 extern void glBox(idVec3 &color, idVec3 &point, float size);
20 extern void glLabeledPoint(idVec3 &color, idVec3 &point, float size, const char *label);
22 static idVec4 blue(0, 0, 1, 1);
23 static idVec4 red(1, 0, 0, 1);
25 class idPointListInterface {
27 idPointListInterface() {
28 selectedPoints.Clear();
30 virtual ~idPointListInterface() {};
32 virtual int numPoints() {
36 virtual void addPoint(const float x, const float y, const float z) {}
37 virtual void addPoint(const idVec3 &v) {}
38 virtual void removePoint(int index) {}
39 virtual idVec3 *getPoint(int index) { return NULL; }
41 int selectPointByRay(float ox, float oy, float oz, float dx, float dy, float dz, bool single) {
42 idVec3 origin(ox, oy, oz);
43 idVec3 dir(dx, dy, dz);
44 return selectPointByRay(origin, dir, single);
47 int selectPointByRay(const idVec3 origin, const idVec3 direction, bool single) {
52 // find the point closest to the ray
57 for (i=0; i < count; i++) {
61 d = DotProduct(temp, direction);
62 __VectorMA (origin, d, direction, temp);
72 selectPoint(besti, single);
78 int isPointSelected(int index) {
79 int count = selectedPoints.Num();
80 for (int i = 0; i < count; i++) {
81 if (selectedPoints[i] == index) {
88 int selectPoint(int index, bool single) {
89 if (index >= 0 && index < numPoints()) {
93 if (isPointSelected(index) >= 0) {
94 selectedPoints.Remove(index);
97 return selectedPoints.Append(index);
103 selectedPoints.Clear();
104 for (int i = 0; i < numPoints(); i++) {
105 selectedPoints.Append(i);
110 selectedPoints.Clear();
113 int numSelectedPoints();
115 idVec3 *getSelectedPoint(int index) {
116 assert(index >= 0 && index < numSelectedPoints());
117 return getPoint(selectedPoints[index]);
120 virtual void updateSelection(float x, float y, float z) {
121 idVec3 move(x, y, z);
122 updateSelection(move);
125 virtual void updateSelection(const idVec3 &move) {
126 int count = selectedPoints.Num();
127 for (int i = 0; i < count; i++) {
128 *getPoint(selectedPoints[i]) += move;
132 void drawSelection() {
133 int count = selectedPoints.Num();
134 for (int i = 0; i < count; i++) {
135 glBox(red, *getPoint(selectedPoints[i]), 4);
140 idList<int> selectedPoints;
153 idSplineList(const char *p) {
162 void clearControl() {
163 for (int i = 0; i < controlPoints.Num(); i++) {
164 delete controlPoints[i];
166 controlPoints.Clear();
170 for (int i = 0; i < splinePoints.Num(); i++) {
171 delete splinePoints[i];
173 splinePoints.Clear();
176 void parse(const char *(*text));
177 void write(fileHandle_t file, const char *name);
186 granularity = 0.025f;
187 pathColor.set(1.0f, 0.5f, 0.0f);
188 controlColor.set(0.7f, 0.0f, 1.0f);
189 segmentColor.set(0.0f, 0.0f, 1.0f);
190 activeColor.set(1.0f, 0.0f, 0.0f);
193 void initPosition(long startTime, long totalTime);
194 const idVec3 *getPosition(long time);
197 void draw(bool editMode);
198 void addToRenderer();
200 void setSelectedPoint(idVec3 *p);
201 idVec3 *getSelectedPoint() {
205 void addPoint(const idVec3 &v) {
206 controlPoints.Append(new idVec3(v));
210 void addPoint(float x, float y, float z) {
211 controlPoints.Append(new idVec3(x, y, z));
215 void updateSelection(const idVec3 &move);
227 void setGranularity(float f) {
231 float getGranularity() {
236 return controlPoints.Num();
239 idVec3 *getPoint(int index) {
240 assert(index >= 0 && index < controlPoints.Num());
241 return controlPoints[index];
244 idVec3 *getSegmentPoint(int index) {
245 assert(index >= 0 && index < splinePoints.Num());
246 return splinePoints[index];
250 void setSegmentTime(int index, int time) {
251 assert(index >= 0 && index < splinePoints.Num());
252 splineTime[index] = time;
255 int getSegmentTime(int index) {
256 assert(index >= 0 && index < splinePoints.Num());
257 return (int)splineTime[index];
259 void addSegmentTime(int index, int time) {
260 assert(index >= 0 && index < splinePoints.Num());
261 splineTime[index] += time;
264 float totalDistance();
268 int getActiveSegment() {
269 return activeSegment;
272 void setActiveSegment(int i) {
273 //assert(i >= 0 && (splinePoints.Num() > 0 && i < splinePoints.Num()));
278 return splinePoints.Num();
281 void setColors(idVec3 &path, idVec3 &segment, idVec3 &control, idVec3 &active) {
283 segmentColor = segment;
284 controlColor = control;
285 activeColor = active;
288 const char *getName() {
292 void setName(const char *p) {
300 // gcc doesn't allow static casting away from bools
301 // why? I've no idea...
302 return (bool)(splineTime.Num() > 0 && splineTime.Num() == splinePoints.Num());
305 void setTime(long t) {
309 void setBaseTime(long t) {
315 float calcSpline(int step, float tension);
316 idList<idVec3*> controlPoints;
317 idList<idVec3*> splinePoints;
318 idList<double> splineTime;
320 idVec3 pathColor, segmentColor, controlColor, activeColor;
327 friend class idCamera;
330 // time in milliseconds
331 // velocity where 1.0 equal rough walking speed
333 idVelocity(long start, long duration, float s) {
343 // can either be a look at or origin position for a camera
345 class idCameraPosition : public idPointListInterface {
348 virtual void clearVelocities() {
349 for (int i = 0; i < velocities.Num(); i++) {
350 delete velocities[i];
351 velocities[i] = NULL;
356 virtual void clear() {
361 idCameraPosition(const char *p) {
370 idCameraPosition(long t) {
374 virtual ~idCameraPosition() {
379 // this can be done with RTTI syntax but i like the derived classes setting a type
380 // makes serialization a bit easier to see
390 virtual void start(long t) {
398 virtual void setTime(long t) {
402 float getBaseVelocity() {
406 float getVelocity(long t) {
407 long check = t - startTime;
408 for (int i = 0; i < velocities.Num(); i++) {
409 if (check >= velocities[i]->startTime && check <= velocities[i]->startTime + velocities[i]->time) {
410 return velocities[i]->speed;
416 void addVelocity(long start, long duration, float speed) {
417 velocities.Append(new idVelocity(start, duration, speed));
420 virtual const idVec3 *getPosition(long t) {
425 virtual void draw(bool editMode) {};
427 virtual void parse(const char *(*text)) {};
428 virtual void write(fileHandle_t file, const char *name);
429 virtual bool parseToken(const char *key, const char *(*text));
431 const char *getName() {
435 void setName(const char *p) {
439 virtual void startEdit() {
443 virtual void stopEdit() {
447 virtual void draw() {};
449 const char *typeStr() {
450 return positionStr[static_cast<int>(type)];
453 void calcVelocity(float distance) {
454 float secs = (float)time / 1000;
455 baseVelocity = distance / secs;
459 static const char* positionStr[POSITION_COUNT];
462 idCameraPosition::positionType type;
465 idList<idVelocity*> velocities;
469 class idFixedPosition : public idCameraPosition {
474 type = idCameraPosition::FIXED;
477 idFixedPosition() : idCameraPosition() {
481 idFixedPosition(idVec3 p) : idCameraPosition() {
486 virtual void addPoint(const idVec3 &v) {
490 virtual void addPoint(const float x, const float y, const float z) {
498 virtual const idVec3 *getPosition(long t) {
502 void parse(const char *(*text));
503 void write(fileHandle_t file, const char *name);
505 virtual int numPoints() {
509 virtual idVec3 *getPoint(int index) {
516 virtual void draw(bool editMode) {
517 glLabeledPoint(blue, pos, (editMode) ? 5 : 3, "Fixed point");
524 class idInterpolatedPosition : public idCameraPosition {
528 type = idCameraPosition::INTERPOLATED;
534 idInterpolatedPosition() : idCameraPosition() {
538 idInterpolatedPosition(idVec3 start, idVec3 end, long time) : idCameraPosition(time) {
544 ~idInterpolatedPosition() {
547 virtual const idVec3 *getPosition(long t);
549 void parse(const char *(*text));
550 void write(fileHandle_t file, const char *name);
552 virtual int numPoints() {
556 virtual idVec3 *getPoint(int index) {
557 assert(index >= 0 && index < 2);
564 virtual void addPoint(const float x, const float y, const float z) {
566 startPos.set(x, y, z);
574 virtual void addPoint(const idVec3 &v) {
584 virtual void draw(bool editMode) {
585 glLabeledPoint(blue, startPos, (editMode) ? 5 : 3, "Start interpolated");
586 glLabeledPoint(blue, endPos, (editMode) ? 5 : 3, "End interpolated");
588 qglVertex3fv(startPos);
589 qglVertex3fv(endPos);
593 virtual void start(long t) {
594 idCameraPosition::start(t);
595 lastTime = startTime;
597 idVec3 temp = startPos;
599 calcVelocity(temp.Length());
610 class idSplinePosition : public idCameraPosition {
614 type = idCameraPosition::SPLINE;
617 idSplinePosition() : idCameraPosition() {
621 idSplinePosition(long time) : idCameraPosition(time) {
625 ~idSplinePosition() {
628 virtual void start(long t) {
629 idCameraPosition::start(t);
630 target.initPosition(t, time);
631 lastTime = startTime;
633 calcVelocity(target.totalDistance());
636 //virtual const idVec3 *getPosition(long t) {
637 // return target.getPosition(t);
639 virtual const idVec3 *getPosition(long t);
642 //virtual const idVec3 *getPosition(long t) const {
644 void addControlPoint(idVec3 &v) {
648 void parse(const char *(*text));
649 void write(fileHandle_t file, const char *name);
651 virtual int numPoints() {
652 return target.numPoints();
655 virtual idVec3 *getPoint(int index) {
656 return target.getPoint(index);
659 virtual void addPoint(const idVec3 &v) {
663 virtual void addPoint(const float x, const float y, const float z) {
664 target.addPoint(x, y, z);
667 virtual void draw(bool editMode) {
668 target.draw(editMode);
671 virtual void updateSelection(const idVec3 &move) {
672 idCameraPosition::updateSelection(move);
673 target.buildSpline();
697 idCameraFOV(int s, int e, long t) {
706 void setFOV(float f) {
710 float getFOV(long t) {
712 float percent = (t - startTime) / length;
715 } else if (percent > 1.0) {
718 float temp = endFOV - startFOV;
720 fov = startFOV + temp;
722 if (percent == 1.0) {
733 void reset(float startfov, float endfov, int start, float len) {
740 void parse(const char *(*text));
741 void write(fileHandle_t file, const char *name);
755 class idCameraEvent {
756 public: // parameters
762 EVENT_TARGET, // char(name)
764 EVENT_FOV, // int(time), int(targetfov)
769 EVENT_FADEOUT, // int(time)
770 EVENT_FADEIN, // int(time)
775 static const char* eventStr[EVENT_COUNT];
783 idCameraEvent(eventType t, const char *param, long n) {
791 eventType getType() {
795 const char *typeStr() {
796 return eventStr[static_cast<int>(type)];
799 const char *getParam() {
800 return paramStr.c_str();
807 void setTime(long n) {
811 void parse(const char *(*text));
812 void write(fileHandle_t file, const char *name);
814 void setTriggered(bool b) {
818 bool getTriggered() {
834 currentCameraPosition = 0;
835 cameraRunning = false;
836 lastDirection.Zero();
842 for (i = 0; i < targetPositions.Num(); i++) {
843 delete targetPositions[i];
845 for (i = 0; i < events.Num(); i++) {
848 delete cameraPosition;
849 cameraPosition = NULL;
851 targetPositions.Clear();
854 idCameraPosition *startNewCamera(idCameraPosition::positionType type) {
856 if (type == idCameraPosition::SPLINE) {
857 cameraPosition = new idSplinePosition();
858 } else if (type == idCameraPosition::INTERPOLATED) {
859 cameraPosition = new idInterpolatedPosition();
861 cameraPosition = new idFixedPosition();
863 return cameraPosition;
867 cameraPosition = NULL;
875 void addEvent(idCameraEvent::eventType t, const char *param, long time);
877 void addEvent(idCameraEvent *event);
879 void removeEvent( int index);
881 static int sortEvents(const void *p1, const void *p2);
887 idCameraEvent *getEvent(int index) {
888 assert(index >= 0 && index < events.Num());
889 return events[index];
892 void parse(const char *(*text));
893 bool load(const char *filename);
894 void save(const char *filename);
898 //idSplineList *getcameraPosition() {
899 // return &cameraPosition;
902 static idCameraPosition *newFromType(idCameraPosition::positionType t) {
904 case idCameraPosition::FIXED : return new idFixedPosition();
905 case idCameraPosition::INTERPOLATED : return new idInterpolatedPosition();
906 case idCameraPosition::SPLINE : return new idSplinePosition();
913 void addTarget(const char *name, idCameraPosition::positionType type);
915 idCameraPosition *getActiveTarget() {
916 if (targetPositions.Num() == 0) {
917 addTarget(NULL, idCameraPosition::FIXED);
919 return targetPositions[activeTarget];
922 idCameraPosition *getActiveTarget(int index) {
923 if (targetPositions.Num() == 0) {
924 addTarget(NULL, idCameraPosition::FIXED);
925 return targetPositions[0];
927 return targetPositions[index];
931 return targetPositions.Num();
935 void setActiveTargetByName(const char *name) {
936 for (int i = 0; i < targetPositions.Num(); i++) {
937 if (Q_stricmp(name, targetPositions[i]->getName()) == 0) {
944 void setActiveTarget(int index) {
945 assert(index >= 0 && index < targetPositions.Num());
946 activeTarget = index;
949 void setRunning(bool b) {
953 void setBaseTime(float f) {
957 float getBaseTime() {
961 float getTotalTime() {
965 void startCamera(long t);
967 cameraRunning = true;
969 void getActiveSegmentInfo(int segment, idVec3 &origin, idVec3 &direction, float *fv);
971 bool getCameraInfo(long time, idVec3 &origin, idVec3 &direction, float *fv);
972 bool getCameraInfo(long time, float *origin, float *direction, float *fv) {
977 dir[0] = direction[0];
978 dir[1] = direction[1];
979 dir[2] = direction[2];
980 bool b = getCameraInfo(time, org, dir, fv);
984 direction[0] = dir[0];
985 direction[1] = dir[1];
986 direction[2] = dir[2];
990 void draw(bool editMode) {
991 // gcc doesn't allow casting away from bools
992 // why? I've no idea...
993 if (cameraPosition) {
994 cameraPosition->draw((bool)((editMode || cameraRunning) && cameraEdit));
995 int count = targetPositions.Num();
996 for (int i = 0; i < count; i++) {
997 targetPositions[i]->draw((bool)((editMode || cameraRunning) && i == activeTarget && !cameraEdit));
1005 return cameraPosition.numSegments();
1007 return getTargetSpline()->numSegments();
1010 int getActiveSegment() {
1012 return cameraPosition.getActiveSegment();
1014 return getTargetSpline()->getActiveSegment();
1017 void setActiveSegment(int i) {
1019 cameraPosition.setActiveSegment(i);
1021 getTargetSpline()->setActiveSegment(i);
1027 return cameraPosition->numPoints();
1029 return getActiveTarget()->numPoints();
1032 const idVec3 *getPoint(int index) {
1034 return cameraPosition->getPoint(index);
1036 return getActiveTarget()->getPoint(index);
1042 cameraPosition->stopEdit();
1044 getActiveTarget()->stopEdit();
1048 void startEdit(bool camera) {
1049 cameraEdit = camera;
1051 cameraPosition->startEdit();
1052 for (int i = 0; i < targetPositions.Num(); i++) {
1053 targetPositions[i]->stopEdit();
1056 getActiveTarget()->startEdit();
1057 cameraPosition->stopEdit();
1062 bool waitEvent(int index);
1064 const char *getName() {
1065 return name.c_str();
1068 void setName(const char *p) {
1072 idCameraPosition *getPositionObj() {
1073 if (cameraPosition == NULL) {
1074 cameraPosition = new idFixedPosition();
1076 return cameraPosition;
1081 int currentCameraPosition;
1082 idVec3 lastDirection;
1084 idCameraPosition *cameraPosition;
1085 idList<idCameraPosition*> targetPositions;
1086 idList<idCameraEvent*> events;
1097 extern bool g_splineMode;
1099 extern idCameraDef *g_splineList;