Repository navigation
Conversation
A time-offset binding used to call UpdateValue on its source curve at the offset time and then again at the curve set's time to put it back. That re-fired every event key on a TriEventCurve each frame, dragged curves owned by other curve sets to this set's time, and evaluated the curve twice more per frame. Bindings now sample through the typed curves' GetValueAt, which leaves the curve's state alone. The binding decides this when it resolves its source: only the currentValue of a scalar, vector, quaternion or color curve can be sampled, and an offset on anything else is ignored with a warning. The curve set no longer special-cases offset bindings. ITr2ValueBinding has a single CopyValueAt(TriCurveSetTime) instead of GetTimeOffset and CopyValueSampledAt, and TriCurveSetTime carries the looped range so the binding can wrap its own offset. The range wrapping is shared with the curve set's own time update, which also stops a zero-length looped range from producing NaN. Also drops the unused TriValueBinding::SetTimeOffset, moves the Tracy link fix to its own branch, and adds tests. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Fails on the previous implementation, which restored the curve to the binding's own curve set's time. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- The timeOffset description claimed every ignored offset logs a warning. Bindings run without a curve set time (lens flares, child links, socket parameters, dynamic bindings) ignore it silently; say so. - TriCurveSampleFunc writes into a Vector4& instead of a void* whose size was only stated in a comment. - Test vector and color curves and a swizzled source (currentValue.y), which exercises the sample offset path. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Timing on a TrinityDev build showed one curve driving two offset bindings costing 1.5x (4 keys) to 17x (512 keys) the time of two duplicated curves. Two causes: - Every sample looked up the curve's typed interface again (QueryInterface plus a reference count round trip). TriCurveSampler now finds it once when the binding resolves its source and keeps the raw pointer, which lives exactly as long as the binding's existing pointer into the source. - Tr2CurveScalar caches the last key segment it used. Sampling one curve at two times a frame keeps moving that cache, and every miss scanned all keys. A miss now binary searches the sorted keys, keeping the linear scan only for keys edited out of order without OnKeysChanged. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Exercises the scalar curve's key search on a cache miss. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A shared curve sampled at its curve set's time and at a binding's offset time kept moving its single cached key segment, so most lookups searched. That left one shared curve about 2.2x the cost of two duplicated curves. Tr2CurveScalar and Tr2CurveQuaternion now look their keys up through one FindCurveSegment helper that takes the cache to use, replacing the two copies of the same lookup. Their own GetValue passes the curve's cache as before; the new SampleValue takes the caller's. TriCurveSampler recognises these keyed curves and keeps a segment cache per binding, so an offset binding finds its keys as quickly as a duplicated curve would, and leaves the curve's own cache alone. The quaternion curve also gets the binary search on a cache miss, and both can now step back from segment 1 to segment 0 from the cache (the left neighbour check stopped at 1). Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Timing showed the shared segment lookup slowed every curve evaluation by about 25-30 ns in unoptimised builds: GetValue, SampleValue, the lookup and a lambda each cost a real call there. The curves' own UpdateValue, Update and GetValueAt now call SampleValue directly, and the cache checks in FindCurveSegment are written out. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
FindCurveSegment was still one extra call on every curve evaluation, which cost about 15 ns in unoptimised builds. Curves now check their cached segment inline and only call it on a miss. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Allows designers/developers to reuse a curve (Noise over time for example) by applying a time offset to the binding. desyncronising the peaks and troughs of the curve with other bindings using the same curve. which enables much more naturalistic "random" looking patterns, or even phasing/sequencing.
2026-10-20.12-03-17.mp4
2026-10-20.15-14-17.mp4
Linked issue (optional)
https://fenriscreations.atlassian.net/browse/EF-20375
Testing
AI assistance
Claude wrote all the code for this feature, and I iteratively used the thermo-nuclear-code-quality-review skill to highlight and resolve any implementation issues.
I read all the rationale and outputted code. I have a lot of experience with C#/Java/Python, but not so much C++.
A lot of tests were added which may or may not be overkill depending on your view.
Checklist