#include "SCENE.h" void Quat::ComputeFromMatrix(MATRIX *ActualMat) { float T, S; int iBestColumn; MATRIX LocalNormed; LocalNormed = *ActualMat; LocalNormed.I.Normalize(); LocalNormed.J.Normalize(); LocalNormed.K.Normalize(); if ((LocalNormed.I ^ LocalNormed.J) * LocalNormed.K < 0.0f) iBestColumn = 0; // <- never enter here !!! */ /* trace of the matrix */ T = LocalNormed.I.x + LocalNormed.J.y + LocalNormed.K.z; if(T > 0.0f) { S = sqrtf(T + 1.0f); w = S * 0.5f; S = 0.5f / S; x = (LocalNormed.J.z - LocalNormed.K.y) * S; y = (LocalNormed.K.x - LocalNormed.I.z) * S; z = (LocalNormed.I.y - LocalNormed.J.x) * S; } else { /* Find the greatest diagonal element */ if(LocalNormed.I.x >= LocalNormed.J.y) { if(LocalNormed.I.x >= LocalNormed.K.z) iBestColumn = 1; else iBestColumn = 3; } else { if(LocalNormed.J.y >= LocalNormed.K.z) iBestColumn = 2; else iBestColumn = 3; } switch(iBestColumn) { case 1: S = sqrtf(1.0f + LocalNormed.I.x - LocalNormed.J.y - LocalNormed.K.z); x = S * 0.5f; S = 0.5f / S; y = (LocalNormed.J.x + LocalNormed.I.y) * S; z = (LocalNormed.K.x + LocalNormed.I.z) * S; w = (LocalNormed.J.z - LocalNormed.K.y) * S; break; case 2: S = sqrtf(1.0f - LocalNormed.I.x + LocalNormed.J.y - LocalNormed.K.z); y = S * 0.5f; S = 0.5f / S; z = (LocalNormed.K.y + LocalNormed.J.z) * S; x = (LocalNormed.I.y + LocalNormed.J.x) * S; w = (LocalNormed.K.x - LocalNormed.I.z) * S; break; case 3: S = sqrtf(1.0f - LocalNormed.I.x - LocalNormed.J.y + LocalNormed.K.z); z = S * 0.5f; S = 0.5f / S; x = (LocalNormed.I.z + LocalNormed.K.x) * S; y = (LocalNormed.J.z + LocalNormed.K.y) * S; w = (LocalNormed.I.y - LocalNormed.J.x) * S; break; } } Normalize(); }; void Quat::TransforToMatrix(MATRIX *ActualMat) { float xx, xy, xz, xw, yy, yz, yw, zz, zw; xx = 0.5f - 2.0f * x * x; xy = 2.0f * x * y; xz = 2.0f * x * z; xw = 2.0f * x * w; yy = 0.5f - 2.0f * y * y; yz = 2.0f * y * z; yw = 2.0f * y * w; zz = 0.5f - 2.0f * z * z; zw = 2.0f * z * w; ActualMat->I.x = yy + zz; ActualMat->J.x = xy - zw; ActualMat->K.x = xz + yw; ActualMat->I.y = xy + zw; ActualMat->J.y = xx + zz; ActualMat->K.y = yz - xw; ActualMat->I.z = xz - yw; ActualMat->J.z = yz + xw; ActualMat->K.z = xx + yy; ActualMat->T = Vector(0,0,0); } #define MEM_ADJUST(NewNumber,Number,type,Pointer,DefaultValue)\ {\ u32 RealNewN;\ RealNewN = (NewNumber & ~0x1f) + 32;\ if (Number)\ {\ Pointer = (type *)CC_realloc(Pointer,RealNewN*sizeof(type));\ } else\ Pointer = (type *)CC_malloc(RealNewN*sizeof(type));\ while (Number < RealNewN) {\ Pointer[Number++] = DefaultValue;\ };\ } /**********************************************************************************/ /************* Track Stream ************/ /**********************************************************************************/ void TrackPlayer_Stream::VerifyStream(int TimeLineIndex) { if (TimeLineIndex >= ulNumberOfMC) { MatrixCompressed DefaultMat; DefaultMat.IsValid = 0; DefaultMat.Trans = Vector(0,0,0); DefaultMat.Rot = Quat(0,0,0,1); DefaultMat.SkinColor = 0; DefaultMat.DataIndex = -1; MEM_ADJUST(TimeLineIndex,ulNumberOfMC,MatrixCompressed,pAnimation,DefaultMat); } } void TrackPlayer_Stream::Set(u32 TimeLineIndex,MATRIX *ActualMat,u32 Validity) { VerifyStream(TimeLineIndex); if (ActualMat != NULL) { pAnimation[TimeLineIndex].Trans = ActualMat->T; pAnimation[TimeLineIndex].Rot.ComputeFromMatrix(ActualMat); pAnimation[TimeLineIndex].IsValid = Validity; } } u32 TrackPlayer_Stream::Get(u32 TimeLineIndex,MATRIX *ActualMat) { if (TimeLineIndex >= ulNumberOfMC) return 0; pAnimation[TimeLineIndex].Rot.TransforToMatrix(ActualMat); ActualMat->T = pAnimation[TimeLineIndex].Trans; return pAnimation[TimeLineIndex].IsValid; } u32 TrackPlayer_Stream::Get(double TimeLineFloat,MATRIX *ActualMat) { u32 TimeInt = (u32)TimeLineFloat; double diff = TimeLineFloat - (double)TimeInt; if (diff < 0.1) { if (TimeInt >= ulNumberOfMC) return 0; pAnimation[TimeInt].Rot.TransforToMatrix(ActualMat); ActualMat->T = pAnimation[TimeInt].Trans; return pAnimation[TimeInt].IsValid; } else if (diff > 0.9) { TimeInt++; if (TimeInt >= ulNumberOfMC) return 0; pAnimation[TimeInt].Rot.TransforToMatrix(ActualMat); ActualMat->T = pAnimation[TimeInt].Trans; return pAnimation[TimeInt].IsValid; } else { if (TimeInt+1 >= ulNumberOfMC) return 0; if (pAnimation[TimeInt].IsValid >= 4 || IsMatriceCompressedNull(&pAnimation[TimeInt]) || pAnimation[TimeInt+1].IsValid >= 4 || IsMatriceCompressedNull(&pAnimation[TimeInt+1])) return pAnimation[TimeInt].IsValid; Quat RotInterpol; RotInterpol = pAnimation[TimeInt].Rot*(1.0-diff) + pAnimation[TimeInt+1].Rot*diff; RotInterpol.NormalizeW(); RotInterpol.TransforToMatrix(ActualMat); ActualMat->T = pAnimation[TimeInt].Trans*(1.0-diff)+ pAnimation[TimeInt+1].Trans*diff; return pAnimation[TimeInt].IsValid; } } void TrackPlayer_Stream::SetSkinColor(u32 TimeLineIndex,u32 Color) { VerifyStream(TimeLineIndex); pAnimation[TimeLineIndex].SkinColor = Color; } u32 TrackPlayer_Stream::GetSkinColor(u32 TimeLineIndex) { if (TimeLineIndex >= ulNumberOfMC) return 0; return pAnimation[TimeLineIndex].SkinColor; // Do not return changing scene status } void TrackPlayer_Stream::SetDataIndex(u32 TimeLineIndex, int DataIndex) { VerifyStream(TimeLineIndex); pAnimation[TimeLineIndex].DataIndex = DataIndex; } int TrackPlayer_Stream::GetDataIndex(u32 TimeLineIndex) { if (TimeLineIndex >= ulNumberOfMC) return -1; return pAnimation[TimeLineIndex].DataIndex; } /**********************************************************************************/ /************* Track Data ************/ /**********************************************************************************/ int TrackPlayer_Data::GetInfoIndex(char *name) { // naive version, no dictionary TrackPlayer_DataInfo *InfosPtrIn = InfosPtr; for (int idx=0; idxName, name)) return idx; } return -1; } int TrackPlayer_Data::AddInfoIndex(char *name, TRK_DATA_TYPE type) { int index = GetInfoIndex(name); TrackPlayer_DataInfo *InfosPtrIn = InfosPtr; if (index == -1) { index = ulNumberOfInfos; if (ulNumberOfInfos == 0) { ulNumberOfInfos = 1; InfosPtr = (TrackPlayer_DataInfo *)CC_malloc(ulNumberOfInfos*sizeof(TrackPlayer_DataInfo)); InfosPtrIn = InfosPtr; } else { ulNumberOfInfos++; InfosPtr = (TrackPlayer_DataInfo *)CC_realloc(InfosPtr, ulNumberOfInfos*sizeof(TrackPlayer_DataInfo)); InfosPtrIn = InfosPtr + (ulNumberOfInfos - 1); } memset(InfosPtrIn, 0, sizeof(TrackPlayer_DataInfo)); strcpy(InfosPtrIn->Name, name); InfosPtrIn->DataType = type; } return index; } int TrackPlayer_Data::DelInfoIndex(int index) { if (index < 0 && index >= ulNumberOfInfos) return 0; *InfosPtr[index].Name = 0; return 1; } TRK_DATA_TYPE TrackPlayer_Data::GetInfoType(char *name) { int idx = GetInfoIndex(name); if (idx != -1) return GetInfoType(idx); return TRK_DATA_EMPTY; } TRK_DATA_TYPE TrackPlayer_Data::GetInfoType(int index) { if (index < 0 || index >= ulNumberOfInfos) return TRK_DATA_EMPTY; return InfosPtr[index].DataType; } int TrackPlayer_Data::GetCell(char TrackStream, int TrackPos) { TrackPlayer_DataCell *CellsPtrIn = CellsPtr; for (int idx = 0; idx < ulNumberOfCells; idx++, CellsPtrIn++) { if (CellsPtrIn->TrackStream == TrackStream && CellsPtrIn->TrackPos == TrackPos && CellsPtrIn->PrevCell == -1) return idx; } return -1; } int TrackPlayer_Data::AddCell(int NameIdx, int cellIdx) { TrackPlayer_DataCell *CellsPtrIn = CellsPtr; int emptyCellIdx = -1; if (CellsPtr) { if (EmptyCellList != -1) { emptyCellIdx = EmptyCellList; EmptyCellList = CellsPtr[EmptyCellList].NextCell; if (EmptyCellList != -1) CellsPtr[EmptyCellList].PrevCell = -1; } } if (emptyCellIdx == -1) { emptyCellIdx = ulNumberOfCells; if (ulNumberOfCells == 0) { ulNumberOfCells = 256; CellsPtr = (TrackPlayer_DataCell *)CC_malloc(ulNumberOfCells*sizeof(TrackPlayer_DataCell)); CellsPtrIn = CellsPtr; } else { ulNumberOfCells += 256; CellsPtr = (TrackPlayer_DataCell *)CC_realloc(CellsPtr, ulNumberOfCells*sizeof(TrackPlayer_DataCell)); CellsPtrIn = CellsPtr + (ulNumberOfCells - 256); } memset(CellsPtrIn, 0, 256*sizeof(TrackPlayer_DataCell)); CellsPtrIn++; // for used; EmptyCellList = emptyCellIdx + 1; for (int idx = EmptyCellList; idx < ulNumberOfCells; idx++, CellsPtrIn++) { CellsPtrIn->DataNameIdx = -1; CellsPtrIn->PrevCell = idx-1; CellsPtrIn->NextCell = idx+1; } CellsPtr[EmptyCellList].PrevCell = -1; CellsPtr[ulNumberOfCells-1].NextCell= -1; } CellsPtr[emptyCellIdx].DataNameIdx = NameIdx; if (cellIdx != -1) { while (CellsPtr[cellIdx].NextCell != -1) cellIdx = CellsPtr[cellIdx].NextCell; CellsPtr[cellIdx].NextCell = emptyCellIdx; } CellsPtr[emptyCellIdx].PrevCell = cellIdx; CellsPtr[emptyCellIdx].NextCell = -1; return emptyCellIdx; } int TrackPlayer_Data::DelCell(int cellIdx) { int nextPos = -1; if (cellIdx < 0 || cellIdx >= ulNumberOfCells) return -1; if (CellsPtr[cellIdx].DataNameIdx != -1 && InfosPtr[CellsPtr[cellIdx].DataNameIdx].DataType == TRK_DATA_STR && CellsPtr[cellIdx].ValueStr) { CC_free(CellsPtr[cellIdx].ValueStr); CellsPtr[cellIdx].ValueStr = NULL; CellsPtr[cellIdx].ValueLen = 0; } CellsPtr[cellIdx].DataNameIdx = -1; if (CellsPtr[cellIdx].PrevCell != -1) CellsPtr[CellsPtr[cellIdx].PrevCell].NextCell = CellsPtr[cellIdx].NextCell; if (CellsPtr[cellIdx].NextCell != -1) CellsPtr[CellsPtr[cellIdx].NextCell].PrevCell = CellsPtr[cellIdx].PrevCell; nextPos = CellsPtr[cellIdx].NextCell; CellsPtr[cellIdx].PrevCell = -1; CellsPtr[cellIdx].NextCell = EmptyCellList; CellsPtr[EmptyCellList].PrevCell= cellIdx; EmptyCellList = cellIdx; return nextPos; } /********** Shortcut functions ***********/ int TrackPlayer_Data::SetValueInt(int cellIdx, int value, int TrackStream, int TrackPos) { if (cellIdx < 0 || cellIdx >= ulNumberOfCells) return 0; int NameIdx = CellsPtr[cellIdx].DataNameIdx; if (NameIdx == -1) return 0; if (InfosPtr[NameIdx].DataType != TRK_DATA_INT) return 0; CellsPtr[cellIdx].TrackStream = TrackStream; CellsPtr[cellIdx].TrackPos = TrackPos; CellsPtr[cellIdx].ValueLen = 4; CellsPtr[cellIdx].ValueInt = value; return 1; } u32 TrackPlayer_Data::GetValueInt(int cellIdx, int *value) { if (cellIdx < 0 || cellIdx >= ulNumberOfCells) return 0; int NameIdx = CellsPtr[cellIdx].DataNameIdx; if (NameIdx == -1) return 0; if (InfosPtr[NameIdx].DataType != TRK_DATA_INT) return 0; *value = CellsPtr[cellIdx].ValueInt; return 1; } int TrackPlayer_Data::SetValueFloat(int cellIdx, float value, int TrackStream, int TrackPos) { if (cellIdx < 0 || cellIdx >= ulNumberOfCells) return 0; int NameIdx = CellsPtr[cellIdx].DataNameIdx; if (NameIdx == -1) return 0; if (InfosPtr[NameIdx].DataType != TRK_DATA_FLOAT) return 0; CellsPtr[cellIdx].TrackStream = TrackStream; CellsPtr[cellIdx].TrackPos = TrackPos; CellsPtr[cellIdx].ValueLen = 4; CellsPtr[cellIdx].ValueFloat = value; return 1; } u32 TrackPlayer_Data::GetValueFloat(int cellIdx, float *value) { if (cellIdx < 0 || cellIdx >= ulNumberOfCells) return 0; int NameIdx = CellsPtr[cellIdx].DataNameIdx; if (NameIdx == -1) return 0; if (InfosPtr[NameIdx].DataType != TRK_DATA_FLOAT) return 0; *value = CellsPtr[cellIdx].ValueFloat; return 1; } int TrackPlayer_Data::SetValueStr(int cellIdx, char *value, int TrackStream, int TrackPos) { if (cellIdx < 0 || cellIdx >= ulNumberOfCells) return 0; int NameIdx = CellsPtr[cellIdx].DataNameIdx; if (NameIdx == -1) return 0; if (InfosPtr[NameIdx].DataType != TRK_DATA_STR) return 0; CellsPtr[cellIdx].TrackStream = TrackStream; CellsPtr[cellIdx].TrackPos = TrackPos; CellsPtr[cellIdx].ValueLen = strlen(value) + 1; if (CellsPtr[cellIdx].ValueStr) CC_free(CellsPtr[cellIdx].ValueStr); CellsPtr[cellIdx].ValueStr = (char *)CC_malloc(CellsPtr[cellIdx].ValueLen); strcpy(CellsPtr[cellIdx].ValueStr, value); return 1; } u32 TrackPlayer_Data::GetValueStr(int cellIdx, char *value) { if (cellIdx < 0 || cellIdx >= ulNumberOfCells) return NULL; int NameIdx = CellsPtr[cellIdx].DataNameIdx; if (NameIdx == -1) return 0; if (InfosPtr[NameIdx].DataType != TRK_DATA_STR) return 0; strcpy(value, CellsPtr[cellIdx].ValueStr); return 1; } /**********************************************************************************/ /************* Track Player ************/ /**********************************************************************************/ BOOL TrackPlayer::VerifyTracks(u32 StreamIndex) { if (StreamIndex > 1024) return 0; if (StreamIndex >= ulNumberOfTracks) { TrackPlayer_Stream *NewS; NewS = (TrackPlayer_Stream*)CC_malloc(sizeof(TrackPlayer_Stream) * (StreamIndex+1)); memset(NewS,0,sizeof(TrackPlayer_Stream) * (StreamIndex+1)); if (TracksPtrs) { memcpy(NewS,TracksPtrs,sizeof(TrackPlayer_Stream) * (ulNumberOfTracks)); CC_free(TracksPtrs); } TracksPtrs = NewS; ulNumberOfTracks = StreamIndex + 1; } return 1; } void TrackPlayer::Set(u32 StreamIndex,u32 TimeLineIndex,MATRIX *ActualMat,u32 Validity) { if (!VerifyTracks(StreamIndex)) return; TracksPtrs[StreamIndex].Set(TimeLineIndex,ActualMat,Validity); } void TrackPlayer::DelStream(u32 StreamIndex) { if (StreamIndex > 1024) return; if (StreamIndex < ulNumberOfTracks) { CC_free(TracksPtrs[StreamIndex].pAnimation); for(int i = StreamIndex; iT.z = -100000.0f; // Hide it if (StreamIndex >= ulNumberOfTracks) return -1; return TracksPtrs[StreamIndex].Get(TimeLineIndex,ActualMat); } u32 TrackPlayer::Get(u32 StreamIndex,double TimeLineFloat,MATRIX *ActualMat) { ActualMat->T.z = -100000.0f; // Hide it if (StreamIndex >= ulNumberOfTracks) return -1; return TracksPtrs[StreamIndex].Get(TimeLineFloat,ActualMat); } int TrackPlayer::GetDataCell(u32 TrackIndex, u32 TimeLineIndex, char *DataName, TRK_DATA_TYPE type, BOOL create) { int foundedDataIndex; int currentDataIndex; int NameIdx = Datas.GetInfoIndex(DataName); if (NameIdx == -1) { if (create) NameIdx = Datas.AddInfoIndex(DataName, type); else return 0; } else if (Datas.InfosPtr[NameIdx].DataType != type) return 0; if ( Datas.CellsPtr == NULL) { foundedDataIndex = -1; } else { if (TrackIndex == -1) { foundedDataIndex = GetDescriptor(TimeLineIndex)->DataIndex; } else { if (!VerifyTracks(TrackIndex)) return -1; foundedDataIndex = TracksPtrs[TrackIndex].GetDataIndex(TimeLineIndex); } } currentDataIndex = foundedDataIndex; while (currentDataIndex != -1 && Datas.CellsPtr[currentDataIndex].DataNameIdx != NameIdx) currentDataIndex = Datas.CellsPtr[currentDataIndex].NextCell; if (!create) return currentDataIndex; if (currentDataIndex == -1) { currentDataIndex = Datas.AddCell(NameIdx, foundedDataIndex); } if (foundedDataIndex == -1) { if (TrackIndex == -1) { GetDescriptor(TimeLineIndex)->DataIndex = currentDataIndex; } else { if (!VerifyTracks(TrackIndex)) return -1; TracksPtrs[TrackIndex].SetDataIndex(TimeLineIndex, currentDataIndex); } } return currentDataIndex; } u32 TrackPlayer::SetDataInt(u32 TrackIndex,u32 TimeLineIndex, char *DataName, int value) { int cellIndex = GetDataCell(TrackIndex, TimeLineIndex, DataName, TRK_DATA_INT, true); if (cellIndex != -1) return Datas.SetValueInt(cellIndex, value, TrackIndex, TimeLineIndex); return 0; } u32 TrackPlayer::GetDataInt(u32 TrackIndex,u32 TimeLineIndex, char *DataName, int *value) { int cellIndex = GetDataCell(TrackIndex, TimeLineIndex, DataName, TRK_DATA_INT, false); if (cellIndex != -1) return Datas.GetValueInt(cellIndex, value); return 0; } u32 TrackPlayer::SetDataFloat(u32 TrackIndex,u32 TimeLineIndex, char *DataName, float value) { int cellIndex = GetDataCell(TrackIndex, TimeLineIndex, DataName, TRK_DATA_FLOAT, true); if (cellIndex != -1) return Datas.SetValueFloat(cellIndex, value, TrackIndex, TimeLineIndex); return 0; } u32 TrackPlayer::GetDataFloat(u32 TrackIndex,u32 TimeLineIndex, char *DataName, float *value) { int cellIndex = GetDataCell(TrackIndex, TimeLineIndex, DataName, TRK_DATA_FLOAT, false); if (cellIndex != -1) return Datas.GetValueFloat(cellIndex, value); return 0; } u32 TrackPlayer::SetDataStr(u32 TrackIndex,u32 TimeLineIndex, char *DataName, char * value) { int cellIndex = GetDataCell(TrackIndex, TimeLineIndex, DataName, TRK_DATA_STR, true); if (cellIndex != -1) return Datas.SetValueStr(cellIndex, value, TrackIndex, TimeLineIndex); return 0; } u32 TrackPlayer::GetDataStr(u32 TrackIndex,u32 TimeLineIndex, char *DataName, char * value) { int cellIndex = GetDataCell(TrackIndex, TimeLineIndex, DataName, TRK_DATA_STR, false); if (cellIndex != -1) return Datas.GetValueStr(cellIndex, value); return 0; } void TrackPlayer::SetSkinColor(u32 StreamIndex,u32 TimeLineIndex,u32 Color) { if (StreamIndex > 1024) return; if (StreamIndex >= ulNumberOfTracks) { TrackPlayer_Stream *NewS; NewS = (TrackPlayer_Stream*)CC_malloc(sizeof(TrackPlayer_Stream) * (StreamIndex+1)); memset(NewS,0,sizeof(TrackPlayer_Stream) * (StreamIndex+1)); if (TracksPtrs) { memcpy(NewS,TracksPtrs,sizeof(TrackPlayer_Stream) * (ulNumberOfTracks)); CC_free(TracksPtrs); } TracksPtrs = NewS; ulNumberOfTracks = StreamIndex + 1; } TracksPtrs[StreamIndex].SetSkinColor(TimeLineIndex,Color); } u32 TrackPlayer::GetSkinColor(u32 StreamIndex,u32 TimeLineIndex) { if (StreamIndex >= ulNumberOfTracks) return 0; return TracksPtrs[StreamIndex].GetSkinColor(TimeLineIndex); } u32 TrackPlayer::IsCutScene(u32 TimeLineIndex) { if (TimeLineIndex >= ulNumberOfDescriptors) return 0; return (DescriptorsPtrs[TimeLineIndex].Flags & 1); } u32 TrackPlayer::GetScale(u32 StreamIndex,Vector *Scale) { if (StreamIndex >= ulNumberOfTracks) return -1; if (TracksPtrs[StreamIndex].Scale.SqrNorm() == 0.0f) TracksPtrs[StreamIndex].Scale = Vector(1,1,1); *Scale = TracksPtrs[StreamIndex].Scale; return 0; } u32 TrackPlayer::SetScale(u32 StreamIndex,Vector *Scale) { if (StreamIndex >= ulNumberOfTracks) return -1; TracksPtrs[StreamIndex].Scale = *Scale; return 0; } TrackPlayer_Descriptors * TrackPlayer::GetDescriptor(u32 TimeLineIndex) { if (TimeLineIndex > 100000) TimeLineIndex = 100000; if (TimeLineIndex >= ulNumberOfDescriptors) { u32 ulNewNumberOfDescriptors; ulNewNumberOfDescriptors = (TimeLineIndex & ~255) + 256; if (DescriptorsPtrs == NULL) DescriptorsPtrs = (TrackPlayer_Descriptors*)CC_malloc(sizeof(TrackPlayer_Descriptors)*ulNewNumberOfDescriptors); else DescriptorsPtrs = (TrackPlayer_Descriptors*)CC_realloc(DescriptorsPtrs,sizeof(TrackPlayer_Descriptors)*ulNewNumberOfDescriptors); memset(DescriptorsPtrs+ulNumberOfDescriptors, 0 , sizeof(TrackPlayer_Descriptors)*(ulNewNumberOfDescriptors - ulNumberOfDescriptors)); for (int descIdx=ulNumberOfDescriptors; descIdxImageMarker == 0 || descPtr->ImageMarker == imgMarker) { //descPtr->ImageMarker = imgMarker; // ?? return index; } else { for (int counter = 1; counter <= MAX_DECALAGE; counter++) { if ((u32)counter < index && GetDescriptor(index-counter)->ImageMarker == imgMarker) return (index-counter); if (GetDescriptor(index+counter)->ImageMarker == imgMarker) return (index+counter); } return index; } } BOOL IsMatriceCompressedNull(MatrixCompressed *mc) { return ( mc->Trans.x == 0.0 && mc->Trans.y == 0.0) && ( mc->Rot.x == 0.0 && mc->Rot.y == 0.0 && mc->Rot.z == 0.0); } #define MAX_NB_BAD_TO_CLEAN 40 void TrackPlayer::CleanZone(int curTrak, int zBegin, int zEnd) { float localVal; int nbBad; int badIdx; int zIdx; TrackPlayer_Stream* trackStreamPtr = TracksPtrs + curTrak; if (trackStreamPtr->ulNumberOfMC <= zEnd) return; nbBad = zEnd - zBegin; for (badIdx=1, zIdx=zBegin+1; badIdxpAnimation[zIdx].IsValid = 0; // or 3 ... must be set, but value to define trackStreamPtr->pAnimation[zIdx].Trans.x = ((nbBad - badIdx)*trackStreamPtr->pAnimation[zBegin].Trans.x + badIdx *trackStreamPtr->pAnimation[zEnd].Trans.x)/nbBad; trackStreamPtr->pAnimation[zIdx].Trans.y = ((nbBad - badIdx)*trackStreamPtr->pAnimation[zBegin].Trans.y + badIdx *trackStreamPtr->pAnimation[zEnd].Trans.y)/nbBad; trackStreamPtr->pAnimation[zIdx].Trans.z = ((nbBad - badIdx)*trackStreamPtr->pAnimation[zBegin].Trans.z + badIdx *trackStreamPtr->pAnimation[zEnd].Trans.z)/nbBad; trackStreamPtr->pAnimation[zIdx].Rot.x = ((nbBad - badIdx)*trackStreamPtr->pAnimation[zBegin].Rot.x + badIdx *trackStreamPtr->pAnimation[zEnd].Rot.x)/nbBad; trackStreamPtr->pAnimation[zIdx].Rot.y = ((nbBad - badIdx)*trackStreamPtr->pAnimation[zBegin].Rot.y + badIdx *trackStreamPtr->pAnimation[zEnd].Rot.y)/nbBad; trackStreamPtr->pAnimation[zIdx].Rot.z = ((nbBad - badIdx)*trackStreamPtr->pAnimation[zBegin].Rot.z + badIdx *trackStreamPtr->pAnimation[zEnd].Rot.z)/nbBad; localVal = trackStreamPtr->pAnimation[zIdx].Rot.x*trackStreamPtr->pAnimation[zIdx].Rot.x + trackStreamPtr->pAnimation[zIdx].Rot.y*trackStreamPtr->pAnimation[zIdx].Rot.y + trackStreamPtr->pAnimation[zIdx].Rot.z*trackStreamPtr->pAnimation[zIdx].Rot.z; if (localVal < 1) { trackStreamPtr->pAnimation[zIdx].Rot.w = sqrt(1 - localVal); if (trackStreamPtr->pAnimation[zBegin].Rot.w < 0) trackStreamPtr->pAnimation[zIdx].Rot.w = -trackStreamPtr->pAnimation[zIdx].Rot.w; } GetDescriptor(zIdx)->CurrentFocal = ((nbBad - badIdx)*GetDescriptor(zBegin)->CurrentFocal + badIdx *GetDescriptor(zEnd)->CurrentFocal)/nbBad; } } void TrackPlayer::Clean(int maxBadToClean) { u32 trackIdx; u32 mcIdx; u32 mcIdxIn; u32 mcEnd; TrackPlayer_Stream* trackStreamPtr; if (maxBadToClean <= 0) maxBadToClean = MAX_NB_BAD_TO_CLEAN; for (trackIdx=0, trackStreamPtr = TracksPtrs; trackIdxulNumberOfMC) { mcEnd = trackStreamPtr->ulNumberOfMC - 1; for (mcIdx=1; mcIdxpAnimation[mcIdx])) { if (IsMatriceCompressedNull(&trackStreamPtr->pAnimation[mcIdx-1])) continue; for (mcIdxIn = mcIdx+1; !(GetDescriptor(mcIdxIn)->Flags & 1) && IsMatriceCompressedNull(&trackStreamPtr->pAnimation[mcIdxIn]) && (mcIdxIn-mcIdx) < MAX_NB_BAD_TO_CLEAN; mcIdxIn++); if (!(GetDescriptor(mcIdxIn)->Flags & 1) && (mcIdxIn-mcIdx) < maxBadToClean) { CleanZone(trackIdx, mcIdx-1, mcIdxIn); } mcIdx = mcIdxIn-1; } } } } } /******* Clean ŕ tester N Manquant ŕ recollé ********/