void GutUserControl_RotateObject(Matrix4x4 object_matrix, float time_advance)
{
	// 讀取滑鼠
	GutMouseInfo mouse;
	if ( GutReadMouse(&mouse) )
	{
		float rotation_speed = 1.0 * time_advance;

		// 如果按下滑鼠左鍵,就旋轉鏡頭
		if ( mouse.button[0] )
		{
			Matrix4x4 rotate_matrix;

			rotate_matrix.RotateY_Replace(mouse.x * rotation_speed);
			rotate_matrix.RotateX(mouse.y * rotation_speed);

			object_matrix = object_matrix * rotate_matrix;
		}

		// 用滾輪來縮放物件
		if ( mouse.z )
		{
			float scale = 1.0f + mouse.z / 1000.0f;
			object_matrix.Scale(scale, scale, scale);
		}
	}
}
Exemple #2
0
/*
=============
Uniform Scale
=============
*/
void PS2Sprite::Scale( const float s ) {
	Matrix4x4 rotationMatrix; 
	rotationMatrix.Scale( s ); // apply required scaling to matrix
	for( int i = 0; i < mNumOfVerts; i++ ) { // apply to Vertex Vectors
		pVerts[ i ] = rotationMatrix * pVerts[ i ];
	}
}
Exemple #3
0
const Matrix4x4
Layer::GetTransform() const
{
  Matrix4x4 transform = mTransform;
  if (const ContainerLayer* c = AsContainerLayer()) {
    transform.Scale(c->GetPreXScale(), c->GetPreYScale(), 1.0f);
  }
  transform = transform * Matrix4x4().Scale(mPostXScale, mPostYScale, 1.0f);
  return transform;
}
Exemple #4
0
const Matrix4x4
Layer::GetLocalTransform()
{
  Matrix4x4 transform;
  if (LayerComposite* shadow = AsLayerComposite())
    transform = shadow->GetShadowTransform();
  else
    transform = mTransform;
  if (ContainerLayer* c = AsContainerLayer()) {
    transform.Scale(c->GetPreXScale(), c->GetPreYScale(), 1.0f);
  }
  transform = transform * Matrix4x4().Scale(mPostXScale, mPostYScale, 1.0f);

  return transform;
}
void
AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer)
{
  LayerComposite* layerComposite = aLayer->AsLayerComposite();

  const FrameMetrics& metrics = aLayer->GetFrameMetrics();
  // We must apply the resolution scale before a pan/zoom transform, so we call
  // GetTransform here.
  Matrix4x4 oldTransform = aLayer->GetTransform();

  CSSToLayerScale geckoZoom = metrics.LayersPixelsPerCSSPixel();

  LayerIntPoint scrollOffsetLayerPixels = RoundedToInt(metrics.GetScrollOffset() * geckoZoom);

  if (mIsFirstPaint) {
    mContentRect = metrics.mScrollableRect;
    SetFirstPaintViewport(scrollOffsetLayerPixels,
                          geckoZoom,
                          mContentRect);
    mIsFirstPaint = false;
  } else if (!metrics.mScrollableRect.IsEqualEdges(mContentRect)) {
    mContentRect = metrics.mScrollableRect;
    SetPageRect(mContentRect);
  }

  // We synchronise the viewport information with Java after sending the above
  // notifications, so that Java can take these into account in its response.
  // Calculate the absolute display port to send to Java
  LayerIntRect displayPort = RoundedToInt(
    (metrics.mCriticalDisplayPort.IsEmpty()
      ? metrics.mDisplayPort
      : metrics.mCriticalDisplayPort
    ) * geckoZoom);
  displayPort += scrollOffsetLayerPixels;

  LayerMargin fixedLayerMargins(0, 0, 0, 0);
  ScreenPoint offset(0, 0);

  // Ideally we would initialize userZoom to AsyncPanZoomController::CalculateResolution(metrics)
  // but this causes a reftest-ipc test to fail (see bug 883646 comment 27). The reason for this
  // appears to be that metrics.mZoom is poorly initialized in some scenarios. In these scenarios,
  // however, we can assume there is no async zooming in progress and so the following statement
  // works fine.
  CSSToScreenScale userZoom(metrics.mDevPixelsPerCSSPixel * metrics.mCumulativeResolution * LayerToScreenScale(1));
  ScreenPoint userScroll = metrics.GetScrollOffset() * userZoom;
  SyncViewportInfo(displayPort, geckoZoom, mLayersUpdated,
                   userScroll, userZoom, fixedLayerMargins,
                   offset);
  mLayersUpdated = false;

  // Apply the render offset
  mLayerManager->GetCompositor()->SetScreenRenderOffset(offset);

  // Handle transformations for asynchronous panning and zooming. We determine the
  // zoom used by Gecko from the transformation set on the root layer, and we
  // determine the scroll offset used by Gecko from the frame metrics of the
  // primary scrollable layer. We compare this to the user zoom and scroll
  // offset in the view transform we obtained from Java in order to compute the
  // transformation we need to apply.
  ScreenPoint geckoScroll(0, 0);
  if (metrics.IsScrollable()) {
    geckoScroll = metrics.GetScrollOffset() * userZoom;
  }
  ParentLayerToScreenScale scale = userZoom
                                  / metrics.mDevPixelsPerCSSPixel
                                  / metrics.GetParentResolution();
  ScreenPoint translation = userScroll - geckoScroll;
  Matrix4x4 treeTransform = ViewTransform(scale, -translation);

  // The transform already takes the resolution scale into account.  Since we
  // will apply the resolution scale again when computing the effective
  // transform, we must apply the inverse resolution scale here.
  Matrix4x4 computedTransform = oldTransform * treeTransform;
  if (ContainerLayer* container = aLayer->AsContainerLayer()) {
    computedTransform.Scale(1.0f/container->GetPreXScale(),
                            1.0f/container->GetPreYScale(),
                            1);
  }
  computedTransform.ScalePost(1.0f/aLayer->GetPostXScale(),
                              1.0f/aLayer->GetPostYScale(),
                              1);
  layerComposite->SetShadowTransform(computedTransform);
  NS_ASSERTION(!layerComposite->GetShadowTransformSetByAnimation(),
               "overwriting animated transform!");

  // Apply resolution scaling to the old transform - the layer tree as it is
  // doesn't have the necessary transform to display correctly.
  oldTransform.Scale(metrics.mResolution.scale, metrics.mResolution.scale, 1);

  // Make sure that overscroll and under-zoom are represented in the old
  // transform so that fixed position content moves and scales accordingly.
  // These calculations will effectively scale and offset fixed position layers
  // in screen space when the compensatory transform is performed in
  // AlignFixedAndStickyLayers.
  ScreenRect contentScreenRect = mContentRect * userZoom;
  gfxPoint3D overscrollTranslation;
  if (userScroll.x < contentScreenRect.x) {
    overscrollTranslation.x = contentScreenRect.x - userScroll.x;
  } else if (userScroll.x + metrics.mCompositionBounds.width > contentScreenRect.XMost()) {
    overscrollTranslation.x = contentScreenRect.XMost() -
      (userScroll.x + metrics.mCompositionBounds.width);
  }
  if (userScroll.y < contentScreenRect.y) {
    overscrollTranslation.y = contentScreenRect.y - userScroll.y;
  } else if (userScroll.y + metrics.mCompositionBounds.height > contentScreenRect.YMost()) {
    overscrollTranslation.y = contentScreenRect.YMost() -
      (userScroll.y + metrics.mCompositionBounds.height);
  }
  oldTransform.Translate(overscrollTranslation.x,
                         overscrollTranslation.y,
                         overscrollTranslation.z);

  gfx::Size underZoomScale(1.0f, 1.0f);
  if (mContentRect.width * userZoom.scale < metrics.mCompositionBounds.width) {
    underZoomScale.width = (mContentRect.width * userZoom.scale) /
      metrics.mCompositionBounds.width;
  }
  if (mContentRect.height * userZoom.scale < metrics.mCompositionBounds.height) {
    underZoomScale.height = (mContentRect.height * userZoom.scale) /
      metrics.mCompositionBounds.height;
  }
  oldTransform.Scale(underZoomScale.width, underZoomScale.height, 1);

  // Make sure fixed position layers don't move away from their anchor points
  // when we're asynchronously panning or zooming
  AlignFixedAndStickyLayers(aLayer, aLayer, oldTransform,
                            aLayer->GetLocalTransform(), fixedLayerMargins);
}
static void
ApplyAsyncTransformToScrollbarForContent(ContainerLayer* aScrollbar,
                                         Layer* aContent, bool aScrollbarIsChild)
{
  // We only apply the transform if the scroll-target layer has non-container
  // children (i.e. when it has some possibly-visible content). This is to
  // avoid moving scroll-bars in the situation that only a scroll information
  // layer has been built for a scroll frame, as this would result in a
  // disparity between scrollbars and visible content.
  if (aContent->AsContainerLayer() &&
      !LayerHasNonContainerDescendants(aContent->AsContainerLayer())) {
    return;
  }

  const FrameMetrics& metrics = aContent->GetFrameMetrics();
  AsyncPanZoomController* apzc = aContent->GetAsyncPanZoomController();

  Matrix4x4 asyncTransform = apzc->GetCurrentAsyncTransform();
  Matrix4x4 nontransientTransform = apzc->GetNontransientAsyncTransform();
  Matrix4x4 nontransientUntransform = nontransientTransform;
  nontransientUntransform.Invert();
  Matrix4x4 transientTransform = asyncTransform * nontransientUntransform;

  // |transientTransform| represents the amount by which we have scrolled and
  // zoomed since the last paint. Because the scrollbar was sized and positioned based
  // on the painted content, we need to adjust it based on transientTransform so that
  // it reflects what the user is actually seeing now.
  // - The scroll thumb needs to be scaled in the direction of scrolling by the inverse
  //   of the transientTransform scale (representing the zoom). This is because zooming
  //   in decreases the fraction of the whole scrollable rect that is in view.
  // - It needs to be translated in opposite direction of the transientTransform
  //   translation (representing the scroll). This is because scrolling down, which
  //   translates the layer content up, should result in moving the scroll thumb down.
  //   The amount of the translation to the scroll thumb should be such that the ratio
  //   of the translation to the size of the scroll port is the same as the ratio
  //   of the scroll amount to the size of the scrollable rect.
  Matrix4x4 scrollbarTransform;
  if (aScrollbar->GetScrollbarDirection() == Layer::VERTICAL) {
    float scale = metrics.CalculateCompositedSizeInCssPixels().height / metrics.mScrollableRect.height;
    scrollbarTransform = scrollbarTransform * Matrix4x4().Scale(1.f, 1.f / transientTransform._22, 1.f);
    scrollbarTransform = scrollbarTransform * Matrix4x4().Translate(0, -transientTransform._42 * scale, 0);
  }
  if (aScrollbar->GetScrollbarDirection() == Layer::HORIZONTAL) {
    float scale = metrics.CalculateCompositedSizeInCssPixels().width / metrics.mScrollableRect.width;
    scrollbarTransform = scrollbarTransform * Matrix4x4().Scale(1.f / transientTransform._11, 1.f, 1.f);
    scrollbarTransform = scrollbarTransform * Matrix4x4().Translate(-transientTransform._41 * scale, 0, 0);
  }

  Matrix4x4 transform = scrollbarTransform * aScrollbar->GetTransform();

  if (aScrollbarIsChild) {
    // If the scrollbar layer is a child of the content it is a scrollbar for, then we
    // need to do an extra untransform to cancel out the transient async transform on
    // the content. This is needed because otherwise that transient async transform is
    // part of the effective transform of this scrollbar, and the scrollbar will jitter
    // as the content scrolls.
    transientTransform.Invert();
    transform = transform * transientTransform;
  }

  // GetTransform already takes the pre- and post-scale into account.  Since we
  // will apply the pre- and post-scale again when computing the effective
  // transform, we must apply the inverses here.
  transform.Scale(1.0f/aScrollbar->GetPreXScale(),
                  1.0f/aScrollbar->GetPreYScale(),
                  1);
  transform = transform * Matrix4x4().Scale(1.0f/aScrollbar->GetPostXScale(),
                                            1.0f/aScrollbar->GetPostYScale(),
                                            1);
  aScrollbar->AsLayerComposite()->SetShadowTransform(transform);
}
bool
AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer)
{
  bool appliedTransform = false;
  for (Layer* child = aLayer->GetFirstChild();
      child; child = child->GetNextSibling()) {
    appliedTransform |=
      ApplyAsyncContentTransformToTree(child);
  }

  if (AsyncPanZoomController* controller = aLayer->GetAsyncPanZoomController()) {
    LayerComposite* layerComposite = aLayer->AsLayerComposite();
    Matrix4x4 oldTransform = aLayer->GetTransform();

    ViewTransform asyncTransformWithoutOverscroll, overscrollTransform;
    ScreenPoint scrollOffset;
    controller->SampleContentTransformForFrame(&asyncTransformWithoutOverscroll,
                                               scrollOffset,
                                               &overscrollTransform);

    const FrameMetrics& metrics = aLayer->GetFrameMetrics();
    CSSToLayerScale paintScale = metrics.LayersPixelsPerCSSPixel();
    CSSRect displayPort(metrics.mCriticalDisplayPort.IsEmpty() ?
                        metrics.mDisplayPort : metrics.mCriticalDisplayPort);
    LayerMargin fixedLayerMargins(0, 0, 0, 0);
    ScreenPoint offset(0, 0);
    SyncFrameMetrics(scrollOffset, asyncTransformWithoutOverscroll.mScale.scale,
                     metrics.mScrollableRect, mLayersUpdated, displayPort,
                     paintScale, mIsFirstPaint, fixedLayerMargins, offset);

    mIsFirstPaint = false;
    mLayersUpdated = false;

    // Apply the render offset
    mLayerManager->GetCompositor()->SetScreenRenderOffset(offset);

    Matrix4x4 transform = AdjustAndCombineWithCSSTransform(
        asyncTransformWithoutOverscroll * overscrollTransform, aLayer);

    // GetTransform already takes the pre- and post-scale into account.  Since we
    // will apply the pre- and post-scale again when computing the effective
    // transform, we must apply the inverses here.
    if (ContainerLayer* container = aLayer->AsContainerLayer()) {
      transform.Scale(1.0f/container->GetPreXScale(),
                      1.0f/container->GetPreYScale(),
                      1);
    }
    transform = transform * Matrix4x4().Scale(1.0f/aLayer->GetPostXScale(),
                                              1.0f/aLayer->GetPostYScale(),
                                              1);
    layerComposite->SetShadowTransform(transform);
    NS_ASSERTION(!layerComposite->GetShadowTransformSetByAnimation(),
                 "overwriting animated transform!");

    // Apply resolution scaling to the old transform - the layer tree as it is
    // doesn't have the necessary transform to display correctly.
    LayoutDeviceToLayerScale resolution = metrics.mCumulativeResolution;
    oldTransform.Scale(resolution.scale, resolution.scale, 1);

    // For the purpose of aligning fixed and sticky layers, we disregard
    // the overscroll transform when computing the 'aCurrentTransformForRoot'
    // parameter. This ensures that the overscroll transform is not unapplied,
    // and therefore that the visual effect applies to fixed and sticky layers.
    Matrix4x4 transformWithoutOverscroll = AdjustAndCombineWithCSSTransform(
        asyncTransformWithoutOverscroll, aLayer);
    AlignFixedAndStickyLayers(aLayer, aLayer, oldTransform,
                              transformWithoutOverscroll, fixedLayerMargins);

    appliedTransform = true;
  }

  if (aLayer->AsContainerLayer() && aLayer->GetScrollbarDirection() != Layer::NONE) {
    ApplyAsyncTransformToScrollbar(aLayer->AsContainerLayer());
  }
  return appliedTransform;
}