doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
splines.cpp
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 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.
23 
24 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.
25 
26 ===========================================================================
27 */
28 
29 #include "../../idlib/precompiled.h"
30 #pragma hdrstop
31 
32 #include "splines.h"
33 
36 
37 /*
38 ================
39 glLabeledPoint
40 ================
41 */
42 void glLabeledPoint(idVec4 &color, idVec3 &point, float size, const char *label) {
43  qglColor3fv( color.ToFloatPtr() );
44  qglPointSize( size );
45  qglBegin( GL_POINTS );
46  qglVertex3fv( point.ToFloatPtr() );
47  qglEnd();
48  idVec3 v = point;
49  v.x += 1;
50  v.y += 1;
51  v.z += 1;
53  qglCallLists( strlen(label), GL_UNSIGNED_BYTE, label );
54 }
55 
56 /*
57 ================
58 glBox
59 ================
60 */
61 void glBox(idVec4 &color, idVec3 &point, float size) {
62  idVec3 mins(point);
63  idVec3 maxs(point);
64  mins[0] -= size;
65  mins[1] += size;
66  mins[2] -= size;
67  maxs[0] += size;
68  maxs[1] -= size;
69  maxs[2] += size;
70  idVec4 saveColor;
71  qglGetFloatv(GL_CURRENT_COLOR, saveColor.ToFloatPtr());
72  qglColor3fv( color.ToFloatPtr() );
73  qglBegin(GL_LINE_LOOP);
74  qglVertex3f(mins[0],mins[1],mins[2]);
75  qglVertex3f(maxs[0],mins[1],mins[2]);
76  qglVertex3f(maxs[0],maxs[1],mins[2]);
77  qglVertex3f(mins[0],maxs[1],mins[2]);
78  qglEnd();
79  qglBegin(GL_LINE_LOOP);
80  qglVertex3f(mins[0],mins[1],maxs[2]);
81  qglVertex3f(maxs[0],mins[1],maxs[2]);
82  qglVertex3f(maxs[0],maxs[1],maxs[2]);
83  qglVertex3f(mins[0],maxs[1],maxs[2]);
84  qglEnd();
85 
86  qglBegin(GL_LINES);
87  qglVertex3f(mins[0],mins[1],mins[2]);
88  qglVertex3f(mins[0],mins[1],maxs[2]);
89  qglVertex3f(mins[0],maxs[1],maxs[2]);
90  qglVertex3f(mins[0],maxs[1],mins[2]);
91  qglVertex3f(maxs[0],mins[1],mins[2]);
92  qglVertex3f(maxs[0],mins[1],maxs[2]);
93  qglVertex3f(maxs[0],maxs[1],maxs[2]);
94  qglVertex3f(maxs[0],maxs[1],mins[2]);
95  qglEnd();
96  qglColor4fv(saveColor.ToFloatPtr());
97 
98 }
99 
100 /*
101 ================
102 splineTest
103 ================
104 */
105 void splineTest() {
106  //g_splineList->load("p:/doom/base/maps/test_base1.camera");
107 }
108 
109 /*
110 ================
111 splineDraw
112 ================
113 */
114 void splineDraw() {
115  //g_splineList->addToRenderer();
116 }
117 
118 /*
119 ================
120 debugLine
121 ================
122 */
123 void debugLine(idVec4 &color, float x, float y, float z, float x2, float y2, float z2) {
124  idVec3 from(x, y, z);
125  idVec3 to(x2, y2, z2);
126  session->rw->DebugLine(color, from, to);
127 }
128 
129 
130 /*
131 =================================================================================
132 
133 idPointListInterface
134 
135 =================================================================================
136 */
137 
138 /*
139 ================
140 idPointListInterface::selectPointByRay
141 ================
142 */
143 int idPointListInterface::selectPointByRay(const idVec3 &origin, const idVec3 &direction, bool single) {
144  int i, besti, count;
145  float d, bestd;
146  idVec3 temp, temp2;
147 
148  // find the point closest to the ray
149  besti = -1;
150  bestd = 8;
151  count = numPoints();
152 
153  for (i=0; i < count; i++) {
154  temp = *getPoint(i);
155  temp2 = temp;
156  temp -= origin;
157  d = DotProduct(temp, direction);
158  VectorMA (origin, d, direction, temp);
159  temp2 -= temp;
160  d = temp2.Length();
161  if (d <= bestd) {
162  bestd = d;
163  besti = i;
164  }
165  }
166 
167  if (besti >= 0) {
168  selectPoint(besti, single);
169  }
170 
171  return besti;
172 }
173 
174 /*
175 ================
176 idPointListInterface::isPointSelected
177 ================
178 */
180  int count = selectedPoints.Num();
181  for (int i = 0; i < count; i++) {
182  if (selectedPoints[i] == index) {
183  return i;
184  }
185  }
186  return -1;
187 }
188 
189 /*
190 ================
191 idPointListInterface::selectPoint
192 ================
193 */
195  if (index >= 0 && index < numPoints()) {
196  if (single) {
197  deselectAll();
198  } else {
199  if (isPointSelected(index) >= 0) {
200  selectedPoints.Remove(index);
201  }
202  }
203  return selectedPoints.Append(index);
204  }
205  return -1;
206 }
207 
208 /*
209 ================
210 idPointListInterface::selectAll
211 ================
212 */
215  for (int i = 0; i < numPoints(); i++) {
217  }
218 }
219 
220 /*
221 ================
222 idPointListInterface::deselectAll
223 ================
224 */
227 }
228 
229 /*
230 ================
231 idPointListInterface::getSelectedPoint
232 ================
233 */
235  assert(index >= 0 && index < numSelectedPoints());
236  return getPoint(selectedPoints[index]);
237 }
238 
239 /*
240 ================
241 idPointListInterface::updateSelection
242 ================
243 */
245  int count = selectedPoints.Num();
246  for (int i = 0; i < count; i++) {
247  *getPoint(selectedPoints[i]) += move;
248  }
249 }
250 
251 /*
252 ================
253 idPointListInterface::drawSelection
254 ================
255 */
257  int count = selectedPoints.Num();
258  for (int i = 0; i < count; i++) {
260  }
261 }
262 
263 /*
264 =================================================================================
265 
266 idSplineList
267 
268 =================================================================================
269 */
270 
271 /*
272 ================
273 idSplineList::clearControl
274 ================
275 */
277  for (int i = 0; i < controlPoints.Num(); i++) {
278  delete controlPoints[i];
279  }
281 }
282 
283 /*
284 ================
285 idSplineList::clearSpline
286 ================
287 */
289  for (int i = 0; i < splinePoints.Num(); i++) {
290  delete splinePoints[i];
291  }
293 }
294 
295 /*
296 ================
297 idSplineList::clear
298 ================
299 */
301  clearControl();
302  clearSpline();
303  splineTime.Clear();
304  selected = NULL;
305  dirty = true;
306  activeSegment = 0;
307  granularity = 0.025f;
308  pathColor = idVec4(1.0f, 0.5f, 0.0f, 1.0f);
309  controlColor = idVec4(0.7f, 0.0f, 1.0f, 1.0f);
310  segmentColor = idVec4(0.0f, 0.0f, 1.0f, 1.0);
311  activeColor = idVec4(1.0f, 0.0f, 0.0f, 1.0f);
312 }
313 
314 /*
315 ================
316 idSplineList::setColors
317 ================
318 */
319 void idSplineList::setColors(idVec4 &path, idVec4 &segment, idVec4 &control, idVec4 &active) {
320  pathColor = path;
321  segmentColor = segment;
322  controlColor = control;
323  activeColor = active;
324 }
325 
326 /*
327 ================
328 idSplineList::validTime
329 ================
330 */
332  if (dirty) {
333  buildSpline();
334  }
335  // gcc doesn't allow static casting away from bools
336  // why? I've no idea...
337  return (bool)(splineTime.Num() > 0 && splineTime.Num() == splinePoints.Num());
338 }
339 
340 /*
341 ================
342 idSplineList::addToRenderer
343 ================
344 */
346  int i;
347  idVec3 mins, maxs;
348 
349  if (controlPoints.Num() == 0) {
350  return;
351  }
352 
353  for(i = 0; i < controlPoints.Num(); i++) {
354  VectorCopy(*controlPoints[i], mins);
355  VectorCopy(mins, maxs);
356  mins[0] -= 8;
357  mins[1] += 8;
358  mins[2] -= 8;
359  maxs[0] += 8;
360  maxs[1] -= 8;
361  maxs[2] += 8;
362  debugLine( colorYellow, mins[0], mins[1], mins[2], maxs[0], mins[1], mins[2]);
363  debugLine( colorYellow, maxs[0], mins[1], mins[2], maxs[0], maxs[1], mins[2]);
364  debugLine( colorYellow, maxs[0], maxs[1], mins[2], mins[0], maxs[1], mins[2]);
365  debugLine( colorYellow, mins[0], maxs[1], mins[2], mins[0], mins[1], mins[2]);
366 
367  debugLine( colorYellow, mins[0], mins[1], maxs[2], maxs[0], mins[1], maxs[2]);
368  debugLine( colorYellow, maxs[0], mins[1], maxs[2], maxs[0], maxs[1], maxs[2]);
369  debugLine( colorYellow, maxs[0], maxs[1], maxs[2], mins[0], maxs[1], maxs[2]);
370  debugLine( colorYellow, mins[0], maxs[1], maxs[2], mins[0], mins[1], maxs[2]);
371 
372  }
373 
374  int step = 0;
375  idVec3 step1;
376  for(i = 3; i < controlPoints.Num(); i++) {
377  for (float tension = 0.0f; tension < 1.001f; tension += 0.1f) {
378  float x = 0;
379  float y = 0;
380  float z = 0;
381  for (int j = 0; j < 4; j++) {
382  x += controlPoints[i - (3 - j)]->x * calcSpline(j, tension);
383  y += controlPoints[i - (3 - j)]->y * calcSpline(j, tension);
384  z += controlPoints[i - (3 - j)]->z * calcSpline(j, tension);
385  }
386  if (step == 0) {
387  step1[0] = x;
388  step1[1] = y;
389  step1[2] = z;
390  step = 1;
391  } else {
392  debugLine( colorWhite, step1[0], step1[1], step1[2], x, y, z);
393  step = 0;
394  }
395 
396  }
397  }
398 }
399 
400 /*
401 ================
402 idSplineList::buildSpline
403 ================
404 */
406  int start = Sys_Milliseconds();
407  clearSpline();
408  for(int i = 3; i < controlPoints.Num(); i++) {
409  for (float tension = 0.0f; tension < 1.001f; tension += granularity) {
410  float x = 0;
411  float y = 0;
412  float z = 0;
413  for (int j = 0; j < 4; j++) {
414  x += controlPoints[i - (3 - j)]->x * calcSpline(j, tension);
415  y += controlPoints[i - (3 - j)]->y * calcSpline(j, tension);
416  z += controlPoints[i - (3 - j)]->z * calcSpline(j, tension);
417  }
418  splinePoints.Append(new idVec3(x, y, z));
419  }
420  }
421  dirty = false;
422  //common->Printf("Spline build took %f seconds\n", (float)(Sys_Milliseconds() - start) / 1000);
423 }
424 
425 /*
426 ================
427 idSplineList::draw
428 ================
429 */
430 void idSplineList::draw(bool editMode) {
431  int i;
432 
433  if (controlPoints.Num() == 0) {
434  return;
435  }
436 
437  if (dirty) {
438  buildSpline();
439  }
440 
441 
443  qglPointSize( 5 );
444 
445  qglBegin(GL_POINTS);
446  for (i = 0; i < controlPoints.Num(); i++) {
447  qglVertex3fv( (*controlPoints[i]).ToFloatPtr() );
448  }
449  qglEnd();
450 
451  if (editMode) {
452  for(i = 0; i < controlPoints.Num(); i++) {
454  }
455  }
456 
457  //Draw the curve
459  qglBegin(GL_LINE_STRIP);
460  int count = splinePoints.Num();
461  for (i = 0; i < count; i++) {
462  qglVertex3fv( (*splinePoints[i]).ToFloatPtr() );
463  }
464  qglEnd();
465 
466  if (editMode) {
468  qglPointSize(3);
469  qglBegin(GL_POINTS);
470  for (i = 0; i < count; i++) {
471  qglVertex3fv( (*splinePoints[i]).ToFloatPtr() );
472  }
473  qglEnd();
474  }
475  if (count > 0) {
476  //assert(activeSegment >=0 && activeSegment < count);
477  if (activeSegment >=0 && activeSegment < count) {
479  glBox(colorYellow, *splinePoints[activeSegment], 8);
480  }
481  }
482 
483 }
484 
485 /*
486 ================
487 idSplineList::totalDistance
488 ================
489 */
491 
492  // FIXME: save dist and return
493  //
494  if (controlPoints.Num() == 0) {
495  return 0.0f;
496  }
497 
498  if (dirty) {
499  buildSpline();
500  }
501 
502  float dist = 0.0f;
503  idVec3 temp;
504  int count = splinePoints.Num();
505  for(int i = 1; i < count; i++) {
506  temp = *splinePoints[i-1];
507  temp -= *splinePoints[i];
508  dist += temp.Length();
509  }
510  return dist;
511 }
512 
513 /*
514 ================
515 idSplineList::initPosition
516 ================
517 */
518 void idSplineList::initPosition(long bt, long totalTime) {
519 
520  if (dirty) {
521  buildSpline();
522  }
523 
524  if (splinePoints.Num() == 0) {
525  return;
526  }
527 
528  baseTime = bt;
529  time = totalTime;
530 
531  // calc distance to travel ( this will soon be broken into time segments )
532  splineTime.Clear();
533  splineTime.Append(bt);
534  double dist = totalDistance();
535  double distSoFar = 0.0;
536  idVec3 temp;
537  int count = splinePoints.Num();
538  //for(int i = 2; i < count - 1; i++) {
539  for(int i = 1; i < count; i++) {
540  temp = *splinePoints[i-1];
541  temp -= *splinePoints[i];
542  distSoFar += temp.Length();
543  double percent = distSoFar / dist;
544  percent *= totalTime;
545  splineTime.Append(percent + bt);
546  }
548  activeSegment = 0;
549 }
550 
551 /*
552 ================
553 idSplineList::calcSpline
554 ================
555 */
556 float idSplineList::calcSpline(int step, float tension) {
557  switch(step) {
558  case 0: return (pow(1 - tension, 3)) / 6;
559  case 1: return (3 * pow(tension, 3) - 6 * pow(tension, 2) + 4) / 6;
560  case 2: return (-3 * pow(tension, 3) + 3 * pow(tension, 2) + 3 * tension + 1) / 6;
561  case 3: return pow(tension, 3) / 6;
562  }
563  return 0.0f;
564 }
565 
566 /*
567 ================
568 idSplineList::updateSelection
569 ================
570 */
572  if (selected) {
573  dirty = true;
574  VectorAdd(*selected, move, *selected);
575  }
576 }
577 
578 /*
579 ================
580 idSplineList::setSelectedPoint
581 ================
582 */
584  if (p) {
585  p->SnapInt();
586  for(int i = 0; i < controlPoints.Num(); i++) {
587  if ( (*p).Compare( *controlPoints[i], VECTOR_EPSILON ) ) {
589  }
590  }
591  } else {
592  selected = NULL;
593  }
594 }
595 
596 /*
597 ================
598 idSplineList::getPosition
599 ================
600 */
602  static idVec3 interpolatedPos;
603 
604  int count = splineTime.Num();
605  if (count == 0) {
606  return &vec3_zero;
607  }
608 
610 
611 #if 0
612  float velocity = getVelocity(t);
613  float timePassed = t - lastTime;
614  lastTime = t;
615 
616  // convert to seconds
617  timePassed /= 1000;
618 
619  float distToTravel = timePassed * velocity;
620 
621  distSoFar += distToTravel;
622  float tempDistance = 0;
623 
624  idVec3 temp;
625  int count = splinePoints.Num();
626  //for(int i = 2; i < count - 1; i++) {
627  for(int i = 1; i < count; i++) {
628  temp = *splinePoints[i-1];
629  temp -= *splinePoints[i];
630  tempDistance += temp.Length();
631  if (tempDistance >= distSoFar) {
632  break;
633  }
634  }
635 
636  if (i == count) {
637  interpolatedPos = splinePoints[i-1];
638  } else {
639  double timeHi = splineTime[i + 1];
640  double timeLo = splineTime[i - 1];
641  double percent = (timeHi - t) / (timeHi - timeLo);
642  idVec3 v1 = *splinePoints[i - 1];
643  idVec3 v2 = *splinePoints[i + 1];
644  v2 *= (1.0f - percent);
645  v1 *= percent;
646  v2 += v1;
647  interpolatedPos = v2;
648  }
649  return &interpolatedPos;
650 
651 #else
652  while (activeSegment < count) {
653  if (splineTime[activeSegment] >= t) {
654  if (activeSegment > 0 && activeSegment < count - 1) {
655  double timeHi = splineTime[activeSegment + 1];
656  double timeLo = splineTime[activeSegment - 1];
657  //float percent = (float)(baseTime + time - t) / time;
658  double percent = (timeHi - t) / (timeHi - timeLo);
659  // pick two bounding points
662  v2 *= (1.0f - percent);
663  v1 *= percent;
664  v2 += v1;
665  interpolatedPos = v2;
666  return &interpolatedPos;
667  }
668  return splinePoints[activeSegment];
669  } else {
670  activeSegment++;
671  }
672  }
673  return splinePoints[count-1];
674 #endif
675 }
676 
677 /*
678 ================
679 idSplineList::parse
680 ================
681 */
683  idToken token;
684  idStr key;
685 
686  src->ExpectTokenString( "{" );
687 
688  while ( 1 ) {
689  if ( !src->ExpectAnyToken( &token ) ) {
690  break;
691  }
692  if ( token == "}" ) {
693  break;
694  }
695  // if token is not a brace, it is a key for a key/value pair
696  if ( token == "(" ) {
697  src->UnreadToken( &token );
698  // read the control point
699  idVec3 point;
700  src->Parse1DMatrix( 3, point.ToFloatPtr() );
701  addPoint(point.x, point.y, point.z);
702  }
703  else {
704  key = token;
705  src->ReadTokenOnLine( &token );
706  if ( !key.Icmp( "granularity" ) ) {
707  granularity = atof(token.c_str());
708  }
709  else if ( !key.Icmp( "name" ) ) {
710  name = token;
711  }
712  else {
713  src->Error( "unknown spline list key: %s", key.c_str() );
714  break;
715  }
716  }
717  }
718  dirty = true;
719 }
720 
721 /*
722 ================
723 idSplineList::write
724 ================
725 */
726 void idSplineList::write( idFile *f, const char *p) {
727  f->Printf( "\t\t%s {\n", p );
728 
729  //f->Printf( "\t\tname %s\n", name.c_str() );
730  f->Printf( "\t\t\tgranularity %f\n", granularity );
731  int count = controlPoints.Num();
732  for (int i = 0; i < count; i++) {
733  f->Printf( "\t\t\t( %f %f %f )\n", controlPoints[i]->x, controlPoints[i]->y, controlPoints[i]->z );
734  }
735  f->Printf( "\t\t}\n" );
736 }
737 
738 /*
739 =================================================================================
740 
741 idCamaraDef
742 
743 =================================================================================
744 */
745 
746 /*
747 ================
748 idCameraDef::clear
749 ================
750 */
753  cameraRunning = false;
755  baseTime = 30;
756  activeTarget = 0;
757  name = "camera01";
758  fov.SetFOV(90);
759  int i;
760  for (i = 0; i < targetPositions.Num(); i++) {
761  delete targetPositions[i];
762  }
763  for (i = 0; i < events.Num(); i++) {
764  delete events[i];
765  }
766  delete cameraPosition;
768  events.Clear();
770 }
771 
772 /*
773 ================
774 idCameraDef::startNewCamera
775 ================
776 */
778  clear();
779  if (type == idCameraPosition::SPLINE) {
781  } else if (type == idCameraPosition::INTERPOLATED) {
783  } else {
785  }
786  return cameraPosition;
787 }
788 
789 /*
790 ================
791 idCameraDef::addTarget
792 ================
793 */
795  const char *text = (name == NULL) ? va("target0%d", numTargets()+1) : name;
796  idCameraPosition *pos = newFromType(type);
797  if (pos) {
798  pos->setName(name);
799  targetPositions.Append(pos);
800  activeTarget = numTargets()-1;
801  if (activeTarget == 0) {
802  // first one
804  }
805  }
806 }
807 
808 /*
809 ================
810 idCameraDef::getActiveTarget
811 ================
812 */
814  if (targetPositions.Num() == 0) {
816  }
818 }
819 
820 /*
821 ================
822 idCameraDef::getActiveTarget
823 ================
824 */
826  if (targetPositions.Num() == 0) {
828  return targetPositions[0];
829  }
830  return targetPositions[index];
831 }
832 
833 /*
834 ================
835 idCameraDef::setActiveTargetByName
836 ================
837 */
839  for (int i = 0; i < targetPositions.Num(); i++) {
840  if (idStr::Icmp(name, targetPositions[i]->getName()) == 0) {
842  return;
843  }
844  }
845 }
846 
847 /*
848 ================
849 idCameraDef::setActiveTarget
850 ================
851 */
853  assert(index >= 0 && index < targetPositions.Num());
855 }
856 
857 /*
858 ================
859 idCameraDef::draw
860 ================
861 */
862 void idCameraDef::draw( bool editMode ) {
863  // gcc doesn't allow casting away from bools
864  // why? I've no idea...
865  if (cameraPosition) {
866  cameraPosition->draw((bool)((editMode || cameraRunning) && cameraEdit));
867  int count = targetPositions.Num();
868  for (int i = 0; i < count; i++) {
869  targetPositions[i]->draw((bool)((editMode || cameraRunning) && i == activeTarget && !cameraEdit));
870  }
871  }
872 }
873 
874 /*
875 ================
876 idCameraDef::numPoints
877 ================
878 */
880  if (cameraEdit) {
881  return cameraPosition->numPoints();
882  }
883  return getActiveTarget()->numPoints();
884 }
885 
886 /*
887 ================
888 idCameraDef::getPoint
889 ================
890 */
892  if (cameraEdit) {
893  return cameraPosition->getPoint(index);
894  }
895  return getActiveTarget()->getPoint(index);
896 }
897 
898 /*
899 ================
900 idCameraDef::stopEdit
901 ================
902 */
904  editMode = false;
905  if (cameraEdit) {
907  } else {
909  }
910 }
911 
912 /*
913 ================
914 idCameraDef::startEdit
915 ================
916 */
917 void idCameraDef::startEdit(bool camera) {
918  cameraEdit = camera;
919  if (camera) {
921  for (int i = 0; i < targetPositions.Num(); i++) {
922  targetPositions[i]->stopEdit();
923  }
924  } else {
927  }
928  editMode = true;
929 }
930 
931 /*
932 ================
933 idCameraDef::getPositionObj
934 ================
935 */
937  if (cameraPosition == NULL) {
939  }
940  return cameraPosition;
941 }
942 
943 /*
944 ================
945 idCameraDef::getActiveSegmentInfo
946 ================
947 */
948 void idCameraDef::getActiveSegmentInfo(int segment, idVec3 &origin, idVec3 &direction, float *fov) {
949 #if 0
950  if (!cameraSpline.validTime()) {
951  buildCamera();
952  }
953  double d = (double)segment / numSegments();
954  getCameraInfo(d * totalTime * 1000, origin, direction, fov);
955 #endif
956 /*
957  if (!cameraSpline.validTime()) {
958  buildCamera();
959  }
960  origin = *cameraSpline.getSegmentPoint(segment);
961 
962 
963  idVec3 temp;
964 
965  int numTargets = getTargetSpline()->controlPoints.Num();
966  int count = cameraSpline.splineTime.Num();
967  if (numTargets == 0) {
968  // follow the path
969  if (cameraSpline.getActiveSegment() < count - 1) {
970  temp = *cameraSpline.splinePoints[cameraSpline.getActiveSegment()+1];
971  }
972  } else if (numTargets == 1) {
973  temp = *getTargetSpline()->controlPoints[0];
974  } else {
975  temp = *getTargetSpline()->getSegmentPoint(segment);
976  }
977 
978  temp -= origin;
979  temp.Normalize();
980  direction = temp;
981 */
982 }
983 
984 /*
985 ================
986 idCameraDef::getCameraInfo
987 ================
988 */
989 bool idCameraDef::getCameraInfo(long time, idVec3 &origin, idVec3 &direction, float *fv) {
990  char buff[ 1024 ];
991  int i;
992 
993  if ((time - startTime) / 1000 <= totalTime) {
994 
995  for( i = 0; i < events.Num(); i++ ) {
996  if (time >= startTime + events[i]->getTime() && !events[i]->getTriggered()) {
997  events[i]->setTriggered(true);
998  if (events[i]->getType() == idCameraEvent::EVENT_TARGET) {
999  setActiveTargetByName(events[i]->getParam());
1000  getActiveTarget()->start(startTime + events[i]->getTime());
1001  //common->Printf("Triggered event switch to target: %s\n",events[i]->getParam());
1002  } else if (events[i]->getType() == idCameraEvent::EVENT_TRIGGER) {
1003 #if 0
1004 //FIXME: seperate game and editor spline code
1005  idEntity *ent;
1006  ent = gameLocal.FindEntity( events[i]->getParam() );
1007  if (ent) {
1008  ent->Signal( SIG_TRIGGER );
1010  }
1011 #endif
1012  } else if (events[i]->getType() == idCameraEvent::EVENT_FOV) {
1013  memset(buff, 0, sizeof(buff));
1014  strcpy(buff, events[i]->getParam());
1015  const char *param1 = strtok(buff, " \t,\0");
1016  const char *param2 = strtok(NULL, " \t,\0");
1017  fov.reset(fov.GetFOV(time), atof(param1), time, atoi(param2));
1018  //*fv = fov = atof(events[i]->getParam());
1019  } else if (events[i]->getType() == idCameraEvent::EVENT_CAMERA) {
1020  } else if (events[i]->getType() == idCameraEvent::EVENT_STOP) {
1021  return false;
1022  }
1023  }
1024  }
1025  } else {
1026  }
1027 
1028  origin = *cameraPosition->getPosition(time);
1029 
1030  *fv = fov.GetFOV(time);
1031 
1032  idVec3 temp = origin;
1033 
1034  int numTargets = targetPositions.Num();
1035  if (numTargets == 0) {
1036 /*
1037  // follow the path
1038  if (cameraSpline.getActiveSegment() < count - 1) {
1039  temp = *cameraSpline.splinePoints[cameraSpline.getActiveSegment()+1];
1040  if (temp == origin) {
1041  int index = cameraSpline.getActiveSegment() + 2;
1042  while (temp == origin && index < count - 1) {
1043  temp = *cameraSpline.splinePoints[index++];
1044  }
1045  }
1046  }
1047 */
1048  } else {
1049  temp = *getActiveTarget()->getPosition(time);
1050  }
1051 
1052  temp -= origin;
1053  temp.Normalize();
1054  direction = temp;
1055 
1056  return true;
1057 }
1058 
1059 /*
1060 ================
1061 idCameraDef::waitEvent
1062 ================
1063 */
1065  //for (int i = 0; i < events.Num(); i++) {
1066  // if (events[i]->getSegment() == index && events[i]->getType() == idCameraEvent::EVENT_WAIT) {
1067  // return true;
1068  // }
1069  //}
1070  return false;
1071 }
1072 
1073 /*
1074 ================
1075 idCameraDef::buildCamera
1076 ================
1077 */
1078 #define NUM_CCELERATION_SEGS 10
1079 #define CELL_AMT 5
1080 
1082  int i;
1083  int lastSwitch = 0;
1084  idList<float> waits;
1085  idList<int> targets;
1086 
1087  totalTime = baseTime;
1088  cameraPosition->setTime(totalTime * 1000);
1089  // we have a base time layout for the path and the target path
1090  // now we need to layer on any wait or speed changes
1091  for (i = 0; i < events.Num(); i++) {
1092  idCameraEvent *ev = events[i];
1093  events[i]->setTriggered(false);
1094  switch (events[i]->getType()) {
1096  targets.Append(i);
1097  break;
1098  }
1100  long startTime = 0;
1101  float speed = 0;
1102  long loopTime = 10;
1103  float stepGoal = cameraPosition->getBaseVelocity() / (1000 / loopTime);
1104  while (startTime <= 1000) {
1105  cameraPosition->addVelocity(startTime, loopTime, speed);
1106  speed += stepGoal;
1107  if (speed > cameraPosition->getBaseVelocity()) {
1108  speed = cameraPosition->getBaseVelocity();
1109  }
1110  startTime += loopTime;
1111  }
1112 
1113  startTime = totalTime * 1000 - 1000;
1114  long endTime = startTime + 1000;
1115  speed = cameraPosition->getBaseVelocity();
1116  while (startTime < endTime) {
1117  speed -= stepGoal;
1118  if (speed < 0) {
1119  speed = 0;
1120  }
1121  cameraPosition->addVelocity(startTime, loopTime, speed);
1122  startTime += loopTime;
1123  }
1124  break;
1125 
1126  }
1127  case idCameraEvent::EVENT_WAIT : {
1128  waits.Append(atof(events[i]->getParam()));
1129 
1130  //FIXME: this is quite hacky for Wolf E3, accel and decel needs
1131  // do be parameter based etc..
1132  long startTime = events[i]->getTime() - 1000;
1133  if (startTime < 0) {
1134  startTime = 0;
1135  }
1136  float speed = cameraPosition->getBaseVelocity();
1137  long loopTime = 10;
1138  float steps = speed / ((events[i]->getTime() - startTime) / loopTime);
1139  while (startTime <= events[i]->getTime() - loopTime) {
1140  cameraPosition->addVelocity(startTime, loopTime, speed);
1141  speed -= steps;
1142  startTime += loopTime;
1143  }
1144  cameraPosition->addVelocity(events[i]->getTime(), atof(events[i]->getParam()) * 1000, 0);
1145 
1146  startTime = events[i]->getTime() + atof(events[i]->getParam()) * 1000;
1147  long endTime = startTime + 1000;
1148  speed = 0;
1149  while (startTime <= endTime) {
1150  cameraPosition->addVelocity(startTime, loopTime, speed);
1151  speed += steps;
1152  startTime += loopTime;
1153  }
1154  break;
1155  }
1157  //targetWaits.Append(i);
1158  break;
1159  }
1161 /*
1162  // take the average delay between up to the next five segments
1163  float adjust = atof(events[i]->getParam());
1164  int index = events[i]->getSegment();
1165  total = 0;
1166  count = 0;
1167 
1168  // get total amount of time over the remainder of the segment
1169  for (j = index; j < cameraSpline.numSegments() - 1; j++) {
1170  total += cameraSpline.getSegmentTime(j + 1) - cameraSpline.getSegmentTime(j);
1171  count++;
1172  }
1173 
1174  // multiply that by the adjustment
1175  double newTotal = total * adjust;
1176  // what is the difference..
1177  newTotal -= total;
1178  totalTime += newTotal / 1000;
1179 
1180  // per segment difference
1181  newTotal /= count;
1182  int additive = newTotal;
1183 
1184  // now propogate that difference out to each segment
1185  for (j = index; j < cameraSpline.numSegments(); j++) {
1186  cameraSpline.addSegmentTime(j, additive);
1187  additive += newTotal;
1188  }
1189  break;
1190 */
1191  }
1192  }
1193  }
1194 
1195 
1196  for (i = 0; i < waits.Num(); i++) {
1197  totalTime += waits[i];
1198  }
1199 
1200  // on a new target switch, we need to take time to this point ( since last target switch )
1201  // and allocate it across the active target, then reset time to this point
1202  long timeSoFar = 0;
1203  long total = totalTime * 1000;
1204  for (i = 0; i < targets.Num(); i++) {
1205  long t;
1206  if (i < targets.Num() - 1) {
1207  t = events[targets[i+1]]->getTime();
1208  } else {
1209  t = total - timeSoFar;
1210  }
1211  // t is how much time to use for this target
1212  setActiveTargetByName(events[targets[i]]->getParam());
1213  getActiveTarget()->setTime(t);
1214  timeSoFar += t;
1215  }
1216 }
1217 
1218 /*
1219 ================
1220 idCameraDef::startCamera
1221 ================
1222 */
1225  cameraPosition->start(t);
1226  buildCamera();
1227  //for (int i = 0; i < targetPositions.Num(); i++) {
1228  // targetPositions[i]->
1229  //}
1230  startTime = t;
1231  cameraRunning = true;
1232 }
1233 
1234 /*
1235 ================
1236 idCameraDef::parse
1237 ================
1238 */
1240  idToken token;
1241 
1242  src->ReadToken(&token);
1243  src->ExpectTokenString( "{" );
1244  while ( 1 ) {
1245 
1246  src->ExpectAnyToken( &token );
1247 
1248  if ( token == "}" ) {
1249  break;
1250  }
1251  else if ( !token.Icmp( "time" ) ) {
1252  baseTime = src->ParseFloat();
1253  }
1254  else if ( !token.Icmp( "camera_fixed") ) {
1256  cameraPosition->parse( src );
1257  }
1258  else if ( !token.Icmp( "camera_interpolated") ) {
1260  cameraPosition->parse( src );
1261  }
1262  else if ( !token.Icmp( "camera_spline") ) {
1264  cameraPosition->parse( src );
1265  }
1266  else if ( !token.Icmp( "target_fixed") ) {
1267  idFixedPosition *pos = new idFixedPosition();
1268  pos->parse( src );
1269  targetPositions.Append(pos);
1270  }
1271  else if ( !token.Icmp( "target_interpolated") ) {
1273  pos->parse( src );
1274  targetPositions.Append(pos);
1275  }
1276  else if ( !token.Icmp( "target_spline") ) {
1277  idSplinePosition *pos = new idSplinePosition();
1278  pos->parse( src );
1279  targetPositions.Append(pos);
1280  }
1281  else if ( !token.Icmp( "fov") ) {
1282  fov.parse( src );
1283  }
1284  else if ( !token.Icmp( "event") ) {
1285  idCameraEvent *event = new idCameraEvent();
1286  event->parse( src );
1287  addEvent(event);
1288  }
1289  else {
1290  src->Error( "unknown camera def: %s", token.c_str() );
1291  break;
1292  }
1293  }
1294 
1295  if ( !cameraPosition ) {
1296  common->Printf( "no camera position specified\n" );
1297  // prevent a crash later on
1299  }
1300 }
1301 
1302 /*
1303 ================
1304 idCameraDef::load
1305 ================
1306 */
1307 bool idCameraDef::load( const char *filename ) {
1308  idParser *src;
1309 
1311  if ( !src->IsLoaded() ) {
1312  common->Printf( "couldn't load %s\n", filename );
1313  delete src;
1314  return false;
1315  }
1316 
1317  clear();
1318  parse( src );
1319 
1320  delete src;
1321 
1322  return true;
1323 }
1324 
1325 /*
1326 ================
1327 idCameraDef::save
1328 ================
1329 */
1330 void idCameraDef::save(const char *filename) {
1331  idFile *f = fileSystem->OpenFileWrite( filename, "fs_devpath" );
1332  if ( f ) {
1333  int i;
1334  f->Printf( "cameraPathDef { \n" );
1335  f->Printf( "\ttime %f\n", baseTime );
1336 
1337  cameraPosition->write( f, va("camera_%s",cameraPosition->typeStr()) );
1338 
1339  for (i = 0; i < numTargets(); i++) {
1340  targetPositions[i]->write( f, va("target_%s", targetPositions[i]->typeStr()) );
1341  }
1342 
1343  for (i = 0; i < events.Num(); i++) {
1344  events[i]->write( f, "event" );
1345  }
1346 
1347  fov.write( f, "fov" );
1348 
1349  f->Printf( "}\n" );
1350  }
1351  fileSystem->CloseFile( f );
1352 }
1353 
1354 /*
1355 ================
1356 idCameraDef::sortEvents
1357 ================
1358 */
1359 int idCameraDef::sortEvents(const void *p1, const void *p2) {
1360  idCameraEvent *ev1 = (idCameraEvent*)(p1);
1361  idCameraEvent *ev2 = (idCameraEvent*)(p2);
1362 
1363  if (ev1->getTime() > ev2->getTime()) {
1364  return -1;
1365  }
1366  if (ev1->getTime() < ev2->getTime()) {
1367  return 1;
1368  }
1369  return 0;
1370 }
1371 
1372 /*
1373 ================
1374 idCameraDef::addEvent
1375 ================
1376 */
1378  events.Append(event);
1379  //events.Sort(&sortEvents);
1380 
1381 }
1382 
1383 /*
1384 ================
1385 idCameraDef::addEvent
1386 ================
1387 */
1389  addEvent(new idCameraEvent(t, param, time));
1390  buildCamera();
1391 }
1392 
1393 /*
1394 ================
1395 idCameraDef::newFromType
1396 ================
1397 */
1399  switch (t) {
1400  case idCameraPosition::FIXED : return new idFixedPosition();
1402  case idCameraPosition::SPLINE : return new idSplinePosition();
1403  };
1404  return NULL;
1405 }
1406 
1407 
1408 /*
1409 =================================================================================
1410 
1411 idCamaraEvent
1412 
1413 =================================================================================
1414 */
1415 
1416 /*
1417 ================
1418 idCameraEvent::eventStr
1419 ================
1420 */
1421 const char *idCameraEvent::eventStr[] = {
1422  "NA",
1423  "WAIT",
1424  "TARGETWAIT",
1425  "SPEED",
1426  "TARGET",
1427  "SNAPTARGET",
1428  "FOV",
1429  "CMD",
1430  "TRIGGER",
1431  "STOP",
1432  "CAMERA",
1433  "FADEOUT",
1434  "FADEIN",
1435  "FEATHER"
1436 };
1437 
1438 /*
1439 ================
1440 idCameraEvent::parse
1441 ================
1442 */
1444  idToken token;
1445  idStr key;
1446 
1447  src->ExpectTokenString( "{" );
1448 
1449  while ( 1 ) {
1450 
1451  if ( !src->ExpectAnyToken( &token ) ) {
1452  break;
1453  }
1454  if ( token == "}" ) {
1455  break;
1456  }
1457 
1458  key = token;
1459  src->ReadTokenOnLine( &token );
1460  if ( !key.Icmp( "type" ) ) {
1461  type = static_cast<idCameraEvent::eventType>(atoi(token.c_str()));
1462  }
1463  else if ( !key.Icmp( "param" ) ) {
1464  paramStr = token;
1465  }
1466  else if ( !key.Icmp( "time" ) ) {
1467  time = atoi(token.c_str());
1468  }
1469  else {
1470  src->Error( "unknown camera event key: %s", key.c_str() );
1471  break;
1472  }
1473  }
1474 }
1475 
1476 /*
1477 ================
1478 idCameraEvent::write
1479 ================
1480 */
1481 void idCameraEvent::write( idFile *f, const char *name) {
1482  f->Printf( "\t%s {\n", name );
1483  f->Printf( "\t\ttype %d\n", static_cast<int>(type) );
1484  f->Printf( "\t\tparam \"%s\"\n", paramStr.c_str() );
1485  f->Printf( "\t\ttime %d\n", time );
1486  f->Printf( "\t}\n" );
1487 }
1488 
1489 /*
1490 =================================================================================
1491 
1492 idCamaraPosition
1493 
1494 =================================================================================
1495 */
1496 
1497 /*
1498 ================
1499 idCameraPosition::positionStr
1500 ================
1501 */
1502 const char *idCameraPosition::positionStr[] = {
1503  "Fixed",
1504  "Interpolated",
1505  "Spline",
1506 };
1507 
1508 /*
1509 ================
1510 idCameraPosition::positionStr
1511 ================
1512 */
1514  for (int i = 0; i < velocities.Num(); i++) {
1515  delete velocities[i];
1516  velocities[i] = NULL;
1517  }
1518  velocities.Clear();
1519 }
1520 
1521 /*
1522 ================
1523 idCameraPosition::positionStr
1524 ================
1525 */
1527  long check = t - startTime;
1528  for ( int i = 0; i < velocities.Num(); i++ ) {
1529  if (check >= velocities[i]->startTime && check <= velocities[i]->startTime + velocities[i]->time) {
1530  return velocities[i]->speed;
1531  }
1532  }
1533  return baseVelocity;
1534 }
1535 
1536 /*
1537 ================
1538 idCameraPosition::parseToken
1539 ================
1540 */
1542  idToken token;
1543 
1544  if ( !key.Icmp( "time" ) ) {
1545  time = src->ParseInt();
1546  return true;
1547  }
1548  else if ( !key.Icmp( "type" ) ) {
1549  type = static_cast<idCameraPosition::positionType> ( src->ParseInt() );
1550  return true;
1551  }
1552  else if ( !key.Icmp( "velocity" ) ) {
1553  long t = atol(token);
1554  long d = src->ParseInt();
1555  float s = src->ParseFloat();
1556  addVelocity(t, d, s);
1557  return true;
1558  }
1559  else if ( !key.Icmp( "baseVelocity" ) ) {
1560  baseVelocity = src->ParseFloat();
1561  return true;
1562  }
1563  else if ( !key.Icmp( "name" ) ) {
1564  src->ReadToken( &token );
1565  name = token;
1566  return true;
1567  }
1568  else if ( !key.Icmp( "time" ) ) {
1569  time = src->ParseInt();
1570  return true;
1571  }
1572  else {
1573  src->Error( "unknown camera position key: %s", key.c_str() );
1574  return false;
1575  }
1576 }
1577 
1578 /*
1579 ================
1580 idCameraPosition::write
1581 ================
1582 */
1583 void idCameraPosition::write( idFile *f, const char *p ) {
1584  f->Printf( "\t\ttime %i\n", time );
1585  f->Printf( "\t\ttype %i\n", static_cast<int>(type) );
1586  f->Printf( "\t\tname %s\n", name.c_str() );
1587  f->Printf( "\t\tbaseVelocity %f\n", baseVelocity );
1588  for (int i = 0; i < velocities.Num(); i++) {
1589  f->Printf( "\t\tvelocity %i %i %f\n", velocities[i]->startTime, velocities[i]->time, velocities[i]->speed );
1590  }
1591 }
1592 
1593 /*
1594 =================================================================================
1595 
1596 idInterpolatedPosition
1597 
1598 =================================================================================
1599 */
1600 
1601 /*
1602 ================
1603 idInterpolatedPosition::getPoint
1604 ================
1605 */
1607  assert( index >= 0 && index < 2 );
1608  if ( index == 0 ) {
1609  return &startPos;
1610  }
1611  return &endPos;
1612 }
1613 
1614 /*
1615 ================
1616 idInterpolatedPosition::addPoint
1617 ================
1618 */
1619 void idInterpolatedPosition::addPoint( const float x, const float y, const float z ) {
1620  if (first) {
1621  startPos.Set(x, y, z);
1622  first = false;
1623  } else {
1624  endPos.Set(x, y, z);
1625  first = true;
1626  }
1627 }
1628 
1629 /*
1630 ================
1631 idInterpolatedPosition::addPoint
1632 ================
1633 */
1635  if (first) {
1636  startPos = v;
1637  first = false;
1638  }
1639  else {
1640  endPos = v;
1641  first = true;
1642  }
1643 }
1644 
1645 /*
1646 ================
1647 idInterpolatedPosition::draw
1648 ================
1649 */
1650 void idInterpolatedPosition::draw( bool editMode ) {
1651  glLabeledPoint(colorBlue, startPos, (editMode) ? 5 : 3, "Start interpolated");
1652  glLabeledPoint(colorBlue, endPos, (editMode) ? 5 : 3, "End interpolated");
1653  qglBegin(GL_LINES);
1656  qglEnd();
1657 }
1658 
1659 /*
1660 ================
1661 idInterpolatedPosition::start
1662 ================
1663 */
1666  lastTime = startTime;
1667  distSoFar = 0.0f;
1668  idVec3 temp = startPos;
1669  temp -= endPos;
1670  calcVelocity(temp.Length());
1671 }
1672 
1673 /*
1674 ================
1675 idInterpolatedPosition::getPosition
1676 ================
1677 */
1679  static idVec3 interpolatedPos;
1680 
1681  if (t - startTime > 6000) {
1682  int i = 0;
1683  }
1684 
1685  float velocity = getVelocity(t);
1686  float timePassed = t - lastTime;
1687  lastTime = t;
1688 
1689  // convert to seconds
1690  timePassed /= 1000;
1691 
1692  if (velocity != getBaseVelocity()) {
1693  int i = 0;
1694  }
1695 
1696  float distToTravel = timePassed * velocity;
1697 
1698  idVec3 temp = startPos;
1699  temp -= endPos;
1700  float distance = temp.Length();
1701 
1702  distSoFar += distToTravel;
1703  float percent = (float)(distSoFar) / distance;
1704 
1705  if ( percent > 1.0f ) {
1706  percent = 1.0f;
1707  } else if ( percent < 0.0f ) {
1708  percent = 0.0f;
1709  }
1710 
1711  // the following line does a straigt calc on percentage of time
1712  // float percent = (float)(startTime + time - t) / time;
1713 
1714  idVec3 v1 = startPos;
1715  idVec3 v2 = endPos;
1716  v1 *= (1.0f - percent);
1717  v2 *= percent;
1718  v1 += v2;
1719  interpolatedPos = v1;
1720  return &interpolatedPos;
1721 }
1722 
1723 /*
1724 ================
1725 idInterpolatedPosition::parse
1726 ================
1727 */
1729  idToken token;
1730 
1731  src->ExpectTokenString( "{" );
1732  while ( 1 ) {
1733  if ( !src->ExpectAnyToken( &token ) ) {
1734  break;
1735  }
1736  if ( token == "}" ) {
1737  break;
1738  }
1739 
1740  if ( !token.Icmp( "startPos" ) ) {
1741  src->Parse1DMatrix( 3, startPos.ToFloatPtr() );
1742  }
1743  else if ( !token.Icmp( "endPos" ) ) {
1744  src->Parse1DMatrix( 3, endPos.ToFloatPtr() );
1745  }
1746  else {
1747  idCameraPosition::parseToken( token, src);
1748  }
1749  }
1750 }
1751 
1752 /*
1753 ================
1754 idInterpolatedPosition::write
1755 ================
1756 */
1757 void idInterpolatedPosition::write( idFile *f, const char *p ) {
1758  f->Printf( "\t%s {\n", p );
1759  idCameraPosition::write( f, p );
1760  f->Printf( "\t\tstartPos ( %f %f %f )\n", startPos.x, startPos.y, startPos.z );
1761  f->Printf( "\t\tendPos ( %f %f %f )\n", endPos.x, endPos.y, endPos.z );
1762  f->Printf( "\t}\n" );
1763 }
1764 
1765 /*
1766 =================================================================================
1767 
1768 idCameraFOV
1769 
1770 =================================================================================
1771 */
1772 
1773 /*
1774 ================
1775 idCameraFOV::GetFOV
1776 ================
1777 */
1778 float idCameraFOV::GetFOV( long t ) {
1779  if (time) {
1780  assert(startTime);
1781  float percent = (t - startTime) / length;
1782  if ( percent < 0.0f ) {
1783  percent = 0.0f;
1784  } else if ( percent > 1.0f ) {
1785  percent = 1.0f;
1786  }
1787  float temp = endFOV - startFOV;
1788  temp *= percent;
1789  fov = startFOV + temp;
1790  }
1791  return fov;
1792 }
1793 
1794 /*
1795 ================
1796 idCameraFOV::reset
1797 ================
1798 */
1799 void idCameraFOV::reset( float startfov, float endfov, int start, int len ) {
1800  startFOV = startfov;
1801  endFOV = endfov;
1802  startTime = start;
1803  length = len;
1804 }
1805 
1806 /*
1807 ================
1808 idCameraFOV::parse
1809 ================
1810 */
1812  idToken token;
1813 
1814  src->ExpectTokenString( "{" );
1815  while ( 1 ) {
1816  if ( !src->ExpectAnyToken( &token ) ) {
1817  break;
1818  }
1819  if ( token == "}" ) {
1820  break;
1821  }
1822 
1823  if ( !token.Icmp( "fov" ) ) {
1824  fov = src->ParseFloat();
1825  }
1826  else if ( !token.Icmp( "startFOV" ) ) {
1827  startFOV = src->ParseFloat();
1828  }
1829  else if ( !token.Icmp( "endFOV" ) ) {
1830  endFOV = src->ParseFloat();
1831  }
1832  else if ( !token.Icmp( "time" ) ) {
1833  time = src->ParseInt();
1834  }
1835  else {
1836  src->Error( "unknown camera FOV key: %s", token.c_str() );
1837  break;
1838  }
1839  }
1840 }
1841 
1842 /*
1843 ================
1844 idCameraFOV::write
1845 ================
1846 */
1847 void idCameraFOV::write( idFile *f, const char *p ) {
1848  f->Printf( "\t%s {\n", p );
1849  f->Printf( "\t\tfov %f\n", fov );
1850  f->Printf( "\t\tstartFOV %f\n", startFOV );
1851  f->Printf( "\t\tendFOV %f\n", endFOV );
1852  f->Printf( "\t\ttime %i\n", time );
1853  f->Printf( "\t}\n" );
1854 }
1855 
1856 /*
1857 =================================================================================
1858 
1859 idFixedPosition
1860 
1861 =================================================================================
1862 */
1863 
1864 /*
1865 ================
1866 idFixedPosition::parse
1867 ================
1868 */
1870  idToken token;
1871 
1872  src->ExpectTokenString( "{" );
1873  while ( 1 ) {
1874  if ( !src->ExpectAnyToken( &token ) ) {
1875  break;
1876  }
1877  if ( token == "}" ) {
1878  break;
1879  }
1880 
1881  if ( !token.Icmp( "pos" ) ) {
1882  src->Parse1DMatrix( 3, pos.ToFloatPtr() );
1883  }
1884  else {
1885  idCameraPosition::parseToken( token, src );
1886  }
1887  }
1888 }
1889 
1890 /*
1891 ================
1892 idFixedPosition::write
1893 ================
1894 */
1895 void idFixedPosition::write( idFile *f, const char *p ) {
1896  f->Printf( "\t%s {\n", p );
1897  idCameraPosition::write( f, p );
1898  f->Printf( "\t\tpos ( %f %f %f )\n", pos.x, pos.y, pos.z );
1899  f->Printf( "\t}\n" );
1900 }
1901 
1902 /*
1903 =================================================================================
1904 
1905 idSplinePosition
1906 
1907 =================================================================================
1908 */
1909 
1910 /*
1911 ================
1912 idSplinePosition::start
1913 ================
1914 */
1917  target.initPosition(t, time);
1918  lastTime = startTime;
1919  distSoFar = 0.0f;
1921 }
1922 
1923 /*
1924 ================
1925 idSplinePosition::parse
1926 ================
1927 */
1929  idToken token;
1930 
1931  src->ExpectTokenString( "{" );
1932  while ( 1 ) {
1933  if ( !src->ExpectAnyToken( &token ) ) {
1934  break;
1935  }
1936  if ( token == "}" ) {
1937  break;
1938  }
1939  if ( !token.Icmp( "target" ) ) {
1940  target.parse( src );
1941  }
1942  else {
1943  idCameraPosition::parseToken( token, src );
1944  }
1945  }
1946 }
1947 
1948 /*
1949 ================
1950 idSplinePosition::write
1951 ================
1952 */
1953 void idSplinePosition::write( idFile *f, const char *p ) {
1954  f->Printf( "\t%s {\n", p );
1955  idCameraPosition::write( f, p );
1956  target.write( f, "target" );
1957  f->Printf( "\t}\n" );
1958 }
1959 
1960 /*
1961 ================
1962 idSplinePosition::getPosition
1963 ================
1964 */
1966  static idVec3 interpolatedPos;
1967 
1968  float velocity = getVelocity(t);
1969  float timePassed = t - lastTime;
1970  lastTime = t;
1971 
1972  // convert to seconds
1973  timePassed /= 1000;
1974 
1975  float distToTravel = timePassed * velocity;
1976 
1977  distSoFar += distToTravel;
1978  double tempDistance = target.totalDistance();
1979 
1980  double percent = (double)(distSoFar) / tempDistance;
1981 
1982  double targetDistance = percent * tempDistance;
1983  tempDistance = 0;
1984 
1985  double lastDistance1,lastDistance2;
1986  lastDistance1 = lastDistance2 = 0;
1987  //FIXME: calc distances on spline build
1988  idVec3 temp;
1989  int count = target.numSegments();
1990  //for(int i = 2; i < count - 1; i++) {
1991  int i;
1992  for( i = 1; i < count; i++) {
1993  temp = *target.getSegmentPoint(i-1);
1994  temp -= *target.getSegmentPoint(i);
1995  tempDistance += temp.Length();
1996  if (i & 1) {
1997  lastDistance1 = tempDistance;
1998  } else {
1999  lastDistance2 = tempDistance;
2000  }
2001  if (tempDistance >= targetDistance) {
2002  break;
2003  }
2004  }
2005 
2006  if (i >= count - 1) {
2007  interpolatedPos = *target.getSegmentPoint(i-1);
2008  } else {
2009 #if 0
2010  double timeHi = target.getSegmentTime(i + 1);
2011  double timeLo = target.getSegmentTime(i - 1);
2012  double percent = (timeHi - t) / (timeHi - timeLo);
2013  idVec3 v1 = *target.getSegmentPoint(i - 1);
2014  idVec3 v2 = *target.getSegmentPoint(i + 1);
2015  v2 *= (1.0f - percent);
2016  v1 *= percent;
2017  v2 += v1;
2018  interpolatedPos = v2;
2019 #else
2020  if (lastDistance1 > lastDistance2) {
2021  double d = lastDistance2;
2022  lastDistance2 = lastDistance1;
2023  lastDistance1 = d;
2024  }
2025 
2026  idVec3 v1 = *target.getSegmentPoint(i - 1);
2027  idVec3 v2 = *target.getSegmentPoint(i);
2028  double percent = (lastDistance2 - targetDistance) / (lastDistance2 - lastDistance1);
2029  v2 *= (1.0f - percent);
2030  v1 *= percent;
2031  v2 += v1;
2032  interpolatedPos = v2;
2033 #endif
2034  }
2035  return &interpolatedPos;
2036 
2037 }
void splineDraw()
Definition: splines.cpp:114
byte color[4]
Definition: MegaTexture.cpp:54
void Error(const char *str,...) const id_attribute((format(printf
Definition: Parser.cpp:318
void clearControl()
Definition: splines.cpp:276
void calcVelocity(float distance)
Definition: splines.h:180
bool editMode
Definition: splines.h:392
float Normalize(void)
Definition: Vector.h:646
float calcSpline(int step, float tension)
Definition: splines.cpp:556
virtual const idVec3 * getPosition(long t)
Definition: splines.h:169
assert(prefInfo.fullscreenBtn)
void UnreadToken(idToken *token)
Definition: Parser.cpp:2745
virtual void parse(idParser *src)
Definition: splines.h:171
float fov
Definition: splines.h:281
idVec3 lastDirection
Definition: splines.h:380
virtual int numPoints()
Definition: splines.h:41
void updateSelection(const idVec3 &move)
Definition: splines.cpp:571
int numPoints()
Definition: splines.cpp:879
static const char * positionStr[POSITION_COUNT]
Definition: splines.h:183
idVec4 colorWhite
Definition: Lib.cpp:116
int numTargets()
Definition: splines.h:354
virtual bool parseToken(const idStr &key, idParser *src)
Definition: splines.cpp:1541
float baseVelocity
Definition: splines.h:190
static int sortEvents(const void *p1, const void *p2)
Definition: splines.cpp:1359
const GLdouble * v
Definition: glext.h:2936
GLdouble GLdouble x2
Definition: qgl.h:415
float GetFOV(long t)
Definition: splines.cpp:1778
idCameraFOV fov
Definition: splines.h:385
void stopEdit()
Definition: splines.cpp:903
const idEventDef EV_Activate("activate","e")
void glLabeledPoint(idVec4 &color, idVec3 &point, float size, const char *label)
Definition: splines.cpp:42
void setActiveTargetByName(const char *name)
Definition: splines.cpp:838
const float * ToFloatPtr(void) const
Definition: Vector.h:719
idList< idVelocity * > velocities
Definition: splines.h:189
void Set(const float x, const float y, const float z)
Definition: Vector.h:409
GLenum GLint GLint y
Definition: glext.h:2849
idEntity * FindEntity(const char *name) const
GLfloat param
Definition: glext.h:3038
idCameraPosition * startNewCamera(idCameraPosition::positionType type)
Definition: splines.cpp:777
const char * getName()
Definition: splines.h:371
float z
Definition: Vector.h:320
void clear()
Definition: splines.cpp:300
int isPointSelected(int index)
Definition: splines.cpp:179
int currentCameraPosition
Definition: splines.h:379
int Sys_Milliseconds(void)
#define VectorCopy(a, b)
Definition: Vector.h:1999
void debugLine(idVec4 &color, float x, float y, float z, float x2, float y2, float z2)
Definition: splines.cpp:123
bool ProcessEvent(const idEventDef *ev)
Definition: Class.cpp:858
idFileSystem * fileSystem
Definition: FileSystem.cpp:500
bool cameraEdit
Definition: splines.h:391
virtual idVec3 * getPoint(int index)
Definition: splines.cpp:1606
#define qglBegin
Definition: qgl_linked.h:33
int time
Definition: splines.h:285
Definition: Vector.h:316
case const float
Definition: Callbacks.cpp:62
int selectPointByRay(const idVec3 &origin, const idVec3 &direction, bool single)
Definition: splines.cpp:143
#define qglVertex3fv
Definition: qgl_linked.h:350
idSplineList target
Definition: splines.h:261
virtual void draw()
Definition: splines.h:178
void addTarget(const char *name, idCameraPosition::positionType type)
Definition: splines.cpp:794
static const char * eventStr[EVENT_COUNT]
Definition: splines.h:323
idVec3 * getSelectedPoint(int index)
Definition: splines.cpp:234
#define VectorAdd(a, b, c)
Definition: Vector.h:1996
GLuint GLuint GLsizei GLenum type
Definition: glext.h:2845
int ExpectTokenString(const char *string)
Definition: Parser.cpp:2402
Definition: Token.h:71
GLdouble s
Definition: glext.h:2935
GLuint src
Definition: glext.h:5390
GLenum GLsizei len
Definition: glext.h:3472
int activeTarget
Definition: splines.h:386
float endFOV
Definition: splines.h:283
void addVelocity(long start, long duration, float speed)
Definition: splines.h:168
idVec4 activeColor
Definition: splines.h:124
void parse(idParser *src)
Definition: splines.cpp:682
float x
Definition: Vector.h:318
void buildSpline()
Definition: splines.cpp:405
GLenum GLint x
Definition: glext.h:2849
int i
Definition: process.py:33
int IsLoaded(void) const
Definition: Parser.h:94
virtual void start(long t)
Definition: splines.h:163
void parse(idParser *src)
Definition: splines.cpp:1443
void addEvent(idCameraEvent::eventType t, const char *param, long time)
Definition: splines.cpp:1388
float totalDistance()
Definition: splines.cpp:490
void write(idFile *f, const char *name)
Definition: splines.cpp:1757
virtual const idVec3 * getPosition(long t)
Definition: splines.cpp:1965
int Icmp(const char *text) const
Definition: Str.h:667
void setActiveTarget(int index)
Definition: splines.cpp:852
void parse(idParser *src)
Definition: splines.cpp:1928
idVec4 colorRed
Definition: Lib.cpp:117
void parse(idParser *src)
Definition: splines.cpp:1811
idVec4 controlColor
Definition: splines.h:124
Definition: File.h:50
int ReadToken(idToken *token)
Definition: Parser.cpp:2338
virtual const idVec3 * getPosition(long t)
Definition: splines.cpp:1678
float baseTime
Definition: splines.h:388
GLfloat GLfloat GLfloat v2
Definition: glext.h:3608
idRenderWorld * rw
Definition: Session.h:153
void start(long t)
Definition: splines.h:275
const idVec3 * getPosition(long time)
Definition: splines.cpp:601
GLuint GLuint GLsizei count
Definition: glext.h:2845
idVec4 colorYellow
Definition: Lib.cpp:120
virtual void addPoint(const float x, const float y, const float z)
Definition: splines.cpp:1619
bool waitEvent(int index)
Definition: splines.cpp:1064
virtual void DebugLine(const idVec4 &color, const idVec3 &start, const idVec3 &end, const int lifetime=0, const bool depthTest=false)=0
int ParseInt(void)
Definition: Parser.cpp:2775
GLuint index
Definition: glext.h:3476
void reset(float startfov, float endfov, int start, int len)
Definition: splines.cpp:1799
void save(const char *filename)
Definition: splines.cpp:1330
idList< idVec3 * > controlPoints
Definition: splines.h:120
Definition: Vector.h:808
float Length(void) const
Definition: Vector.h:631
idWorldspawn * world
Definition: Game_local.h:280
void startCamera(long t)
Definition: splines.cpp:1223
#define qglRasterPos3fv
Definition: qgl_linked.h:252
#define vec3_zero
Definition: Vector.h:390
bool validTime()
Definition: splines.cpp:331
int Parse1DMatrix(int x, float *m)
Definition: Parser.cpp:2834
idStr paramStr
Definition: splines.h:327
void setColors(idVec4 &path, idVec4 &segment, idVec4 &control, idVec4 &active)
Definition: splines.cpp:319
idList< double > splineTime
Definition: splines.h:122
void clearSpline()
Definition: splines.cpp:288
idCommon * common
Definition: Common.cpp:206
#define VECTOR_EPSILON
Definition: Vector.h:40
void clear()
Definition: splines.cpp:751
int selectPoint(int index, bool single)
Definition: splines.cpp:194
#define NULL
Definition: Lib.h:88
idList< idCameraEvent * > events
Definition: splines.h:384
long startTime
Definition: splines.h:389
long getTime()
Definition: splines.h:316
float y
Definition: Vector.h:319
idCameraDef splineList
Definition: splines.cpp:34
void write(idFile *f, const char *name)
Definition: splines.cpp:1895
#define qglEnd
Definition: qgl_linked.h:103
idCameraPosition * cameraPosition
Definition: splines.h:382
void glBox(idVec4 &color, idVec3 &point, float size)
Definition: splines.cpp:61
virtual idFile * OpenFileWrite(const char *relativePath, const char *basePath="fs_savepath")=0
#define qglGetFloatv
Definition: qgl_linked.h:132
static idCameraPosition * newFromType(idCameraPosition::positionType t)
Definition: splines.cpp:1398
const char * path
Definition: sws.c:117
float ParseFloat(void)
Definition: Parser.cpp:2812
float getBaseVelocity()
Definition: splines.h:167
bool load(const char *filename)
Definition: splines.cpp:1307
idVec4 pathColor
Definition: splines.h:124
virtual void draw(bool editMode)
Definition: splines.h:170
void setName(const char *p)
Definition: splines.h:175
idGameLocal gameLocal
Definition: Game_local.cpp:64
long time
Definition: splines.h:130
void startEdit(bool camera)
Definition: splines.cpp:917
virtual void Printf(const char *fmt,...) id_attribute((format(printf
virtual void updateSelection(const idVec3 &move)
Definition: splines.cpp:244
int ExpectAnyToken(idToken *token)
Definition: Parser.cpp:2476
GLdouble GLdouble GLdouble y2
Definition: qgl.h:415
const float * ToFloatPtr(void) const
Definition: Vector.h:1051
idCameraPosition * getActiveTarget()
Definition: splines.cpp:813
virtual void clearVelocities()
Definition: splines.cpp:1513
#define qglPointSize
Definition: qgl_linked.h:228
GLfloat GLfloat v1
Definition: glext.h:3607
float getVelocity(long t)
Definition: splines.cpp:1526
void splineTest()
Definition: splines.cpp:105
void buildCamera()
Definition: splines.cpp:1081
void getActiveSegmentInfo(int segment, idVec3 &origin, idVec3 &direction, float *fv)
Definition: splines.cpp:948
void parse(idParser *src)
Definition: splines.cpp:1869
idVec3 * getSegmentPoint(int index)
Definition: splines.h:98
void write(idFile *f, const char *name)
Definition: splines.cpp:1847
virtual idVec3 * getPoint(int index)
Definition: splines.h:45
int Append(const type &obj)
Definition: List.h:646
bool cameraRunning
Definition: splines.h:381
int getSegmentTime(int index)
Definition: splines.h:100
void parse(idParser *src)
Definition: splines.cpp:1728
const idVec3 * getPoint(int index)
Definition: splines.cpp:891
void setSelectedPoint(idVec3 *p)
Definition: splines.cpp:583
tuple f
Definition: idal.py:89
float distSoFar
Definition: splines.h:263
int activeSegment
Definition: splines.h:128
int Num(void) const
Definition: List.h:265
idList< int > selectedPoints
Definition: splines.h:58
const GLcharARB * name
Definition: glext.h:3629
void initPosition(long startTime, long totalTime)
Definition: splines.cpp:518
GLsizeiptr size
Definition: glext.h:3112
void Signal(signalNum_t signalnum)
Definition: Entity.cpp:3352
void draw(bool editMode)
Definition: splines.cpp:430
void parse(idParser *src)
Definition: splines.cpp:1239
virtual void start(long t)
Definition: splines.cpp:1915
Definition: Str.h:116
bool getCameraInfo(long time, idVec3 &origin, idVec3 &direction, float *fv)
Definition: splines.cpp:989
GLsizei const GLcharARB const GLint * length
Definition: glext.h:3599
bool dirty
Definition: splines.h:127
virtual void write(idFile *f, const char *name)
Definition: splines.cpp:1583
float startFOV
Definition: splines.h:282
int ReadTokenOnLine(idToken *token)
Definition: Parser.cpp:2754
const char * c_str(void) const
Definition: Str.h:487
#define qglColor4fv
Definition: qgl_linked.h:67
#define DotProduct(a, b)
Definition: Vector.h:1994
idVec3 pos
Definition: splines.h:212
idCameraDef * g_splineList
Definition: splines.cpp:35
idList< idCameraPosition * > targetPositions
Definition: splines.h:383
#define qglCallLists
Definition: qgl_linked.h:38
#define qglVertex3f
Definition: qgl_linked.h:349
idVec3 * selected
Definition: splines.h:123
virtual void start(long t)
Definition: splines.cpp:1664
void draw(bool editMode)
Definition: splines.cpp:862
#define qglColor3fv
Definition: qgl_linked.h:51
idVec4 segmentColor
Definition: splines.h:124
void SetFOV(float f)
Definition: splines.h:273
GLint j
Definition: qgl.h:264
#define VectorMA(v, s, b, o)
Definition: Vector.h:1998
GLint * first
Definition: glext.h:3036
void write(idFile *f, const char *name)
Definition: splines.cpp:726
idSession * session
Definition: Session.cpp:48
float granularity
Definition: splines.h:125
char * va(const char *fmt,...)
Definition: Str.cpp:1568
int startTime
Definition: splines.h:284
virtual void CloseFile(idFile *f)=0
long baseTime
Definition: splines.h:129
int numSelectedPoints()
Definition: splines.h:47
GLfloat GLfloat p
Definition: glext.h:4674
const char * typeStr()
Definition: splines.h:179
GLdouble GLdouble z
Definition: glext.h:3067
void Zero(void)
Definition: Vector.h:415
void write(idFile *f, const char *name)
Definition: splines.cpp:1481
virtual int Printf(const char *fmt,...) id_attribute((format(printf
Definition: File.cpp:260
virtual void setTime(long t)
Definition: splines.h:165
GLuint start
Definition: glext.h:2845
bool Remove(const type &obj)
Definition: List.h:878
idList< idVec3 * > splinePoints
Definition: splines.h:121
float totalTime
Definition: splines.h:387
idVec4 colorBlue
Definition: Lib.cpp:119
virtual void stopEdit()
Definition: splines.h:177
void SnapInt(void)
Definition: Vector.h:701
void write(idFile *f, const char *name)
Definition: splines.cpp:1953
idCameraPosition * getPositionObj()
Definition: splines.cpp:936
virtual void startEdit()
Definition: splines.h:176
int numSegments()
Definition: splines.h:106
void addToRenderer()
Definition: splines.cpp:345
void addPoint(const idVec3 &v)
Definition: splines.h:86
GLdouble GLdouble t
Definition: glext.h:2943
void Clear(void)
Definition: List.h:184