4429a4f82c
It's been driving me nuts that I can't just write `SkMatrix44 m;`, and I often don't care whether it's initialized or not. The default identity constructor would be nice to use, but it's deprecated. By tagging this constructor deprecated, we're only hurting ourselves; our big clients disable warnings about deprecated routines and use it freely. A quick tally in Skia shows we mostly use the uninitialized constructor, but sometimes the identity constructor, and there is a spread of all three in Chromium. So I've left the two explicit calls available. I switched a bunch of calls in Skia to use the less verbose constructor where it was clear that it didn't matter if the matrix was initialized. Literally zero of the kUninitialized constructor calls looked important for performance, so the only place I've kept is its lone unit test. A few places read clearer with an explicit "identity" to read. Change-Id: I0573cb6201f5a36f3b43070fb111f7d9af92736f Reviewed-on: https://skia-review.googlesource.com/c/159480 Reviewed-by: Brian Osman <brianosman@google.com>
210 lines
5.5 KiB
C++
210 lines
5.5 KiB
C++
/*
|
|
* Copyright 2018 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include "gm.h"
|
|
#include "Sk3D.h"
|
|
#include "SkPath.h"
|
|
#include "SkPoint3.h"
|
|
|
|
#ifdef SK_ENABLE_SKOTTIE
|
|
|
|
#include "SkAnimTimer.h"
|
|
#include "Resources.h"
|
|
#include "SkStream.h"
|
|
#include "Skottie.h"
|
|
|
|
static SkMatrix operator*(const SkMatrix& a, const SkMatrix& b) {
|
|
SkMatrix44 c;
|
|
c.setConcat(a, b);
|
|
return c;
|
|
}
|
|
|
|
class GM3d : public skiagm::GM {
|
|
float fNear = 0.5;
|
|
float fFar = 4;
|
|
float fAngle = SK_ScalarPI / 4;
|
|
|
|
SkPoint3 fEye { 0, 0, 4 };
|
|
SkPoint3 fCOA {0,0,0};//{ 0.5f, 0.5f, 0.5f };
|
|
SkPoint3 fUp { 0, 1, 0 };
|
|
|
|
SkPoint3 fP3[8];
|
|
|
|
sk_sp<skottie::Animation> fAnim;
|
|
SkScalar fAnimT = 0;
|
|
|
|
public:
|
|
GM3d() {}
|
|
~GM3d() override {}
|
|
|
|
protected:
|
|
void onOnceBeforeDraw() override {
|
|
if (auto stream = GetResourceAsStream("skottie/skottie_sample_2.json")) {
|
|
fAnim = skottie::Animation::Make(stream.get());
|
|
}
|
|
|
|
int index = 0;
|
|
for (float x = 0; x <= 1; ++x) {
|
|
for (float y = 0; y <= 1; ++y) {
|
|
for (float z = 0; z <= 1; ++z) {
|
|
fP3[index++] = { x, y, z };
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void draw_viewport(SkCanvas* canvas, const SkMatrix& viewport) {
|
|
SkPaint p;
|
|
p.setColor(0x10FF0000);
|
|
|
|
canvas->save();
|
|
canvas->concat(viewport);
|
|
canvas->drawRect({-1, -1, 1, 1}, p);
|
|
|
|
p.setColor(0x80FF0000);
|
|
canvas->drawLine({-1, -1}, {1, 1}, p);
|
|
canvas->drawLine({1, -1}, {-1, 1}, p);
|
|
canvas->restore();
|
|
}
|
|
|
|
static void draw_skia(SkCanvas* canvas, const SkMatrix44& m4, const SkMatrix& vp,
|
|
skottie::Animation* anim) {
|
|
auto proc = [canvas, vp, anim](SkColor c, const SkMatrix44& m4) {
|
|
SkPaint p;
|
|
p.setColor(c);
|
|
SkRect r = { 0, 0, 1, 1 };
|
|
canvas->save();
|
|
canvas->concat(vp * SkMatrix(m4));
|
|
anim->render(canvas, &r);
|
|
// canvas->drawRect({0, 0, 1, 1}, p);
|
|
canvas->restore();
|
|
};
|
|
|
|
SkMatrix44 tmp;
|
|
|
|
proc(0x400000FF, m4);
|
|
tmp.setTranslate(0, 0, 1);
|
|
proc(0xC00000FF, m4 * tmp);
|
|
tmp.setRotateAboutUnit(1, 0, 0, SK_ScalarPI/2);
|
|
proc(0x4000FF00, m4 * tmp);
|
|
tmp.postTranslate(0, 1, 0);
|
|
proc(0xC000FF00, m4 * tmp);
|
|
tmp.setRotateAboutUnit(0, 1, 0, -SK_ScalarPI/2);
|
|
proc(0x40FF0000, m4 * tmp);
|
|
tmp.postTranslate(1, 0, 0);
|
|
proc(0xC0FF0000, m4 * tmp);
|
|
}
|
|
|
|
void onDraw(SkCanvas* canvas) override {
|
|
if (!fAnim) {
|
|
return;
|
|
}
|
|
SkMatrix44 camera,
|
|
perspective,
|
|
mv;
|
|
SkMatrix viewport;
|
|
|
|
{
|
|
float w = this->width();
|
|
float h = this->height();
|
|
float s = std::min(w, h);
|
|
viewport.setTranslate(1, -1);
|
|
viewport.postScale(s/2, -s/2);
|
|
|
|
draw_viewport(canvas, viewport);
|
|
}
|
|
|
|
Sk3Perspective(&perspective, fNear, fFar, fAngle);
|
|
Sk3LookAt(&camera, fEye, fCOA, fUp);
|
|
mv.postConcat(camera);
|
|
mv.postConcat(perspective);
|
|
SkPoint pts[8];
|
|
Sk3MapPts(pts, mv, fP3, 8);
|
|
viewport.mapPoints(pts, 8);
|
|
|
|
SkPaint paint;
|
|
paint.setStyle(SkPaint::kStroke_Style);
|
|
|
|
SkPath cube;
|
|
|
|
cube.moveTo(pts[0]);
|
|
cube.lineTo(pts[2]);
|
|
cube.lineTo(pts[6]);
|
|
cube.lineTo(pts[4]);
|
|
cube.close();
|
|
|
|
cube.moveTo(pts[1]);
|
|
cube.lineTo(pts[3]);
|
|
cube.lineTo(pts[7]);
|
|
cube.lineTo(pts[5]);
|
|
cube.close();
|
|
|
|
cube.moveTo(pts[0]); cube.lineTo(pts[1]);
|
|
cube.moveTo(pts[2]); cube.lineTo(pts[3]);
|
|
cube.moveTo(pts[4]); cube.lineTo(pts[5]);
|
|
cube.moveTo(pts[6]); cube.lineTo(pts[7]);
|
|
|
|
canvas->drawPath(cube, paint);
|
|
|
|
{
|
|
SkPoint3 src[4] = {
|
|
{ 0, 0, 0 }, { 2, 0, 0 }, { 0, 2, 0 }, { 0, 0, 2 },
|
|
};
|
|
SkPoint dst[4];
|
|
mv.setConcat(perspective, camera);
|
|
Sk3MapPts(dst, mv, src, 4);
|
|
viewport.mapPoints(dst, 4);
|
|
const char str[] = "XYZ";
|
|
for (int i = 1; i <= 3; ++i) {
|
|
canvas->drawLine(dst[0], dst[i], paint);
|
|
}
|
|
|
|
for (int i = 1; i <= 3; ++i) {
|
|
canvas->drawText(&str[i-1], 1, dst[i].fX, dst[i].fY, paint);
|
|
}
|
|
}
|
|
|
|
fAnim->seek(fAnimT);
|
|
draw_skia(canvas, mv, viewport, fAnim.get());
|
|
}
|
|
|
|
SkISize onISize() override { return { 1024, 768 }; }
|
|
|
|
SkString onShortName() override { return SkString("3dgm"); }
|
|
|
|
bool onAnimate(const SkAnimTimer& timer) override {
|
|
if (!fAnim) {
|
|
return false;
|
|
}
|
|
SkScalar dur = fAnim->duration();
|
|
fAnimT = fmod(timer.secs(), dur) / dur;
|
|
return true;
|
|
}
|
|
bool onHandleKey(SkUnichar uni) override {
|
|
switch (uni) {
|
|
case 'a': fEye.fX += 0.125f; return true;
|
|
case 'd': fEye.fX -= 0.125f; return true;
|
|
case 'w': fEye.fY += 0.125f; return true;
|
|
case 's': fEye.fY -= 0.125f; return true;
|
|
case 'q': fEye.fZ += 0.125f; return true;
|
|
case 'z': fEye.fZ -= 0.125f; return true;
|
|
default: break;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool onGetControls(SkMetaData*) override { return false; }
|
|
void onSetControls(const SkMetaData&) override {
|
|
|
|
}
|
|
};
|
|
|
|
DEF_GM(return new GM3d;)
|
|
|
|
#endif
|
|
|