michael@0: /* michael@0: * Copyright 2006 The Android Open Source Project michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: // Inspired by Rob Johnson's most excellent QuickDraw GX sample code michael@0: michael@0: #ifndef SkCamera_DEFINED michael@0: #define SkCamera_DEFINED michael@0: michael@0: #include "SkMatrix.h" michael@0: michael@0: class SkCanvas; michael@0: michael@0: struct SkUnit3D { michael@0: SkScalar fX, fY, fZ; michael@0: michael@0: void set(SkScalar x, SkScalar y, SkScalar z) { michael@0: fX = x; fY = y; fZ = z; michael@0: } michael@0: static SkScalar Dot(const SkUnit3D&, const SkUnit3D&); michael@0: static void Cross(const SkUnit3D&, const SkUnit3D&, SkUnit3D* cross); michael@0: }; michael@0: michael@0: struct SkPoint3D { michael@0: SkScalar fX, fY, fZ; michael@0: michael@0: void set(SkScalar x, SkScalar y, SkScalar z) { michael@0: fX = x; fY = y; fZ = z; michael@0: } michael@0: SkScalar normalize(SkUnit3D*) const; michael@0: }; michael@0: typedef SkPoint3D SkVector3D; michael@0: michael@0: struct SkMatrix3D { michael@0: SkScalar fMat[3][4]; michael@0: michael@0: void reset(); michael@0: michael@0: void setRow(int row, SkScalar a, SkScalar b, SkScalar c, SkScalar d = 0) { michael@0: SkASSERT((unsigned)row < 3); michael@0: fMat[row][0] = a; michael@0: fMat[row][1] = b; michael@0: fMat[row][2] = c; michael@0: fMat[row][3] = d; michael@0: } michael@0: michael@0: void setRotateX(SkScalar deg); michael@0: void setRotateY(SkScalar deg); michael@0: void setRotateZ(SkScalar deg); michael@0: void setTranslate(SkScalar x, SkScalar y, SkScalar z); michael@0: michael@0: void preRotateX(SkScalar deg); michael@0: void preRotateY(SkScalar deg); michael@0: void preRotateZ(SkScalar deg); michael@0: void preTranslate(SkScalar x, SkScalar y, SkScalar z); michael@0: michael@0: void setConcat(const SkMatrix3D& a, const SkMatrix3D& b); michael@0: void mapPoint(const SkPoint3D& src, SkPoint3D* dst) const; michael@0: void mapVector(const SkVector3D& src, SkVector3D* dst) const; michael@0: michael@0: void mapPoint(SkPoint3D* v) const { michael@0: this->mapPoint(*v, v); michael@0: } michael@0: michael@0: void mapVector(SkVector3D* v) const { michael@0: this->mapVector(*v, v); michael@0: } michael@0: }; michael@0: michael@0: class SkPatch3D { michael@0: public: michael@0: SkPatch3D(); michael@0: michael@0: void reset(); michael@0: void transform(const SkMatrix3D&, SkPatch3D* dst = NULL) const; michael@0: michael@0: // dot a unit vector with the patch's normal michael@0: SkScalar dotWith(SkScalar dx, SkScalar dy, SkScalar dz) const; michael@0: SkScalar dotWith(const SkVector3D& v) const { michael@0: return this->dotWith(v.fX, v.fY, v.fZ); michael@0: } michael@0: michael@0: // deprecated, but still here for animator (for now) michael@0: void rotate(SkScalar x, SkScalar y, SkScalar z) {} michael@0: void rotateDegrees(SkScalar x, SkScalar y, SkScalar z) {} michael@0: michael@0: private: michael@0: public: // make public for SkDraw3D for now michael@0: SkVector3D fU, fV; michael@0: SkPoint3D fOrigin; michael@0: michael@0: friend class SkCamera3D; michael@0: }; michael@0: michael@0: class SkCamera3D { michael@0: public: michael@0: SkCamera3D(); michael@0: michael@0: void reset(); michael@0: void update(); michael@0: void patchToMatrix(const SkPatch3D&, SkMatrix* matrix) const; michael@0: michael@0: SkPoint3D fLocation; michael@0: SkPoint3D fAxis; michael@0: SkPoint3D fZenith; michael@0: SkPoint3D fObserver; michael@0: michael@0: private: michael@0: mutable SkMatrix fOrientation; michael@0: mutable bool fNeedToUpdate; michael@0: michael@0: void doUpdate() const; michael@0: }; michael@0: michael@0: class Sk3DView : SkNoncopyable { michael@0: public: michael@0: Sk3DView(); michael@0: ~Sk3DView(); michael@0: michael@0: void save(); michael@0: void restore(); michael@0: michael@0: void translate(SkScalar x, SkScalar y, SkScalar z); michael@0: void rotateX(SkScalar deg); michael@0: void rotateY(SkScalar deg); michael@0: void rotateZ(SkScalar deg); michael@0: michael@0: #ifdef SK_BUILD_FOR_ANDROID michael@0: void setCameraLocation(SkScalar x, SkScalar y, SkScalar z); michael@0: SkScalar getCameraLocationX(); michael@0: SkScalar getCameraLocationY(); michael@0: SkScalar getCameraLocationZ(); michael@0: #endif michael@0: michael@0: void getMatrix(SkMatrix*) const; michael@0: void applyToCanvas(SkCanvas*) const; michael@0: michael@0: SkScalar dotWithNormal(SkScalar dx, SkScalar dy, SkScalar dz) const; michael@0: michael@0: private: michael@0: struct Rec { michael@0: Rec* fNext; michael@0: SkMatrix3D fMatrix; michael@0: }; michael@0: Rec* fRec; michael@0: Rec fInitialRec; michael@0: SkCamera3D fCamera; michael@0: }; michael@0: michael@0: #endif