Particles: remove non-stable random, add better enum reflection
The other generator was never used (or useful). String-based serialization of enums is quite helpful, though. Bug: skia: Change-Id: Ic9d58f8d20cfe7aba47722bd74f1e6f8f0f219e5 Reviewed-on: https://skia-review.googlesource.com/c/195368 Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
f12d675179
commit
e5d532edae
@ -43,11 +43,10 @@ struct SkParticleState {
|
||||
SkParticleVelocity fVelocity;
|
||||
SkColor4f fColor;
|
||||
SkScalar fFrame; // Parameter to drawable for animated sprites, etc.
|
||||
SkRandom fStableRandom;
|
||||
SkRandom fRandom;
|
||||
};
|
||||
|
||||
struct SkParticleUpdateParams {
|
||||
SkRandom* fRandom;
|
||||
float fDeltaTime;
|
||||
};
|
||||
|
||||
|
@ -31,6 +31,9 @@ public:
|
||||
void visit(const char* name, SkString& s) override {
|
||||
fWriter.appendString(name, s.c_str());
|
||||
}
|
||||
void visit(const char* name, int& i, const EnumStringMapping* map, int count) override {
|
||||
fWriter.appendString(name, EnumToString(i, map, count));
|
||||
}
|
||||
|
||||
// Compound types
|
||||
void visit(const char* name, SkPoint& p) override {
|
||||
@ -87,6 +90,12 @@ public:
|
||||
void visit(const char* name, SkString& s) override {
|
||||
TryParse(get(name), s);
|
||||
}
|
||||
void visit(const char* name, int& i, const EnumStringMapping* map, int count) override {
|
||||
SkString str;
|
||||
if (TryParse(get(name), str)) {
|
||||
i = StringToEnum(str.c_str(), map, count);
|
||||
}
|
||||
}
|
||||
|
||||
void visit(const char* name, SkPoint& p) override {
|
||||
if (const skjson::ObjectValue* obj = get(name)) {
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include "SkString.h"
|
||||
#include "SkTArray.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
class SkFieldVisitor;
|
||||
class SkRandom;
|
||||
|
||||
@ -148,6 +150,13 @@ public:
|
||||
virtual void visit(const char*, SkPoint&) = 0;
|
||||
virtual void visit(const char*, SkColor4f&) = 0;
|
||||
|
||||
// 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;
|
||||
|
||||
// Specific virtual signature for SkCurve, to allow for heavily customized UI in SkGuiVisitor.
|
||||
virtual void visit(const char* name, SkCurve& c) {
|
||||
this->enterObject(name);
|
||||
@ -233,6 +242,23 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
virtual void enterObject(const char* name) = 0;
|
||||
virtual void exitObject() = 0;
|
||||
|
||||
|
@ -11,6 +11,12 @@
|
||||
#include "SkParticleData.h"
|
||||
#include "SkRandom.h"
|
||||
|
||||
constexpr SkFieldVisitor::EnumStringMapping gParticleFrameMapping[] = {
|
||||
{ kWorld_ParticleFrame, "World" },
|
||||
{ kLocal_ParticleFrame, "Local" },
|
||||
{ kVelocity_ParticleFrame, "Velocity" },
|
||||
};
|
||||
|
||||
void SkParticleAffector::apply(SkParticleUpdateParams& params, SkParticleState ps[], int count) {
|
||||
if (fEnabled) {
|
||||
this->onApply(params, ps, count);
|
||||
@ -53,12 +59,12 @@ public:
|
||||
|
||||
void onApply(SkParticleUpdateParams& params, SkParticleState ps[], int count) override {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
float angle = fAngle.eval(ps[i].fAge, ps[i].fStableRandom);
|
||||
float angle = fAngle.eval(ps[i].fAge, ps[i].fRandom);
|
||||
SkScalar c_local, s_local = SkScalarSinCos(SkDegreesToRadians(angle), &c_local);
|
||||
SkVector heading = get_heading(ps[i], static_cast<SkParticleFrame>(fFrame));
|
||||
SkScalar c = heading.fX * c_local - heading.fY * s_local;
|
||||
SkScalar s = heading.fX * s_local + heading.fY * c_local;
|
||||
float strength = fStrength.eval(ps[i].fAge, ps[i].fStableRandom);
|
||||
float strength = fStrength.eval(ps[i].fAge, ps[i].fRandom);
|
||||
SkVector force = { c * strength, s * strength };
|
||||
if (fForce) {
|
||||
ps[i].fVelocity.fLinear += force * params.fDeltaTime;
|
||||
@ -71,7 +77,7 @@ public:
|
||||
void visitFields(SkFieldVisitor* v) override {
|
||||
SkParticleAffector::visitFields(v);
|
||||
v->visit("Force", fForce);
|
||||
v->visit("Frame", fFrame);
|
||||
v->visit("Frame", fFrame, gParticleFrameMapping, SK_ARRAY_COUNT(gParticleFrameMapping));
|
||||
v->visit("Angle", fAngle);
|
||||
v->visit("Strength", fStrength);
|
||||
}
|
||||
@ -93,7 +99,7 @@ public:
|
||||
|
||||
void onApply(SkParticleUpdateParams& params, SkParticleState ps[], int count) override {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
float strength = fStrength.eval(ps[i].fAge, ps[i].fStableRandom);
|
||||
float strength = fStrength.eval(ps[i].fAge, ps[i].fRandom);
|
||||
if (fForce) {
|
||||
ps[i].fVelocity.fAngular += strength * params.fDeltaTime;
|
||||
} else {
|
||||
@ -155,7 +161,7 @@ public:
|
||||
|
||||
void onApply(SkParticleUpdateParams& params, SkParticleState ps[], int count) override {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
float angle = fAngle.eval(ps[i].fAge, ps[i].fStableRandom);
|
||||
float angle = fAngle.eval(ps[i].fAge, ps[i].fRandom);
|
||||
SkScalar c_local, s_local = SkScalarSinCos(SkDegreesToRadians(angle), &c_local);
|
||||
SkVector heading = get_heading(ps[i], static_cast<SkParticleFrame>(fFrame));
|
||||
ps[i].fPose.fHeading.set(heading.fX * c_local - heading.fY * s_local,
|
||||
@ -165,7 +171,7 @@ public:
|
||||
|
||||
void visitFields(SkFieldVisitor *v) override {
|
||||
SkParticleAffector::visitFields(v);
|
||||
v->visit("Frame", fFrame);
|
||||
v->visit("Frame", fFrame, gParticleFrameMapping, SK_ARRAY_COUNT(gParticleFrameMapping));
|
||||
v->visit("Angle", fAngle);
|
||||
}
|
||||
|
||||
@ -182,7 +188,7 @@ public:
|
||||
|
||||
void onApply(SkParticleUpdateParams& params, SkParticleState ps[], int count) override {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
ps[i].fPose.fScale = fCurve.eval(ps[i].fAge, ps[i].fStableRandom);
|
||||
ps[i].fPose.fScale = fCurve.eval(ps[i].fAge, ps[i].fRandom);
|
||||
}
|
||||
}
|
||||
|
||||
@ -203,7 +209,7 @@ public:
|
||||
|
||||
void onApply(SkParticleUpdateParams& params, SkParticleState ps[], int count) override {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
ps[i].fFrame = fCurve.eval(ps[i].fAge, ps[i].fStableRandom);
|
||||
ps[i].fFrame = fCurve.eval(ps[i].fAge, ps[i].fRandom);
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,7 +231,7 @@ public:
|
||||
|
||||
void onApply(SkParticleUpdateParams& params, SkParticleState ps[], int count) override {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
ps[i].fColor = fCurve.eval(ps[i].fAge, ps[i].fStableRandom);
|
||||
ps[i].fColor = fCurve.eval(ps[i].fAge, ps[i].fRandom);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,6 @@ void SkParticleEffect::update(const SkAnimTimer& timer) {
|
||||
|
||||
SkParticleUpdateParams updateParams;
|
||||
updateParams.fDeltaTime = deltaTime;
|
||||
updateParams.fRandom = &fRandom;
|
||||
|
||||
// Advance age for existing particles, and remove any that have reached their end of life
|
||||
for (int i = 0; i < fCount; ++i) {
|
||||
@ -106,7 +105,7 @@ void SkParticleEffect::update(const SkAnimTimer& timer) {
|
||||
fParticles[fCount].fColor = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
fParticles[fCount].fFrame = 0.0f;
|
||||
|
||||
fParticles[fCount].fStableRandom = fStableRandoms[fCount] = fRandom;
|
||||
fParticles[fCount].fRandom = fStableRandoms[fCount] = fRandom;
|
||||
fCount++;
|
||||
}
|
||||
|
||||
@ -123,7 +122,7 @@ void SkParticleEffect::update(const SkAnimTimer& timer) {
|
||||
|
||||
// Restore all stable random generators so update affectors get consistent behavior each frame
|
||||
for (int i = 0; i < fCount; ++i) {
|
||||
fParticles[i].fStableRandom = fStableRandoms[i];
|
||||
fParticles[i].fRandom = fStableRandoms[i];
|
||||
}
|
||||
|
||||
// Apply update rules
|
||||
|
@ -34,7 +34,7 @@
|
||||
"Type": "SkLinearVelocityAffector",
|
||||
"Enabled": true,
|
||||
"Force": false,
|
||||
"Frame": 0,
|
||||
"Frame": "World",
|
||||
"Angle": {
|
||||
"XValues": [],
|
||||
"Segments": [
|
||||
|
@ -36,7 +36,7 @@
|
||||
"Type": "SkLinearVelocityAffector",
|
||||
"Enabled": true,
|
||||
"Force": false,
|
||||
"Frame": 0,
|
||||
"Frame": "World",
|
||||
"Angle": {
|
||||
"XValues": [],
|
||||
"Segments": [
|
||||
@ -80,7 +80,7 @@
|
||||
"Type": "SkLinearVelocityAffector",
|
||||
"Enabled": true,
|
||||
"Force": true,
|
||||
"Frame": 0,
|
||||
"Frame": "World",
|
||||
"Angle": {
|
||||
"XValues": [],
|
||||
"Segments": [
|
||||
@ -121,7 +121,7 @@
|
||||
{
|
||||
"Type": "SkOrientationAffector",
|
||||
"Enabled": true,
|
||||
"Frame": 2,
|
||||
"Frame": "Velocity",
|
||||
"Angle": {
|
||||
"XValues": [],
|
||||
"Segments": [
|
||||
|
@ -34,7 +34,7 @@
|
||||
"Type": "SkLinearVelocityAffector",
|
||||
"Enabled": true,
|
||||
"Force": false,
|
||||
"Frame": 0,
|
||||
"Frame": "World",
|
||||
"Angle": {
|
||||
"XValues": [],
|
||||
"Segments": [
|
||||
|
@ -34,7 +34,7 @@
|
||||
"Type": "SkLinearVelocityAffector",
|
||||
"Enabled": true,
|
||||
"Force": false,
|
||||
"Frame": 0,
|
||||
"Frame": "World",
|
||||
"Angle": {
|
||||
"XValues": [],
|
||||
"Segments": [
|
||||
|
@ -34,7 +34,7 @@
|
||||
"Type": "SkLinearVelocityAffector",
|
||||
"Enabled": true,
|
||||
"Force": false,
|
||||
"Frame": 0,
|
||||
"Frame": "World",
|
||||
"Angle": {
|
||||
"XValues": [],
|
||||
"Segments": [
|
||||
@ -78,7 +78,7 @@
|
||||
"Type": "SkLinearVelocityAffector",
|
||||
"Enabled": true,
|
||||
"Force": true,
|
||||
"Frame": 0,
|
||||
"Frame": "World",
|
||||
"Angle": {
|
||||
"XValues": [],
|
||||
"Segments": [
|
||||
|
@ -64,6 +64,19 @@ public:
|
||||
&s);
|
||||
}
|
||||
}
|
||||
void visit(const char* name, int& i, const EnumStringMapping* map, int count) override {
|
||||
if (fTreeStack.back()) {
|
||||
const char* curStr = EnumToString(i, map, count);
|
||||
if (ImGui::BeginCombo(item(name), curStr ? curStr : "Unknown")) {
|
||||
for (int j = 0; j < count; ++j) {
|
||||
if (ImGui::Selectable(map[j].fName, i == map[j].fValue)) {
|
||||
i = map[j].fValue;
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void visit(const char* name, SkPoint& p) override {
|
||||
if (fTreeStack.back()) {
|
||||
|
Loading…
Reference in New Issue
Block a user