1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 18 19 // Inspired by Rob Johnson's most excellent QuickDraw GX sample code 20 21 #ifndef SkCamera_DEFINED 22 #define SkCamera_DEFINED 23 24 #include "Sk64.h" 25 #include "SkMatrix.h" 26 27 class SkCanvas; 28 29 #ifdef SK_SCALAR_IS_FIXED 30 typedef SkFract SkUnitScalar; 31 #define SK_UnitScalar1 SK_Fract1 32 #define SkUnitScalarMul(a, b) SkFractMul(a, b) 33 #define SkUnitScalarDiv(a, b) SkFractDiv(a, b) 34 #else 35 typedef float SkUnitScalar; 36 #define SK_UnitScalar1 SK_Scalar1 37 #define SkUnitScalarMul(a, b) SkScalarMul(a, b) 38 #define SkUnitScalarDiv(a, b) SkScalarDiv(a, b) 39 #endif 40 41 struct SkUnit3D { 42 SkUnitScalar fX, fY, fZ; 43 44 void set(SkUnitScalar x, SkUnitScalar y, SkUnitScalar z) 45 { 46 fX = x; fY = y; fZ = z; 47 } 48 static SkUnitScalar Dot(const SkUnit3D&, const SkUnit3D&); 49 static void Cross(const SkUnit3D&, const SkUnit3D&, SkUnit3D* cross); 50 }; 51 52 struct SkPoint3D { 53 SkScalar fX, fY, fZ; 54 55 void set(SkScalar x, SkScalar y, SkScalar z) 56 { 57 fX = x; fY = y; fZ = z; 58 } 59 SkScalar normalize(SkUnit3D*) const; 60 }; 61 typedef SkPoint3D SkVector3D; 62 63 struct SkMatrix3D { 64 SkScalar fMat[3][4]; 65 66 void reset(); 67 68 void setRow(int row, SkScalar a, SkScalar b, SkScalar c, SkScalar d = 0) 69 { 70 SkASSERT((unsigned)row < 3); 71 fMat[row][0] = a; 72 fMat[row][1] = b; 73 fMat[row][2] = c; 74 fMat[row][3] = d; 75 } 76 77 void setRotateX(SkScalar deg); 78 void setRotateY(SkScalar deg); 79 void setRotateZ(SkScalar deg); 80 void setTranslate(SkScalar x, SkScalar y, SkScalar z); 81 82 void preRotateX(SkScalar deg); 83 void preRotateY(SkScalar deg); 84 void preRotateZ(SkScalar deg); 85 void preTranslate(SkScalar x, SkScalar y, SkScalar z); 86 87 void setConcat(const SkMatrix3D& a, const SkMatrix3D& b); 88 void mapPoint(const SkPoint3D& src, SkPoint3D* dst) const; 89 void mapVector(const SkVector3D& src, SkVector3D* dst) const; 90 91 void mapPoint(SkPoint3D* v) const 92 { 93 this->mapPoint(*v, v); 94 } 95 void mapVector(SkVector3D* v) const 96 { 97 this->mapVector(*v, v); 98 } 99 }; 100 101 class SkPatch3D { 102 public: 103 SkPatch3D(); 104 105 void reset(); 106 void transform(const SkMatrix3D&, SkPatch3D* dst = NULL) const; 107 108 // dot a unit vector with the patch's normal 109 SkScalar dotWith(SkScalar dx, SkScalar dy, SkScalar dz) const; 110 SkScalar dotWith(const SkVector3D& v) const 111 { 112 return this->dotWith(v.fX, v.fY, v.fZ); 113 } 114 115 // depreicated, but still here for animator (for now) 116 void rotate(SkScalar x, SkScalar y, SkScalar z) {} 117 void rotateDegrees(SkScalar x, SkScalar y, SkScalar z) {} 118 119 private: 120 public: // make public for SkDraw3D for now 121 SkVector3D fU, fV; 122 SkPoint3D fOrigin; 123 124 friend class SkCamera3D; 125 }; 126 127 class SkCamera3D { 128 public: 129 SkCamera3D(); 130 131 void reset(); 132 void update(); 133 void patchToMatrix(const SkPatch3D&, SkMatrix* matrix) const; 134 135 SkPoint3D fLocation; 136 SkPoint3D fAxis; 137 SkPoint3D fZenith; 138 SkPoint3D fObserver; 139 140 private: 141 mutable SkMatrix fOrientation; 142 mutable bool fNeedToUpdate; 143 144 void doUpdate() const; 145 }; 146 147 class Sk3DView : SkNoncopyable { 148 public: 149 Sk3DView(); 150 ~Sk3DView(); 151 152 void save(); 153 void restore(); 154 155 void translate(SkScalar x, SkScalar y, SkScalar z); 156 void rotateX(SkScalar deg); 157 void rotateY(SkScalar deg); 158 void rotateZ(SkScalar deg); 159 160 void getMatrix(SkMatrix*) const; 161 void applyToCanvas(SkCanvas*) const; 162 163 SkScalar dotWithNormal(SkScalar dx, SkScalar dy, SkScalar dz) const; 164 165 private: 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