2009-11-16 2 views
1

У меня есть несколько 3d-прямоугольников на моем экране, которые я хочу поворачивать вокруг оси Y.WPF 3D анимации вращения

Я хочу надавить на мышь и повернуть 3D-объект на максимальное вращение, но когда пользователь перемещает мышь, я хочу слегка повернуть ее так, чтобы она выглядела как смотровая пила (вращающаяся от диапазон от -13 до 13 градусов по оси Y).

На данный момент я могу это сделать, но скорость передачи кадров действительно сильно страдает, когда я быстро перемещаю мышь. Например, когда я нажимаю левую сторону прямоугольника, я генерирую объекты раскадровки и анимации, а затем поворачиваю 3D-объект на -13 градусов. Затем, когда я слегка перемещаю мышь вправо, я хочу повернуть ее на -12.5 и так далее ...

Опять же, я могу сделать все это, просто так, что производительность сильно страдает! В некоторых случаях он снижается до 5-FPS ... что неприемлемо.

Мой вопрос: я делаю это наилучшим образом? Как еще вы могли бы анимировать базу вращения в позиции пользователей на экране?

Спасибо за любую помощь, которую вы можете предоставить! Mark

+0

Вы вращаете объект или камеру вокруг центральной точки объекта? –

+0

объект, я не могу переместить камеру, иначе это повлияет на другие 3D-объекты тоже – Mark

ответ

0

MSDN представляет some tips о том, что влияет на производительность WPF 3D. Если вы еще не наткнулись на это, проверьте элементы в списке «Performance Impact: High».

Редактировать: В марте 2009 года Джош Смит опубликовал an article в CodeProject, который включает в себя вращающиеся 3D-объекты. Возможно, вы хотите проверить его решение.

+0

спасибо за помощь, я действительно видел эти статьи! Я думаю, что то, что я делаю, действительно единственный способ, мне просто нужно быть умным из-за моей логики за кулисами. – Mark

2

Я предполагаю, что вы делаете следующее:

  • Использование отдельного Model3D для объекта вы вращаете & включая его в Model3DGroup
  • придав ему RotateTransform3D, содержащий AxisAngleRotation3D
  • оживляющий AxisAngle3D-х Осевое имущество в раскадровке

Если мои предположения верны, я думаю, В то время как CPU требовалось обновить одно значение Axis, перекомпонуйте Transform и обновление MILCore незначительно.

Я могу придумать несколько способов, которые могут улучшить производительность рендеринга:

  1. Если Model3D вращают является GeometryModel3D подкреплена MeshGeometry3D, сделать столько, сколько вы можете упростить сетку и материалы используемый. Он также может помочь заменить другую сетку для крупным планом.

  2. Если Model3D поворота является GeometryModel3D, который использует кисть визуала, в ходе анимации временно заменить VisualBrush с ImageBrush, содержащей BitmapImage, который представляет собой снимок Визуальных лежащий в основе VisualBrush по состоянию на момент анимации начинается. Когда анимация заканчивается, верните VisualBrush. Пользователь, вероятно, не заметит, что содержимое объекта временно замораживается при вращении. (Обратите внимание, что этот же метод можно использовать, если ваш Visual3D является Viewport2DVisual3D.)

  3. Если вращающийся Model3D объединен в Model3DGroup с другими объектами, но полностью лежит перед или за другими группами, отделите модель на свой отдельный Viewport3DVisual, соответствующий слой, чтобы получить необходимый эффект.

  4. Simplify освещение или материалы типа

  5. Контролировать фактическую частоту кадров, и если она будет слишком низкой при использовании раскадровки, повернуть объект немедленно, где мышь указует без использования анимации.

+0

Отличный совет. Рэй: . 1: Мне действительно нужно большое количество деталей. 2: Мне нужны материалы для создания освещения эффект, когда они вращаются, поэтому я действительно не могу их заменить 3: Они слоистые seperatly 4: Нет, может, как я сказал в # 1, мне действительно нужно большое количество деталей 5: Неплохая идея! Что я могу сделать, каков наилучший способ получить частоту кадров? Отличные советы! – Mark

+0

Я получил бы частоту кадров, подписавшись на статическое событие CompositionTarget.Rendering и измеряя время с помощью DateTime.Now и вычитая. Моя первая эвристика может заключаться в том, что если если более трех кадров в строке занимает> 100 мс для рендеринга за время анимации, отключите анимацию в течение следующих 30 секунд. Обратите внимание, что вы хотите сделать это с помощью статических методов или экземпляра singleton, чтобы не подписываться несколько раз на событие Rendering и превзойти вещи из GCed. –

Смежные вопросы