Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/scene/3d/copy_transform_modifier_3d.cpp
9896 views
1
/**************************************************************************/
2
/* copy_transform_modifier_3d.cpp */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#include "copy_transform_modifier_3d.h"
32
33
bool CopyTransformModifier3D::_set(const StringName &p_path, const Variant &p_value) {
34
String path = p_path;
35
36
if (path.begins_with("settings/")) {
37
int which = path.get_slicec('/', 1).to_int();
38
String what = path.get_slicec('/', 2);
39
ERR_FAIL_INDEX_V(which, settings.size(), false);
40
41
if (what == "copy") {
42
set_copy_flags(which, static_cast<BitField<TransformFlag>>((int)p_value));
43
} else if (what == "axes") {
44
set_axis_flags(which, static_cast<BitField<AxisFlag>>((int)p_value));
45
} else if (what == "invert") {
46
set_invert_flags(which, static_cast<BitField<AxisFlag>>((int)p_value));
47
} else if (what == "relative") {
48
set_relative(which, p_value);
49
} else if (what == "additive") {
50
set_additive(which, p_value);
51
} else {
52
return false;
53
}
54
}
55
return true;
56
}
57
58
bool CopyTransformModifier3D::_get(const StringName &p_path, Variant &r_ret) const {
59
String path = p_path;
60
61
if (path.begins_with("settings/")) {
62
int which = path.get_slicec('/', 1).to_int();
63
String what = path.get_slicec('/', 2);
64
ERR_FAIL_INDEX_V(which, settings.size(), false);
65
66
if (what == "copy") {
67
r_ret = (int)get_copy_flags(which);
68
} else if (what == "axes") {
69
r_ret = (int)get_axis_flags(which);
70
} else if (what == "invert") {
71
r_ret = (int)get_invert_flags(which);
72
} else if (what == "relative") {
73
r_ret = is_relative(which);
74
} else if (what == "additive") {
75
r_ret = is_additive(which);
76
} else {
77
return false;
78
}
79
}
80
return true;
81
}
82
83
void CopyTransformModifier3D::_get_property_list(List<PropertyInfo> *p_list) const {
84
BoneConstraint3D::get_property_list(p_list);
85
86
for (int i = 0; i < settings.size(); i++) {
87
String path = "settings/" + itos(i) + "/";
88
p_list->push_back(PropertyInfo(Variant::INT, path + "copy", PROPERTY_HINT_FLAGS, "Position,Rotation,Scale"));
89
p_list->push_back(PropertyInfo(Variant::INT, path + "axes", PROPERTY_HINT_FLAGS, "X,Y,Z"));
90
p_list->push_back(PropertyInfo(Variant::INT, path + "invert", PROPERTY_HINT_FLAGS, "X,Y,Z"));
91
p_list->push_back(PropertyInfo(Variant::BOOL, path + "relative"));
92
p_list->push_back(PropertyInfo(Variant::BOOL, path + "additive"));
93
}
94
}
95
96
void CopyTransformModifier3D::_validate_setting(int p_index) {
97
settings.write[p_index] = memnew(CopyTransform3DSetting);
98
}
99
100
void CopyTransformModifier3D::set_copy_flags(int p_index, BitField<TransformFlag> p_copy_flags) {
101
ERR_FAIL_INDEX(p_index, settings.size());
102
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
103
setting->copy_flags = p_copy_flags;
104
notify_property_list_changed();
105
}
106
107
BitField<CopyTransformModifier3D::TransformFlag> CopyTransformModifier3D::get_copy_flags(int p_index) const {
108
ERR_FAIL_INDEX_V(p_index, settings.size(), 0);
109
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
110
return setting->copy_flags;
111
}
112
113
void CopyTransformModifier3D::set_axis_flags(int p_index, BitField<AxisFlag> p_axis_flags) {
114
ERR_FAIL_INDEX(p_index, settings.size());
115
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
116
setting->axis_flags = p_axis_flags;
117
notify_property_list_changed();
118
}
119
120
BitField<CopyTransformModifier3D::AxisFlag> CopyTransformModifier3D::get_axis_flags(int p_index) const {
121
ERR_FAIL_INDEX_V(p_index, settings.size(), 0);
122
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
123
return setting->axis_flags;
124
}
125
126
void CopyTransformModifier3D::set_invert_flags(int p_index, BitField<AxisFlag> p_axis_flags) {
127
ERR_FAIL_INDEX(p_index, settings.size());
128
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
129
setting->invert_flags = p_axis_flags;
130
notify_property_list_changed();
131
}
132
133
BitField<CopyTransformModifier3D::AxisFlag> CopyTransformModifier3D::get_invert_flags(int p_index) const {
134
ERR_FAIL_INDEX_V(p_index, settings.size(), false);
135
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
136
return setting->invert_flags;
137
}
138
139
void CopyTransformModifier3D::set_copy_position(int p_index, bool p_enabled) {
140
ERR_FAIL_INDEX(p_index, settings.size());
141
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
142
if (p_enabled) {
143
setting->copy_flags.set_flag(TRANSFORM_FLAG_POSITION);
144
} else {
145
setting->copy_flags.clear_flag(TRANSFORM_FLAG_POSITION);
146
}
147
}
148
149
bool CopyTransformModifier3D::is_position_copying(int p_index) const {
150
ERR_FAIL_INDEX_V(p_index, settings.size(), false);
151
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
152
return setting->copy_flags.has_flag(TRANSFORM_FLAG_POSITION);
153
}
154
155
void CopyTransformModifier3D::set_copy_rotation(int p_index, bool p_enabled) {
156
ERR_FAIL_INDEX(p_index, settings.size());
157
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
158
if (p_enabled) {
159
setting->copy_flags.set_flag(TRANSFORM_FLAG_ROTATION);
160
} else {
161
setting->copy_flags.clear_flag(TRANSFORM_FLAG_ROTATION);
162
}
163
}
164
165
bool CopyTransformModifier3D::is_rotation_copying(int p_index) const {
166
ERR_FAIL_INDEX_V(p_index, settings.size(), false);
167
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
168
return setting->copy_flags.has_flag(TRANSFORM_FLAG_ROTATION);
169
}
170
171
void CopyTransformModifier3D::set_copy_scale(int p_index, bool p_enabled) {
172
ERR_FAIL_INDEX(p_index, settings.size());
173
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
174
if (p_enabled) {
175
setting->copy_flags.set_flag(TRANSFORM_FLAG_SCALE);
176
} else {
177
setting->copy_flags.clear_flag(TRANSFORM_FLAG_SCALE);
178
}
179
}
180
181
bool CopyTransformModifier3D::is_scale_copying(int p_index) const {
182
ERR_FAIL_INDEX_V(p_index, settings.size(), false);
183
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
184
return setting->copy_flags.has_flag(TRANSFORM_FLAG_SCALE);
185
}
186
187
void CopyTransformModifier3D::set_axis_x_enabled(int p_index, bool p_enabled) {
188
ERR_FAIL_INDEX(p_index, settings.size());
189
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
190
if (p_enabled) {
191
setting->axis_flags.set_flag(AXIS_FLAG_X);
192
} else {
193
setting->axis_flags.clear_flag(AXIS_FLAG_X);
194
}
195
}
196
197
bool CopyTransformModifier3D::is_axis_x_enabled(int p_index) const {
198
ERR_FAIL_INDEX_V(p_index, settings.size(), false);
199
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
200
return setting->axis_flags.has_flag(AXIS_FLAG_X);
201
}
202
203
void CopyTransformModifier3D::set_axis_y_enabled(int p_index, bool p_enabled) {
204
ERR_FAIL_INDEX(p_index, settings.size());
205
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
206
if (p_enabled) {
207
setting->axis_flags.set_flag(AXIS_FLAG_Y);
208
} else {
209
setting->axis_flags.clear_flag(AXIS_FLAG_Y);
210
}
211
}
212
213
bool CopyTransformModifier3D::is_axis_y_enabled(int p_index) const {
214
ERR_FAIL_INDEX_V(p_index, settings.size(), false);
215
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
216
return setting->axis_flags.has_flag(AXIS_FLAG_Y);
217
}
218
219
void CopyTransformModifier3D::set_axis_z_enabled(int p_index, bool p_enabled) {
220
ERR_FAIL_INDEX(p_index, settings.size());
221
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
222
if (p_enabled) {
223
setting->axis_flags.set_flag(AXIS_FLAG_Z);
224
} else {
225
setting->axis_flags.clear_flag(AXIS_FLAG_Z);
226
}
227
}
228
229
bool CopyTransformModifier3D::is_axis_z_enabled(int p_index) const {
230
ERR_FAIL_INDEX_V(p_index, settings.size(), false);
231
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
232
return setting->axis_flags.has_flag(AXIS_FLAG_Z);
233
}
234
235
void CopyTransformModifier3D::set_axis_x_inverted(int p_index, bool p_enabled) {
236
ERR_FAIL_INDEX(p_index, settings.size());
237
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
238
if (p_enabled) {
239
setting->invert_flags.set_flag(AXIS_FLAG_X);
240
} else {
241
setting->invert_flags.clear_flag(AXIS_FLAG_X);
242
}
243
}
244
245
bool CopyTransformModifier3D::is_axis_x_inverted(int p_index) const {
246
ERR_FAIL_INDEX_V(p_index, settings.size(), false);
247
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
248
return setting->invert_flags.has_flag(AXIS_FLAG_X);
249
}
250
251
void CopyTransformModifier3D::set_axis_y_inverted(int p_index, bool p_enabled) {
252
ERR_FAIL_INDEX(p_index, settings.size());
253
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
254
if (p_enabled) {
255
setting->invert_flags.set_flag(AXIS_FLAG_Y);
256
} else {
257
setting->invert_flags.clear_flag(AXIS_FLAG_Y);
258
}
259
}
260
261
bool CopyTransformModifier3D::is_axis_y_inverted(int p_index) const {
262
ERR_FAIL_INDEX_V(p_index, settings.size(), false);
263
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
264
return setting->invert_flags.has_flag(AXIS_FLAG_Y);
265
}
266
267
void CopyTransformModifier3D::set_axis_z_inverted(int p_index, bool p_enabled) {
268
ERR_FAIL_INDEX(p_index, settings.size());
269
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
270
if (p_enabled) {
271
setting->invert_flags.set_flag(AXIS_FLAG_Z);
272
} else {
273
setting->invert_flags.clear_flag(AXIS_FLAG_Z);
274
}
275
}
276
277
bool CopyTransformModifier3D::is_axis_z_inverted(int p_index) const {
278
ERR_FAIL_INDEX_V(p_index, settings.size(), false);
279
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
280
return setting->invert_flags.has_flag(AXIS_FLAG_Z);
281
}
282
283
void CopyTransformModifier3D::set_relative(int p_index, bool p_enabled) {
284
ERR_FAIL_INDEX(p_index, settings.size());
285
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
286
setting->relative = p_enabled;
287
}
288
289
bool CopyTransformModifier3D::is_relative(int p_index) const {
290
ERR_FAIL_INDEX_V(p_index, settings.size(), 0);
291
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
292
return setting->relative;
293
}
294
295
void CopyTransformModifier3D::set_additive(int p_index, bool p_enabled) {
296
ERR_FAIL_INDEX(p_index, settings.size());
297
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
298
setting->additive = p_enabled;
299
}
300
301
bool CopyTransformModifier3D::is_additive(int p_index) const {
302
ERR_FAIL_INDEX_V(p_index, settings.size(), 0);
303
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
304
return setting->additive;
305
}
306
307
void CopyTransformModifier3D::_bind_methods() {
308
ClassDB::bind_method(D_METHOD("set_copy_flags", "index", "copy_flags"), &CopyTransformModifier3D::set_copy_flags);
309
ClassDB::bind_method(D_METHOD("get_copy_flags", "index"), &CopyTransformModifier3D::get_copy_flags);
310
ClassDB::bind_method(D_METHOD("set_axis_flags", "index", "axis_flags"), &CopyTransformModifier3D::set_axis_flags);
311
ClassDB::bind_method(D_METHOD("get_axis_flags", "index"), &CopyTransformModifier3D::get_axis_flags);
312
ClassDB::bind_method(D_METHOD("set_invert_flags", "index", "axis_flags"), &CopyTransformModifier3D::set_invert_flags);
313
ClassDB::bind_method(D_METHOD("get_invert_flags", "index"), &CopyTransformModifier3D::get_invert_flags);
314
315
ClassDB::bind_method(D_METHOD("set_copy_position", "index", "enabled"), &CopyTransformModifier3D::set_copy_position);
316
ClassDB::bind_method(D_METHOD("is_position_copying", "index"), &CopyTransformModifier3D::is_position_copying);
317
ClassDB::bind_method(D_METHOD("set_copy_rotation", "index", "enabled"), &CopyTransformModifier3D::set_copy_rotation);
318
ClassDB::bind_method(D_METHOD("is_rotation_copying", "index"), &CopyTransformModifier3D::is_rotation_copying);
319
ClassDB::bind_method(D_METHOD("set_copy_scale", "index", "enabled"), &CopyTransformModifier3D::set_copy_scale);
320
ClassDB::bind_method(D_METHOD("is_scale_copying", "index"), &CopyTransformModifier3D::is_scale_copying);
321
322
ClassDB::bind_method(D_METHOD("set_axis_x_enabled", "index", "enabled"), &CopyTransformModifier3D::set_axis_x_enabled);
323
ClassDB::bind_method(D_METHOD("is_axis_x_enabled", "index"), &CopyTransformModifier3D::is_axis_x_enabled);
324
ClassDB::bind_method(D_METHOD("set_axis_y_enabled", "index", "enabled"), &CopyTransformModifier3D::set_axis_y_enabled);
325
ClassDB::bind_method(D_METHOD("is_axis_y_enabled", "index"), &CopyTransformModifier3D::is_axis_y_enabled);
326
ClassDB::bind_method(D_METHOD("set_axis_z_enabled", "index", "enabled"), &CopyTransformModifier3D::set_axis_z_enabled);
327
ClassDB::bind_method(D_METHOD("is_axis_z_enabled", "index"), &CopyTransformModifier3D::is_axis_z_enabled);
328
329
ClassDB::bind_method(D_METHOD("set_axis_x_inverted", "index", "enabled"), &CopyTransformModifier3D::set_axis_x_inverted);
330
ClassDB::bind_method(D_METHOD("is_axis_x_inverted", "index"), &CopyTransformModifier3D::is_axis_x_inverted);
331
ClassDB::bind_method(D_METHOD("set_axis_y_inverted", "index", "enabled"), &CopyTransformModifier3D::set_axis_y_inverted);
332
ClassDB::bind_method(D_METHOD("is_axis_y_inverted", "index"), &CopyTransformModifier3D::is_axis_y_inverted);
333
ClassDB::bind_method(D_METHOD("set_axis_z_inverted", "index", "enabled"), &CopyTransformModifier3D::set_axis_z_inverted);
334
ClassDB::bind_method(D_METHOD("is_axis_z_inverted", "index"), &CopyTransformModifier3D::is_axis_z_inverted);
335
336
ClassDB::bind_method(D_METHOD("set_relative", "index", "enabled"), &CopyTransformModifier3D::set_relative);
337
ClassDB::bind_method(D_METHOD("is_relative", "index"), &CopyTransformModifier3D::is_relative);
338
ClassDB::bind_method(D_METHOD("set_additive", "index", "enabled"), &CopyTransformModifier3D::set_additive);
339
ClassDB::bind_method(D_METHOD("is_additive", "index"), &CopyTransformModifier3D::is_additive);
340
341
ADD_ARRAY_COUNT("Settings", "setting_count", "set_setting_count", "get_setting_count", "settings/");
342
343
BIND_BITFIELD_FLAG(TRANSFORM_FLAG_POSITION);
344
BIND_BITFIELD_FLAG(TRANSFORM_FLAG_ROTATION);
345
BIND_BITFIELD_FLAG(TRANSFORM_FLAG_SCALE);
346
BIND_BITFIELD_FLAG(TRANSFORM_FLAG_ALL);
347
348
BIND_BITFIELD_FLAG(AXIS_FLAG_X);
349
BIND_BITFIELD_FLAG(AXIS_FLAG_Y);
350
BIND_BITFIELD_FLAG(AXIS_FLAG_Z);
351
BIND_BITFIELD_FLAG(AXIS_FLAG_ALL);
352
}
353
354
void CopyTransformModifier3D::_process_constraint(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, int p_reference_bone, float p_amount) {
355
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
356
357
Transform3D destination = p_skeleton->get_bone_pose(p_reference_bone);
358
if (setting->relative) {
359
Vector3 scl_relative = destination.basis.get_scale() / p_skeleton->get_bone_rest(p_reference_bone).basis.get_scale();
360
destination.basis = p_skeleton->get_bone_rest(p_reference_bone).basis.get_rotation_quaternion().inverse() * destination.basis.get_rotation_quaternion();
361
destination.basis.scale_local(scl_relative);
362
destination.origin = destination.origin - p_skeleton->get_bone_rest(p_reference_bone).origin;
363
}
364
Vector3 dest_pos = destination.origin;
365
Quaternion dest_rot = destination.basis.get_rotation_quaternion();
366
Vector3 dest_scl = destination.basis.get_scale();
367
368
// Mask pos and scale.
369
for (int i = 0; i < 3; i++) {
370
if (!setting->axis_flags.has_flag(static_cast<AxisFlag>(1 << i))) {
371
dest_pos[i] = 0.0;
372
dest_scl[i] = 1.0;
373
}
374
}
375
376
// Mask rot.
377
switch (static_cast<int>(setting->axis_flags)) {
378
case 0: {
379
dest_rot = Quaternion();
380
} break;
381
case AXIS_FLAG_X: {
382
Vector3 axis = get_vector_from_axis(Vector3::AXIS_X);
383
dest_rot = Quaternion(axis, get_roll_angle(dest_rot, axis));
384
} break;
385
case AXIS_FLAG_Y: {
386
Vector3 axis = get_vector_from_axis(Vector3::AXIS_Y);
387
dest_rot = Quaternion(axis, get_roll_angle(dest_rot, axis));
388
} break;
389
case AXIS_FLAG_Z: {
390
Vector3 axis = get_vector_from_axis(Vector3::AXIS_Z);
391
dest_rot = Quaternion(axis, get_roll_angle(dest_rot, axis));
392
} break;
393
case AXIS_FLAG_X | AXIS_FLAG_Y: {
394
Vector3 axis = get_vector_from_axis(Vector3::AXIS_Z);
395
dest_rot = dest_rot * Quaternion(axis, get_roll_angle(dest_rot, axis)).inverse();
396
} break;
397
case AXIS_FLAG_Y | AXIS_FLAG_Z: {
398
Vector3 axis = get_vector_from_axis(Vector3::AXIS_X);
399
dest_rot = dest_rot * Quaternion(axis, get_roll_angle(dest_rot, axis)).inverse();
400
} break;
401
case AXIS_FLAG_Z | AXIS_FLAG_X: {
402
Vector3 axis = get_vector_from_axis(Vector3::AXIS_Y);
403
dest_rot = dest_rot * Quaternion(axis, get_roll_angle(dest_rot, axis)).inverse();
404
} break;
405
case AXIS_FLAG_ALL: {
406
} break;
407
}
408
409
// Process inversion.
410
for (int i = 0; i < 3; i++) {
411
AxisFlag axis = static_cast<AxisFlag>(1 << i);
412
if (setting->axis_flags.has_flag(axis) && setting->invert_flags.has_flag(axis)) {
413
dest_pos[i] *= -1;
414
dest_rot[i] *= -1;
415
dest_scl[i] = 1.0 / dest_scl[i];
416
}
417
}
418
dest_rot.normalize();
419
420
if (setting->additive) {
421
destination.origin = p_skeleton->get_bone_pose_position(p_apply_bone) + dest_pos;
422
destination.basis = p_skeleton->get_bone_pose_rotation(p_apply_bone) * Basis(dest_rot);
423
destination.basis.scale_local(p_skeleton->get_bone_pose_scale(p_apply_bone) * dest_scl);
424
} else if (setting->relative) {
425
Transform3D rest = p_skeleton->get_bone_rest(p_apply_bone);
426
destination.origin = rest.origin + dest_pos;
427
destination.basis = rest.basis.get_rotation_quaternion() * Basis(dest_rot);
428
destination.basis.scale_local(rest.basis.get_scale() * dest_scl);
429
} else {
430
destination.origin = dest_pos;
431
destination.basis = Basis(dest_rot);
432
destination.basis.scale_local(dest_scl);
433
}
434
435
// Process interpolation depends on the amount.
436
destination = p_skeleton->get_bone_pose(p_apply_bone).interpolate_with(destination, p_amount);
437
438
// Apply transform depends on the element mask.
439
if (setting->copy_flags.has_flag(TRANSFORM_FLAG_POSITION)) {
440
p_skeleton->set_bone_pose_position(p_apply_bone, destination.origin);
441
}
442
if (setting->copy_flags.has_flag(TRANSFORM_FLAG_ROTATION)) {
443
p_skeleton->set_bone_pose_rotation(p_apply_bone, destination.basis.get_rotation_quaternion());
444
}
445
if (setting->copy_flags.has_flag(TRANSFORM_FLAG_SCALE)) {
446
p_skeleton->set_bone_pose_scale(p_apply_bone, destination.basis.get_scale());
447
}
448
}
449
450
CopyTransformModifier3D::~CopyTransformModifier3D() {
451
clear_settings();
452
}
453
454