gfx/skia/trunk/src/utils/SkCamera.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /*
michael@0 2 * Copyright 2006 The Android Open Source Project
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license that can be
michael@0 5 * found in the LICENSE file.
michael@0 6 */
michael@0 7
michael@0 8 #include "SkCamera.h"
michael@0 9
michael@0 10 static SkScalar SkScalarDotDiv(int count, const SkScalar a[], int step_a,
michael@0 11 const SkScalar b[], int step_b,
michael@0 12 SkScalar denom) {
michael@0 13 SkScalar prod = 0;
michael@0 14 for (int i = 0; i < count; i++) {
michael@0 15 prod += a[0] * b[0];
michael@0 16 a += step_a;
michael@0 17 b += step_b;
michael@0 18 }
michael@0 19 return prod / denom;
michael@0 20 }
michael@0 21
michael@0 22 static SkScalar SkScalarDot(int count, const SkScalar a[], int step_a,
michael@0 23 const SkScalar b[], int step_b) {
michael@0 24 SkScalar prod = 0;
michael@0 25 for (int i = 0; i < count; i++) {
michael@0 26 prod += a[0] * b[0];
michael@0 27 a += step_a;
michael@0 28 b += step_b;
michael@0 29 }
michael@0 30 return prod;
michael@0 31 }
michael@0 32
michael@0 33 ///////////////////////////////////////////////////////////////////////////////
michael@0 34
michael@0 35 SkScalar SkPoint3D::normalize(SkUnit3D* unit) const {
michael@0 36 SkScalar mag = SkScalarSqrt(fX*fX + fY*fY + fZ*fZ);
michael@0 37 if (mag) {
michael@0 38 SkScalar scale = SkScalarInvert(mag);
michael@0 39 unit->fX = fX * scale;
michael@0 40 unit->fY = fY * scale;
michael@0 41 unit->fZ = fZ * scale;
michael@0 42 } else {
michael@0 43 unit->fX = unit->fY = unit->fZ = 0;
michael@0 44 }
michael@0 45 return mag;
michael@0 46 }
michael@0 47
michael@0 48 SkScalar SkUnit3D::Dot(const SkUnit3D& a, const SkUnit3D& b) {
michael@0 49 return a.fX * b.fX + a.fY * b.fY + a.fZ * b.fZ;
michael@0 50 }
michael@0 51
michael@0 52 void SkUnit3D::Cross(const SkUnit3D& a, const SkUnit3D& b, SkUnit3D* cross) {
michael@0 53 SkASSERT(cross);
michael@0 54
michael@0 55 // use x,y,z, in case &a == cross or &b == cross
michael@0 56
michael@0 57 SkScalar x = a.fY * b.fZ - a.fZ * b.fY;
michael@0 58 SkScalar y = a.fZ * b.fX - a.fX * b.fY;
michael@0 59 SkScalar z = a.fX * b.fY - a.fY * b.fX;
michael@0 60
michael@0 61 cross->set(x, y, z);
michael@0 62 }
michael@0 63
michael@0 64 ///////////////////////////////////////////////////////////////////////////////
michael@0 65
michael@0 66 SkPatch3D::SkPatch3D() {
michael@0 67 this->reset();
michael@0 68 }
michael@0 69
michael@0 70 void SkPatch3D::reset() {
michael@0 71 fOrigin.set(0, 0, 0);
michael@0 72 fU.set(SK_Scalar1, 0, 0);
michael@0 73 fV.set(0, -SK_Scalar1, 0);
michael@0 74 }
michael@0 75
michael@0 76 void SkPatch3D::transform(const SkMatrix3D& m, SkPatch3D* dst) const {
michael@0 77 if (dst == NULL) {
michael@0 78 dst = (SkPatch3D*)this;
michael@0 79 }
michael@0 80 m.mapVector(fU, &dst->fU);
michael@0 81 m.mapVector(fV, &dst->fV);
michael@0 82 m.mapPoint(fOrigin, &dst->fOrigin);
michael@0 83 }
michael@0 84
michael@0 85 SkScalar SkPatch3D::dotWith(SkScalar dx, SkScalar dy, SkScalar dz) const {
michael@0 86 SkScalar cx = SkScalarMul(fU.fY, fV.fZ) - SkScalarMul(fU.fZ, fV.fY);
michael@0 87 SkScalar cy = SkScalarMul(fU.fZ, fV.fX) - SkScalarMul(fU.fX, fV.fY);
michael@0 88 SkScalar cz = SkScalarMul(fU.fX, fV.fY) - SkScalarMul(fU.fY, fV.fX);
michael@0 89
michael@0 90 return SkScalarMul(cx, dx) + SkScalarMul(cy, dy) + SkScalarMul(cz, dz);
michael@0 91 }
michael@0 92
michael@0 93 ///////////////////////////////////////////////////////////////////////////////
michael@0 94
michael@0 95 void SkMatrix3D::reset() {
michael@0 96 memset(fMat, 0, sizeof(fMat));
michael@0 97 fMat[0][0] = fMat[1][1] = fMat[2][2] = SK_Scalar1;
michael@0 98 }
michael@0 99
michael@0 100 void SkMatrix3D::setTranslate(SkScalar x, SkScalar y, SkScalar z) {
michael@0 101 memset(fMat, 0, sizeof(fMat));
michael@0 102 fMat[0][0] = x;
michael@0 103 fMat[1][1] = y;
michael@0 104 fMat[2][2] = z;
michael@0 105 }
michael@0 106
michael@0 107 void SkMatrix3D::setRotateX(SkScalar degX) {
michael@0 108 SkScalar s, c;
michael@0 109
michael@0 110 s = SkScalarSinCos(SkDegreesToRadians(degX), &c);
michael@0 111 this->setRow(0, SK_Scalar1, 0, 0);
michael@0 112 this->setRow(1, 0, c, -s);
michael@0 113 this->setRow(2, 0, s, c);
michael@0 114 }
michael@0 115
michael@0 116 void SkMatrix3D::setRotateY(SkScalar degY) {
michael@0 117 SkScalar s, c;
michael@0 118
michael@0 119 s = SkScalarSinCos(SkDegreesToRadians(degY), &c);
michael@0 120 this->setRow(0, c, 0, -s);
michael@0 121 this->setRow(1, 0, SK_Scalar1, 0);
michael@0 122 this->setRow(2, s, 0, c);
michael@0 123 }
michael@0 124
michael@0 125 void SkMatrix3D::setRotateZ(SkScalar degZ) {
michael@0 126 SkScalar s, c;
michael@0 127
michael@0 128 s = SkScalarSinCos(SkDegreesToRadians(degZ), &c);
michael@0 129 this->setRow(0, c, -s, 0);
michael@0 130 this->setRow(1, s, c, 0);
michael@0 131 this->setRow(2, 0, 0, SK_Scalar1);
michael@0 132 }
michael@0 133
michael@0 134 void SkMatrix3D::preTranslate(SkScalar x, SkScalar y, SkScalar z) {
michael@0 135 SkScalar col[3] = { x, y, z};
michael@0 136
michael@0 137 for (int i = 0; i < 3; i++) {
michael@0 138 fMat[i][3] += SkScalarDot(3, &fMat[i][0], 1, col, 1);
michael@0 139 }
michael@0 140 }
michael@0 141
michael@0 142 void SkMatrix3D::preRotateX(SkScalar degX) {
michael@0 143 SkMatrix3D m;
michael@0 144 m.setRotateX(degX);
michael@0 145 this->setConcat(*this, m);
michael@0 146 }
michael@0 147
michael@0 148 void SkMatrix3D::preRotateY(SkScalar degY) {
michael@0 149 SkMatrix3D m;
michael@0 150 m.setRotateY(degY);
michael@0 151 this->setConcat(*this, m);
michael@0 152 }
michael@0 153
michael@0 154 void SkMatrix3D::preRotateZ(SkScalar degZ) {
michael@0 155 SkMatrix3D m;
michael@0 156 m.setRotateZ(degZ);
michael@0 157 this->setConcat(*this, m);
michael@0 158 }
michael@0 159
michael@0 160 void SkMatrix3D::setConcat(const SkMatrix3D& a, const SkMatrix3D& b) {
michael@0 161 SkMatrix3D tmp;
michael@0 162 SkMatrix3D* c = this;
michael@0 163
michael@0 164 if (this == &a || this == &b) {
michael@0 165 c = &tmp;
michael@0 166 }
michael@0 167 for (int i = 0; i < 3; i++) {
michael@0 168 for (int j = 0; j < 3; j++) {
michael@0 169 c->fMat[i][j] = SkScalarDot(3, &a.fMat[i][0], 1, &b.fMat[0][j], 4);
michael@0 170 }
michael@0 171 c->fMat[i][3] = SkScalarDot(3, &a.fMat[i][0], 1,
michael@0 172 &b.fMat[0][3], 4) + a.fMat[i][3];
michael@0 173 }
michael@0 174
michael@0 175 if (c == &tmp) {
michael@0 176 *this = tmp;
michael@0 177 }
michael@0 178 }
michael@0 179
michael@0 180 void SkMatrix3D::mapPoint(const SkPoint3D& src, SkPoint3D* dst) const {
michael@0 181 SkScalar x = SkScalarDot(3, &fMat[0][0], 1, &src.fX, 1) + fMat[0][3];
michael@0 182 SkScalar y = SkScalarDot(3, &fMat[1][0], 1, &src.fX, 1) + fMat[1][3];
michael@0 183 SkScalar z = SkScalarDot(3, &fMat[2][0], 1, &src.fX, 1) + fMat[2][3];
michael@0 184 dst->set(x, y, z);
michael@0 185 }
michael@0 186
michael@0 187 void SkMatrix3D::mapVector(const SkVector3D& src, SkVector3D* dst) const {
michael@0 188 SkScalar x = SkScalarDot(3, &fMat[0][0], 1, &src.fX, 1);
michael@0 189 SkScalar y = SkScalarDot(3, &fMat[1][0], 1, &src.fX, 1);
michael@0 190 SkScalar z = SkScalarDot(3, &fMat[2][0], 1, &src.fX, 1);
michael@0 191 dst->set(x, y, z);
michael@0 192 }
michael@0 193
michael@0 194 ///////////////////////////////////////////////////////////////////////////////
michael@0 195
michael@0 196 SkCamera3D::SkCamera3D() {
michael@0 197 this->reset();
michael@0 198 }
michael@0 199
michael@0 200 void SkCamera3D::reset() {
michael@0 201 fLocation.set(0, 0, -SkIntToScalar(576)); // 8 inches backward
michael@0 202 fAxis.set(0, 0, SK_Scalar1); // forward
michael@0 203 fZenith.set(0, -SK_Scalar1, 0); // up
michael@0 204
michael@0 205 fObserver.set(0, 0, fLocation.fZ);
michael@0 206
michael@0 207 fNeedToUpdate = true;
michael@0 208 }
michael@0 209
michael@0 210 void SkCamera3D::update() {
michael@0 211 fNeedToUpdate = true;
michael@0 212 }
michael@0 213
michael@0 214 void SkCamera3D::doUpdate() const {
michael@0 215 SkUnit3D axis, zenith, cross;
michael@0 216
michael@0 217 fAxis.normalize(&axis);
michael@0 218
michael@0 219 {
michael@0 220 SkScalar dot = SkUnit3D::Dot(*SkTCast<const SkUnit3D*>(&fZenith), axis);
michael@0 221
michael@0 222 zenith.fX = fZenith.fX - dot * axis.fX;
michael@0 223 zenith.fY = fZenith.fY - dot * axis.fY;
michael@0 224 zenith.fZ = fZenith.fZ - dot * axis.fZ;
michael@0 225
michael@0 226 SkTCast<SkPoint3D*>(&zenith)->normalize(&zenith);
michael@0 227 }
michael@0 228
michael@0 229 SkUnit3D::Cross(axis, zenith, &cross);
michael@0 230
michael@0 231 {
michael@0 232 SkMatrix* orien = &fOrientation;
michael@0 233 SkScalar x = fObserver.fX;
michael@0 234 SkScalar y = fObserver.fY;
michael@0 235 SkScalar z = fObserver.fZ;
michael@0 236
michael@0 237 orien->set(SkMatrix::kMScaleX, x * axis.fX - z * cross.fX);
michael@0 238 orien->set(SkMatrix::kMSkewX, x * axis.fY - z * cross.fY);
michael@0 239 orien->set(SkMatrix::kMTransX, x * axis.fZ - z * cross.fZ);
michael@0 240 orien->set(SkMatrix::kMSkewY, y * axis.fX - z * zenith.fX);
michael@0 241 orien->set(SkMatrix::kMScaleY, y * axis.fY - z * zenith.fY);
michael@0 242 orien->set(SkMatrix::kMTransY, y * axis.fZ - z * zenith.fZ);
michael@0 243 orien->set(SkMatrix::kMPersp0, axis.fX);
michael@0 244 orien->set(SkMatrix::kMPersp1, axis.fY);
michael@0 245 orien->set(SkMatrix::kMPersp2, axis.fZ);
michael@0 246 }
michael@0 247 }
michael@0 248
michael@0 249 void SkCamera3D::patchToMatrix(const SkPatch3D& quilt, SkMatrix* matrix) const {
michael@0 250 if (fNeedToUpdate) {
michael@0 251 this->doUpdate();
michael@0 252 fNeedToUpdate = false;
michael@0 253 }
michael@0 254
michael@0 255 const SkScalar* mapPtr = (const SkScalar*)(const void*)&fOrientation;
michael@0 256 const SkScalar* patchPtr;
michael@0 257 SkPoint3D diff;
michael@0 258 SkScalar dot;
michael@0 259
michael@0 260 diff.fX = quilt.fOrigin.fX - fLocation.fX;
michael@0 261 diff.fY = quilt.fOrigin.fY - fLocation.fY;
michael@0 262 diff.fZ = quilt.fOrigin.fZ - fLocation.fZ;
michael@0 263
michael@0 264 dot = SkUnit3D::Dot(*SkTCast<const SkUnit3D*>(&diff),
michael@0 265 *SkTCast<const SkUnit3D*>(SkTCast<const SkScalar*>(&fOrientation) + 6));
michael@0 266
michael@0 267 patchPtr = (const SkScalar*)&quilt;
michael@0 268 matrix->set(SkMatrix::kMScaleX, SkScalarDotDiv(3, patchPtr, 1, mapPtr, 1, dot));
michael@0 269 matrix->set(SkMatrix::kMSkewY, SkScalarDotDiv(3, patchPtr, 1, mapPtr+3, 1, dot));
michael@0 270 matrix->set(SkMatrix::kMPersp0, SkScalarDotDiv(3, patchPtr, 1, mapPtr+6, 1, dot));
michael@0 271
michael@0 272 patchPtr += 3;
michael@0 273 matrix->set(SkMatrix::kMSkewX, SkScalarDotDiv(3, patchPtr, 1, mapPtr, 1, dot));
michael@0 274 matrix->set(SkMatrix::kMScaleY, SkScalarDotDiv(3, patchPtr, 1, mapPtr+3, 1, dot));
michael@0 275 matrix->set(SkMatrix::kMPersp1, SkScalarDotDiv(3, patchPtr, 1, mapPtr+6, 1, dot));
michael@0 276
michael@0 277 patchPtr = (const SkScalar*)(const void*)&diff;
michael@0 278 matrix->set(SkMatrix::kMTransX, SkScalarDotDiv(3, patchPtr, 1, mapPtr, 1, dot));
michael@0 279 matrix->set(SkMatrix::kMTransY, SkScalarDotDiv(3, patchPtr, 1, mapPtr+3, 1, dot));
michael@0 280 matrix->set(SkMatrix::kMPersp2, SK_Scalar1);
michael@0 281 }
michael@0 282
michael@0 283 ///////////////////////////////////////////////////////////////////////////////
michael@0 284
michael@0 285 Sk3DView::Sk3DView() {
michael@0 286 fInitialRec.fMatrix.reset();
michael@0 287 fRec = &fInitialRec;
michael@0 288 }
michael@0 289
michael@0 290 Sk3DView::~Sk3DView() {
michael@0 291 Rec* rec = fRec;
michael@0 292 while (rec != &fInitialRec) {
michael@0 293 Rec* next = rec->fNext;
michael@0 294 SkDELETE(rec);
michael@0 295 rec = next;
michael@0 296 }
michael@0 297 }
michael@0 298
michael@0 299 void Sk3DView::save() {
michael@0 300 Rec* rec = SkNEW(Rec);
michael@0 301 rec->fNext = fRec;
michael@0 302 rec->fMatrix = fRec->fMatrix;
michael@0 303 fRec = rec;
michael@0 304 }
michael@0 305
michael@0 306 void Sk3DView::restore() {
michael@0 307 SkASSERT(fRec != &fInitialRec);
michael@0 308 Rec* next = fRec->fNext;
michael@0 309 SkDELETE(fRec);
michael@0 310 fRec = next;
michael@0 311 }
michael@0 312
michael@0 313 #ifdef SK_BUILD_FOR_ANDROID
michael@0 314 void Sk3DView::setCameraLocation(SkScalar x, SkScalar y, SkScalar z) {
michael@0 315 // the camera location is passed in inches, set in pt
michael@0 316 SkScalar lz = z * 72.0f;
michael@0 317 fCamera.fLocation.set(x * 72.0f, y * 72.0f, lz);
michael@0 318 fCamera.fObserver.set(0, 0, lz);
michael@0 319 fCamera.update();
michael@0 320
michael@0 321 }
michael@0 322
michael@0 323 SkScalar Sk3DView::getCameraLocationX() {
michael@0 324 return fCamera.fLocation.fX / 72.0f;
michael@0 325 }
michael@0 326
michael@0 327 SkScalar Sk3DView::getCameraLocationY() {
michael@0 328 return fCamera.fLocation.fY / 72.0f;
michael@0 329 }
michael@0 330
michael@0 331 SkScalar Sk3DView::getCameraLocationZ() {
michael@0 332 return fCamera.fLocation.fZ / 72.0f;
michael@0 333 }
michael@0 334 #endif
michael@0 335
michael@0 336 void Sk3DView::translate(SkScalar x, SkScalar y, SkScalar z) {
michael@0 337 fRec->fMatrix.preTranslate(x, y, z);
michael@0 338 }
michael@0 339
michael@0 340 void Sk3DView::rotateX(SkScalar deg) {
michael@0 341 fRec->fMatrix.preRotateX(deg);
michael@0 342 }
michael@0 343
michael@0 344 void Sk3DView::rotateY(SkScalar deg) {
michael@0 345 fRec->fMatrix.preRotateY(deg);
michael@0 346 }
michael@0 347
michael@0 348 void Sk3DView::rotateZ(SkScalar deg) {
michael@0 349 fRec->fMatrix.preRotateZ(deg);
michael@0 350 }
michael@0 351
michael@0 352 SkScalar Sk3DView::dotWithNormal(SkScalar x, SkScalar y, SkScalar z) const {
michael@0 353 SkPatch3D patch;
michael@0 354 patch.transform(fRec->fMatrix);
michael@0 355 return patch.dotWith(x, y, z);
michael@0 356 }
michael@0 357
michael@0 358 void Sk3DView::getMatrix(SkMatrix* matrix) const {
michael@0 359 if (matrix != NULL) {
michael@0 360 SkPatch3D patch;
michael@0 361 patch.transform(fRec->fMatrix);
michael@0 362 fCamera.patchToMatrix(patch, matrix);
michael@0 363 }
michael@0 364 }
michael@0 365
michael@0 366 #include "SkCanvas.h"
michael@0 367
michael@0 368 void Sk3DView::applyToCanvas(SkCanvas* canvas) const {
michael@0 369 SkMatrix matrix;
michael@0 370
michael@0 371 this->getMatrix(&matrix);
michael@0 372 canvas->concat(matrix);
michael@0 373 }

mercurial