void SkUnit3D::Cross(const SkUnit3D& a, const SkUnit3D& b, SkUnit3D* cross) { SkASSERT(cross); // use x,y,z, in case &a == cross or &b == cross SkScalar x = SkUnitScalarMul(a.fY, b.fZ) - SkUnitScalarMul(a.fZ, b.fY); SkScalar y = SkUnitScalarMul(a.fZ, b.fX) - SkUnitScalarMul(a.fX, b.fY); SkScalar z = SkUnitScalarMul(a.fX, b.fY) - SkUnitScalarMul(a.fY, b.fX); cross->set(x, y, z); }
void SkCamera3D::doUpdate() const { SkUnit3D axis, zenith, cross; fAxis.normalize(&axis); { 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); } SkUnit3D::Cross(axis, zenith, &cross); { 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); } }
SkUnitScalar SkUnit3D::Dot(const SkUnit3D& a, const SkUnit3D& b) { return SkUnitScalarMul(a.fX, b.fX) + SkUnitScalarMul(a.fY, b.fY) + SkUnitScalarMul(a.fZ, b.fZ); }