Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2019 Google LLC
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
2019-04-23 17:05:21 +00:00
|
|
|
#include "tools/viewer/ParticlesSlide.h"
|
|
|
|
|
2020-03-30 19:57:14 +00:00
|
|
|
#include "include/core/SkCanvas.h"
|
2019-04-23 17:05:21 +00:00
|
|
|
#include "modules/particles/include/SkParticleEffect.h"
|
|
|
|
#include "modules/particles/include/SkParticleSerialization.h"
|
|
|
|
#include "modules/particles/include/SkReflected.h"
|
2019-11-27 15:34:18 +00:00
|
|
|
#include "modules/skresources/include/SkResources.h"
|
2019-04-23 17:05:21 +00:00
|
|
|
#include "src/core/SkOSFile.h"
|
2021-01-20 19:01:30 +00:00
|
|
|
#include "src/sksl/SkSLVMGenerator.h"
|
2019-04-23 17:05:21 +00:00
|
|
|
#include "src/utils/SkOSPath.h"
|
|
|
|
#include "tools/Resources.h"
|
2020-12-07 15:07:27 +00:00
|
|
|
#include "tools/ToolUtils.h"
|
2019-04-23 17:05:21 +00:00
|
|
|
#include "tools/viewer/ImGuiLayer.h"
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
|
|
|
|
#include "imgui.h"
|
|
|
|
|
2020-12-07 15:07:27 +00:00
|
|
|
#include <string>
|
|
|
|
#include <unordered_map>
|
|
|
|
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
using namespace sk_app;
|
|
|
|
|
2020-12-07 15:07:27 +00:00
|
|
|
class TestingResourceProvider : public skresources::ResourceProvider {
|
|
|
|
public:
|
|
|
|
TestingResourceProvider() {}
|
|
|
|
|
|
|
|
sk_sp<SkData> load(const char resource_path[], const char resource_name[]) const override {
|
|
|
|
auto it = fResources.find(resource_name);
|
|
|
|
if (it != fResources.end()) {
|
|
|
|
return it->second;
|
|
|
|
} else {
|
|
|
|
return GetResourceAsData(SkOSPath::Join(resource_path, resource_name).c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sk_sp<skresources::ImageAsset> loadImageAsset(const char resource_path[],
|
|
|
|
const char resource_name[],
|
|
|
|
const char /*resource_id*/[]) const override {
|
|
|
|
auto data = this->load(resource_path, resource_name);
|
|
|
|
return skresources::MultiFrameImageAsset::Make(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void addPath(const char resource_name[], const SkPath& path) {
|
|
|
|
fResources[resource_name] = path.serialize();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
std::unordered_map<std::string, sk_sp<SkData>> fResources;
|
|
|
|
};
|
|
|
|
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
static int InputTextCallback(ImGuiInputTextCallbackData* data) {
|
|
|
|
if (data->EventFlag == ImGuiInputTextFlags_CallbackResize) {
|
|
|
|
SkString* s = (SkString*)data->UserData;
|
|
|
|
SkASSERT(data->Buf == s->writable_str());
|
|
|
|
SkString tmp(data->Buf, data->BufTextLen);
|
|
|
|
s->swap(tmp);
|
|
|
|
data->Buf = s->writable_str();
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-05-08 14:41:42 +00:00
|
|
|
static int count_lines(const SkString& s) {
|
|
|
|
int lines = 1;
|
|
|
|
for (size_t i = 0; i < s.size(); ++i) {
|
|
|
|
if (s[i] == '\n') {
|
|
|
|
++lines;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return lines;
|
|
|
|
}
|
|
|
|
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
class SkGuiVisitor : public SkFieldVisitor {
|
|
|
|
public:
|
|
|
|
SkGuiVisitor() {
|
|
|
|
fTreeStack.push_back(true);
|
|
|
|
}
|
|
|
|
|
2019-02-19 15:45:56 +00:00
|
|
|
void visit(const char* name, float& f) override {
|
2019-12-02 21:52:51 +00:00
|
|
|
fDirty = (fTreeStack.back() && ImGui::DragFloat(item(name), &f)) || fDirty;
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
}
|
2019-02-19 15:45:56 +00:00
|
|
|
void visit(const char* name, int& i) override {
|
2019-12-02 21:52:51 +00:00
|
|
|
fDirty = (fTreeStack.back() && ImGui::DragInt(item(name), &i)) || fDirty;
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
}
|
2019-02-19 15:45:56 +00:00
|
|
|
void visit(const char* name, bool& b) override {
|
2019-12-02 21:52:51 +00:00
|
|
|
fDirty = (fTreeStack.back() && ImGui::Checkbox(item(name), &b)) || fDirty;
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
}
|
2019-12-02 21:52:51 +00:00
|
|
|
|
2019-02-19 15:45:56 +00:00
|
|
|
void visit(const char* name, SkString& s) override {
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
if (fTreeStack.back()) {
|
2019-05-08 14:41:42 +00:00
|
|
|
int lines = count_lines(s);
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
ImGuiInputTextFlags flags = ImGuiInputTextFlags_CallbackResize;
|
2019-05-08 14:41:42 +00:00
|
|
|
if (lines > 1) {
|
2019-09-12 20:25:52 +00:00
|
|
|
ImGui::LabelText("##Label", "%s", name);
|
2019-05-08 14:41:42 +00:00
|
|
|
ImVec2 boxSize(-1.0f, ImGui::GetTextLineHeight() * (lines + 1));
|
2019-12-02 21:52:51 +00:00
|
|
|
fDirty = ImGui::InputTextMultiline(item(name), s.writable_str(), s.size() + 1,
|
|
|
|
boxSize, flags, InputTextCallback, &s)
|
|
|
|
|| fDirty;
|
2019-05-08 14:41:42 +00:00
|
|
|
} else {
|
2019-12-02 21:52:51 +00:00
|
|
|
fDirty = ImGui::InputText(item(name), s.writable_str(), s.size() + 1, flags,
|
|
|
|
InputTextCallback, &s)
|
|
|
|
|| fDirty;
|
2019-05-08 14:41:42 +00:00
|
|
|
}
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
}
|
|
|
|
}
|
2019-02-14 18:23:51 +00:00
|
|
|
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
void visit(sk_sp<SkReflected>& e, const SkReflected::Type* baseType) override {
|
|
|
|
if (fTreeStack.back()) {
|
|
|
|
const SkReflected::Type* curType = e ? e->getType() : nullptr;
|
|
|
|
if (ImGui::BeginCombo("Type", curType ? curType->fName : "Null")) {
|
2019-12-02 21:52:51 +00:00
|
|
|
auto visitType = [baseType, curType, &e, this](const SkReflected::Type* t) {
|
2019-03-06 16:08:48 +00:00
|
|
|
if (t->fFactory && (t == baseType || t->isDerivedFrom(baseType)) &&
|
|
|
|
ImGui::Selectable(t->fName, curType == t)) {
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
e = t->fFactory();
|
2019-12-02 21:52:51 +00:00
|
|
|
fDirty = true;
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
}
|
|
|
|
};
|
2019-03-06 16:08:48 +00:00
|
|
|
SkReflected::VisitTypes(visitType);
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
ImGui::EndCombo();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void enterObject(const char* name) override {
|
|
|
|
if (fTreeStack.back()) {
|
2019-02-14 18:23:51 +00:00
|
|
|
fTreeStack.push_back(ImGui::TreeNodeEx(item(name),
|
|
|
|
ImGuiTreeNodeFlags_AllowItemOverlap));
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
} else {
|
|
|
|
fTreeStack.push_back(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void exitObject() override {
|
|
|
|
if (fTreeStack.back()) {
|
|
|
|
ImGui::TreePop();
|
|
|
|
}
|
|
|
|
fTreeStack.pop_back();
|
|
|
|
}
|
|
|
|
|
2019-02-14 18:23:51 +00:00
|
|
|
int enterArray(const char* name, int oldCount) override {
|
|
|
|
this->enterObject(item(name));
|
|
|
|
fArrayCounterStack.push_back(0);
|
|
|
|
fArrayEditStack.push_back();
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
|
2019-02-14 18:23:51 +00:00
|
|
|
int count = oldCount;
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
if (fTreeStack.back()) {
|
2019-02-14 18:23:51 +00:00
|
|
|
ImGui::SameLine();
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
if (ImGui::Button("+")) {
|
2019-02-14 18:23:51 +00:00
|
|
|
++count;
|
2019-12-02 21:52:51 +00:00
|
|
|
fDirty = true;
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
}
|
|
|
|
}
|
2019-02-14 18:23:51 +00:00
|
|
|
return count;
|
|
|
|
}
|
|
|
|
ArrayEdit exitArray() override {
|
|
|
|
fArrayCounterStack.pop_back();
|
|
|
|
auto edit = fArrayEditStack.back();
|
|
|
|
fArrayEditStack.pop_back();
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
this->exitObject();
|
2019-02-14 18:23:51 +00:00
|
|
|
return edit;
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
}
|
|
|
|
|
2019-12-02 21:52:51 +00:00
|
|
|
bool fDirty = false;
|
|
|
|
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
private:
|
2019-02-14 18:23:51 +00:00
|
|
|
const char* item(const char* name) {
|
|
|
|
if (name) {
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We're in an array. Add extra controls and a dynamic label.
|
|
|
|
int index = fArrayCounterStack.back()++;
|
|
|
|
ArrayEdit& edit(fArrayEditStack.back());
|
|
|
|
fScratchLabel = SkStringPrintf("[%d]", index);
|
|
|
|
|
|
|
|
ImGui::PushID(index);
|
|
|
|
|
|
|
|
if (ImGui::Button("X")) {
|
|
|
|
edit.fVerb = ArrayEdit::Verb::kRemove;
|
|
|
|
edit.fIndex = index;
|
2019-12-02 21:52:51 +00:00
|
|
|
fDirty = true;
|
2019-02-14 18:23:51 +00:00
|
|
|
}
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
|
|
|
ImGui::PopID();
|
|
|
|
|
|
|
|
return fScratchLabel.c_str();
|
|
|
|
}
|
|
|
|
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
SkSTArray<16, bool, true> fTreeStack;
|
2019-02-14 18:23:51 +00:00
|
|
|
SkSTArray<16, int, true> fArrayCounterStack;
|
|
|
|
SkSTArray<16, ArrayEdit, true> fArrayEditStack;
|
|
|
|
SkString fScratchLabel;
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
ParticlesSlide::ParticlesSlide() {
|
|
|
|
// Register types for serialization
|
2019-08-30 14:59:47 +00:00
|
|
|
SkParticleEffect::RegisterParticleTypes();
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
fName = "Particles";
|
2020-12-07 15:07:27 +00:00
|
|
|
auto provider = sk_make_sp<TestingResourceProvider>();
|
|
|
|
SkPath star = ToolUtils::make_star({ 0, 0, 100, 100 }, 5);
|
|
|
|
star.close();
|
|
|
|
provider->addPath("star", star);
|
|
|
|
fResourceProvider = provider;
|
2019-03-06 16:08:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ParticlesSlide::loadEffects(const char* dirname) {
|
|
|
|
fLoaded.reset();
|
|
|
|
fRunning.reset();
|
|
|
|
SkOSFile::Iter iter(dirname, ".json");
|
|
|
|
for (SkString file; iter.next(&file); ) {
|
|
|
|
LoadedEffect effect;
|
|
|
|
effect.fName = SkOSPath::Join(dirname, file.c_str());
|
|
|
|
effect.fParams.reset(new SkParticleEffectParams());
|
|
|
|
if (auto fileData = SkData::MakeFromFileName(effect.fName.c_str())) {
|
|
|
|
skjson::DOM dom(static_cast<const char*>(fileData->data()), fileData->size());
|
|
|
|
SkFromJsonVisitor fromJson(dom.root());
|
|
|
|
effect.fParams->visitFields(&fromJson);
|
2019-12-02 21:52:51 +00:00
|
|
|
effect.fParams->prepare(fResourceProvider.get());
|
2019-03-06 16:08:48 +00:00
|
|
|
fLoaded.push_back(effect);
|
|
|
|
}
|
|
|
|
}
|
2021-01-29 14:53:00 +00:00
|
|
|
std::sort(fLoaded.begin(), fLoaded.end(), [](const LoadedEffect& a, const LoadedEffect& b) {
|
|
|
|
return strcmp(a.fName.c_str(), b.fName.c_str()) < 0;
|
|
|
|
});
|
2019-02-14 18:22:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ParticlesSlide::load(SkScalar winWidth, SkScalar winHeight) {
|
2019-03-06 16:08:48 +00:00
|
|
|
this->loadEffects(GetResourcePath("particles").c_str());
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ParticlesSlide::draw(SkCanvas* canvas) {
|
2019-10-07 13:38:30 +00:00
|
|
|
canvas->clear(SK_ColorGRAY);
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
|
2019-03-06 16:08:48 +00:00
|
|
|
// Window to show all loaded effects, and allow playing them
|
|
|
|
if (ImGui::Begin("Library", nullptr, ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
|
2019-02-14 19:49:55 +00:00
|
|
|
static bool looped = true;
|
|
|
|
ImGui::Checkbox("Looped", &looped);
|
2019-03-06 16:08:48 +00:00
|
|
|
|
|
|
|
static SkString dirname = GetResourcePath("particles");
|
|
|
|
ImGuiInputTextFlags textFlags = ImGuiInputTextFlags_CallbackResize;
|
|
|
|
ImGui::InputText("Directory", dirname.writable_str(), dirname.size() + 1, textFlags,
|
|
|
|
InputTextCallback, &dirname);
|
|
|
|
|
|
|
|
if (ImGui::Button("New")) {
|
|
|
|
LoadedEffect effect;
|
|
|
|
effect.fName = SkOSPath::Join(dirname.c_str(), "new.json");
|
|
|
|
effect.fParams.reset(new SkParticleEffectParams());
|
|
|
|
fLoaded.push_back(effect);
|
2019-02-14 19:49:55 +00:00
|
|
|
}
|
2019-03-06 16:08:48 +00:00
|
|
|
ImGui::SameLine();
|
|
|
|
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
if (ImGui::Button("Load")) {
|
2019-03-06 16:08:48 +00:00
|
|
|
this->loadEffects(dirname.c_str());
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
}
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
|
|
|
if (ImGui::Button("Save")) {
|
2019-03-06 16:08:48 +00:00
|
|
|
for (const auto& effect : fLoaded) {
|
|
|
|
SkFILEWStream fileStream(effect.fName.c_str());
|
|
|
|
if (fileStream.isValid()) {
|
|
|
|
SkJSONWriter writer(&fileStream, SkJSONWriter::Mode::kPretty);
|
|
|
|
SkToJsonVisitor toJson(writer);
|
|
|
|
writer.beginObject();
|
|
|
|
effect.fParams->visitFields(&toJson);
|
|
|
|
writer.endObject();
|
|
|
|
writer.flush();
|
|
|
|
fileStream.flush();
|
|
|
|
} else {
|
|
|
|
SkDebugf("Failed to open %s\n", effect.fName.c_str());
|
|
|
|
}
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SkGuiVisitor gui;
|
2019-03-06 16:08:48 +00:00
|
|
|
for (int i = 0; i < fLoaded.count(); ++i) {
|
|
|
|
ImGui::PushID(i);
|
2019-07-11 20:32:53 +00:00
|
|
|
if (fAnimated && ImGui::Button("Play")) {
|
2020-02-10 18:45:22 +00:00
|
|
|
sk_sp<SkParticleEffect> effect(new SkParticleEffect(fLoaded[i].fParams));
|
|
|
|
effect->start(fAnimationTime, looped, { 0, 0 }, { 0, -1 }, 1, { 0, 0 }, 0,
|
2020-12-22 21:15:28 +00:00
|
|
|
{ 1, 1, 1, 1 }, 0, fRandom.nextF());
|
2019-12-05 19:38:14 +00:00
|
|
|
fRunning.push_back({ fLoaded[i].fName, effect, false });
|
2019-03-06 16:08:48 +00:00
|
|
|
}
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
|
|
|
ImGui::InputText("##Name", fLoaded[i].fName.writable_str(), fLoaded[i].fName.size() + 1,
|
|
|
|
textFlags, InputTextCallback, &fLoaded[i].fName);
|
|
|
|
|
|
|
|
if (ImGui::TreeNode("##Details")) {
|
|
|
|
fLoaded[i].fParams->visitFields(&gui);
|
|
|
|
ImGui::TreePop();
|
2019-12-02 21:52:51 +00:00
|
|
|
if (gui.fDirty) {
|
|
|
|
fLoaded[i].fParams->prepare(fResourceProvider.get());
|
|
|
|
gui.fDirty = false;
|
|
|
|
}
|
2019-03-06 16:08:48 +00:00
|
|
|
}
|
|
|
|
ImGui::PopID();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ImGui::End();
|
|
|
|
|
2019-12-05 19:38:14 +00:00
|
|
|
// Most effects are centered around the origin, so we shift the canvas...
|
|
|
|
constexpr SkVector kTranslation = { 250.0f, 250.0f };
|
|
|
|
const SkPoint mousePos = fMousePos - kTranslation;
|
|
|
|
|
2019-03-06 16:08:48 +00:00
|
|
|
// Another window to show all the running effects
|
|
|
|
if (ImGui::Begin("Running")) {
|
|
|
|
for (int i = 0; i < fRunning.count(); ++i) {
|
2019-10-15 20:41:18 +00:00
|
|
|
SkParticleEffect* effect = fRunning[i].fEffect.get();
|
|
|
|
ImGui::PushID(effect);
|
|
|
|
|
2019-10-15 14:27:59 +00:00
|
|
|
ImGui::Checkbox("##Track", &fRunning[i].fTrackMouse);
|
|
|
|
ImGui::SameLine();
|
2019-10-15 20:41:18 +00:00
|
|
|
bool remove = ImGui::Button("X") || !effect->isAlive();
|
2019-03-06 16:08:48 +00:00
|
|
|
ImGui::SameLine();
|
2019-12-05 19:38:14 +00:00
|
|
|
ImGui::Text("%5d %s", effect->getCount(), fRunning[i].fName.c_str());
|
2019-10-15 14:27:59 +00:00
|
|
|
if (fRunning[i].fTrackMouse) {
|
2019-12-05 19:38:14 +00:00
|
|
|
effect->setPosition(mousePos);
|
2019-10-15 14:27:59 +00:00
|
|
|
}
|
2019-10-15 20:41:18 +00:00
|
|
|
|
2021-01-20 19:01:30 +00:00
|
|
|
auto uniformsGui = [mousePos](const SkSL::UniformInfo* info, float* data) {
|
|
|
|
if (!info || !data) {
|
2019-10-15 20:41:18 +00:00
|
|
|
return;
|
|
|
|
}
|
2021-01-20 19:01:30 +00:00
|
|
|
for (size_t i = 0; i < info->fUniforms.size(); ++i) {
|
|
|
|
const auto& uni = info->fUniforms[i];
|
2019-10-15 20:41:18 +00:00
|
|
|
float* vals = data + uni.fSlot;
|
|
|
|
|
|
|
|
// Skip over builtin uniforms, to reduce clutter
|
|
|
|
if (uni.fName == "dt" || uni.fName.startsWith("effect.")) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Special case for 'uniform float2 mouse_pos' - an example of likely app logic
|
|
|
|
if (uni.fName == "mouse_pos" &&
|
2021-01-20 19:01:30 +00:00
|
|
|
uni.fKind == SkSL::Type::NumberKind::kFloat &&
|
2019-10-15 20:41:18 +00:00
|
|
|
uni.fRows == 2 && uni.fColumns == 1) {
|
2019-12-05 19:38:14 +00:00
|
|
|
vals[0] = mousePos.fX;
|
|
|
|
vals[1] = mousePos.fY;
|
2019-10-15 20:41:18 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-01-20 19:01:30 +00:00
|
|
|
if (uni.fKind == SkSL::Type::NumberKind::kBoolean) {
|
2019-10-15 20:41:18 +00:00
|
|
|
for (int c = 0; c < uni.fColumns; ++c, vals += uni.fRows) {
|
|
|
|
for (int r = 0; r < uni.fRows; ++r, ++vals) {
|
|
|
|
ImGui::PushID(c*uni.fRows + r);
|
|
|
|
if (r > 0) {
|
|
|
|
ImGui::SameLine();
|
|
|
|
}
|
|
|
|
ImGui::CheckboxFlags(r == uni.fRows - 1 ? uni.fName.c_str()
|
|
|
|
: "##Hidden",
|
|
|
|
(unsigned int*)vals, ~0);
|
|
|
|
ImGui::PopID();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGuiDataType dataType = ImGuiDataType_COUNT;
|
2021-01-20 19:01:30 +00:00
|
|
|
using NumberKind = SkSL::Type::NumberKind;
|
|
|
|
switch (uni.fKind) {
|
|
|
|
case NumberKind::kSigned: dataType = ImGuiDataType_S32; break;
|
|
|
|
case NumberKind::kUnsigned: dataType = ImGuiDataType_U32; break;
|
|
|
|
case NumberKind::kFloat: dataType = ImGuiDataType_Float; break;
|
|
|
|
default: break;
|
2019-10-15 20:41:18 +00:00
|
|
|
}
|
|
|
|
SkASSERT(dataType != ImGuiDataType_COUNT);
|
|
|
|
for (int c = 0; c < uni.fColumns; ++c, vals += uni.fRows) {
|
|
|
|
ImGui::PushID(c);
|
|
|
|
ImGui::DragScalarN(uni.fName.c_str(), dataType, vals, uni.fRows, 1.0f);
|
|
|
|
ImGui::PopID();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2021-01-29 19:32:09 +00:00
|
|
|
uniformsGui(effect->uniformInfo(), effect->uniformData());
|
2019-03-06 16:08:48 +00:00
|
|
|
if (remove) {
|
|
|
|
fRunning.removeShuffle(i);
|
|
|
|
}
|
|
|
|
ImGui::PopID();
|
|
|
|
}
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
}
|
|
|
|
ImGui::End();
|
|
|
|
|
2019-12-05 19:38:14 +00:00
|
|
|
canvas->save();
|
|
|
|
canvas->translate(kTranslation.fX, kTranslation.fY);
|
2019-03-06 16:08:48 +00:00
|
|
|
for (const auto& effect : fRunning) {
|
|
|
|
effect.fEffect->draw(canvas);
|
|
|
|
}
|
2019-12-05 19:38:14 +00:00
|
|
|
canvas->restore();
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
}
|
|
|
|
|
2019-07-11 20:32:53 +00:00
|
|
|
bool ParticlesSlide::animate(double nanos) {
|
|
|
|
fAnimated = true;
|
|
|
|
fAnimationTime = 1e-9 * nanos;
|
2019-03-06 16:08:48 +00:00
|
|
|
for (const auto& effect : fRunning) {
|
2019-07-11 20:32:53 +00:00
|
|
|
effect.fEffect->update(fAnimationTime);
|
2019-03-06 16:08:48 +00:00
|
|
|
}
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-08-29 14:39:22 +00:00
|
|
|
bool ParticlesSlide::onMouse(SkScalar x, SkScalar y, skui::InputState state, skui::ModifierKey modifiers) {
|
2019-12-05 19:38:14 +00:00
|
|
|
fMousePos.set(x, y);
|
Experimental Particle System
This adds a new "Particles" slide to viewer, that allows
editing, loading, and saving particle effects. All of the
particle system code is in modules/particles.
There are many rough edges and some not-yet-finished changes
to generalize the model[1]. A rough overview:
- SkReflected.h implements a lightweight reflection system
for classes derived from SkReflected. Adding a new class
involves deriving from SkReflected, adding a macro to the
class declaration, and implementing visitFields(), which
simply calls a virtual on an SkFieldVisitor for each field.
Currently, emitters and affectors use this mechanism.
- SkParticleSerialization.h demonstrates two useful field
visitors - for serializing to and from JSON. The driver
code that uses those is directly in ParticlesSlide.
- SkParticleData.h and SkCurve.h define a variety of helper
types for talking about particles, both for parameterizing
individual values, and communicating about the state of a
particle among the effect, affectors, and emitters.
- SkParticleEffect.h defines the static data definition of
an effect (SkParticleEffectParams), as well as a running
instance of an effect (SkParticleEffect). The effect has
simple update() and draw() methods.
- ParticlesSlide.cpp adds a third field visitor to generate
GUIs for interactively editing the running effect.
---
1: The critical change I'd like to make is to remove all
special case behavior over time and at spawn (setting sprite
frames, size over time, color over time, etc...). Integration
is the only fixed function behavior. Everything else is driven
by two lists of affectors. One is applied at spawn time, using
the effect's lifetime to evaluate curves. This allows spawning
particles with different colors as the effect ages out, for
example. The second list is applied every frame to update
existing particles, and is driven by the particle's lifetime.
This allows particles to change color after being spawned, for
example.
With a small set of affectors using a single expressive curve
primitive (keyframed list of cubic curve segments), we can
have affectors that update color, size, velocity, position,
sprite frame, etc., and implement many complex behaviors.
Bug: skia:
Change-Id: Id9402bef22825d55d021c5a2f9e5e41791aabaf4
Reviewed-on: https://skia-review.googlesource.com/c/181404
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
2019-02-12 18:27:51 +00:00
|
|
|
return false;
|
|
|
|
}
|