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 int EncodeEntry(int index, AnimDataFormat format, KeyframeCollection kf, VoidPtr addr) { int numFrames = kf._frameCount; KeyframeEntry frame, root = kf._keyRoots[index]; 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._keyCounts[index]; KeyFrameMode mode = KeyFrameMode.ScaleX + index; if (format == AnimDataFormat.L4) { //Use all frames, just in case not all frames are key. for (i = 0; i < numFrames; i++) *pVal++ = kf[mode, i]; 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, kf._linearRot); 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[mode, i] - 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, 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, 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; }