1
2/*
3 * Copyright 2006 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10
11
12//  Inspired by Rob Johnson's most excellent QuickDraw GX sample code
13
14#ifndef SkCamera_DEFINED
15#define SkCamera_DEFINED
16
17#include "Sk64.h"
18#include "SkMatrix.h"
19
20class SkCanvas;
21
22#ifdef SK_SCALAR_IS_FIXED
23    typedef SkFract SkUnitScalar;
24    #define SK_UnitScalar1          SK_Fract1
25    #define SkUnitScalarMul(a, b)   SkFractMul(a, b)
26    #define SkUnitScalarDiv(a, b)   SkFractDiv(a, b)
27#else
28    typedef float   SkUnitScalar;
29    #define SK_UnitScalar1          SK_Scalar1
30    #define SkUnitScalarMul(a, b)   SkScalarMul(a, b)
31    #define SkUnitScalarDiv(a, b)   SkScalarDiv(a, b)
32#endif
33
34struct SkUnit3D {
35    SkUnitScalar    fX, fY, fZ;
36
37    void set(SkUnitScalar x, SkUnitScalar y, SkUnitScalar z)
38    {
39        fX = x; fY = y; fZ = z;
40    }
41    static SkUnitScalar Dot(const SkUnit3D&, const SkUnit3D&);
42    static void Cross(const SkUnit3D&, const SkUnit3D&, SkUnit3D* cross);
43};
44
45struct SkPoint3D {
46    SkScalar    fX, fY, fZ;
47
48    void set(SkScalar x, SkScalar y, SkScalar z)
49    {
50        fX = x; fY = y; fZ = z;
51    }
52    SkScalar    normalize(SkUnit3D*) const;
53};
54typedef SkPoint3D SkVector3D;
55
56struct SkMatrix3D {
57    SkScalar    fMat[3][4];
58
59    void reset();
60
61    void setRow(int row, SkScalar a, SkScalar b, SkScalar c, SkScalar d = 0)
62    {
63        SkASSERT((unsigned)row < 3);
64        fMat[row][0] = a;
65        fMat[row][1] = b;
66        fMat[row][2] = c;
67        fMat[row][3] = d;
68    }
69
70    void setRotateX(SkScalar deg);
71    void setRotateY(SkScalar deg);
72    void setRotateZ(SkScalar deg);
73    void setTranslate(SkScalar x, SkScalar y, SkScalar z);
74
75    void preRotateX(SkScalar deg);
76    void preRotateY(SkScalar deg);
77    void preRotateZ(SkScalar deg);
78    void preTranslate(SkScalar x, SkScalar y, SkScalar z);
79
80    void setConcat(const SkMatrix3D& a, const SkMatrix3D& b);
81    void mapPoint(const SkPoint3D& src, SkPoint3D* dst) const;
82    void mapVector(const SkVector3D& src, SkVector3D* dst) const;
83
84    void mapPoint(SkPoint3D* v) const
85    {
86        this->mapPoint(*v, v);
87    }
88    void mapVector(SkVector3D* v) const
89    {
90        this->mapVector(*v, v);
91    }
92};
93
94class SkPatch3D {
95public:
96    SkPatch3D();
97
98    void    reset();
99    void    transform(const SkMatrix3D&, SkPatch3D* dst = NULL) const;
100
101    // dot a unit vector with the patch's normal
102    SkScalar dotWith(SkScalar dx, SkScalar dy, SkScalar dz) const;
103    SkScalar dotWith(const SkVector3D& v) const
104    {
105        return this->dotWith(v.fX, v.fY, v.fZ);
106    }
107
108    // depreicated, but still here for animator (for now)
109    void rotate(SkScalar x, SkScalar y, SkScalar z) {}
110    void rotateDegrees(SkScalar x, SkScalar y, SkScalar z) {}
111
112private:
113public: // make public for SkDraw3D for now
114    SkVector3D  fU, fV;
115    SkPoint3D   fOrigin;
116
117    friend class SkCamera3D;
118};
119
120class SkCamera3D {
121public:
122    SkCamera3D();
123
124    void reset();
125    void update();
126    void patchToMatrix(const SkPatch3D&, SkMatrix* matrix) const;
127
128    SkPoint3D   fLocation;
129    SkPoint3D   fAxis;
130    SkPoint3D   fZenith;
131    SkPoint3D   fObserver;
132
133private:
134    mutable SkMatrix    fOrientation;
135    mutable bool        fNeedToUpdate;
136
137    void doUpdate() const;
138};
139
140class Sk3DView : SkNoncopyable {
141public:
142    Sk3DView();
143    ~Sk3DView();
144
145    void save();
146    void restore();
147
148    void translate(SkScalar x, SkScalar y, SkScalar z);
149    void rotateX(SkScalar deg);
150    void rotateY(SkScalar deg);
151    void rotateZ(SkScalar deg);
152
153#ifdef SK_BUILD_FOR_ANDROID
154    void setCameraLocation(SkScalar x, SkScalar y, SkScalar z);
155    SkScalar getCameraLocationX();
156    SkScalar getCameraLocationY();
157    SkScalar getCameraLocationZ();
158#endif
159
160    void getMatrix(SkMatrix*) const;
161    void applyToCanvas(SkCanvas*) const;
162
163    SkScalar dotWithNormal(SkScalar dx, SkScalar dy, SkScalar dz) const;
164
165private:
166    struct Rec {
167        Rec*        fNext;
168        SkMatrix3D  fMatrix;
169    };
170    Rec*        fRec;
171    Rec         fInitialRec;
172    SkCamera3D  fCamera;
173};
174
175#endif
176
177