private static int EncodeEntry(int index, AnimDataFormat format, KeyframeCollection kf, VoidPtr addr) { int numFrames = kf.FrameLimit; KeyframeEntry frame, root = kf._keyArrays[index]._keyRoot; bfloat * pVal = (bfloat *)addr; float val, frameScale = numFrames <= 1 ? 1 : 1.0f / (numFrames - 1); float min, max, stride, step; int span, i; int keyCount = kf._keyArrays[index]._keyCount; if (format == AnimDataFormat.L4) { //Use all frames, just in case not all frames are key. for (i = 0; i < numFrames; i++) { *pVal++ = kf[i, index]; } return(numFrames * 4); } if (format == AnimDataFormat.I12) { I12Header *header = (I12Header *)addr; * header = new I12Header(keyCount, frameScale); I12Entry *entry = header->Data; for (frame = root._next; frame._index != -1; frame = frame._next) { *entry++ = new I12Entry(frame._index, frame._value, frame._tangent); } return(keyCount * 12 + 8); } //Get floor/ceil/stride min = float.MaxValue; max = float.MinValue; for (frame = root._next; frame != root; frame = frame._next) { val = frame._value; if (val > max) { max = val; } if (val < min) { min = val; } } stride = max - min; if (format == AnimDataFormat.L1) { //Find best span span = EvalSpan(255, 32, min, stride, root, true); step = stride / span; L1Header *header = (L1Header *)addr; * header = new L1Header(step, min); byte *dPtr = header->Data; for (i = 0; i < numFrames; i++) { *dPtr++ = (byte)((kf[i, index] - min) / step + 0.5f); } //Fill remaining bytes while ((i++ & 3) != 0) { *dPtr++ = 0; } return((8 + numFrames).Align(4)); } if (format == AnimDataFormat.I4) { //Find best span span = EvalSpan(4095, 32, min, stride, root, false); step = stride / span; I4Header *header = (I4Header *)addr; * header = new I4Header(keyCount, frameScale, step, min); I4Entry *entry = header->Data; for (frame = root._next; frame._index != -1; frame = frame._next) { val = (frame._value - min) / step; val += val < 0 ? -0.5f : 0.5f; *entry++ = new I4Entry(frame._index, (int)val, frame._tangent); } return(keyCount * 4 + 16); } if (format == AnimDataFormat.I6) { //Find best span span = EvalSpan(65535, 32, min, stride, root, false); step = stride / span; I6Header *header = (I6Header *)addr; * header = new I6Header(keyCount, frameScale, step, min); I6Entry *entry = header->Data; for (frame = root._next; frame._index != -1; frame = frame._next) { val = (frame._value - min) / step; val += val < 0 ? -0.5f : 0.5f; *entry++ = new I6Entry(frame._index, (int)val, frame._tangent); } //Fill remaining bytes if ((keyCount & 1) != 0) { entry->_data = 0; } return((keyCount * 6 + 16).Align(4)); } return(0); }
private static void DecodeFrames(KeyframeCollection kf, void *dataAddr, AnimDataFormat format, params int[] arrays) { int fCount; float vStep, vBase; switch (format) { case AnimDataFormat.I4: { I4Header *header = (I4Header *)dataAddr; fCount = header->_entries; vStep = header->_step; vBase = header->_base; foreach (int x in arrays) { I4Entry *entry = header->Data; for (int i = 0; i < fCount; i++, entry++) { kf.SetFrameValue(x, entry->FrameIndex, vBase + entry->Step * vStep, true)._tangent = entry->Tangent; } } break; } case AnimDataFormat.I6: { I6Header *header = (I6Header *)dataAddr; fCount = header->_numFrames; vStep = header->_step; vBase = header->_base; foreach (int x in arrays) { I6Entry *entry = header->Data; for (int i = 0; i < fCount; i++, entry++) { kf.SetFrameValue(x, entry->FrameIndex, vBase + entry->_step * vStep, true)._tangent = entry->Tangent; } } break; } case AnimDataFormat.I12: { I12Header *header = (I12Header *)dataAddr; fCount = header->_numFrames; foreach (int x in arrays) { I12Entry *entry = header->Data; for (int i = 0; i < fCount; i++, entry++) { kf.SetFrameValue(x, (int)entry->_index, entry->_value, true)._tangent = entry->_tangent; } } break; } case AnimDataFormat.L1: { L1Header *header = (L1Header *)dataAddr; vStep = header->_step; vBase = header->_base; foreach (int x in arrays) { byte *sPtr = header->Data; for (int i = 0; i < kf.FrameLimit; i++) { kf.SetFrameValue(x, i, vBase + *sPtr++ *vStep, true).GenerateTangent(); } } break; } case AnimDataFormat.L2: { L1Header *header = (L1Header *)dataAddr; vStep = header->_step; vBase = header->_base; foreach (int x in arrays) { bushort *sPtr = (bushort *)header->Data; for (int i = 0; i < kf.FrameLimit; i++) { kf.SetFrameValue(x, i, vBase + *sPtr++ *vStep, true).GenerateTangent(); } } break; } case AnimDataFormat.L4: { foreach (int x in arrays) { bfloat *sPtr = (bfloat *)dataAddr; for (int i = 0; i < kf.FrameLimit; i++) { kf.SetFrameValue(x, i, *sPtr++, true).GenerateTangent(); } } break; } } }
private static void DecodeCHR0Frames(KeyframeCollection kf, void *dataAddr, AnimDataFormat format, KeyFrameMode mode) { int fCount; float vStep, vBase; switch (format) { case AnimDataFormat.I4: { I4Header *header = (I4Header *)dataAddr; fCount = header->_entries; vStep = header->_step; vBase = header->_base; I4Entry *entry = header->Data; for (int i = 0; i < fCount; i++, entry++) { kf.SetFrameValue(mode, entry->FrameIndex, vBase + (entry->Step * vStep))._tangent = entry->Tangent; } break; } case AnimDataFormat.I6: { I6Header *header = (I6Header *)dataAddr; fCount = header->_numFrames; vStep = header->_step; vBase = header->_base; I6Entry *entry = header->Data; for (int i = 0; i < fCount; i++, entry++) { kf.SetFrameValue(mode, entry->FrameIndex, vBase + (entry->_step * vStep))._tangent = entry->Tangent; } break; } case AnimDataFormat.I12: { I12Header *header = (I12Header *)dataAddr; fCount = header->_numFrames; I12Entry *entry = header->Data; for (int i = 0; i < fCount; i++, entry++) { kf.SetFrameValue(mode, (int)entry->_index, entry->_value)._tangent = entry->_tangent; } break; } case AnimDataFormat.L1: { L1Header *header = (L1Header *)dataAddr; vStep = header->_step; vBase = header->_base; byte *sPtr = header->Data; for (int i = 0; i < kf.FrameCount; i++) { kf[mode, i] = vBase + (*sPtr++ *vStep); } KeyframeEntry root = kf._keyRoots[(int)mode & 0xF]; for (KeyframeEntry entry = root._next; entry != root; entry = entry._next) { entry.GenerateTangent(); } break; } case AnimDataFormat.L2: { L1Header *header = (L1Header *)dataAddr; vStep = header->_step; vBase = header->_base; bushort *sPtr = (bushort *)header->Data; for (int i = 0; i < kf.FrameCount; i++) { kf[mode, i] = vBase + (*sPtr++ *vStep); } KeyframeEntry root = kf._keyRoots[(int)mode & 0xF]; for (KeyframeEntry entry = root._next; entry != root; entry = entry._next) { entry.GenerateTangent(); } break; } case AnimDataFormat.L4: { bfloat *sPtr = (bfloat *)dataAddr; for (int i = 0; i < kf.FrameCount; i++) { kf[mode, i] = *sPtr++; } KeyframeEntry root = kf._keyRoots[(int)mode & 0xF]; for (KeyframeEntry entry = root._next; entry != root; entry = entry._next) { entry.GenerateTangent(); } break; } } }