Picture this: We have a 3D character named Luntik, fully rigged and animation-ready. Luntik stars in a TV series where each episode brings a new adventure and, consequently, a new look. One episode features Luntik in a hat, another in a coat, and yet another in a winter jacket. For each of these variations, our rigging department creates a separate version of Luntik, each housed in its own Maya file with the new attire or props attached to the base model. The result? One base character and a multitude of Luntik variations.
Now, imagine discovering a major bug in the base rigged version of Luntik. The rigging artist fixes it in the main version - but what about all the other versions? Manually replicating this fix across, say, 10 different versions of Luntik is not only a headache but also an inefficient use of time.
The complexity multiplies when considering a cast of characters like Luntik, each with their unique episode-to-episode transformations. While using pure references in Maya – loading Luntik and his accessories as separate references, rigging them, and saving the result for later use – might seem like a solution, it’s fraught with problems. Nested reference edits tend to overlap, leading to potential system crashes and maintenance nightmares in Maya.
So, what's the solution? Could it be a 'recipes system'? No, not for cooking – for character rigging! Let’s dive into how this might work.
The concept behind the 'recipes editor' is straightforward yet ingenious. When a minor change is needed in a character's appearance, we start with the main character version and any additional elements (like a hat) in an empty scene as references. From there, we proceed with our rigging procedures. The final output is saved in a separate file, which meticulously records every aspect of the modification: all reference paths used, any newly created non-reference nodes (like constraints), and all changes to attributes, edits, and connections. This file can then be used to replicate the entire setup in any scene. Impressively, this system introduces all modifications directly within the scene, avoiding nested edits and relying solely on live updates.
While the recipes system was developed for our company's specific needs and its source code remains proprietary, its functionality is worth noting. To replicate all these changes, the recipe data encompasses:
Despite the complexity, saving a recipe is surprisingly swift, usually taking less than 10 seconds.
With the necessary data in hand, we proceed to integrate it into the scene using our recipe file. The process is methodical and must adhere to a specific sequence:
Each step is crucial and must be executed in the outlined order. For instance, nodes must be created before their attributes can be set.
Two aspects pose particular challenges: reference loading and node creation. The names of newly created nodes and loaded references generated in the scene will differ from those in our recipe file. Therefore, a mapping process is essential. Each created node and reference DAG node is mapped to its corresponding name in the recipe. This mapping is pivotal when applying reference edits and node connections, as it requires updating node names to match the scene's context.
In the node creation phase, especially with meshes, each type (like polygons, NURBS curves, and NURBS surfaces) requires specific coding for accurate recreation.
Once integrated into the scene, it's prudent to tag each created node with the recipe ID. This tagging is vital, given that a scene might contain multiple recipes or the same recipe applied multiple times. By marking each node with a unique recipe ID and name, we gain the ability to track and manage all recipes within the scene. Furthermore, this system enables the complete removal of a recipe by deleting all nodes associated with its ID.
A standout feature of our editor is the ability to apply recipes to characters that are already loaded and even animated in the scene. What does this mean in practice? Imagine you've loaded Luntik into a scene and started testing some animation. You can then apply a new recipe – let's say, adding a hat. The animated Luntik remains in the scene, with only the hat being added and the recipe applied seamlessly. The critical point here is ensuring that any newly loaded references, such as the hat, align with Luntik's current transformations. This ensures the hat appears correctly positioned on Luntik's head, rather than at the scene's origin.
It's possible that a recipe might need updating after it has been loaded into the scene. Since we're not working with traditional reference data, our editor includes a recipe reloading feature. However, this process can be delicate, especially if there are existing animations. For instance, suppose a supervisor informs you that the hat's design has changed, and the rigging department has updated the source recipe. You're now tasked with reloading this recipe, but Luntik is already animated, and the animator might have made several adjustments.
To handle this, we first preserve the current state of all nodes related to the recipe. Before removing any references, we disconnect all connections to ensure that linked animation curves and other nodes remain intact. Each recipe's initial load includes an attribute detailing its initial state – essentially the recipe file encoded as a string attribute. We store this initial state in memory. The next step involves completely removing the recipe from the scene, which includes deleting all nodes and related references. We then reload the recipe with the new hat and any other modifications.
The challenging part is reapplying the recipe state judiciously. We need to discern which changes to retain and which to discard. If we reapply everything, we'll end up with the original recipe, pre-reload. This is managed by comparing the initial version of the recipe with the newly reloaded one, filtering out changes that would override recent updates. For instance, if attribute A's value has been altered, we omit this change from the animator's data. The result? Luntik gets his new hat, the recipe is updated, and the animator’s work is preserved. Let’s visually walk through this process again:
While this recipe system is a significant improvement, it's important to note that it doesn't entirely replace the need for distinct character versions. Major changes to characters should still be handled in separate Maya files. However, for smaller alterations, this recipe system proves to be an effective solution. There are, however, some challenges in its current usage:
Overall, while the recipe system streamlines certain aspects of character modification, its application is most effective for minor updates, with room for future enhancements to address these identified challenges.