blob: 1c4c1fbd7ebc09c85edc03d5470d3d6d36368d03 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@android.com8a1c16f2008-12-17 15:59:43 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2006 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00004 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00005 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@android.com8a1c16f2008-12-17 15:59:43 +00007 */
8
9
10
epoger@google.comec3ed6a2011-07-28 14:26:00 +000011
reed@android.com8a1c16f2008-12-17 15:59:43 +000012// 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
djsollen@google.com56c69772011-11-08 19:00:26 +0000153#ifdef SK_BUILD_FOR_ANDROID
djsollen@google.comcd9d69b2011-03-14 20:30:14 +0000154 void setCameraLocation(SkScalar x, SkScalar y, SkScalar z);
djsollen@google.come63793a2012-03-21 15:39:03 +0000155 SkScalar getCameraLocationX();
156 SkScalar getCameraLocationY();
157 SkScalar getCameraLocationZ();
djsollen@google.comcd9d69b2011-03-14 20:30:14 +0000158#endif
159
reed@android.com8a1c16f2008-12-17 15:59:43 +0000160 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