36float lerp(
float a,
float b,
float t) {
52static constexpr struct ShaderFactory {
55} gShaderFactories[] = {
84static constexpr struct VertexAnimator {
86 void (*fAanimate)(
const std::vector<SkPoint>& uv,
float t, std::vector<SkPoint>&
out);
87} gVertexAnimators[] = {
91 [](
const std::vector<SkPoint>& uvs,
float t, std::vector<SkPoint>&
out) {
92 static constexpr float kCylRadius = .2f;
94 const auto cyl_pos = t;
96 for (
size_t i = 0;
i < uvs.size(); ++
i) {
97 const auto& uv = uvs[
i];
99 if (uv.fX <= cyl_pos) {
104 const auto arc_len = uv.fX - cyl_pos,
105 arc_ang = arc_len/kCylRadius;
108 cyl_pos + std::sin(arc_ang)*kCylRadius,
118 [](
const std::vector<SkPoint>& uvs,
float t, std::vector<SkPoint>&
out) {
119 for (
size_t i = 0;
i < uvs.size(); ++
i) {
121 const auto uv = (uvs[
i] -
SkPoint{0.5,0.5});
126 const auto s =
lerp(1, (0.5f /
d), t);
135 [](
const std::vector<SkPoint>& uvs,
float t, std::vector<SkPoint>&
out) {
136 static constexpr float kMaxRotate =
SK_FloatPI*4;
138 for (
size_t i = 0;
i < uvs.size(); ++
i) {
140 const auto uv = (uvs[
i] -
SkPoint{0.5,0.5});
141 const auto angle = kMaxRotate * t * uv.length();
149 [](
const std::vector<SkPoint>& uvs,
float t, std::vector<SkPoint>&
out) {
150 const float radius = t*0.2f/(
std::sqrt(uvs.size()) - 1);
151 for (
size_t i = 0;
i < uvs.size(); ++
i) {
155 radius*std::cos(angle),
156 radius*std::sin(angle),
163 [](
const std::vector<SkPoint>& uvs,
float, std::vector<SkPoint>&
out) {
out = uvs; },
167class MeshSlide final :
public Slide {
169 MeshSlide() : fTimeMapper({0.5f, 0}, {0.5f, 1}) {
fName =
"Mesh"; }
175 this->initShader(gShaderFactories[0]);
184 p.setAntiAlias(
true);
187 static constexpr float kMeshFraction = 0.85f;
188 const float mesh_size =
std::min(fSize.fWidth, fSize.fHeight)*kMeshFraction;
190 canvas->
translate((fSize.fWidth - mesh_size) * 0.5f,
191 (fSize.fHeight - mesh_size) * 0.5f);
192 canvas->
scale(mesh_size, mesh_size);
197 fShader ? fUVs.data() :
nullptr,
198 fShader ?
nullptr : fColors.data(),
201 p.setShader(fShader);
205 p.setShader(
nullptr);
208 p.setStrokeWidth(0.5f/mesh_size);
211 for (
auto i = fIndices.cbegin();
i < fIndices.cend();
i += 6) {
212 canvas->
drawLine(fVertices[
i[0]], fVertices[
i[1]],
p);
213 canvas->
drawLine(fVertices[
i[1]], fVertices[
i[2]],
p);
214 canvas->
drawLine(fVertices[
i[2]], fVertices[
i[0]],
p);
215 canvas->
drawLine(fVertices[
i[3]], fVertices[
i[4]],
p);
216 canvas->
drawLine(fVertices[
i[4]], fVertices[
i[5]],
p);
217 canvas->
drawLine(fVertices[
i[5]], fVertices[
i[3]],
p);
221 p.setStrokeWidth(5/mesh_size);
225 this->drawControls();
228 bool animate(
double nanos)
override {
235 std::abs((std::fmod((nanos - fTimeBase)*0.000000001*fAnimationSpeed, 2) - 1));
238 fCurrentAnimator->fAanimate(fUVs, fTimeMapper.computeYFromX(t), fVertices);
244 void initMesh(
size_t vertex_count) {
247 const auto n =
static_cast<size_t>(
std::sqrt(vertex_count));
251 fVertices.resize(vertex_count);
252 fUVs.resize(vertex_count);
253 fColors.resize(vertex_count);
254 for (
size_t i = 0;
i < vertex_count; ++
i) {
255 fVertices[
i] = fUVs[
i] = {
256 static_cast<float>(
i % n) / (n - 1),
257 static_cast<float>(
i / n) / (n - 1),
275 const size_t triangle_count = 2*(n - 1)*(n - 1),
276 index_count = 3*triangle_count;
279 fIndices.reserve(index_count);
280 for (
size_t i = 0;
i < n - 1; ++
i) {
281 for (
size_t j = 0; j < n - 1; ++j) {
282 const auto row_0_idx = j*n +
i,
283 row_1_idx = row_0_idx + n,
287 fIndices.push_back(row_0_idx + 0);
288 fIndices.push_back(row_0_idx + 1);
289 fIndices.push_back(row_1_idx + off_0);
291 fIndices.push_back(row_0_idx + off_1);
292 fIndices.push_back(row_1_idx + 1);
293 fIndices.push_back(row_1_idx + 0);
297 SkASSERT(fIndices.size() == index_count);
300 void initShader(
const ShaderFactory& fact) {
301 fShader = fact.fBuild();
302 fCurrentShaderFactory = &fact;
305 void drawControls() {
306 ImGui::Begin(
"Mesh Options");
308 if (ImGui::BeginCombo(
"Texture", fCurrentShaderFactory->fName)) {
309 for (
const auto& fact : gShaderFactories) {
310 const auto is_selected = (fCurrentShaderFactory->fName == fact.fName);
311 if (ImGui::Selectable(fact.fName) && !is_selected) {
312 this->initShader(fact);
315 ImGui::SetItemDefaultFocus();
321 if (ImGui::BeginCombo(
"Animator", fCurrentAnimator->fName)) {
322 for (
const auto& anim : gVertexAnimators) {
323 const auto is_selected = (fCurrentAnimator->fName == anim.fName);
324 if (ImGui::Selectable(anim.fName) && !is_selected) {
325 fCurrentAnimator = &anim;
329 ImGui::SetItemDefaultFocus();
335 static constexpr struct {
344 {
"128x128", 16384 },
346 ImGui::SliderInt(
"Mesh Size",
349 gSizeInfo[fMeshSizeSelector].fLabel);
350 if (fVertices.size() != gSizeInfo[fMeshSizeSelector].fCount) {
351 this->initMesh(gSizeInfo[fMeshSizeSelector].
fCount);
354 ImGui::SliderFloat(
"Speed", &fAnimationSpeed, 0.25, 4,
"%.2f");
356 ImGui::Checkbox(
"Show mesh", &fShowMesh);
363 std::vector<SkPoint> fVertices,
365 std::vector<SkColor> fColors;
366 std::vector<uint16_t> fIndices;
368 double fTimeBase = 0;
372 const ShaderFactory* fCurrentShaderFactory = &gShaderFactories[0];
373 const VertexAnimator* fCurrentAnimator = &gVertexAnimators[0];
374 int fMeshSizeSelector = 2;
375 float fAnimationSpeed = 1.f;
376 bool fShowMesh =
false;
SkPoint lerp(const SkPoint &a, const SkPoint &b, float t)
static const SkColor gColors[]
#define SkColorSetRGB(r, g, b)
constexpr SkColor SK_ColorBLUE
constexpr SkColor SK_ColorRED
constexpr SkColor SK_ColorGREEN
constexpr SkColor SK_ColorWHITE
constexpr float SK_FloatPI
static SkString resource(SkPDFResourceType type, int index)
static SkPDFIndirectReference make_image_shader(SkPDFDocument *doc, SkMatrix finalMatrix, SkTileMode tileModesX, SkTileMode tileModesY, SkRect bBox, const SkImage *image, SkColor4f paintColor)
void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint &paint)
void translate(SkScalar dx, SkScalar dy)
void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint &paint)
void scale(SkScalar sx, SkScalar sy)
void drawVertices(const SkVertices *vertices, SkBlendMode mode, const SkPaint &paint)
@ kPoints_PointMode
draw each point separately
static sk_sp< SkShader > MakeRadial(const SkPoint ¢er, SkScalar radius, const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, uint32_t flags=0, const SkMatrix *localMatrix=nullptr)
sk_sp< SkShader > makeShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions &, const SkMatrix *localMatrix=nullptr) const
static SkMatrix Scale(SkScalar sx, SkScalar sy)
static SkMatrix RotateRad(SkScalar rad)
SkPoint mapPoint(SkPoint pt) const
static sk_sp< SkVertices > MakeCopy(VertexMode mode, int vertexCount, const SkPoint positions[], const SkPoint texs[], const SkColor colors[], int indexCount, const uint16_t indices[])
virtual void resize(SkScalar winWidth, SkScalar winHeight)
virtual void load(SkScalar winWidth, SkScalar winHeight)
virtual bool animate(double nanos)
virtual void draw(SkCanvas *canvas)=0
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
static float max(float r, float g, float b)
static float min(float r, float g, float b)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
SkSamplingOptions(SkFilterMode::kLinear))
SIN Vec< N, float > abs(const Vec< N, float > &x)
SIN Vec< N, float > sqrt(const Vec< N, float > &x)