Home | History | Annotate | Download | only in utils
      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 
     15 class SkCanvas;
     16 
     17 struct 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 
     27 struct 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 };
     35 typedef SkPoint3D SkVector3D;
     36 
     37 struct 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 
     73 class SkPatch3D {
     74 public:
     75     SkPatch3D();
     76 
     77     void    reset();
     78     void    transform(const SkMatrix3D&, SkPatch3D* dst = NULL) 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 
     90 private:
     91 public: // make public for SkDraw3D for now
     92     SkVector3D  fU, fV;
     93     SkPoint3D   fOrigin;
     94 
     95     friend class SkCamera3D;
     96 };
     97 
     98 class SkCamera3D {
     99 public:
    100     SkCamera3D();
    101 
    102     void reset();
    103     void update();
    104     void patchToMatrix(const SkPatch3D&, SkMatrix* matrix) const;
    105 
    106     SkPoint3D   fLocation;
    107     SkPoint3D   fAxis;
    108     SkPoint3D   fZenith;
    109     SkPoint3D   fObserver;
    110 
    111 private:
    112     mutable SkMatrix    fOrientation;
    113     mutable bool        fNeedToUpdate;
    114 
    115     void doUpdate() const;
    116 };
    117 
    118 class Sk3DView : SkNoncopyable {
    119 public:
    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 
    143 private:
    144     struct Rec {
    145         Rec*        fNext;
    146         SkMatrix3D  fMatrix;
    147     };
    148     Rec*        fRec;
    149     Rec         fInitialRec;
    150     SkCamera3D  fCamera;
    151 };
    152 
    153 #endif
    154