blob: a2818bba19b150d6304773fd3ea22911eb440325 [file] [log] [blame]
Mike Reed27714a02018-05-30 16:02:48 -04001/*
2 * Copyright 2018 Google Inc.
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#include "gm.h"
9#include "Sk3D.h"
10#include "SkPath.h"
11#include "SkPoint3.h"
12
Mike Reed2f0edd52018-05-31 14:22:30 -040013#ifdef SK_ENABLE_SKOTTIE
14
15#include "SkAnimTimer.h"
16#include "Resources.h"
17#include "SkStream.h"
18#include "Skottie.h"
19
20static SkMatrix operator*(const SkMatrix& a, const SkMatrix& b) {
21 SkMatrix44 c;
22 c.setConcat(a, b);
23 return c;
24}
25
Mike Reed27714a02018-05-30 16:02:48 -040026class GM3d : public skiagm::GM {
27 float fNear = 0.5;
28 float fFar = 4;
29 float fAngle = SK_ScalarPI / 4;
30
31 SkPoint3 fEye { 0, 0, 4 };
32 SkPoint3 fCOA {0,0,0};//{ 0.5f, 0.5f, 0.5f };
33 SkPoint3 fUp { 0, 1, 0 };
34
Mike Reed27714a02018-05-30 16:02:48 -040035 SkPoint3 fP3[8];
Mike Reed2f0edd52018-05-31 14:22:30 -040036
37 sk_sp<skottie::Animation> fAnim;
38 SkScalar fAnimT = 0;
39
Mike Reed27714a02018-05-30 16:02:48 -040040public:
Mike Reed2f0edd52018-05-31 14:22:30 -040041 GM3d() {}
Mike Reed27714a02018-05-30 16:02:48 -040042 ~GM3d() override {}
43
44protected:
45 void onOnceBeforeDraw() override {
Florin Malita527a2972018-06-13 13:03:04 -040046 if (auto stream = GetResourceAsStream("skotty/skotty_sample_2.json")) {
47 fAnim = skottie::Animation::Make(stream.get());
48 }
Mike Reed2f0edd52018-05-31 14:22:30 -040049
Mike Reed27714a02018-05-30 16:02:48 -040050 int index = 0;
51 for (float x = 0; x <= 1; ++x) {
52 for (float y = 0; y <= 1; ++y) {
53 for (float z = 0; z <= 1; ++z) {
54 fP3[index++] = { x, y, z };
55 }
56 }
57 }
Mike Reed27714a02018-05-30 16:02:48 -040058 }
59
60 static void draw_viewport(SkCanvas* canvas, const SkMatrix& viewport) {
61 SkPaint p;
62 p.setColor(0x10FF0000);
63
64 canvas->save();
65 canvas->concat(viewport);
66 canvas->drawRect({-1, -1, 1, 1}, p);
67
68 p.setColor(0x80FF0000);
69 canvas->drawLine({-1, -1}, {1, 1}, p);
70 canvas->drawLine({1, -1}, {-1, 1}, p);
71 canvas->restore();
72 }
73
Mike Reed2f0edd52018-05-31 14:22:30 -040074 static void draw_skia(SkCanvas* canvas, const SkMatrix44& m4, const SkMatrix& vp,
75 skottie::Animation* anim) {
76 auto proc = [canvas, vp, anim](SkColor c, const SkMatrix44& m4) {
77 SkPaint p;
78 p.setColor(c);
79 SkRect r = { 0, 0, 1, 1 };
80 canvas->save();
81 canvas->concat(vp * SkMatrix(m4));
82 anim->render(canvas, &r);
83// canvas->drawRect({0, 0, 1, 1}, p);
84 canvas->restore();
85 };
86
87 SkMatrix44 tmp(SkMatrix44::kIdentity_Constructor);
88
89 proc(0x400000FF, m4);
90 tmp.setTranslate(0, 0, 1);
91 proc(0xC00000FF, m4 * tmp);
92 tmp.setRotateAboutUnit(1, 0, 0, SK_ScalarPI/2);
93 proc(0x4000FF00, m4 * tmp);
94 tmp.postTranslate(0, 1, 0);
95 proc(0xC000FF00, m4 * tmp);
96 tmp.setRotateAboutUnit(0, 1, 0, -SK_ScalarPI/2);
97 proc(0x40FF0000, m4 * tmp);
98 tmp.postTranslate(1, 0, 0);
99 proc(0xC0FF0000, m4 * tmp);
100 }
101
Mike Reed27714a02018-05-30 16:02:48 -0400102 void onDraw(SkCanvas* canvas) override {
Florin Malita527a2972018-06-13 13:03:04 -0400103 if (!fAnim) {
104 return;
105 }
Mike Reed27714a02018-05-30 16:02:48 -0400106 SkMatrix44 camera(SkMatrix44::kIdentity_Constructor),
107 perspective(SkMatrix44::kIdentity_Constructor),
Mike Reed2f0edd52018-05-31 14:22:30 -0400108 mv(SkMatrix44::kIdentity_Constructor);
Mike Reed27714a02018-05-30 16:02:48 -0400109 SkMatrix viewport;
110
111 {
112 float w = this->width();
113 float h = this->height();
114 float s = std::min(w, h);
115 viewport.setTranslate(1, -1);
116 viewport.postScale(s/2, -s/2);
117
118 draw_viewport(canvas, viewport);
119 }
120
121 Sk3Perspective(&perspective, fNear, fFar, fAngle);
122 Sk3LookAt(&camera, fEye, fCOA, fUp);
123 mv.postConcat(camera);
124 mv.postConcat(perspective);
125 SkPoint pts[8];
126 Sk3MapPts(pts, mv, fP3, 8);
127 viewport.mapPoints(pts, 8);
128
129 SkPaint paint;
130 paint.setStyle(SkPaint::kStroke_Style);
131
132 SkPath cube;
133
134 cube.moveTo(pts[0]);
135 cube.lineTo(pts[2]);
136 cube.lineTo(pts[6]);
137 cube.lineTo(pts[4]);
138 cube.close();
139
140 cube.moveTo(pts[1]);
141 cube.lineTo(pts[3]);
142 cube.lineTo(pts[7]);
143 cube.lineTo(pts[5]);
144 cube.close();
145
146 cube.moveTo(pts[0]); cube.lineTo(pts[1]);
147 cube.moveTo(pts[2]); cube.lineTo(pts[3]);
148 cube.moveTo(pts[4]); cube.lineTo(pts[5]);
149 cube.moveTo(pts[6]); cube.lineTo(pts[7]);
150
151 canvas->drawPath(cube, paint);
152
153 {
154 SkPoint3 src[4] = {
155 { 0, 0, 0 }, { 2, 0, 0 }, { 0, 2, 0 }, { 0, 0, 2 },
156 };
157 SkPoint dst[4];
158 mv.setConcat(perspective, camera);
159 Sk3MapPts(dst, mv, src, 4);
160 viewport.mapPoints(dst, 4);
161 const char str[] = "XYZ";
162 for (int i = 1; i <= 3; ++i) {
163 canvas->drawLine(dst[0], dst[i], paint);
164 }
165
166 for (int i = 1; i <= 3; ++i) {
167 canvas->drawText(&str[i-1], 1, dst[i].fX, dst[i].fY, paint);
168 }
169 }
Mike Reed2f0edd52018-05-31 14:22:30 -0400170
171 fAnim->seek(fAnimT);
172 draw_skia(canvas, mv, viewport, fAnim.get());
Mike Reed27714a02018-05-30 16:02:48 -0400173 }
174
175 SkISize onISize() override { return { 1024, 768 }; }
176
177 SkString onShortName() override { return SkString("3dgm"); }
178
Mike Reed2f0edd52018-05-31 14:22:30 -0400179 bool onAnimate(const SkAnimTimer& timer) override {
Jim Van Verth70276912018-06-01 13:46:46 -0400180 if (!fAnim) {
181 return false;
182 }
Mike Reed2f0edd52018-05-31 14:22:30 -0400183 SkScalar dur = fAnim->duration();
184 fAnimT = fmod(timer.secs(), dur) / dur;
185 return true;
186 }
Mike Reed27714a02018-05-30 16:02:48 -0400187 bool onHandleKey(SkUnichar uni) override {
188 switch (uni) {
189 case 'a': fEye.fX += 0.125f; return true;
190 case 'd': fEye.fX -= 0.125f; return true;
191 case 'w': fEye.fY += 0.125f; return true;
192 case 's': fEye.fY -= 0.125f; return true;
193 case 'q': fEye.fZ += 0.125f; return true;
194 case 'z': fEye.fZ -= 0.125f; return true;
195 default: break;
196 }
197 return false;
198 }
199
200 bool onGetControls(SkMetaData*) override { return false; }
201 void onSetControls(const SkMetaData&) override {
202
203 }
204};
205
206DEF_GM(return new GM3d;)
Mike Reed2f0edd52018-05-31 14:22:30 -0400207
208#endif
209