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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef SkReflected_DEFINED
|
|
|
|
#define SkReflected_DEFINED
|
|
|
|
|
|
|
|
#include "SkColor.h"
|
|
|
|
#include "SkRefCnt.h"
|
|
|
|
#include "SkString.h"
|
|
|
|
#include "SkTArray.h"
|
|
|
|
|
2019-02-26 19:58:40 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
2019-03-04 15:55:22 +00:00
|
|
|
struct SkCurve;
|
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 SkFieldVisitor;
|
|
|
|
class SkRandom;
|
|
|
|
|
2019-02-19 18:04:40 +00:00
|
|
|
/**
|
|
|
|
* Classes and macros for a lightweight reflection system.
|
|
|
|
*
|
|
|
|
* Classes that derive from SkReflected have several features:
|
|
|
|
* - Access to an SkReflected::Type instance, via static GetType() or virtual getType()
|
|
|
|
* The Type instance can be used to create additional instances (fFactory), get the name
|
|
|
|
* of the type, and answer queries of the form "is X derived from Y".
|
|
|
|
* - Given a string containing a type name, SkReflected can create an instance of that type.
|
2019-03-06 16:08:48 +00:00
|
|
|
* - SkReflected::VisitTypes can be used to enumerate all Types.
|
2019-02-19 18:04:40 +00:00
|
|
|
*
|
|
|
|
* Together, this simplifies the implementation of serialization and other dynamic type factories.
|
|
|
|
*
|
|
|
|
* Finally, all SkReflected-derived types must implement visitFields, which provides field-level
|
|
|
|
* reflection, in conjunction with SkFieldVisitor. See SkFieldVisitor, below.
|
|
|
|
*
|
|
|
|
* To create a new reflected class:
|
|
|
|
* - Derive the class (directly or indirectly) from SkReflected.
|
|
|
|
* - Ensure that the class can be default constructed.
|
|
|
|
* - In the public area of the class declaration, add REFLECTED(<ClassName>, <BaseClassName>).
|
|
|
|
* If the class is abstract, use REFLECTED_ABSTRACT(<ClassName>, <BaseClassName>) instead.
|
|
|
|
* - Add a one-time call to REGISTER_REFLECTED(<ClassName>) at initialization time.
|
|
|
|
* - Implement visitFields(), as described below.
|
|
|
|
*/
|
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 SkReflected : public SkRefCnt {
|
|
|
|
public:
|
|
|
|
typedef sk_sp<SkReflected>(*Factory)();
|
|
|
|
struct Type {
|
|
|
|
const char* fName;
|
|
|
|
const Type* fBase;
|
|
|
|
Factory fFactory;
|
2019-03-06 20:00:36 +00:00
|
|
|
bool fRegistered = 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
|
|
|
|
|
|
|
bool isDerivedFrom(const Type* t) const {
|
|
|
|
const Type* base = fBase;
|
|
|
|
while (base) {
|
|
|
|
if (base == t) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
base = base->fBase;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
virtual const Type* getType() const = 0;
|
|
|
|
static const Type* GetType() {
|
|
|
|
static Type gType{ "SkReflected", nullptr, nullptr };
|
2019-03-06 20:00:36 +00:00
|
|
|
RegisterOnce(&gType);
|
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 &gType;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isOfType(const Type* t) const {
|
|
|
|
const Type* thisType = this->getType();
|
|
|
|
return thisType == t || thisType->isDerivedFrom(t);
|
|
|
|
}
|
|
|
|
|
|
|
|
static sk_sp<SkReflected> CreateInstance(const char* name) {
|
|
|
|
for (const Type* type : gTypes) {
|
|
|
|
if (0 == strcmp(name, type->fName)) {
|
|
|
|
return type->fFactory();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void visitFields(SkFieldVisitor*) = 0;
|
|
|
|
|
2019-03-06 16:08:48 +00:00
|
|
|
static void VisitTypes(std::function<void(const Type*)> visitor);
|
|
|
|
|
2019-03-06 20:00:36 +00:00
|
|
|
protected:
|
|
|
|
static void RegisterOnce(Type* type) {
|
|
|
|
if (!type->fRegistered) {
|
|
|
|
gTypes.push_back(type);
|
|
|
|
type->fRegistered = 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
|
|
|
private:
|
|
|
|
static SkSTArray<16, const Type*, true> gTypes;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define REFLECTED(TYPE, BASE) \
|
|
|
|
static sk_sp<SkReflected> CreateProc() { \
|
|
|
|
return sk_sp<SkReflected>(new TYPE()); \
|
|
|
|
} \
|
|
|
|
static const Type* GetType() { \
|
|
|
|
static Type gType{ #TYPE, BASE::GetType(), CreateProc }; \
|
2019-03-06 20:00:36 +00:00
|
|
|
RegisterOnce(&gType); \
|
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 &gType; \
|
|
|
|
} \
|
|
|
|
const Type* getType() const override { return GetType(); }
|
|
|
|
|
|
|
|
#define REFLECTED_ABSTRACT(TYPE, BASE) \
|
|
|
|
static const Type* GetType() { \
|
|
|
|
static Type gType{ #TYPE, BASE::GetType(), nullptr }; \
|
2019-03-06 20:00:36 +00:00
|
|
|
RegisterOnce(&gType); \
|
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 &gType; \
|
|
|
|
} \
|
|
|
|
const Type* getType() const override { return GetType(); }
|
|
|
|
|
2019-03-06 20:00:36 +00:00
|
|
|
#define REGISTER_REFLECTED(TYPE) TYPE::GetType()
|
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
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
struct SkPoint;
|
|
|
|
|
2019-02-19 18:04:40 +00:00
|
|
|
/**
|
|
|
|
* SkFieldVisitor is an interface that can be implemented by any class to visit all fields of
|
|
|
|
* SkReflected types, and of types that implement the visitFields() function.
|
|
|
|
*
|
|
|
|
* Classes implementing the interface must supply implementations of virtual functions that visit
|
|
|
|
* basic types (float, int, bool, SkString, etc...), as well as helper methods for entering the
|
|
|
|
* scope of an object or array.
|
|
|
|
*
|
|
|
|
* All visit functions supply a field name, and a non-constant reference to an actual field.
|
|
|
|
* This allows visitors to serialize or deserialize collections of objects, or perform edits on
|
|
|
|
* existing objects.
|
|
|
|
*
|
|
|
|
* Classes that implement visitFields (typically derived from SkReflected) should simply call
|
|
|
|
* visit() for each of their fields, passing a (unique) field name, and the actual field. If your
|
|
|
|
* class has derived fields, it's best to only visit() the fields that you would serialize, then
|
|
|
|
* enforce any constraints afterwards.
|
|
|
|
*
|
|
|
|
* See SkParticleSerialization.h for example visitors that perform serialization to and from JSON.
|
|
|
|
*/
|
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 SkFieldVisitor {
|
|
|
|
public:
|
|
|
|
virtual ~SkFieldVisitor() {}
|
|
|
|
|
2019-02-19 18:04:40 +00:00
|
|
|
// Visit functions for primitive types, to be implemented by derived visitors.
|
2019-02-19 15:45:56 +00:00
|
|
|
virtual void visit(const char*, float&) = 0;
|
|
|
|
virtual void visit(const char*, int&) = 0;
|
|
|
|
virtual void visit(const char*, bool&) = 0;
|
|
|
|
virtual void visit(const char*, SkString&) = 0;
|
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
|
|
|
virtual void visit(const char*, SkPoint&) = 0;
|
|
|
|
virtual void visit(const char*, SkColor4f&) = 0;
|
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-26 19:58:40 +00:00
|
|
|
// Accommodation for enums, where caller can supply a value <-> string map
|
|
|
|
struct EnumStringMapping {
|
|
|
|
int fValue;
|
|
|
|
const char* fName;
|
|
|
|
};
|
|
|
|
virtual void visit(const char*, int&, const EnumStringMapping*, int count) = 0;
|
|
|
|
|
2019-02-19 18:04:40 +00:00
|
|
|
// Specific virtual signature for SkCurve, to allow for heavily customized UI in SkGuiVisitor.
|
2019-03-04 15:55:22 +00:00
|
|
|
virtual void visit(const char* name, SkCurve& c);
|
2019-02-15 15:45:56 +00:00
|
|
|
|
2019-02-19 18:04:40 +00:00
|
|
|
// Default visit function for structs with no special behavior. It is assumed that any such
|
|
|
|
// struct implements visitFields(SkFieldVisitor*) to recursively visit each of its fields.
|
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
|
|
|
template <typename T>
|
|
|
|
void visit(const char* name, T& value) {
|
|
|
|
this->enterObject(name);
|
|
|
|
value.visitFields(this);
|
|
|
|
this->exitObject();
|
|
|
|
}
|
|
|
|
|
2019-02-19 18:04:40 +00:00
|
|
|
// Specialization for SkTArrays. In conjunction with the enterArray/exitArray virtuals, this
|
|
|
|
// allows visitors to resize an array (for deserialization), and apply a single edit operation
|
|
|
|
// (remove or move a single element). Each element of the array is visited as normal.
|
2019-02-14 18:23:51 +00:00
|
|
|
template <typename T, bool MEM_MOVE>
|
|
|
|
void visit(const char* name, SkTArray<T, MEM_MOVE>& arr) {
|
|
|
|
arr.resize_back(this->enterArray(name, arr.count()));
|
|
|
|
for (int i = 0; i < arr.count(); ++i) {
|
|
|
|
this->visit(nullptr, arr[i]);
|
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
|
|
|
this->exitArray().apply(arr);
|
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 18:04:40 +00:00
|
|
|
// Specialization for sk_sp pointers to types derived from SkReflected. Those types are known
|
|
|
|
// to implement visitFields. This allows the visitor to modify the contents of the object, or
|
|
|
|
// even replace it with an entirely new object. The virtual function uses SkReflected as a
|
|
|
|
// common type, but uses SkReflected::Type to communicate the required base-class. In this way,
|
|
|
|
// the new object can be verified to match the type of the original (templated) pointer.
|
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
|
|
|
template <typename T>
|
|
|
|
void visit(const char* name, sk_sp<T>& obj) {
|
|
|
|
this->enterObject(name);
|
|
|
|
|
|
|
|
sk_sp<SkReflected> newObj = obj;
|
|
|
|
this->visit(newObj, T::GetType());
|
|
|
|
if (newObj != obj) {
|
|
|
|
if (!newObj || newObj->isOfType(T::GetType())) {
|
|
|
|
obj.reset(static_cast<T*>(newObj.release()));
|
|
|
|
} else {
|
|
|
|
obj.reset();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (obj) {
|
|
|
|
obj->visitFields(this);
|
|
|
|
}
|
|
|
|
this->exitObject();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
2019-02-19 18:04:40 +00:00
|
|
|
// Helper struct to allow exitArray to specify a single operation performed on the array.
|
2019-02-14 18:23:51 +00:00
|
|
|
struct ArrayEdit {
|
|
|
|
enum class Verb {
|
|
|
|
kNone,
|
|
|
|
kRemove,
|
|
|
|
kMoveForward,
|
|
|
|
};
|
|
|
|
|
|
|
|
Verb fVerb = Verb::kNone;
|
|
|
|
int fIndex = 0;
|
|
|
|
|
|
|
|
template <typename T, bool MEM_MOVE>
|
|
|
|
void apply(SkTArray<T, MEM_MOVE>& arr) const {
|
|
|
|
switch (fVerb) {
|
|
|
|
case Verb::kNone:
|
|
|
|
break;
|
|
|
|
case Verb::kRemove:
|
|
|
|
for (int i = fIndex; i < arr.count() - 1; ++i) {
|
|
|
|
arr[i] = arr[i + 1];
|
|
|
|
}
|
|
|
|
arr.pop_back();
|
|
|
|
break;
|
|
|
|
case Verb::kMoveForward:
|
|
|
|
if (fIndex > 0 && fIndex < arr.count()) {
|
|
|
|
std::swap(arr[fIndex - 1], arr[fIndex]);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-02-26 19:58:40 +00:00
|
|
|
static const char* EnumToString(int value, const EnumStringMapping* map, int count) {
|
|
|
|
for (int i = 0; i < count; ++i) {
|
|
|
|
if (map[i].fValue == value) {
|
|
|
|
return map[i].fName;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
static int StringToEnum(const char* str, const EnumStringMapping* map, int count) {
|
|
|
|
for (int i = 0; i < count; ++i) {
|
|
|
|
if (0 == strcmp(str, map[i].fName)) {
|
|
|
|
return map[i].fValue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
virtual void enterObject(const char* name) = 0;
|
|
|
|
virtual void exitObject() = 0;
|
2019-02-14 18:23:51 +00:00
|
|
|
|
|
|
|
virtual int enterArray(const char* name, int oldCount) = 0;
|
|
|
|
virtual ArrayEdit exitArray() = 0;
|
|
|
|
|
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
|
|
|
virtual void visit(sk_sp<SkReflected>&, const SkReflected::Type* baseType) = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // SkReflected_DEFINED
|