Animation is performed only on the GPU, entities are not truly moved, vertices and bounding box don't change, collision detection doesn't work and so on. To edit entities position you can apply a transformation, but the computation is heavier and the animation slower. You can see the difference between these approaches in the Assemble sample.
The steps to animate a group of entities are the following, you can see the code implementation in MachineSimulator or PistonAnimation samples:
- Create groups of moving objects (using Block class and adding entities to the Block.Entities collection)
- Add blocks created at point 1) to the Design.Blocks collection
- Subclass the BlockReference class for each moving group of objects
- Override the BlockReference.Animate() method of the class at point 3) and add the code to compute the data for entities transformation at that specific time frame. The data should be calculated so that the entity is not moved when the frame number is zero.
- Override the BlockReference.MoveTo() method of the class at point 3) and add the code to move the objects on the GPU
- Override the BlockReference.IsInFrustum() method of the class at point 3) and return true without calling the base to avoid undesired clipping. It might be necessary to override also the bounding box scene extents
- Add the block references created at point 3) to the Design.Entities collection
- Call StartAnimation() providing the time interval between each frame
- Call StopAnimation() to stop the animation
Timer
The timer used to perform animation is a System.Threading.Timer since the System.Forms.Timer doesn't fire when the UI is busy. This means that code in Animate() is executed in a background thread while the MoveTo() is executed on the main thread.
During an animation, if you need to edit the entities or blocks collections or if you notice some flickering, you can marshal the Animate() call on the main thread.
class MyDesign : Design
{
protected override void OnAnimationTimerTick(object stateInfo)
{
BeginInvoke(new Action(() => base.OnAnimationTimerTick(stateInfo)));
}
}
Update for version 2020 and newer
Because of new optimizations on the scene graph, the MoveTo method is called only while the animation is running, when it's stopped all the entities are drawn in their real position. To continue drawing entities with the custom transformation you can set Design.AnimationStep to zero instead of stopping the animation.
Comments
This is a quite amazing feature. Thanks!
Please sign in to leave a comment.