public void addTimeSample(int timeIn, int dataIdxIn)
        {
            CreatureTimeSample newTimeSample = new CreatureTimeSample(timeIn, timeIn, dataIdxIn);

            timeSamplesMap[timeIn] = newTimeSample;

            if (firstSet == false)
            {
                firstSet  = true;
                startTime = timeIn;
                endTime   = timeIn;
            }
            else
            {
                if (startTime > timeIn)
                {
                    startTime = timeIn;
                }

                if (endTime < timeIn)
                {
                    endTime = timeIn;
                }
            }
        }
        public void finalTimeSamples()
        {
            int        oldTime     = startTime;
            List <int> sorted_keys = new List <int>();

            foreach (var curData in timeSamplesMap)
            {
                sorted_keys.Add(curData.Key);
            }

            sorted_keys.Sort();

            foreach (var curTime in sorted_keys)
            {
                if (curTime != oldTime)
                {
                    for (int fillTime = oldTime + 1; fillTime < curTime; fillTime++)
                    {
                        CreatureTimeSample newTimeSample = new CreatureTimeSample(oldTime, curTime, -1);
                        timeSamplesMap[fillTime] = newTimeSample;
                    }

                    oldTime = curTime;
                }
            }
        }
        // Call this before a render to update the render data
        public void syncRenderData()
        {
            {
                // Points blending
                if (activeAnimationName == prevAnimationName)
                {
                    var cur_clip = data.animClipMap[activeAnimationName];
                    // no blending
                    var cur_clip_info            = cur_clip.sampleTime(getRunTime(activeAnimationName));
                    CreatureTimeSample low_data  = cur_clip.timeSamplesMap[cur_clip_info.firstSampleIdx];
                    CreatureTimeSample high_data = cur_clip.timeSamplesMap[cur_clip_info.secondSampleIdx];

                    float[] anim_low_points  = (float[])cur_clip.fileData[low_data.getAnimPointsOffset()];
                    float[] anim_high_points = (float[])cur_clip.fileData[high_data.getAnimPointsOffset()];

                    for (var i = 0; i < renders_base_size; i++)
                    {
                        for (var j = 0; j < 2; j++)
                        {
                            var low_val  = (float)(anim_low_points[i * 2 + j]);
                            var high_val = (float)(anim_high_points[i * 2 + j]);
                            render_points[i * 3 + j] = interpScalar(low_val, high_val, cur_clip_info.sampleFraction);
                        }

                        render_points[i * 3 + 2] = 0.0f;
                    }
                }
                else
                {
                    // blending

                    // Active Clip
                    var active_clip = data.animClipMap[activeAnimationName];

                    var active_clip_info = active_clip.sampleTime(getRunTime(activeAnimationName));
                    CreatureTimeSample active_low_data  = active_clip.timeSamplesMap[active_clip_info.firstSampleIdx];
                    CreatureTimeSample active_high_data = active_clip.timeSamplesMap[active_clip_info.secondSampleIdx];

                    float[] active_anim_low_points  = (float[])active_clip.fileData[active_low_data.getAnimPointsOffset()];
                    float[] active_anim_high_points = (float[])active_clip.fileData[active_high_data.getAnimPointsOffset()];

                    // Previous Clip
                    var prev_clip = data.animClipMap[prevAnimationName];

                    var prev_clip_info = prev_clip.sampleTime(getRunTime(prevAnimationName));
                    CreatureTimeSample prev_low_data  = prev_clip.timeSamplesMap[prev_clip_info.firstSampleIdx];
                    CreatureTimeSample prev_high_data = prev_clip.timeSamplesMap[prev_clip_info.secondSampleIdx];

                    float[] prev_anim_low_points  = (float[])prev_clip.fileData[prev_low_data.getAnimPointsOffset()];
                    float[] prev_anim_high_points = (float[])prev_clip.fileData[prev_high_data.getAnimPointsOffset()];

                    for (var i = 0; i < renders_base_size; i++)
                    {
                        for (var j = 0; j < 2; j++)
                        {
                            var active_low_val  = (float)(active_anim_low_points[i * 2 + j]);
                            var active_high_val = (float)(active_anim_high_points[i * 2 + j]);
                            var active_val      = interpScalar(active_low_val, active_high_val, active_clip_info.sampleFraction);

                            var prev_low_val  = (float)(prev_anim_low_points[i * 2 + j]);
                            var prev_high_val = (float)(prev_anim_high_points[i * 2 + j]);
                            var prev_val      = interpScalar(prev_low_val, prev_high_val, prev_clip_info.sampleFraction);

                            render_points[i * 3 + j] = interpScalar(prev_val, active_val, animBlendFactor);
                        }

                        render_points[i * 3 + 2] = 0.0f;
                    }
                }

                // Colors
                {
                    var cur_clip = data.animClipMap[activeAnimationName];
                    // no blending
                    var cur_clip_info            = cur_clip.sampleTime(getRunTime(activeAnimationName));
                    CreatureTimeSample low_data  = cur_clip.timeSamplesMap[cur_clip_info.firstSampleIdx];
                    CreatureTimeSample high_data = cur_clip.timeSamplesMap[cur_clip_info.secondSampleIdx];

                    object[] anim_low_colors  = (object[])cur_clip.fileData[low_data.getAnimColorsOffset()];
                    object[] anim_high_colors = (object[])cur_clip.fileData[high_data.getAnimColorsOffset()];

                    if ((anim_low_colors.Length == getRenderColorsLength()) &&
                        (anim_high_colors.Length == getRenderColorsLength()))
                    {
                        for (var i = 0; i < getRenderColorsLength(); i++)
                        {
                            float low_val  = (float)(int)(anim_low_colors[i]);
                            float high_val = (float)(int)(anim_high_colors[i]);

                            render_colors[i] = (byte)interpScalar(low_val, high_val, cur_clip_info.sampleFraction);
                        }
                    }
                }

                // UVs
                {
                    var cur_clip                = data.animClipMap[activeAnimationName];
                    var cur_clip_info           = cur_clip.sampleTime(getRunTime(activeAnimationName));
                    CreatureTimeSample low_data = cur_clip.timeSamplesMap[cur_clip_info.firstSampleIdx];
                    object[]           anim_uvs = (object[])cur_clip.fileData[low_data.getAnimUvsOffset()];

                    if (anim_uvs.Length == getRenderUVsLength())
                    {
                        for (var i = 0; i < getRenderUVsLength(); i++)
                        {
                            render_uvs[i] = (float)(anim_uvs[i]);
                        }
                    }
                }
            }
        }