Skia的SkCamera.cpp的doUpdate() 算法。

1.一个空间坐标系A1由U,V 和Origin来表述。
其中U,代表横轴。V代表纵轴。Origin代表原点。[初始值与屏幕坐标相同]

2.另外一个空间坐标系A2由当前矩阵Matrix描述。

3.A1经过A2进行变换,变换后的值A3为新的坐标系下的值。


4.A4是另外一个新的坐标系,代表的是一个方锥形的投影。
  A3经过A4进行变换,得到一个新的矩阵A5.代表的是A1在视口中的矩阵标示。


观察点在0,0,-576 (fLocation.fZ 和 fObserver 是同一值,标示观察的位置)
向前的方向为 0,0,1  fAxis 标示观察方向
向上的方向为 0, -1, 0  fZenith标示相机向上的方向。

doUpdate方法中。
对fZenith和fAxis求了一次点积。然后通过以下方法对位置fZenith的坐标进行了调整


SkUnit3D    axis, zenith, cross;
         SkScalar dot = SkUnit3D::Dot(*(const SkUnit3D*)(const void*)&fZenith, axis);

        zenith.fX = fZenith.fX - SkUnitScalarMul(dot, axis.fX);
        zenith.fY = fZenith.fY - SkUnitScalarMul(dot, axis.fY);
        zenith.fZ = fZenith.fZ - SkUnitScalarMul(dot, axis.fZ);

        (void)((SkPoint3D*)(void*)&zenith)->normalize(&zenith);

然后对zenith 和 axis求了一次叉积。很明显,是再求相机朝右的方向。

      SkUnit3D::Cross(axis, zenith, &cross);


最后,对这个相机针对观察点 fObserver。要进行一次平移变换。

           SkMatrix* orien = &fOrientation;
        SkScalar x = fObserver.fX;
        SkScalar y = fObserver.fY;
        SkScalar z = fObserver.fZ;

        orien->set(SkMatrix::kMScaleX, SkUnitScalarMul(x, axis.fX) - SkUnitScalarMul(z, cross.fX));
        orien->set(SkMatrix::kMSkewX,  SkUnitScalarMul(x, axis.fY) - SkUnitScalarMul(z, cross.fY));
        orien->set(SkMatrix::kMTransX, SkUnitScalarMul(x, axis.fZ) - SkUnitScalarMul(z, cross.fZ));
        orien->set(SkMatrix::kMSkewY,  SkUnitScalarMul(y, axis.fX) - SkUnitScalarMul(z, zenith.fX));
        orien->set(SkMatrix::kMScaleY, SkUnitScalarMul(y, axis.fY) - SkUnitScalarMul(z, zenith.fY));
        orien->set(SkMatrix::kMTransY, SkUnitScalarMul(y, axis.fZ) - SkUnitScalarMul(z, zenith.fZ));
        orien->set(SkMatrix::kMPersp0, axis.fX);
        orien->set(SkMatrix::kMPersp1, axis.fY);
        orien->set(SkMatrix::kMPersp2, axis.fZ);

你可能感兴趣的:(update)