Properly applying both translation and rotation to bones.
This commit is contained in:
parent
69bb2d7980
commit
3bb0725e3e
@ -306,29 +306,26 @@ void SyncedAnimationGraph::_apply_animation_data(const AnimationData &output_dat
|
|||||||
for (const KeyValue<Animation::TypeHash, AnimationData::TrackValue *> &K : output_data.track_values) {
|
for (const KeyValue<Animation::TypeHash, AnimationData::TrackValue *> &K : output_data.track_values) {
|
||||||
const AnimationData::TrackValue *track_value = K.value;
|
const AnimationData::TrackValue *track_value = K.value;
|
||||||
switch (track_value->type) {
|
switch (track_value->type) {
|
||||||
case AnimationData::TrackType::TYPE_POSITION_3D: {
|
case AnimationData::TrackType::TYPE_POSITION_3D:
|
||||||
const AnimationData::PositionTrackValue *position_value = static_cast<const AnimationData::PositionTrackValue *>(track_value);
|
|
||||||
|
|
||||||
NodePath path = position_value->track->path;
|
|
||||||
|
|
||||||
if (path.get_subname_count() == 1) {
|
|
||||||
int bone_idx = graph_context.skeleton_3d->find_bone(path.get_subname(0));
|
|
||||||
if (bone_idx != -1) {
|
|
||||||
graph_context.skeleton_3d->set_bone_pose_position(position_value->bone_idx, position_value->position);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case AnimationData::TrackType::TYPE_ROTATION_3D: {
|
case AnimationData::TrackType::TYPE_ROTATION_3D: {
|
||||||
const AnimationData::RotationTrackValue *rotation_value = static_cast<const AnimationData::RotationTrackValue *>(track_value);
|
const AnimationData::TransformTrackValue *transform_track_value = static_cast<const AnimationData::TransformTrackValue *>(track_value);
|
||||||
|
|
||||||
NodePath path = rotation_value->track->path;
|
int bone_idx = -1;
|
||||||
|
NodePath path = transform_track_value->track->path;
|
||||||
|
|
||||||
if (path.get_subname_count() == 1) {
|
if (path.get_subname_count() == 1) {
|
||||||
int bone_idx = graph_context.skeleton_3d->find_bone(path.get_subname(0));
|
bone_idx = graph_context.skeleton_3d->find_bone(path.get_subname(0));
|
||||||
|
|
||||||
if (bone_idx != -1) {
|
if (bone_idx != -1) {
|
||||||
graph_context.skeleton_3d->set_bone_pose_rotation(rotation_value->bone_idx, rotation_value->rotation);
|
if (transform_track_value->loc_used) {
|
||||||
|
graph_context.skeleton_3d->set_bone_pose_position(transform_track_value->bone_idx, transform_track_value->loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transform_track_value->rot_used) {
|
||||||
|
graph_context.skeleton_3d->set_bone_pose_rotation(transform_track_value->bone_idx, transform_track_value->rot);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert(false && "Not yet implemented!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -140,7 +140,7 @@ void AnimationData::sample_from_animation(const Ref<Animation> &animation, const
|
|||||||
|
|
||||||
int count = tracks.size();
|
int count = tracks.size();
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
AnimationData::TrackValue *track_value = nullptr;
|
TrackValue *track_value = nullptr;
|
||||||
const Animation::Track *animation_track = tracks_ptr[i];
|
const Animation::Track *animation_track = tracks_ptr[i];
|
||||||
const NodePath &track_node_path = animation_track->path;
|
const NodePath &track_node_path = animation_track->path;
|
||||||
if (!animation_track->enabled) {
|
if (!animation_track->enabled) {
|
||||||
@ -149,38 +149,43 @@ void AnimationData::sample_from_animation(const Ref<Animation> &animation, const
|
|||||||
|
|
||||||
Animation::TrackType ttype = animation_track->type;
|
Animation::TrackType ttype = animation_track->type;
|
||||||
switch (ttype) {
|
switch (ttype) {
|
||||||
case Animation::TYPE_POSITION_3D: {
|
case Animation::TYPE_POSITION_3D:
|
||||||
AnimationData::PositionTrackValue *position_track_value = memnew(AnimationData::PositionTrackValue);
|
|
||||||
|
|
||||||
if (track_node_path.get_subname_count() == 1) {
|
|
||||||
int bone_idx = skeleton_3d->find_bone(track_node_path.get_subname(0));
|
|
||||||
if (bone_idx != -1) {
|
|
||||||
position_track_value->bone_idx = bone_idx;
|
|
||||||
}
|
|
||||||
animation->try_position_track_interpolate(i, p_time, &position_track_value->position);
|
|
||||||
} else {
|
|
||||||
// TODO
|
|
||||||
assert(false && !"Not yet implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
track_value = position_track_value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Animation::TYPE_ROTATION_3D: {
|
case Animation::TYPE_ROTATION_3D: {
|
||||||
AnimationData::RotationTrackValue *rotation_track_value = memnew(AnimationData::RotationTrackValue);
|
TransformTrackValue *transform_track_value = nullptr;
|
||||||
|
if (track_values.has(animation_track->thash)) {
|
||||||
|
transform_track_value = static_cast<TransformTrackValue *>(track_values[animation_track->thash]);
|
||||||
|
} else {
|
||||||
|
transform_track_value = memnew(AnimationData::TransformTrackValue);
|
||||||
|
}
|
||||||
|
int bone_idx = -1;
|
||||||
|
|
||||||
if (track_node_path.get_subname_count() == 1) {
|
if (track_node_path.get_subname_count() == 1) {
|
||||||
int bone_idx = skeleton_3d->find_bone(track_node_path.get_subname(0));
|
bone_idx = skeleton_3d->find_bone(track_node_path.get_subname(0));
|
||||||
if (bone_idx != -1) {
|
if (bone_idx != -1) {
|
||||||
rotation_track_value->bone_idx = bone_idx;
|
transform_track_value->bone_idx = bone_idx;
|
||||||
|
switch (ttype) {
|
||||||
|
case Animation::TYPE_POSITION_3D: {
|
||||||
|
animation->try_position_track_interpolate(i, p_time, &transform_track_value->loc);
|
||||||
|
transform_track_value->loc_used = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Animation::TYPE_ROTATION_3D: {
|
||||||
|
animation->try_rotation_track_interpolate(i, p_time, &transform_track_value->rot);
|
||||||
|
transform_track_value->rot_used = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
assert(false && !"Not yet implemented");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
animation->try_rotation_track_interpolate(i, p_time, &rotation_track_value->rotation);
|
|
||||||
} else {
|
} else {
|
||||||
// TODO
|
// TODO
|
||||||
assert(false && !"Not yet implemented");
|
assert(false && !"Not yet implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
track_value = rotation_track_value;
|
track_value = transform_track_value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
|||||||
@ -51,68 +51,65 @@ struct AnimationData {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PositionTrackValue : public TrackValue {
|
struct TransformTrackValue : public TrackValue {
|
||||||
int bone_idx = -1;
|
int bone_idx = -1;
|
||||||
Vector3 position = Vector3(0, 0, 0);
|
|
||||||
PositionTrackValue() { type = TYPE_POSITION_3D; }
|
|
||||||
|
|
||||||
void blend(const TrackValue &to_value, const float lambda) override {
|
bool loc_used = false;
|
||||||
const PositionTrackValue *to_value_casted = &static_cast<const PositionTrackValue &>(to_value);
|
bool rot_used = false;
|
||||||
assert(bone_idx == to_value_casted->bone_idx);
|
bool scale_used = false;
|
||||||
position = (1. - lambda) * position + lambda * to_value_casted->position;
|
Vector3 init_loc = Vector3(0, 0, 0);
|
||||||
}
|
Quaternion init_rot = Quaternion(0, 0, 0, 1);
|
||||||
|
Vector3 init_scale = Vector3(1, 1, 1);
|
||||||
bool operator==(const TrackValue &other_value) const override {
|
Vector3 loc;
|
||||||
if (type != other_value.type) {
|
Quaternion rot;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const PositionTrackValue *other_value_casted = &static_cast<const PositionTrackValue &>(other_value);
|
|
||||||
return bone_idx == other_value_casted->bone_idx && position == other_value_casted->position;
|
|
||||||
}
|
|
||||||
|
|
||||||
TrackValue *clone() const override {
|
|
||||||
PositionTrackValue *result = memnew(PositionTrackValue);
|
|
||||||
result->track = track;
|
|
||||||
result->bone_idx = bone_idx;
|
|
||||||
result->position = position;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RotationTrackValue : public TrackValue {
|
|
||||||
int bone_idx = -1;
|
|
||||||
Quaternion rotation = Quaternion(0, 0, 0, 1);
|
|
||||||
RotationTrackValue() { type = TYPE_ROTATION_3D; }
|
|
||||||
|
|
||||||
void blend(const TrackValue &to_value, const float lambda) override {
|
|
||||||
const RotationTrackValue *to_value_casted = &static_cast<const RotationTrackValue &>(to_value);
|
|
||||||
assert(bone_idx == to_value_casted->bone_idx);
|
|
||||||
rotation = rotation.slerp(to_value_casted->rotation, lambda);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const TrackValue &other_value) const override {
|
|
||||||
if (type != other_value.type) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const RotationTrackValue *other_value_casted = &static_cast<const RotationTrackValue &>(other_value);
|
|
||||||
return bone_idx == other_value_casted->bone_idx && rotation == other_value_casted->rotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
TrackValue *clone() const override {
|
|
||||||
RotationTrackValue *result = memnew(RotationTrackValue);
|
|
||||||
result->track = track;
|
|
||||||
result->bone_idx = bone_idx;
|
|
||||||
result->rotation = rotation;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ScaleTrackValue : public TrackValue {
|
|
||||||
int bone_idx = -1;
|
|
||||||
Vector3 scale;
|
Vector3 scale;
|
||||||
ScaleTrackValue() { type = TYPE_SCALE_3D; }
|
|
||||||
|
TransformTrackValue() { type = TYPE_POSITION_3D; }
|
||||||
|
|
||||||
|
void blend(const TrackValue &to_value, const float lambda) override {
|
||||||
|
const TransformTrackValue *to_value_casted = &static_cast<const TransformTrackValue &>(to_value);
|
||||||
|
assert(bone_idx == to_value_casted->bone_idx);
|
||||||
|
if (loc_used) {
|
||||||
|
loc = (1. - lambda) * loc + lambda * to_value_casted->loc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rot_used) {
|
||||||
|
rot = rot.slerp(to_value_casted->rot, lambda);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scale_used) {
|
||||||
|
scale = (1. - lambda) * scale + lambda * to_value_casted->scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const TrackValue &other_value) const override {
|
||||||
|
if (type != other_value.type) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TransformTrackValue *other_value_casted = &static_cast<const TransformTrackValue &>(other_value);
|
||||||
|
return bone_idx == other_value_casted->bone_idx && loc == other_value_casted->loc && rot == other_value_casted->rot && scale == other_value_casted->scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
TrackValue *clone() const override {
|
||||||
|
TransformTrackValue *result = memnew(TransformTrackValue);
|
||||||
|
result->track = track;
|
||||||
|
result->bone_idx = bone_idx;
|
||||||
|
|
||||||
|
result->loc_used = loc_used;
|
||||||
|
result->rot_used = rot_used;
|
||||||
|
result->scale_used = scale_used;
|
||||||
|
|
||||||
|
result->init_loc = init_loc;
|
||||||
|
result->init_rot = init_rot;
|
||||||
|
result->init_scale = init_scale;
|
||||||
|
|
||||||
|
result->loc = loc;
|
||||||
|
result->rot = rot;
|
||||||
|
result->scale = scale;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
AnimationData() = default;
|
AnimationData() = default;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user