void XICamera.Update(GameTime game_time) { if (mListener_WorldRegenerated.GetMaxOne() != null) { InitFromWorld(); } XTouch.MultiDragData multi_drag_msg = mListener_MultiDrag.GetMaxOne(); if (multi_drag_msg != null) { if (multi_drag_msg.mFrameCount == 0) { mMultiDragPrev = multi_drag_msg; } // figure out zoom. damp so that human powered drag zoom is not jittery. // it's not that there is anything wrong with the measurement or the calculation, it's // that people don't seem to keep their fingers at constant separation when they mean to. const float k_zoom_damping = 0.8f; float ideal_zoom_ratio = (float)(mMultiDragPrev.mMaxScreenSeparation / multi_drag_msg.mMaxScreenSeparation); float zoom_ratio = (mDampedMaxScreenSeparation > -1f) ? (k_zoom_damping * mDampedMaxScreenSeparation + (1f - k_zoom_damping) * ideal_zoom_ratio) : ideal_zoom_ratio; mDampedMaxScreenSeparation = zoom_ratio; // place new world view so that the zoom point in world space is at the same place on the screen. Vector2 size_0 = mWorldView.GetSize(); Vector2 size_1 = zoom_ratio * size_0; Vector2 avg_world_pos = CalcWorldPos(multi_drag_msg.mAvgScreenPos); float pos_x_fraction = multi_drag_msg.mAvgScreenPos.X / mScreenDim.x; float pos_y_fraction = multi_drag_msg.mAvgScreenPos.Y / mScreenDim.y; float dx_world = pos_x_fraction * size_1.X; float dy_world = pos_y_fraction * size_1.Y; Vector2 p0 = new Vector2(avg_world_pos.X - dx_world, avg_world_pos.Y - dy_world); Vector2 p1 = p0 + size_1; xAABB2 world_view = new xAABB2(p0, p1); // figure out translation // this calculation assumes fullscreen, viewport not taken into consideration Vector2 pixel_move = multi_drag_msg.mAvgScreenPos - mMultiDragPrev.mAvgScreenPos; Vector2 screen_fraction = new Vector2(pixel_move.X / mScreenDim.x, pixel_move.Y / mScreenDim.y); Vector2 world_view_size = world_view.GetSize(); Vector2 world_move = new Vector2(screen_fraction.X * world_view_size.X, screen_fraction.Y * world_view_size.Y); world_view.Translate(-world_move); mMultiDragPrev = multi_drag_msg; // clamp and calc projection matrix mWorldView = ClampWorldView(world_view); CalcProjectionMatrix(); } }
private void InitFromWorld() { mWorldSize = XWorld.Instance().GetMapSize(); // initial view of map xAABB2 world_view = new xAABB2(new Vector2(0, 0), new Vector2(mWorldSize.x, mWorldSize.y)); mWorldView = ClampWorldView(world_view); // view matrix is unchanging Vector3 pos = new Vector3(0, 0, 1f); Vector3 target = pos - 2f * Vector3.UnitZ; mViewMatrix = Matrix.CreateLookAt(pos, target, Vector3.UnitY); CalcProjectionMatrix(); mMultiDragPrev = new XTouch.MultiDragData(Vector2.Zero, 1f, 0); mDampedMaxScreenSeparation = -1f; }