| /* |
| * Copyright (C) 2006 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| |
| |
| // Inspired by Rob Johnson's most excellent QuickDraw GX sample code |
| |
| #ifndef SkCamera_DEFINED |
| #define SkCamera_DEFINED |
| |
| #include "Sk64.h" |
| #include "SkMatrix.h" |
| |
| class SkCanvas; |
| |
| #ifdef SK_SCALAR_IS_FIXED |
| typedef SkFract SkUnitScalar; |
| #define SK_UnitScalar1 SK_Fract1 |
| #define SkUnitScalarMul(a, b) SkFractMul(a, b) |
| #define SkUnitScalarDiv(a, b) SkFractDiv(a, b) |
| #else |
| typedef float SkUnitScalar; |
| #define SK_UnitScalar1 SK_Scalar1 |
| #define SkUnitScalarMul(a, b) SkScalarMul(a, b) |
| #define SkUnitScalarDiv(a, b) SkScalarDiv(a, b) |
| #endif |
| |
| struct SkUnit3D { |
| SkUnitScalar fX, fY, fZ; |
| |
| void set(SkUnitScalar x, SkUnitScalar y, SkUnitScalar z) |
| { |
| fX = x; fY = y; fZ = z; |
| } |
| static SkUnitScalar Dot(const SkUnit3D&, const SkUnit3D&); |
| static void Cross(const SkUnit3D&, const SkUnit3D&, SkUnit3D* cross); |
| }; |
| |
| struct SkPoint3D { |
| SkScalar fX, fY, fZ; |
| |
| void set(SkScalar x, SkScalar y, SkScalar z) |
| { |
| fX = x; fY = y; fZ = z; |
| } |
| SkScalar normalize(SkUnit3D*) const; |
| }; |
| typedef SkPoint3D SkVector3D; |
| |
| struct SkMatrix3D { |
| SkScalar fMat[3][4]; |
| |
| void reset(); |
| |
| void setRow(int row, SkScalar a, SkScalar b, SkScalar c, SkScalar d = 0) |
| { |
| SkASSERT((unsigned)row < 3); |
| fMat[row][0] = a; |
| fMat[row][1] = b; |
| fMat[row][2] = c; |
| fMat[row][3] = d; |
| } |
| |
| void setRotateX(SkScalar deg); |
| void setRotateY(SkScalar deg); |
| void setRotateZ(SkScalar deg); |
| void setTranslate(SkScalar x, SkScalar y, SkScalar z); |
| |
| void preRotateX(SkScalar deg); |
| void preRotateY(SkScalar deg); |
| void preRotateZ(SkScalar deg); |
| void preTranslate(SkScalar x, SkScalar y, SkScalar z); |
| |
| void setConcat(const SkMatrix3D& a, const SkMatrix3D& b); |
| void mapPoint(const SkPoint3D& src, SkPoint3D* dst) const; |
| void mapVector(const SkVector3D& src, SkVector3D* dst) const; |
| |
| void mapPoint(SkPoint3D* v) const |
| { |
| this->mapPoint(*v, v); |
| } |
| void mapVector(SkVector3D* v) const |
| { |
| this->mapVector(*v, v); |
| } |
| }; |
| |
| class SkPatch3D { |
| public: |
| SkPatch3D(); |
| |
| void reset(); |
| void transform(const SkMatrix3D&, SkPatch3D* dst = NULL) const; |
| |
| // dot a unit vector with the patch's normal |
| SkScalar dotWith(SkScalar dx, SkScalar dy, SkScalar dz) const; |
| SkScalar dotWith(const SkVector3D& v) const |
| { |
| return this->dotWith(v.fX, v.fY, v.fZ); |
| } |
| |
| // depreicated, but still here for animator (for now) |
| void rotate(SkScalar x, SkScalar y, SkScalar z) {} |
| void rotateDegrees(SkScalar x, SkScalar y, SkScalar z) {} |
| |
| private: |
| public: // make public for SkDraw3D for now |
| SkVector3D fU, fV; |
| SkPoint3D fOrigin; |
| |
| friend class SkCamera3D; |
| }; |
| |
| class SkCamera3D { |
| public: |
| SkCamera3D(); |
| |
| void reset(); |
| void update(); |
| void patchToMatrix(const SkPatch3D&, SkMatrix* matrix) const; |
| |
| SkPoint3D fLocation; |
| SkPoint3D fAxis; |
| SkPoint3D fZenith; |
| SkPoint3D fObserver; |
| |
| private: |
| mutable SkMatrix fOrientation; |
| mutable bool fNeedToUpdate; |
| |
| void doUpdate() const; |
| }; |
| |
| class Sk3DView : SkNoncopyable { |
| public: |
| Sk3DView(); |
| ~Sk3DView(); |
| |
| void save(); |
| void restore(); |
| |
| void translate(SkScalar x, SkScalar y, SkScalar z); |
| void rotateX(SkScalar deg); |
| void rotateY(SkScalar deg); |
| void rotateZ(SkScalar deg); |
| |
| void getMatrix(SkMatrix*) const; |
| void applyToCanvas(SkCanvas*) const; |
| |
| SkScalar dotWithNormal(SkScalar dx, SkScalar dy, SkScalar dz) const; |
| |
| private: |
| struct Rec { |
| Rec* fNext; |
| SkMatrix3D fMatrix; |
| }; |
| Rec* fRec; |
| Rec fInitialRec; |
| SkCamera3D fCamera; |
| }; |
| |
| #endif |
| |