180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2006 The Android Open Source Project
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkCamera.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkScalar SkScalarDotDiv(int count, const SkScalar a[], int step_a,
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                               const SkScalar b[], int step_b,
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                               SkScalar denom) {
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FLOAT
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    float prod = 0;
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < count; i++) {
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        prod += a[0] * b[0];
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        a += step_a;
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        b += step_b;
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return prod / denom;
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Sk64    prod, tmp;
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    prod.set(0);
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < count; i++) {
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        tmp.setMul(a[0], b[0]);
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        prod.add(tmp);
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        a += step_a;
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        b += step_b;
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    prod.div(denom, Sk64::kRound_DivOption);
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return prod.get32();
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkScalar SkScalarDot(int count, const SkScalar a[], int step_a,
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                       const SkScalar b[], int step_b) {
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FLOAT
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    float prod = 0;
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < count; i++) {
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        prod += a[0] * b[0];
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        a += step_a;
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        b += step_b;
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return prod;
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Sk64    prod, tmp;
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    prod.set(0);
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < count; i++) {
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        tmp.setMul(a[0], b[0]);
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        prod.add(tmp);
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        a += step_a;
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        b += step_b;
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return prod.getFixed();
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkUnitScalar SkPoint3D::normalize(SkUnit3D* unit) const {
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FLOAT
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    float mag = sk_float_sqrt(fX*fX + fY*fY + fZ*fZ);
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (mag) {
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        float scale = 1.0f / mag;
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        unit->fX = fX * scale;
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        unit->fY = fY * scale;
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        unit->fZ = fZ * scale;
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        unit->fX = unit->fY = unit->fZ = 0;
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Sk64    tmp1, tmp2;
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    tmp1.setMul(fX, fX);
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    tmp2.setMul(fY, fY);
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    tmp1.add(tmp2);
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    tmp2.setMul(fZ, fZ);
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    tmp1.add(tmp2);
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkFixed mag = tmp1.getSqrt();
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (mag) {
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // what if mag < SK_Fixed1 ??? we will underflow the fixdiv
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkFixed scale = SkFixedDiv(SK_Fract1, mag);
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        unit->fX = SkFixedMul(fX, scale);
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        unit->fY = SkFixedMul(fY, scale);
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        unit->fZ = SkFixedMul(fZ, scale);
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        unit->fX = unit->fY = unit->fZ = 0;
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return mag;
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkUnitScalar SkUnit3D::Dot(const SkUnit3D& a, const SkUnit3D& b) {
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return  SkUnitScalarMul(a.fX, b.fX) +
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkUnitScalarMul(a.fY, b.fY) +
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkUnitScalarMul(a.fZ, b.fZ);
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkUnit3D::Cross(const SkUnit3D& a, const SkUnit3D& b, SkUnit3D* cross) {
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(cross);
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // use x,y,z, in case &a == cross or &b == cross
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar x = SkUnitScalarMul(a.fY, b.fZ) - SkUnitScalarMul(a.fZ, b.fY);
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar y = SkUnitScalarMul(a.fZ, b.fX) - SkUnitScalarMul(a.fX, b.fY);
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar z = SkUnitScalarMul(a.fX, b.fY) - SkUnitScalarMul(a.fY, b.fX);
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    cross->set(x, y, z);
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkPatch3D::SkPatch3D() {
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->reset();
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPatch3D::reset() {
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fOrigin.set(0, 0, 0);
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fU.set(SK_Scalar1, 0, 0);
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fV.set(0, -SK_Scalar1, 0);
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPatch3D::transform(const SkMatrix3D& m, SkPatch3D* dst) const {
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (dst == NULL) {
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        dst = (SkPatch3D*)this;
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    m.mapVector(fU, &dst->fU);
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    m.mapVector(fV, &dst->fV);
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    m.mapPoint(fOrigin, &dst->fOrigin);
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkScalar SkPatch3D::dotWith(SkScalar dx, SkScalar dy, SkScalar dz) const {
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar cx = SkScalarMul(fU.fY, fV.fZ) - SkScalarMul(fU.fZ, fV.fY);
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar cy = SkScalarMul(fU.fZ, fV.fX) - SkScalarMul(fU.fX, fV.fY);
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar cz = SkScalarMul(fU.fX, fV.fY) - SkScalarMul(fU.fY, fV.fX);
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkScalarMul(cx, dx) + SkScalarMul(cy, dy) + SkScalarMul(cz, dz);
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix3D::reset() {
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    memset(fMat, 0, sizeof(fMat));
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fMat[0][0] = fMat[1][1] = fMat[2][2] = SK_Scalar1;
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix3D::setTranslate(SkScalar x, SkScalar y, SkScalar z) {
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    memset(fMat, 0, sizeof(fMat));
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fMat[0][0] = x;
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fMat[1][1] = y;
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fMat[2][2] = z;
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix3D::setRotateX(SkScalar degX) {
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar    s, c;
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    s = SkScalarSinCos(SkDegreesToRadians(degX), &c);
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->setRow(0, SK_Scalar1, 0, 0);
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->setRow(1, 0, c, -s);
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->setRow(2, 0, s, c);
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix3D::setRotateY(SkScalar degY) {
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar    s, c;
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    s = SkScalarSinCos(SkDegreesToRadians(degY), &c);
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->setRow(0, c, 0, -s);
17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->setRow(1, 0, SK_Scalar1, 0);
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->setRow(2, s, 0, c);
17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix3D::setRotateZ(SkScalar degZ) {
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar    s, c;
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    s = SkScalarSinCos(SkDegreesToRadians(degZ), &c);
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->setRow(0, c, -s, 0);
18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->setRow(1, s, c, 0);
18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->setRow(2, 0, 0, SK_Scalar1);
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix3D::preTranslate(SkScalar x, SkScalar y, SkScalar z) {
18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar col[3] = { x, y, z};
18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < 3; i++) {
19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fMat[i][3] += SkScalarDot(3, &fMat[i][0], 1, col, 1);
19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix3D::preRotateX(SkScalar degX) {
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkMatrix3D m;
19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    m.setRotateX(degX);
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->setConcat(*this, m);
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix3D::preRotateY(SkScalar degY) {
20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkMatrix3D m;
20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    m.setRotateY(degY);
20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->setConcat(*this, m);
20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix3D::preRotateZ(SkScalar degZ) {
20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkMatrix3D m;
20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    m.setRotateZ(degZ);
20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->setConcat(*this, m);
21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix3D::setConcat(const SkMatrix3D& a, const SkMatrix3D& b) {
21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkMatrix3D  tmp;
21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkMatrix3D* c = this;
21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (this == &a || this == &b) {
21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        c = &tmp;
21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < 3; i++) {
22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (int j = 0; j < 3; j++) {
22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            c->fMat[i][j] = SkScalarDot(3, &a.fMat[i][0], 1, &b.fMat[0][j], 4);
22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        c->fMat[i][3] = SkScalarDot(3, &a.fMat[i][0], 1,
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                    &b.fMat[0][3], 4) + a.fMat[i][3];
22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (c == &tmp) {
22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        *this = tmp;
22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix3D::mapPoint(const SkPoint3D& src, SkPoint3D* dst) const {
23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar x = SkScalarDot(3, &fMat[0][0], 1, &src.fX, 1) + fMat[0][3];
23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar y = SkScalarDot(3, &fMat[1][0], 1, &src.fX, 1) + fMat[1][3];
23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar z = SkScalarDot(3, &fMat[2][0], 1, &src.fX, 1) + fMat[2][3];
23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    dst->set(x, y, z);
23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix3D::mapVector(const SkVector3D& src, SkVector3D* dst) const {
24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar x = SkScalarDot(3, &fMat[0][0], 1, &src.fX, 1);
24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar y = SkScalarDot(3, &fMat[1][0], 1, &src.fX, 1);
24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar z = SkScalarDot(3, &fMat[2][0], 1, &src.fX, 1);
24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    dst->set(x, y, z);
24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkCamera3D::SkCamera3D() {
24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->reset();
25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkCamera3D::reset() {
25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fLocation.set(0, 0, -SkIntToScalar(576));   // 8 inches backward
25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fAxis.set(0, 0, SK_Scalar1);                // forward
25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fZenith.set(0, -SK_Scalar1, 0);             // up
25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fObserver.set(0, 0, fLocation.fZ);
25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fNeedToUpdate = true;
26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkCamera3D::update() {
26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fNeedToUpdate = true;
26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkCamera3D::doUpdate() const {
26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkUnit3D    axis, zenith, cross;
26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fAxis.normalize(&axis);
27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkScalar dot = SkUnit3D::Dot(*SkTCast<const SkUnit3D*>(&fZenith), axis);
27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        zenith.fX = fZenith.fX - SkUnitScalarMul(dot, axis.fX);
27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        zenith.fY = fZenith.fY - SkUnitScalarMul(dot, axis.fY);
27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        zenith.fZ = fZenith.fZ - SkUnitScalarMul(dot, axis.fZ);
27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkTCast<SkPoint3D*>(&zenith)->normalize(&zenith);
27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkUnit3D::Cross(axis, zenith, &cross);
28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkMatrix* orien = &fOrientation;
28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkScalar x = fObserver.fX;
28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkScalar y = fObserver.fY;
28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkScalar z = fObserver.fZ;
28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        orien->set(SkMatrix::kMScaleX, SkUnitScalarMul(x, axis.fX) - SkUnitScalarMul(z, cross.fX));
29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        orien->set(SkMatrix::kMSkewX,  SkUnitScalarMul(x, axis.fY) - SkUnitScalarMul(z, cross.fY));
29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        orien->set(SkMatrix::kMTransX, SkUnitScalarMul(x, axis.fZ) - SkUnitScalarMul(z, cross.fZ));
29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        orien->set(SkMatrix::kMSkewY,  SkUnitScalarMul(y, axis.fX) - SkUnitScalarMul(z, zenith.fX));
29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        orien->set(SkMatrix::kMScaleY, SkUnitScalarMul(y, axis.fY) - SkUnitScalarMul(z, zenith.fY));
29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        orien->set(SkMatrix::kMTransY, SkUnitScalarMul(y, axis.fZ) - SkUnitScalarMul(z, zenith.fZ));
29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        orien->set(SkMatrix::kMPersp0, axis.fX);
29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        orien->set(SkMatrix::kMPersp1, axis.fY);
29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        orien->set(SkMatrix::kMPersp2, axis.fZ);
29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkCamera3D::patchToMatrix(const SkPatch3D& quilt, SkMatrix* matrix) const {
30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fNeedToUpdate) {
30380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->doUpdate();
30480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fNeedToUpdate = false;
30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkScalar* mapPtr = (const SkScalar*)(const void*)&fOrientation;
30880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkScalar* patchPtr;
30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPoint3D       diff;
31080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkScalar        dot;
31180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
31280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    diff.fX = quilt.fOrigin.fX - fLocation.fX;
31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    diff.fY = quilt.fOrigin.fY - fLocation.fY;
31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    diff.fZ = quilt.fOrigin.fZ - fLocation.fZ;
31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    dot = SkUnit3D::Dot(*SkTCast<const SkUnit3D*>(&diff),
31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        *SkTCast<const SkUnit3D*>(SkTCast<const SkScalar*>(&fOrientation) + 6));
31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
31980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    patchPtr = (const SkScalar*)&quilt;
32080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    matrix->set(SkMatrix::kMScaleX, SkScalarDotDiv(3, patchPtr, 1, mapPtr, 1, dot));
32180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    matrix->set(SkMatrix::kMSkewY,  SkScalarDotDiv(3, patchPtr, 1, mapPtr+3, 1, dot));
32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    matrix->set(SkMatrix::kMPersp0, SkScalarDotDiv(3, patchPtr, 1, mapPtr+6, 1, dot));
32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    patchPtr += 3;
32580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    matrix->set(SkMatrix::kMSkewX,  SkScalarDotDiv(3, patchPtr, 1, mapPtr, 1, dot));
32680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    matrix->set(SkMatrix::kMScaleY, SkScalarDotDiv(3, patchPtr, 1, mapPtr+3, 1, dot));
32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    matrix->set(SkMatrix::kMPersp1, SkScalarDotDiv(3, patchPtr, 1, mapPtr+6, 1, dot));
32880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
32980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    patchPtr = (const SkScalar*)(const void*)&diff;
33080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    matrix->set(SkMatrix::kMTransX, SkScalarDotDiv(3, patchPtr, 1, mapPtr, 1, dot));
33180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    matrix->set(SkMatrix::kMTransY, SkScalarDotDiv(3, patchPtr, 1, mapPtr+3, 1, dot));
33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    matrix->set(SkMatrix::kMPersp2, SK_UnitScalar1);
33380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
33480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
33780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSk3DView::Sk3DView() {
33880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fInitialRec.fMatrix.reset();
33980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fRec = &fInitialRec;
34080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
34180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
34280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSk3DView::~Sk3DView() {
34380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Rec* rec = fRec;
34480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    while (rec != &fInitialRec) {
34580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        Rec* next = rec->fNext;
34680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDELETE(rec);
34780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        rec = next;
34880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
34980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
35080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
35180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid Sk3DView::save() {
35280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Rec* rec = SkNEW(Rec);
35380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    rec->fNext = fRec;
35480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    rec->fMatrix = fRec->fMatrix;
35580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fRec = rec;
35680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
35780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
35880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid Sk3DView::restore() {
35980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(fRec != &fInitialRec);
36080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Rec* next = fRec->fNext;
36180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDELETE(fRec);
36280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fRec = next;
36380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
36480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
36580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_BUILD_FOR_ANDROID
36680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid Sk3DView::setCameraLocation(SkScalar x, SkScalar y, SkScalar z) {
36780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // the camera location is passed in inches, set in pt
368910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    SkScalar lz = z * 72.0f;
369910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    fCamera.fLocation.set(x * 72.0f, y * 72.0f, lz);
37080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fCamera.fObserver.set(0, 0, lz);
37180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fCamera.update();
37280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
37380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
37480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
37580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkScalar Sk3DView::getCameraLocationX() {
376910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    return fCamera.fLocation.fX / 72.0f;
37780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
37880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
37980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkScalar Sk3DView::getCameraLocationY() {
380910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    return fCamera.fLocation.fY / 72.0f;
38180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
38280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
38380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkScalar Sk3DView::getCameraLocationZ() {
384910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger    return fCamera.fLocation.fZ / 72.0f;
38580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
38680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
38780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
38880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid Sk3DView::translate(SkScalar x, SkScalar y, SkScalar z) {
38980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fRec->fMatrix.preTranslate(x, y, z);
39080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
39180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
39280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid Sk3DView::rotateX(SkScalar deg) {
39380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fRec->fMatrix.preRotateX(deg);
39480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
39580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
39680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid Sk3DView::rotateY(SkScalar deg) {
39780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fRec->fMatrix.preRotateY(deg);
39880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
39980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
40080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid Sk3DView::rotateZ(SkScalar deg) {
40180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fRec->fMatrix.preRotateZ(deg);
40280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
40380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
40480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkScalar Sk3DView::dotWithNormal(SkScalar x, SkScalar y, SkScalar z) const {
40580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPatch3D   patch;
40680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    patch.transform(fRec->fMatrix);
40780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return patch.dotWith(x, y, z);
40880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
40980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
41080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid Sk3DView::getMatrix(SkMatrix* matrix) const {
41180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (matrix != NULL) {
41280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkPatch3D   patch;
41380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        patch.transform(fRec->fMatrix);
41480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fCamera.patchToMatrix(patch, matrix);
41580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
41680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
41780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
41880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkCanvas.h"
41980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
42080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid Sk3DView::applyToCanvas(SkCanvas* canvas) const {
42180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkMatrix    matrix;
42280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
42380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->getMatrix(&matrix);
42480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    canvas->concat(matrix);
42580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
426