splines.cpp 44 KB

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