2023-05-31 16:19:06 +02:00
|
|
|
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup bke
|
2011-02-27 20:40:57 +00:00
|
|
|
*/
|
|
|
|
|
|
2023-07-22 11:27:25 +10:00
|
|
|
#include <cmath>
|
|
|
|
|
#include <cstddef>
|
|
|
|
|
#include <cstdlib>
|
|
|
|
|
#include <cstring>
|
2023-05-26 19:17:51 +02:00
|
|
|
#include <optional>
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
2020-09-10 11:02:42 +02:00
|
|
|
/* Allow using deprecated functionality for .blend file I/O. */
|
|
|
|
|
#define DNA_DEPRECATED_ALLOW
|
|
|
|
|
|
2.5: Blender "Animato" - New Animation System
Finally, here is the basic (functional) prototype of the new animation system which will allow for the infamous "everything is animatable", and which also addresses several of the more serious shortcomings of the old system. Unfortunately, this will break old animation files (especially right now, as I haven't written the version patching code yet), however, this is for the future.
Highlights of the new system:
* Scrapped IPO-Curves/IPO/(Action+Constraint-Channels)/Action system, and replaced it with F-Curve/Action.
- F-Curves (animators from other packages will feel at home with this name) replace IPO-Curves.
- The 'new' Actions, act as the containers for F-Curves, so that they can be reused. They are therefore more akin to the old 'IPO' blocks, except they do not have the blocktype restriction, so you can store materials/texture/geometry F-Curves in the same Action as Object transforms, etc.
* F-Curves use RNA-paths for Data Access, hence allowing "every" (where sensible/editable that is) user-accessible setting from RNA to be animated.
* Drivers are no longer mixed with Animation Data, so rigs will not be that easily broken and several dependency problems can be eliminated. (NOTE: drivers haven't been hooked up yet, but the code is in place)
* F-Curve modifier system allows useful 'large-scale' manipulation of F-Curve values, including (I've only included implemented ones here): envelope deform (similar to lattices to allow broad-scale reshaping of curves), curve generator (polynomial or py-expression), cycles (replacing the old cyclic extrapolation modes, giving more control over this). (NOTE: currently this cannot be tested, as there's not access to them, but the code is all in place)
* NLA system with 'tracks' (i.e. layers), and multiple strips per track. (NOTE: NLA system is not yet functional, as it's only partially coded still)
There are more nice things that I will be preparing some nice docs for soon, but for now, check for more details:
http://lists.blender.org/pipermail/bf-taskforce25/2009-January/000260.html
So, what currently works:
* I've implemented two basic operators for the 3D-view only to Insert and Delete Keyframes. These are tempolary ones only that will be replaced in due course with 'proper' code.
* Object Loc/Rot/Scale can be keyframed. Also, the colour of the 'active' material (Note: this should really be for nth material instead, but that doesn't work yet in RNA) can also be keyframed into the same datablock.
* Standard animation refresh (i.e. animation resulting from NLA and Action evaluation) is now done completely separate from drivers before anything else is done after a frame change. Drivers are handled after this in a separate pass, as dictated by depsgraph flags, etc.
Notes:
* Drivers haven't been hooked up yet
* Only objects and data directly linked to objects can be animated.
* Depsgraph will need further tweaks. Currently, I've only made sure that it will update some things in the most basic cases (i.e. frame change).
* Animation Editors are currently broken (in terms of editing stuff). This will be my next target (priority to get Dopesheet working first, then F-Curve editor - i.e. old IPO Editor)
* I've had to put in large chunks of XXX sandboxing for old animation system code all around the place. This will be cleaned up in due course, as some places need special review.
In particular, the particles and sequencer code have far too many manual calls to calculate + flush animation info, which is really bad (this is a 'please explain yourselves' call to Physics coders!).
2009-01-17 03:12:50 +00:00
|
|
|
#include "DNA_anim_types.h"
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
#include "DNA_armature_types.h"
|
|
|
|
|
#include "DNA_constraint_types.h"
|
2010-08-04 04:01:27 +00:00
|
|
|
#include "DNA_object_types.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "DNA_scene_types.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_blenlib.h"
|
2024-10-07 10:45:11 +02:00
|
|
|
#include "BLI_endian_switch.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_ghash.h"
|
Cleanup: reduce amount of math-related includes
Using ClangBuildAnalyzer on the whole Blender build, it was pointing
out that BLI_math.h is the heaviest "header hub" (i.e. non tiny file
that is included a lot).
However, there's very little (actually zero) source files in Blender
that need "all the math" (base, colors, vectors, matrices,
quaternions, intersection, interpolation, statistics, solvers and
time). A common use case is source files needing just vectors, or
just vectors & matrices, or just colors etc. Actually, 181 files
were including the whole math thing without needing it at all.
This change removes BLI_math.h completely, and instead in all the
places that need it, includes BLI_math_vector.h or BLI_math_color.h
and so on.
Change from that:
- BLI_math_color.h was included 1399 times -> now 408 (took 114.0sec
to parse -> now 36.3sec)
- BLI_simd.h 1403 -> 418 (109.7sec -> 34.9sec).
Full rebuild of Blender (Apple M1, Xcode, RelWithDebInfo) is not
affected much (342sec -> 334sec). Most of benefit would be when
someone's changing BLI_simd.h or BLI_math_color.h or similar files,
that now there's 3x fewer files result in a recompile.
Pull Request #110944
2023-08-09 11:39:20 +03:00
|
|
|
#include "BLI_math_color.h"
|
|
|
|
|
#include "BLI_math_matrix.h"
|
|
|
|
|
#include "BLI_math_rotation.h"
|
|
|
|
|
#include "BLI_math_vector.h"
|
2024-01-22 13:47:13 +01:00
|
|
|
#include "BLI_session_uid.h"
|
2023-10-18 17:15:30 +02:00
|
|
|
#include "BLI_string_utils.hh"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
|
|
|
|
|
2024-02-09 18:59:42 +01:00
|
|
|
#include "BLT_translation.hh"
|
2013-03-25 08:29:06 +00:00
|
|
|
|
2024-10-14 13:59:06 +02:00
|
|
|
#include "BLO_read_write.hh"
|
|
|
|
|
|
2024-09-10 14:55:47 +02:00
|
|
|
#include "BKE_action.hh"
|
2024-02-28 11:51:03 +01:00
|
|
|
#include "BKE_anim_data.hh"
|
2020-04-03 11:35:04 +02:00
|
|
|
#include "BKE_anim_visualization.h"
|
2013-03-25 08:29:06 +00:00
|
|
|
#include "BKE_animsys.h"
|
2023-11-16 11:41:55 +01:00
|
|
|
#include "BKE_armature.hh"
|
|
|
|
|
#include "BKE_asset.hh"
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
#include "BKE_constraint.h"
|
2024-01-29 18:57:16 -05:00
|
|
|
#include "BKE_deform.hh"
|
2024-03-05 18:39:08 +01:00
|
|
|
#include "BKE_fcurve.hh"
|
2024-03-26 12:57:30 -04:00
|
|
|
#include "BKE_idprop.hh"
|
2024-01-20 19:17:36 +01:00
|
|
|
#include "BKE_idtype.hh"
|
2024-01-15 12:44:04 -05:00
|
|
|
#include "BKE_lib_id.hh"
|
2024-01-18 12:20:42 +01:00
|
|
|
#include "BKE_lib_query.hh"
|
2023-12-01 19:43:16 +01:00
|
|
|
#include "BKE_main.hh"
|
2023-10-09 23:41:53 +02:00
|
|
|
#include "BKE_object.hh"
|
2023-11-16 09:16:48 +01:00
|
|
|
#include "BKE_object_types.hh"
|
2023-09-04 18:02:16 +02:00
|
|
|
#include "BKE_preview_image.hh"
|
2011-01-07 19:18:31 +00:00
|
|
|
|
2023-09-22 03:18:17 +02:00
|
|
|
#include "DEG_depsgraph.hh"
|
|
|
|
|
#include "DEG_depsgraph_build.hh"
|
2017-04-06 16:11:50 +02:00
|
|
|
|
2009-09-24 21:22:24 +00:00
|
|
|
#include "BIK_api.h"
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
|
2023-08-10 22:40:27 +02:00
|
|
|
#include "RNA_access.hh"
|
|
|
|
|
#include "RNA_path.hh"
|
2024-07-10 18:30:02 +02:00
|
|
|
#include "RNA_prototypes.hh"
|
2009-04-15 12:59:49 +00:00
|
|
|
|
2023-08-28 15:01:05 +02:00
|
|
|
#include "BLO_read_write.hh"
|
2020-09-10 11:02:42 +02:00
|
|
|
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
#include "ANIM_action.hh"
|
2024-09-25 09:33:04 +02:00
|
|
|
#include "ANIM_action_legacy.hh"
|
2023-12-05 15:05:28 +01:00
|
|
|
#include "ANIM_bone_collections.hh"
|
Anim: move bone colors from bone groups to individual bones
Move control over the color of bones from bone groups to the bones
themselves. Instead of using bone groups (which are defined on the pose,
and thus owned by the object), the color is stored on:
- the bone (`struct Bone`, or RNA `armature.bones['bone_name'].color`)
- a possible override on the pose bone (`struct bPoseChannel`, or RNA
`ob.pose.bones['bone_name'].color`).
When the pose bone is set to its default color, the color is determined
by the armature bone. In armature edit mode, the armature bone colors
are always used, as then the pose data is unavailable.
Versioning code converts bone group colors to bone colors. If the
Armature has a single user, the group color is stored on the bones
directly. If it has multiple users, the group colors will be stored on
the pose bones instead.
The bone group color is not removed from DNA for forward compatibility,
that is, to avoid immediate dataloss when saving a 3.6 file with 4.0.
This is part of the replacement of bone groups & armature layers with
bone collections. See the design task at #108941.
Pull request: https://projects.blender.org/blender/blender/pulls/109976
2023-08-22 11:11:52 +02:00
|
|
|
#include "ANIM_bonecolor.hh"
|
|
|
|
|
|
2019-02-01 12:44:19 +11:00
|
|
|
#include "CLG_log.h"
|
|
|
|
|
|
|
|
|
|
static CLG_LogRef LOG = {"bke.action"};
|
|
|
|
|
|
2024-09-25 09:33:04 +02:00
|
|
|
using namespace blender;
|
|
|
|
|
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
/* *********************** NOTE ON POSE AND ACTION **********************
|
2012-03-03 20:19:11 +00:00
|
|
|
*
|
|
|
|
|
* - Pose is the local (object level) component of armature. The current
|
|
|
|
|
* object pose is saved in files, and (will be) is presorted for dependency
|
|
|
|
|
* - Actions have fewer (or other) channels, and write data to a Pose
|
2012-05-05 16:03:57 +00:00
|
|
|
* - Currently ob->pose data is controlled in BKE_pose_where_is only. The (recalc)
|
2012-03-03 20:19:11 +00:00
|
|
|
* event system takes care of calling that
|
|
|
|
|
* - The NLA system (here too) uses Poses as interpolation format for Actions
|
|
|
|
|
* - Therefore we assume poses to be static, and duplicates of poses have channels in
|
|
|
|
|
* same order, for quick interpolation reasons
|
|
|
|
|
*
|
|
|
|
|
* ****************************** (ton) ************************************ */
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
|
2020-03-06 16:35:23 +01:00
|
|
|
/**************************** Action Datablock ******************************/
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
|
2020-03-06 16:35:23 +01:00
|
|
|
/*********************** Armature Datablock ***********************/
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
namespace blender::bke {
|
2011-06-29 04:34:20 +00:00
|
|
|
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
/**
|
2019-04-27 12:07:07 +10:00
|
|
|
* Only copy internal data of Action ID from source
|
|
|
|
|
* to already allocated/initialized destination.
|
|
|
|
|
* You probably never want to use that directly,
|
|
|
|
|
* use #BKE_id_copy or #BKE_id_copy_ex for typical needs.
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
*
|
|
|
|
|
* WARNING! This function will not handle ID user count!
|
|
|
|
|
*
|
2024-01-15 12:44:04 -05:00
|
|
|
* \param flag: Copying options (see BKE_lib_id.hh's LIB_ID_COPY_... flags for more).
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
*/
|
2023-05-26 19:17:51 +02:00
|
|
|
static void action_copy_data(Main * /*bmain*/,
|
|
|
|
|
std::optional<Library *> /*owner_library*/,
|
|
|
|
|
ID *id_dst,
|
|
|
|
|
const ID *id_src,
|
|
|
|
|
const int flag)
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
{
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
bAction *dna_action_dst = reinterpret_cast<bAction *>(id_dst);
|
|
|
|
|
animrig::Action &action_dst = dna_action_dst->wrap();
|
|
|
|
|
|
|
|
|
|
const bAction *dna_action_src = reinterpret_cast<const bAction *>(id_src);
|
|
|
|
|
const animrig::Action &action_src = dna_action_src->wrap();
|
2020-03-06 16:35:23 +01:00
|
|
|
|
|
|
|
|
bActionGroup *group_dst, *group_src;
|
|
|
|
|
FCurve *fcurve_dst, *fcurve_src;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-06 16:35:23 +01:00
|
|
|
/* Duplicate the lists of groups and markers. */
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
BLI_duplicatelist(&action_dst.groups, &action_src.groups);
|
|
|
|
|
BLI_duplicatelist(&action_dst.markers, &action_src.markers);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-06 16:35:23 +01:00
|
|
|
/* Copy F-Curves, fixing up the links as we go. */
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
BLI_listbase_clear(&action_dst.curves);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
for (fcurve_src = static_cast<FCurve *>(action_src.curves.first); fcurve_src;
|
2023-07-17 10:46:26 +02:00
|
|
|
fcurve_src = fcurve_src->next)
|
|
|
|
|
{
|
2020-03-06 16:35:23 +01:00
|
|
|
/* Duplicate F-Curve. */
|
2019-04-27 12:07:07 +10:00
|
|
|
|
2023-07-09 21:22:31 +10:00
|
|
|
/* XXX TODO: pass sub-data flag?
|
2023-01-03 10:19:27 +11:00
|
|
|
* But surprisingly does not seem to be doing any ID reference-counting. */
|
2020-06-05 09:30:15 +02:00
|
|
|
fcurve_dst = BKE_fcurve_copy(fcurve_src);
|
2019-04-27 12:07:07 +10:00
|
|
|
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
BLI_addtail(&action_dst.curves, fcurve_dst);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-09-16 18:13:19 +10:00
|
|
|
/* Fix group links (kind of bad list-in-list search, but this is the most reliable way). */
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
for (group_dst = static_cast<bActionGroup *>(action_dst.groups.first),
|
|
|
|
|
group_src = static_cast<bActionGroup *>(action_src.groups.first);
|
2020-03-06 16:35:23 +01:00
|
|
|
group_dst && group_src;
|
|
|
|
|
group_dst = group_dst->next, group_src = group_src->next)
|
|
|
|
|
{
|
|
|
|
|
if (fcurve_src->grp == group_src) {
|
|
|
|
|
fcurve_dst->grp = group_dst;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-06 16:35:23 +01:00
|
|
|
if (group_dst->channels.first == fcurve_src) {
|
|
|
|
|
group_dst->channels.first = fcurve_dst;
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
}
|
2020-03-06 16:35:23 +01:00
|
|
|
if (group_dst->channels.last == fcurve_src) {
|
|
|
|
|
group_dst->channels.last = fcurve_dst;
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
}
|
2009-04-13 11:15:43 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-02-04 14:17:50 +01:00
|
|
|
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
/* Copy all simple properties. */
|
|
|
|
|
action_dst.layer_array_num = action_src.layer_array_num;
|
|
|
|
|
action_dst.layer_active_index = action_src.layer_active_index;
|
2024-07-05 16:59:34 +02:00
|
|
|
action_dst.slot_array_num = action_src.slot_array_num;
|
|
|
|
|
action_dst.last_slot_handle = action_src.last_slot_handle;
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
|
Anim: change how action strip data is stored
This updates the layered action data model to store strip data differently. Specifically:
- `Strip` is now just a single, POD type that only stores the data common to all
strips, such as start/end frames.
- The data that might be of a completely different nature between strips (e.g.
keyframe data vs modifier data) is now stored in arrays on the action itself.
- `Strip`s indicate their type with an enum, and specify their data with an
index into the array on the action that stores data for that type.
This approach requires a little more data juggling, but has the advantage of
making `Strip`s themselves super simple POD types, and also opening the door to
trivial strip instancing later on: instances are just strips that point at the
same data.
The intention is that the RNA API remains the same: from RNA's perspective there
is no data storage separate from the strips, and a strip's data is presented as
fields and methods directly on the strip itself. Different strip types will be
presented as different subtypes of `ActionStrip`, each with their own fields and
methods specific to their underlying data's type. However, this PR doesn't
implement that sub-typing, leaving it for a future PR. It does, however, put the
fields and methods of the one strip type we have so far directly on the strip,
which avoids changing the APIs we have so far.
This PR implements the bulk of this new approach, and everything should be
functional and working correctly. However, there are two TODO items left over
that will be implemented in forthcoming PRs:
- Type refinement in the RNA api. This PR actually removes the existing type
refinement code that was implemented in terms of the inheritance tree of the
actual C++ types, and this will need to be reimplemented in terms of the new
data model. The RNA API still works without the type refinement since there
are only keyframe strips right now, but it will be needed in preparation for
more strip types down the road.
- Strip data deletion. This PR only deletes data from the strip data arrays when
the whole action is deleted, and otherwise just accumulates strip data as more
and more strips are added, never removing the data when the corresponding
strips get removed. That's fine in the short term, especially since we only
support single strips right now. But it does need to be implemented in
preparation for proper layered actions.
Pull Request: https://projects.blender.org/blender/blender/pulls/126559
2024-09-17 17:31:09 +02:00
|
|
|
/* Layers, and (recursively) Strips. */
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
action_dst.layer_array = MEM_cnew_array<ActionLayer *>(action_src.layer_array_num, __func__);
|
|
|
|
|
for (int i : action_src.layers().index_range()) {
|
2024-09-17 18:55:30 +02:00
|
|
|
action_dst.layer_array[i] = action_src.layer(i)->duplicate_with_shallow_strip_copies(__func__);
|
Anim: change how action strip data is stored
This updates the layered action data model to store strip data differently. Specifically:
- `Strip` is now just a single, POD type that only stores the data common to all
strips, such as start/end frames.
- The data that might be of a completely different nature between strips (e.g.
keyframe data vs modifier data) is now stored in arrays on the action itself.
- `Strip`s indicate their type with an enum, and specify their data with an
index into the array on the action that stores data for that type.
This approach requires a little more data juggling, but has the advantage of
making `Strip`s themselves super simple POD types, and also opening the door to
trivial strip instancing later on: instances are just strips that point at the
same data.
The intention is that the RNA API remains the same: from RNA's perspective there
is no data storage separate from the strips, and a strip's data is presented as
fields and methods directly on the strip itself. Different strip types will be
presented as different subtypes of `ActionStrip`, each with their own fields and
methods specific to their underlying data's type. However, this PR doesn't
implement that sub-typing, leaving it for a future PR. It does, however, put the
fields and methods of the one strip type we have so far directly on the strip,
which avoids changing the APIs we have so far.
This PR implements the bulk of this new approach, and everything should be
functional and working correctly. However, there are two TODO items left over
that will be implemented in forthcoming PRs:
- Type refinement in the RNA api. This PR actually removes the existing type
refinement code that was implemented in terms of the inheritance tree of the
actual C++ types, and this will need to be reimplemented in terms of the new
data model. The RNA API still works without the type refinement since there
are only keyframe strips right now, but it will be needed in preparation for
more strip types down the road.
- Strip data deletion. This PR only deletes data from the strip data arrays when
the whole action is deleted, and otherwise just accumulates strip data as more
and more strips are added, never removing the data when the corresponding
strips get removed. That's fine in the short term, especially since we only
support single strips right now. But it does need to be implemented in
preparation for proper layered actions.
Pull Request: https://projects.blender.org/blender/blender/pulls/126559
2024-09-17 17:31:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Strip data. */
|
|
|
|
|
action_dst.strip_keyframe_data_array = MEM_cnew_array<ActionStripKeyframeData *>(
|
|
|
|
|
action_src.strip_keyframe_data_array_num, __func__);
|
|
|
|
|
for (int i : action_src.strip_keyframe_data().index_range()) {
|
|
|
|
|
action_dst.strip_keyframe_data_array[i] = MEM_new<animrig::StripKeyframeData>(
|
|
|
|
|
__func__, *action_src.strip_keyframe_data()[i]);
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
}
|
|
|
|
|
|
2024-07-05 16:59:34 +02:00
|
|
|
/* Slots. */
|
|
|
|
|
action_dst.slot_array = MEM_cnew_array<ActionSlot *>(action_src.slot_array_num, __func__);
|
|
|
|
|
for (int i : action_src.slots().index_range()) {
|
|
|
|
|
action_dst.slot_array[i] = MEM_new<animrig::Slot>(__func__, *action_src.slot(i));
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
}
|
|
|
|
|
|
2021-02-04 14:17:50 +01:00
|
|
|
if (flag & LIB_ID_COPY_NO_PREVIEW) {
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
action_dst.preview = nullptr;
|
2021-02-04 14:17:50 +01:00
|
|
|
}
|
|
|
|
|
else {
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
BKE_previewimg_id_copy(&action_dst.id, &action_src.id);
|
2021-02-04 14:17:50 +01:00
|
|
|
}
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
}
|
2015-01-09 09:52:51 +01:00
|
|
|
|
2020-03-06 16:35:23 +01:00
|
|
|
/** Free (or release) any data used by this action (does not free the action itself). */
|
2023-06-03 08:36:28 +10:00
|
|
|
static void action_free_data(ID *id)
|
2020-03-06 16:35:23 +01:00
|
|
|
{
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
animrig::Action &action = reinterpret_cast<bAction *>(id)->wrap();
|
|
|
|
|
|
Anim: change how action strip data is stored
This updates the layered action data model to store strip data differently. Specifically:
- `Strip` is now just a single, POD type that only stores the data common to all
strips, such as start/end frames.
- The data that might be of a completely different nature between strips (e.g.
keyframe data vs modifier data) is now stored in arrays on the action itself.
- `Strip`s indicate their type with an enum, and specify their data with an
index into the array on the action that stores data for that type.
This approach requires a little more data juggling, but has the advantage of
making `Strip`s themselves super simple POD types, and also opening the door to
trivial strip instancing later on: instances are just strips that point at the
same data.
The intention is that the RNA API remains the same: from RNA's perspective there
is no data storage separate from the strips, and a strip's data is presented as
fields and methods directly on the strip itself. Different strip types will be
presented as different subtypes of `ActionStrip`, each with their own fields and
methods specific to their underlying data's type. However, this PR doesn't
implement that sub-typing, leaving it for a future PR. It does, however, put the
fields and methods of the one strip type we have so far directly on the strip,
which avoids changing the APIs we have so far.
This PR implements the bulk of this new approach, and everything should be
functional and working correctly. However, there are two TODO items left over
that will be implemented in forthcoming PRs:
- Type refinement in the RNA api. This PR actually removes the existing type
refinement code that was implemented in terms of the inheritance tree of the
actual C++ types, and this will need to be reimplemented in terms of the new
data model. The RNA API still works without the type refinement since there
are only keyframe strips right now, but it will be needed in preparation for
more strip types down the road.
- Strip data deletion. This PR only deletes data from the strip data arrays when
the whole action is deleted, and otherwise just accumulates strip data as more
and more strips are added, never removing the data when the corresponding
strips get removed. That's fine in the short term, especially since we only
support single strips right now. But it does need to be implemented in
preparation for proper layered actions.
Pull Request: https://projects.blender.org/blender/blender/pulls/126559
2024-09-17 17:31:09 +02:00
|
|
|
/* Free keyframe data. */
|
|
|
|
|
for (animrig::StripKeyframeData *keyframe_data : action.strip_keyframe_data()) {
|
|
|
|
|
MEM_delete(keyframe_data);
|
|
|
|
|
}
|
|
|
|
|
MEM_SAFE_FREE(action.strip_keyframe_data_array);
|
|
|
|
|
action.strip_keyframe_data_array_num = 0;
|
|
|
|
|
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
/* Free layers. */
|
|
|
|
|
for (animrig::Layer *layer : action.layers()) {
|
|
|
|
|
MEM_delete(layer);
|
|
|
|
|
}
|
|
|
|
|
MEM_SAFE_FREE(action.layer_array);
|
|
|
|
|
action.layer_array_num = 0;
|
2020-03-06 16:35:23 +01:00
|
|
|
|
2024-07-05 16:59:34 +02:00
|
|
|
/* Free slots. */
|
|
|
|
|
for (animrig::Slot *slot : action.slots()) {
|
|
|
|
|
MEM_delete(slot);
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
}
|
2024-07-05 16:59:34 +02:00
|
|
|
MEM_SAFE_FREE(action.slot_array);
|
|
|
|
|
action.slot_array_num = 0;
|
2020-03-06 16:35:23 +01:00
|
|
|
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
/* Free legacy F-Curves & groups. */
|
|
|
|
|
BKE_fcurves_free(&action.curves);
|
|
|
|
|
BLI_freelistN(&action.groups);
|
2020-03-06 16:35:23 +01:00
|
|
|
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
/* Free markers & preview. */
|
|
|
|
|
BLI_freelistN(&action.markers);
|
|
|
|
|
BKE_previewimg_free(&action.preview);
|
2021-02-04 14:17:50 +01:00
|
|
|
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
BLI_assert(action.is_empty());
|
2020-03-06 16:35:23 +01:00
|
|
|
}
|
|
|
|
|
|
2020-05-18 18:43:11 +02:00
|
|
|
static void action_foreach_id(ID *id, LibraryForeachIDData *data)
|
|
|
|
|
{
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
animrig::Action &action = reinterpret_cast<bAction *>(id)->wrap();
|
2024-06-13 14:27:36 +02:00
|
|
|
|
|
|
|
|
/* When this function is called without the IDWALK_READONLY flag, calls to
|
|
|
|
|
* BKE_LIB_FOREACHID_PROCESS_... macros can change ID pointers. ID remapping is the main example
|
|
|
|
|
* of such use.
|
|
|
|
|
*
|
|
|
|
|
* Those ID pointer changes are not guaranteed to be valid, though. For example, the remapping
|
|
|
|
|
* can be used to replace one Mesh with another, but that neither means that the new Mesh is
|
|
|
|
|
* animated with the same Action, nor that the old Mesh is no longer animated by that Action. In
|
|
|
|
|
* other words, the best that can be done is to invalidate the cache.
|
|
|
|
|
*
|
|
|
|
|
* NOTE: early-returns by BKE_LIB_FOREACHID_PROCESS_... macros are forbidden in non-readonly
|
|
|
|
|
* cases (see #IDWALK_RET_STOP_ITER documentation). */
|
|
|
|
|
|
2023-08-22 15:42:19 +02:00
|
|
|
const int flag = BKE_lib_query_foreachid_process_flags_get(data);
|
2024-06-13 14:27:36 +02:00
|
|
|
const bool is_readonly = flag & IDWALK_READONLY;
|
|
|
|
|
|
|
|
|
|
constexpr int idwalk_flags = IDWALK_CB_NEVER_SELF | IDWALK_CB_LOOPBACK;
|
|
|
|
|
|
|
|
|
|
Main *bmain = BKE_lib_query_foreachid_process_main_get(data);
|
|
|
|
|
|
|
|
|
|
if (is_readonly) {
|
|
|
|
|
/* bmain is still necessary to have, because in the read-only mode the cache
|
|
|
|
|
* may still be dirty, and we have no way to check. Without that knowledge
|
|
|
|
|
* it's possible to report invalid pointers, which should be avoided at all
|
|
|
|
|
* time. */
|
|
|
|
|
if (bmain) {
|
2024-07-05 16:59:34 +02:00
|
|
|
for (animrig::Slot *slot : action.slots()) {
|
|
|
|
|
for (ID *slot_user : slot->users(*bmain)) {
|
|
|
|
|
BKE_LIB_FOREACHID_PROCESS_ID(data, slot_user, idwalk_flags);
|
2024-06-13 14:27:36 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-07-05 16:59:34 +02:00
|
|
|
else if (bmain && !bmain->is_action_slot_to_id_map_dirty) {
|
2024-06-13 14:27:36 +02:00
|
|
|
/* Because BKE_library_foreach_ID_link() can be called with bmain=nullptr,
|
|
|
|
|
* there are cases where we do not know which `main` this is called for. An example is in
|
|
|
|
|
* `deg_eval_copy_on_write.cc`, function `deg_expand_eval_copy_datablock`.
|
|
|
|
|
*
|
|
|
|
|
* Also if the cache is already dirty, we shouldn't loop over the pointers in there. If we
|
2024-07-05 16:59:34 +02:00
|
|
|
* were to call `slot->users(*bmain)` in that case, it would rebuild the cache. But then
|
2024-06-13 14:27:36 +02:00
|
|
|
* another ID using the same Action may also trigger a rebuild of the cache, because another
|
|
|
|
|
* user pointer changed, forcing way too many rebuilds of the user map. */
|
|
|
|
|
bool should_invalidate = false;
|
|
|
|
|
|
2024-07-05 16:59:34 +02:00
|
|
|
for (animrig::Slot *slot : action.slots()) {
|
|
|
|
|
for (ID *slot_user : slot->runtime_users()) {
|
|
|
|
|
ID *old_pointer = slot_user;
|
|
|
|
|
BKE_LIB_FOREACHID_PROCESS_ID(data, slot_user, idwalk_flags);
|
|
|
|
|
/* If slot_user changed, the cache should be invalidated. */
|
|
|
|
|
should_invalidate |= (slot_user != old_pointer);
|
2024-06-13 14:27:36 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (should_invalidate) {
|
2024-07-05 16:59:34 +02:00
|
|
|
animrig::Slot::users_invalidate(*bmain);
|
2024-06-13 14:27:36 +02:00
|
|
|
}
|
|
|
|
|
}
|
2020-05-18 18:43:11 +02:00
|
|
|
|
2024-06-28 15:57:53 +02:00
|
|
|
/* Note that, even though `BKE_fcurve_foreach_id()` exists, it is not called here. That function
|
|
|
|
|
* is only relevant for drivers, but the F-Curves stored in an Action are always just animation
|
|
|
|
|
* data, not drivers. */
|
2020-05-26 11:53:00 +02:00
|
|
|
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
LISTBASE_FOREACH (TimeMarker *, marker, &action.markers) {
|
2021-10-26 10:40:36 +02:00
|
|
|
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, marker->camera, IDWALK_CB_NOP);
|
2020-05-18 18:43:11 +02:00
|
|
|
}
|
2023-08-22 15:42:19 +02:00
|
|
|
|
2024-06-28 15:57:53 +02:00
|
|
|
/* Legacy IPO curves. */
|
2023-08-22 15:42:19 +02:00
|
|
|
if (flag & IDWALK_DO_DEPRECATED_POINTERS) {
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
LISTBASE_FOREACH (bActionChannel *, chan, &action.chanbase) {
|
2023-08-22 15:42:19 +02:00
|
|
|
BKE_LIB_FOREACHID_PROCESS_ID_NOCHECK(data, chan->ipo, IDWALK_CB_USER);
|
|
|
|
|
LISTBASE_FOREACH (bConstraintChannel *, chan_constraint, &chan->constraintChannels) {
|
|
|
|
|
BKE_LIB_FOREACHID_PROCESS_ID_NOCHECK(data, chan_constraint->ipo, IDWALK_CB_USER);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-05-18 18:43:11 +02:00
|
|
|
}
|
|
|
|
|
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
static void write_channelbag(BlendWriter *writer, animrig::ChannelBag &channelbag)
|
|
|
|
|
{
|
|
|
|
|
BLO_write_struct(writer, ActionChannelBag, &channelbag);
|
|
|
|
|
|
Anim: add channel groups to layered actions
This PR adds channel groups (also known as fcurve groups or action groups) to
layered actions. For layered actions, these groups belong to the `ChannelBag`s
and can vary by bag.
From a user perspective, the goal is for these to function just like channel
groups from legacy actions. However, internally they are implemented a little
differently: legacy actions store both channel groups and fcurves in a listbase,
and groups indicate what fcurves are in them with a listbase that points
directly into the larger fcurve listbase. Layered actions, on the other hand,
store both fcurves and channel groups in an array, and groups indicate what
fcurves are in them by indexing into the fcurve array.
Despite taking this different approach, we still reuse the `bActionGroup` struct
for the new channel groups, just adding the necessary fields for index-based
fcurve membership as described above.
This PR does not implement all of the functionality needed to reach feature
parity with legacy action channel groups, but implements the main core and gets
them basically working.
It's easier to list the things that *haven't* been implemented yet:
- Operators for letting the user manually create/remove/move channel groups.
- Keyframe selection in the action/dopesheet editor on channel group rows
themselves are not yet working correctly.
- Handling channel groups in legacy/layered action conversion operators.
- Making the legacy `action.groups` property work on single-layer-single-strip
layered actions.
Those are left for future PRs. Other than that, in theory everything should be
working now.
Pull Request: https://projects.blender.org/blender/blender/pulls/125774
2024-08-22 17:13:12 +02:00
|
|
|
Span<bActionGroup *> groups = channelbag.channel_groups();
|
|
|
|
|
BLO_write_pointer_array(writer, groups.size(), groups.data());
|
2024-09-15 23:14:09 +10:00
|
|
|
for (const bActionGroup *group : groups) {
|
Anim: add channel groups to layered actions
This PR adds channel groups (also known as fcurve groups or action groups) to
layered actions. For layered actions, these groups belong to the `ChannelBag`s
and can vary by bag.
From a user perspective, the goal is for these to function just like channel
groups from legacy actions. However, internally they are implemented a little
differently: legacy actions store both channel groups and fcurves in a listbase,
and groups indicate what fcurves are in them with a listbase that points
directly into the larger fcurve listbase. Layered actions, on the other hand,
store both fcurves and channel groups in an array, and groups indicate what
fcurves are in them by indexing into the fcurve array.
Despite taking this different approach, we still reuse the `bActionGroup` struct
for the new channel groups, just adding the necessary fields for index-based
fcurve membership as described above.
This PR does not implement all of the functionality needed to reach feature
parity with legacy action channel groups, but implements the main core and gets
them basically working.
It's easier to list the things that *haven't* been implemented yet:
- Operators for letting the user manually create/remove/move channel groups.
- Keyframe selection in the action/dopesheet editor on channel group rows
themselves are not yet working correctly.
- Handling channel groups in legacy/layered action conversion operators.
- Making the legacy `action.groups` property work on single-layer-single-strip
layered actions.
Those are left for future PRs. Other than that, in theory everything should be
working now.
Pull Request: https://projects.blender.org/blender/blender/pulls/125774
2024-08-22 17:13:12 +02:00
|
|
|
BLO_write_struct(writer, bActionGroup, group);
|
|
|
|
|
}
|
|
|
|
|
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
Span<FCurve *> fcurves = channelbag.fcurves();
|
|
|
|
|
BLO_write_pointer_array(writer, fcurves.size(), fcurves.data());
|
|
|
|
|
for (FCurve *fcurve : fcurves) {
|
|
|
|
|
BLO_write_struct(writer, FCurve, fcurve);
|
|
|
|
|
BKE_fcurve_blend_write_data(writer, fcurve);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Anim: change how action strip data is stored
This updates the layered action data model to store strip data differently. Specifically:
- `Strip` is now just a single, POD type that only stores the data common to all
strips, such as start/end frames.
- The data that might be of a completely different nature between strips (e.g.
keyframe data vs modifier data) is now stored in arrays on the action itself.
- `Strip`s indicate their type with an enum, and specify their data with an
index into the array on the action that stores data for that type.
This approach requires a little more data juggling, but has the advantage of
making `Strip`s themselves super simple POD types, and also opening the door to
trivial strip instancing later on: instances are just strips that point at the
same data.
The intention is that the RNA API remains the same: from RNA's perspective there
is no data storage separate from the strips, and a strip's data is presented as
fields and methods directly on the strip itself. Different strip types will be
presented as different subtypes of `ActionStrip`, each with their own fields and
methods specific to their underlying data's type. However, this PR doesn't
implement that sub-typing, leaving it for a future PR. It does, however, put the
fields and methods of the one strip type we have so far directly on the strip,
which avoids changing the APIs we have so far.
This PR implements the bulk of this new approach, and everything should be
functional and working correctly. However, there are two TODO items left over
that will be implemented in forthcoming PRs:
- Type refinement in the RNA api. This PR actually removes the existing type
refinement code that was implemented in terms of the inheritance tree of the
actual C++ types, and this will need to be reimplemented in terms of the new
data model. The RNA API still works without the type refinement since there
are only keyframe strips right now, but it will be needed in preparation for
more strip types down the road.
- Strip data deletion. This PR only deletes data from the strip data arrays when
the whole action is deleted, and otherwise just accumulates strip data as more
and more strips are added, never removing the data when the corresponding
strips get removed. That's fine in the short term, especially since we only
support single strips right now. But it does need to be implemented in
preparation for proper layered actions.
Pull Request: https://projects.blender.org/blender/blender/pulls/126559
2024-09-17 17:31:09 +02:00
|
|
|
static void write_strip_keyframe_data(BlendWriter *writer,
|
|
|
|
|
animrig::StripKeyframeData &strip_keyframe_data)
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
{
|
Anim: change how action strip data is stored
This updates the layered action data model to store strip data differently. Specifically:
- `Strip` is now just a single, POD type that only stores the data common to all
strips, such as start/end frames.
- The data that might be of a completely different nature between strips (e.g.
keyframe data vs modifier data) is now stored in arrays on the action itself.
- `Strip`s indicate their type with an enum, and specify their data with an
index into the array on the action that stores data for that type.
This approach requires a little more data juggling, but has the advantage of
making `Strip`s themselves super simple POD types, and also opening the door to
trivial strip instancing later on: instances are just strips that point at the
same data.
The intention is that the RNA API remains the same: from RNA's perspective there
is no data storage separate from the strips, and a strip's data is presented as
fields and methods directly on the strip itself. Different strip types will be
presented as different subtypes of `ActionStrip`, each with their own fields and
methods specific to their underlying data's type. However, this PR doesn't
implement that sub-typing, leaving it for a future PR. It does, however, put the
fields and methods of the one strip type we have so far directly on the strip,
which avoids changing the APIs we have so far.
This PR implements the bulk of this new approach, and everything should be
functional and working correctly. However, there are two TODO items left over
that will be implemented in forthcoming PRs:
- Type refinement in the RNA api. This PR actually removes the existing type
refinement code that was implemented in terms of the inheritance tree of the
actual C++ types, and this will need to be reimplemented in terms of the new
data model. The RNA API still works without the type refinement since there
are only keyframe strips right now, but it will be needed in preparation for
more strip types down the road.
- Strip data deletion. This PR only deletes data from the strip data arrays when
the whole action is deleted, and otherwise just accumulates strip data as more
and more strips are added, never removing the data when the corresponding
strips get removed. That's fine in the short term, especially since we only
support single strips right now. But it does need to be implemented in
preparation for proper layered actions.
Pull Request: https://projects.blender.org/blender/blender/pulls/126559
2024-09-17 17:31:09 +02:00
|
|
|
BLO_write_struct(writer, ActionStripKeyframeData, &strip_keyframe_data);
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
|
Anim: change how action strip data is stored
This updates the layered action data model to store strip data differently. Specifically:
- `Strip` is now just a single, POD type that only stores the data common to all
strips, such as start/end frames.
- The data that might be of a completely different nature between strips (e.g.
keyframe data vs modifier data) is now stored in arrays on the action itself.
- `Strip`s indicate their type with an enum, and specify their data with an
index into the array on the action that stores data for that type.
This approach requires a little more data juggling, but has the advantage of
making `Strip`s themselves super simple POD types, and also opening the door to
trivial strip instancing later on: instances are just strips that point at the
same data.
The intention is that the RNA API remains the same: from RNA's perspective there
is no data storage separate from the strips, and a strip's data is presented as
fields and methods directly on the strip itself. Different strip types will be
presented as different subtypes of `ActionStrip`, each with their own fields and
methods specific to their underlying data's type. However, this PR doesn't
implement that sub-typing, leaving it for a future PR. It does, however, put the
fields and methods of the one strip type we have so far directly on the strip,
which avoids changing the APIs we have so far.
This PR implements the bulk of this new approach, and everything should be
functional and working correctly. However, there are two TODO items left over
that will be implemented in forthcoming PRs:
- Type refinement in the RNA api. This PR actually removes the existing type
refinement code that was implemented in terms of the inheritance tree of the
actual C++ types, and this will need to be reimplemented in terms of the new
data model. The RNA API still works without the type refinement since there
are only keyframe strips right now, but it will be needed in preparation for
more strip types down the road.
- Strip data deletion. This PR only deletes data from the strip data arrays when
the whole action is deleted, and otherwise just accumulates strip data as more
and more strips are added, never removing the data when the corresponding
strips get removed. That's fine in the short term, especially since we only
support single strips right now. But it does need to be implemented in
preparation for proper layered actions.
Pull Request: https://projects.blender.org/blender/blender/pulls/126559
2024-09-17 17:31:09 +02:00
|
|
|
auto channelbags = strip_keyframe_data.channelbags();
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
BLO_write_pointer_array(writer, channelbags.size(), channelbags.data());
|
|
|
|
|
|
|
|
|
|
for (animrig::ChannelBag *channelbag : channelbags) {
|
|
|
|
|
write_channelbag(writer, *channelbag);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Anim: change how action strip data is stored
This updates the layered action data model to store strip data differently. Specifically:
- `Strip` is now just a single, POD type that only stores the data common to all
strips, such as start/end frames.
- The data that might be of a completely different nature between strips (e.g.
keyframe data vs modifier data) is now stored in arrays on the action itself.
- `Strip`s indicate their type with an enum, and specify their data with an
index into the array on the action that stores data for that type.
This approach requires a little more data juggling, but has the advantage of
making `Strip`s themselves super simple POD types, and also opening the door to
trivial strip instancing later on: instances are just strips that point at the
same data.
The intention is that the RNA API remains the same: from RNA's perspective there
is no data storage separate from the strips, and a strip's data is presented as
fields and methods directly on the strip itself. Different strip types will be
presented as different subtypes of `ActionStrip`, each with their own fields and
methods specific to their underlying data's type. However, this PR doesn't
implement that sub-typing, leaving it for a future PR. It does, however, put the
fields and methods of the one strip type we have so far directly on the strip,
which avoids changing the APIs we have so far.
This PR implements the bulk of this new approach, and everything should be
functional and working correctly. However, there are two TODO items left over
that will be implemented in forthcoming PRs:
- Type refinement in the RNA api. This PR actually removes the existing type
refinement code that was implemented in terms of the inheritance tree of the
actual C++ types, and this will need to be reimplemented in terms of the new
data model. The RNA API still works without the type refinement since there
are only keyframe strips right now, but it will be needed in preparation for
more strip types down the road.
- Strip data deletion. This PR only deletes data from the strip data arrays when
the whole action is deleted, and otherwise just accumulates strip data as more
and more strips are added, never removing the data when the corresponding
strips get removed. That's fine in the short term, especially since we only
support single strips right now. But it does need to be implemented in
preparation for proper layered actions.
Pull Request: https://projects.blender.org/blender/blender/pulls/126559
2024-09-17 17:31:09 +02:00
|
|
|
static void write_strip_keyframe_data_array(
|
|
|
|
|
BlendWriter *writer, Span<animrig::StripKeyframeData *> strip_keyframe_data_array)
|
|
|
|
|
{
|
|
|
|
|
BLO_write_pointer_array(
|
|
|
|
|
writer, strip_keyframe_data_array.size(), strip_keyframe_data_array.data());
|
|
|
|
|
|
|
|
|
|
for (animrig::StripKeyframeData *keyframe_data : strip_keyframe_data_array) {
|
|
|
|
|
write_strip_keyframe_data(writer, *keyframe_data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
static void write_strips(BlendWriter *writer, Span<animrig::Strip *> strips)
|
|
|
|
|
{
|
|
|
|
|
BLO_write_pointer_array(writer, strips.size(), strips.data());
|
|
|
|
|
|
|
|
|
|
for (animrig::Strip *strip : strips) {
|
Anim: change how action strip data is stored
This updates the layered action data model to store strip data differently. Specifically:
- `Strip` is now just a single, POD type that only stores the data common to all
strips, such as start/end frames.
- The data that might be of a completely different nature between strips (e.g.
keyframe data vs modifier data) is now stored in arrays on the action itself.
- `Strip`s indicate their type with an enum, and specify their data with an
index into the array on the action that stores data for that type.
This approach requires a little more data juggling, but has the advantage of
making `Strip`s themselves super simple POD types, and also opening the door to
trivial strip instancing later on: instances are just strips that point at the
same data.
The intention is that the RNA API remains the same: from RNA's perspective there
is no data storage separate from the strips, and a strip's data is presented as
fields and methods directly on the strip itself. Different strip types will be
presented as different subtypes of `ActionStrip`, each with their own fields and
methods specific to their underlying data's type. However, this PR doesn't
implement that sub-typing, leaving it for a future PR. It does, however, put the
fields and methods of the one strip type we have so far directly on the strip,
which avoids changing the APIs we have so far.
This PR implements the bulk of this new approach, and everything should be
functional and working correctly. However, there are two TODO items left over
that will be implemented in forthcoming PRs:
- Type refinement in the RNA api. This PR actually removes the existing type
refinement code that was implemented in terms of the inheritance tree of the
actual C++ types, and this will need to be reimplemented in terms of the new
data model. The RNA API still works without the type refinement since there
are only keyframe strips right now, but it will be needed in preparation for
more strip types down the road.
- Strip data deletion. This PR only deletes data from the strip data arrays when
the whole action is deleted, and otherwise just accumulates strip data as more
and more strips are added, never removing the data when the corresponding
strips get removed. That's fine in the short term, especially since we only
support single strips right now. But it does need to be implemented in
preparation for proper layered actions.
Pull Request: https://projects.blender.org/blender/blender/pulls/126559
2024-09-17 17:31:09 +02:00
|
|
|
BLO_write_struct(writer, ActionStrip, strip);
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void write_layers(BlendWriter *writer, Span<animrig::Layer *> layers)
|
|
|
|
|
{
|
|
|
|
|
BLO_write_pointer_array(writer, layers.size(), layers.data());
|
|
|
|
|
|
|
|
|
|
for (animrig::Layer *layer : layers) {
|
|
|
|
|
BLO_write_struct(writer, ActionLayer, layer);
|
|
|
|
|
write_strips(writer, layer->strips());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-05 16:59:34 +02:00
|
|
|
static void write_slots(BlendWriter *writer, Span<animrig::Slot *> slots)
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
{
|
2024-07-05 16:59:34 +02:00
|
|
|
BLO_write_pointer_array(writer, slots.size(), slots.data());
|
|
|
|
|
for (animrig::Slot *slot : slots) {
|
2024-06-13 14:27:36 +02:00
|
|
|
/* Make a shallow copy using the C type, so that no new runtime struct is
|
|
|
|
|
* allocated for the copy. */
|
2024-07-05 16:59:34 +02:00
|
|
|
ActionSlot shallow_copy = *slot;
|
2024-06-13 14:27:36 +02:00
|
|
|
shallow_copy.runtime = nullptr;
|
|
|
|
|
|
2024-07-05 16:59:34 +02:00
|
|
|
BLO_write_struct_at_address(writer, ActionSlot, slot, &shallow_copy);
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
}
|
|
|
|
|
}
|
Anim: forward compatibility for F-Curves in layered Actions
When writing a layered Action to disk, take the F-Curves from the
first keyframe strip and write that as `action.curves` as well. This
will make older Blender versions see those curves and load them
properly.
Only the curves for the first slot are written this way. This means
that any legacy Action that was converted to a layered Action will be
loaded again properly by older Blender versions. Of course this is
limited to a single layer, single strip, and single slot -- once the
newer features are used, older versions of Blender will not be able to
see this extra data.
When an Action contains multiple slots, so with animation for multiple
distinct objects, the forward compatibility becomes a bit iffy. Older
versions of Blender will just see a legacy Action, with its legacy
semantics, and thus all objects that use that Action will receive the
exact same animation data. I don't think there's a way around this.
(_Unless we start breaking up Actions into an Action per slot, alter
the assignments, and then store metadata so that modern Blenders can
reassemble them. I do not think this is a good idea._)
Ref: #124714
Pull Request: https://projects.blender.org/blender/blender/pulls/125065
2024-07-26 11:13:40 +02:00
|
|
|
|
Anim: add channel groups to layered actions
This PR adds channel groups (also known as fcurve groups or action groups) to
layered actions. For layered actions, these groups belong to the `ChannelBag`s
and can vary by bag.
From a user perspective, the goal is for these to function just like channel
groups from legacy actions. However, internally they are implemented a little
differently: legacy actions store both channel groups and fcurves in a listbase,
and groups indicate what fcurves are in them with a listbase that points
directly into the larger fcurve listbase. Layered actions, on the other hand,
store both fcurves and channel groups in an array, and groups indicate what
fcurves are in them by indexing into the fcurve array.
Despite taking this different approach, we still reuse the `bActionGroup` struct
for the new channel groups, just adding the necessary fields for index-based
fcurve membership as described above.
This PR does not implement all of the functionality needed to reach feature
parity with legacy action channel groups, but implements the main core and gets
them basically working.
It's easier to list the things that *haven't* been implemented yet:
- Operators for letting the user manually create/remove/move channel groups.
- Keyframe selection in the action/dopesheet editor on channel group rows
themselves are not yet working correctly.
- Handling channel groups in legacy/layered action conversion operators.
- Making the legacy `action.groups` property work on single-layer-single-strip
layered actions.
Those are left for future PRs. Other than that, in theory everything should be
working now.
Pull Request: https://projects.blender.org/blender/blender/pulls/125774
2024-08-22 17:13:12 +02:00
|
|
|
/**
|
|
|
|
|
* Create a listbase from a Span of channel groups.
|
|
|
|
|
*
|
|
|
|
|
* \note this does NOT transfer ownership of the pointers. The ListBase should
|
|
|
|
|
* not be freed, but given to
|
|
|
|
|
* `action_blend_write_clear_legacy_channel_groups_listbase()` below.
|
|
|
|
|
*
|
|
|
|
|
* \warning This code is modifying actual '`Main`' data in-place, which is
|
|
|
|
|
* usually not acceptable (due to risks of unsafe concurrent accesses mainly).
|
|
|
|
|
* The reasons why this is currently seen as 'reasonably safe' are:
|
|
|
|
|
* - Current blender code is _not_ expected to access the affected bActionGroup data
|
|
|
|
|
* (`prev`/`next` listbase pointers) in any way, as they are stored in an array.
|
|
|
|
|
* - The `action.groups` listbase modification is safe/valid, as this is a member of
|
|
|
|
|
* the Action ID, which is a shallow copy of the actual ID data from Main.
|
|
|
|
|
*/
|
|
|
|
|
static void action_blend_write_make_legacy_channel_groups_listbase(
|
|
|
|
|
ListBase &listbase, const Span<bActionGroup *> channel_groups)
|
|
|
|
|
{
|
|
|
|
|
if (channel_groups.is_empty()) {
|
|
|
|
|
BLI_listbase_clear(&listbase);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Set the fcurve listbase pointers.
|
|
|
|
|
*
|
|
|
|
|
* Note that the fcurves' own prev/next pointers are hooked up by
|
|
|
|
|
* `action_blend_write_make_legacy_fcurves_listbase()`, so that they function
|
|
|
|
|
* properly as a list. */
|
|
|
|
|
for (bActionGroup *group : channel_groups) {
|
2024-08-29 19:12:45 +02:00
|
|
|
Span<FCurve *> fcurves = group->wrap().fcurves();
|
|
|
|
|
if (fcurves.is_empty()) {
|
Anim: add channel groups to layered actions
This PR adds channel groups (also known as fcurve groups or action groups) to
layered actions. For layered actions, these groups belong to the `ChannelBag`s
and can vary by bag.
From a user perspective, the goal is for these to function just like channel
groups from legacy actions. However, internally they are implemented a little
differently: legacy actions store both channel groups and fcurves in a listbase,
and groups indicate what fcurves are in them with a listbase that points
directly into the larger fcurve listbase. Layered actions, on the other hand,
store both fcurves and channel groups in an array, and groups indicate what
fcurves are in them by indexing into the fcurve array.
Despite taking this different approach, we still reuse the `bActionGroup` struct
for the new channel groups, just adding the necessary fields for index-based
fcurve membership as described above.
This PR does not implement all of the functionality needed to reach feature
parity with legacy action channel groups, but implements the main core and gets
them basically working.
It's easier to list the things that *haven't* been implemented yet:
- Operators for letting the user manually create/remove/move channel groups.
- Keyframe selection in the action/dopesheet editor on channel group rows
themselves are not yet working correctly.
- Handling channel groups in legacy/layered action conversion operators.
- Making the legacy `action.groups` property work on single-layer-single-strip
layered actions.
Those are left for future PRs. Other than that, in theory everything should be
working now.
Pull Request: https://projects.blender.org/blender/blender/pulls/125774
2024-08-22 17:13:12 +02:00
|
|
|
group->channels = {nullptr, nullptr};
|
|
|
|
|
}
|
2024-09-06 12:30:21 +02:00
|
|
|
else {
|
|
|
|
|
group->channels = {fcurves.first(), fcurves.last()};
|
|
|
|
|
}
|
Anim: add channel groups to layered actions
This PR adds channel groups (also known as fcurve groups or action groups) to
layered actions. For layered actions, these groups belong to the `ChannelBag`s
and can vary by bag.
From a user perspective, the goal is for these to function just like channel
groups from legacy actions. However, internally they are implemented a little
differently: legacy actions store both channel groups and fcurves in a listbase,
and groups indicate what fcurves are in them with a listbase that points
directly into the larger fcurve listbase. Layered actions, on the other hand,
store both fcurves and channel groups in an array, and groups indicate what
fcurves are in them by indexing into the fcurve array.
Despite taking this different approach, we still reuse the `bActionGroup` struct
for the new channel groups, just adding the necessary fields for index-based
fcurve membership as described above.
This PR does not implement all of the functionality needed to reach feature
parity with legacy action channel groups, but implements the main core and gets
them basically working.
It's easier to list the things that *haven't* been implemented yet:
- Operators for letting the user manually create/remove/move channel groups.
- Keyframe selection in the action/dopesheet editor on channel group rows
themselves are not yet working correctly.
- Handling channel groups in legacy/layered action conversion operators.
- Making the legacy `action.groups` property work on single-layer-single-strip
layered actions.
Those are left for future PRs. Other than that, in theory everything should be
working now.
Pull Request: https://projects.blender.org/blender/blender/pulls/125774
2024-08-22 17:13:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Determine the prev/next pointers on the elements. */
|
|
|
|
|
const int last_index = channel_groups.size() - 1;
|
|
|
|
|
for (int index : channel_groups.index_range()) {
|
|
|
|
|
channel_groups[index]->prev = (index > 0) ? channel_groups[index - 1] : nullptr;
|
|
|
|
|
channel_groups[index]->next = (index < last_index) ? channel_groups[index + 1] : nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
listbase.first = channel_groups[0];
|
|
|
|
|
listbase.last = channel_groups[last_index];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void action_blend_write_clear_legacy_channel_groups_listbase(ListBase &listbase)
|
|
|
|
|
{
|
2024-08-30 12:54:41 +02:00
|
|
|
LISTBASE_FOREACH_MUTABLE (bActionGroup *, group, &listbase) {
|
Anim: add channel groups to layered actions
This PR adds channel groups (also known as fcurve groups or action groups) to
layered actions. For layered actions, these groups belong to the `ChannelBag`s
and can vary by bag.
From a user perspective, the goal is for these to function just like channel
groups from legacy actions. However, internally they are implemented a little
differently: legacy actions store both channel groups and fcurves in a listbase,
and groups indicate what fcurves are in them with a listbase that points
directly into the larger fcurve listbase. Layered actions, on the other hand,
store both fcurves and channel groups in an array, and groups indicate what
fcurves are in them by indexing into the fcurve array.
Despite taking this different approach, we still reuse the `bActionGroup` struct
for the new channel groups, just adding the necessary fields for index-based
fcurve membership as described above.
This PR does not implement all of the functionality needed to reach feature
parity with legacy action channel groups, but implements the main core and gets
them basically working.
It's easier to list the things that *haven't* been implemented yet:
- Operators for letting the user manually create/remove/move channel groups.
- Keyframe selection in the action/dopesheet editor on channel group rows
themselves are not yet working correctly.
- Handling channel groups in legacy/layered action conversion operators.
- Making the legacy `action.groups` property work on single-layer-single-strip
layered actions.
Those are left for future PRs. Other than that, in theory everything should be
working now.
Pull Request: https://projects.blender.org/blender/blender/pulls/125774
2024-08-22 17:13:12 +02:00
|
|
|
group->prev = nullptr;
|
|
|
|
|
group->next = nullptr;
|
2024-08-27 17:02:18 +02:00
|
|
|
group->channels = {nullptr, nullptr};
|
Anim: add channel groups to layered actions
This PR adds channel groups (also known as fcurve groups or action groups) to
layered actions. For layered actions, these groups belong to the `ChannelBag`s
and can vary by bag.
From a user perspective, the goal is for these to function just like channel
groups from legacy actions. However, internally they are implemented a little
differently: legacy actions store both channel groups and fcurves in a listbase,
and groups indicate what fcurves are in them with a listbase that points
directly into the larger fcurve listbase. Layered actions, on the other hand,
store both fcurves and channel groups in an array, and groups indicate what
fcurves are in them by indexing into the fcurve array.
Despite taking this different approach, we still reuse the `bActionGroup` struct
for the new channel groups, just adding the necessary fields for index-based
fcurve membership as described above.
This PR does not implement all of the functionality needed to reach feature
parity with legacy action channel groups, but implements the main core and gets
them basically working.
It's easier to list the things that *haven't* been implemented yet:
- Operators for letting the user manually create/remove/move channel groups.
- Keyframe selection in the action/dopesheet editor on channel group rows
themselves are not yet working correctly.
- Handling channel groups in legacy/layered action conversion operators.
- Making the legacy `action.groups` property work on single-layer-single-strip
layered actions.
Those are left for future PRs. Other than that, in theory everything should be
working now.
Pull Request: https://projects.blender.org/blender/blender/pulls/125774
2024-08-22 17:13:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BLI_listbase_clear(&listbase);
|
|
|
|
|
}
|
|
|
|
|
|
Anim: forward compatibility for F-Curves in layered Actions
When writing a layered Action to disk, take the F-Curves from the
first keyframe strip and write that as `action.curves` as well. This
will make older Blender versions see those curves and load them
properly.
Only the curves for the first slot are written this way. This means
that any legacy Action that was converted to a layered Action will be
loaded again properly by older Blender versions. Of course this is
limited to a single layer, single strip, and single slot -- once the
newer features are used, older versions of Blender will not be able to
see this extra data.
When an Action contains multiple slots, so with animation for multiple
distinct objects, the forward compatibility becomes a bit iffy. Older
versions of Blender will just see a legacy Action, with its legacy
semantics, and thus all objects that use that Action will receive the
exact same animation data. I don't think there's a way around this.
(_Unless we start breaking up Actions into an Action per slot, alter
the assignments, and then store metadata so that modern Blenders can
reassemble them. I do not think this is a good idea._)
Ref: #124714
Pull Request: https://projects.blender.org/blender/blender/pulls/125065
2024-07-26 11:13:40 +02:00
|
|
|
/**
|
|
|
|
|
* Create a listbase from a Span of F-Curves.
|
|
|
|
|
*
|
|
|
|
|
* \note this does NOT transfer ownership of the pointers. The ListBase should not be freed,
|
|
|
|
|
* but given to `action_blend_write_clear_legacy_fcurves_listbase()` below.
|
|
|
|
|
*
|
|
|
|
|
* \warning This code is modifying actual '`Main`' data in-place, which is
|
|
|
|
|
* usually not acceptable (due to risks of unsafe concurrent accesses mainly).
|
|
|
|
|
* The reasons why this is currently seen as 'reasonably safe' are:
|
|
|
|
|
* - Current blender code is _not_ expected to access the affected FCurve data
|
|
|
|
|
* (`prev`/`next` listbase pointers) in any way, as they are stored in an array.
|
|
|
|
|
* - The `action.curves` listbase modification is safe/valid, as this is a member of
|
|
|
|
|
* the Action ID, which is a shallow copy of the actual ID data from Main.
|
|
|
|
|
*/
|
|
|
|
|
static void action_blend_write_make_legacy_fcurves_listbase(ListBase &listbase,
|
|
|
|
|
const Span<FCurve *> fcurves)
|
|
|
|
|
{
|
|
|
|
|
if (fcurves.is_empty()) {
|
|
|
|
|
BLI_listbase_clear(&listbase);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Determine the prev/next pointers on the elements. */
|
|
|
|
|
const int last_index = fcurves.size() - 1;
|
|
|
|
|
for (int index : fcurves.index_range()) {
|
|
|
|
|
fcurves[index]->prev = (index > 0) ? fcurves[index - 1] : nullptr;
|
|
|
|
|
fcurves[index]->next = (index < last_index) ? fcurves[index + 1] : nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
listbase.first = fcurves[0];
|
|
|
|
|
listbase.last = fcurves[last_index];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void action_blend_write_clear_legacy_fcurves_listbase(ListBase &listbase)
|
|
|
|
|
{
|
2024-08-30 12:54:41 +02:00
|
|
|
LISTBASE_FOREACH_MUTABLE (FCurve *, fcurve, &listbase) {
|
Anim: forward compatibility for F-Curves in layered Actions
When writing a layered Action to disk, take the F-Curves from the
first keyframe strip and write that as `action.curves` as well. This
will make older Blender versions see those curves and load them
properly.
Only the curves for the first slot are written this way. This means
that any legacy Action that was converted to a layered Action will be
loaded again properly by older Blender versions. Of course this is
limited to a single layer, single strip, and single slot -- once the
newer features are used, older versions of Blender will not be able to
see this extra data.
When an Action contains multiple slots, so with animation for multiple
distinct objects, the forward compatibility becomes a bit iffy. Older
versions of Blender will just see a legacy Action, with its legacy
semantics, and thus all objects that use that Action will receive the
exact same animation data. I don't think there's a way around this.
(_Unless we start breaking up Actions into an Action per slot, alter
the assignments, and then store metadata so that modern Blenders can
reassemble them. I do not think this is a good idea._)
Ref: #124714
Pull Request: https://projects.blender.org/blender/blender/pulls/125065
2024-07-26 11:13:40 +02:00
|
|
|
fcurve->prev = nullptr;
|
|
|
|
|
fcurve->next = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BLI_listbase_clear(&listbase);
|
|
|
|
|
}
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
|
2020-09-10 11:02:42 +02:00
|
|
|
static void action_blend_write(BlendWriter *writer, ID *id, const void *id_address)
|
|
|
|
|
{
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
animrig::Action &action = reinterpret_cast<bAction *>(id)->wrap();
|
2020-09-10 11:02:42 +02:00
|
|
|
|
Anim: forward compatibility for F-Curves in layered Actions
When writing a layered Action to disk, take the F-Curves from the
first keyframe strip and write that as `action.curves` as well. This
will make older Blender versions see those curves and load them
properly.
Only the curves for the first slot are written this way. This means
that any legacy Action that was converted to a layered Action will be
loaded again properly by older Blender versions. Of course this is
limited to a single layer, single strip, and single slot -- once the
newer features are used, older versions of Blender will not be able to
see this extra data.
When an Action contains multiple slots, so with animation for multiple
distinct objects, the forward compatibility becomes a bit iffy. Older
versions of Blender will just see a legacy Action, with its legacy
semantics, and thus all objects that use that Action will receive the
exact same animation data. I don't think there's a way around this.
(_Unless we start breaking up Actions into an Action per slot, alter
the assignments, and then store metadata so that modern Blenders can
reassemble them. I do not think this is a good idea._)
Ref: #124714
Pull Request: https://projects.blender.org/blender/blender/pulls/125065
2024-07-26 11:13:40 +02:00
|
|
|
/* Create legacy data for Layered Actions: the F-Curves from the first Slot,
|
|
|
|
|
* bottom layer, first Keyframe strip. */
|
|
|
|
|
const bool do_write_forward_compat = !BLO_write_is_undo(writer) && action.slot_array_num > 0 &&
|
|
|
|
|
action.is_action_layered();
|
|
|
|
|
if (do_write_forward_compat) {
|
|
|
|
|
animrig::assert_baklava_phase_1_invariants(action);
|
|
|
|
|
BLI_assert_msg(BLI_listbase_is_empty(&action.curves),
|
|
|
|
|
"Layered Action should not have legacy data");
|
|
|
|
|
BLI_assert_msg(BLI_listbase_is_empty(&action.groups),
|
|
|
|
|
"Layered Action should not have legacy data");
|
|
|
|
|
|
|
|
|
|
const animrig::Slot &first_slot = *action.slot(0);
|
Anim: add channel groups to layered actions
This PR adds channel groups (also known as fcurve groups or action groups) to
layered actions. For layered actions, these groups belong to the `ChannelBag`s
and can vary by bag.
From a user perspective, the goal is for these to function just like channel
groups from legacy actions. However, internally they are implemented a little
differently: legacy actions store both channel groups and fcurves in a listbase,
and groups indicate what fcurves are in them with a listbase that points
directly into the larger fcurve listbase. Layered actions, on the other hand,
store both fcurves and channel groups in an array, and groups indicate what
fcurves are in them by indexing into the fcurve array.
Despite taking this different approach, we still reuse the `bActionGroup` struct
for the new channel groups, just adding the necessary fields for index-based
fcurve membership as described above.
This PR does not implement all of the functionality needed to reach feature
parity with legacy action channel groups, but implements the main core and gets
them basically working.
It's easier to list the things that *haven't* been implemented yet:
- Operators for letting the user manually create/remove/move channel groups.
- Keyframe selection in the action/dopesheet editor on channel group rows
themselves are not yet working correctly.
- Handling channel groups in legacy/layered action conversion operators.
- Making the legacy `action.groups` property work on single-layer-single-strip
layered actions.
Those are left for future PRs. Other than that, in theory everything should be
working now.
Pull Request: https://projects.blender.org/blender/blender/pulls/125774
2024-08-22 17:13:12 +02:00
|
|
|
|
|
|
|
|
/* Note: channel group forward-compat data requires that fcurve
|
|
|
|
|
* forward-compat legacy data is also written, and vice-versa. Both have
|
|
|
|
|
* pointers to each other that won't resolve properly when loaded in older
|
|
|
|
|
* Blender versions if only one is written. */
|
2024-08-29 19:12:45 +02:00
|
|
|
animrig::ChannelBag *bag = channelbag_for_action_slot(action, first_slot.handle);
|
|
|
|
|
if (bag) {
|
|
|
|
|
action_blend_write_make_legacy_fcurves_listbase(action.curves, bag->fcurves());
|
|
|
|
|
action_blend_write_make_legacy_channel_groups_listbase(action.groups, bag->channel_groups());
|
|
|
|
|
}
|
Anim: forward compatibility for F-Curves in layered Actions
When writing a layered Action to disk, take the F-Curves from the
first keyframe strip and write that as `action.curves` as well. This
will make older Blender versions see those curves and load them
properly.
Only the curves for the first slot are written this way. This means
that any legacy Action that was converted to a layered Action will be
loaded again properly by older Blender versions. Of course this is
limited to a single layer, single strip, and single slot -- once the
newer features are used, older versions of Blender will not be able to
see this extra data.
When an Action contains multiple slots, so with animation for multiple
distinct objects, the forward compatibility becomes a bit iffy. Older
versions of Blender will just see a legacy Action, with its legacy
semantics, and thus all objects that use that Action will receive the
exact same animation data. I don't think there's a way around this.
(_Unless we start breaking up Actions into an Action per slot, alter
the assignments, and then store metadata so that modern Blenders can
reassemble them. I do not think this is a good idea._)
Ref: #124714
Pull Request: https://projects.blender.org/blender/blender/pulls/125065
2024-07-26 11:13:40 +02:00
|
|
|
}
|
2024-07-25 11:38:40 +02:00
|
|
|
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
BLO_write_id_struct(writer, bAction, id_address, &action.id);
|
|
|
|
|
BKE_id_blend_write(writer, &action.id);
|
2020-09-10 11:02:42 +02:00
|
|
|
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
/* Write layered Action data. */
|
Anim: change how action strip data is stored
This updates the layered action data model to store strip data differently. Specifically:
- `Strip` is now just a single, POD type that only stores the data common to all
strips, such as start/end frames.
- The data that might be of a completely different nature between strips (e.g.
keyframe data vs modifier data) is now stored in arrays on the action itself.
- `Strip`s indicate their type with an enum, and specify their data with an
index into the array on the action that stores data for that type.
This approach requires a little more data juggling, but has the advantage of
making `Strip`s themselves super simple POD types, and also opening the door to
trivial strip instancing later on: instances are just strips that point at the
same data.
The intention is that the RNA API remains the same: from RNA's perspective there
is no data storage separate from the strips, and a strip's data is presented as
fields and methods directly on the strip itself. Different strip types will be
presented as different subtypes of `ActionStrip`, each with their own fields and
methods specific to their underlying data's type. However, this PR doesn't
implement that sub-typing, leaving it for a future PR. It does, however, put the
fields and methods of the one strip type we have so far directly on the strip,
which avoids changing the APIs we have so far.
This PR implements the bulk of this new approach, and everything should be
functional and working correctly. However, there are two TODO items left over
that will be implemented in forthcoming PRs:
- Type refinement in the RNA api. This PR actually removes the existing type
refinement code that was implemented in terms of the inheritance tree of the
actual C++ types, and this will need to be reimplemented in terms of the new
data model. The RNA API still works without the type refinement since there
are only keyframe strips right now, but it will be needed in preparation for
more strip types down the road.
- Strip data deletion. This PR only deletes data from the strip data arrays when
the whole action is deleted, and otherwise just accumulates strip data as more
and more strips are added, never removing the data when the corresponding
strips get removed. That's fine in the short term, especially since we only
support single strips right now. But it does need to be implemented in
preparation for proper layered actions.
Pull Request: https://projects.blender.org/blender/blender/pulls/126559
2024-09-17 17:31:09 +02:00
|
|
|
write_strip_keyframe_data_array(writer, action.strip_keyframe_data());
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
write_layers(writer, action.layers());
|
2024-07-05 16:59:34 +02:00
|
|
|
write_slots(writer, action.slots());
|
Anim: forward compatibility for F-Curves in layered Actions
When writing a layered Action to disk, take the F-Curves from the
first keyframe strip and write that as `action.curves` as well. This
will make older Blender versions see those curves and load them
properly.
Only the curves for the first slot are written this way. This means
that any legacy Action that was converted to a layered Action will be
loaded again properly by older Blender versions. Of course this is
limited to a single layer, single strip, and single slot -- once the
newer features are used, older versions of Blender will not be able to
see this extra data.
When an Action contains multiple slots, so with animation for multiple
distinct objects, the forward compatibility becomes a bit iffy. Older
versions of Blender will just see a legacy Action, with its legacy
semantics, and thus all objects that use that Action will receive the
exact same animation data. I don't think there's a way around this.
(_Unless we start breaking up Actions into an Action per slot, alter
the assignments, and then store metadata so that modern Blenders can
reassemble them. I do not think this is a good idea._)
Ref: #124714
Pull Request: https://projects.blender.org/blender/blender/pulls/125065
2024-07-26 11:13:40 +02:00
|
|
|
|
|
|
|
|
if (do_write_forward_compat) {
|
|
|
|
|
/* The pointers to the first/last FCurve in the `action.curves` have already
|
|
|
|
|
* been written as part of the Action struct data, so they can be cleared
|
|
|
|
|
* here, such that the code writing legacy fcurves below does nothing (as
|
|
|
|
|
* expected). And to leave the Action in a consistent state (it shouldn't
|
|
|
|
|
* have F-Curves in both legacy and layered storage).
|
|
|
|
|
*
|
|
|
|
|
* Note that the FCurves themselves have been written as part of the layered
|
|
|
|
|
* animation writing code called above. Writing them again as part of the
|
|
|
|
|
* handling of the legacy `action.fcurves` ListBase would corrupt the
|
2024-07-30 12:38:16 +10:00
|
|
|
* blend-file by generating two `BHead` `DATA` blocks with the same old
|
Anim: forward compatibility for F-Curves in layered Actions
When writing a layered Action to disk, take the F-Curves from the
first keyframe strip and write that as `action.curves` as well. This
will make older Blender versions see those curves and load them
properly.
Only the curves for the first slot are written this way. This means
that any legacy Action that was converted to a layered Action will be
loaded again properly by older Blender versions. Of course this is
limited to a single layer, single strip, and single slot -- once the
newer features are used, older versions of Blender will not be able to
see this extra data.
When an Action contains multiple slots, so with animation for multiple
distinct objects, the forward compatibility becomes a bit iffy. Older
versions of Blender will just see a legacy Action, with its legacy
semantics, and thus all objects that use that Action will receive the
exact same animation data. I don't think there's a way around this.
(_Unless we start breaking up Actions into an Action per slot, alter
the assignments, and then store metadata so that modern Blenders can
reassemble them. I do not think this is a good idea._)
Ref: #124714
Pull Request: https://projects.blender.org/blender/blender/pulls/125065
2024-07-26 11:13:40 +02:00
|
|
|
* address for the same ID.
|
|
|
|
|
*/
|
Anim: add channel groups to layered actions
This PR adds channel groups (also known as fcurve groups or action groups) to
layered actions. For layered actions, these groups belong to the `ChannelBag`s
and can vary by bag.
From a user perspective, the goal is for these to function just like channel
groups from legacy actions. However, internally they are implemented a little
differently: legacy actions store both channel groups and fcurves in a listbase,
and groups indicate what fcurves are in them with a listbase that points
directly into the larger fcurve listbase. Layered actions, on the other hand,
store both fcurves and channel groups in an array, and groups indicate what
fcurves are in them by indexing into the fcurve array.
Despite taking this different approach, we still reuse the `bActionGroup` struct
for the new channel groups, just adding the necessary fields for index-based
fcurve membership as described above.
This PR does not implement all of the functionality needed to reach feature
parity with legacy action channel groups, but implements the main core and gets
them basically working.
It's easier to list the things that *haven't* been implemented yet:
- Operators for letting the user manually create/remove/move channel groups.
- Keyframe selection in the action/dopesheet editor on channel group rows
themselves are not yet working correctly.
- Handling channel groups in legacy/layered action conversion operators.
- Making the legacy `action.groups` property work on single-layer-single-strip
layered actions.
Those are left for future PRs. Other than that, in theory everything should be
working now.
Pull Request: https://projects.blender.org/blender/blender/pulls/125774
2024-08-22 17:13:12 +02:00
|
|
|
action_blend_write_clear_legacy_channel_groups_listbase(action.groups);
|
Anim: forward compatibility for F-Curves in layered Actions
When writing a layered Action to disk, take the F-Curves from the
first keyframe strip and write that as `action.curves` as well. This
will make older Blender versions see those curves and load them
properly.
Only the curves for the first slot are written this way. This means
that any legacy Action that was converted to a layered Action will be
loaded again properly by older Blender versions. Of course this is
limited to a single layer, single strip, and single slot -- once the
newer features are used, older versions of Blender will not be able to
see this extra data.
When an Action contains multiple slots, so with animation for multiple
distinct objects, the forward compatibility becomes a bit iffy. Older
versions of Blender will just see a legacy Action, with its legacy
semantics, and thus all objects that use that Action will receive the
exact same animation data. I don't think there's a way around this.
(_Unless we start breaking up Actions into an Action per slot, alter
the assignments, and then store metadata so that modern Blenders can
reassemble them. I do not think this is a good idea._)
Ref: #124714
Pull Request: https://projects.blender.org/blender/blender/pulls/125065
2024-07-26 11:13:40 +02:00
|
|
|
action_blend_write_clear_legacy_fcurves_listbase(action.curves);
|
|
|
|
|
}
|
2020-09-10 11:02:42 +02:00
|
|
|
|
Anim: forward compatibility for F-Curves in layered Actions
When writing a layered Action to disk, take the F-Curves from the
first keyframe strip and write that as `action.curves` as well. This
will make older Blender versions see those curves and load them
properly.
Only the curves for the first slot are written this way. This means
that any legacy Action that was converted to a layered Action will be
loaded again properly by older Blender versions. Of course this is
limited to a single layer, single strip, and single slot -- once the
newer features are used, older versions of Blender will not be able to
see this extra data.
When an Action contains multiple slots, so with animation for multiple
distinct objects, the forward compatibility becomes a bit iffy. Older
versions of Blender will just see a legacy Action, with its legacy
semantics, and thus all objects that use that Action will receive the
exact same animation data. I don't think there's a way around this.
(_Unless we start breaking up Actions into an Action per slot, alter
the assignments, and then store metadata so that modern Blenders can
reassemble them. I do not think this is a good idea._)
Ref: #124714
Pull Request: https://projects.blender.org/blender/blender/pulls/125065
2024-07-26 11:13:40 +02:00
|
|
|
/* Write legacy F-Curves & Groups. */
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
BKE_fcurve_blend_write_listbase(writer, &action.curves);
|
|
|
|
|
LISTBASE_FOREACH (bActionGroup *, grp, &action.groups) {
|
2021-08-19 11:13:55 +02:00
|
|
|
BLO_write_struct(writer, bActionGroup, grp);
|
|
|
|
|
}
|
2021-02-04 14:17:50 +01:00
|
|
|
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
LISTBASE_FOREACH (TimeMarker *, marker, &action.markers) {
|
2021-08-19 11:13:55 +02:00
|
|
|
BLO_write_struct(writer, TimeMarker, marker);
|
2020-09-10 11:02:42 +02:00
|
|
|
}
|
2021-08-19 11:13:55 +02:00
|
|
|
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
BKE_previewimg_blend_write(writer, action.preview);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void read_channelbag(BlendDataReader *reader, animrig::ChannelBag &channelbag)
|
|
|
|
|
{
|
2024-07-31 16:55:29 +02:00
|
|
|
BLO_read_pointer_array(
|
Anim: add channel groups to layered actions
This PR adds channel groups (also known as fcurve groups or action groups) to
layered actions. For layered actions, these groups belong to the `ChannelBag`s
and can vary by bag.
From a user perspective, the goal is for these to function just like channel
groups from legacy actions. However, internally they are implemented a little
differently: legacy actions store both channel groups and fcurves in a listbase,
and groups indicate what fcurves are in them with a listbase that points
directly into the larger fcurve listbase. Layered actions, on the other hand,
store both fcurves and channel groups in an array, and groups indicate what
fcurves are in them by indexing into the fcurve array.
Despite taking this different approach, we still reuse the `bActionGroup` struct
for the new channel groups, just adding the necessary fields for index-based
fcurve membership as described above.
This PR does not implement all of the functionality needed to reach feature
parity with legacy action channel groups, but implements the main core and gets
them basically working.
It's easier to list the things that *haven't* been implemented yet:
- Operators for letting the user manually create/remove/move channel groups.
- Keyframe selection in the action/dopesheet editor on channel group rows
themselves are not yet working correctly.
- Handling channel groups in legacy/layered action conversion operators.
- Making the legacy `action.groups` property work on single-layer-single-strip
layered actions.
Those are left for future PRs. Other than that, in theory everything should be
working now.
Pull Request: https://projects.blender.org/blender/blender/pulls/125774
2024-08-22 17:13:12 +02:00
|
|
|
reader, channelbag.group_array_num, reinterpret_cast<void **>(&channelbag.group_array));
|
|
|
|
|
for (int i = 0; i < channelbag.group_array_num; i++) {
|
|
|
|
|
BLO_read_struct(reader, bActionGroup, &channelbag.group_array[i]);
|
2024-08-29 19:12:45 +02:00
|
|
|
channelbag.group_array[i]->channel_bag = &channelbag;
|
2024-08-27 17:02:18 +02:00
|
|
|
|
2024-08-29 17:16:42 +10:00
|
|
|
/* Clear the legacy channels #ListBase, since it will have been set for some
|
|
|
|
|
* groups for forward compatibility.
|
|
|
|
|
* See #action_blend_write_make_legacy_channel_groups_listbase. */
|
2024-08-27 17:02:18 +02:00
|
|
|
channelbag.group_array[i]->channels = {nullptr, nullptr};
|
Anim: add channel groups to layered actions
This PR adds channel groups (also known as fcurve groups or action groups) to
layered actions. For layered actions, these groups belong to the `ChannelBag`s
and can vary by bag.
From a user perspective, the goal is for these to function just like channel
groups from legacy actions. However, internally they are implemented a little
differently: legacy actions store both channel groups and fcurves in a listbase,
and groups indicate what fcurves are in them with a listbase that points
directly into the larger fcurve listbase. Layered actions, on the other hand,
store both fcurves and channel groups in an array, and groups indicate what
fcurves are in them by indexing into the fcurve array.
Despite taking this different approach, we still reuse the `bActionGroup` struct
for the new channel groups, just adding the necessary fields for index-based
fcurve membership as described above.
This PR does not implement all of the functionality needed to reach feature
parity with legacy action channel groups, but implements the main core and gets
them basically working.
It's easier to list the things that *haven't* been implemented yet:
- Operators for letting the user manually create/remove/move channel groups.
- Keyframe selection in the action/dopesheet editor on channel group rows
themselves are not yet working correctly.
- Handling channel groups in legacy/layered action conversion operators.
- Making the legacy `action.groups` property work on single-layer-single-strip
layered actions.
Those are left for future PRs. Other than that, in theory everything should be
working now.
Pull Request: https://projects.blender.org/blender/blender/pulls/125774
2024-08-22 17:13:12 +02:00
|
|
|
}
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
|
Anim: add channel groups to layered actions
This PR adds channel groups (also known as fcurve groups or action groups) to
layered actions. For layered actions, these groups belong to the `ChannelBag`s
and can vary by bag.
From a user perspective, the goal is for these to function just like channel
groups from legacy actions. However, internally they are implemented a little
differently: legacy actions store both channel groups and fcurves in a listbase,
and groups indicate what fcurves are in them with a listbase that points
directly into the larger fcurve listbase. Layered actions, on the other hand,
store both fcurves and channel groups in an array, and groups indicate what
fcurves are in them by indexing into the fcurve array.
Despite taking this different approach, we still reuse the `bActionGroup` struct
for the new channel groups, just adding the necessary fields for index-based
fcurve membership as described above.
This PR does not implement all of the functionality needed to reach feature
parity with legacy action channel groups, but implements the main core and gets
them basically working.
It's easier to list the things that *haven't* been implemented yet:
- Operators for letting the user manually create/remove/move channel groups.
- Keyframe selection in the action/dopesheet editor on channel group rows
themselves are not yet working correctly.
- Handling channel groups in legacy/layered action conversion operators.
- Making the legacy `action.groups` property work on single-layer-single-strip
layered actions.
Those are left for future PRs. Other than that, in theory everything should be
working now.
Pull Request: https://projects.blender.org/blender/blender/pulls/125774
2024-08-22 17:13:12 +02:00
|
|
|
BLO_read_pointer_array(
|
|
|
|
|
reader, channelbag.fcurve_array_num, reinterpret_cast<void **>(&channelbag.fcurve_array));
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
for (int i = 0; i < channelbag.fcurve_array_num; i++) {
|
|
|
|
|
BLO_read_struct(reader, FCurve, &channelbag.fcurve_array[i]);
|
Anim: forward compatibility for F-Curves in layered Actions
When writing a layered Action to disk, take the F-Curves from the
first keyframe strip and write that as `action.curves` as well. This
will make older Blender versions see those curves and load them
properly.
Only the curves for the first slot are written this way. This means
that any legacy Action that was converted to a layered Action will be
loaded again properly by older Blender versions. Of course this is
limited to a single layer, single strip, and single slot -- once the
newer features are used, older versions of Blender will not be able to
see this extra data.
When an Action contains multiple slots, so with animation for multiple
distinct objects, the forward compatibility becomes a bit iffy. Older
versions of Blender will just see a legacy Action, with its legacy
semantics, and thus all objects that use that Action will receive the
exact same animation data. I don't think there's a way around this.
(_Unless we start breaking up Actions into an Action per slot, alter
the assignments, and then store metadata so that modern Blenders can
reassemble them. I do not think this is a good idea._)
Ref: #124714
Pull Request: https://projects.blender.org/blender/blender/pulls/125065
2024-07-26 11:13:40 +02:00
|
|
|
FCurve *fcurve = channelbag.fcurve_array[i];
|
|
|
|
|
|
|
|
|
|
/* Clear the prev/next pointers set by the forward compatibility code in
|
|
|
|
|
* action_blend_write(). */
|
|
|
|
|
fcurve->prev = nullptr;
|
|
|
|
|
fcurve->next = nullptr;
|
|
|
|
|
|
|
|
|
|
BKE_fcurve_blend_read_data(reader, fcurve);
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Anim: change how action strip data is stored
This updates the layered action data model to store strip data differently. Specifically:
- `Strip` is now just a single, POD type that only stores the data common to all
strips, such as start/end frames.
- The data that might be of a completely different nature between strips (e.g.
keyframe data vs modifier data) is now stored in arrays on the action itself.
- `Strip`s indicate their type with an enum, and specify their data with an
index into the array on the action that stores data for that type.
This approach requires a little more data juggling, but has the advantage of
making `Strip`s themselves super simple POD types, and also opening the door to
trivial strip instancing later on: instances are just strips that point at the
same data.
The intention is that the RNA API remains the same: from RNA's perspective there
is no data storage separate from the strips, and a strip's data is presented as
fields and methods directly on the strip itself. Different strip types will be
presented as different subtypes of `ActionStrip`, each with their own fields and
methods specific to their underlying data's type. However, this PR doesn't
implement that sub-typing, leaving it for a future PR. It does, however, put the
fields and methods of the one strip type we have so far directly on the strip,
which avoids changing the APIs we have so far.
This PR implements the bulk of this new approach, and everything should be
functional and working correctly. However, there are two TODO items left over
that will be implemented in forthcoming PRs:
- Type refinement in the RNA api. This PR actually removes the existing type
refinement code that was implemented in terms of the inheritance tree of the
actual C++ types, and this will need to be reimplemented in terms of the new
data model. The RNA API still works without the type refinement since there
are only keyframe strips right now, but it will be needed in preparation for
more strip types down the road.
- Strip data deletion. This PR only deletes data from the strip data arrays when
the whole action is deleted, and otherwise just accumulates strip data as more
and more strips are added, never removing the data when the corresponding
strips get removed. That's fine in the short term, especially since we only
support single strips right now. But it does need to be implemented in
preparation for proper layered actions.
Pull Request: https://projects.blender.org/blender/blender/pulls/126559
2024-09-17 17:31:09 +02:00
|
|
|
static void read_strip_keyframe_data(BlendDataReader *reader,
|
|
|
|
|
animrig::StripKeyframeData &strip_keyframe_data)
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
{
|
Anim: change how action strip data is stored
This updates the layered action data model to store strip data differently. Specifically:
- `Strip` is now just a single, POD type that only stores the data common to all
strips, such as start/end frames.
- The data that might be of a completely different nature between strips (e.g.
keyframe data vs modifier data) is now stored in arrays on the action itself.
- `Strip`s indicate their type with an enum, and specify their data with an
index into the array on the action that stores data for that type.
This approach requires a little more data juggling, but has the advantage of
making `Strip`s themselves super simple POD types, and also opening the door to
trivial strip instancing later on: instances are just strips that point at the
same data.
The intention is that the RNA API remains the same: from RNA's perspective there
is no data storage separate from the strips, and a strip's data is presented as
fields and methods directly on the strip itself. Different strip types will be
presented as different subtypes of `ActionStrip`, each with their own fields and
methods specific to their underlying data's type. However, this PR doesn't
implement that sub-typing, leaving it for a future PR. It does, however, put the
fields and methods of the one strip type we have so far directly on the strip,
which avoids changing the APIs we have so far.
This PR implements the bulk of this new approach, and everything should be
functional and working correctly. However, there are two TODO items left over
that will be implemented in forthcoming PRs:
- Type refinement in the RNA api. This PR actually removes the existing type
refinement code that was implemented in terms of the inheritance tree of the
actual C++ types, and this will need to be reimplemented in terms of the new
data model. The RNA API still works without the type refinement since there
are only keyframe strips right now, but it will be needed in preparation for
more strip types down the road.
- Strip data deletion. This PR only deletes data from the strip data arrays when
the whole action is deleted, and otherwise just accumulates strip data as more
and more strips are added, never removing the data when the corresponding
strips get removed. That's fine in the short term, especially since we only
support single strips right now. But it does need to be implemented in
preparation for proper layered actions.
Pull Request: https://projects.blender.org/blender/blender/pulls/126559
2024-09-17 17:31:09 +02:00
|
|
|
BLO_read_pointer_array(reader,
|
|
|
|
|
strip_keyframe_data.channelbag_array_num,
|
|
|
|
|
reinterpret_cast<void **>(&strip_keyframe_data.channelbag_array));
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
|
Anim: change how action strip data is stored
This updates the layered action data model to store strip data differently. Specifically:
- `Strip` is now just a single, POD type that only stores the data common to all
strips, such as start/end frames.
- The data that might be of a completely different nature between strips (e.g.
keyframe data vs modifier data) is now stored in arrays on the action itself.
- `Strip`s indicate their type with an enum, and specify their data with an
index into the array on the action that stores data for that type.
This approach requires a little more data juggling, but has the advantage of
making `Strip`s themselves super simple POD types, and also opening the door to
trivial strip instancing later on: instances are just strips that point at the
same data.
The intention is that the RNA API remains the same: from RNA's perspective there
is no data storage separate from the strips, and a strip's data is presented as
fields and methods directly on the strip itself. Different strip types will be
presented as different subtypes of `ActionStrip`, each with their own fields and
methods specific to their underlying data's type. However, this PR doesn't
implement that sub-typing, leaving it for a future PR. It does, however, put the
fields and methods of the one strip type we have so far directly on the strip,
which avoids changing the APIs we have so far.
This PR implements the bulk of this new approach, and everything should be
functional and working correctly. However, there are two TODO items left over
that will be implemented in forthcoming PRs:
- Type refinement in the RNA api. This PR actually removes the existing type
refinement code that was implemented in terms of the inheritance tree of the
actual C++ types, and this will need to be reimplemented in terms of the new
data model. The RNA API still works without the type refinement since there
are only keyframe strips right now, but it will be needed in preparation for
more strip types down the road.
- Strip data deletion. This PR only deletes data from the strip data arrays when
the whole action is deleted, and otherwise just accumulates strip data as more
and more strips are added, never removing the data when the corresponding
strips get removed. That's fine in the short term, especially since we only
support single strips right now. But it does need to be implemented in
preparation for proper layered actions.
Pull Request: https://projects.blender.org/blender/blender/pulls/126559
2024-09-17 17:31:09 +02:00
|
|
|
for (int i = 0; i < strip_keyframe_data.channelbag_array_num; i++) {
|
|
|
|
|
BLO_read_struct(reader, ActionChannelBag, &strip_keyframe_data.channelbag_array[i]);
|
|
|
|
|
ActionChannelBag *channelbag = strip_keyframe_data.channelbag_array[i];
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
read_channelbag(reader, channelbag->wrap());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Anim: change how action strip data is stored
This updates the layered action data model to store strip data differently. Specifically:
- `Strip` is now just a single, POD type that only stores the data common to all
strips, such as start/end frames.
- The data that might be of a completely different nature between strips (e.g.
keyframe data vs modifier data) is now stored in arrays on the action itself.
- `Strip`s indicate their type with an enum, and specify their data with an
index into the array on the action that stores data for that type.
This approach requires a little more data juggling, but has the advantage of
making `Strip`s themselves super simple POD types, and also opening the door to
trivial strip instancing later on: instances are just strips that point at the
same data.
The intention is that the RNA API remains the same: from RNA's perspective there
is no data storage separate from the strips, and a strip's data is presented as
fields and methods directly on the strip itself. Different strip types will be
presented as different subtypes of `ActionStrip`, each with their own fields and
methods specific to their underlying data's type. However, this PR doesn't
implement that sub-typing, leaving it for a future PR. It does, however, put the
fields and methods of the one strip type we have so far directly on the strip,
which avoids changing the APIs we have so far.
This PR implements the bulk of this new approach, and everything should be
functional and working correctly. However, there are two TODO items left over
that will be implemented in forthcoming PRs:
- Type refinement in the RNA api. This PR actually removes the existing type
refinement code that was implemented in terms of the inheritance tree of the
actual C++ types, and this will need to be reimplemented in terms of the new
data model. The RNA API still works without the type refinement since there
are only keyframe strips right now, but it will be needed in preparation for
more strip types down the road.
- Strip data deletion. This PR only deletes data from the strip data arrays when
the whole action is deleted, and otherwise just accumulates strip data as more
and more strips are added, never removing the data when the corresponding
strips get removed. That's fine in the short term, especially since we only
support single strips right now. But it does need to be implemented in
preparation for proper layered actions.
Pull Request: https://projects.blender.org/blender/blender/pulls/126559
2024-09-17 17:31:09 +02:00
|
|
|
static void read_strip_keyframe_data_array(BlendDataReader *reader, animrig::Action &action)
|
|
|
|
|
{
|
|
|
|
|
BLO_read_pointer_array(reader,
|
|
|
|
|
action.strip_keyframe_data_array_num,
|
|
|
|
|
reinterpret_cast<void **>(&action.strip_keyframe_data_array));
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < action.strip_keyframe_data_array_num; i++) {
|
|
|
|
|
BLO_read_struct(reader, ActionStripKeyframeData, &action.strip_keyframe_data_array[i]);
|
|
|
|
|
ActionStripKeyframeData *keyframe_data = action.strip_keyframe_data_array[i];
|
|
|
|
|
read_strip_keyframe_data(reader, keyframe_data->wrap());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-05 17:01:50 +02:00
|
|
|
static void read_layers(BlendDataReader *reader, animrig::Action &action)
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
{
|
2024-07-31 16:55:29 +02:00
|
|
|
BLO_read_pointer_array(
|
|
|
|
|
reader, action.layer_array_num, reinterpret_cast<void **>(&action.layer_array));
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
|
2024-07-05 17:01:50 +02:00
|
|
|
for (int layer_idx = 0; layer_idx < action.layer_array_num; layer_idx++) {
|
|
|
|
|
BLO_read_struct(reader, ActionLayer, &action.layer_array[layer_idx]);
|
|
|
|
|
ActionLayer *layer = action.layer_array[layer_idx];
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
|
2024-07-31 16:55:29 +02:00
|
|
|
BLO_read_pointer_array(
|
|
|
|
|
reader, layer->strip_array_num, reinterpret_cast<void **>(&layer->strip_array));
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
for (int strip_idx = 0; strip_idx < layer->strip_array_num; strip_idx++) {
|
|
|
|
|
BLO_read_struct(reader, ActionStrip, &layer->strip_array[strip_idx]);
|
|
|
|
|
|
Anim: change how action strip data is stored
This updates the layered action data model to store strip data differently. Specifically:
- `Strip` is now just a single, POD type that only stores the data common to all
strips, such as start/end frames.
- The data that might be of a completely different nature between strips (e.g.
keyframe data vs modifier data) is now stored in arrays on the action itself.
- `Strip`s indicate their type with an enum, and specify their data with an
index into the array on the action that stores data for that type.
This approach requires a little more data juggling, but has the advantage of
making `Strip`s themselves super simple POD types, and also opening the door to
trivial strip instancing later on: instances are just strips that point at the
same data.
The intention is that the RNA API remains the same: from RNA's perspective there
is no data storage separate from the strips, and a strip's data is presented as
fields and methods directly on the strip itself. Different strip types will be
presented as different subtypes of `ActionStrip`, each with their own fields and
methods specific to their underlying data's type. However, this PR doesn't
implement that sub-typing, leaving it for a future PR. It does, however, put the
fields and methods of the one strip type we have so far directly on the strip,
which avoids changing the APIs we have so far.
This PR implements the bulk of this new approach, and everything should be
functional and working correctly. However, there are two TODO items left over
that will be implemented in forthcoming PRs:
- Type refinement in the RNA api. This PR actually removes the existing type
refinement code that was implemented in terms of the inheritance tree of the
actual C++ types, and this will need to be reimplemented in terms of the new
data model. The RNA API still works without the type refinement since there
are only keyframe strips right now, but it will be needed in preparation for
more strip types down the road.
- Strip data deletion. This PR only deletes data from the strip data arrays when
the whole action is deleted, and otherwise just accumulates strip data as more
and more strips are added, never removing the data when the corresponding
strips get removed. That's fine in the short term, especially since we only
support single strips right now. But it does need to be implemented in
preparation for proper layered actions.
Pull Request: https://projects.blender.org/blender/blender/pulls/126559
2024-09-17 17:31:09 +02:00
|
|
|
/* This if statement and the code in it is only for a transitional period
|
|
|
|
|
* while we land #126559 and for a while after, to prevent crashes for
|
|
|
|
|
* people that were already playing with slotted actions and have some
|
|
|
|
|
* blend files written with them. This code can be removed after a while.
|
|
|
|
|
* At the very least, if you're reading this and slotted actions are
|
|
|
|
|
* already in an official release of Blender then this code is no longer
|
|
|
|
|
* relevant and can be deleted. */
|
|
|
|
|
if (layer->strip_array[strip_idx] == nullptr) {
|
|
|
|
|
layer->strip_array[strip_idx] = &animrig::Strip::create(action,
|
|
|
|
|
animrig::Strip::Type::Keyframe);
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-05 17:01:50 +02:00
|
|
|
static void read_slots(BlendDataReader *reader, animrig::Action &action)
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
{
|
2024-07-31 16:55:29 +02:00
|
|
|
BLO_read_pointer_array(
|
|
|
|
|
reader, action.slot_array_num, reinterpret_cast<void **>(&action.slot_array));
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
|
2024-07-05 17:01:50 +02:00
|
|
|
for (int i = 0; i < action.slot_array_num; i++) {
|
|
|
|
|
BLO_read_struct(reader, ActionSlot, &action.slot_array[i]);
|
2024-10-07 10:45:11 +02:00
|
|
|
|
|
|
|
|
/* Undo generic endian switching, as the ID type values are not numerically the same between
|
|
|
|
|
* little and big endian machines. Due to the way they are defined, they are always in the same
|
|
|
|
|
* byte order, regardless of hardware/platform endianness. */
|
|
|
|
|
if (BLO_read_requires_endian_switch(reader)) {
|
|
|
|
|
BLI_endian_switch_int16(&action.slot_array[i]->idtype);
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-05 17:01:50 +02:00
|
|
|
action.slot_array[i]->wrap().blend_read_post();
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
}
|
2020-09-10 11:02:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void action_blend_read_data(BlendDataReader *reader, ID *id)
|
|
|
|
|
{
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
animrig::Action &action = reinterpret_cast<bAction *>(id)->wrap();
|
2020-09-10 11:02:42 +02:00
|
|
|
|
2024-10-14 13:59:06 +02:00
|
|
|
/* Undo generic endian switching (careful, only the two least significant bytes of the int32 must
|
|
|
|
|
* be swapped back here, since this value is actually an int16). */
|
|
|
|
|
if (BLO_read_requires_endian_switch(reader)) {
|
|
|
|
|
bAction *act = reinterpret_cast<bAction *>(id);
|
|
|
|
|
BLI_endian_switch_int16(reinterpret_cast<short *>(&act->idroot));
|
|
|
|
|
}
|
|
|
|
|
|
Anim: change how action strip data is stored
This updates the layered action data model to store strip data differently. Specifically:
- `Strip` is now just a single, POD type that only stores the data common to all
strips, such as start/end frames.
- The data that might be of a completely different nature between strips (e.g.
keyframe data vs modifier data) is now stored in arrays on the action itself.
- `Strip`s indicate their type with an enum, and specify their data with an
index into the array on the action that stores data for that type.
This approach requires a little more data juggling, but has the advantage of
making `Strip`s themselves super simple POD types, and also opening the door to
trivial strip instancing later on: instances are just strips that point at the
same data.
The intention is that the RNA API remains the same: from RNA's perspective there
is no data storage separate from the strips, and a strip's data is presented as
fields and methods directly on the strip itself. Different strip types will be
presented as different subtypes of `ActionStrip`, each with their own fields and
methods specific to their underlying data's type. However, this PR doesn't
implement that sub-typing, leaving it for a future PR. It does, however, put the
fields and methods of the one strip type we have so far directly on the strip,
which avoids changing the APIs we have so far.
This PR implements the bulk of this new approach, and everything should be
functional and working correctly. However, there are two TODO items left over
that will be implemented in forthcoming PRs:
- Type refinement in the RNA api. This PR actually removes the existing type
refinement code that was implemented in terms of the inheritance tree of the
actual C++ types, and this will need to be reimplemented in terms of the new
data model. The RNA API still works without the type refinement since there
are only keyframe strips right now, but it will be needed in preparation for
more strip types down the road.
- Strip data deletion. This PR only deletes data from the strip data arrays when
the whole action is deleted, and otherwise just accumulates strip data as more
and more strips are added, never removing the data when the corresponding
strips get removed. That's fine in the short term, especially since we only
support single strips right now. But it does need to be implemented in
preparation for proper layered actions.
Pull Request: https://projects.blender.org/blender/blender/pulls/126559
2024-09-17 17:31:09 +02:00
|
|
|
read_strip_keyframe_data_array(reader, action);
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
read_layers(reader, action);
|
2024-07-05 16:59:34 +02:00
|
|
|
read_slots(reader, action);
|
2020-09-10 11:02:42 +02:00
|
|
|
|
Anim: forward compatibility for F-Curves in layered Actions
When writing a layered Action to disk, take the F-Curves from the
first keyframe strip and write that as `action.curves` as well. This
will make older Blender versions see those curves and load them
properly.
Only the curves for the first slot are written this way. This means
that any legacy Action that was converted to a layered Action will be
loaded again properly by older Blender versions. Of course this is
limited to a single layer, single strip, and single slot -- once the
newer features are used, older versions of Blender will not be able to
see this extra data.
When an Action contains multiple slots, so with animation for multiple
distinct objects, the forward compatibility becomes a bit iffy. Older
versions of Blender will just see a legacy Action, with its legacy
semantics, and thus all objects that use that Action will receive the
exact same animation data. I don't think there's a way around this.
(_Unless we start breaking up Actions into an Action per slot, alter
the assignments, and then store metadata so that modern Blenders can
reassemble them. I do not think this is a good idea._)
Ref: #124714
Pull Request: https://projects.blender.org/blender/blender/pulls/125065
2024-07-26 11:13:40 +02:00
|
|
|
if (action.is_action_layered()) {
|
|
|
|
|
/* Clear the forward-compatible storage (see action_blend_write_data()). */
|
2024-09-04 20:35:49 +10:00
|
|
|
BLI_listbase_clear(&action.chanbase);
|
Anim: forward compatibility for F-Curves in layered Actions
When writing a layered Action to disk, take the F-Curves from the
first keyframe strip and write that as `action.curves` as well. This
will make older Blender versions see those curves and load them
properly.
Only the curves for the first slot are written this way. This means
that any legacy Action that was converted to a layered Action will be
loaded again properly by older Blender versions. Of course this is
limited to a single layer, single strip, and single slot -- once the
newer features are used, older versions of Blender will not be able to
see this extra data.
When an Action contains multiple slots, so with animation for multiple
distinct objects, the forward compatibility becomes a bit iffy. Older
versions of Blender will just see a legacy Action, with its legacy
semantics, and thus all objects that use that Action will receive the
exact same animation data. I don't think there's a way around this.
(_Unless we start breaking up Actions into an Action per slot, alter
the assignments, and then store metadata so that modern Blenders can
reassemble them. I do not think this is a good idea._)
Ref: #124714
Pull Request: https://projects.blender.org/blender/blender/pulls/125065
2024-07-26 11:13:40 +02:00
|
|
|
BLI_listbase_clear(&action.curves);
|
Anim: add channel groups to layered actions
This PR adds channel groups (also known as fcurve groups or action groups) to
layered actions. For layered actions, these groups belong to the `ChannelBag`s
and can vary by bag.
From a user perspective, the goal is for these to function just like channel
groups from legacy actions. However, internally they are implemented a little
differently: legacy actions store both channel groups and fcurves in a listbase,
and groups indicate what fcurves are in them with a listbase that points
directly into the larger fcurve listbase. Layered actions, on the other hand,
store both fcurves and channel groups in an array, and groups indicate what
fcurves are in them by indexing into the fcurve array.
Despite taking this different approach, we still reuse the `bActionGroup` struct
for the new channel groups, just adding the necessary fields for index-based
fcurve membership as described above.
This PR does not implement all of the functionality needed to reach feature
parity with legacy action channel groups, but implements the main core and gets
them basically working.
It's easier to list the things that *haven't* been implemented yet:
- Operators for letting the user manually create/remove/move channel groups.
- Keyframe selection in the action/dopesheet editor on channel group rows
themselves are not yet working correctly.
- Handling channel groups in legacy/layered action conversion operators.
- Making the legacy `action.groups` property work on single-layer-single-strip
layered actions.
Those are left for future PRs. Other than that, in theory everything should be
working now.
Pull Request: https://projects.blender.org/blender/blender/pulls/125774
2024-08-22 17:13:12 +02:00
|
|
|
BLI_listbase_clear(&action.groups);
|
Anim: forward compatibility for F-Curves in layered Actions
When writing a layered Action to disk, take the F-Curves from the
first keyframe strip and write that as `action.curves` as well. This
will make older Blender versions see those curves and load them
properly.
Only the curves for the first slot are written this way. This means
that any legacy Action that was converted to a layered Action will be
loaded again properly by older Blender versions. Of course this is
limited to a single layer, single strip, and single slot -- once the
newer features are used, older versions of Blender will not be able to
see this extra data.
When an Action contains multiple slots, so with animation for multiple
distinct objects, the forward compatibility becomes a bit iffy. Older
versions of Blender will just see a legacy Action, with its legacy
semantics, and thus all objects that use that Action will receive the
exact same animation data. I don't think there's a way around this.
(_Unless we start breaking up Actions into an Action per slot, alter
the assignments, and then store metadata so that modern Blenders can
reassemble them. I do not think this is a good idea._)
Ref: #124714
Pull Request: https://projects.blender.org/blender/blender/pulls/125065
2024-07-26 11:13:40 +02:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Read legacy data. */
|
|
|
|
|
BLO_read_struct_list(reader, bActionChannel, &action.chanbase);
|
|
|
|
|
BLO_read_struct_list(reader, FCurve, &action.curves);
|
|
|
|
|
BLO_read_struct_list(reader, bActionGroup, &action.groups);
|
|
|
|
|
|
2024-09-04 20:35:49 +10:00
|
|
|
LISTBASE_FOREACH (bActionChannel *, achan, &action.chanbase) {
|
|
|
|
|
BLO_read_struct(reader, bActionGroup, &achan->grp);
|
|
|
|
|
BLO_read_struct_list(reader, bConstraintChannel, &achan->constraintChannels);
|
|
|
|
|
}
|
|
|
|
|
|
Anim: forward compatibility for F-Curves in layered Actions
When writing a layered Action to disk, take the F-Curves from the
first keyframe strip and write that as `action.curves` as well. This
will make older Blender versions see those curves and load them
properly.
Only the curves for the first slot are written this way. This means
that any legacy Action that was converted to a layered Action will be
loaded again properly by older Blender versions. Of course this is
limited to a single layer, single strip, and single slot -- once the
newer features are used, older versions of Blender will not be able to
see this extra data.
When an Action contains multiple slots, so with animation for multiple
distinct objects, the forward compatibility becomes a bit iffy. Older
versions of Blender will just see a legacy Action, with its legacy
semantics, and thus all objects that use that Action will receive the
exact same animation data. I don't think there's a way around this.
(_Unless we start breaking up Actions into an Action per slot, alter
the assignments, and then store metadata so that modern Blenders can
reassemble them. I do not think this is a good idea._)
Ref: #124714
Pull Request: https://projects.blender.org/blender/blender/pulls/125065
2024-07-26 11:13:40 +02:00
|
|
|
BKE_fcurve_blend_read_data_listbase(reader, &action.curves);
|
|
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (bActionGroup *, agrp, &action.groups) {
|
|
|
|
|
BLO_read_struct(reader, FCurve, &agrp->channels.first);
|
|
|
|
|
BLO_read_struct(reader, FCurve, &agrp->channels.last);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
BLO_read_struct_list(reader, TimeMarker, &action.markers);
|
2020-09-10 11:02:42 +02:00
|
|
|
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
/* End of reading legacy data. */
|
2021-02-04 14:17:50 +01:00
|
|
|
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
BLO_read_struct(reader, PreviewImage, &action.preview);
|
|
|
|
|
BKE_previewimg_blend_read(reader, action.preview);
|
2020-09-10 11:02:42 +02:00
|
|
|
}
|
|
|
|
|
|
2021-11-11 17:51:38 +01:00
|
|
|
static IDProperty *action_asset_type_property(const bAction *action)
|
|
|
|
|
{
|
2024-03-26 15:39:34 -04:00
|
|
|
using namespace blender;
|
2024-09-13 15:04:47 +02:00
|
|
|
const bool is_single_frame = action && action->wrap().has_single_frame();
|
2024-03-26 15:39:34 -04:00
|
|
|
return bke::idprop::create("is_single_frame", int(is_single_frame)).release();
|
2021-11-11 17:51:38 +01:00
|
|
|
}
|
|
|
|
|
|
2023-09-26 16:38:50 +02:00
|
|
|
static void action_asset_metadata_ensure(void *asset_ptr, AssetMetaData *asset_data)
|
2021-11-11 17:51:38 +01:00
|
|
|
{
|
|
|
|
|
bAction *action = (bAction *)asset_ptr;
|
|
|
|
|
BLI_assert(GS(action->id.name) == ID_AC);
|
|
|
|
|
|
|
|
|
|
IDProperty *action_type = action_asset_type_property(action);
|
|
|
|
|
BKE_asset_metadata_idprop_ensure(asset_data, action_type);
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-11 18:14:53 +11:00
|
|
|
static AssetTypeInfo AssetType_AC = {
|
2023-09-26 16:38:50 +02:00
|
|
|
/*pre_save_fn*/ action_asset_metadata_ensure,
|
|
|
|
|
/*on_mark_asset_fn*/ action_asset_metadata_ensure,
|
2024-05-08 11:25:00 +02:00
|
|
|
/*on_clear_asset_fn*/ nullptr,
|
2021-11-11 17:51:38 +01:00
|
|
|
};
|
|
|
|
|
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
} // namespace blender::bke
|
|
|
|
|
|
2020-03-06 16:35:23 +01:00
|
|
|
IDTypeInfo IDType_ID_AC = {
|
2023-07-17 10:46:26 +02:00
|
|
|
/*id_code*/ ID_AC,
|
|
|
|
|
/*id_filter*/ FILTER_ID_AC,
|
2024-07-11 10:49:49 +02:00
|
|
|
|
|
|
|
|
/* This value will be set dynamically in `BKE_idtype_init()` to only include
|
2024-07-25 12:04:05 +02:00
|
|
|
* animatable ID types (see `animrig::Slot::users()`). */
|
2024-06-13 14:27:36 +02:00
|
|
|
/*dependencies_id_types*/ FILTER_ID_ALL,
|
2024-07-11 10:49:49 +02:00
|
|
|
|
2023-07-17 10:46:26 +02:00
|
|
|
/*main_listbase_index*/ INDEX_ID_AC,
|
|
|
|
|
/*struct_size*/ sizeof(bAction),
|
|
|
|
|
/*name*/ "Action",
|
|
|
|
|
/*name_plural*/ "actions",
|
|
|
|
|
/*translation_context*/ BLT_I18NCONTEXT_ID_ACTION,
|
|
|
|
|
/*flags*/ IDTYPE_FLAGS_NO_ANIMDATA,
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
/*asset_type_info*/ &blender::bke::AssetType_AC,
|
2023-07-17 10:46:26 +02:00
|
|
|
|
|
|
|
|
/*init_data*/ nullptr,
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
/*copy_data*/ blender::bke::action_copy_data,
|
|
|
|
|
/*free_data*/ blender::bke::action_free_data,
|
2023-07-17 10:46:26 +02:00
|
|
|
/*make_local*/ nullptr,
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
/*foreach_id*/ blender::bke::action_foreach_id,
|
2023-07-17 10:46:26 +02:00
|
|
|
/*foreach_cache*/ nullptr,
|
|
|
|
|
/*foreach_path*/ nullptr,
|
|
|
|
|
/*owner_pointer_get*/ nullptr,
|
|
|
|
|
|
Anim: merge Animation data-block into bAction
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
2024-05-13 15:51:26 +02:00
|
|
|
/*blend_write*/ blender::bke::action_blend_write,
|
|
|
|
|
/*blend_read_data*/ blender::bke::action_blend_read_data,
|
2023-03-11 18:07:59 +01:00
|
|
|
/*blend_read_after_liblink*/ nullptr,
|
2023-07-17 10:46:26 +02:00
|
|
|
|
|
|
|
|
/*blend_read_undo_preserve*/ nullptr,
|
|
|
|
|
|
|
|
|
|
/*lib_override_apply_post*/ nullptr,
|
2020-03-06 16:35:23 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* ***************** Library data level operations on action ************** */
|
|
|
|
|
|
|
|
|
|
bAction *BKE_action_add(Main *bmain, const char name[])
|
|
|
|
|
{
|
|
|
|
|
bAction *act;
|
|
|
|
|
|
2023-07-17 10:46:26 +02:00
|
|
|
act = static_cast<bAction *>(BKE_id_new(bmain, ID_AC, name));
|
2020-03-06 16:35:23 +01:00
|
|
|
|
|
|
|
|
return act;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* .................................. */
|
|
|
|
|
|
2009-09-17 10:14:56 +00:00
|
|
|
/* *************** Action Groups *************** */
|
2004-11-11 15:31:44 +00:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
bActionGroup *get_active_actiongroup(bAction *act)
|
2009-02-09 10:04:11 +00:00
|
|
|
{
|
2024-09-25 09:33:04 +02:00
|
|
|
/* TODO: move this logic to the animrig::ChannelBag struct and unify with code
|
|
|
|
|
* that uses direct access to the flags. */
|
|
|
|
|
for (bActionGroup *agrp : animrig::legacy::channel_groups_all(act)) {
|
|
|
|
|
if (agrp->flag & AGRP_ACTIVE) {
|
|
|
|
|
return agrp;
|
2009-02-09 10:04:11 +00:00
|
|
|
}
|
|
|
|
|
}
|
2024-09-25 09:33:04 +02:00
|
|
|
return nullptr;
|
2009-02-09 10:04:11 +00:00
|
|
|
}
|
|
|
|
|
|
2012-04-29 17:11:40 +00:00
|
|
|
void set_active_action_group(bAction *act, bActionGroup *agrp, short select)
|
2009-02-09 10:04:11 +00:00
|
|
|
{
|
2024-09-25 09:33:04 +02:00
|
|
|
/* TODO: move this logic to the animrig::ChannelBag struct and unify with code
|
|
|
|
|
* that uses direct access to the flags. */
|
|
|
|
|
for (bActionGroup *grp : animrig::legacy::channel_groups_all(act)) {
|
2019-04-22 09:39:35 +10:00
|
|
|
if ((grp == agrp) && (select)) {
|
2009-02-09 10:04:11 +00:00
|
|
|
grp->flag |= AGRP_ACTIVE;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2009-02-09 10:04:11 +00:00
|
|
|
grp->flag &= ~AGRP_ACTIVE;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2009-02-09 10:04:11 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-03 01:15:03 +00:00
|
|
|
void action_group_colors_sync(bActionGroup *grp, const bActionGroup *ref_grp)
|
2012-06-01 13:54:44 +00:00
|
|
|
{
|
2021-06-24 15:56:58 +10:00
|
|
|
/* Only do color copying if using a custom color (i.e. not default color). */
|
2012-06-01 13:54:44 +00:00
|
|
|
if (grp->customCol) {
|
|
|
|
|
if (grp->customCol > 0) {
|
|
|
|
|
/* copy theme colors on-to group's custom color in case user tries to edit color */
|
2024-04-03 10:22:05 +11:00
|
|
|
const bTheme *btheme = static_cast<const bTheme *>(U.themes.first);
|
|
|
|
|
const ThemeWireColor *col_set = &btheme->tarm[(grp->customCol - 1)];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-06-01 13:54:44 +00:00
|
|
|
memcpy(&grp->cs, col_set, sizeof(ThemeWireColor));
|
|
|
|
|
}
|
|
|
|
|
else {
|
2012-07-03 01:15:03 +00:00
|
|
|
/* if a reference group is provided, use the custom color from there... */
|
|
|
|
|
if (ref_grp) {
|
|
|
|
|
/* assumption: reference group has a color set */
|
|
|
|
|
memcpy(&grp->cs, &ref_grp->cs, sizeof(ThemeWireColor));
|
|
|
|
|
}
|
|
|
|
|
/* otherwise, init custom color with a generic/placeholder color set if
|
|
|
|
|
* no previous theme color was used that we can just keep using
|
|
|
|
|
*/
|
|
|
|
|
else if (grp->cs.solid[0] == 0) {
|
2012-06-01 13:54:44 +00:00
|
|
|
/* define for setting colors in theme below */
|
2019-08-06 04:20:17 +10:00
|
|
|
rgba_uchar_args_set(grp->cs.solid, 0xff, 0x00, 0x00, 255);
|
|
|
|
|
rgba_uchar_args_set(grp->cs.select, 0x81, 0xe6, 0x14, 255);
|
|
|
|
|
rgba_uchar_args_set(grp->cs.active, 0x18, 0xb6, 0xe0, 255);
|
2012-06-01 13:54:44 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Anim: move bone colors from bone groups to individual bones
Move control over the color of bones from bone groups to the bones
themselves. Instead of using bone groups (which are defined on the pose,
and thus owned by the object), the color is stored on:
- the bone (`struct Bone`, or RNA `armature.bones['bone_name'].color`)
- a possible override on the pose bone (`struct bPoseChannel`, or RNA
`ob.pose.bones['bone_name'].color`).
When the pose bone is set to its default color, the color is determined
by the armature bone. In armature edit mode, the armature bone colors
are always used, as then the pose data is unavailable.
Versioning code converts bone group colors to bone colors. If the
Armature has a single user, the group color is stored on the bones
directly. If it has multiple users, the group colors will be stored on
the pose bones instead.
The bone group color is not removed from DNA for forward compatibility,
that is, to avoid immediate dataloss when saving a 3.6 file with 4.0.
This is part of the replacement of bone groups & armature layers with
bone collections. See the design task at #108941.
Pull request: https://projects.blender.org/blender/blender/pulls/109976
2023-08-22 11:11:52 +02:00
|
|
|
void action_group_colors_set_from_posebone(bActionGroup *grp, const bPoseChannel *pchan)
|
|
|
|
|
{
|
2024-02-26 17:40:57 +01:00
|
|
|
BLI_assert_msg(pchan, "cannot 'set action group colors from posebone' without a posebone");
|
|
|
|
|
if (!pchan->bone) {
|
|
|
|
|
/* pchan->bone is only set after leaving editmode. */
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-25 16:49:28 +02:00
|
|
|
const BoneColor &color = blender::animrig::ANIM_bonecolor_posebone_get(pchan);
|
|
|
|
|
action_group_colors_set(grp, &color);
|
Anim: move bone colors from bone groups to individual bones
Move control over the color of bones from bone groups to the bones
themselves. Instead of using bone groups (which are defined on the pose,
and thus owned by the object), the color is stored on:
- the bone (`struct Bone`, or RNA `armature.bones['bone_name'].color`)
- a possible override on the pose bone (`struct bPoseChannel`, or RNA
`ob.pose.bones['bone_name'].color`).
When the pose bone is set to its default color, the color is determined
by the armature bone. In armature edit mode, the armature bone colors
are always used, as then the pose data is unavailable.
Versioning code converts bone group colors to bone colors. If the
Armature has a single user, the group color is stored on the bones
directly. If it has multiple users, the group colors will be stored on
the pose bones instead.
The bone group color is not removed from DNA for forward compatibility,
that is, to avoid immediate dataloss when saving a 3.6 file with 4.0.
This is part of the replacement of bone groups & armature layers with
bone collections. See the design task at #108941.
Pull request: https://projects.blender.org/blender/blender/pulls/109976
2023-08-22 11:11:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void action_group_colors_set(bActionGroup *grp, const BoneColor *color)
|
|
|
|
|
{
|
|
|
|
|
const blender::animrig::BoneColor &bone_color = color->wrap();
|
|
|
|
|
|
|
|
|
|
grp->customCol = bone_color.palette_index;
|
|
|
|
|
|
|
|
|
|
const ThemeWireColor *effective_color = bone_color.effective_color();
|
|
|
|
|
if (effective_color) {
|
|
|
|
|
/* The drawing code assumes that grp->cs always contains the effective
|
|
|
|
|
* color. This is why the effective color is always written to it, and why
|
|
|
|
|
* the above action_group_colors_sync() function exists: it needs to update
|
|
|
|
|
* grp->cs in case the theme changes. */
|
|
|
|
|
memcpy(&grp->cs, effective_color, sizeof(grp->cs));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
bActionGroup *action_groups_add_new(bAction *act, const char name[])
|
2010-04-01 06:26:41 +00:00
|
|
|
{
|
|
|
|
|
bActionGroup *agrp;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2010-04-01 06:26:41 +00:00
|
|
|
/* sanity check: must have action and name */
|
2023-07-17 10:46:26 +02:00
|
|
|
if (ELEM(nullptr, act, name)) {
|
|
|
|
|
return nullptr;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2024-09-24 17:36:36 +02:00
|
|
|
BLI_assert(act->wrap().is_action_legacy());
|
|
|
|
|
|
2010-04-01 06:26:41 +00:00
|
|
|
/* allocate a new one */
|
2023-07-17 10:46:26 +02:00
|
|
|
agrp = static_cast<bActionGroup *>(MEM_callocN(sizeof(bActionGroup), "bActionGroup"));
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2010-04-01 06:26:41 +00:00
|
|
|
/* make it selected, with default name */
|
|
|
|
|
agrp->flag = AGRP_SELECTED;
|
2023-05-13 17:38:48 +10:00
|
|
|
STRNCPY_UTF8(agrp->name, name[0] ? name : DATA_("Group"));
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2010-04-01 06:26:41 +00:00
|
|
|
/* add to action, and validate */
|
|
|
|
|
BLI_addtail(&act->groups, agrp);
|
2013-03-25 08:29:06 +00:00
|
|
|
BLI_uniquename(
|
|
|
|
|
&act->groups, agrp, DATA_("Group"), '.', offsetof(bActionGroup, name), sizeof(agrp->name));
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2010-04-01 06:26:41 +00:00
|
|
|
/* return the new group */
|
|
|
|
|
return agrp;
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-29 17:11:40 +00:00
|
|
|
void action_groups_add_channel(bAction *act, bActionGroup *agrp, FCurve *fcurve)
|
2018-06-17 17:05:51 +02:00
|
|
|
{
|
2009-02-09 10:04:11 +00:00
|
|
|
/* sanity checks */
|
2023-07-17 10:46:26 +02:00
|
|
|
if (ELEM(nullptr, act, agrp, fcurve)) {
|
2009-02-09 10:04:11 +00:00
|
|
|
return;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-09-24 17:36:36 +02:00
|
|
|
BLI_assert(act->wrap().is_action_legacy());
|
|
|
|
|
|
2009-12-18 11:55:18 +00:00
|
|
|
/* if no channels anywhere, just add to two lists at the same time */
|
2014-02-08 06:07:10 +11:00
|
|
|
if (BLI_listbase_is_empty(&act->curves)) {
|
2023-07-17 10:46:26 +02:00
|
|
|
fcurve->next = fcurve->prev = nullptr;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-02-09 10:04:11 +00:00
|
|
|
agrp->channels.first = agrp->channels.last = fcurve;
|
|
|
|
|
act->curves.first = act->curves.last = fcurve;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-06-17 17:05:51 +02:00
|
|
|
/* if the group already has channels, the F-Curve can simply be added to the list
|
2009-12-18 11:55:18 +00:00
|
|
|
* (i.e. as the last channel in the group)
|
|
|
|
|
*/
|
|
|
|
|
else if (agrp->channels.first) {
|
2018-06-17 17:05:51 +02:00
|
|
|
/* if the group's last F-Curve is the action's last F-Curve too,
|
2009-12-18 11:55:18 +00:00
|
|
|
* then set the F-Curve as the last for the action first so that
|
|
|
|
|
* the lists will be in sync after linking
|
|
|
|
|
*/
|
2019-04-22 09:39:35 +10:00
|
|
|
if (agrp->channels.last == act->curves.last) {
|
2012-05-06 15:15:33 +00:00
|
|
|
act->curves.last = fcurve;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-12-18 11:55:18 +00:00
|
|
|
/* link in the given F-Curve after the last F-Curve in the group,
|
|
|
|
|
* which means that it should be able to fit in with the rest of the
|
|
|
|
|
* list seamlessly
|
|
|
|
|
*/
|
|
|
|
|
BLI_insertlinkafter(&agrp->channels, agrp->channels.last, fcurve);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-12-18 11:55:18 +00:00
|
|
|
/* otherwise, need to find the nearest F-Curve in group before/after current to link with */
|
|
|
|
|
else {
|
|
|
|
|
bActionGroup *grp;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-12-18 11:55:18 +00:00
|
|
|
/* firstly, link this F-Curve to the group */
|
|
|
|
|
agrp->channels.first = agrp->channels.last = fcurve;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-27 12:07:07 +10:00
|
|
|
/* Step through the groups preceding this one,
|
|
|
|
|
* finding the F-Curve there to attach this one after. */
|
2012-05-06 15:15:33 +00:00
|
|
|
for (grp = agrp->prev; grp; grp = grp->prev) {
|
2019-04-27 12:07:07 +10:00
|
|
|
/* if this group has F-Curves, we want weave the given one in right after the last channel
|
|
|
|
|
* there, but via the Action's list not this group's list
|
2018-11-14 12:53:15 +11:00
|
|
|
* - this is so that the F-Curve is in the right place in the Action,
|
2019-04-27 12:07:07 +10:00
|
|
|
* but won't be included in the previous group.
|
2009-12-18 11:55:18 +00:00
|
|
|
*/
|
|
|
|
|
if (grp->channels.last) {
|
|
|
|
|
/* once we've added, break here since we don't need to search any further... */
|
|
|
|
|
BLI_insertlinkafter(&act->curves, grp->channels.last, fcurve);
|
2009-02-09 10:04:11 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-17 10:46:26 +02:00
|
|
|
/* If grp is nullptr, that means we fell through, and this F-Curve should be added as the new
|
2019-04-27 12:07:07 +10:00
|
|
|
* first since group is (effectively) the first group. Thus, the existing first F-Curve becomes
|
2021-06-28 15:44:12 +10:00
|
|
|
* the second in the chain, etc. */
|
2023-07-17 10:46:26 +02:00
|
|
|
if (grp == nullptr) {
|
2009-12-18 11:55:18 +00:00
|
|
|
BLI_insertlinkbefore(&act->curves, act->curves.first, fcurve);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2009-02-09 10:04:11 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-12-18 11:55:18 +00:00
|
|
|
/* set the F-Curve's new group */
|
2012-05-06 15:15:33 +00:00
|
|
|
fcurve->grp = agrp;
|
2018-06-17 17:05:51 +02:00
|
|
|
}
|
2009-02-09 10:04:11 +00:00
|
|
|
|
2019-12-17 15:20:11 +01:00
|
|
|
void BKE_action_groups_reconstruct(bAction *act)
|
|
|
|
|
{
|
|
|
|
|
/* Sanity check. */
|
2024-09-24 17:36:36 +02:00
|
|
|
if (!act) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (BLI_listbase_is_empty(&act->groups)) {
|
2024-10-01 10:38:15 +02:00
|
|
|
/* NOTE: this also includes layered Actions, as act->groups is the legacy storage for groups.
|
|
|
|
|
* Layered Actions should never have to deal with 'reconstructing' groups, as arbitrarily
|
|
|
|
|
* shuffling of the underlying data isn't allowed, and the available methods for modifying
|
|
|
|
|
* F-Curves/Groups already ensure that the data is valid when they return. */
|
2019-12-17 15:20:11 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-01 10:38:15 +02:00
|
|
|
BLI_assert(act->wrap().is_action_legacy());
|
|
|
|
|
|
2019-12-17 15:20:11 +01:00
|
|
|
/* Clear out all group channels. Channels that are actually in use are
|
|
|
|
|
* reconstructed below; this step is necessary to clear out unused groups. */
|
|
|
|
|
LISTBASE_FOREACH (bActionGroup *, group, &act->groups) {
|
|
|
|
|
BLI_listbase_clear(&group->channels);
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-06 15:36:27 +03:00
|
|
|
/* Sort the channels into the group lists, destroying the act->curves list. */
|
2023-07-17 10:46:26 +02:00
|
|
|
ListBase ungrouped = {nullptr, nullptr};
|
2021-07-06 15:36:27 +03:00
|
|
|
|
|
|
|
|
LISTBASE_FOREACH_MUTABLE (FCurve *, fcurve, &act->curves) {
|
|
|
|
|
if (fcurve->grp) {
|
|
|
|
|
BLI_assert(BLI_findindex(&act->groups, fcurve->grp) >= 0);
|
2019-12-17 15:20:11 +01:00
|
|
|
|
2021-07-06 15:36:27 +03:00
|
|
|
BLI_addtail(&fcurve->grp->channels, fcurve);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BLI_addtail(&ungrouped, fcurve);
|
2019-12-17 15:20:11 +01:00
|
|
|
}
|
2021-07-06 15:36:27 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Recombine into the main list. */
|
|
|
|
|
BLI_listbase_clear(&act->curves);
|
2019-12-17 15:20:11 +01:00
|
|
|
|
2021-07-06 15:36:27 +03:00
|
|
|
LISTBASE_FOREACH (bActionGroup *, group, &act->groups) {
|
|
|
|
|
/* Copy the list header to preserve the pointers in the group. */
|
|
|
|
|
ListBase tmp = group->channels;
|
|
|
|
|
BLI_movelisttolist(&act->curves, &tmp);
|
2019-12-17 15:20:11 +01:00
|
|
|
}
|
2021-07-06 15:36:27 +03:00
|
|
|
|
|
|
|
|
BLI_movelisttolist(&act->curves, &ungrouped);
|
2019-12-17 15:20:11 +01:00
|
|
|
}
|
|
|
|
|
|
2012-04-29 17:11:40 +00:00
|
|
|
void action_groups_remove_channel(bAction *act, FCurve *fcu)
|
2009-02-09 10:04:11 +00:00
|
|
|
{
|
|
|
|
|
/* sanity checks */
|
2023-07-17 10:46:26 +02:00
|
|
|
if (ELEM(nullptr, act, fcu)) {
|
2009-02-09 10:04:11 +00:00
|
|
|
return;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-09-24 17:36:36 +02:00
|
|
|
BLI_assert(act->wrap().is_action_legacy());
|
|
|
|
|
|
2009-02-09 10:04:11 +00:00
|
|
|
/* check if any group used this directly */
|
|
|
|
|
if (fcu->grp) {
|
2012-05-06 15:15:33 +00:00
|
|
|
bActionGroup *agrp = fcu->grp;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-02-09 10:04:11 +00:00
|
|
|
if (agrp->channels.first == agrp->channels.last) {
|
|
|
|
|
if (agrp->channels.first == fcu) {
|
2014-02-08 06:07:10 +11:00
|
|
|
BLI_listbase_clear(&agrp->channels);
|
2009-02-09 10:04:11 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (agrp->channels.first == fcu) {
|
2019-04-22 09:39:35 +10:00
|
|
|
if ((fcu->next) && (fcu->next->grp == agrp)) {
|
2012-05-06 15:15:33 +00:00
|
|
|
agrp->channels.first = fcu->next;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2023-07-17 10:46:26 +02:00
|
|
|
agrp->channels.first = nullptr;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2009-02-09 10:04:11 +00:00
|
|
|
}
|
|
|
|
|
else if (agrp->channels.last == fcu) {
|
2019-04-22 09:39:35 +10:00
|
|
|
if ((fcu->prev) && (fcu->prev->grp == agrp)) {
|
2012-05-06 15:15:33 +00:00
|
|
|
agrp->channels.last = fcu->prev;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2023-07-17 10:46:26 +02:00
|
|
|
agrp->channels.last = nullptr;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2009-02-09 10:04:11 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-17 10:46:26 +02:00
|
|
|
fcu->grp = nullptr;
|
2009-02-09 10:04:11 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-02-09 10:04:11 +00:00
|
|
|
/* now just remove from list */
|
|
|
|
|
BLI_remlink(&act->curves, fcu);
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
bActionGroup *BKE_action_group_find_name(bAction *act, const char name[])
|
2009-02-09 10:04:11 +00:00
|
|
|
{
|
|
|
|
|
/* sanity checks */
|
2023-07-17 10:46:26 +02:00
|
|
|
if (ELEM(nullptr, act, act->groups.first, name) || (name[0] == 0)) {
|
|
|
|
|
return nullptr;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2024-09-24 17:36:36 +02:00
|
|
|
BLI_assert(act->wrap().is_action_legacy());
|
|
|
|
|
|
2009-02-09 10:04:11 +00:00
|
|
|
/* do string comparisons */
|
2023-07-17 10:46:26 +02:00
|
|
|
return static_cast<bActionGroup *>(
|
|
|
|
|
BLI_findstring(&act->groups, name, offsetof(bActionGroup, name)));
|
2009-02-09 10:04:11 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2012-04-29 17:11:40 +00:00
|
|
|
void action_groups_clear_tempflags(bAction *act)
|
2010-12-29 11:51:53 +00:00
|
|
|
{
|
2024-09-24 17:36:36 +02:00
|
|
|
for (bActionGroup *agrp : animrig::legacy::channel_groups_all(act)) {
|
2010-12-29 11:51:53 +00:00
|
|
|
agrp->flag &= ~AGRP_TEMP;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2010-12-29 11:51:53 +00:00
|
|
|
}
|
|
|
|
|
|
2009-09-17 10:14:56 +00:00
|
|
|
/* *************** Pose channels *************** */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2024-01-22 13:47:13 +01:00
|
|
|
void BKE_pose_channel_session_uid_generate(bPoseChannel *pchan)
|
2020-08-03 17:17:57 +02:00
|
|
|
{
|
2024-01-22 13:47:13 +01:00
|
|
|
pchan->runtime.session_uid = BLI_session_uid_generate();
|
2020-08-03 17:17:57 +02:00
|
|
|
}
|
|
|
|
|
|
2012-05-05 16:03:57 +00:00
|
|
|
bPoseChannel *BKE_pose_channel_find_name(const bPose *pose, const char *name)
|
2004-01-02 20:57:43 +00:00
|
|
|
{
|
2023-07-17 10:46:26 +02:00
|
|
|
if (ELEM(nullptr, pose, name) || (name[0] == '\0')) {
|
|
|
|
|
return nullptr;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (pose->chanhash) {
|
2023-07-17 10:46:26 +02:00
|
|
|
return static_cast<bPoseChannel *>(BLI_ghash_lookup(pose->chanhash, (const void *)name));
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2023-07-17 10:46:26 +02:00
|
|
|
return static_cast<bPoseChannel *>(
|
|
|
|
|
BLI_findstring(&pose->chanbase, name, offsetof(bPoseChannel, name)));
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2021-04-30 15:30:41 +10:00
|
|
|
bPoseChannel *BKE_pose_channel_ensure(bPose *pose, const char *name)
|
2004-01-02 20:57:43 +00:00
|
|
|
{
|
2002-10-12 11:37:38 +00:00
|
|
|
bPoseChannel *chan;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2023-07-17 10:46:26 +02:00
|
|
|
if (pose == nullptr) {
|
|
|
|
|
return nullptr;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2009-01-18 10:41:45 +00:00
|
|
|
/* See if this channel exists */
|
2018-06-11 20:26:29 +02:00
|
|
|
chan = BKE_pose_channel_find_name(pose, name);
|
2012-03-24 06:18:31 +00:00
|
|
|
if (chan) {
|
2011-05-01 06:34:40 +00:00
|
|
|
return chan;
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
}
|
2011-05-01 06:34:40 +00:00
|
|
|
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
/* If not, create it and add it */
|
2023-07-17 10:46:26 +02:00
|
|
|
chan = static_cast<bPoseChannel *>(MEM_callocN(sizeof(bPoseChannel), "verifyPoseChannel"));
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2024-01-22 13:47:13 +01:00
|
|
|
BKE_pose_channel_session_uid_generate(chan);
|
2020-08-03 17:17:57 +02:00
|
|
|
|
2023-05-09 12:50:37 +10:00
|
|
|
STRNCPY(chan->name, name);
|
2015-09-21 23:49:58 +10:00
|
|
|
|
2021-05-11 11:22:41 +02:00
|
|
|
copy_v3_fl(chan->custom_scale_xyz, 1.0f);
|
|
|
|
|
zero_v3(chan->custom_translation);
|
|
|
|
|
zero_v3(chan->custom_rotation_euler);
|
2024-05-30 15:51:30 +02:00
|
|
|
chan->custom_shape_wire_width = 1.0f;
|
2015-09-21 23:49:58 +10:00
|
|
|
|
== Constraints System ==
After just over a week of coding, I've finished doing a major refactor/cleanup of the constraints code. In the process, quite a few old kludges and ugly hacks have been removed. Also, some new features which will greatly benefit riggers have been implemented.
=== What's New ===
* The long-awaited ``ChildOf Constraint'':
This allows you to animate parent influences, and choose which transformation channels the parent affects the child on (i.e. no translation/rotation/scaling). It should be noted that disabling some combinations may not totally work as expected. Also, the 'Set Inverse' and 'Clear Inverse' buttons at the bottom of this constraint's panel set/clear the inverse correction for the parent's effects. Use these to make the owner not stick/be glued to the parent.
* Constraint/Target Evaluation Spaces:
In some constraints, there are now 1-2 combo boxes at the bottom of their panel, which allows you to pick which `co-ordinate space' they are evaluated in. This is much more flexible than the old 'local' options for bones only were.
* Action Constraint - Loc/Rot/Size Inputs
The Action Constraint can finally use the target's location/rotation/scaling transforms as input, to control the owner of the constraint. This should work much more reliably than it used to. The target evaluation should now also be more accurate due to the new space conversion stuff.
* Transform - No longer in Crazy Space (TM)
Transforming objects/bones with constraints applied should no longer occur in Crazy Space. They are now correctly inverse-corrected. This also applies to old-style object tracking.
=== General Code Changes ===
* solve_constraints is now in constraints.c. I've removed the old `blend consecutive constraints of same type' junk, which made the code more complex than it needed to be.
* evaluate_constraint is now only passed the constraint, and two matrices. A few unused variables have been removed from here.
* A tempolary struct, bConstraintOb, is now passed to solve_constraints instead of relying on an ugly, static workobject in some cases. This works much better.
* Made the formatting of constraint code consistent
* There's a version patch for older files so that constraint settings are correctly converted to the new system. This is currently done for MajorVersion <= 244, and SubVersion < 3. I've bumped up the subversion to 3 for this purpose. However, with the imminent 2.45 release, this may need to be adjusted accordingly.
* LocEulSizeToMat4 and LocQuatSizeToMat4 now work in the order Size, Rot, Location. I've also added a few other math functions.
* Mat4BlendMat4 is now in arithb. I've modified it's method slightly, to use other arithb functions, instead of its crazy blending scheme.
* Moved some of the RigidBodyJoint constraint's code out of blenkernel, and into src. It shouldn't be setting its target in its data initialisation function based + accessing scene stuff where it was doing so.
=== Future Work ===
* Geometry to act as targets for constraints. A space has been reserved for this already.
* Tidy up UI buttons of constraints
2007-07-15 03:35:37 +00:00
|
|
|
/* init vars to prevent math errors */
|
2011-02-02 00:40:55 +00:00
|
|
|
unit_qt(chan->quat);
|
|
|
|
|
unit_axis_angle(chan->rotAxis, &chan->rotAngle);
|
2009-01-18 10:41:45 +00:00
|
|
|
chan->size[0] = chan->size[1] = chan->size[2] = 1.0f;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
Armature: add B-Bone Y scale channel and extra flag fields to DNA.
In addition to the base bone transformation itself, B-Bones have
controls that affect transformation of its segments. For rotation
the features are quite complete, allowing to both reorient the
Bezier handles via properties, and to control them using custom
handle bones. However for scaling there are two deficiencies.
First, there are only X and Y scale factors (actually X and Z),
while lengthwise all segments have the same scaling. The ease
option merely affects the shape of the curve, and does not cause
actual scaling.
Second, scaling can only be controlled via properties, thus
requiring up to 6 drivers per joint between B-Bones to transfer
scaling factors from the handle bone. This is very inefficient.
Finally, the Z channels are confusingly called Y.
This commit adds a B-Bone Y Scale channel and extra B-Bone flag
fields to DNA with appropriate versioning (including for F-Curves
and drivers) in preparation to addressing these limitations.
Functionality is not changed, so the new fields are not used
until the following commits.
Differential Revision: https://developer.blender.org/D9870
2020-12-11 19:17:39 +03:00
|
|
|
copy_v3_fl(chan->scale_in, 1.0f);
|
|
|
|
|
copy_v3_fl(chan->scale_out, 1.0f);
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2016-11-16 11:09:02 +13:00
|
|
|
chan->limitmin[0] = chan->limitmin[1] = chan->limitmin[2] = -M_PI;
|
|
|
|
|
chan->limitmax[0] = chan->limitmax[1] = chan->limitmax[2] = M_PI;
|
2012-05-06 15:15:33 +00:00
|
|
|
chan->stiffness[0] = chan->stiffness[1] = chan->stiffness[2] = 0.0f;
|
2009-09-24 21:22:24 +00:00
|
|
|
chan->ikrotweight = chan->iklinweight = 0.0f;
|
2009-11-10 20:43:45 +00:00
|
|
|
unit_m4(chan->constinv);
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
chan->protectflag = OB_LOCK_ROT4D; /* lock by components by default */
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2.5: Blender "Animato" - New Animation System
Finally, here is the basic (functional) prototype of the new animation system which will allow for the infamous "everything is animatable", and which also addresses several of the more serious shortcomings of the old system. Unfortunately, this will break old animation files (especially right now, as I haven't written the version patching code yet), however, this is for the future.
Highlights of the new system:
* Scrapped IPO-Curves/IPO/(Action+Constraint-Channels)/Action system, and replaced it with F-Curve/Action.
- F-Curves (animators from other packages will feel at home with this name) replace IPO-Curves.
- The 'new' Actions, act as the containers for F-Curves, so that they can be reused. They are therefore more akin to the old 'IPO' blocks, except they do not have the blocktype restriction, so you can store materials/texture/geometry F-Curves in the same Action as Object transforms, etc.
* F-Curves use RNA-paths for Data Access, hence allowing "every" (where sensible/editable that is) user-accessible setting from RNA to be animated.
* Drivers are no longer mixed with Animation Data, so rigs will not be that easily broken and several dependency problems can be eliminated. (NOTE: drivers haven't been hooked up yet, but the code is in place)
* F-Curve modifier system allows useful 'large-scale' manipulation of F-Curve values, including (I've only included implemented ones here): envelope deform (similar to lattices to allow broad-scale reshaping of curves), curve generator (polynomial or py-expression), cycles (replacing the old cyclic extrapolation modes, giving more control over this). (NOTE: currently this cannot be tested, as there's not access to them, but the code is all in place)
* NLA system with 'tracks' (i.e. layers), and multiple strips per track. (NOTE: NLA system is not yet functional, as it's only partially coded still)
There are more nice things that I will be preparing some nice docs for soon, but for now, check for more details:
http://lists.blender.org/pipermail/bf-taskforce25/2009-January/000260.html
So, what currently works:
* I've implemented two basic operators for the 3D-view only to Insert and Delete Keyframes. These are tempolary ones only that will be replaced in due course with 'proper' code.
* Object Loc/Rot/Scale can be keyframed. Also, the colour of the 'active' material (Note: this should really be for nth material instead, but that doesn't work yet in RNA) can also be keyframed into the same datablock.
* Standard animation refresh (i.e. animation resulting from NLA and Action evaluation) is now done completely separate from drivers before anything else is done after a frame change. Drivers are handled after this in a separate pass, as dictated by depsgraph flags, etc.
Notes:
* Drivers haven't been hooked up yet
* Only objects and data directly linked to objects can be animated.
* Depsgraph will need further tweaks. Currently, I've only made sure that it will update some things in the most basic cases (i.e. frame change).
* Animation Editors are currently broken (in terms of editing stuff). This will be my next target (priority to get Dopesheet working first, then F-Curve editor - i.e. old IPO Editor)
* I've had to put in large chunks of XXX sandboxing for old animation system code all around the place. This will be cleaned up in due course, as some places need special review.
In particular, the particles and sequencer code have far too many manual calls to calculate + flush animation info, which is really bad (this is a 'please explain yourselves' call to Physics coders!).
2009-01-17 03:12:50 +00:00
|
|
|
BLI_addtail(&pose->chanbase, chan);
|
2018-06-11 20:26:29 +02:00
|
|
|
if (pose->chanhash) {
|
|
|
|
|
BLI_ghash_insert(pose->chanhash, chan->name, chan);
|
|
|
|
|
}
|
2018-06-17 17:05:51 +02:00
|
|
|
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
return chan;
|
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2013-10-01 13:28:59 +00:00
|
|
|
#ifndef NDEBUG
|
|
|
|
|
bool BKE_pose_channels_is_valid(const bPose *pose)
|
|
|
|
|
{
|
|
|
|
|
if (pose->chanhash) {
|
|
|
|
|
bPoseChannel *pchan;
|
2023-07-17 10:46:26 +02:00
|
|
|
for (pchan = static_cast<bPoseChannel *>(pose->chanbase.first); pchan; pchan = pchan->next) {
|
2013-10-01 13:28:59 +00:00
|
|
|
if (BLI_ghash_lookup(pose->chanhash, pchan->name) != pchan) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-10-01 13:28:59 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
2013-10-26 03:56:32 +00:00
|
|
|
|
2023-08-29 10:59:06 +02:00
|
|
|
bool BKE_pose_is_bonecoll_visible(const bArmature *arm, const bPoseChannel *pchan)
|
2021-11-09 12:22:06 +01:00
|
|
|
{
|
2024-01-04 13:42:23 +01:00
|
|
|
return pchan->bone && ANIM_bone_in_visible_collection(arm, pchan->bone);
|
2021-11-09 12:22:06 +01:00
|
|
|
}
|
|
|
|
|
|
2023-08-29 10:59:06 +02:00
|
|
|
bPoseChannel *BKE_pose_channel_active(Object *ob, const bool check_bonecoll)
|
2008-12-21 10:33:24 +00:00
|
|
|
{
|
2023-07-17 10:46:26 +02:00
|
|
|
bArmature *arm = static_cast<bArmature *>((ob) ? ob->data : nullptr);
|
|
|
|
|
if (ELEM(nullptr, ob, ob->pose, arm)) {
|
|
|
|
|
return nullptr;
|
2012-03-25 22:35:18 +00:00
|
|
|
}
|
|
|
|
|
|
2008-12-21 10:33:24 +00:00
|
|
|
/* find active */
|
2023-08-04 08:51:13 +10:00
|
|
|
LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
|
2021-11-09 12:22:06 +01:00
|
|
|
if ((pchan->bone) && (pchan->bone == arm->act_bone)) {
|
2024-01-04 13:42:23 +01:00
|
|
|
if (!check_bonecoll || ANIM_bone_in_visible_collection(arm, pchan->bone)) {
|
2021-11-09 12:22:06 +01:00
|
|
|
return pchan;
|
|
|
|
|
}
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2008-12-21 10:33:24 +00:00
|
|
|
}
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2023-07-17 10:46:26 +02:00
|
|
|
return nullptr;
|
2008-12-21 10:33:24 +00:00
|
|
|
}
|
|
|
|
|
|
2023-08-29 10:59:06 +02:00
|
|
|
bPoseChannel *BKE_pose_channel_active_if_bonecoll_visible(Object *ob)
|
2021-11-09 12:22:06 +01:00
|
|
|
{
|
|
|
|
|
return BKE_pose_channel_active(ob, true);
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-03 08:36:28 +10:00
|
|
|
bPoseChannel *BKE_pose_channel_active_or_first_selected(Object *ob)
|
2019-07-18 18:45:56 +10:00
|
|
|
{
|
2023-07-17 10:46:26 +02:00
|
|
|
bArmature *arm = static_cast<bArmature *>((ob) ? ob->data : nullptr);
|
2019-07-18 18:45:56 +10:00
|
|
|
|
2023-07-17 10:46:26 +02:00
|
|
|
if (ELEM(nullptr, ob, ob->pose, arm)) {
|
|
|
|
|
return nullptr;
|
2019-07-18 18:45:56 +10:00
|
|
|
}
|
|
|
|
|
|
2023-08-29 10:59:06 +02:00
|
|
|
bPoseChannel *pchan = BKE_pose_channel_active_if_bonecoll_visible(ob);
|
2019-07-18 18:45:56 +10:00
|
|
|
if (pchan && (pchan->bone->flag & BONE_SELECTED) && PBONE_VISIBLE(arm, pchan->bone)) {
|
|
|
|
|
return pchan;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-04 08:51:13 +10:00
|
|
|
LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
|
2023-07-17 10:46:26 +02:00
|
|
|
if (pchan->bone != nullptr) {
|
2019-07-18 18:45:56 +10:00
|
|
|
if ((pchan->bone->flag & BONE_SELECTED) && PBONE_VISIBLE(arm, pchan->bone)) {
|
|
|
|
|
return pchan;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-07-17 10:46:26 +02:00
|
|
|
return nullptr;
|
2019-07-18 18:45:56 +10:00
|
|
|
}
|
|
|
|
|
|
2013-11-17 04:30:36 +11:00
|
|
|
bPoseChannel *BKE_pose_channel_get_mirrored(const bPose *pose, const char *name)
|
|
|
|
|
{
|
|
|
|
|
char name_flip[MAXBONENAME];
|
|
|
|
|
|
2017-01-16 20:34:13 +01:00
|
|
|
BLI_string_flip_side_name(name_flip, name, false, sizeof(name_flip));
|
2013-11-17 04:30:36 +11:00
|
|
|
|
|
|
|
|
if (!STREQ(name_flip, name)) {
|
|
|
|
|
return BKE_pose_channel_find_name(pose, name_flip);
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-17 10:46:26 +02:00
|
|
|
return nullptr;
|
2013-11-17 04:30:36 +11:00
|
|
|
}
|
|
|
|
|
|
2012-05-05 16:03:57 +00:00
|
|
|
const char *BKE_pose_ikparam_get_name(bPose *pose)
|
2009-09-24 21:22:24 +00:00
|
|
|
{
|
|
|
|
|
if (pose) {
|
|
|
|
|
switch (pose->iksolver) {
|
2012-11-24 00:18:34 +00:00
|
|
|
case IKSOLVER_STANDARD:
|
2023-07-17 10:46:26 +02:00
|
|
|
return nullptr;
|
2012-05-06 15:15:33 +00:00
|
|
|
case IKSOLVER_ITASC:
|
|
|
|
|
return "bItasc";
|
2009-09-24 21:22:24 +00:00
|
|
|
}
|
|
|
|
|
}
|
2023-07-17 10:46:26 +02:00
|
|
|
return nullptr;
|
2009-09-24 21:22:24 +00:00
|
|
|
}
|
2013-10-26 03:56:32 +00:00
|
|
|
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
void BKE_pose_copy_data_ex(bPose **dst,
|
|
|
|
|
const bPose *src,
|
|
|
|
|
const int flag,
|
|
|
|
|
const bool copy_constraints)
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
{
|
|
|
|
|
bPose *outPose;
|
|
|
|
|
ListBase listb;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Cleanup of MotionPaths+Ghosts (AnimViz) - Part 1
This commit sets up some of the groundwork necessary to extend the animation visualisation capabilities, previously only available for bones in PoseMode, to Objects as well. Also, some of the other goals of this refactor is to make future visualisation goodies (i.e. editable paths) more feasible...
(There's really nothing to see here yet. The following log notes are really just for my own reference to keep track of things.)
Currently, the following things have been done:
* New datastructures + settings have been tidied up, ready for usage
* Added these new types into the Object and PoseBone code as necessary, with freeing/adding/copying accounted for
* File IO code for the new data, including version patching to convert the old system to the new one.
* Set up the drawing system for motionpaths based on the old armature path drawing code. Armatures still draw using the old system, since the two systems use different storage systems.
* Started setting up the motionpath 'baking' code, but the core of this still needs to be coded...
Next Steps (after some semi-urgent Durian Driver changes):
* Port the ghosting/onionskinning code over too
* Finish motionpath baking code
* RNA wrapping for the new types
* Hooking up all the new code into the operators, etc.
2010-01-01 12:24:16 +00:00
|
|
|
if (!src) {
|
2023-07-17 10:46:26 +02:00
|
|
|
*dst = nullptr;
|
2002-10-12 11:37:38 +00:00
|
|
|
return;
|
2008-06-13 02:20:09 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-17 10:46:26 +02:00
|
|
|
outPose = static_cast<bPose *>(MEM_callocN(sizeof(bPose), "pose"));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2008-12-19 11:45:46 +00:00
|
|
|
BLI_duplicatelist(&outPose->chanbase, &src->chanbase);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-05-20 19:08:48 +12:00
|
|
|
/* Rebuild ghash here too, so that name lookups below won't be too bad...
|
|
|
|
|
* BUT this will have the penalty that the ghash will be built twice
|
|
|
|
|
* if BKE_pose_rebuild() gets called after this...
|
|
|
|
|
*/
|
|
|
|
|
if (outPose->chanbase.first != outPose->chanbase.last) {
|
2023-07-17 10:46:26 +02:00
|
|
|
outPose->chanhash = nullptr;
|
2021-04-30 15:28:13 +10:00
|
|
|
BKE_pose_channels_hash_ensure(outPose);
|
2016-05-20 19:08:48 +12:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-09-24 21:22:24 +00:00
|
|
|
outPose->iksolver = src->iksolver;
|
2023-07-17 10:46:26 +02:00
|
|
|
outPose->ikdata = nullptr;
|
2009-09-24 21:22:24 +00:00
|
|
|
outPose->ikparam = MEM_dupallocN(src->ikparam);
|
2012-10-03 08:51:05 +00:00
|
|
|
outPose->avs = src->avs;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-08-04 08:51:13 +10:00
|
|
|
LISTBASE_FOREACH (bPoseChannel *, pchan, &outPose->chanbase) {
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
|
|
|
|
|
id_us_plus((ID *)pchan->custom);
|
2014-05-01 05:57:01 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-08-03 17:17:57 +02:00
|
|
|
if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
|
2024-01-22 13:47:13 +01:00
|
|
|
BKE_pose_channel_session_uid_generate(pchan);
|
2020-08-03 17:17:57 +02:00
|
|
|
}
|
|
|
|
|
|
2016-05-20 19:08:48 +12:00
|
|
|
/* warning, O(n2) here, if done without the hash, but these are rarely used features. */
|
2014-05-01 06:05:35 +10:00
|
|
|
if (pchan->custom_tx) {
|
|
|
|
|
pchan->custom_tx = BKE_pose_channel_find_name(outPose, pchan->custom_tx->name);
|
|
|
|
|
}
|
2016-05-20 19:08:48 +12:00
|
|
|
if (pchan->bbone_prev) {
|
|
|
|
|
pchan->bbone_prev = BKE_pose_channel_find_name(outPose, pchan->bbone_prev->name);
|
|
|
|
|
}
|
|
|
|
|
if (pchan->bbone_next) {
|
|
|
|
|
pchan->bbone_next = BKE_pose_channel_find_name(outPose, pchan->bbone_next->name);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-10-26 03:56:32 +00:00
|
|
|
if (copy_constraints) {
|
2023-07-17 10:46:26 +02:00
|
|
|
/* #BKE_constraints_copy nullptr's `listb` */
|
2021-06-23 12:05:40 +10:00
|
|
|
BKE_constraints_copy_ex(&listb, &pchan->constraints, flag, true);
|
|
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
pchan->constraints = listb;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-27 12:07:07 +10:00
|
|
|
/* XXX: This is needed for motionpath drawing to work.
|
|
|
|
|
* Dunno why it was setting to null before... */
|
2018-06-01 16:38:21 +02:00
|
|
|
pchan->mpath = animviz_copy_motionpath(pchan->mpath);
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:18:31 +00:00
|
|
|
if (pchan->prop) {
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
pchan->prop = IDP_CopyProperty_ex(pchan->prop, flag);
|
2009-11-23 13:35:21 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-17 10:46:26 +02:00
|
|
|
pchan->draw_data = nullptr; /* Drawing cache, no need to copy. */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-11-22 13:38:03 +03:00
|
|
|
/* Runtime data, no need to copy. */
|
2020-08-03 17:17:57 +02:00
|
|
|
BKE_pose_channel_runtime_reset_on_copy(&pchan->runtime);
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-11-23 13:35:21 +00:00
|
|
|
/* for now, duplicate Bone Groups too when doing this */
|
2013-10-26 03:56:32 +00:00
|
|
|
if (copy_constraints) {
|
2009-11-23 13:35:21 +00:00
|
|
|
BLI_duplicatelist(&outPose->agroups, &src->agroups);
|
2013-10-26 03:56:32 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
*dst = outPose;
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
void BKE_pose_copy_data(bPose **dst, const bPose *src, const bool copy_constraints)
|
|
|
|
|
{
|
|
|
|
|
BKE_pose_copy_data_ex(dst, src, 0, copy_constraints);
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-05 16:03:57 +00:00
|
|
|
void BKE_pose_itasc_init(bItasc *itasc)
|
2009-09-24 21:22:24 +00:00
|
|
|
{
|
|
|
|
|
if (itasc) {
|
|
|
|
|
itasc->iksolver = IKSOLVER_ITASC;
|
|
|
|
|
itasc->minstep = 0.01f;
|
|
|
|
|
itasc->maxstep = 0.06f;
|
|
|
|
|
itasc->numiter = 100;
|
|
|
|
|
itasc->numstep = 4;
|
|
|
|
|
itasc->precision = 0.005f;
|
2012-05-06 15:15:33 +00:00
|
|
|
itasc->flag = ITASC_AUTO_STEP | ITASC_INITIAL_REITERATION;
|
2012-04-11 08:15:13 +00:00
|
|
|
itasc->feedback = 20.0f;
|
|
|
|
|
itasc->maxvel = 50.0f;
|
2009-09-24 21:22:24 +00:00
|
|
|
itasc->solver = ITASC_SOLVER_SDLS;
|
|
|
|
|
itasc->dampmax = 0.5;
|
|
|
|
|
itasc->dampeps = 0.15;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-05-05 16:03:57 +00:00
|
|
|
void BKE_pose_ikparam_init(bPose *pose)
|
2009-09-24 21:22:24 +00:00
|
|
|
{
|
|
|
|
|
bItasc *itasc;
|
|
|
|
|
switch (pose->iksolver) {
|
2012-05-06 15:15:33 +00:00
|
|
|
case IKSOLVER_ITASC:
|
2023-07-17 10:46:26 +02:00
|
|
|
itasc = static_cast<bItasc *>(MEM_callocN(sizeof(bItasc), "itasc"));
|
2012-05-06 15:15:33 +00:00
|
|
|
BKE_pose_itasc_init(itasc);
|
|
|
|
|
pose->ikparam = itasc;
|
|
|
|
|
break;
|
2012-11-24 00:18:34 +00:00
|
|
|
case IKSOLVER_STANDARD:
|
2012-05-06 15:15:33 +00:00
|
|
|
default:
|
2023-07-17 10:46:26 +02:00
|
|
|
pose->ikparam = nullptr;
|
2012-05-06 15:15:33 +00:00
|
|
|
break;
|
2009-09-24 21:22:24 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-13 03:03:46 +00:00
|
|
|
/* only for real IK, not for auto-IK */
|
|
|
|
|
static bool pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan, int level)
|
|
|
|
|
{
|
|
|
|
|
/* No need to check if constraint is active (has influence),
|
|
|
|
|
* since all constraints with CONSTRAINT_IK_AUTO are active */
|
2023-08-04 08:51:13 +10:00
|
|
|
LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) {
|
2013-09-13 03:03:46 +00:00
|
|
|
if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
|
2023-07-17 10:46:26 +02:00
|
|
|
bKinematicConstraint *data = static_cast<bKinematicConstraint *>(con->data);
|
2013-09-13 03:03:46 +00:00
|
|
|
if ((data->rootbone == 0) || (data->rootbone > level)) {
|
2019-04-22 09:39:35 +10:00
|
|
|
if ((data->flag & CONSTRAINT_IK_AUTO) == 0) {
|
2013-09-13 03:03:46 +00:00
|
|
|
return true;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2013-09-13 03:03:46 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-08-04 08:51:13 +10:00
|
|
|
LISTBASE_FOREACH (Bone *, bone, &pchan->bone->childbase) {
|
2013-09-13 03:03:46 +00:00
|
|
|
pchan = BKE_pose_channel_find_name(ob->pose, bone->name);
|
2019-04-22 09:39:35 +10:00
|
|
|
if (pchan && pose_channel_in_IK_chain(ob, pchan, level + 1)) {
|
2013-09-13 03:03:46 +00:00
|
|
|
return true;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2013-09-13 03:03:46 +00:00
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool BKE_pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan)
|
|
|
|
|
{
|
|
|
|
|
return pose_channel_in_IK_chain(ob, pchan, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-30 15:28:13 +10:00
|
|
|
void BKE_pose_channels_hash_ensure(bPose *pose)
|
2010-03-26 10:33:53 +00:00
|
|
|
{
|
2012-03-24 06:18:31 +00:00
|
|
|
if (!pose->chanhash) {
|
2012-05-16 00:51:36 +00:00
|
|
|
pose->chanhash = BLI_ghash_str_new("make_pose_chan gh");
|
2023-08-04 08:51:13 +10:00
|
|
|
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
|
2010-03-26 10:33:53 +00:00
|
|
|
BLI_ghash_insert(pose->chanhash, pchan->name, pchan);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2010-03-26 10:33:53 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-17 17:05:51 +02:00
|
|
|
void BKE_pose_channels_hash_free(bPose *pose)
|
2010-03-26 10:33:53 +00:00
|
|
|
{
|
2012-03-24 06:18:31 +00:00
|
|
|
if (pose->chanhash) {
|
2023-07-17 10:46:26 +02:00
|
|
|
BLI_ghash_free(pose->chanhash, nullptr, nullptr);
|
|
|
|
|
pose->chanhash = nullptr;
|
2010-03-26 10:33:53 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-15 15:13:33 +02:00
|
|
|
static void pose_channels_remove_internal_links(Object *ob, bPoseChannel *unlinked_pchan)
|
|
|
|
|
{
|
|
|
|
|
LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
|
|
|
|
|
if (pchan->bbone_prev == unlinked_pchan) {
|
2023-07-17 10:46:26 +02:00
|
|
|
pchan->bbone_prev = nullptr;
|
2019-07-15 15:13:33 +02:00
|
|
|
}
|
|
|
|
|
if (pchan->bbone_next == unlinked_pchan) {
|
2023-07-17 10:46:26 +02:00
|
|
|
pchan->bbone_next = nullptr;
|
2019-07-15 15:13:33 +02:00
|
|
|
}
|
|
|
|
|
if (pchan->custom_tx == unlinked_pchan) {
|
2023-07-17 10:46:26 +02:00
|
|
|
pchan->custom_tx = nullptr;
|
2019-07-15 15:13:33 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-13 03:20:07 +10:00
|
|
|
void BKE_pose_channels_remove(Object *ob,
|
|
|
|
|
bool (*filter_fn)(const char *bone_name, void *user_data),
|
|
|
|
|
void *user_data)
|
|
|
|
|
{
|
2016-05-20 19:08:48 +12:00
|
|
|
/* Erase any associated pose channel, along with any references to them */
|
2015-06-13 03:20:07 +10:00
|
|
|
if (ob->pose) {
|
|
|
|
|
bPoseChannel *pchan, *pchan_next;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-17 10:46:26 +02:00
|
|
|
for (pchan = static_cast<bPoseChannel *>(ob->pose->chanbase.first); pchan; pchan = pchan_next)
|
|
|
|
|
{
|
2015-06-13 03:20:07 +10:00
|
|
|
pchan_next = pchan->next;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-06-13 03:20:07 +10:00
|
|
|
if (filter_fn(pchan->name, user_data)) {
|
2016-05-20 19:08:48 +12:00
|
|
|
/* Bone itself is being removed */
|
2015-06-13 03:20:07 +10:00
|
|
|
BKE_pose_channel_free(pchan);
|
2019-07-15 15:13:33 +02:00
|
|
|
pose_channels_remove_internal_links(ob, pchan);
|
2015-06-13 03:20:07 +10:00
|
|
|
if (ob->pose->chanhash) {
|
2023-07-17 10:46:26 +02:00
|
|
|
BLI_ghash_remove(ob->pose->chanhash, pchan->name, nullptr, nullptr);
|
2015-06-13 03:20:07 +10:00
|
|
|
}
|
|
|
|
|
BLI_freelinkN(&ob->pose->chanbase, pchan);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2016-05-20 19:08:48 +12:00
|
|
|
/* Maybe something the bone references is being removed instead? */
|
2023-08-04 08:51:13 +10:00
|
|
|
LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) {
|
2023-07-17 10:46:26 +02:00
|
|
|
ListBase targets = {nullptr, nullptr};
|
2020-11-23 23:42:05 +03:00
|
|
|
if (BKE_constraint_targets_get(con, &targets)) {
|
2023-08-04 08:51:13 +10:00
|
|
|
LISTBASE_FOREACH (bConstraintTarget *, ct, &targets) {
|
2015-06-13 03:20:07 +10:00
|
|
|
if (ct->tar == ob) {
|
|
|
|
|
if (ct->subtarget[0]) {
|
|
|
|
|
if (filter_fn(ct->subtarget, user_data)) {
|
|
|
|
|
con->flag |= CONSTRAINT_DISABLE;
|
|
|
|
|
ct->subtarget[0] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-22 11:36:59 +10:00
|
|
|
BKE_constraint_targets_flush(con, &targets, false);
|
2015-06-13 03:20:07 +10:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-05-20 19:08:48 +12:00
|
|
|
if (pchan->bbone_prev) {
|
2019-04-22 09:39:35 +10:00
|
|
|
if (filter_fn(pchan->bbone_prev->name, user_data)) {
|
2023-07-17 10:46:26 +02:00
|
|
|
pchan->bbone_prev = nullptr;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2016-05-20 19:08:48 +12:00
|
|
|
}
|
|
|
|
|
if (pchan->bbone_next) {
|
2019-04-22 09:39:35 +10:00
|
|
|
if (filter_fn(pchan->bbone_next->name, user_data)) {
|
2023-07-17 10:46:26 +02:00
|
|
|
pchan->bbone_next = nullptr;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2016-05-20 19:08:48 +12:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-05-20 19:08:48 +12:00
|
|
|
if (pchan->custom_tx) {
|
2019-04-22 09:39:35 +10:00
|
|
|
if (filter_fn(pchan->custom_tx->name, user_data)) {
|
2023-07-17 10:46:26 +02:00
|
|
|
pchan->custom_tx = nullptr;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2016-05-20 19:08:48 +12:00
|
|
|
}
|
2015-06-13 03:20:07 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-25 16:43:26 +06:00
|
|
|
void BKE_pose_channel_free_ex(bPoseChannel *pchan, bool do_id_user)
|
2009-11-21 11:26:09 +00:00
|
|
|
{
|
2013-08-07 15:23:09 +00:00
|
|
|
if (pchan->custom) {
|
2013-12-25 16:43:26 +06:00
|
|
|
if (do_id_user) {
|
|
|
|
|
id_us_min(&pchan->custom->id);
|
|
|
|
|
}
|
2023-07-17 10:46:26 +02:00
|
|
|
pchan->custom = nullptr;
|
2013-08-07 15:23:09 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Cleanup of MotionPaths+Ghosts (AnimViz) - Part 1
This commit sets up some of the groundwork necessary to extend the animation visualisation capabilities, previously only available for bones in PoseMode, to Objects as well. Also, some of the other goals of this refactor is to make future visualisation goodies (i.e. editable paths) more feasible...
(There's really nothing to see here yet. The following log notes are really just for my own reference to keep track of things.)
Currently, the following things have been done:
* New datastructures + settings have been tidied up, ready for usage
* Added these new types into the Object and PoseBone code as necessary, with freeing/adding/copying accounted for
* File IO code for the new data, including version patching to convert the old system to the new one.
* Set up the drawing system for motionpaths based on the old armature path drawing code. Armatures still draw using the old system, since the two systems use different storage systems.
* Started setting up the motionpath 'baking' code, but the core of this still needs to be coded...
Next Steps (after some semi-urgent Durian Driver changes):
* Port the ghosting/onionskinning code over too
* Finish motionpath baking code
* RNA wrapping for the new types
* Hooking up all the new code into the operators, etc.
2010-01-01 12:24:16 +00:00
|
|
|
if (pchan->mpath) {
|
|
|
|
|
animviz_free_motionpath(pchan->mpath);
|
2023-07-17 10:46:26 +02:00
|
|
|
pchan->mpath = nullptr;
|
Cleanup of MotionPaths+Ghosts (AnimViz) - Part 1
This commit sets up some of the groundwork necessary to extend the animation visualisation capabilities, previously only available for bones in PoseMode, to Objects as well. Also, some of the other goals of this refactor is to make future visualisation goodies (i.e. editable paths) more feasible...
(There's really nothing to see here yet. The following log notes are really just for my own reference to keep track of things.)
Currently, the following things have been done:
* New datastructures + settings have been tidied up, ready for usage
* Added these new types into the Object and PoseBone code as necessary, with freeing/adding/copying accounted for
* File IO code for the new data, including version patching to convert the old system to the new one.
* Set up the drawing system for motionpaths based on the old armature path drawing code. Armatures still draw using the old system, since the two systems use different storage systems.
* Started setting up the motionpath 'baking' code, but the core of this still needs to be coded...
Next Steps (after some semi-urgent Durian Driver changes):
* Port the ghosting/onionskinning code over too
* Finish motionpath baking code
* RNA wrapping for the new types
* Hooking up all the new code into the operators, etc.
2010-01-01 12:24:16 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-03-06 15:21:01 +05:00
|
|
|
BKE_constraints_free_ex(&pchan->constraints, do_id_user);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Cleanup of MotionPaths+Ghosts (AnimViz) - Part 1
This commit sets up some of the groundwork necessary to extend the animation visualisation capabilities, previously only available for bones in PoseMode, to Objects as well. Also, some of the other goals of this refactor is to make future visualisation goodies (i.e. editable paths) more feasible...
(There's really nothing to see here yet. The following log notes are really just for my own reference to keep track of things.)
Currently, the following things have been done:
* New datastructures + settings have been tidied up, ready for usage
* Added these new types into the Object and PoseBone code as necessary, with freeing/adding/copying accounted for
* File IO code for the new data, including version patching to convert the old system to the new one.
* Set up the drawing system for motionpaths based on the old armature path drawing code. Armatures still draw using the old system, since the two systems use different storage systems.
* Started setting up the motionpath 'baking' code, but the core of this still needs to be coded...
Next Steps (after some semi-urgent Durian Driver changes):
* Port the ghosting/onionskinning code over too
* Finish motionpath baking code
* RNA wrapping for the new types
* Hooking up all the new code into the operators, etc.
2010-01-01 12:24:16 +00:00
|
|
|
if (pchan->prop) {
|
2020-07-01 14:42:24 +03:00
|
|
|
IDP_FreeProperty_ex(pchan->prop, do_id_user);
|
2023-07-17 10:46:26 +02:00
|
|
|
pchan->prop = nullptr;
|
2009-11-21 11:26:09 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-04 01:32:16 +10:00
|
|
|
/* Cached data, for new draw manager rendering code. */
|
2017-05-03 16:10:25 +02:00
|
|
|
MEM_SAFE_FREE(pchan->draw_data);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-18 21:19:57 +03:00
|
|
|
/* Cached B-Bone shape and other data. */
|
|
|
|
|
BKE_pose_channel_runtime_free(&pchan->runtime);
|
2018-11-22 13:38:03 +03:00
|
|
|
}
|
|
|
|
|
|
2019-04-18 21:19:57 +03:00
|
|
|
void BKE_pose_channel_runtime_reset(bPoseChannel_Runtime *runtime)
|
2018-11-22 13:38:03 +03:00
|
|
|
{
|
2019-04-18 21:19:57 +03:00
|
|
|
memset(runtime, 0, sizeof(*runtime));
|
|
|
|
|
}
|
2018-11-22 13:38:03 +03:00
|
|
|
|
2020-08-03 17:17:57 +02:00
|
|
|
void BKE_pose_channel_runtime_reset_on_copy(bPoseChannel_Runtime *runtime)
|
|
|
|
|
{
|
2024-01-22 13:47:13 +01:00
|
|
|
const SessionUID uid = runtime->session_uid;
|
2020-08-03 17:17:57 +02:00
|
|
|
memset(runtime, 0, sizeof(*runtime));
|
2024-01-22 13:47:13 +01:00
|
|
|
runtime->session_uid = uid;
|
2020-08-03 17:17:57 +02:00
|
|
|
}
|
|
|
|
|
|
2019-04-18 21:19:57 +03:00
|
|
|
void BKE_pose_channel_runtime_free(bPoseChannel_Runtime *runtime)
|
|
|
|
|
{
|
|
|
|
|
BKE_pose_channel_free_bbone_cache(runtime);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_pose_channel_free_bbone_cache(bPoseChannel_Runtime *runtime)
|
|
|
|
|
{
|
2018-11-22 13:38:03 +03:00
|
|
|
runtime->bbone_segments = 0;
|
|
|
|
|
MEM_SAFE_FREE(runtime->bbone_rest_mats);
|
|
|
|
|
MEM_SAFE_FREE(runtime->bbone_pose_mats);
|
|
|
|
|
MEM_SAFE_FREE(runtime->bbone_deform_mats);
|
|
|
|
|
MEM_SAFE_FREE(runtime->bbone_dual_quats);
|
Anim: implement a new curve-aware vertex to B-Bone segment mapping mode.
Currently vertices are mapped to B-Bone segments without taking the
rest pose curve into account. This is very simple and fast, but causes
poor deformations in some cases where the rest curvature is significant,
e.g. mouth corners in the new Rigify face rig.
This patch implements a new mapping mode that addresses this problem.
The general idea is to do an orthogonal projection on the curve. However,
since there is no analytical solution for bezier curves, it uses the
segment approximation:
* First, boundaries between segments are used for a binary space
partitioning search to narrow down the mapping to one segment.
* Then, a position on the segment is chosen via linear
interpolation between the BSP planes.
* Finally, to remove the sharp discontinuity at the evolute surface
a smoothing pass is applied to the chosen position by blending to
reduce the slope around the planes previously used in the BSP search.
In order to make per-vertex processing faster, a new array with the
necessary vectors converted to the pose space, as well as some
precomputed coefficients, is built.
The new mode is implemented as a per-bone option in order to ensure
backward compatibility, and also because the new mode may not be
optimal for all cases due to the difference in performance, and
complications like the smoothed but still present mapping
discontinuities around the evolute surface.
Wiki: https://wiki.blender.org/wiki/Source/Animation/B-Bone_Vertex_Mapping
Pull Request: https://projects.blender.org/blender/blender/pulls/110758
Pull Request: https://projects.blender.org/blender/blender/pulls/110758
2023-07-14 16:34:18 +03:00
|
|
|
MEM_SAFE_FREE(runtime->bbone_segment_boundaries);
|
2009-11-21 11:26:09 +00:00
|
|
|
}
|
|
|
|
|
|
2013-12-25 16:43:26 +06:00
|
|
|
void BKE_pose_channel_free(bPoseChannel *pchan)
|
|
|
|
|
{
|
|
|
|
|
BKE_pose_channel_free_ex(pchan, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_pose_channels_free_ex(bPose *pose, bool do_id_user)
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
{
|
2023-08-04 08:51:13 +10:00
|
|
|
if (!BLI_listbase_is_empty(&pose->chanbase)) {
|
|
|
|
|
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
|
2013-12-25 16:43:26 +06:00
|
|
|
BKE_pose_channel_free_ex(pchan, do_id_user);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2008-03-16 03:51:00 +00:00
|
|
|
BLI_freelistN(&pose->chanbase);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2010-03-26 10:33:53 +00:00
|
|
|
|
2012-05-05 16:03:57 +00:00
|
|
|
BKE_pose_channels_hash_free(pose);
|
2019-04-14 21:53:03 +03:00
|
|
|
|
|
|
|
|
MEM_SAFE_FREE(pose->chan_array);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
2013-12-25 16:43:26 +06:00
|
|
|
void BKE_pose_channels_free(bPose *pose)
|
|
|
|
|
{
|
|
|
|
|
BKE_pose_channels_free_ex(pose, true);
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-10 16:45:27 +02:00
|
|
|
void BKE_pose_free_data_ex(bPose *pose, bool do_id_user)
|
|
|
|
|
{
|
|
|
|
|
/* free pose-channels */
|
|
|
|
|
BKE_pose_channels_free_ex(pose, do_id_user);
|
|
|
|
|
|
|
|
|
|
/* free pose-groups */
|
2019-04-22 09:39:35 +10:00
|
|
|
if (pose->agroups.first) {
|
2016-05-10 16:45:27 +02:00
|
|
|
BLI_freelistN(&pose->agroups);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2016-05-10 16:45:27 +02:00
|
|
|
|
|
|
|
|
/* free IK solver state */
|
|
|
|
|
BIK_clear_data(pose);
|
|
|
|
|
|
|
|
|
|
/* free IK solver param */
|
2019-04-22 09:39:35 +10:00
|
|
|
if (pose->ikparam) {
|
2016-05-10 16:45:27 +02:00
|
|
|
MEM_freeN(pose->ikparam);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2016-05-10 16:45:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_pose_free_data(bPose *pose)
|
|
|
|
|
{
|
|
|
|
|
BKE_pose_free_data_ex(pose, true);
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-25 16:43:26 +06:00
|
|
|
void BKE_pose_free_ex(bPose *pose, bool do_id_user)
|
== Bone Groups ==
I'm committing some work-in-progress code for "bone groups" now, as I there have been are some major bugs caused by the timeoffset stuff (some of my test files were not loading, and other files were showing all sorts of weird problems).
Anyway, in this commit, the following things for "bone groups" have been done:
* Bone groups are stored per armature (internally, this is per bPose block)
* Added controls for editing bone-groups per armature - "add", "remove", "rename". These can be found in the "Links and Materials" panel in PoseMode, beside the settings for PoseLib.
* Reorganised buttons for editing selected bones in PoseMode. I've replaced the "dist" and "weight" buttons (they existed in EditMode anyway) with a menu to choose the bone-group and the custom-shape-ob field. In the place of the old custom-shape-ob field, I've restored the "Hide" button. This might break muscle-memory a bit, but there isn't a lot of space to play with there.
Some stuff I'd been originally planning to do before committing:
* When adding keyframes for bones, an action-group with the same name as the bone's group will be added to the action, and the action-channel will be made a member of that.
* New action/bone groups have unique names (renaming/adding new should check if name exists before assigning it)
* There's a setting under Bone-Groups stuff which sets which custom-colour set is used to colour that group's bones. Currently, this is non-functional, as the necessary drawing code for armatures is not in place yet.
2008-01-20 02:55:35 +00:00
|
|
|
{
|
|
|
|
|
if (pose) {
|
2016-05-10 16:45:27 +02:00
|
|
|
BKE_pose_free_data_ex(pose, do_id_user);
|
2009-09-24 21:22:24 +00:00
|
|
|
/* free pose */
|
2008-09-17 01:29:54 +00:00
|
|
|
MEM_freeN(pose);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-25 16:43:26 +06:00
|
|
|
void BKE_pose_free(bPose *pose)
|
|
|
|
|
{
|
|
|
|
|
BKE_pose_free_ex(pose, true);
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-05 16:03:57 +00:00
|
|
|
void BKE_pose_channel_copy_data(bPoseChannel *pchan, const bPoseChannel *pchan_from)
|
2009-11-23 23:03:04 +00:00
|
|
|
{
|
|
|
|
|
/* copy transform locks */
|
|
|
|
|
pchan->protectflag = pchan_from->protectflag;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-11-23 23:03:04 +00:00
|
|
|
/* copy rotation mode */
|
|
|
|
|
pchan->rotmode = pchan_from->rotmode;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-11-23 23:03:04 +00:00
|
|
|
/* copy bone group */
|
2012-05-06 15:15:33 +00:00
|
|
|
pchan->agrp_index = pchan_from->agrp_index;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-10-18 11:16:24 +11:00
|
|
|
/* IK (DOF) settings. */
|
2009-11-23 23:03:04 +00:00
|
|
|
pchan->ikflag = pchan_from->ikflag;
|
2011-10-28 12:40:15 +00:00
|
|
|
copy_v3_v3(pchan->limitmin, pchan_from->limitmin);
|
|
|
|
|
copy_v3_v3(pchan->limitmax, pchan_from->limitmax);
|
|
|
|
|
copy_v3_v3(pchan->stiffness, pchan_from->stiffness);
|
2012-05-06 15:15:33 +00:00
|
|
|
pchan->ikstretch = pchan_from->ikstretch;
|
|
|
|
|
pchan->ikrotweight = pchan_from->ikrotweight;
|
|
|
|
|
pchan->iklinweight = pchan_from->iklinweight;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-05-20 19:08:48 +12:00
|
|
|
/* bbone settings (typically not animated) */
|
|
|
|
|
pchan->bbone_next = pchan_from->bbone_next;
|
|
|
|
|
pchan->bbone_prev = pchan_from->bbone_prev;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-11-23 23:03:04 +00:00
|
|
|
/* constraints */
|
2014-04-11 11:47:07 +10:00
|
|
|
BKE_constraints_copy(&pchan->constraints, &pchan_from->constraints, true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-11-23 23:03:04 +00:00
|
|
|
/* id-properties */
|
2012-03-24 06:18:31 +00:00
|
|
|
if (pchan->prop) {
|
2009-11-23 23:03:04 +00:00
|
|
|
/* unlikely but possible it exists */
|
|
|
|
|
IDP_FreeProperty(pchan->prop);
|
2023-07-17 10:46:26 +02:00
|
|
|
pchan->prop = nullptr;
|
2009-11-23 23:03:04 +00:00
|
|
|
}
|
2012-03-24 06:18:31 +00:00
|
|
|
if (pchan_from->prop) {
|
2012-05-06 15:15:33 +00:00
|
|
|
pchan->prop = IDP_CopyProperty(pchan_from->prop);
|
2009-11-23 23:03:04 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-11-23 23:03:04 +00:00
|
|
|
/* custom shape */
|
2012-05-06 15:15:33 +00:00
|
|
|
pchan->custom = pchan_from->custom;
|
2013-08-12 13:52:13 +00:00
|
|
|
if (pchan->custom) {
|
|
|
|
|
id_us_plus(&pchan->custom->id);
|
|
|
|
|
}
|
2021-05-11 11:22:41 +02:00
|
|
|
copy_v3_v3(pchan->custom_scale_xyz, pchan_from->custom_scale_xyz);
|
|
|
|
|
copy_v3_v3(pchan->custom_translation, pchan_from->custom_translation);
|
|
|
|
|
copy_v3_v3(pchan->custom_rotation_euler, pchan_from->custom_rotation_euler);
|
2024-06-11 12:37:57 +02:00
|
|
|
pchan->custom_shape_wire_width = pchan_from->custom_shape_wire_width;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-10-16 09:26:48 +02:00
|
|
|
pchan->color.palette_index = pchan_from->color.palette_index;
|
|
|
|
|
copy_v4_v4_uchar(pchan->color.custom.active, pchan_from->color.custom.active);
|
|
|
|
|
copy_v4_v4_uchar(pchan->color.custom.select, pchan_from->color.custom.select);
|
|
|
|
|
copy_v4_v4_uchar(pchan->color.custom.solid, pchan_from->color.custom.solid);
|
|
|
|
|
pchan->color.custom.flag = pchan_from->color.custom.flag;
|
|
|
|
|
|
2019-05-14 22:35:07 +02:00
|
|
|
pchan->drawflag = pchan_from->drawflag;
|
2009-11-23 23:03:04 +00:00
|
|
|
}
|
|
|
|
|
|
2012-05-05 16:03:57 +00:00
|
|
|
void BKE_pose_update_constraint_flags(bPose *pose)
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
{
|
2023-09-25 11:23:46 +02:00
|
|
|
pose->flag &= ~POSE_CONSTRAINTS_TIMEDEPEND;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-08-04 08:51:13 +10:00
|
|
|
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
|
2012-05-06 15:15:33 +00:00
|
|
|
pchan->constflag = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-08-04 08:51:13 +10:00
|
|
|
LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) {
|
2023-09-25 11:29:57 +02:00
|
|
|
pchan->constflag |= PCHAN_HAS_CONST;
|
|
|
|
|
|
2023-09-25 11:23:46 +02:00
|
|
|
switch (con->type) {
|
|
|
|
|
case CONSTRAINT_TYPE_KINEMATIC: {
|
|
|
|
|
bKinematicConstraint *data = (bKinematicConstraint *)con->data;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-09-25 11:23:46 +02:00
|
|
|
pchan->constflag |= PCHAN_HAS_IK;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-09-25 11:23:46 +02:00
|
|
|
if (data->tar == nullptr || (data->tar->type == OB_ARMATURE && data->subtarget[0] == 0))
|
|
|
|
|
{
|
2023-09-25 12:03:30 +02:00
|
|
|
pchan->constflag |= PCHAN_HAS_NO_TARGET;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Anim: enable visual keying of IK-influenced bones
Enable visual keying of bones that are influenced by an IK constraint.
This wasn't possible before, as the visual keying system only checked
constraints on the bone itself, and not whether the bone was part of an
IK chain.
This commit introduces a new `bPoseChannel::constflag` value
`PCHAN_INFLUENCED_BY_IK` that is set whenever the pose bone is part of
an IK chain.
The `pchan->constflag` field is computed during depsgraph evaluation. If
the depsgraph is active, it is now also written back to the original
pchan, so that it can be used in the "should visual keying be used"
function.
Fixes: #76791 "Different results when keyframing visual transforms and
applying transforms manually on IK constraint". Note that visually
keying does *not* copy the visual pose to the current pose. Furthermore,
when visually keying only part of the IK chain, the result of
re-evaluating the IK constraint (for example by moving the scene forward
and then backward by one frame) may still produce a different result, as
the IK chain now has a different start orientation.
Note that commit explicitly does not cover Spline IK constraints. They
can introduce heavy shear, especially with the default settings, which
cannot be represented by keys on loc/rot/scale.
For historical reference: 876cfc837e2f065fa370940ca578983d84c48a11
introduces the 'use visual keying' preference option, where Blender
automatically chooses whether or not to use visual keying. This is why
there is a function at all that determines whether to use visual keying
or not.
2023-09-25 14:37:22 +02:00
|
|
|
bPoseChannel *chain_tip = (data->flag & CONSTRAINT_IK_TIP) ? pchan : pchan->parent;
|
|
|
|
|
|
2023-09-25 11:23:46 +02:00
|
|
|
/* negative rootbone = recalc rootbone index. used in do_versions */
|
|
|
|
|
if (data->rootbone < 0) {
|
|
|
|
|
data->rootbone = 0;
|
|
|
|
|
|
|
|
|
|
bPoseChannel *parchan = chain_tip;
|
|
|
|
|
while (parchan) {
|
|
|
|
|
data->rootbone++;
|
|
|
|
|
if ((parchan->bone->flag & BONE_CONNECTED) == 0) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
parchan = parchan->parent;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
Integration of new IK lib features in Armature Poses.
Best is to forget yesterday's commit and old docs. New docs are underway...
Here's how IK works now;
- IK chains can go all the way to the furthest parent Bone. Disregarding
the old option "IK to Parent" and disgregarding whether a Bone has an
offset to its parent (offsets now work for IK, so you can also make
T-bones).
- The old "IK to Parent" option now only does what it should do: it denotes
whether a Bone is directly connected to a Parent Bone, or not.
In the UI and in code this option is now called "Connected".
- You can also define yourself which Bone will become the "Root" for an IK
chain. This can be any Parent of the IK tip (where the IK constraint is).
By default it goes all the way, unless you set a value for the new IK
Constraint Panel option "Chain Lenght".
- "Tree IK" now is detected automatic, when multiple IK Roots are on the
same Bone, and when there's a branched structure.
Multiple IK's on a single chain (no branches) is still executed as usual,
doing the IK's sequentially.
- Note: Branched structures, with _partial_ overlapping IK chains, that don't
share the same Root will possibly disconnect branches.
- When you select a Bone with IK, it now draws a yellow dashed line to its
Root.
- The IK options "Location Weight" and "Rotation Weight" are relative,
in case there's a Tree IK structure. These weights cannot be set to
zero. To animate or disable IK Targets, use the "Influence" slider.
- This new IK is backwards and upwards compatible for Blender files.
Of course, the new features won't show in older Blender binaries! :)
Other changes & notes;
- In PoseMode, the Constraint Panel now also draws in Editing Buttons, next
to the Bones Panel.
- IK Constraint Panel was redesigned... it's still a bit squished
- Buttons "No X DoF" is now called "Lock X". This to follow convention to
name options positive.
- Added Undo push for Make/Clear Parent in Editmode Armature
- Use CTRL+P "Make Parent" on a single selected Bone to make it become
connected (ALT+P had already "Disconnect").
On todo next; Visualizing & review of Bone DoF limits and stiffness
2005-08-28 12:23:06 +00:00
|
|
|
}
|
Anim: enable visual keying of IK-influenced bones
Enable visual keying of bones that are influenced by an IK constraint.
This wasn't possible before, as the visual keying system only checked
constraints on the bone itself, and not whether the bone was part of an
IK chain.
This commit introduces a new `bPoseChannel::constflag` value
`PCHAN_INFLUENCED_BY_IK` that is set whenever the pose bone is part of
an IK chain.
The `pchan->constflag` field is computed during depsgraph evaluation. If
the depsgraph is active, it is now also written back to the original
pchan, so that it can be used in the "should visual keying be used"
function.
Fixes: #76791 "Different results when keyframing visual transforms and
applying transforms manually on IK constraint". Note that visually
keying does *not* copy the visual pose to the current pose. Furthermore,
when visually keying only part of the IK chain, the result of
re-evaluating the IK constraint (for example by moving the scene forward
and then backward by one frame) may still produce a different result, as
the IK chain now has a different start orientation.
Note that commit explicitly does not cover Spline IK constraints. They
can introduce heavy shear, especially with the default settings, which
cannot be represented by keys on loc/rot/scale.
For historical reference: 876cfc837e2f065fa370940ca578983d84c48a11
introduces the 'use visual keying' preference option, where Blender
automatically chooses whether or not to use visual keying. This is why
there is a function at all that determines whether to use visual keying
or not.
2023-09-25 14:37:22 +02:00
|
|
|
|
|
|
|
|
/* Mark the pose bones in the IK chain as influenced by it. */
|
|
|
|
|
{
|
|
|
|
|
bPoseChannel *chain_bone = chain_tip;
|
|
|
|
|
for (short index = 0; chain_bone && (data->rootbone == 0 || index < data->rootbone);
|
2024-01-02 18:12:54 +01:00
|
|
|
index++)
|
|
|
|
|
{
|
Anim: enable visual keying of IK-influenced bones
Enable visual keying of bones that are influenced by an IK constraint.
This wasn't possible before, as the visual keying system only checked
constraints on the bone itself, and not whether the bone was part of an
IK chain.
This commit introduces a new `bPoseChannel::constflag` value
`PCHAN_INFLUENCED_BY_IK` that is set whenever the pose bone is part of
an IK chain.
The `pchan->constflag` field is computed during depsgraph evaluation. If
the depsgraph is active, it is now also written back to the original
pchan, so that it can be used in the "should visual keying be used"
function.
Fixes: #76791 "Different results when keyframing visual transforms and
applying transforms manually on IK constraint". Note that visually
keying does *not* copy the visual pose to the current pose. Furthermore,
when visually keying only part of the IK chain, the result of
re-evaluating the IK constraint (for example by moving the scene forward
and then backward by one frame) may still produce a different result, as
the IK chain now has a different start orientation.
Note that commit explicitly does not cover Spline IK constraints. They
can introduce heavy shear, especially with the default settings, which
cannot be represented by keys on loc/rot/scale.
For historical reference: 876cfc837e2f065fa370940ca578983d84c48a11
introduces the 'use visual keying' preference option, where Blender
automatically chooses whether or not to use visual keying. This is why
there is a function at all that determines whether to use visual keying
or not.
2023-09-25 14:37:22 +02:00
|
|
|
chain_bone->constflag |= PCHAN_INFLUENCED_BY_IK;
|
|
|
|
|
chain_bone = chain_bone->parent;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-09-25 11:23:46 +02:00
|
|
|
break;
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-09-25 11:23:46 +02:00
|
|
|
case CONSTRAINT_TYPE_FOLLOWPATH: {
|
|
|
|
|
bFollowPathConstraint *data = (bFollowPathConstraint *)con->data;
|
|
|
|
|
|
|
|
|
|
/* if we have a valid target, make sure that this will get updated on frame-change
|
|
|
|
|
* (needed for when there is no anim-data for this pose)
|
|
|
|
|
*/
|
|
|
|
|
if ((data->tar) && (data->tar->type == OB_CURVES_LEGACY)) {
|
|
|
|
|
pose->flag |= POSE_CONSTRAINTS_TIMEDEPEND;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2023-09-25 11:23:46 +02:00
|
|
|
|
|
|
|
|
case CONSTRAINT_TYPE_SPLINEIK:
|
|
|
|
|
pchan->constflag |= PCHAN_HAS_SPLINEIK;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
}
|
2023-09-25 11:23:46 +02:00
|
|
|
|
2015-03-19 18:28:49 +05:00
|
|
|
pose->flag &= ~POSE_CONSTRAINTS_NEED_UPDATE_FLAGS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_pose_tag_update_constraint_flags(bPose *pose)
|
|
|
|
|
{
|
|
|
|
|
pose->flag |= POSE_CONSTRAINTS_NEED_UPDATE_FLAGS;
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2009-07-21 10:18:08 +00:00
|
|
|
/* ************************** Bone Groups ************************** */
|
|
|
|
|
|
2014-07-09 10:27:31 +02:00
|
|
|
bActionGroup *BKE_pose_add_group(bPose *pose, const char *name)
|
2009-07-21 10:18:08 +00:00
|
|
|
{
|
|
|
|
|
bActionGroup *grp;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2014-07-09 10:27:31 +02:00
|
|
|
if (!name) {
|
|
|
|
|
name = DATA_("Group");
|
|
|
|
|
}
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2023-07-17 10:46:26 +02:00
|
|
|
grp = static_cast<bActionGroup *>(MEM_callocN(sizeof(bActionGroup), "PoseGroup"));
|
2023-05-09 12:50:37 +10:00
|
|
|
STRNCPY(grp->name, name);
|
2009-07-21 10:18:08 +00:00
|
|
|
BLI_addtail(&pose->agroups, grp);
|
2014-07-09 10:27:31 +02:00
|
|
|
BLI_uniquename(&pose->agroups, grp, name, '.', offsetof(bActionGroup, name), sizeof(grp->name));
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2014-11-16 13:57:58 +01:00
|
|
|
pose->active_group = BLI_listbase_count(&pose->agroups);
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2014-07-09 10:27:31 +02:00
|
|
|
return grp;
|
2009-07-21 10:18:08 +00:00
|
|
|
}
|
|
|
|
|
|
2014-07-09 10:27:31 +02:00
|
|
|
void BKE_pose_remove_group(bPose *pose, bActionGroup *grp, const int index)
|
2009-07-21 10:18:08 +00:00
|
|
|
{
|
2014-07-09 10:27:31 +02:00
|
|
|
int idx = index;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-07-09 10:27:31 +02:00
|
|
|
if (idx < 1) {
|
|
|
|
|
idx = BLI_findindex(&pose->agroups, grp) + 1;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-07-09 10:27:31 +02:00
|
|
|
BLI_assert(idx > 0);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-07-09 10:27:31 +02:00
|
|
|
/* adjust group references (the trouble of using indices!):
|
2018-11-14 12:53:15 +11:00
|
|
|
* - firstly, make sure nothing references it
|
|
|
|
|
* - also, make sure that those after this item get corrected
|
2014-07-09 10:27:31 +02:00
|
|
|
*/
|
2023-08-04 08:51:13 +10:00
|
|
|
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
|
2019-04-22 09:39:35 +10:00
|
|
|
if (pchan->agrp_index == idx) {
|
2014-07-09 10:27:31 +02:00
|
|
|
pchan->agrp_index = 0;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
else if (pchan->agrp_index > idx) {
|
2014-07-09 10:27:31 +02:00
|
|
|
pchan->agrp_index--;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2014-07-09 10:27:31 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-07-09 10:27:31 +02:00
|
|
|
/* now, remove it from the pose */
|
|
|
|
|
BLI_freelinkN(&pose->agroups, grp);
|
|
|
|
|
if (pose->active_group >= idx) {
|
2015-01-23 16:59:16 +05:00
|
|
|
const bool has_groups = !BLI_listbase_is_empty(&pose->agroups);
|
2011-05-18 08:16:33 +00:00
|
|
|
pose->active_group--;
|
2015-01-23 16:59:16 +05:00
|
|
|
if (pose->active_group == 0 && has_groups) {
|
|
|
|
|
pose->active_group = 1;
|
|
|
|
|
}
|
|
|
|
|
else if (pose->active_group < 0 || !has_groups) {
|
2012-05-06 15:15:33 +00:00
|
|
|
pose->active_group = 0;
|
2011-05-18 08:16:33 +00:00
|
|
|
}
|
2009-07-21 10:18:08 +00:00
|
|
|
}
|
|
|
|
|
}
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
|
2014-07-09 10:27:31 +02:00
|
|
|
void BKE_pose_remove_group_index(bPose *pose, const int index)
|
|
|
|
|
{
|
2023-07-17 10:46:26 +02:00
|
|
|
bActionGroup *grp = nullptr;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2014-07-09 10:27:31 +02:00
|
|
|
/* get group to remove */
|
2023-07-17 10:46:26 +02:00
|
|
|
grp = static_cast<bActionGroup *>(BLI_findlink(&pose->agroups, index - 1));
|
2014-07-09 10:27:31 +02:00
|
|
|
if (grp) {
|
|
|
|
|
BKE_pose_remove_group(pose, grp, index);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-09-17 10:14:56 +00:00
|
|
|
/* ************** Pose Management Tools ****************** */
|
|
|
|
|
|
2020-07-21 09:51:27 -04:00
|
|
|
void BKE_pose_rest(bPose *pose, bool selected_bones_only)
|
2.5: Blender "Animato" - New Animation System
Finally, here is the basic (functional) prototype of the new animation system which will allow for the infamous "everything is animatable", and which also addresses several of the more serious shortcomings of the old system. Unfortunately, this will break old animation files (especially right now, as I haven't written the version patching code yet), however, this is for the future.
Highlights of the new system:
* Scrapped IPO-Curves/IPO/(Action+Constraint-Channels)/Action system, and replaced it with F-Curve/Action.
- F-Curves (animators from other packages will feel at home with this name) replace IPO-Curves.
- The 'new' Actions, act as the containers for F-Curves, so that they can be reused. They are therefore more akin to the old 'IPO' blocks, except they do not have the blocktype restriction, so you can store materials/texture/geometry F-Curves in the same Action as Object transforms, etc.
* F-Curves use RNA-paths for Data Access, hence allowing "every" (where sensible/editable that is) user-accessible setting from RNA to be animated.
* Drivers are no longer mixed with Animation Data, so rigs will not be that easily broken and several dependency problems can be eliminated. (NOTE: drivers haven't been hooked up yet, but the code is in place)
* F-Curve modifier system allows useful 'large-scale' manipulation of F-Curve values, including (I've only included implemented ones here): envelope deform (similar to lattices to allow broad-scale reshaping of curves), curve generator (polynomial or py-expression), cycles (replacing the old cyclic extrapolation modes, giving more control over this). (NOTE: currently this cannot be tested, as there's not access to them, but the code is all in place)
* NLA system with 'tracks' (i.e. layers), and multiple strips per track. (NOTE: NLA system is not yet functional, as it's only partially coded still)
There are more nice things that I will be preparing some nice docs for soon, but for now, check for more details:
http://lists.blender.org/pipermail/bf-taskforce25/2009-January/000260.html
So, what currently works:
* I've implemented two basic operators for the 3D-view only to Insert and Delete Keyframes. These are tempolary ones only that will be replaced in due course with 'proper' code.
* Object Loc/Rot/Scale can be keyframed. Also, the colour of the 'active' material (Note: this should really be for nth material instead, but that doesn't work yet in RNA) can also be keyframed into the same datablock.
* Standard animation refresh (i.e. animation resulting from NLA and Action evaluation) is now done completely separate from drivers before anything else is done after a frame change. Drivers are handled after this in a separate pass, as dictated by depsgraph flags, etc.
Notes:
* Drivers haven't been hooked up yet
* Only objects and data directly linked to objects can be animated.
* Depsgraph will need further tweaks. Currently, I've only made sure that it will update some things in the most basic cases (i.e. frame change).
* Animation Editors are currently broken (in terms of editing stuff). This will be my next target (priority to get Dopesheet working first, then F-Curve editor - i.e. old IPO Editor)
* I've had to put in large chunks of XXX sandboxing for old animation system code all around the place. This will be cleaned up in due course, as some places need special review.
In particular, the particles and sequencer code have far too many manual calls to calculate + flush animation info, which is really bad (this is a 'please explain yourselves' call to Physics coders!).
2009-01-17 03:12:50 +00:00
|
|
|
{
|
2019-04-22 09:39:35 +10:00
|
|
|
if (!pose) {
|
2.5: Blender "Animato" - New Animation System
Finally, here is the basic (functional) prototype of the new animation system which will allow for the infamous "everything is animatable", and which also addresses several of the more serious shortcomings of the old system. Unfortunately, this will break old animation files (especially right now, as I haven't written the version patching code yet), however, this is for the future.
Highlights of the new system:
* Scrapped IPO-Curves/IPO/(Action+Constraint-Channels)/Action system, and replaced it with F-Curve/Action.
- F-Curves (animators from other packages will feel at home with this name) replace IPO-Curves.
- The 'new' Actions, act as the containers for F-Curves, so that they can be reused. They are therefore more akin to the old 'IPO' blocks, except they do not have the blocktype restriction, so you can store materials/texture/geometry F-Curves in the same Action as Object transforms, etc.
* F-Curves use RNA-paths for Data Access, hence allowing "every" (where sensible/editable that is) user-accessible setting from RNA to be animated.
* Drivers are no longer mixed with Animation Data, so rigs will not be that easily broken and several dependency problems can be eliminated. (NOTE: drivers haven't been hooked up yet, but the code is in place)
* F-Curve modifier system allows useful 'large-scale' manipulation of F-Curve values, including (I've only included implemented ones here): envelope deform (similar to lattices to allow broad-scale reshaping of curves), curve generator (polynomial or py-expression), cycles (replacing the old cyclic extrapolation modes, giving more control over this). (NOTE: currently this cannot be tested, as there's not access to them, but the code is all in place)
* NLA system with 'tracks' (i.e. layers), and multiple strips per track. (NOTE: NLA system is not yet functional, as it's only partially coded still)
There are more nice things that I will be preparing some nice docs for soon, but for now, check for more details:
http://lists.blender.org/pipermail/bf-taskforce25/2009-January/000260.html
So, what currently works:
* I've implemented two basic operators for the 3D-view only to Insert and Delete Keyframes. These are tempolary ones only that will be replaced in due course with 'proper' code.
* Object Loc/Rot/Scale can be keyframed. Also, the colour of the 'active' material (Note: this should really be for nth material instead, but that doesn't work yet in RNA) can also be keyframed into the same datablock.
* Standard animation refresh (i.e. animation resulting from NLA and Action evaluation) is now done completely separate from drivers before anything else is done after a frame change. Drivers are handled after this in a separate pass, as dictated by depsgraph flags, etc.
Notes:
* Drivers haven't been hooked up yet
* Only objects and data directly linked to objects can be animated.
* Depsgraph will need further tweaks. Currently, I've only made sure that it will update some things in the most basic cases (i.e. frame change).
* Animation Editors are currently broken (in terms of editing stuff). This will be my next target (priority to get Dopesheet working first, then F-Curve editor - i.e. old IPO Editor)
* I've had to put in large chunks of XXX sandboxing for old animation system code all around the place. This will be cleaned up in due course, as some places need special review.
In particular, the particles and sequencer code have far too many manual calls to calculate + flush animation info, which is really bad (this is a 'please explain yourselves' call to Physics coders!).
2009-01-17 03:12:50 +00:00
|
|
|
return;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2.5: Blender "Animato" - New Animation System
Finally, here is the basic (functional) prototype of the new animation system which will allow for the infamous "everything is animatable", and which also addresses several of the more serious shortcomings of the old system. Unfortunately, this will break old animation files (especially right now, as I haven't written the version patching code yet), however, this is for the future.
Highlights of the new system:
* Scrapped IPO-Curves/IPO/(Action+Constraint-Channels)/Action system, and replaced it with F-Curve/Action.
- F-Curves (animators from other packages will feel at home with this name) replace IPO-Curves.
- The 'new' Actions, act as the containers for F-Curves, so that they can be reused. They are therefore more akin to the old 'IPO' blocks, except they do not have the blocktype restriction, so you can store materials/texture/geometry F-Curves in the same Action as Object transforms, etc.
* F-Curves use RNA-paths for Data Access, hence allowing "every" (where sensible/editable that is) user-accessible setting from RNA to be animated.
* Drivers are no longer mixed with Animation Data, so rigs will not be that easily broken and several dependency problems can be eliminated. (NOTE: drivers haven't been hooked up yet, but the code is in place)
* F-Curve modifier system allows useful 'large-scale' manipulation of F-Curve values, including (I've only included implemented ones here): envelope deform (similar to lattices to allow broad-scale reshaping of curves), curve generator (polynomial or py-expression), cycles (replacing the old cyclic extrapolation modes, giving more control over this). (NOTE: currently this cannot be tested, as there's not access to them, but the code is all in place)
* NLA system with 'tracks' (i.e. layers), and multiple strips per track. (NOTE: NLA system is not yet functional, as it's only partially coded still)
There are more nice things that I will be preparing some nice docs for soon, but for now, check for more details:
http://lists.blender.org/pipermail/bf-taskforce25/2009-January/000260.html
So, what currently works:
* I've implemented two basic operators for the 3D-view only to Insert and Delete Keyframes. These are tempolary ones only that will be replaced in due course with 'proper' code.
* Object Loc/Rot/Scale can be keyframed. Also, the colour of the 'active' material (Note: this should really be for nth material instead, but that doesn't work yet in RNA) can also be keyframed into the same datablock.
* Standard animation refresh (i.e. animation resulting from NLA and Action evaluation) is now done completely separate from drivers before anything else is done after a frame change. Drivers are handled after this in a separate pass, as dictated by depsgraph flags, etc.
Notes:
* Drivers haven't been hooked up yet
* Only objects and data directly linked to objects can be animated.
* Depsgraph will need further tweaks. Currently, I've only made sure that it will update some things in the most basic cases (i.e. frame change).
* Animation Editors are currently broken (in terms of editing stuff). This will be my next target (priority to get Dopesheet working first, then F-Curve editor - i.e. old IPO Editor)
* I've had to put in large chunks of XXX sandboxing for old animation system code all around the place. This will be cleaned up in due course, as some places need special review.
In particular, the particles and sequencer code have far too many manual calls to calculate + flush animation info, which is really bad (this is a 'please explain yourselves' call to Physics coders!).
2009-01-17 03:12:50 +00:00
|
|
|
memset(pose->stride_offset, 0, sizeof(pose->stride_offset));
|
|
|
|
|
memset(pose->cyclic_offset, 0, sizeof(pose->cyclic_offset));
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2023-08-04 08:51:13 +10:00
|
|
|
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
|
2023-07-17 10:46:26 +02:00
|
|
|
if (selected_bones_only && pchan->bone != nullptr && (pchan->bone->flag & BONE_SELECTED) == 0)
|
|
|
|
|
{
|
2020-07-21 09:51:27 -04:00
|
|
|
continue;
|
|
|
|
|
}
|
2011-02-02 00:40:55 +00:00
|
|
|
zero_v3(pchan->loc);
|
|
|
|
|
zero_v3(pchan->eul);
|
|
|
|
|
unit_qt(pchan->quat);
|
|
|
|
|
unit_axis_angle(pchan->rotAxis, &pchan->rotAngle);
|
2012-05-06 15:15:33 +00:00
|
|
|
pchan->size[0] = pchan->size[1] = pchan->size[2] = 1.0f;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2016-05-20 19:08:48 +12:00
|
|
|
pchan->roll1 = pchan->roll2 = 0.0f;
|
Armature: add B-Bone Y scale channel and extra flag fields to DNA.
In addition to the base bone transformation itself, B-Bones have
controls that affect transformation of its segments. For rotation
the features are quite complete, allowing to both reorient the
Bezier handles via properties, and to control them using custom
handle bones. However for scaling there are two deficiencies.
First, there are only X and Y scale factors (actually X and Z),
while lengthwise all segments have the same scaling. The ease
option merely affects the shape of the curve, and does not cause
actual scaling.
Second, scaling can only be controlled via properties, thus
requiring up to 6 drivers per joint between B-Bones to transfer
scaling factors from the handle bone. This is very inefficient.
Finally, the Z channels are confusingly called Y.
This commit adds a B-Bone Y Scale channel and extra B-Bone flag
fields to DNA with appropriate versioning (including for F-Curves
and drivers) in preparation to addressing these limitations.
Functionality is not changed, so the new fields are not used
until the following commits.
Differential Revision: https://developer.blender.org/D9870
2020-12-11 19:17:39 +03:00
|
|
|
pchan->curve_in_x = pchan->curve_in_z = 0.0f;
|
|
|
|
|
pchan->curve_out_x = pchan->curve_out_z = 0.0f;
|
2017-11-01 13:38:51 +13:00
|
|
|
pchan->ease1 = pchan->ease2 = 0.0f;
|
Armature: add B-Bone Y scale channel and extra flag fields to DNA.
In addition to the base bone transformation itself, B-Bones have
controls that affect transformation of its segments. For rotation
the features are quite complete, allowing to both reorient the
Bezier handles via properties, and to control them using custom
handle bones. However for scaling there are two deficiencies.
First, there are only X and Y scale factors (actually X and Z),
while lengthwise all segments have the same scaling. The ease
option merely affects the shape of the curve, and does not cause
actual scaling.
Second, scaling can only be controlled via properties, thus
requiring up to 6 drivers per joint between B-Bones to transfer
scaling factors from the handle bone. This is very inefficient.
Finally, the Z channels are confusingly called Y.
This commit adds a B-Bone Y Scale channel and extra B-Bone flag
fields to DNA with appropriate versioning (including for F-Curves
and drivers) in preparation to addressing these limitations.
Functionality is not changed, so the new fields are not used
until the following commits.
Differential Revision: https://developer.blender.org/D9870
2020-12-11 19:17:39 +03:00
|
|
|
|
|
|
|
|
copy_v3_fl(pchan->scale_in, 1.0f);
|
|
|
|
|
copy_v3_fl(pchan->scale_out, 1.0f);
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2016-05-20 19:08:48 +12:00
|
|
|
pchan->flag &= ~(POSE_LOC | POSE_ROT | POSE_SIZE | POSE_BBONE_SHAPE);
|
2.5: Blender "Animato" - New Animation System
Finally, here is the basic (functional) prototype of the new animation system which will allow for the infamous "everything is animatable", and which also addresses several of the more serious shortcomings of the old system. Unfortunately, this will break old animation files (especially right now, as I haven't written the version patching code yet), however, this is for the future.
Highlights of the new system:
* Scrapped IPO-Curves/IPO/(Action+Constraint-Channels)/Action system, and replaced it with F-Curve/Action.
- F-Curves (animators from other packages will feel at home with this name) replace IPO-Curves.
- The 'new' Actions, act as the containers for F-Curves, so that they can be reused. They are therefore more akin to the old 'IPO' blocks, except they do not have the blocktype restriction, so you can store materials/texture/geometry F-Curves in the same Action as Object transforms, etc.
* F-Curves use RNA-paths for Data Access, hence allowing "every" (where sensible/editable that is) user-accessible setting from RNA to be animated.
* Drivers are no longer mixed with Animation Data, so rigs will not be that easily broken and several dependency problems can be eliminated. (NOTE: drivers haven't been hooked up yet, but the code is in place)
* F-Curve modifier system allows useful 'large-scale' manipulation of F-Curve values, including (I've only included implemented ones here): envelope deform (similar to lattices to allow broad-scale reshaping of curves), curve generator (polynomial or py-expression), cycles (replacing the old cyclic extrapolation modes, giving more control over this). (NOTE: currently this cannot be tested, as there's not access to them, but the code is all in place)
* NLA system with 'tracks' (i.e. layers), and multiple strips per track. (NOTE: NLA system is not yet functional, as it's only partially coded still)
There are more nice things that I will be preparing some nice docs for soon, but for now, check for more details:
http://lists.blender.org/pipermail/bf-taskforce25/2009-January/000260.html
So, what currently works:
* I've implemented two basic operators for the 3D-view only to Insert and Delete Keyframes. These are tempolary ones only that will be replaced in due course with 'proper' code.
* Object Loc/Rot/Scale can be keyframed. Also, the colour of the 'active' material (Note: this should really be for nth material instead, but that doesn't work yet in RNA) can also be keyframed into the same datablock.
* Standard animation refresh (i.e. animation resulting from NLA and Action evaluation) is now done completely separate from drivers before anything else is done after a frame change. Drivers are handled after this in a separate pass, as dictated by depsgraph flags, etc.
Notes:
* Drivers haven't been hooked up yet
* Only objects and data directly linked to objects can be animated.
* Depsgraph will need further tweaks. Currently, I've only made sure that it will update some things in the most basic cases (i.e. frame change).
* Animation Editors are currently broken (in terms of editing stuff). This will be my next target (priority to get Dopesheet working first, then F-Curve editor - i.e. old IPO Editor)
* I've had to put in large chunks of XXX sandboxing for old animation system code all around the place. This will be cleaned up in due course, as some places need special review.
In particular, the particles and sequencer code have far too many manual calls to calculate + flush animation info, which is really bad (this is a 'please explain yourselves' call to Physics coders!).
2009-01-17 03:12:50 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-14 10:45:35 +02:00
|
|
|
void BKE_pose_copy_pchan_result(bPoseChannel *pchanto, const bPoseChannel *pchanfrom)
|
2018-07-31 13:23:01 +02:00
|
|
|
{
|
|
|
|
|
copy_m4_m4(pchanto->pose_mat, pchanfrom->pose_mat);
|
|
|
|
|
copy_m4_m4(pchanto->chan_mat, pchanfrom->chan_mat);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-31 13:23:01 +02:00
|
|
|
/* used for local constraints */
|
|
|
|
|
copy_v3_v3(pchanto->loc, pchanfrom->loc);
|
|
|
|
|
copy_qt_qt(pchanto->quat, pchanfrom->quat);
|
|
|
|
|
copy_v3_v3(pchanto->eul, pchanfrom->eul);
|
|
|
|
|
copy_v3_v3(pchanto->size, pchanfrom->size);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-31 13:23:01 +02:00
|
|
|
copy_v3_v3(pchanto->pose_head, pchanfrom->pose_head);
|
|
|
|
|
copy_v3_v3(pchanto->pose_tail, pchanfrom->pose_tail);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-31 13:23:01 +02:00
|
|
|
pchanto->roll1 = pchanfrom->roll1;
|
|
|
|
|
pchanto->roll2 = pchanfrom->roll2;
|
2019-04-23 13:15:30 +03:00
|
|
|
pchanto->curve_in_x = pchanfrom->curve_in_x;
|
Armature: add B-Bone Y scale channel and extra flag fields to DNA.
In addition to the base bone transformation itself, B-Bones have
controls that affect transformation of its segments. For rotation
the features are quite complete, allowing to both reorient the
Bezier handles via properties, and to control them using custom
handle bones. However for scaling there are two deficiencies.
First, there are only X and Y scale factors (actually X and Z),
while lengthwise all segments have the same scaling. The ease
option merely affects the shape of the curve, and does not cause
actual scaling.
Second, scaling can only be controlled via properties, thus
requiring up to 6 drivers per joint between B-Bones to transfer
scaling factors from the handle bone. This is very inefficient.
Finally, the Z channels are confusingly called Y.
This commit adds a B-Bone Y Scale channel and extra B-Bone flag
fields to DNA with appropriate versioning (including for F-Curves
and drivers) in preparation to addressing these limitations.
Functionality is not changed, so the new fields are not used
until the following commits.
Differential Revision: https://developer.blender.org/D9870
2020-12-11 19:17:39 +03:00
|
|
|
pchanto->curve_in_z = pchanfrom->curve_in_z;
|
2019-04-23 13:15:30 +03:00
|
|
|
pchanto->curve_out_x = pchanfrom->curve_out_x;
|
Armature: add B-Bone Y scale channel and extra flag fields to DNA.
In addition to the base bone transformation itself, B-Bones have
controls that affect transformation of its segments. For rotation
the features are quite complete, allowing to both reorient the
Bezier handles via properties, and to control them using custom
handle bones. However for scaling there are two deficiencies.
First, there are only X and Y scale factors (actually X and Z),
while lengthwise all segments have the same scaling. The ease
option merely affects the shape of the curve, and does not cause
actual scaling.
Second, scaling can only be controlled via properties, thus
requiring up to 6 drivers per joint between B-Bones to transfer
scaling factors from the handle bone. This is very inefficient.
Finally, the Z channels are confusingly called Y.
This commit adds a B-Bone Y Scale channel and extra B-Bone flag
fields to DNA with appropriate versioning (including for F-Curves
and drivers) in preparation to addressing these limitations.
Functionality is not changed, so the new fields are not used
until the following commits.
Differential Revision: https://developer.blender.org/D9870
2020-12-11 19:17:39 +03:00
|
|
|
pchanto->curve_out_z = pchanfrom->curve_out_z;
|
2018-07-31 13:23:01 +02:00
|
|
|
pchanto->ease1 = pchanfrom->ease1;
|
|
|
|
|
pchanto->ease2 = pchanfrom->ease2;
|
Armature: add B-Bone Y scale channel and extra flag fields to DNA.
In addition to the base bone transformation itself, B-Bones have
controls that affect transformation of its segments. For rotation
the features are quite complete, allowing to both reorient the
Bezier handles via properties, and to control them using custom
handle bones. However for scaling there are two deficiencies.
First, there are only X and Y scale factors (actually X and Z),
while lengthwise all segments have the same scaling. The ease
option merely affects the shape of the curve, and does not cause
actual scaling.
Second, scaling can only be controlled via properties, thus
requiring up to 6 drivers per joint between B-Bones to transfer
scaling factors from the handle bone. This is very inefficient.
Finally, the Z channels are confusingly called Y.
This commit adds a B-Bone Y Scale channel and extra B-Bone flag
fields to DNA with appropriate versioning (including for F-Curves
and drivers) in preparation to addressing these limitations.
Functionality is not changed, so the new fields are not used
until the following commits.
Differential Revision: https://developer.blender.org/D9870
2020-12-11 19:17:39 +03:00
|
|
|
|
|
|
|
|
copy_v3_v3(pchanto->scale_in, pchanfrom->scale_in);
|
|
|
|
|
copy_v3_v3(pchanto->scale_out, pchanfrom->scale_out);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-31 13:23:01 +02:00
|
|
|
pchanto->rotmode = pchanfrom->rotmode;
|
|
|
|
|
pchanto->flag = pchanfrom->flag;
|
|
|
|
|
pchanto->protectflag = pchanfrom->protectflag;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-24 14:48:08 +00:00
|
|
|
bool BKE_pose_copy_result(bPose *to, bPose *from)
|
2.5: Blender "Animato" - New Animation System
Finally, here is the basic (functional) prototype of the new animation system which will allow for the infamous "everything is animatable", and which also addresses several of the more serious shortcomings of the old system. Unfortunately, this will break old animation files (especially right now, as I haven't written the version patching code yet), however, this is for the future.
Highlights of the new system:
* Scrapped IPO-Curves/IPO/(Action+Constraint-Channels)/Action system, and replaced it with F-Curve/Action.
- F-Curves (animators from other packages will feel at home with this name) replace IPO-Curves.
- The 'new' Actions, act as the containers for F-Curves, so that they can be reused. They are therefore more akin to the old 'IPO' blocks, except they do not have the blocktype restriction, so you can store materials/texture/geometry F-Curves in the same Action as Object transforms, etc.
* F-Curves use RNA-paths for Data Access, hence allowing "every" (where sensible/editable that is) user-accessible setting from RNA to be animated.
* Drivers are no longer mixed with Animation Data, so rigs will not be that easily broken and several dependency problems can be eliminated. (NOTE: drivers haven't been hooked up yet, but the code is in place)
* F-Curve modifier system allows useful 'large-scale' manipulation of F-Curve values, including (I've only included implemented ones here): envelope deform (similar to lattices to allow broad-scale reshaping of curves), curve generator (polynomial or py-expression), cycles (replacing the old cyclic extrapolation modes, giving more control over this). (NOTE: currently this cannot be tested, as there's not access to them, but the code is all in place)
* NLA system with 'tracks' (i.e. layers), and multiple strips per track. (NOTE: NLA system is not yet functional, as it's only partially coded still)
There are more nice things that I will be preparing some nice docs for soon, but for now, check for more details:
http://lists.blender.org/pipermail/bf-taskforce25/2009-January/000260.html
So, what currently works:
* I've implemented two basic operators for the 3D-view only to Insert and Delete Keyframes. These are tempolary ones only that will be replaced in due course with 'proper' code.
* Object Loc/Rot/Scale can be keyframed. Also, the colour of the 'active' material (Note: this should really be for nth material instead, but that doesn't work yet in RNA) can also be keyframed into the same datablock.
* Standard animation refresh (i.e. animation resulting from NLA and Action evaluation) is now done completely separate from drivers before anything else is done after a frame change. Drivers are handled after this in a separate pass, as dictated by depsgraph flags, etc.
Notes:
* Drivers haven't been hooked up yet
* Only objects and data directly linked to objects can be animated.
* Depsgraph will need further tweaks. Currently, I've only made sure that it will update some things in the most basic cases (i.e. frame change).
* Animation Editors are currently broken (in terms of editing stuff). This will be my next target (priority to get Dopesheet working first, then F-Curve editor - i.e. old IPO Editor)
* I've had to put in large chunks of XXX sandboxing for old animation system code all around the place. This will be cleaned up in due course, as some places need special review.
In particular, the particles and sequencer code have far too many manual calls to calculate + flush animation info, which is really bad (this is a 'please explain yourselves' call to Physics coders!).
2009-01-17 03:12:50 +00:00
|
|
|
{
|
2023-07-17 10:46:26 +02:00
|
|
|
if (to == nullptr || from == nullptr) {
|
2019-02-01 12:44:19 +11:00
|
|
|
CLOG_ERROR(
|
|
|
|
|
&LOG, "Pose copy error, pose to:%p from:%p", (void *)to, (void *)from); /* debug temp */
|
2013-01-24 14:48:08 +00:00
|
|
|
return false;
|
2.5: Blender "Animato" - New Animation System
Finally, here is the basic (functional) prototype of the new animation system which will allow for the infamous "everything is animatable", and which also addresses several of the more serious shortcomings of the old system. Unfortunately, this will break old animation files (especially right now, as I haven't written the version patching code yet), however, this is for the future.
Highlights of the new system:
* Scrapped IPO-Curves/IPO/(Action+Constraint-Channels)/Action system, and replaced it with F-Curve/Action.
- F-Curves (animators from other packages will feel at home with this name) replace IPO-Curves.
- The 'new' Actions, act as the containers for F-Curves, so that they can be reused. They are therefore more akin to the old 'IPO' blocks, except they do not have the blocktype restriction, so you can store materials/texture/geometry F-Curves in the same Action as Object transforms, etc.
* F-Curves use RNA-paths for Data Access, hence allowing "every" (where sensible/editable that is) user-accessible setting from RNA to be animated.
* Drivers are no longer mixed with Animation Data, so rigs will not be that easily broken and several dependency problems can be eliminated. (NOTE: drivers haven't been hooked up yet, but the code is in place)
* F-Curve modifier system allows useful 'large-scale' manipulation of F-Curve values, including (I've only included implemented ones here): envelope deform (similar to lattices to allow broad-scale reshaping of curves), curve generator (polynomial or py-expression), cycles (replacing the old cyclic extrapolation modes, giving more control over this). (NOTE: currently this cannot be tested, as there's not access to them, but the code is all in place)
* NLA system with 'tracks' (i.e. layers), and multiple strips per track. (NOTE: NLA system is not yet functional, as it's only partially coded still)
There are more nice things that I will be preparing some nice docs for soon, but for now, check for more details:
http://lists.blender.org/pipermail/bf-taskforce25/2009-January/000260.html
So, what currently works:
* I've implemented two basic operators for the 3D-view only to Insert and Delete Keyframes. These are tempolary ones only that will be replaced in due course with 'proper' code.
* Object Loc/Rot/Scale can be keyframed. Also, the colour of the 'active' material (Note: this should really be for nth material instead, but that doesn't work yet in RNA) can also be keyframed into the same datablock.
* Standard animation refresh (i.e. animation resulting from NLA and Action evaluation) is now done completely separate from drivers before anything else is done after a frame change. Drivers are handled after this in a separate pass, as dictated by depsgraph flags, etc.
Notes:
* Drivers haven't been hooked up yet
* Only objects and data directly linked to objects can be animated.
* Depsgraph will need further tweaks. Currently, I've only made sure that it will update some things in the most basic cases (i.e. frame change).
* Animation Editors are currently broken (in terms of editing stuff). This will be my next target (priority to get Dopesheet working first, then F-Curve editor - i.e. old IPO Editor)
* I've had to put in large chunks of XXX sandboxing for old animation system code all around the place. This will be cleaned up in due course, as some places need special review.
In particular, the particles and sequencer code have far too many manual calls to calculate + flush animation info, which is really bad (this is a 'please explain yourselves' call to Physics coders!).
2009-01-17 03:12:50 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
if (to == from) {
|
2019-02-01 12:44:19 +11:00
|
|
|
CLOG_ERROR(&LOG, "source and target are the same");
|
2013-01-24 14:48:08 +00:00
|
|
|
return false;
|
2.5: Blender "Animato" - New Animation System
Finally, here is the basic (functional) prototype of the new animation system which will allow for the infamous "everything is animatable", and which also addresses several of the more serious shortcomings of the old system. Unfortunately, this will break old animation files (especially right now, as I haven't written the version patching code yet), however, this is for the future.
Highlights of the new system:
* Scrapped IPO-Curves/IPO/(Action+Constraint-Channels)/Action system, and replaced it with F-Curve/Action.
- F-Curves (animators from other packages will feel at home with this name) replace IPO-Curves.
- The 'new' Actions, act as the containers for F-Curves, so that they can be reused. They are therefore more akin to the old 'IPO' blocks, except they do not have the blocktype restriction, so you can store materials/texture/geometry F-Curves in the same Action as Object transforms, etc.
* F-Curves use RNA-paths for Data Access, hence allowing "every" (where sensible/editable that is) user-accessible setting from RNA to be animated.
* Drivers are no longer mixed with Animation Data, so rigs will not be that easily broken and several dependency problems can be eliminated. (NOTE: drivers haven't been hooked up yet, but the code is in place)
* F-Curve modifier system allows useful 'large-scale' manipulation of F-Curve values, including (I've only included implemented ones here): envelope deform (similar to lattices to allow broad-scale reshaping of curves), curve generator (polynomial or py-expression), cycles (replacing the old cyclic extrapolation modes, giving more control over this). (NOTE: currently this cannot be tested, as there's not access to them, but the code is all in place)
* NLA system with 'tracks' (i.e. layers), and multiple strips per track. (NOTE: NLA system is not yet functional, as it's only partially coded still)
There are more nice things that I will be preparing some nice docs for soon, but for now, check for more details:
http://lists.blender.org/pipermail/bf-taskforce25/2009-January/000260.html
So, what currently works:
* I've implemented two basic operators for the 3D-view only to Insert and Delete Keyframes. These are tempolary ones only that will be replaced in due course with 'proper' code.
* Object Loc/Rot/Scale can be keyframed. Also, the colour of the 'active' material (Note: this should really be for nth material instead, but that doesn't work yet in RNA) can also be keyframed into the same datablock.
* Standard animation refresh (i.e. animation resulting from NLA and Action evaluation) is now done completely separate from drivers before anything else is done after a frame change. Drivers are handled after this in a separate pass, as dictated by depsgraph flags, etc.
Notes:
* Drivers haven't been hooked up yet
* Only objects and data directly linked to objects can be animated.
* Depsgraph will need further tweaks. Currently, I've only made sure that it will update some things in the most basic cases (i.e. frame change).
* Animation Editors are currently broken (in terms of editing stuff). This will be my next target (priority to get Dopesheet working first, then F-Curve editor - i.e. old IPO Editor)
* I've had to put in large chunks of XXX sandboxing for old animation system code all around the place. This will be cleaned up in due course, as some places need special review.
In particular, the particles and sequencer code have far too many manual calls to calculate + flush animation info, which is really bad (this is a 'please explain yourselves' call to Physics coders!).
2009-01-17 03:12:50 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-08-04 08:51:13 +10:00
|
|
|
LISTBASE_FOREACH (bPoseChannel *, pchanfrom, &from->chanbase) {
|
|
|
|
|
bPoseChannel *pchanto = BKE_pose_channel_find_name(to, pchanfrom->name);
|
2023-07-17 10:46:26 +02:00
|
|
|
if (pchanto != nullptr) {
|
2019-10-14 10:45:35 +02:00
|
|
|
BKE_pose_copy_pchan_result(pchanto, pchanfrom);
|
2.5: Blender "Animato" - New Animation System
Finally, here is the basic (functional) prototype of the new animation system which will allow for the infamous "everything is animatable", and which also addresses several of the more serious shortcomings of the old system. Unfortunately, this will break old animation files (especially right now, as I haven't written the version patching code yet), however, this is for the future.
Highlights of the new system:
* Scrapped IPO-Curves/IPO/(Action+Constraint-Channels)/Action system, and replaced it with F-Curve/Action.
- F-Curves (animators from other packages will feel at home with this name) replace IPO-Curves.
- The 'new' Actions, act as the containers for F-Curves, so that they can be reused. They are therefore more akin to the old 'IPO' blocks, except they do not have the blocktype restriction, so you can store materials/texture/geometry F-Curves in the same Action as Object transforms, etc.
* F-Curves use RNA-paths for Data Access, hence allowing "every" (where sensible/editable that is) user-accessible setting from RNA to be animated.
* Drivers are no longer mixed with Animation Data, so rigs will not be that easily broken and several dependency problems can be eliminated. (NOTE: drivers haven't been hooked up yet, but the code is in place)
* F-Curve modifier system allows useful 'large-scale' manipulation of F-Curve values, including (I've only included implemented ones here): envelope deform (similar to lattices to allow broad-scale reshaping of curves), curve generator (polynomial or py-expression), cycles (replacing the old cyclic extrapolation modes, giving more control over this). (NOTE: currently this cannot be tested, as there's not access to them, but the code is all in place)
* NLA system with 'tracks' (i.e. layers), and multiple strips per track. (NOTE: NLA system is not yet functional, as it's only partially coded still)
There are more nice things that I will be preparing some nice docs for soon, but for now, check for more details:
http://lists.blender.org/pipermail/bf-taskforce25/2009-January/000260.html
So, what currently works:
* I've implemented two basic operators for the 3D-view only to Insert and Delete Keyframes. These are tempolary ones only that will be replaced in due course with 'proper' code.
* Object Loc/Rot/Scale can be keyframed. Also, the colour of the 'active' material (Note: this should really be for nth material instead, but that doesn't work yet in RNA) can also be keyframed into the same datablock.
* Standard animation refresh (i.e. animation resulting from NLA and Action evaluation) is now done completely separate from drivers before anything else is done after a frame change. Drivers are handled after this in a separate pass, as dictated by depsgraph flags, etc.
Notes:
* Drivers haven't been hooked up yet
* Only objects and data directly linked to objects can be animated.
* Depsgraph will need further tweaks. Currently, I've only made sure that it will update some things in the most basic cases (i.e. frame change).
* Animation Editors are currently broken (in terms of editing stuff). This will be my next target (priority to get Dopesheet working first, then F-Curve editor - i.e. old IPO Editor)
* I've had to put in large chunks of XXX sandboxing for old animation system code all around the place. This will be cleaned up in due course, as some places need special review.
In particular, the particles and sequencer code have far too many manual calls to calculate + flush animation info, which is really bad (this is a 'please explain yourselves' call to Physics coders!).
2009-01-17 03:12:50 +00:00
|
|
|
}
|
|
|
|
|
}
|
2013-01-24 14:48:08 +00:00
|
|
|
return true;
|
2.5: Blender "Animato" - New Animation System
Finally, here is the basic (functional) prototype of the new animation system which will allow for the infamous "everything is animatable", and which also addresses several of the more serious shortcomings of the old system. Unfortunately, this will break old animation files (especially right now, as I haven't written the version patching code yet), however, this is for the future.
Highlights of the new system:
* Scrapped IPO-Curves/IPO/(Action+Constraint-Channels)/Action system, and replaced it with F-Curve/Action.
- F-Curves (animators from other packages will feel at home with this name) replace IPO-Curves.
- The 'new' Actions, act as the containers for F-Curves, so that they can be reused. They are therefore more akin to the old 'IPO' blocks, except they do not have the blocktype restriction, so you can store materials/texture/geometry F-Curves in the same Action as Object transforms, etc.
* F-Curves use RNA-paths for Data Access, hence allowing "every" (where sensible/editable that is) user-accessible setting from RNA to be animated.
* Drivers are no longer mixed with Animation Data, so rigs will not be that easily broken and several dependency problems can be eliminated. (NOTE: drivers haven't been hooked up yet, but the code is in place)
* F-Curve modifier system allows useful 'large-scale' manipulation of F-Curve values, including (I've only included implemented ones here): envelope deform (similar to lattices to allow broad-scale reshaping of curves), curve generator (polynomial or py-expression), cycles (replacing the old cyclic extrapolation modes, giving more control over this). (NOTE: currently this cannot be tested, as there's not access to them, but the code is all in place)
* NLA system with 'tracks' (i.e. layers), and multiple strips per track. (NOTE: NLA system is not yet functional, as it's only partially coded still)
There are more nice things that I will be preparing some nice docs for soon, but for now, check for more details:
http://lists.blender.org/pipermail/bf-taskforce25/2009-January/000260.html
So, what currently works:
* I've implemented two basic operators for the 3D-view only to Insert and Delete Keyframes. These are tempolary ones only that will be replaced in due course with 'proper' code.
* Object Loc/Rot/Scale can be keyframed. Also, the colour of the 'active' material (Note: this should really be for nth material instead, but that doesn't work yet in RNA) can also be keyframed into the same datablock.
* Standard animation refresh (i.e. animation resulting from NLA and Action evaluation) is now done completely separate from drivers before anything else is done after a frame change. Drivers are handled after this in a separate pass, as dictated by depsgraph flags, etc.
Notes:
* Drivers haven't been hooked up yet
* Only objects and data directly linked to objects can be animated.
* Depsgraph will need further tweaks. Currently, I've only made sure that it will update some things in the most basic cases (i.e. frame change).
* Animation Editors are currently broken (in terms of editing stuff). This will be my next target (priority to get Dopesheet working first, then F-Curve editor - i.e. old IPO Editor)
* I've had to put in large chunks of XXX sandboxing for old animation system code all around the place. This will be cleaned up in due course, as some places need special review.
In particular, the particles and sequencer code have far too many manual calls to calculate + flush animation info, which is really bad (this is a 'please explain yourselves' call to Physics coders!).
2009-01-17 03:12:50 +00:00
|
|
|
}
|
|
|
|
|
|
Depsgraph: New dependency graph integration commit
This commit integrates the work done so far on the new dependency graph system,
where goal was to replace legacy depsgraph with the new one, supporting loads of
neat features like:
- More granular dependency relation nature, which solves issues with fake cycles
in the dependencies.
- Move towards all-animatable, by better integration of drivers into the system.
- Lay down some basis for upcoming copy-on-write, overrides and so on.
The new system is living side-by-side with the previous one and disabled by
default, so nothing will become suddenly broken. The way to enable new depsgraph
is to pass `--new-depsgraph` command line argument.
It's a bit early to consider the system production-ready, there are some TODOs
and issues were discovered during the merge period, they'll be addressed ASAP.
But it's important to merge, because it's the only way to attract artists to
really start testing this system.
There are number of assorted documents related on the design of the new system:
* http://wiki.blender.org/index.php/User:Aligorith/GSoC2013_Depsgraph#Design_Documents
* http://wiki.blender.org/index.php/User:Nazg-gul/DependencyGraph
There are also some user-related information online:
* http://code.blender.org/2015/02/blender-dependency-graph-branch-for-users/
* http://code.blender.org/2015/03/more-dependency-graph-tricks/
Kudos to everyone who was involved into the project:
- Joshua "Aligorith" Leung -- design specification, initial code
- Lukas "lukas_t" Toenne -- integrating code into blender, with further fixes
- Sergey "Sergey" "Sharybin" -- some mocking around, trying to wrap up the
project and so
- Bassam "slikdigit" Kurdali -- stressing the new system, reporting all the
issues and recording/writing documentation.
- Everyone else who i forgot to mention here :)
2015-05-12 15:05:57 +05:00
|
|
|
void BKE_pose_tag_recalc(Main *bmain, bPose *pose)
|
2015-05-12 13:13:36 +05:00
|
|
|
{
|
|
|
|
|
pose->flag |= POSE_RECALC;
|
Depsgraph: New dependency graph integration commit
This commit integrates the work done so far on the new dependency graph system,
where goal was to replace legacy depsgraph with the new one, supporting loads of
neat features like:
- More granular dependency relation nature, which solves issues with fake cycles
in the dependencies.
- Move towards all-animatable, by better integration of drivers into the system.
- Lay down some basis for upcoming copy-on-write, overrides and so on.
The new system is living side-by-side with the previous one and disabled by
default, so nothing will become suddenly broken. The way to enable new depsgraph
is to pass `--new-depsgraph` command line argument.
It's a bit early to consider the system production-ready, there are some TODOs
and issues were discovered during the merge period, they'll be addressed ASAP.
But it's important to merge, because it's the only way to attract artists to
really start testing this system.
There are number of assorted documents related on the design of the new system:
* http://wiki.blender.org/index.php/User:Aligorith/GSoC2013_Depsgraph#Design_Documents
* http://wiki.blender.org/index.php/User:Nazg-gul/DependencyGraph
There are also some user-related information online:
* http://code.blender.org/2015/02/blender-dependency-graph-branch-for-users/
* http://code.blender.org/2015/03/more-dependency-graph-tricks/
Kudos to everyone who was involved into the project:
- Joshua "Aligorith" Leung -- design specification, initial code
- Lukas "lukas_t" Toenne -- integrating code into blender, with further fixes
- Sergey "Sergey" "Sharybin" -- some mocking around, trying to wrap up the
project and so
- Bassam "slikdigit" Kurdali -- stressing the new system, reporting all the
issues and recording/writing documentation.
- Everyone else who i forgot to mention here :)
2015-05-12 15:05:57 +05:00
|
|
|
/* Depsgraph components depends on actual pose state,
|
|
|
|
|
* if pose was changed depsgraph is to be updated as well.
|
|
|
|
|
*/
|
2017-04-06 16:11:50 +02:00
|
|
|
DEG_relations_tag_update(bmain);
|
2015-05-12 13:13:36 +05:00
|
|
|
}
|
|
|
|
|
|
T77086 Animation: Passing Dependency Graph to Drivers
Custom driver functions need access to the dependency graph that is
triggering the evaluation of the driver. This patch passes the
dependency graph pointer through all the animation-related calls.
Instead of passing the evaluation time to functions, the code now passes
an `AnimationEvalContext` pointer:
```
typedef struct AnimationEvalContext {
struct Depsgraph *const depsgraph;
const float eval_time;
} AnimationEvalContext;
```
These structs are read-only, meaning that the code cannot change the
evaluation time. Note that the `depsgraph` pointer itself is const, but
it points to a non-const depsgraph.
FCurves and Drivers can be evaluated at a different time than the
current scene time, for example when evaluating NLA strips. This means
that, even though the current time is stored in the dependency graph, we
need an explicit evaluation time.
There are two functions that allow creation of `AnimationEvalContext`
objects:
- `BKE_animsys_eval_context_construct(Depsgraph *depsgraph, float
eval_time)`, which creates a new context object from scratch, and
- `BKE_animsys_eval_context_construct_at(AnimationEvalContext
*anim_eval_context, float eval_time)`, which can be used to create a
`AnimationEvalContext` with the same depsgraph, but at a different
time. This makes it possible to later add fields without changing any
of the code that just want to change the eval time.
This also provides a fix for T75553, although it does require a change
to the custom driver function. The driver should call
`custom_function(depsgraph)`, and the function should use that depsgraph
instead of information from `bpy.context`.
Reviewed By: brecht, sergey
Differential Revision: https://developer.blender.org/D8047
2020-07-17 17:38:09 +02:00
|
|
|
void what_does_obaction(Object *ob,
|
|
|
|
|
Object *workob,
|
|
|
|
|
bPose *pose,
|
|
|
|
|
bAction *act,
|
2024-09-13 11:37:44 +02:00
|
|
|
const int32_t action_slot_handle,
|
T77086 Animation: Passing Dependency Graph to Drivers
Custom driver functions need access to the dependency graph that is
triggering the evaluation of the driver. This patch passes the
dependency graph pointer through all the animation-related calls.
Instead of passing the evaluation time to functions, the code now passes
an `AnimationEvalContext` pointer:
```
typedef struct AnimationEvalContext {
struct Depsgraph *const depsgraph;
const float eval_time;
} AnimationEvalContext;
```
These structs are read-only, meaning that the code cannot change the
evaluation time. Note that the `depsgraph` pointer itself is const, but
it points to a non-const depsgraph.
FCurves and Drivers can be evaluated at a different time than the
current scene time, for example when evaluating NLA strips. This means
that, even though the current time is stored in the dependency graph, we
need an explicit evaluation time.
There are two functions that allow creation of `AnimationEvalContext`
objects:
- `BKE_animsys_eval_context_construct(Depsgraph *depsgraph, float
eval_time)`, which creates a new context object from scratch, and
- `BKE_animsys_eval_context_construct_at(AnimationEvalContext
*anim_eval_context, float eval_time)`, which can be used to create a
`AnimationEvalContext` with the same depsgraph, but at a different
time. This makes it possible to later add fields without changing any
of the code that just want to change the eval time.
This also provides a fix for T75553, although it does require a change
to the custom driver function. The driver should call
`custom_function(depsgraph)`, and the function should use that depsgraph
instead of information from `bpy.context`.
Reviewed By: brecht, sergey
Differential Revision: https://developer.blender.org/D8047
2020-07-17 17:38:09 +02:00
|
|
|
char groupname[],
|
|
|
|
|
const AnimationEvalContext *anim_eval_context)
|
2009-01-29 11:22:34 +00:00
|
|
|
{
|
2024-09-13 11:37:44 +02:00
|
|
|
using namespace blender::animrig;
|
|
|
|
|
BLI_assert(act);
|
|
|
|
|
|
|
|
|
|
bActionGroup *agrp = nullptr;
|
2024-09-19 16:24:37 +02:00
|
|
|
if (groupname && groupname[0]) {
|
2024-09-13 11:37:44 +02:00
|
|
|
/* Find the named channel group. */
|
|
|
|
|
Action &action = act->wrap();
|
|
|
|
|
if (action.is_action_layered()) {
|
|
|
|
|
ChannelBag *cbag = channelbag_for_action_slot(action, action_slot_handle);
|
|
|
|
|
agrp = cbag ? cbag->channel_group_find(groupname) : nullptr;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
agrp = BKE_action_group_find_name(act, groupname);
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-04-15 12:59:49 +00:00
|
|
|
/* clear workob */
|
2023-11-16 09:16:48 +01:00
|
|
|
blender::bke::ObjectRuntime workob_runtime;
|
2012-05-05 14:03:12 +00:00
|
|
|
BKE_object_workob_clear(workob);
|
2023-11-16 09:16:48 +01:00
|
|
|
workob->runtime = &workob_runtime;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-01-29 11:22:34 +00:00
|
|
|
/* init workob */
|
2024-02-14 16:14:49 +01:00
|
|
|
copy_m4_m4(workob->runtime->object_to_world.ptr(), ob->object_to_world().ptr());
|
2009-11-10 20:43:45 +00:00
|
|
|
copy_m4_m4(workob->parentinv, ob->parentinv);
|
|
|
|
|
copy_m4_m4(workob->constinv, ob->constinv);
|
2012-05-06 15:15:33 +00:00
|
|
|
workob->parent = ob->parent;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
workob->rotmode = ob->rotmode;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
workob->trackflag = ob->trackflag;
|
|
|
|
|
workob->upflag = ob->upflag;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
workob->partype = ob->partype;
|
|
|
|
|
workob->par1 = ob->par1;
|
|
|
|
|
workob->par2 = ob->par2;
|
|
|
|
|
workob->par3 = ob->par3;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-01-29 11:22:34 +00:00
|
|
|
workob->constraints.first = ob->constraints.first;
|
|
|
|
|
workob->constraints.last = ob->constraints.last;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-07-02 22:17:22 +10:00
|
|
|
/* Need to set pose too, since this is used for both types of Action Constraint. */
|
|
|
|
|
workob->pose = pose;
|
2016-04-26 14:11:03 +02:00
|
|
|
if (pose) {
|
2016-05-10 16:45:27 +02:00
|
|
|
/* This function is most likely to be used with a temporary pose with a single bone in there.
|
|
|
|
|
* For such cases it makes no sense to create hash since it'll only waste CPU ticks on memory
|
|
|
|
|
* allocation and also will make lookup slower.
|
|
|
|
|
*/
|
|
|
|
|
if (pose->chanbase.first != pose->chanbase.last) {
|
2021-04-30 15:28:13 +10:00
|
|
|
BKE_pose_channels_hash_ensure(pose);
|
2016-05-10 16:45:27 +02:00
|
|
|
}
|
2016-04-26 14:11:03 +02:00
|
|
|
if (pose->flag & POSE_CONSTRAINTS_NEED_UPDATE_FLAGS) {
|
|
|
|
|
BKE_pose_update_constraint_flags(pose);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2016-04-26 14:11:03 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-05-09 12:50:37 +10:00
|
|
|
STRNCPY(workob->parsubstr, ob->parsubstr);
|
2019-04-27 12:07:07 +10:00
|
|
|
|
|
|
|
|
/* we don't use real object name, otherwise RNA screws with the real thing */
|
2023-05-09 12:50:37 +10:00
|
|
|
STRNCPY(workob->id.name, "OB<ConstrWorkOb>");
|
2019-04-27 12:07:07 +10:00
|
|
|
|
|
|
|
|
/* If we're given a group to use, it's likely to be more efficient
|
|
|
|
|
* (though a bit more dangerous). */
|
2009-04-15 12:59:49 +00:00
|
|
|
if (agrp) {
|
|
|
|
|
/* specifically evaluate this group only */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-04-15 12:59:49 +00:00
|
|
|
/* get RNA-pointer for the workob's ID */
|
2023-09-06 00:48:50 +02:00
|
|
|
PointerRNA id_ptr = RNA_id_pointer_create(&workob->id);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-04-15 12:59:49 +00:00
|
|
|
/* execute action for this group only */
|
T77086 Animation: Passing Dependency Graph to Drivers
Custom driver functions need access to the dependency graph that is
triggering the evaluation of the driver. This patch passes the
dependency graph pointer through all the animation-related calls.
Instead of passing the evaluation time to functions, the code now passes
an `AnimationEvalContext` pointer:
```
typedef struct AnimationEvalContext {
struct Depsgraph *const depsgraph;
const float eval_time;
} AnimationEvalContext;
```
These structs are read-only, meaning that the code cannot change the
evaluation time. Note that the `depsgraph` pointer itself is const, but
it points to a non-const depsgraph.
FCurves and Drivers can be evaluated at a different time than the
current scene time, for example when evaluating NLA strips. This means
that, even though the current time is stored in the dependency graph, we
need an explicit evaluation time.
There are two functions that allow creation of `AnimationEvalContext`
objects:
- `BKE_animsys_eval_context_construct(Depsgraph *depsgraph, float
eval_time)`, which creates a new context object from scratch, and
- `BKE_animsys_eval_context_construct_at(AnimationEvalContext
*anim_eval_context, float eval_time)`, which can be used to create a
`AnimationEvalContext` with the same depsgraph, but at a different
time. This makes it possible to later add fields without changing any
of the code that just want to change the eval time.
This also provides a fix for T75553, although it does require a change
to the custom driver function. The driver should call
`custom_function(depsgraph)`, and the function should use that depsgraph
instead of information from `bpy.context`.
Reviewed By: brecht, sergey
Differential Revision: https://developer.blender.org/D8047
2020-07-17 17:38:09 +02:00
|
|
|
animsys_evaluate_action_group(&id_ptr, act, agrp, anim_eval_context);
|
2009-04-15 12:59:49 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2023-07-17 10:46:26 +02:00
|
|
|
AnimData adt = {nullptr};
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-04-15 12:59:49 +00:00
|
|
|
/* init animdata, and attach to workob */
|
2012-05-06 15:15:33 +00:00
|
|
|
workob->adt = &adt;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-06 15:15:33 +00:00
|
|
|
adt.action = act;
|
2024-09-13 11:37:44 +02:00
|
|
|
adt.slot_handle = action_slot_handle;
|
2020-09-25 11:07:32 +02:00
|
|
|
BKE_animdata_action_ensure_idroot(&workob->id, act);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-04-15 12:59:49 +00:00
|
|
|
/* execute effects of Action on to workob (or its PoseChannels) */
|
T77086 Animation: Passing Dependency Graph to Drivers
Custom driver functions need access to the dependency graph that is
triggering the evaluation of the driver. This patch passes the
dependency graph pointer through all the animation-related calls.
Instead of passing the evaluation time to functions, the code now passes
an `AnimationEvalContext` pointer:
```
typedef struct AnimationEvalContext {
struct Depsgraph *const depsgraph;
const float eval_time;
} AnimationEvalContext;
```
These structs are read-only, meaning that the code cannot change the
evaluation time. Note that the `depsgraph` pointer itself is const, but
it points to a non-const depsgraph.
FCurves and Drivers can be evaluated at a different time than the
current scene time, for example when evaluating NLA strips. This means
that, even though the current time is stored in the dependency graph, we
need an explicit evaluation time.
There are two functions that allow creation of `AnimationEvalContext`
objects:
- `BKE_animsys_eval_context_construct(Depsgraph *depsgraph, float
eval_time)`, which creates a new context object from scratch, and
- `BKE_animsys_eval_context_construct_at(AnimationEvalContext
*anim_eval_context, float eval_time)`, which can be used to create a
`AnimationEvalContext` with the same depsgraph, but at a different
time. This makes it possible to later add fields without changing any
of the code that just want to change the eval time.
This also provides a fix for T75553, although it does require a change
to the custom driver function. The driver should call
`custom_function(depsgraph)`, and the function should use that depsgraph
instead of information from `bpy.context`.
Reviewed By: brecht, sergey
Differential Revision: https://developer.blender.org/D8047
2020-07-17 17:38:09 +02:00
|
|
|
BKE_animsys_evaluate_animdata(&workob->id, &adt, anim_eval_context, ADT_RECALC_ANIM, false);
|
2024-04-04 10:55:14 +11:00
|
|
|
|
|
|
|
|
/* Ensure stack memory set here isn't accessed later, relates to !118847. */
|
|
|
|
|
workob->adt = nullptr;
|
2009-04-15 12:59:49 +00:00
|
|
|
}
|
2024-02-29 11:02:11 +11:00
|
|
|
/* Ensure stack memory set here isn't accessed later, see !118847. */
|
|
|
|
|
workob->runtime = nullptr;
|
2009-01-29 11:22:34 +00:00
|
|
|
}
|
2020-08-03 17:17:57 +02:00
|
|
|
|
2024-01-22 13:47:13 +01:00
|
|
|
void BKE_pose_check_uids_unique_and_report(const bPose *pose)
|
2020-08-03 17:17:57 +02:00
|
|
|
{
|
2023-07-17 10:46:26 +02:00
|
|
|
if (pose == nullptr) {
|
2020-08-03 17:17:57 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-22 13:47:13 +01:00
|
|
|
GSet *used_uids = BLI_gset_new(
|
|
|
|
|
BLI_session_uid_ghash_hash, BLI_session_uid_ghash_compare, "sequencer used uids");
|
2020-08-03 17:17:57 +02:00
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
|
2024-01-22 13:47:13 +01:00
|
|
|
const SessionUID *session_uid = &pchan->runtime.session_uid;
|
|
|
|
|
if (!BLI_session_uid_is_generated(session_uid)) {
|
|
|
|
|
printf("Pose channel %s does not have UID generated.\n", pchan->name);
|
2020-08-03 17:17:57 +02:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-22 13:47:13 +01:00
|
|
|
if (BLI_gset_lookup(used_uids, session_uid) != nullptr) {
|
|
|
|
|
printf("Pose channel %s has duplicate UID generated.\n", pchan->name);
|
2020-08-03 17:17:57 +02:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-22 13:47:13 +01:00
|
|
|
BLI_gset_insert(used_uids, (void *)session_uid);
|
2020-08-03 17:17:57 +02:00
|
|
|
}
|
|
|
|
|
|
2024-01-22 13:47:13 +01:00
|
|
|
BLI_gset_free(used_uids, nullptr);
|
2020-08-03 17:17:57 +02:00
|
|
|
}
|
2020-11-06 17:58:12 +01:00
|
|
|
|
|
|
|
|
void BKE_pose_blend_write(BlendWriter *writer, bPose *pose, bArmature *arm)
|
|
|
|
|
{
|
2023-07-12 13:29:35 +10:00
|
|
|
#ifndef __GNUC__
|
2023-07-17 10:46:26 +02:00
|
|
|
BLI_assert(pose != nullptr && arm != nullptr);
|
2023-07-12 11:49:55 +10:00
|
|
|
#endif
|
2020-11-06 17:58:12 +01:00
|
|
|
|
|
|
|
|
/* Write channels */
|
|
|
|
|
LISTBASE_FOREACH (bPoseChannel *, chan, &pose->chanbase) {
|
|
|
|
|
/* Write ID Properties -- and copy this comment EXACTLY for easy finding
|
2021-06-26 21:35:18 +10:00
|
|
|
* of library blocks that implement this. */
|
2020-11-06 17:58:12 +01:00
|
|
|
if (chan->prop) {
|
|
|
|
|
IDP_BlendWrite(writer, chan->prop);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BKE_constraint_blend_write(writer, &chan->constraints);
|
|
|
|
|
|
|
|
|
|
animviz_motionpath_blend_write(writer, chan->mpath);
|
|
|
|
|
|
2023-06-07 21:45:48 +10:00
|
|
|
/* Prevent crashes with auto-save,
|
2020-11-06 17:58:12 +01:00
|
|
|
* when a bone duplicated in edit-mode has not yet been assigned to its pose-channel.
|
|
|
|
|
* Also needed with memundo, in some cases we can store a step before pose has been
|
|
|
|
|
* properly rebuilt from previous undo step. */
|
|
|
|
|
Bone *bone = (pose->flag & POSE_RECALC) ? BKE_armature_find_bone_name(arm, chan->name) :
|
|
|
|
|
chan->bone;
|
2023-07-17 10:46:26 +02:00
|
|
|
if (bone != nullptr) {
|
2020-11-06 17:58:12 +01:00
|
|
|
/* gets restored on read, for library armatures */
|
|
|
|
|
chan->selectflag = bone->flag & BONE_SELECTED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BLO_write_struct(writer, bPoseChannel, chan);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Write groups */
|
|
|
|
|
LISTBASE_FOREACH (bActionGroup *, grp, &pose->agroups) {
|
|
|
|
|
BLO_write_struct(writer, bActionGroup, grp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* write IK param */
|
|
|
|
|
if (pose->ikparam) {
|
|
|
|
|
const char *structname = BKE_pose_ikparam_get_name(pose);
|
|
|
|
|
if (structname) {
|
|
|
|
|
BLO_write_struct_by_name(writer, structname, pose->ikparam);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Write this pose */
|
|
|
|
|
BLO_write_struct(writer, bPose, pose);
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-14 16:45:18 +02:00
|
|
|
void BKE_pose_blend_read_data(BlendDataReader *reader, ID *id_owner, bPose *pose)
|
2020-11-06 17:58:12 +01:00
|
|
|
{
|
|
|
|
|
if (!pose) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-24 17:01:22 +02:00
|
|
|
BLO_read_struct_list(reader, bPoseChannel, &pose->chanbase);
|
|
|
|
|
BLO_read_struct_list(reader, bActionGroup, &pose->agroups);
|
2020-11-06 17:58:12 +01:00
|
|
|
|
2023-07-17 10:46:26 +02:00
|
|
|
pose->chanhash = nullptr;
|
|
|
|
|
pose->chan_array = nullptr;
|
2020-11-06 17:58:12 +01:00
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
|
|
|
|
|
BKE_pose_channel_runtime_reset(&pchan->runtime);
|
2024-01-22 13:47:13 +01:00
|
|
|
BKE_pose_channel_session_uid_generate(pchan);
|
2020-11-06 17:58:12 +01:00
|
|
|
|
2023-07-17 10:46:26 +02:00
|
|
|
pchan->bone = nullptr;
|
2024-04-24 17:01:22 +02:00
|
|
|
BLO_read_struct(reader, bPoseChannel, &pchan->parent);
|
|
|
|
|
BLO_read_struct(reader, bPoseChannel, &pchan->child);
|
|
|
|
|
BLO_read_struct(reader, bPoseChannel, &pchan->custom_tx);
|
2020-11-06 17:58:12 +01:00
|
|
|
|
2024-04-24 17:01:22 +02:00
|
|
|
BLO_read_struct(reader, bPoseChannel, &pchan->bbone_prev);
|
|
|
|
|
BLO_read_struct(reader, bPoseChannel, &pchan->bbone_next);
|
2020-11-06 17:58:12 +01:00
|
|
|
|
2023-08-14 16:45:18 +02:00
|
|
|
BKE_constraint_blend_read_data(reader, id_owner, &pchan->constraints);
|
2020-11-06 17:58:12 +01:00
|
|
|
|
2024-04-24 17:01:22 +02:00
|
|
|
BLO_read_struct(reader, IDProperty, &pchan->prop);
|
2020-11-06 17:58:12 +01:00
|
|
|
IDP_BlendDataRead(reader, &pchan->prop);
|
|
|
|
|
|
2024-04-24 17:01:22 +02:00
|
|
|
BLO_read_struct(reader, bMotionPath, &pchan->mpath);
|
2020-11-06 17:58:12 +01:00
|
|
|
if (pchan->mpath) {
|
|
|
|
|
animviz_motionpath_blend_read_data(reader, pchan->mpath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BLI_listbase_clear(&pchan->iktree);
|
|
|
|
|
BLI_listbase_clear(&pchan->siktree);
|
|
|
|
|
|
|
|
|
|
/* in case this value changes in future, clamp else we get undefined behavior */
|
|
|
|
|
CLAMP(pchan->rotmode, ROT_MODE_MIN, ROT_MODE_MAX);
|
|
|
|
|
|
2023-07-17 10:46:26 +02:00
|
|
|
pchan->draw_data = nullptr;
|
2020-11-06 17:58:12 +01:00
|
|
|
}
|
2023-07-17 10:46:26 +02:00
|
|
|
pose->ikdata = nullptr;
|
|
|
|
|
if (pose->ikparam != nullptr) {
|
2024-07-31 19:29:09 +02:00
|
|
|
const char *structname = BKE_pose_ikparam_get_name(pose);
|
|
|
|
|
if (structname) {
|
|
|
|
|
pose->ikparam = BLO_read_struct_by_name_array(reader, structname, 1, pose->ikparam);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
pose->ikparam = nullptr;
|
|
|
|
|
}
|
2020-11-06 17:58:12 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-11 18:07:59 +01:00
|
|
|
void BKE_pose_blend_read_after_liblink(BlendLibReader *reader, Object *ob, bPose *pose)
|
2020-11-06 17:58:12 +01:00
|
|
|
{
|
2023-07-17 10:46:26 +02:00
|
|
|
bArmature *arm = static_cast<bArmature *>(ob->data);
|
2020-11-06 17:58:12 +01:00
|
|
|
|
|
|
|
|
if (!pose || !arm) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-03 17:57:40 +01:00
|
|
|
/* Always rebuild to match library changes, except on Undo. */
|
2020-11-06 17:58:12 +01:00
|
|
|
bool rebuild = false;
|
|
|
|
|
|
|
|
|
|
if (!BLO_read_lib_is_undo(reader)) {
|
2022-02-03 17:57:40 +01:00
|
|
|
if (ob->id.lib != arm->id.lib) {
|
2020-11-06 17:58:12 +01:00
|
|
|
rebuild = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
|
|
|
|
|
pchan->bone = BKE_armature_find_bone_name(arm, pchan->name);
|
|
|
|
|
|
2023-07-17 10:46:26 +02:00
|
|
|
if (UNLIKELY(pchan->bone == nullptr)) {
|
2020-11-06 17:58:12 +01:00
|
|
|
rebuild = true;
|
|
|
|
|
}
|
2021-08-26 15:01:14 +02:00
|
|
|
else if (!ID_IS_LINKED(ob) && ID_IS_LINKED(arm)) {
|
2020-11-06 17:58:12 +01:00
|
|
|
/* local pose selection copied to armature, bit hackish */
|
|
|
|
|
pchan->bone->flag &= ~BONE_SELECTED;
|
|
|
|
|
pchan->bone->flag |= pchan->selectflag;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rebuild) {
|
|
|
|
|
Main *bmain = BLO_read_lib_get_main(reader);
|
|
|
|
|
DEG_id_tag_update_ex(
|
|
|
|
|
bmain, &ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
|
|
|
|
|
BKE_pose_tag_recalc(bmain, pose);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-23 11:41:44 +02:00
|
|
|
void BKE_action_fcurves_clear(bAction *act)
|
|
|
|
|
{
|
|
|
|
|
if (!act) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-09-24 17:36:36 +02:00
|
|
|
|
|
|
|
|
BLI_assert(act->wrap().is_action_legacy());
|
|
|
|
|
|
2022-06-23 11:41:44 +02:00
|
|
|
while (act->curves.first) {
|
2023-07-17 10:46:26 +02:00
|
|
|
FCurve *fcu = static_cast<FCurve *>(act->curves.first);
|
2022-06-23 11:41:44 +02:00
|
|
|
action_groups_remove_channel(act, fcu);
|
|
|
|
|
BKE_fcurve_free(fcu);
|
|
|
|
|
}
|
|
|
|
|
DEG_id_tag_update(&act->id, ID_RECALC_ANIMATION_NO_FLUSH);
|
|
|
|
|
}
|