ユーザーがマウス/指を球の上に動かしたときに、3D 球を回転させようとしています。
問題なく回転させることができますが、Surface SDK の Affine2DInertiaProcessor を使用して球体に慣性を追加しようとすると、球体をすばやくフリックするとジャンプの問題が発生し、その理由がわかりません...
ここに私の初期化コードがあります:
private void InitializeManipulationProcessor()
{
manipulationProcessor = new Affine2DManipulationProcessor(
Affine2DManipulations.Rotate |
Affine2DManipulations.TranslateX |
Affine2DManipulations.TranslateY,
_eventSource);
inertiaProcessor = new Affine2DInertiaProcessor();
inertiaProcessor.Affine2DInertiaDelta += Inertia_OnManipulationDelta;
inertiaProcessor.Affine2DInertiaCompleted += InertiaProcessor_Affine2DInertiaCompleted;
manipulationProcessor.Affine2DManipulationStarted += OnManipulationStarted;
manipulationProcessor.Affine2DManipulationDelta += Manipulation_OnManipulationDelta;
manipulationProcessor.Affine2DManipulationCompleted += OnManipulationCompleted;
}
ユーザーが指を動かしたときに、球を回転させるコードは次のとおりです。
private void Manipulation_OnManipulationDelta(object sender, Affine2DOperationDeltaEventArgs e)
{
Point currentPosition = e.ManipulationOrigin;
// avoid any zero axis conditions
if (currentPosition == _previousPosition2D)
return;
Track(currentPosition);
_previousPosition2D = currentPosition;
}
これは、ユーザーが指の動きを止めると、慣性を開始します。
private void OnManipulationCompleted(object sender, Affine2DOperationCompletedEventArgs e)
{
inertiaProcessor.InitialOrigin = e.ManipulationOrigin;
inertiaProcessor.InitialVelocity = e.Velocity;
inertiaProcessor.DesiredDeceleration = 0.0001;
inertiaProcessor.Begin();
}
回転の魔法は、以下のTrackメソッドで発生します。
private void Track(Point currentPosition)
{
Vector3D currentPosition3D = ProjectToTrackball(currentPosition);
Vector3D axis = Vector3D.CrossProduct(_previousPosition3D, currentPosition3D);
double angle = Vector3D.AngleBetween(_previousPosition3D, currentPosition3D);
// quaterion will throw if this happens - sometimes we can get 3D positions that
// are very similar, so we avoid the throw by doing this check and just ignoring
// the event
if (axis.Length == 0)
return;
Quaternion delta = new Quaternion(axis, -angle);
// Get the current orientantion from the RotateTransform3D
Quaternion q = new Quaternion(_rotation.Axis, _rotation.Angle);
// Compose the delta with the previous orientation
q *= delta;
// Write the new orientation back to the Rotation3D
_rotation.Axis = q.Axis;
_rotation.Angle = q.Angle;
_previousPosition3D = currentPosition3D;
}
_rotation変数は、3D メッシュのRotateTransform3Dに使用されるAxisAngleRotation3Dクラスです。
これが特殊なケースであることはわかっていますが、これは計算上の問題であると感じており、これをデバッグする方法が本当にわかりません。
もう 1 つ、非常に興味深い点として、地球儀をゆっくりとフリックすると、ジャンプすることはなく、非常にスムーズです。したがって、それは大規模な計算、または単なるバグと関係があるに違いありません...
あなたが 3D 回転が得意で、あなたが助けてくれると本当に信じているなら、このプロジェクトを ZIP にパッケージ化して、より良いフォーマットが必要な場合はお送りします。
あなたが与えることができるどんな助けにも感謝します、私は本当に助けに感謝します!
マーク