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