Blender V4.3
visualkey.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cstdio>
10#include <cstring>
11
12#include "ANIM_rna.hh"
13#include "ANIM_visualkey.hh"
14
15#include "BKE_armature.hh"
16
17#include "BLI_math_matrix.h"
18#include "BLI_math_rotation.h"
19
21#include "DNA_object_types.h"
22#include "DNA_rigidbody_types.h"
23
24#include "RNA_access.hh"
25#include "RNA_prototypes.hh"
26
27namespace blender::animrig {
28
29/* Internal status codes for visualkey_can_use. */
30enum {
35};
36
38{
39 bConstraint *con = nullptr;
40 bool has_rigidbody = false;
41 bool has_parent = false;
42
43 if (ELEM(nullptr, ptr, ptr->data, prop)) {
44 return false;
45 }
46
47 /* Get first constraint and determine type of keyframe constraints to check for
48 * - constraints can be on either Objects or PoseChannels, so we only check if the
49 * ptr->type is RNA_Object or RNA_PoseBone, which are the RNA wrapping-info for
50 * those structs, allowing us to identify the owner of the data
51 */
52 if (ptr->type == &RNA_Object) {
53 Object *ob = static_cast<Object *>(ptr->data);
55
56 con = static_cast<bConstraint *>(ob->constraints.first);
57 has_parent = (ob->parent != nullptr);
58
59 /* Active rigidbody objects only, as only those are affected by sim. */
60 has_rigidbody = ((rbo) && (rbo->type == RBO_TYPE_ACTIVE));
61 }
62 else if (ptr->type == &RNA_PoseBone) {
63 bPoseChannel *pchan = static_cast<bPoseChannel *>(ptr->data);
64
66 /* Spline IK cannot generally be keyed visually, because (at least with the default
67 * constraint settings) it requires non-uniform scaling that causes shearing in child bones,
68 * which cannot be represented by the bone's loc/rot/scale properties. */
69 return true;
70 }
71
72 con = static_cast<bConstraint *>(pchan->constraints.first);
73 has_parent = (pchan->parent != nullptr);
74 }
75 else {
76 BLI_assert_msg(false,
77 "visualkey_can_use called for data-block that is not an Object or PoseBone.");
78 return false;
79 }
80
81 /* Parent or rigidbody are always matching, no need to check further. */
82 if (has_parent || has_rigidbody) {
83 return true;
84 }
85
86 /* Only do visual keying on transforms. */
87 const char *identifier = RNA_property_identifier(prop);
88 if (identifier == nullptr) {
89 printf("%s failed: nullptr identifier\n", __func__);
90 return false;
91 }
92
93 short searchtype = VISUALKEY_NONE;
94 if (strstr(identifier, "location")) {
95 searchtype = VISUALKEY_LOC;
96 }
97 else if (strstr(identifier, "rotation")) {
98 searchtype = VISUALKEY_ROT;
99 }
100 else if (strstr(identifier, "scale")) {
101 searchtype = VISUALKEY_SCA;
102 }
103 else {
104 printf("%s failed: identifier - '%s'\n", __func__, identifier);
105 return false;
106 }
107
108 /* Check constraints. */
109 for (; con; con = con->next) {
110 /* only consider constraint if it is not disabled, and has influence */
111 if (con->flag & CONSTRAINT_DISABLE) {
112 continue;
113 }
114 if (con->enforce == 0.0f) {
115 continue;
116 }
117
118 /* Some constraints may alter these transforms. */
119 switch (con->type) {
120 /* Multi-transform constraints. */
123 return true;
126 return true;
128 return true;
130 return true;
131
132 /* Single-transform constraints. */
134 if (searchtype == VISUALKEY_ROT) {
135 return true;
136 }
137 break;
139 if (searchtype == VISUALKEY_ROT) {
140 return true;
141 }
142 break;
144 if (searchtype == VISUALKEY_ROT) {
145 return true;
146 }
147 break;
149 if (searchtype == VISUALKEY_LOC) {
150 return true;
151 }
152 break;
154 if (searchtype == VISUALKEY_SCA) {
155 return true;
156 }
157 break;
159 if (searchtype == VISUALKEY_LOC) {
160 return true;
161 }
162 break;
164 if (searchtype == VISUALKEY_ROT) {
165 return true;
166 }
167 break;
169 if (searchtype == VISUALKEY_LOC) {
170 return true;
171 }
172 break;
174 if (searchtype == VISUALKEY_SCA) {
175 return true;
176 }
177 break;
179 if (searchtype == VISUALKEY_ROT) {
180 return true;
181 }
182 break;
184 if (searchtype == VISUALKEY_LOC) {
185 return true;
186 }
187 break;
188
189 default:
190 break;
191 }
192 }
193
194 return false;
195}
196
198{
199 Vector<float> values;
200 const char *identifier = RNA_property_identifier(prop);
201 float tmat[4][4];
202 int rotmode;
203
204 /* Handle for Objects or PoseChannels only
205 * - only Location, Rotation or Scale keyframes are supported currently
206 * - constraints can be on either Objects or PoseChannels, so we only check if the
207 * ptr->type is RNA_Object or RNA_PoseBone, which are the RNA wrapping-info for
208 * those structs, allowing us to identify the owner of the data
209 * - assume that array_index will be sane
210 */
211 if (ptr->type == &RNA_Object) {
212 Object *ob = static_cast<Object *>(ptr->data);
213 /* Loc code is specific... */
214 if (strstr(identifier, "location")) {
215 values.extend({ob->object_to_world().location(), 3});
216 return values;
217 }
218
219 copy_m4_m4(tmat, ob->object_to_world().ptr());
220 rotmode = ob->rotmode;
221 }
222 else if (ptr->type == &RNA_PoseBone) {
223 bPoseChannel *pchan = static_cast<bPoseChannel *>(ptr->data);
224
225 BKE_armature_mat_pose_to_bone(pchan, pchan->pose_mat, tmat);
226 rotmode = pchan->rotmode;
227
228 /* Loc code is specific... */
229 if (strstr(identifier, "location")) {
230 /* Only use for non-connected bones. */
231 if ((pchan->bone->parent == nullptr) || !(pchan->bone->flag & BONE_CONNECTED)) {
232 values.extend({tmat[3], 3});
233 return values;
234 }
235 }
236 }
237 else {
238 return get_rna_values(ptr, prop);
239 }
240
241 /* Rot/Scale code are common! */
242 if (strstr(identifier, "rotation_euler")) {
243 values.resize(3);
244 mat4_to_eulO(values.data(), rotmode, tmat);
245 return values;
246 }
247
248 if (strstr(identifier, "rotation_quaternion")) {
249 values.resize(4);
250 mat4_to_quat(values.data(), tmat);
251 return values;
252 }
253
254 if (strstr(identifier, "rotation_axis_angle")) {
255 /* w = 0, x,y,z = 1,2,3 */
256 values.resize(4);
257 mat4_to_axis_angle(&values[1], &values[0], tmat);
258 return values;
259 }
260
261 if (strstr(identifier, "scale")) {
262 values.resize(3);
263 mat4_to_size(values.data(), tmat);
264 return values;
265 }
266
267 /* As the function hasn't returned yet, read value from system in the default way. */
268 return get_rna_values(ptr, prop);
269}
270} // namespace blender::animrig
Helper functions for animation to interact with the RNA system.
Functions to work with the visual keying system.
void BKE_armature_mat_pose_to_bone(bPoseChannel *pchan, const float inmat[4][4], float outmat[4][4])
Definition armature.cc:2249
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
void copy_m4_m4(float m1[4][4], const float m2[4][4])
void mat4_to_size(float size[3], const float M[4][4])
void mat4_to_axis_angle(float axis[3], float *angle, const float mat[4][4])
void mat4_to_eulO(float eul[3], short order, const float m[4][4])
void mat4_to_quat(float q[4], const float mat[4][4])
#define ELEM(...)
@ PCHAN_INFLUENCED_BY_IK
@ PCHAN_HAS_IK
@ BONE_CONNECTED
@ CONSTRAINT_DISABLE
@ CONSTRAINT_TYPE_TRACKTO
@ CONSTRAINT_TYPE_CHILDOF
@ CONSTRAINT_TYPE_TRANSFORM
@ CONSTRAINT_TYPE_ARMATURE
@ CONSTRAINT_TYPE_LOCLIKE
@ CONSTRAINT_TYPE_MINMAX
@ CONSTRAINT_TYPE_ROTLIMIT
@ CONSTRAINT_TYPE_ROTLIKE
@ CONSTRAINT_TYPE_KINEMATIC
@ CONSTRAINT_TYPE_DISTLIMIT
@ CONSTRAINT_TYPE_TRANSLIKE
@ CONSTRAINT_TYPE_LOCLIMIT
@ CONSTRAINT_TYPE_LOCKTRACK
@ CONSTRAINT_TYPE_SIZELIMIT
@ CONSTRAINT_TYPE_FOLLOWPATH
@ CONSTRAINT_TYPE_SIZELIKE
@ CONSTRAINT_TYPE_DAMPTRACK
Object is a sort of wrapper for general info.
Types and defines for representing Rigid Body entities.
@ RBO_TYPE_ACTIVE
#define printf
Vector< float > visualkey_get_values(PointerRNA *ptr, PropertyRNA *prop)
Definition visualkey.cc:197
bool visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
Definition visualkey.cc:37
Vector< float > get_rna_values(PointerRNA *ptr, PropertyRNA *prop)
Definition anim_rna.cc:16
const char * RNA_property_identifier(const PropertyRNA *prop)
struct Bone * parent
void * first
ListBase constraints
struct RigidBodyOb * rigidbody_object
struct Object * parent
StructRNA * type
Definition RNA_types.hh:41
void * data
Definition RNA_types.hh:42
struct bConstraint * next
struct Bone * bone
struct bPoseChannel * parent
float pose_mat[4][4]
PointerRNA * ptr
Definition wm_files.cc:4126