Fix #139782: USD MeshSequenceCache modifier using the wrong frame

It would run into using the same frame twice, looking like "freeze
frames"

Apparently we had a similar issue before, see 3f8ec963e3

Just a PoC to show that this looks like a precision/rounding issue when
getting a "working" `UsdTimeCode`.
In the modifier code, we are doing a roundtrip going from frame >> time
(in seconds -- via `BKE_cachefile_time_offset`) and then back to frame
before we store that in `USDMeshReadParams`.

To avoid the precision loss, this PR introduces
`BKE_cachefile_frame_offset` to stay in the "frame" domain and
circumvent going through FPS alltogether.

There might be better ways to let USD handle the "sightly off"
`UsdTimeCode` better though.

Pull Request: https://projects.blender.org/blender/blender/pulls/139793
This commit is contained in:
Philipp Oeser
2025-06-04 11:04:37 +02:00
committed by Philipp Oeser
parent e24f46b12b
commit 457cccd964
3 changed files with 10 additions and 1 deletions

View File

@@ -28,6 +28,7 @@ bool BKE_cachefile_filepath_get(const Main *bmain,
char r_filepath[1024]);
double BKE_cachefile_time_offset(const CacheFile *cache_file, double time, double fps);
double BKE_cachefile_frame_offset(const CacheFile *cache_file, double time);
/* Modifiers and constraints open and free readers through these. */
void BKE_cachefile_reader_open(CacheFile *cache_file,

View File

@@ -405,6 +405,13 @@ double BKE_cachefile_time_offset(const CacheFile *cache_file, const double time,
return cache_file->is_sequence ? frame : frame / fps - time_offset;
}
double BKE_cachefile_frame_offset(const CacheFile *cache_file, const double time)
{
const double time_offset = double(cache_file->frame_offset);
const double frame = cache_file->override_frame ? double(cache_file->frame) : time;
return cache_file->is_sequence ? frame : frame - time_offset;
}
bool BKE_cache_file_uses_render_procedural(const CacheFile *cache_file, Scene *scene)
{
RenderEngineType *render_engine_type = RE_engines_find(scene->r.engine);

View File

@@ -174,6 +174,7 @@ static void modify_geometry_set(ModifierData *md,
Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
CacheFile *cache_file = mcmd->cache_file;
const float frame = DEG_get_ctime(ctx->depsgraph);
const double frame_offset = BKE_cachefile_frame_offset(cache_file, double(frame));
const double time = BKE_cachefile_time_offset(cache_file, frame, FPS);
const char *err_str = nullptr;
@@ -236,7 +237,7 @@ static void modify_geometry_set(ModifierData *md,
case CACHEFILE_TYPE_USD: {
# ifdef WITH_USD
const blender::io::usd::USDMeshReadParams params = blender::io::usd::create_mesh_read_params(
time * FPS, mcmd->read_flag);
frame_offset, mcmd->read_flag);
blender::io::usd::USD_read_geometry(
mcmd->reader, ctx->object, *geometry_set, params, &err_str);
# endif