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