1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038 |
- /*
- ===========================================================================
- Doom 3 GPL Source Code
- Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
- This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
- Doom 3 Source Code is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- Doom 3 Source Code is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
- In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
- If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
- ===========================================================================
- */
- #include "../../idlib/precompiled.h"
- #pragma hdrstop
- #include "splines.h"
- idCameraDef splineList;
- idCameraDef *g_splineList = &splineList;
- /*
- ================
- glLabeledPoint
- ================
- */
- void glLabeledPoint(idVec4 &color, idVec3 &point, float size, const char *label) {
- qglColor3fv( color.ToFloatPtr() );
- qglPointSize( size );
- qglBegin( GL_POINTS );
- qglVertex3fv( point.ToFloatPtr() );
- qglEnd();
- idVec3 v = point;
- v.x += 1;
- v.y += 1;
- v.z += 1;
- qglRasterPos3fv( v.ToFloatPtr() );
- qglCallLists( strlen(label), GL_UNSIGNED_BYTE, label );
- }
- /*
- ================
- glBox
- ================
- */
- void glBox(idVec4 &color, idVec3 &point, float size) {
- idVec3 mins(point);
- idVec3 maxs(point);
- mins[0] -= size;
- mins[1] += size;
- mins[2] -= size;
- maxs[0] += size;
- maxs[1] -= size;
- maxs[2] += size;
- idVec4 saveColor;
- qglGetFloatv(GL_CURRENT_COLOR, saveColor.ToFloatPtr());
- qglColor3fv( color.ToFloatPtr() );
- qglBegin(GL_LINE_LOOP);
- qglVertex3f(mins[0],mins[1],mins[2]);
- qglVertex3f(maxs[0],mins[1],mins[2]);
- qglVertex3f(maxs[0],maxs[1],mins[2]);
- qglVertex3f(mins[0],maxs[1],mins[2]);
- qglEnd();
- qglBegin(GL_LINE_LOOP);
- qglVertex3f(mins[0],mins[1],maxs[2]);
- qglVertex3f(maxs[0],mins[1],maxs[2]);
- qglVertex3f(maxs[0],maxs[1],maxs[2]);
- qglVertex3f(mins[0],maxs[1],maxs[2]);
- qglEnd();
- qglBegin(GL_LINES);
- qglVertex3f(mins[0],mins[1],mins[2]);
- qglVertex3f(mins[0],mins[1],maxs[2]);
- qglVertex3f(mins[0],maxs[1],maxs[2]);
- qglVertex3f(mins[0],maxs[1],mins[2]);
- qglVertex3f(maxs[0],mins[1],mins[2]);
- qglVertex3f(maxs[0],mins[1],maxs[2]);
- qglVertex3f(maxs[0],maxs[1],maxs[2]);
- qglVertex3f(maxs[0],maxs[1],mins[2]);
- qglEnd();
- qglColor4fv(saveColor.ToFloatPtr());
- }
- /*
- ================
- splineTest
- ================
- */
- void splineTest() {
- //g_splineList->load("p:/doom/base/maps/test_base1.camera");
- }
- /*
- ================
- splineDraw
- ================
- */
- void splineDraw() {
- //g_splineList->addToRenderer();
- }
- /*
- ================
- debugLine
- ================
- */
- void debugLine(idVec4 &color, float x, float y, float z, float x2, float y2, float z2) {
- idVec3 from(x, y, z);
- idVec3 to(x2, y2, z2);
- session->rw->DebugLine(color, from, to);
- }
- /*
- =================================================================================
- idPointListInterface
- =================================================================================
- */
- /*
- ================
- idPointListInterface::selectPointByRay
- ================
- */
- int idPointListInterface::selectPointByRay(const idVec3 &origin, const idVec3 &direction, bool single) {
- int i, besti, count;
- float d, bestd;
- idVec3 temp, temp2;
- // find the point closest to the ray
- besti = -1;
- bestd = 8;
- count = numPoints();
- for (i=0; i < count; i++) {
- temp = *getPoint(i);
- temp2 = temp;
- temp -= origin;
- d = DotProduct(temp, direction);
- VectorMA (origin, d, direction, temp);
- temp2 -= temp;
- d = temp2.Length();
- if (d <= bestd) {
- bestd = d;
- besti = i;
- }
- }
- if (besti >= 0) {
- selectPoint(besti, single);
- }
- return besti;
- }
- /*
- ================
- idPointListInterface::isPointSelected
- ================
- */
- int idPointListInterface::isPointSelected(int index) {
- int count = selectedPoints.Num();
- for (int i = 0; i < count; i++) {
- if (selectedPoints[i] == index) {
- return i;
- }
- }
- return -1;
- }
- /*
- ================
- idPointListInterface::selectPoint
- ================
- */
- int idPointListInterface::selectPoint(int index, bool single) {
- if (index >= 0 && index < numPoints()) {
- if (single) {
- deselectAll();
- } else {
- if (isPointSelected(index) >= 0) {
- selectedPoints.Remove(index);
- }
- }
- return selectedPoints.Append(index);
- }
- return -1;
- }
- /*
- ================
- idPointListInterface::selectAll
- ================
- */
- void idPointListInterface::selectAll() {
- selectedPoints.Clear();
- for (int i = 0; i < numPoints(); i++) {
- selectedPoints.Append(i);
- }
- }
- /*
- ================
- idPointListInterface::deselectAll
- ================
- */
- void idPointListInterface::deselectAll() {
- selectedPoints.Clear();
- }
- /*
- ================
- idPointListInterface::getSelectedPoint
- ================
- */
- idVec3 *idPointListInterface::getSelectedPoint( int index ) {
- assert(index >= 0 && index < numSelectedPoints());
- return getPoint(selectedPoints[index]);
- }
- /*
- ================
- idPointListInterface::updateSelection
- ================
- */
- void idPointListInterface::updateSelection(const idVec3 &move) {
- int count = selectedPoints.Num();
- for (int i = 0; i < count; i++) {
- *getPoint(selectedPoints[i]) += move;
- }
- }
- /*
- ================
- idPointListInterface::drawSelection
- ================
- */
- void idPointListInterface::drawSelection() {
- int count = selectedPoints.Num();
- for (int i = 0; i < count; i++) {
- glBox(colorRed, *getPoint(selectedPoints[i]), 4);
- }
- }
- /*
- =================================================================================
- idSplineList
- =================================================================================
- */
- /*
- ================
- idSplineList::clearControl
- ================
- */
- void idSplineList::clearControl() {
- for (int i = 0; i < controlPoints.Num(); i++) {
- delete controlPoints[i];
- }
- controlPoints.Clear();
- }
- /*
- ================
- idSplineList::clearSpline
- ================
- */
- void idSplineList::clearSpline() {
- for (int i = 0; i < splinePoints.Num(); i++) {
- delete splinePoints[i];
- }
- splinePoints.Clear();
- }
- /*
- ================
- idSplineList::clear
- ================
- */
- void idSplineList::clear() {
- clearControl();
- clearSpline();
- splineTime.Clear();
- selected = NULL;
- dirty = true;
- activeSegment = 0;
- granularity = 0.025f;
- pathColor = idVec4(1.0f, 0.5f, 0.0f, 1.0f);
- controlColor = idVec4(0.7f, 0.0f, 1.0f, 1.0f);
- segmentColor = idVec4(0.0f, 0.0f, 1.0f, 1.0);
- activeColor = idVec4(1.0f, 0.0f, 0.0f, 1.0f);
- }
- /*
- ================
- idSplineList::setColors
- ================
- */
- void idSplineList::setColors(idVec4 &path, idVec4 &segment, idVec4 &control, idVec4 &active) {
- pathColor = path;
- segmentColor = segment;
- controlColor = control;
- activeColor = active;
- }
- /*
- ================
- idSplineList::validTime
- ================
- */
- bool idSplineList::validTime() {
- if (dirty) {
- buildSpline();
- }
- // gcc doesn't allow static casting away from bools
- // why? I've no idea...
- return (bool)(splineTime.Num() > 0 && splineTime.Num() == splinePoints.Num());
- }
- /*
- ================
- idSplineList::addToRenderer
- ================
- */
- void idSplineList::addToRenderer() {
- int i;
- idVec3 mins, maxs;
- if (controlPoints.Num() == 0) {
- return;
- }
-
- for(i = 0; i < controlPoints.Num(); i++) {
- VectorCopy(*controlPoints[i], mins);
- VectorCopy(mins, maxs);
- mins[0] -= 8;
- mins[1] += 8;
- mins[2] -= 8;
- maxs[0] += 8;
- maxs[1] -= 8;
- maxs[2] += 8;
- debugLine( colorYellow, mins[0], mins[1], mins[2], maxs[0], mins[1], mins[2]);
- debugLine( colorYellow, maxs[0], mins[1], mins[2], maxs[0], maxs[1], mins[2]);
- debugLine( colorYellow, maxs[0], maxs[1], mins[2], mins[0], maxs[1], mins[2]);
- debugLine( colorYellow, mins[0], maxs[1], mins[2], mins[0], mins[1], mins[2]);
-
- debugLine( colorYellow, mins[0], mins[1], maxs[2], maxs[0], mins[1], maxs[2]);
- debugLine( colorYellow, maxs[0], mins[1], maxs[2], maxs[0], maxs[1], maxs[2]);
- debugLine( colorYellow, maxs[0], maxs[1], maxs[2], mins[0], maxs[1], maxs[2]);
- debugLine( colorYellow, mins[0], maxs[1], maxs[2], mins[0], mins[1], maxs[2]);
-
- }
- int step = 0;
- idVec3 step1;
- for(i = 3; i < controlPoints.Num(); i++) {
- for (float tension = 0.0f; tension < 1.001f; tension += 0.1f) {
- float x = 0;
- float y = 0;
- float z = 0;
- for (int j = 0; j < 4; j++) {
- x += controlPoints[i - (3 - j)]->x * calcSpline(j, tension);
- y += controlPoints[i - (3 - j)]->y * calcSpline(j, tension);
- z += controlPoints[i - (3 - j)]->z * calcSpline(j, tension);
- }
- if (step == 0) {
- step1[0] = x;
- step1[1] = y;
- step1[2] = z;
- step = 1;
- } else {
- debugLine( colorWhite, step1[0], step1[1], step1[2], x, y, z);
- step = 0;
- }
- }
- }
- }
- /*
- ================
- idSplineList::buildSpline
- ================
- */
- void idSplineList::buildSpline() {
- int start = Sys_Milliseconds();
- clearSpline();
- for(int i = 3; i < controlPoints.Num(); i++) {
- for (float tension = 0.0f; tension < 1.001f; tension += granularity) {
- float x = 0;
- float y = 0;
- float z = 0;
- for (int j = 0; j < 4; j++) {
- x += controlPoints[i - (3 - j)]->x * calcSpline(j, tension);
- y += controlPoints[i - (3 - j)]->y * calcSpline(j, tension);
- z += controlPoints[i - (3 - j)]->z * calcSpline(j, tension);
- }
- splinePoints.Append(new idVec3(x, y, z));
- }
- }
- dirty = false;
- //common->Printf("Spline build took %f seconds\n", (float)(Sys_Milliseconds() - start) / 1000);
- }
- /*
- ================
- idSplineList::draw
- ================
- */
- void idSplineList::draw(bool editMode) {
- int i;
-
- if (controlPoints.Num() == 0) {
- return;
- }
- if (dirty) {
- buildSpline();
- }
- qglColor3fv( controlColor.ToFloatPtr() );
- qglPointSize( 5 );
-
- qglBegin(GL_POINTS);
- for (i = 0; i < controlPoints.Num(); i++) {
- qglVertex3fv( (*controlPoints[i]).ToFloatPtr() );
- }
- qglEnd();
-
- if (editMode) {
- for(i = 0; i < controlPoints.Num(); i++) {
- glBox(activeColor, *controlPoints[i], 4);
- }
- }
- //Draw the curve
- qglColor3fv( pathColor.ToFloatPtr() );
- qglBegin(GL_LINE_STRIP);
- int count = splinePoints.Num();
- for (i = 0; i < count; i++) {
- qglVertex3fv( (*splinePoints[i]).ToFloatPtr() );
- }
- qglEnd();
- if (editMode) {
- qglColor3fv( segmentColor.ToFloatPtr() );
- qglPointSize(3);
- qglBegin(GL_POINTS);
- for (i = 0; i < count; i++) {
- qglVertex3fv( (*splinePoints[i]).ToFloatPtr() );
- }
- qglEnd();
- }
- if (count > 0) {
- //assert(activeSegment >=0 && activeSegment < count);
- if (activeSegment >=0 && activeSegment < count) {
- glBox(activeColor, *splinePoints[activeSegment], 6);
- glBox(colorYellow, *splinePoints[activeSegment], 8);
- }
- }
- }
- /*
- ================
- idSplineList::totalDistance
- ================
- */
- float idSplineList::totalDistance() {
- // FIXME: save dist and return
- //
- if (controlPoints.Num() == 0) {
- return 0.0f;
- }
- if (dirty) {
- buildSpline();
- }
- float dist = 0.0f;
- idVec3 temp;
- int count = splinePoints.Num();
- for(int i = 1; i < count; i++) {
- temp = *splinePoints[i-1];
- temp -= *splinePoints[i];
- dist += temp.Length();
- }
- return dist;
- }
- /*
- ================
- idSplineList::initPosition
- ================
- */
- void idSplineList::initPosition(long bt, long totalTime) {
- if (dirty) {
- buildSpline();
- }
- if (splinePoints.Num() == 0) {
- return;
- }
- baseTime = bt;
- time = totalTime;
- // calc distance to travel ( this will soon be broken into time segments )
- splineTime.Clear();
- splineTime.Append(bt);
- double dist = totalDistance();
- double distSoFar = 0.0;
- idVec3 temp;
- int count = splinePoints.Num();
- //for(int i = 2; i < count - 1; i++) {
- for(int i = 1; i < count; i++) {
- temp = *splinePoints[i-1];
- temp -= *splinePoints[i];
- distSoFar += temp.Length();
- double percent = distSoFar / dist;
- percent *= totalTime;
- splineTime.Append(percent + bt);
- }
- assert(splineTime.Num() == splinePoints.Num());
- activeSegment = 0;
- }
- /*
- ================
- idSplineList::calcSpline
- ================
- */
- float idSplineList::calcSpline(int step, float tension) {
- switch(step) {
- case 0: return (pow(1 - tension, 3)) / 6;
- case 1: return (3 * pow(tension, 3) - 6 * pow(tension, 2) + 4) / 6;
- case 2: return (-3 * pow(tension, 3) + 3 * pow(tension, 2) + 3 * tension + 1) / 6;
- case 3: return pow(tension, 3) / 6;
- }
- return 0.0f;
- }
- /*
- ================
- idSplineList::updateSelection
- ================
- */
- void idSplineList::updateSelection(const idVec3 &move) {
- if (selected) {
- dirty = true;
- VectorAdd(*selected, move, *selected);
- }
- }
- /*
- ================
- idSplineList::setSelectedPoint
- ================
- */
- void idSplineList::setSelectedPoint(idVec3 *p) {
- if (p) {
- p->SnapInt();
- for(int i = 0; i < controlPoints.Num(); i++) {
- if ( (*p).Compare( *controlPoints[i], VECTOR_EPSILON ) ) {
- selected = controlPoints[i];
- }
- }
- } else {
- selected = NULL;
- }
- }
- /*
- ================
- idSplineList::getPosition
- ================
- */
- const idVec3 *idSplineList::getPosition(long t) {
- static idVec3 interpolatedPos;
- int count = splineTime.Num();
- if (count == 0) {
- return &vec3_zero;
- }
- assert(splineTime.Num() == splinePoints.Num());
- #if 0
- float velocity = getVelocity(t);
- float timePassed = t - lastTime;
- lastTime = t;
- // convert to seconds
- timePassed /= 1000;
- float distToTravel = timePassed * velocity;
- distSoFar += distToTravel;
- float tempDistance = 0;
- idVec3 temp;
- int count = splinePoints.Num();
- //for(int i = 2; i < count - 1; i++) {
- for(int i = 1; i < count; i++) {
- temp = *splinePoints[i-1];
- temp -= *splinePoints[i];
- tempDistance += temp.Length();
- if (tempDistance >= distSoFar) {
- break;
- }
- }
- if (i == count) {
- interpolatedPos = splinePoints[i-1];
- } else {
- double timeHi = splineTime[i + 1];
- double timeLo = splineTime[i - 1];
- double percent = (timeHi - t) / (timeHi - timeLo);
- idVec3 v1 = *splinePoints[i - 1];
- idVec3 v2 = *splinePoints[i + 1];
- v2 *= (1.0f - percent);
- v1 *= percent;
- v2 += v1;
- interpolatedPos = v2;
- }
- return &interpolatedPos;
- #else
- while (activeSegment < count) {
- if (splineTime[activeSegment] >= t) {
- if (activeSegment > 0 && activeSegment < count - 1) {
- double timeHi = splineTime[activeSegment + 1];
- double timeLo = splineTime[activeSegment - 1];
- //float percent = (float)(baseTime + time - t) / time;
- double percent = (timeHi - t) / (timeHi - timeLo);
- // pick two bounding points
- idVec3 v1 = *splinePoints[activeSegment-1];
- idVec3 v2 = *splinePoints[activeSegment+1];
- v2 *= (1.0f - percent);
- v1 *= percent;
- v2 += v1;
- interpolatedPos = v2;
- return &interpolatedPos;
- }
- return splinePoints[activeSegment];
- } else {
- activeSegment++;
- }
- }
- return splinePoints[count-1];
- #endif
- }
- /*
- ================
- idSplineList::parse
- ================
- */
- void idSplineList::parse( idParser *src ) {
- idToken token;
- idStr key;
- src->ExpectTokenString( "{" );
- while ( 1 ) {
- if ( !src->ExpectAnyToken( &token ) ) {
- break;
- }
- if ( token == "}" ) {
- break;
- }
- // if token is not a brace, it is a key for a key/value pair
- if ( token == "(" ) {
- src->UnreadToken( &token );
- // read the control point
- idVec3 point;
- src->Parse1DMatrix( 3, point.ToFloatPtr() );
- addPoint(point.x, point.y, point.z);
- }
- else {
- key = token;
- src->ReadTokenOnLine( &token );
- if ( !key.Icmp( "granularity" ) ) {
- granularity = atof(token.c_str());
- }
- else if ( !key.Icmp( "name" ) ) {
- name = token;
- }
- else {
- src->Error( "unknown spline list key: %s", key.c_str() );
- break;
- }
- }
- }
- dirty = true;
- }
- /*
- ================
- idSplineList::write
- ================
- */
- void idSplineList::write( idFile *f, const char *p) {
- f->Printf( "\t\t%s {\n", p );
- //f->Printf( "\t\tname %s\n", name.c_str() );
- f->Printf( "\t\t\tgranularity %f\n", granularity );
- int count = controlPoints.Num();
- for (int i = 0; i < count; i++) {
- f->Printf( "\t\t\t( %f %f %f )\n", controlPoints[i]->x, controlPoints[i]->y, controlPoints[i]->z );
- }
- f->Printf( "\t\t}\n" );
- }
- /*
- =================================================================================
- idCamaraDef
- =================================================================================
- */
- /*
- ================
- idCameraDef::clear
- ================
- */
- void idCameraDef::clear() {
- currentCameraPosition = 0;
- cameraRunning = false;
- lastDirection.Zero();
- baseTime = 30;
- activeTarget = 0;
- name = "camera01";
- fov.SetFOV(90);
- int i;
- for (i = 0; i < targetPositions.Num(); i++) {
- delete targetPositions[i];
- }
- for (i = 0; i < events.Num(); i++) {
- delete events[i];
- }
- delete cameraPosition;
- cameraPosition = NULL;
- events.Clear();
- targetPositions.Clear();
- }
- /*
- ================
- idCameraDef::startNewCamera
- ================
- */
- idCameraPosition *idCameraDef::startNewCamera( idCameraPosition::positionType type ) {
- clear();
- if (type == idCameraPosition::SPLINE) {
- cameraPosition = new idSplinePosition();
- } else if (type == idCameraPosition::INTERPOLATED) {
- cameraPosition = new idInterpolatedPosition();
- } else {
- cameraPosition = new idFixedPosition();
- }
- return cameraPosition;
- }
- /*
- ================
- idCameraDef::addTarget
- ================
- */
- void idCameraDef::addTarget(const char *name, idCameraPosition::positionType type) {
- const char *text = (name == NULL) ? va("target0%d", numTargets()+1) : name;
- idCameraPosition *pos = newFromType(type);
- if (pos) {
- pos->setName(name);
- targetPositions.Append(pos);
- activeTarget = numTargets()-1;
- if (activeTarget == 0) {
- // first one
- addEvent(idCameraEvent::EVENT_TARGET, name, 0);
- }
- }
- }
- /*
- ================
- idCameraDef::getActiveTarget
- ================
- */
- idCameraPosition *idCameraDef::getActiveTarget() {
- if (targetPositions.Num() == 0) {
- addTarget(NULL, idCameraPosition::FIXED);
- }
- return targetPositions[activeTarget];
- }
- /*
- ================
- idCameraDef::getActiveTarget
- ================
- */
- idCameraPosition *idCameraDef::getActiveTarget(int index) {
- if (targetPositions.Num() == 0) {
- addTarget(NULL, idCameraPosition::FIXED);
- return targetPositions[0];
- }
- return targetPositions[index];
- }
- /*
- ================
- idCameraDef::setActiveTargetByName
- ================
- */
- void idCameraDef::setActiveTargetByName( const char *name ) {
- for (int i = 0; i < targetPositions.Num(); i++) {
- if (idStr::Icmp(name, targetPositions[i]->getName()) == 0) {
- setActiveTarget(i);
- return;
- }
- }
- }
- /*
- ================
- idCameraDef::setActiveTarget
- ================
- */
- void idCameraDef::setActiveTarget( int index ) {
- assert(index >= 0 && index < targetPositions.Num());
- activeTarget = index;
- }
- /*
- ================
- idCameraDef::draw
- ================
- */
- void idCameraDef::draw( bool editMode ) {
- // gcc doesn't allow casting away from bools
- // why? I've no idea...
- if (cameraPosition) {
- cameraPosition->draw((bool)((editMode || cameraRunning) && cameraEdit));
- int count = targetPositions.Num();
- for (int i = 0; i < count; i++) {
- targetPositions[i]->draw((bool)((editMode || cameraRunning) && i == activeTarget && !cameraEdit));
- }
- }
- }
- /*
- ================
- idCameraDef::numPoints
- ================
- */
- int idCameraDef::numPoints() {
- if (cameraEdit) {
- return cameraPosition->numPoints();
- }
- return getActiveTarget()->numPoints();
- }
- /*
- ================
- idCameraDef::getPoint
- ================
- */
- const idVec3 *idCameraDef::getPoint(int index) {
- if (cameraEdit) {
- return cameraPosition->getPoint(index);
- }
- return getActiveTarget()->getPoint(index);
- }
- /*
- ================
- idCameraDef::stopEdit
- ================
- */
- void idCameraDef::stopEdit() {
- editMode = false;
- if (cameraEdit) {
- cameraPosition->stopEdit();
- } else {
- getActiveTarget()->stopEdit();
- }
- }
- /*
- ================
- idCameraDef::startEdit
- ================
- */
- void idCameraDef::startEdit(bool camera) {
- cameraEdit = camera;
- if (camera) {
- cameraPosition->startEdit();
- for (int i = 0; i < targetPositions.Num(); i++) {
- targetPositions[i]->stopEdit();
- }
- } else {
- getActiveTarget()->startEdit();
- cameraPosition->stopEdit();
- }
- editMode = true;
- }
- /*
- ================
- idCameraDef::getPositionObj
- ================
- */
- idCameraPosition *idCameraDef::getPositionObj() {
- if (cameraPosition == NULL) {
- cameraPosition = new idFixedPosition();
- }
- return cameraPosition;
- }
- /*
- ================
- idCameraDef::getActiveSegmentInfo
- ================
- */
- void idCameraDef::getActiveSegmentInfo(int segment, idVec3 &origin, idVec3 &direction, float *fov) {
- #if 0
- if (!cameraSpline.validTime()) {
- buildCamera();
- }
- double d = (double)segment / numSegments();
- getCameraInfo(d * totalTime * 1000, origin, direction, fov);
- #endif
- /*
- if (!cameraSpline.validTime()) {
- buildCamera();
- }
- origin = *cameraSpline.getSegmentPoint(segment);
-
- idVec3 temp;
- int numTargets = getTargetSpline()->controlPoints.Num();
- int count = cameraSpline.splineTime.Num();
- if (numTargets == 0) {
- // follow the path
- if (cameraSpline.getActiveSegment() < count - 1) {
- temp = *cameraSpline.splinePoints[cameraSpline.getActiveSegment()+1];
- }
- } else if (numTargets == 1) {
- temp = *getTargetSpline()->controlPoints[0];
- } else {
- temp = *getTargetSpline()->getSegmentPoint(segment);
- }
- temp -= origin;
- temp.Normalize();
- direction = temp;
- */
- }
- /*
- ================
- idCameraDef::getCameraInfo
- ================
- */
- bool idCameraDef::getCameraInfo(long time, idVec3 &origin, idVec3 &direction, float *fv) {
- char buff[ 1024 ];
- int i;
- if ((time - startTime) / 1000 <= totalTime) {
- for( i = 0; i < events.Num(); i++ ) {
- if (time >= startTime + events[i]->getTime() && !events[i]->getTriggered()) {
- events[i]->setTriggered(true);
- if (events[i]->getType() == idCameraEvent::EVENT_TARGET) {
- setActiveTargetByName(events[i]->getParam());
- getActiveTarget()->start(startTime + events[i]->getTime());
- //common->Printf("Triggered event switch to target: %s\n",events[i]->getParam());
- } else if (events[i]->getType() == idCameraEvent::EVENT_TRIGGER) {
- #if 0
- //FIXME: seperate game and editor spline code
- idEntity *ent;
- ent = gameLocal.FindEntity( events[i]->getParam() );
- if (ent) {
- ent->Signal( SIG_TRIGGER );
- ent->ProcessEvent( &EV_Activate, gameLocal.world );
- }
- #endif
- } else if (events[i]->getType() == idCameraEvent::EVENT_FOV) {
- memset(buff, 0, sizeof(buff));
- strcpy(buff, events[i]->getParam());
- const char *param1 = strtok(buff, " \t,\0");
- const char *param2 = strtok(NULL, " \t,\0");
- fov.reset(fov.GetFOV(time), atof(param1), time, atoi(param2));
- //*fv = fov = atof(events[i]->getParam());
- } else if (events[i]->getType() == idCameraEvent::EVENT_CAMERA) {
- } else if (events[i]->getType() == idCameraEvent::EVENT_STOP) {
- return false;
- }
- }
- }
- } else {
- }
- origin = *cameraPosition->getPosition(time);
-
- *fv = fov.GetFOV(time);
- idVec3 temp = origin;
- int numTargets = targetPositions.Num();
- if (numTargets == 0) {
- /*
- // follow the path
- if (cameraSpline.getActiveSegment() < count - 1) {
- temp = *cameraSpline.splinePoints[cameraSpline.getActiveSegment()+1];
- if (temp == origin) {
- int index = cameraSpline.getActiveSegment() + 2;
- while (temp == origin && index < count - 1) {
- temp = *cameraSpline.splinePoints[index++];
- }
- }
- }
- */
- } else {
- temp = *getActiveTarget()->getPosition(time);
- }
-
- temp -= origin;
- temp.Normalize();
- direction = temp;
- return true;
- }
- /*
- ================
- idCameraDef::waitEvent
- ================
- */
- bool idCameraDef::waitEvent(int index) {
- //for (int i = 0; i < events.Num(); i++) {
- // if (events[i]->getSegment() == index && events[i]->getType() == idCameraEvent::EVENT_WAIT) {
- // return true;
- // }
- //}
- return false;
- }
- /*
- ================
- idCameraDef::buildCamera
- ================
- */
- #define NUM_CCELERATION_SEGS 10
- #define CELL_AMT 5
- void idCameraDef::buildCamera() {
- int i;
- int lastSwitch = 0;
- idList<float> waits;
- idList<int> targets;
- totalTime = baseTime;
- cameraPosition->setTime(totalTime * 1000);
- // we have a base time layout for the path and the target path
- // now we need to layer on any wait or speed changes
- for (i = 0; i < events.Num(); i++) {
- idCameraEvent *ev = events[i];
- events[i]->setTriggered(false);
- switch (events[i]->getType()) {
- case idCameraEvent::EVENT_TARGET : {
- targets.Append(i);
- break;
- }
- case idCameraEvent::EVENT_FEATHER : {
- long startTime = 0;
- float speed = 0;
- long loopTime = 10;
- float stepGoal = cameraPosition->getBaseVelocity() / (1000 / loopTime);
- while (startTime <= 1000) {
- cameraPosition->addVelocity(startTime, loopTime, speed);
- speed += stepGoal;
- if (speed > cameraPosition->getBaseVelocity()) {
- speed = cameraPosition->getBaseVelocity();
- }
- startTime += loopTime;
- }
- startTime = totalTime * 1000 - 1000;
- long endTime = startTime + 1000;
- speed = cameraPosition->getBaseVelocity();
- while (startTime < endTime) {
- speed -= stepGoal;
- if (speed < 0) {
- speed = 0;
- }
- cameraPosition->addVelocity(startTime, loopTime, speed);
- startTime += loopTime;
- }
- break;
- }
- case idCameraEvent::EVENT_WAIT : {
- waits.Append(atof(events[i]->getParam()));
- //FIXME: this is quite hacky for Wolf E3, accel and decel needs
- // do be parameter based etc..
- long startTime = events[i]->getTime() - 1000;
- if (startTime < 0) {
- startTime = 0;
- }
- float speed = cameraPosition->getBaseVelocity();
- long loopTime = 10;
- float steps = speed / ((events[i]->getTime() - startTime) / loopTime);
- while (startTime <= events[i]->getTime() - loopTime) {
- cameraPosition->addVelocity(startTime, loopTime, speed);
- speed -= steps;
- startTime += loopTime;
- }
- cameraPosition->addVelocity(events[i]->getTime(), atof(events[i]->getParam()) * 1000, 0);
- startTime = events[i]->getTime() + atof(events[i]->getParam()) * 1000;
- long endTime = startTime + 1000;
- speed = 0;
- while (startTime <= endTime) {
- cameraPosition->addVelocity(startTime, loopTime, speed);
- speed += steps;
- startTime += loopTime;
- }
- break;
- }
- case idCameraEvent::EVENT_TARGETWAIT : {
- //targetWaits.Append(i);
- break;
- }
- case idCameraEvent::EVENT_SPEED : {
- /*
- // take the average delay between up to the next five segments
- float adjust = atof(events[i]->getParam());
- int index = events[i]->getSegment();
- total = 0;
- count = 0;
- // get total amount of time over the remainder of the segment
- for (j = index; j < cameraSpline.numSegments() - 1; j++) {
- total += cameraSpline.getSegmentTime(j + 1) - cameraSpline.getSegmentTime(j);
- count++;
- }
- // multiply that by the adjustment
- double newTotal = total * adjust;
- // what is the difference..
- newTotal -= total;
- totalTime += newTotal / 1000;
- // per segment difference
- newTotal /= count;
- int additive = newTotal;
- // now propogate that difference out to each segment
- for (j = index; j < cameraSpline.numSegments(); j++) {
- cameraSpline.addSegmentTime(j, additive);
- additive += newTotal;
- }
- break;
- */
- }
- }
- }
- for (i = 0; i < waits.Num(); i++) {
- totalTime += waits[i];
- }
- // on a new target switch, we need to take time to this point ( since last target switch )
- // and allocate it across the active target, then reset time to this point
- long timeSoFar = 0;
- long total = totalTime * 1000;
- for (i = 0; i < targets.Num(); i++) {
- long t;
- if (i < targets.Num() - 1) {
- t = events[targets[i+1]]->getTime();
- } else {
- t = total - timeSoFar;
- }
- // t is how much time to use for this target
- setActiveTargetByName(events[targets[i]]->getParam());
- getActiveTarget()->setTime(t);
- timeSoFar += t;
- }
- }
- /*
- ================
- idCameraDef::startCamera
- ================
- */
- void idCameraDef::startCamera(long t) {
- cameraPosition->clearVelocities();
- cameraPosition->start(t);
- buildCamera();
- //for (int i = 0; i < targetPositions.Num(); i++) {
- // targetPositions[i]->
- //}
- startTime = t;
- cameraRunning = true;
- }
- /*
- ================
- idCameraDef::parse
- ================
- */
- void idCameraDef::parse( idParser *src ) {
- idToken token;
- src->ReadToken(&token);
- src->ExpectTokenString( "{" );
- while ( 1 ) {
- src->ExpectAnyToken( &token );
- if ( token == "}" ) {
- break;
- }
- else if ( !token.Icmp( "time" ) ) {
- baseTime = src->ParseFloat();
- }
- else if ( !token.Icmp( "camera_fixed") ) {
- cameraPosition = new idFixedPosition();
- cameraPosition->parse( src );
- }
- else if ( !token.Icmp( "camera_interpolated") ) {
- cameraPosition = new idInterpolatedPosition();
- cameraPosition->parse( src );
- }
- else if ( !token.Icmp( "camera_spline") ) {
- cameraPosition = new idSplinePosition();
- cameraPosition->parse( src );
- }
- else if ( !token.Icmp( "target_fixed") ) {
- idFixedPosition *pos = new idFixedPosition();
- pos->parse( src );
- targetPositions.Append(pos);
- }
- else if ( !token.Icmp( "target_interpolated") ) {
- idInterpolatedPosition *pos = new idInterpolatedPosition();
- pos->parse( src );
- targetPositions.Append(pos);
- }
- else if ( !token.Icmp( "target_spline") ) {
- idSplinePosition *pos = new idSplinePosition();
- pos->parse( src );
- targetPositions.Append(pos);
- }
- else if ( !token.Icmp( "fov") ) {
- fov.parse( src );
- }
- else if ( !token.Icmp( "event") ) {
- idCameraEvent *event = new idCameraEvent();
- event->parse( src );
- addEvent(event);
- }
- else {
- src->Error( "unknown camera def: %s", token.c_str() );
- break;
- }
- }
- if ( !cameraPosition ) {
- common->Printf( "no camera position specified\n" );
- // prevent a crash later on
- cameraPosition = new idFixedPosition();
- }
- }
- /*
- ================
- idCameraDef::load
- ================
- */
- bool idCameraDef::load( const char *filename ) {
- idParser *src;
- src = new idParser( filename, LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES );
- if ( !src->IsLoaded() ) {
- common->Printf( "couldn't load %s\n", filename );
- delete src;
- return false;
- }
- clear();
- parse( src );
- delete src;
- return true;
- }
- /*
- ================
- idCameraDef::save
- ================
- */
- void idCameraDef::save(const char *filename) {
- idFile *f = fileSystem->OpenFileWrite( filename, "fs_devpath" );
- if ( f ) {
- int i;
- f->Printf( "cameraPathDef { \n" );
- f->Printf( "\ttime %f\n", baseTime );
- cameraPosition->write( f, va("camera_%s",cameraPosition->typeStr()) );
- for (i = 0; i < numTargets(); i++) {
- targetPositions[i]->write( f, va("target_%s", targetPositions[i]->typeStr()) );
- }
- for (i = 0; i < events.Num(); i++) {
- events[i]->write( f, "event" );
- }
- fov.write( f, "fov" );
- f->Printf( "}\n" );
- }
- fileSystem->CloseFile( f );
- }
- /*
- ================
- idCameraDef::sortEvents
- ================
- */
- int idCameraDef::sortEvents(const void *p1, const void *p2) {
- idCameraEvent *ev1 = (idCameraEvent*)(p1);
- idCameraEvent *ev2 = (idCameraEvent*)(p2);
- if (ev1->getTime() > ev2->getTime()) {
- return -1;
- }
- if (ev1->getTime() < ev2->getTime()) {
- return 1;
- }
- return 0;
- }
- /*
- ================
- idCameraDef::addEvent
- ================
- */
- void idCameraDef::addEvent(idCameraEvent *event) {
- events.Append(event);
- //events.Sort(&sortEvents);
- }
- /*
- ================
- idCameraDef::addEvent
- ================
- */
- void idCameraDef::addEvent(idCameraEvent::eventType t, const char *param, long time) {
- addEvent(new idCameraEvent(t, param, time));
- buildCamera();
- }
- /*
- ================
- idCameraDef::newFromType
- ================
- */
- idCameraPosition *idCameraDef::newFromType( idCameraPosition::positionType t ) {
- switch (t) {
- case idCameraPosition::FIXED : return new idFixedPosition();
- case idCameraPosition::INTERPOLATED : return new idInterpolatedPosition();
- case idCameraPosition::SPLINE : return new idSplinePosition();
- };
- return NULL;
- }
- /*
- =================================================================================
- idCamaraEvent
- =================================================================================
- */
- /*
- ================
- idCameraEvent::eventStr
- ================
- */
- const char *idCameraEvent::eventStr[] = {
- "NA",
- "WAIT",
- "TARGETWAIT",
- "SPEED",
- "TARGET",
- "SNAPTARGET",
- "FOV",
- "CMD",
- "TRIGGER",
- "STOP",
- "CAMERA",
- "FADEOUT",
- "FADEIN",
- "FEATHER"
- };
- /*
- ================
- idCameraEvent::parse
- ================
- */
- void idCameraEvent::parse( idParser *src ) {
- idToken token;
- idStr key;
- src->ExpectTokenString( "{" );
- while ( 1 ) {
- if ( !src->ExpectAnyToken( &token ) ) {
- break;
- }
- if ( token == "}" ) {
- break;
- }
- key = token;
- src->ReadTokenOnLine( &token );
- if ( !key.Icmp( "type" ) ) {
- type = static_cast<idCameraEvent::eventType>(atoi(token.c_str()));
- }
- else if ( !key.Icmp( "param" ) ) {
- paramStr = token;
- }
- else if ( !key.Icmp( "time" ) ) {
- time = atoi(token.c_str());
- }
- else {
- src->Error( "unknown camera event key: %s", key.c_str() );
- break;
- }
- }
- }
- /*
- ================
- idCameraEvent::write
- ================
- */
- void idCameraEvent::write( idFile *f, const char *name) {
- f->Printf( "\t%s {\n", name );
- f->Printf( "\t\ttype %d\n", static_cast<int>(type) );
- f->Printf( "\t\tparam \"%s\"\n", paramStr.c_str() );
- f->Printf( "\t\ttime %d\n", time );
- f->Printf( "\t}\n" );
- }
- /*
- =================================================================================
- idCamaraPosition
- =================================================================================
- */
- /*
- ================
- idCameraPosition::positionStr
- ================
- */
- const char *idCameraPosition::positionStr[] = {
- "Fixed",
- "Interpolated",
- "Spline",
- };
- /*
- ================
- idCameraPosition::positionStr
- ================
- */
- void idCameraPosition::clearVelocities() {
- for (int i = 0; i < velocities.Num(); i++) {
- delete velocities[i];
- velocities[i] = NULL;
- }
- velocities.Clear();
- }
- /*
- ================
- idCameraPosition::positionStr
- ================
- */
- float idCameraPosition::getVelocity( long t ) {
- long check = t - startTime;
- for ( int i = 0; i < velocities.Num(); i++ ) {
- if (check >= velocities[i]->startTime && check <= velocities[i]->startTime + velocities[i]->time) {
- return velocities[i]->speed;
- }
- }
- return baseVelocity;
- }
- /*
- ================
- idCameraPosition::parseToken
- ================
- */
- bool idCameraPosition::parseToken( const idStr &key, idParser *src ) {
- idToken token;
- if ( !key.Icmp( "time" ) ) {
- time = src->ParseInt();
- return true;
- }
- else if ( !key.Icmp( "type" ) ) {
- type = static_cast<idCameraPosition::positionType> ( src->ParseInt() );
- return true;
- }
- else if ( !key.Icmp( "velocity" ) ) {
- long t = atol(token);
- long d = src->ParseInt();
- float s = src->ParseFloat();
- addVelocity(t, d, s);
- return true;
- }
- else if ( !key.Icmp( "baseVelocity" ) ) {
- baseVelocity = src->ParseFloat();
- return true;
- }
- else if ( !key.Icmp( "name" ) ) {
- src->ReadToken( &token );
- name = token;
- return true;
- }
- else if ( !key.Icmp( "time" ) ) {
- time = src->ParseInt();
- return true;
- }
- else {
- src->Error( "unknown camera position key: %s", key.c_str() );
- return false;
- }
- }
- /*
- ================
- idCameraPosition::write
- ================
- */
- void idCameraPosition::write( idFile *f, const char *p ) {
- f->Printf( "\t\ttime %i\n", time );
- f->Printf( "\t\ttype %i\n", static_cast<int>(type) );
- f->Printf( "\t\tname %s\n", name.c_str() );
- f->Printf( "\t\tbaseVelocity %f\n", baseVelocity );
- for (int i = 0; i < velocities.Num(); i++) {
- f->Printf( "\t\tvelocity %i %i %f\n", velocities[i]->startTime, velocities[i]->time, velocities[i]->speed );
- }
- }
- /*
- =================================================================================
- idInterpolatedPosition
- =================================================================================
- */
- /*
- ================
- idInterpolatedPosition::getPoint
- ================
- */
- idVec3 *idInterpolatedPosition::getPoint( int index ) {
- assert( index >= 0 && index < 2 );
- if ( index == 0 ) {
- return &startPos;
- }
- return &endPos;
- }
- /*
- ================
- idInterpolatedPosition::addPoint
- ================
- */
- void idInterpolatedPosition::addPoint( const float x, const float y, const float z ) {
- if (first) {
- startPos.Set(x, y, z);
- first = false;
- } else {
- endPos.Set(x, y, z);
- first = true;
- }
- }
- /*
- ================
- idInterpolatedPosition::addPoint
- ================
- */
- void idInterpolatedPosition::addPoint( const idVec3 &v ) {
- if (first) {
- startPos = v;
- first = false;
- }
- else {
- endPos = v;
- first = true;
- }
- }
- /*
- ================
- idInterpolatedPosition::draw
- ================
- */
- void idInterpolatedPosition::draw( bool editMode ) {
- glLabeledPoint(colorBlue, startPos, (editMode) ? 5 : 3, "Start interpolated");
- glLabeledPoint(colorBlue, endPos, (editMode) ? 5 : 3, "End interpolated");
- qglBegin(GL_LINES);
- qglVertex3fv( startPos.ToFloatPtr() );
- qglVertex3fv( endPos.ToFloatPtr() );
- qglEnd();
- }
- /*
- ================
- idInterpolatedPosition::start
- ================
- */
- void idInterpolatedPosition::start( long t ) {
- idCameraPosition::start(t);
- lastTime = startTime;
- distSoFar = 0.0f;
- idVec3 temp = startPos;
- temp -= endPos;
- calcVelocity(temp.Length());
- }
- /*
- ================
- idInterpolatedPosition::getPosition
- ================
- */
- const idVec3 *idInterpolatedPosition::getPosition( long t ) {
- static idVec3 interpolatedPos;
- if (t - startTime > 6000) {
- int i = 0;
- }
- float velocity = getVelocity(t);
- float timePassed = t - lastTime;
- lastTime = t;
- // convert to seconds
- timePassed /= 1000;
- if (velocity != getBaseVelocity()) {
- int i = 0;
- }
- float distToTravel = timePassed * velocity;
- idVec3 temp = startPos;
- temp -= endPos;
- float distance = temp.Length();
- distSoFar += distToTravel;
- float percent = (float)(distSoFar) / distance;
- if ( percent > 1.0f ) {
- percent = 1.0f;
- } else if ( percent < 0.0f ) {
- percent = 0.0f;
- }
- // the following line does a straigt calc on percentage of time
- // float percent = (float)(startTime + time - t) / time;
- idVec3 v1 = startPos;
- idVec3 v2 = endPos;
- v1 *= (1.0f - percent);
- v2 *= percent;
- v1 += v2;
- interpolatedPos = v1;
- return &interpolatedPos;
- }
- /*
- ================
- idInterpolatedPosition::parse
- ================
- */
- void idInterpolatedPosition::parse( idParser *src ) {
- idToken token;
- src->ExpectTokenString( "{" );
- while ( 1 ) {
- if ( !src->ExpectAnyToken( &token ) ) {
- break;
- }
- if ( token == "}" ) {
- break;
- }
- if ( !token.Icmp( "startPos" ) ) {
- src->Parse1DMatrix( 3, startPos.ToFloatPtr() );
- }
- else if ( !token.Icmp( "endPos" ) ) {
- src->Parse1DMatrix( 3, endPos.ToFloatPtr() );
- }
- else {
- idCameraPosition::parseToken( token, src);
- }
- }
- }
- /*
- ================
- idInterpolatedPosition::write
- ================
- */
- void idInterpolatedPosition::write( idFile *f, const char *p ) {
- f->Printf( "\t%s {\n", p );
- idCameraPosition::write( f, p );
- f->Printf( "\t\tstartPos ( %f %f %f )\n", startPos.x, startPos.y, startPos.z );
- f->Printf( "\t\tendPos ( %f %f %f )\n", endPos.x, endPos.y, endPos.z );
- f->Printf( "\t}\n" );
- }
- /*
- =================================================================================
- idCameraFOV
- =================================================================================
- */
- /*
- ================
- idCameraFOV::GetFOV
- ================
- */
- float idCameraFOV::GetFOV( long t ) {
- if (time) {
- assert(startTime);
- float percent = (t - startTime) / length;
- if ( percent < 0.0f ) {
- percent = 0.0f;
- } else if ( percent > 1.0f ) {
- percent = 1.0f;
- }
- float temp = endFOV - startFOV;
- temp *= percent;
- fov = startFOV + temp;
- }
- return fov;
- }
- /*
- ================
- idCameraFOV::reset
- ================
- */
- void idCameraFOV::reset( float startfov, float endfov, int start, int len ) {
- startFOV = startfov;
- endFOV = endfov;
- startTime = start;
- length = len;
- }
- /*
- ================
- idCameraFOV::parse
- ================
- */
- void idCameraFOV::parse( idParser *src ) {
- idToken token;
- src->ExpectTokenString( "{" );
- while ( 1 ) {
- if ( !src->ExpectAnyToken( &token ) ) {
- break;
- }
- if ( token == "}" ) {
- break;
- }
- if ( !token.Icmp( "fov" ) ) {
- fov = src->ParseFloat();
- }
- else if ( !token.Icmp( "startFOV" ) ) {
- startFOV = src->ParseFloat();
- }
- else if ( !token.Icmp( "endFOV" ) ) {
- endFOV = src->ParseFloat();
- }
- else if ( !token.Icmp( "time" ) ) {
- time = src->ParseInt();
- }
- else {
- src->Error( "unknown camera FOV key: %s", token.c_str() );
- break;
- }
- }
- }
- /*
- ================
- idCameraFOV::write
- ================
- */
- void idCameraFOV::write( idFile *f, const char *p ) {
- f->Printf( "\t%s {\n", p );
- f->Printf( "\t\tfov %f\n", fov );
- f->Printf( "\t\tstartFOV %f\n", startFOV );
- f->Printf( "\t\tendFOV %f\n", endFOV );
- f->Printf( "\t\ttime %i\n", time );
- f->Printf( "\t}\n" );
- }
- /*
- =================================================================================
- idFixedPosition
- =================================================================================
- */
- /*
- ================
- idFixedPosition::parse
- ================
- */
- void idFixedPosition::parse( idParser *src ) {
- idToken token;
- src->ExpectTokenString( "{" );
- while ( 1 ) {
- if ( !src->ExpectAnyToken( &token ) ) {
- break;
- }
- if ( token == "}" ) {
- break;
- }
- if ( !token.Icmp( "pos" ) ) {
- src->Parse1DMatrix( 3, pos.ToFloatPtr() );
- }
- else {
- idCameraPosition::parseToken( token, src );
- }
- }
- }
- /*
- ================
- idFixedPosition::write
- ================
- */
- void idFixedPosition::write( idFile *f, const char *p ) {
- f->Printf( "\t%s {\n", p );
- idCameraPosition::write( f, p );
- f->Printf( "\t\tpos ( %f %f %f )\n", pos.x, pos.y, pos.z );
- f->Printf( "\t}\n" );
- }
- /*
- =================================================================================
- idSplinePosition
- =================================================================================
- */
- /*
- ================
- idSplinePosition::start
- ================
- */
- void idSplinePosition::start( long t ) {
- idCameraPosition::start( t );
- target.initPosition(t, time);
- lastTime = startTime;
- distSoFar = 0.0f;
- calcVelocity(target.totalDistance());
- }
- /*
- ================
- idSplinePosition::parse
- ================
- */
- void idSplinePosition::parse( idParser *src ) {
- idToken token;
- src->ExpectTokenString( "{" );
- while ( 1 ) {
- if ( !src->ExpectAnyToken( &token ) ) {
- break;
- }
- if ( token == "}" ) {
- break;
- }
- if ( !token.Icmp( "target" ) ) {
- target.parse( src );
- }
- else {
- idCameraPosition::parseToken( token, src );
- }
- }
- }
- /*
- ================
- idSplinePosition::write
- ================
- */
- void idSplinePosition::write( idFile *f, const char *p ) {
- f->Printf( "\t%s {\n", p );
- idCameraPosition::write( f, p );
- target.write( f, "target" );
- f->Printf( "\t}\n" );
- }
- /*
- ================
- idSplinePosition::getPosition
- ================
- */
- const idVec3 *idSplinePosition::getPosition(long t) {
- static idVec3 interpolatedPos;
- float velocity = getVelocity(t);
- float timePassed = t - lastTime;
- lastTime = t;
- // convert to seconds
- timePassed /= 1000;
- float distToTravel = timePassed * velocity;
- distSoFar += distToTravel;
- double tempDistance = target.totalDistance();
- double percent = (double)(distSoFar) / tempDistance;
- double targetDistance = percent * tempDistance;
- tempDistance = 0;
- double lastDistance1,lastDistance2;
- lastDistance1 = lastDistance2 = 0;
- //FIXME: calc distances on spline build
- idVec3 temp;
- int count = target.numSegments();
- //for(int i = 2; i < count - 1; i++) {
- int i;
- for( i = 1; i < count; i++) {
- temp = *target.getSegmentPoint(i-1);
- temp -= *target.getSegmentPoint(i);
- tempDistance += temp.Length();
- if (i & 1) {
- lastDistance1 = tempDistance;
- } else {
- lastDistance2 = tempDistance;
- }
- if (tempDistance >= targetDistance) {
- break;
- }
- }
- if (i >= count - 1) {
- interpolatedPos = *target.getSegmentPoint(i-1);
- } else {
- #if 0
- double timeHi = target.getSegmentTime(i + 1);
- double timeLo = target.getSegmentTime(i - 1);
- double percent = (timeHi - t) / (timeHi - timeLo);
- idVec3 v1 = *target.getSegmentPoint(i - 1);
- idVec3 v2 = *target.getSegmentPoint(i + 1);
- v2 *= (1.0f - percent);
- v1 *= percent;
- v2 += v1;
- interpolatedPos = v2;
- #else
- if (lastDistance1 > lastDistance2) {
- double d = lastDistance2;
- lastDistance2 = lastDistance1;
- lastDistance1 = d;
- }
- idVec3 v1 = *target.getSegmentPoint(i - 1);
- idVec3 v2 = *target.getSegmentPoint(i);
- double percent = (lastDistance2 - targetDistance) / (lastDistance2 - lastDistance1);
- v2 *= (1.0f - percent);
- v1 *= percent;
- v2 += v1;
- interpolatedPos = v2;
- #endif
- }
- return &interpolatedPos;
- }
|