Fix: FCurve noise modifier offset affected by scale

The issue was that the offset would offset by a different
amount depending on the scale property.
This is a regression from the legacy behavior,
and also harder to control in general.

The versioning code only touches FCurves that are not marked
as "legacy" because the legacy noise didn't have that issue.

Pull Request: https://projects.blender.org/blender/blender/pulls/136502
This commit is contained in:
Christoph Lendenfeld
2025-04-03 11:31:23 +02:00
committed by Christoph Lendenfeld
parent ac201c2d9a
commit 05aac73b45
3 changed files with 47 additions and 2 deletions

View File

@@ -27,7 +27,7 @@
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 13
#define BLENDER_FILE_SUBVERSION 14
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and cancel loading the file, showing a warning to

View File

@@ -839,7 +839,7 @@ static void fcm_noise_evaluate(const FCurve * /*fcu*/,
/* Using float2 to generate a phase offset. Offsetting the evaltime by `offset` to ensure that
* the noise at full frames isn't always at 0. */
noise = blender::noise::perlin_fbm<blender::float2>(
blender::float2(evaltime * scale - data->offset + offset, data->phase),
blender::float2((evaltime - data->offset) * scale + offset, data->phase),
data->depth,
data->roughness,
data->lacunarity,

View File

@@ -136,6 +136,34 @@ static void version_fcurve_noise_modifier(FCurve &fcurve)
}
}
static void version_fix_fcurve_noise_offset(FCurve &fcurve)
{
LISTBASE_FOREACH (FModifier *, fcurve_modifier, &fcurve.modifiers) {
if (fcurve_modifier->type != FMODIFIER_TYPE_NOISE) {
continue;
}
FMod_Noise *data = static_cast<FMod_Noise *>(fcurve_modifier->data);
if (data->legacy_noise) {
/* We don't want to modify anything if the noise is set to legacy, because the issue only
* occurred on the new style noise. */
continue;
}
data->offset *= data->size;
}
}
static void nlastrips_apply_fcurve_versioning(ListBase &strips)
{
LISTBASE_FOREACH (NlaStrip *, strip, &strips) {
LISTBASE_FOREACH (FCurve *, fcurve, &strip->fcurves) {
version_fix_fcurve_noise_offset(*fcurve);
}
/* Check sub-strips (if meta-strips). */
nlastrips_apply_fcurve_versioning(strip->strips);
}
}
/* Move bone-group color to the individual bones. */
static void version_bonegroup_migrate_color(Main *bmain)
{
@@ -2136,6 +2164,23 @@ void do_versions_after_linking_400(FileData *fd, Main *bmain)
}
}
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 405, 14)) {
LISTBASE_FOREACH (bAction *, dna_action, &bmain->actions) {
blender::animrig::Action &action = dna_action->wrap();
blender::animrig::foreach_fcurve_in_action(
action, [&](FCurve &fcurve) { version_fix_fcurve_noise_offset(fcurve); });
}
BKE_animdata_main_cb(bmain, [](ID * /* id */, AnimData *adt) {
LISTBASE_FOREACH (FCurve *, fcurve, &adt->drivers) {
version_fix_fcurve_noise_offset(*fcurve);
}
LISTBASE_FOREACH (NlaTrack *, track, &adt->nla_tracks) {
nlastrips_apply_fcurve_versioning(track->strips);
}
});
}
/**
* Always bump subversion in BKE_blender_version.h when adding versioning
* code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check.