views:

572

answers:

2

Hi Everyone,

I have a few 3d rectangles on my screen that I want to pivot around the Y axis.

I want to press down with the mouse, and rotate the 3d object to a max rotation, but when the user moves their mouse, I want to slightly rotate it so that it looks like a see-saw (rotating from a range of -13 to 13 degrees on the Y-Axis).

At the moment, I can do this, but my frame rate really really suffers when I move the mouse quickly. So for example, when I click the left side of the rectangle, I generate a storyboard and animation objects, then rotate the 3d object to -13 degrees. Then when I slightly move the mouse to the right, I want to rotate it to -12.5, and so on...

Again, I can do all of this, its just that the performance suffers greatly! It goes down to 5-FPS in some cases... which is not acceptable.

My question is am I doing this the best way? How else could you animate a rotation base on the users position on the screen?

Thanks for any help you can provide! Mark

A: 

MSDN presents some tips on what impacts in WPF 3D performance. If you didn't stumble on it yet, check the items on "Performance Impact: High" list.

Edit: In march 2009, Josh Smith published an article on CodeProject that involves rotating 3D objetcs. Maybe you want to check his solution.

Hilton Perantunes
thanks for the help, I did actually see those articles! I think what Im doing is really the only way, I just need to be smart about my logic behind the scenes
Mark
+2  A: 

I assume you are doing the following:

  • Using a separate Model3D for the object you are rotating & including it in a Model3DGroup
  • Giving it a RotateTransform3D containing an AxisAngleRotation3D
  • Animating the AxisAngle3D's Axis property in the Storyboard

If my assumptions are correct I think we can conclude the problem is efficiency in rendering, since the CPU required to update a single Axis value, recompute the Transform, and update MILCore is negligible.

I can think of several ways that could improve the rendering performance:

  1. If your Model3D being rotated is a GeometryModel3D backed by a MeshGeometry3D, do as much as you can to simplify the mesh and the materials used. It can also help to substitute a different mesh for closeups.

  2. If the Model3D being rotated is a GeometryModel3D that uses VisualBrush brushes, during animation temporarily replace the VisualBrush with an ImageBrush containing a BitmapImage that is a snapshot of the Visual underlying the VisualBrush as of the instant the animation starts. When the animation ends, put backthe VisualBrush. The user probably won't notice that the contents of the object freeze temporarily when it rotates. (Note that this same technique can be used if your Visual3D is a Viewport2DVisual3D.)

  3. If the Model3D being rotated is combined into a Model3DGroup with other objects but lies entirely in front of or behind the other groups, separate the model into its own separate Viewport3DVisual, appropriately layered to get the effect you want.

  4. Simplify lighting or Material types

  5. Monitor the actual frame rate and if it is going too low when using the storyboard, rotate the object immediately to where the mouse indicates without using an animation.

Ray Burns
Great advice Ray:1: I really require large amounts of detail sadly2: I require the materials to create a lighting effect when they rotate so I really cant replace them3: They are layered seperatly4: No can do, like i said in #1, I really need large amounts of detail5: Not a bad idea! That I can do, what is the best way to get the frame rate?Great tips though!
Mark
I would get the frame rate by subscribing to the static CompositionTarget.Rendering event and measuring the time using DateTime.Now and subtracting. My first heuristic might be that if if more than three frames in a row take >100ms to render during the time the animation is running, disable the animations for the next 30 seconds. Note you want to do this from static methods or a singleton instance so as not to subscribe multiple times to the Rendering event and prevnting things from being GCed.
Ray Burns