# Curves Working Group This is the design document for Bevy's Curves working group, outlining the scope of the project as well as concrete plans for its implementation. The main motivations for this project are described in the [`Curve` RFC](https://github.com/bevyengine/rfcs/pull/80). ## Scope and process The working group will be focused on three primary tasks: 1. Implement the `Curve` trait API. 2. Integrate the API with `bevy_math`'s cubic spline and NURBS constructions so that the output data result in `Curve`s with access to positional information along with that of derivatives where relevant. 3. Integrate the API with `bevy_animation` by refactoring internal code so that the data that drive animation implement the relevant `Curve` traits. The latter two tasks may lead to (relatively minor) breaking changes in user-facing code; the plan is for this work to all be done proactively on the main branch of the Bevy repository. ## The trait API For the first of these, the API itself is described in substantial detail in [its RFC](https://github.com/bevyengine/rfcs/pull/80). The parts of the implementation fall into a few categories, in order of priority: 1. The minimum needed for the API to be used elsewhere. This must be the first step of the project, since it blocks everything else. 2. Additional work on the API needed specifically for `bevy_animation`: - Extending the API to allow sampling of curves with dynamically-sized array output without allocation. - Reflecting concrete curve types in `bevy_reflect`. 3. Other implementation tasks that are important for completeness; e.g.: - Extending useful data access and manipulation methods to `SampleCurve` and `UnevenSampleCurve`. When (1) is complete, integration with `bevy_math` can proceed. Integration with `bevy_animation` can begin after (2). ## Integration with `bevy_math`'s existing constructions The purpose of this integration is to allow the geometric curves produced by `bevy_math`'s spline constructions work as seamlessly as possible with the new API to allow sampling of points and derivatives along curves where applicable. The main hitch here is that guarantees on a curve's differentiability vary depending on the spline used to construct it; presently, `CubicCurve` performs no differentiation between these, but changing this so that these differences are transparent at the type level is within scope for this project if necessary. The main steps for integration consist of the following: 1. Perform design work to establish a couple of competing models for `Curve` production and consumption, and seek external feedback on these regarding usability and ergonomics. 2. Based on the previous, implement an interface which allows existing curve constructions to produce `Curve<T>` data for relevant values of `T` (position, velocity, etc.); this includes: - `CubicGenerator` -> `CubicCurve` - `RationalGenerator` -> `RationalCurve` - `CubicSegment` / `RationalSegment` 4. Investigate and, if necessary, implement special handling for the easing curves described by the special methods for `CubicSegment<Vec2>`. 5. Reevaluate usability of the new API surface and make changes if necessary. ## Integration with `bevy_animation` Here, the main idea is to replace `VariableCurve`'s internals with a suite of types that implement the relevant kind of `Curve`. For example, a curve describing the translation of an animation bone over time would be something like a `TranslationCurve` implementing `Curve<Vec3>`; for rotations it would be `Curve<Quat>`, and so on. The extension mentioned in the previous section is necessary specifically to accommodate the animation of morph weights; since the number of morph targets cannot be known statically, the associated curve "wants" to be something like a `Curve<Vec<f32>>`, but that would *a priori* allocate a `Vec` every time sampling is performed. The extension avoids this problem. Note that the resulting curve constructions will still adhere very closely to the variants in the glTF spec (as the current implementation does); this work is just the first step in the process in migrating to something like more general `Curve`-based animation, which would more readily accommodate animations defined in-process rather than imported through assets, but further expansion in this direction is out of scope for this working group (although part of the goal in performing this work is to open up the possibility!). The steps necessary to integrate `bevy_animation` are as follows: 1. Take care of blockers within the `Curve` API itself (see above). 2. Replace `VariableCurve` internals: - Replace each animation component curve with a type implementing `Curve`. - Refactor asset loading of glTF animations to match the new implementation. - Refactor `AnimationTargetContext` to sample from the constitutent curves instead of doing its own interpolation. 3. Benchmark animation performance against the previous implementation and update as necessary. 4. Evaluate effects on animation user interface and take mitigating actions where necessary. ## Controlling ongoing project scope Other ideas for future extensions will doubtlessly arise during the execution of the project, along with cleanup tasks that should be performed but are not essential to the completion of the working group's mission. These will be collected in the working group's tracking issue, and when they become actionable they will be spun off into separate issues outside of the purview of the working group *per se*.