comfy chair

Members
  • Content count

    80
  • Joined

  • Last visited

Community Reputation

847 Good

About comfy chair

  • Rank
    Member
  1. Optimize map for high-level pathfinding

            /// <summary>         /// the coordinate map that tells what region(color!) a subtile belongs to         /// </summary>         public ushort[][] AllSubtiles; This array uses the most memory. It covers the whole map and can be about 750 * 750 in size. That's about 1 MB. Then there is some additional data also, and each faction has 3-6 of these region maps... I am thinking now about subdividing the map into square sections, about half a screen wide. The flood fill would stop at the border between sections. Then, the region maps that belong to factions could disregard most of the sections, and just leave them empty. When I create the graph, I could link up with the underlying, full region map whenever there is a hole/empty section.  
  2. In my game, I create high-level maps at runtime that I use for answering distance and accessibility queries. They are not used for pathfinding. I call them "region maps". The region maps cover the whole playfield.   The region maps are made by flood filling the terrain map grid with a small cutoff limit so the map consists of many small regions. Connections between neighbouring regions are stored in a graph and used for lookup.   There is a general region map for the base terrain that can be used by all agents. In addition, each faction has a few region maps which are made from the terrain data with threat data overlaid.   In total, this means that each faction (a single independent agent is also a faction) has a memory footprint of 7 MB.   How can I make the factions' region maps smaller. Most of the information in them is similar to the underlying terrain anyway. It is only the nearby threats that the factions know about which make their region maps different.
  3. Animation takes up too much memory

    With the changes to the struct (uint instead of long, vectors instead of Matrix) I got down to 28 MB. That's good enough for now I think.    Thanks for the help.
  4. Animation takes up too much memory

    Yes, I should of course do that when possible. The build time is long enough already.
  5. Animation takes up too much memory

    Yes, I already made sure that I use the same interpolation method in preprocessing and at runtime. SLERP was necessary to use because LERP sometimes gave crazy errors.   I asked the animator if we ever used scaling, the answer was "don't know". But now I think it will probably be needed at some point, if it isn't being used already.
  6. Animation takes up too much memory

    So I need to choose if I want to support scaling, or not. Actually, I don't think I will ever need it.
  7. Animation takes up too much memory

      I eliminated these frames also and I am now down to 44 MB. Perhaps I can compress it a bit further by increasing the comparison threshold without hurting the playback quality.
  8. Animation takes up too much memory

    Alright then. But L. Spiro used the same term... I am trying to replace this, inside BoneKeyFrame: /// <summary> /// The transform for the keyframe. /// </summary> public readonly Matrix Transform; with a custom class/struct. It should contain an optional translation vector, optional scale vector (when different from 1) and a rotation quaternion.  How can I design it so it becomes as compact as possible...  The point is to reduce the size of the BoneKeyFrame array.  
  9. Animation takes up too much memory

    I found some useful information here: http://www.digitalrune.com/Support/Blog/tabid/719/EntryId/131/Character-Animation-Compression.aspx
  10. Animation takes up too much memory

    I have eliminated the redundant key frames (frames that have the same transform matrix as the preceding one) and have now reduced the size to 84 mb.   I am wondering if there are more low-hanging fruits that can bring it down further....       Yes, what I have is 4*4 matrices, likely quaternions. If I decompose them into vectors, I would need to change the runtime animation code to use vectors instead... I am not sure if I want to do that at this point...   This is what the struct looks like: /// <summary> /// Represents a keyframe in an animation track. /// </summary> public struct BoneKeyframe { /// <summary> /// Creats a new BoneKeyframe. /// </summary> /// <param name="transform">The transform for the keyframe.</param> /// <param name="time">The time in ticks for the keyframe.</param> public BoneKeyframe(Matrix transform, long time) { this.Transform = transform; this.Time = time; } /// <summary> /// The transform for the keyframe. /// </summary> public readonly Matrix Transform; /// <summary> /// The time for the keyframe. /// </summary> public readonly long Time; } Most of the keyframes are just hanging around in memory. How could I compress it until the transform is needed..?         I have already eliminated the frames that are equal. But is the situation really that common in animation that a handmade animation sequence is similar to a SLERP? How would I detect this case. How do I select the endpoints in the animation sequence to compare, when doing the loop I posted above?  
  11. Animation takes up too much memory

    I reduced the sampling rate to 30 frames per second from 60. The memory used went down from 206 mb to 108 mb, while animation quality looks the same. I will try to reduce it a bit further, then I will probably try removing the redundant key frames as was suggested.  
  12. Animation takes up too much memory

      If your code (properly) interpolates animation data at runtime, do you need to do anything other than just load the data? I.e., game assets in general should be "ready to load" at runtime.     The code I posted only runs at build time. It creates the key frame arrays that the game interpolates between during runtime. My problem was that these arrays were so huge.
  13. Animation takes up too much memory

    else // Else the adjacent frames have identical transforms and we can use // the current frames transform for the current keyframe. { keyframe = new AnimationKeyframe(new TimeSpan(time), channel[currentFrame].Transform); } Here, I might as well not store any keyframe at all. I wonder how much data could be saved that way.
  14. Animation takes up too much memory

    Yes, but the code i posted above suggests that everything that gets exported is overridden in a resampling loop.
  15. Animation takes up too much memory

    I am looking at the code that pre-compiles the animation data coming from the exporter. It looks like it is storing 60 keys per second, regardless of what it receives from the exporter. Here is the code:   // Step through time until the time passes the animation duration while (time <= animationDuration) { AnimationKeyframe keyframe; // Clamp the time to the duration of the animation and make this // keyframe equal to the last animation frame. if (time >= animationDuration) { time = animationDuration; keyframe = new AnimationKeyframe(new TimeSpan(time), channel[channel.Count - 1].Transform); } else { // If the channel only has one keyframe, set the transform for the current time // to that keyframes transform if (channel.Count == 1 || time < channel[0].Time.Ticks) { keyframe = new AnimationKeyframe(new TimeSpan(time), channel[0].Transform); } // If the current track duration is less than the animation duration, // use the last transform in the track once the time surpasses the duration else if (channel[channel.Count - 1].Time.Ticks <= time) { keyframe = new AnimationKeyframe(new TimeSpan(time), channel[channel.Count - 1].Transform); } else // proceed as normal { // Go to the next frame that is less than the current time while (channel[currentFrame + 1].Time.Ticks < time) { currentFrame++; } // Numerator of the interpolation factor double interpNumerator = (double)(time - channel[currentFrame].Time.Ticks); // Denominator of the interpolation factor double interpDenom = (double)(channel[currentFrame + 1].Time.Ticks - channel[currentFrame].Time.Ticks); // The interpolation factor, or amount to interpolate between the current // and next frame double interpAmount = interpNumerator / interpDenom; // If the frames are roughly 60 frames per second apart, use linear interpolation if (channel[currentFrame + 1].Time.Ticks - channel[currentFrame].Time.Ticks <= ContentUtil.TICKS_PER_60FPS * 1.05) { // context.Logger.LogImportantMessage("Lerp between frames {0} and {1}, interpAmount: {2}", currentFrame.ToString(), (currentFrame + 1).ToString(), interpAmount.ToString()); // input.Duration.Ticks.ToString(), ((long)(durationFactor * input.Duration.Ticks)).ToString()); keyframe = new AnimationKeyframe(new TimeSpan(time), Matrix.Lerp( channel[currentFrame].Transform, channel[currentFrame + 1].Transform, (float)interpAmount)); } else // else if the transforms between the current frame and the next aren't identical // decompose the matrix and interpolate the rotation separately if (channel[currentFrame].Transform != channel[currentFrame + 1].Transform) { // context.Logger.LogImportantMessage("Slerp between frames {0} and {1}, interpAmount: {2}", currentFrame.ToString(), (currentFrame + 1).ToString(), interpAmount.ToString()); // input.Duration.Ticks.ToString(), ((long)(durationFactor * input.Duration.Ticks)).ToString()); keyframe = new AnimationKeyframe(new TimeSpan(time), ContentUtil.SlerpMatrix( channel[currentFrame].Transform, channel[currentFrame + 1].Transform, (float)interpAmount)); } else // Else the adjacent frames have identical transforms and we can use // the current frames transform for the current keyframe. { keyframe = new AnimationKeyframe(new TimeSpan(time), channel[currentFrame].Transform); } } } // Add the interpolated keyframe to the new channel. outChannel.Add(keyframe); // Step the time forward by 1/60th of a second time += ContentUtil.TICKS_PER_60FPS; } But at runtime, interpolation is performed again. So as some of you mentioned, I may be able to reduce this data and still get smooth playback.