00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <assert.h>
00040 #include <string.h>
00041 #include <stdio.h>
00042
00043 #include "vec3d.h"
00044 #include "vkframe.h"
00045 #include "errorlog.h"
00046 #include "ram.h"
00047
00048 #define LINEAR_BLEND(a,b,t) ( (t)*((b)-(a)) + (a) )
00049
00050
00051 typedef struct
00052 {
00053 geTKArray_TimeType Time;
00054 geVec3d V;
00055 } geVKFrame;
00056
00057
00058
00059
00060 typedef struct
00061 {
00062 geVKFrame Key;
00063 geVec3d SDerivative;
00064 geVec3d DDerivative;
00065 } geVKFrame_Hermite;
00066
00067
00068
00069 typedef struct
00070 {
00071 geVKFrame Key;
00072 } geVKFrame_Linear;
00073
00074
00075
00076 geTKArray *GENESISCC geVKFrame_LinearCreate(void)
00077
00078 {
00079 return geTKArray_Create(sizeof(geVKFrame_Linear) );
00080 }
00081
00082
00083 geTKArray *GENESISCC geVKFrame_HermiteCreate(void)
00084
00085 {
00086 return geTKArray_Create(sizeof(geVKFrame_Hermite) );
00087 }
00088
00089
00090 geBoolean GENESISCC geVKFrame_Insert(
00091 geTKArray **KeyList,
00092 geTKArray_TimeType Time,
00093 const geVec3d *V,
00094 int *Index)
00095
00096 {
00097 assert( KeyList != NULL );
00098 assert( *KeyList != NULL );
00099 assert( V != NULL );
00100 assert( sizeof(geVKFrame_Hermite) == geTKArray_ElementSize(*KeyList)
00101 || sizeof(geVKFrame_Linear) == geTKArray_ElementSize(*KeyList) );
00102
00103 if (geTKArray_Insert(KeyList, Time, Index) == GE_FALSE)
00104 {
00105 geErrorLog_Add(ERR_VKARRAY_INSERT, NULL);
00106 return GE_FALSE;
00107 }
00108 else
00109 {
00110 geVKFrame *KF;
00111 KF = (geVKFrame *)geTKArray_Element(*KeyList,*Index);
00112 KF->V = *V;
00113 return GE_TRUE;
00114 }
00115 }
00116
00117 void GENESISCC geVKFrame_Query(
00118 const geTKArray *KeyList,
00119 int Index,
00120 geTKArray_TimeType *Time,
00121 geVec3d *V)
00122
00123 {
00124 geVKFrame *KF;
00125 assert( KeyList != NULL );
00126 assert( Time != NULL );
00127 assert( V != NULL );
00128 assert( Index < geTKArray_NumElements(KeyList) );
00129 assert( Index >= 0 );
00130 assert( sizeof(geVKFrame_Hermite) == geTKArray_ElementSize(KeyList)
00131 || sizeof(geVKFrame_Linear) == geTKArray_ElementSize(KeyList) );
00132
00133 KF = (geVKFrame *)geTKArray_Element(KeyList,Index);
00134 *Time = KF->Time;
00135 *V = KF->V;
00136 }
00137
00138
00139 void GENESISCC geVKFrame_Modify(
00140 geTKArray *KeyList,
00141 int Index,
00142 const geVec3d *V)
00143
00144 {
00145 geVKFrame *KF;
00146 assert( KeyList != NULL );
00147 assert( V != NULL );
00148 assert( Index < geTKArray_NumElements(KeyList) );
00149 assert( Index >= 0 );
00150 assert( sizeof(geVKFrame_Hermite) == geTKArray_ElementSize(KeyList)
00151 || sizeof(geVKFrame_Linear) == geTKArray_ElementSize(KeyList) );
00152
00153 KF = (geVKFrame *)geTKArray_Element(KeyList,Index);
00154 KF->V = *V;
00155 }
00156
00157
00158 void GENESISCC geVKFrame_LinearInterpolation(
00159 const void *KF1,
00160 const void *KF2,
00161 geFloat T,
00162 void *Result)
00163
00164
00165
00166
00167 {
00168 geVec3d *Vec1,*Vec2;
00169 geVec3d *VNew = (geVec3d *)Result;
00170
00171 assert( Result != NULL );
00172 assert( KF1 != NULL );
00173 assert( KF2 != NULL );
00174
00175 assert( T >= (geFloat)0.0f );
00176 assert( T <= (geFloat)1.0f );
00177
00178 if ( KF1 == KF2 )
00179 {
00180 *VNew = ((geVKFrame_Linear *)KF1)->Key.V;
00181 return;
00182 }
00183
00184 Vec1 = &( ((geVKFrame_Linear *)KF1)->Key.V);
00185 Vec2 = &( ((geVKFrame_Linear *)KF2)->Key.V);
00186
00187 VNew->X = LINEAR_BLEND(Vec1->X,Vec2->X,T);
00188 VNew->Y = LINEAR_BLEND(Vec1->Y,Vec2->Y,T);
00189 VNew->Z = LINEAR_BLEND(Vec1->Z,Vec2->Z,T);
00190 }
00191
00192
00193
00194 void GENESISCC geVKFrame_HermiteInterpolation(
00195 const void *KF1,
00196 const void *KF2,
00197 geFloat T,
00198 void *Result)
00199
00200
00201
00202
00203 {
00204 geVec3d *Vec1,*Vec2;
00205 geVec3d *VNew = (geVec3d *)Result;
00206
00207 assert( Result != NULL );
00208 assert( KF1 != NULL );
00209 assert( KF2 != NULL );
00210
00211 assert( T >= (geFloat)0.0f );
00212 assert( T <= (geFloat)1.0f );
00213
00214 if ( KF1 == KF2 )
00215 {
00216 *VNew = ((geVKFrame_Hermite *)KF1)->Key.V;
00217 return;
00218 }
00219
00220 Vec1 = &( ((geVKFrame_Hermite *)KF1)->Key.V);
00221 Vec2 = &( ((geVKFrame_Hermite *)KF2)->Key.V);
00222
00223 {
00224 geFloat t2;
00225 geFloat t3;
00226 geFloat H1,H2,H3,H4;
00227
00228 t2 = T * T;
00229 t3 = t2 * T;
00230
00231 H2 = -(t3 + t3) + t2*3.0f;
00232 H1 = 1.0f - H2;
00233 H4 = t3 - t2;
00234 H3 = H4 - t2 + T;
00235
00236 geVec3d_Scale(Vec1,H1,VNew);
00237 geVec3d_AddScaled(VNew,Vec2,H2,VNew);
00238 geVec3d_AddScaled(VNew,&( ((geVKFrame_Hermite *)KF1)->DDerivative),H3,VNew);
00239 geVec3d_AddScaled(VNew,&( ((geVKFrame_Hermite *)KF2)->SDerivative),H4,VNew);
00240 }
00241 }
00242
00243
00244 void GENESISCC geVKFrame_HermiteRecompute(
00245 int Looped,
00246 geBoolean ZeroDerivative,
00247 geTKArray *KeyList)
00248
00249 {
00250
00251 int i;
00252 geVec3d V0,V1,V2;
00253 geFloat Time0, Time1, Time2, N0, N1, N0N1;
00254 geVKFrame_Hermite *TK;
00255 geVKFrame_Hermite *Vector= NULL;
00256 int count;
00257 int Index0,Index1,Index2;
00258
00259 assert( KeyList != NULL );
00260 assert( sizeof(geVKFrame_Hermite) == geTKArray_ElementSize(KeyList) );
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 count = geTKArray_NumElements(KeyList);
00282 if (count > 0)
00283 {
00284 Vector = (geVKFrame_Hermite *)geTKArray_Element(KeyList,0);
00285 }
00286
00287 if (ZeroDerivative!=GE_FALSE)
00288 {
00289 for (i =0; i< count; i++)
00290 {
00291 TK = &(Vector[i]);
00292 geVec3d_Clear(&(TK->DDerivative));
00293 geVec3d_Clear(&(TK->SDerivative));
00294 }
00295 return;
00296 }
00297
00298 if (count < 3)
00299 {
00300 Looped = GE_FALSE;
00301
00302
00303 }
00304 for (i =0; i< count; i++)
00305 {
00306 TK = &(Vector[i]);
00307 Index0 = i-1;
00308 Index1 = i;
00309 Index2 = i+1;
00310
00311 Time1 = Vector[Index1].Key.Time;
00312 if (Index1 == 0)
00313 {
00314 if (Looped != GE_TRUE)
00315 {
00316 Index0 = 0;
00317 Time0 = Vector[Index0].Key.Time;
00318 }
00319 else
00320 {
00321 Index0 = count-2;
00322 Time0 = Time1 - (Vector[count-1].Key.Time - Vector[count-2].Key.Time);
00323 }
00324 }
00325 else
00326 {
00327 Time0 = Vector[Index0].Key.Time;
00328 }
00329
00330
00331 if (Index2 == count)
00332 {
00333 if (Looped != GE_TRUE)
00334 {
00335 Index2 = count-1;
00336 Time2 = Vector[Index2].Key.Time;
00337 }
00338 else
00339 {
00340 Index2 = 1;
00341 Time2 = Time1 + (Vector[1].Key.Time - Vector[0].Key.Time);
00342 }
00343 }
00344 else
00345 {
00346 Time2 = Vector[Index2].Key.Time;
00347 }
00348
00349 V0 = Vector[Index0].Key.V;
00350 V1 = Vector[Index1].Key.V;
00351 V2 = Vector[Index2].Key.V;
00352
00353 N0 = (Time1 - Time0);
00354 N1 = (Time2 - Time1);
00355 N0N1 = N0 + N1;
00356
00357 if (( Looped != GE_TRUE) && (Index1 == 0) )
00358 {
00359 geVec3d_Subtract(&V2,&V1,&(TK->SDerivative));
00360 geVec3d_Copy( &(TK->SDerivative), &(TK->DDerivative));
00361 }
00362 else if (( Looped != GE_TRUE) && (Index1 == count-1))
00363 {
00364 geVec3d_Subtract(&V1,&V0,&(TK->SDerivative));
00365 geVec3d_Copy( &(TK->SDerivative), &(TK->DDerivative));
00366 }
00367 else
00368 {
00369 geVec3d Slope;
00370 geVec3d_Subtract(&V2,&V0,&Slope);
00371 geVec3d_Scale(&Slope, (N1 / N0N1), &(TK->DDerivative));
00372 geVec3d_Scale(&Slope, (N0 / N0N1), &(TK->SDerivative));
00373 }
00374 }
00375 }
00376
00377
00378 #define VKFRAME_LINEAR_ASCII_FILE 0x4C464B56 // 'VKFL'
00379 #define VKFRAME_HERMITE_ASCII_FILE 0x48464B56 // 'VKFH'
00380 #define CHECK_FOR_READ(uu, nn) if(uu != nn) { geErrorLog_Add(ERR_PATH_FILE_READ, NULL); return GE_FALSE; }
00381 #define CHECK_FOR_WRITE(uu) if (uu <= 0) { geErrorLog_Add(ERR_PATH_FILE_WRITE, NULL); return GE_FALSE; }
00382
00383 #define VKFRAME_KEYLIST_ID "Keys"
00384
00385
00386
00387
00388
00389 geBoolean GENESISCC geVKFrame_LinearRead(geVFile* pFile, void* geVKFrame)
00390 {
00391 uint32 u;
00392 char KeyString[64];
00393 geVKFrame_Linear* pLinear = (geVKFrame_Linear*)geVKFrame;
00394
00395 assert( pFile != NULL );
00396 assert( geVKFrame != NULL );
00397
00398
00399 if(geVFile_Read(pFile, &u, sizeof(u)) == GE_FALSE)
00400 {
00401 geErrorLog_Add(ERR_PATH_FILE_READ, NULL);
00402 return GE_FALSE;
00403 }
00404
00405 if(u != VKFRAME_LINEAR_ASCII_FILE)
00406 {
00407 geErrorLog_Add(ERR_PATH_FILE_VERSION, NULL);
00408 return GE_FALSE;
00409 }
00410
00411 if (geVFile_GetS(pFile, KeyString, sizeof(KeyString)) == GE_FALSE)
00412 {
00413 geErrorLog_Add(ERR_PATH_FILE_READ, NULL);
00414 return GE_FALSE;
00415 }
00416
00417 u = sscanf(KeyString, "%f %f %f\n", &pLinear->Key.V.X,
00418 &pLinear->Key.V.Y,
00419 &pLinear->Key.V.Z);
00420 CHECK_FOR_READ(u, 3);
00421
00422 return GE_TRUE;
00423 }
00424
00425
00426 geBoolean GENESISCC geVKFrame_HermiteRead(geVFile* pFile, void* geVKFrame)
00427 {
00428 uint32 u;
00429 char HermiteString[128];
00430 geVKFrame_Hermite* pHermite = (geVKFrame_Hermite*)geVKFrame;
00431
00432 assert( pFile != NULL );
00433 assert( geVKFrame != NULL );
00434
00435
00436 if(geVFile_Read(pFile, &u, sizeof(u)) == GE_FALSE)
00437 {
00438 geErrorLog_Add(ERR_PATH_FILE_READ, NULL);
00439 return GE_FALSE;
00440 }
00441
00442 if(u != VKFRAME_HERMITE_ASCII_FILE)
00443 {
00444 geErrorLog_Add(ERR_PATH_FILE_VERSION, NULL);
00445 return GE_FALSE;
00446 }
00447
00448 if (geVFile_GetS(pFile, HermiteString, sizeof(HermiteString)) == GE_FALSE)
00449 {
00450 geErrorLog_Add(ERR_PATH_FILE_READ, NULL);
00451 return GE_FALSE;
00452 }
00453 u = sscanf(HermiteString, "%f %f %f %f %f %f %f %f %f\n", &pHermite->Key.V.X,
00454 &pHermite->Key.V.Y,
00455 &pHermite->Key.V.Z,
00456 &pHermite->SDerivative.X,
00457 &pHermite->SDerivative.Y,
00458 &pHermite->SDerivative.Z,
00459 &pHermite->DDerivative.X,
00460 &pHermite->DDerivative.Y,
00461 &pHermite->DDerivative.Z);
00462 CHECK_FOR_READ(u, 9);
00463
00464 return GE_TRUE;
00465 }
00466
00467
00468
00469
00470 #define LINEARTIME_TOLERANCE (0.0001f)
00471 #define VKFRAME_LINEARTIME_COMPRESSION 0x2
00472
00473
00474
00475 geBoolean GENESISCC geVKFrame_WriteToFile(geVFile *pFile, geTKArray *KeyList,
00476 geVKFrame_InterpolationType InterpolationType, int Looping)
00477 {
00478 int NumElements,i;
00479 geFloat Time,DeltaTime;
00480 int Compression=0;
00481
00482 assert( pFile != NULL );
00483 assert( KeyList != NULL );
00484
00485 NumElements = geTKArray_NumElements(KeyList);
00486
00487 if (NumElements>2)
00488 {
00489 if ( geTKArray_SamplesAreTimeLinear(KeyList,LINEARTIME_TOLERANCE) != GE_FALSE )
00490 {
00491 Compression |= VKFRAME_LINEARTIME_COMPRESSION;
00492 }
00493 }
00494
00495
00496 if (geVFile_Printf(pFile,
00497 "%s %d %d %d %d\n",
00498 VKFRAME_KEYLIST_ID,
00499 NumElements,
00500 InterpolationType,
00501 Compression,
00502 Looping) == GE_FALSE)
00503 {
00504 geErrorLog_Add(ERR_PATH_FILE_WRITE, NULL);
00505 return GE_FALSE;
00506 }
00507
00508 if (Compression & VKFRAME_LINEARTIME_COMPRESSION)
00509 {
00510 Time = geTKArray_ElementTime(KeyList, 0);
00511 DeltaTime = geTKArray_ElementTime(KeyList, 1)- Time;
00512 if(geVFile_Printf(pFile,"%f %f Start T,Delta T\n",Time,DeltaTime) == GE_FALSE)
00513 {
00514 geErrorLog_Add(ERR_PATH_FILE_WRITE, NULL);
00515 return GE_FALSE;
00516 }
00517 }
00518
00519 for(i=0;i<NumElements;i++)
00520 {
00521 geVKFrame_Linear* pLinear = (geVKFrame_Linear*)geTKArray_Element(KeyList, i);
00522 if (!(Compression & VKFRAME_LINEARTIME_COMPRESSION))
00523 {
00524 Time = geTKArray_ElementTime(KeyList, i);
00525 if (geVFile_Printf(pFile, "%f ", Time ) == GE_FALSE)
00526 {
00527 geErrorLog_Add(ERR_PATH_FILE_WRITE, NULL);
00528 return GE_FALSE;
00529 }
00530 }
00531 if (geVFile_Printf(pFile,
00532 "%f %f %f\n",
00533 pLinear->Key.V.X,
00534 pLinear->Key.V.Y,
00535 pLinear->Key.V.Z) == GE_FALSE)
00536 {
00537 geErrorLog_Add(ERR_PATH_FILE_WRITE, NULL);
00538 return GE_FALSE;
00539 }
00540 }
00541 return GE_TRUE;
00542 }
00543
00544
00545 geTKArray *GENESISCC geVKFrame_CreateFromFile(geVFile *pFile, int *InterpolationType, int *Looping)
00546 {
00547 #define ERROREXIT {geErrorLog_Add( ERR_PATH_FILE_READ , NULL);if (KeyList != NULL){geTKArray_Destroy(&KeyList);} return NULL;}
00548 int i,u,NumElements;
00549 int Compression;
00550 #define LINE_LENGTH 256
00551 char line[LINE_LENGTH];
00552 geTKArray *KeyList= NULL;
00553 geFloat StartTime=0.0f;
00554 geFloat DeltaTime=0.0f;
00555
00556
00557 assert( pFile != NULL );
00558 assert( InterpolationType != NULL );
00559
00560 if(geVFile_GetS(pFile, line, LINE_LENGTH) == GE_FALSE)
00561 ERROREXIT;
00562
00563 if(strnicmp(line, VKFRAME_KEYLIST_ID, sizeof(VKFRAME_KEYLIST_ID)-1) != 0)
00564 ERROREXIT;
00565
00566 if(sscanf(line + sizeof(VKFRAME_KEYLIST_ID)-1, "%d %d %d %d",
00567 &NumElements,InterpolationType,&Compression,Looping) != 4)
00568 ERROREXIT;
00569
00570 switch (*InterpolationType)
00571 {
00572 case (VKFRAME_LINEAR):
00573 KeyList = geTKArray_CreateEmpty(sizeof(geVKFrame_Linear),NumElements);
00574 break;
00575 case (VKFRAME_HERMITE):
00576 case (VKFRAME_HERMITE_ZERO_DERIV):
00577 KeyList = geTKArray_CreateEmpty(sizeof(geVKFrame_Hermite),NumElements);
00578 break;
00579 default:
00580 ERROREXIT;
00581 }
00582 if (KeyList == NULL)
00583 ERROREXIT;
00584
00585 if (Compression & VKFRAME_LINEARTIME_COMPRESSION)
00586 {
00587 if(geVFile_GetS(pFile, line, LINE_LENGTH) == GE_FALSE)
00588 ERROREXIT;
00589 if (sscanf(line,"%f %f",&StartTime,&DeltaTime) != 2)
00590 ERROREXIT;
00591 }
00592
00593 for(i=0;i<NumElements;i++)
00594 {
00595 geVKFrame_Linear* pLinear = (geVKFrame_Linear*)geTKArray_Element(KeyList, i);
00596 if(geVFile_GetS(pFile, line, LINE_LENGTH) == GE_FALSE)
00597 ERROREXIT;
00598
00599 if (Compression & VKFRAME_LINEARTIME_COMPRESSION)
00600 {
00601 pLinear->Key.Time = StartTime + DeltaTime * i;
00602 u = sscanf(line,"%f %f %f", &(pLinear->Key.V.X),
00603 &(pLinear->Key.V.Y),&(pLinear->Key.V.Z));
00604 if (u!=3)
00605 ERROREXIT;
00606 }
00607 else
00608 {
00609 u = sscanf(line,"%f %f %f %f",&(pLinear->Key.Time), &(pLinear->Key.V.X),
00610 &(pLinear->Key.V.Y),&(pLinear->Key.V.Z));
00611 if (u!=4)
00612 ERROREXIT;
00613 }
00614 }
00615
00616 switch (*InterpolationType)
00617 {
00618 case (VKFRAME_LINEAR):
00619 break;
00620 case (VKFRAME_HERMITE):
00621 geVKFrame_HermiteRecompute( *Looping, GE_FALSE, KeyList);
00622 break;
00623 case (VKFRAME_HERMITE_ZERO_DERIV):
00624 geVKFrame_HermiteRecompute( *Looping, GE_TRUE, KeyList);
00625 break;
00626 default:
00627 assert(0);
00628 }
00629
00630 return KeyList;
00631 }
00632
00633 uint32 GENESISCC geVKFrame_ComputeBlockSize(geTKArray *KeyList, int Compression)
00634 {
00635 uint32 Size=0;
00636 int Count;
00637
00638 assert( KeyList != NULL );
00639 assert( Compression < 0xFF);
00640
00641 Count = geTKArray_NumElements(KeyList);
00642
00643 Size += sizeof(uint32);
00644 Size += sizeof(uint32);
00645
00646 if (Compression & VKFRAME_LINEARTIME_COMPRESSION)
00647 {
00648 Size += sizeof(geFloat) * 2;
00649 }
00650 else
00651 {
00652 Size += sizeof(geFloat) * Count;
00653 }
00654
00655 Size += sizeof(geVec3d) * Count;
00656 return Size;
00657 }
00658
00659
00660 geTKArray *GENESISCC geVKFrame_CreateFromBinaryFile(geVFile *pFile, int *InterpolationType, int *Looping)
00661 {
00662 uint32 u;
00663 int BlockSize;
00664 int Compression;
00665 int Count,i;
00666 int FieldSize;
00667 char *Block;
00668 geFloat *Data;
00669 geTKArray *KeyList;
00670 geVKFrame_Linear* pLinear0;
00671 geVKFrame_Linear* pLinear;
00672
00673 assert( pFile != NULL );
00674 assert( InterpolationType != NULL );
00675 assert( Looping != NULL );
00676
00677 if (geVFile_Read(pFile, &BlockSize, sizeof(int)) == GE_FALSE)
00678 {
00679 geErrorLog_AddString(-1,"Failure to read binary VKFrame header", NULL);
00680 return NULL;
00681 }
00682 if (BlockSize<0)
00683 {
00684 geErrorLog_AddString(-1,"Bad Blocksize", NULL);
00685 return NULL;
00686 }
00687
00688 Block = geRam_Allocate(BlockSize);
00689 if(geVFile_Read(pFile, Block, BlockSize) == GE_FALSE)
00690 {
00691 geErrorLog_AddString(-1,"Failure to read binary VKFrame header", NULL);
00692 return NULL;
00693 }
00694 u = *(uint32 *)Block;
00695 *InterpolationType = (u>>16)& 0xFF;
00696 Compression = (u>>8) & 0xFF;
00697 *Looping = (u & 0x1);
00698 Count = *(((uint32 *)Block)+1);
00699
00700 if (Compression > 0xFF)
00701 {
00702 geRam_Free(Block);
00703 geErrorLog_AddString(-1,"Bad Compression Flag", NULL);
00704 return NULL;
00705 }
00706 switch (*InterpolationType)
00707 {
00708 case (VKFRAME_LINEAR):
00709 FieldSize = sizeof(geVKFrame_Linear);
00710 break;
00711 case (VKFRAME_HERMITE):
00712 case (VKFRAME_HERMITE_ZERO_DERIV):
00713 FieldSize = sizeof(geVKFrame_Hermite);
00714 break;
00715 default:
00716 geRam_Free(Block);
00717 geErrorLog_AddString(-1,"Bad InterpolationType", NULL);
00718 return NULL;
00719 }
00720
00721 KeyList = geTKArray_CreateEmpty(FieldSize,Count);
00722 if (KeyList == NULL)
00723 {
00724 geRam_Free(Block);
00725 geErrorLog_AddString(-1,"Failed to allocate tkarray", NULL);
00726 return NULL;
00727 }
00728
00729 Data = (geFloat *)(Block + sizeof(uint32)*2);
00730
00731 pLinear0 = (geVKFrame_Linear*)geTKArray_Element(KeyList, 0);
00732
00733 pLinear = pLinear0;
00734
00735 if (Compression & VKFRAME_LINEARTIME_COMPRESSION)
00736 {
00737 geFloat fi;
00738 geFloat fCount = (geFloat)Count;
00739 geFloat Time,DeltaTime;
00740 Time = *(Data++);
00741 DeltaTime = *(Data++);
00742 for(fi=0.0f;fi<fCount;fi+=1.0f)
00743 {
00744 pLinear->Key.Time = Time + fi*DeltaTime;
00745 pLinear = (geVKFrame_Linear *) ( ((char *)pLinear) + FieldSize );
00746 }
00747 }
00748 else
00749 {
00750 for(i=0;i<Count;i++)
00751 {
00752 pLinear->Key.Time = *(Data++);
00753 pLinear = (geVKFrame_Linear *) ( ((char *)pLinear) + FieldSize );
00754 }
00755 }
00756
00757 pLinear = pLinear0;
00758 for(i=0;i<Count;i++)
00759 {
00760 pLinear->Key.V = *(geVec3d *)Data;
00761 Data += 3;
00762 pLinear = (geVKFrame_Linear *) ( ((char *)pLinear) + FieldSize );
00763 }
00764
00765 switch (*InterpolationType)
00766 {
00767 case (VKFRAME_LINEAR):
00768 break;
00769 case (VKFRAME_HERMITE):
00770 geVKFrame_HermiteRecompute( *Looping, GE_FALSE, KeyList);
00771 break;
00772 case (VKFRAME_HERMITE_ZERO_DERIV):
00773 geVKFrame_HermiteRecompute( *Looping, GE_TRUE, KeyList);
00774 break;
00775 default:
00776 assert(0);
00777 }
00778 geRam_Free(Block);
00779 return KeyList;
00780
00781 }
00782
00783 geBoolean GENESISCC geVKFrame_WriteToBinaryFile(geVFile *pFile, geTKArray *KeyList,
00784 geVKFrame_InterpolationType InterpolationType, int Looping)
00785 {
00786 #define WBERREXIT {geErrorLog_AddString( ERR_PATH_FILE_WRITE,"Failure to write binary key data", NULL);return GE_FALSE;}
00787 uint32 u,BlockSize;
00788 int Compression=0;
00789 int Count,i;
00790 geFloat Time,DeltaTime;
00791
00792 assert( pFile != NULL );
00793 assert( InterpolationType < 0xFF);
00794 assert( (Looping == 0) || (Looping == 1) );
00795
00796 if (geTKArray_NumElements(KeyList)>2)
00797 {
00798 if ( geTKArray_SamplesAreTimeLinear(KeyList,LINEARTIME_TOLERANCE) != GE_FALSE )
00799 {
00800 Compression |= VKFRAME_LINEARTIME_COMPRESSION;
00801 }
00802 }
00803
00804 u = (InterpolationType << 16) | (Compression << 8) | Looping;
00805
00806 BlockSize = geVKFrame_ComputeBlockSize(KeyList,Compression);
00807
00808 if (geVFile_Write(pFile, &BlockSize,sizeof(uint32)) == GE_FALSE)
00809 WBERREXIT;
00810
00811 if (geVFile_Write(pFile, &u, sizeof(uint32)) == GE_FALSE)
00812 WBERREXIT;
00813
00814 Count = geTKArray_NumElements(KeyList);
00815 if (geVFile_Write(pFile, &Count, sizeof(uint32)) == GE_FALSE)
00816 WBERREXIT;
00817
00818 if (Compression & VKFRAME_LINEARTIME_COMPRESSION)
00819 {
00820 Time = geTKArray_ElementTime(KeyList, 0);
00821 DeltaTime = geTKArray_ElementTime(KeyList, 1)- Time;
00822 if (geVFile_Write(pFile, &Time,sizeof(geFloat)) == GE_FALSE)
00823 WBERREXIT;
00824 if (geVFile_Write(pFile, &DeltaTime,sizeof(geFloat)) == GE_FALSE)
00825 WBERREXIT;
00826 }
00827 else
00828 {
00829 for(i=0;i<Count;i++)
00830 {
00831 Time = geTKArray_ElementTime(KeyList, i);
00832 if (geVFile_Write(pFile, &Time,sizeof(geFloat)) == GE_FALSE)
00833 WBERREXIT;
00834 }
00835 }
00836
00837 for(i=0;i<Count;i++)
00838 {
00839 geVKFrame_Linear* pLinear = (geVKFrame_Linear*)geTKArray_Element(KeyList, i);
00840 if (geVFile_Write(pFile, &(pLinear->Key.V),sizeof(geVec3d)) == GE_FALSE)
00841 WBERREXIT;
00842 }
00843
00844 return GE_TRUE;
00845 }