Added more hacks to GLTF2 importer to support crap exporter (MakeHuman in this case), fixes #13393
This commit is contained in:
parent
7f1265b41f
commit
f11a138505
3 changed files with 192 additions and 172 deletions
|
@ -185,11 +185,13 @@ Error EditorSceneImporterGLTF::_parse_nodes(GLTFState &state) {
|
|||
}
|
||||
if (n.has("skin")) {
|
||||
node->skin = n["skin"];
|
||||
/*
|
||||
if (!state.skin_users.has(node->skin)) {
|
||||
state.skin_users[node->skin] = Vector<int>();
|
||||
}
|
||||
|
||||
state.skin_users[node->skin].push_back(i);
|
||||
*/
|
||||
}
|
||||
if (n.has("matrix")) {
|
||||
node->xform = _arr_to_xform(n["matrix"]);
|
||||
|
@ -1316,8 +1318,10 @@ Error EditorSceneImporterGLTF::_parse_skins(GLTFState &state) {
|
|||
for (int j = 0; j < joints.size(); j++) {
|
||||
int index = joints[j];
|
||||
ERR_FAIL_INDEX_V(index, state.nodes.size(), ERR_PARSE_ERROR);
|
||||
state.nodes[index]->joint_skin = state.skins.size();
|
||||
state.nodes[index]->joint_bone = j;
|
||||
GLTFNode::Joint joint;
|
||||
joint.skin = state.skins.size();
|
||||
joint.bone = j;
|
||||
state.nodes[index]->joints.push_back(joint);
|
||||
GLTFSkin::Bone bone;
|
||||
bone.node = index;
|
||||
if (bind_matrices.size()) {
|
||||
|
@ -1331,7 +1335,7 @@ Error EditorSceneImporterGLTF::_parse_skins(GLTFState &state) {
|
|||
if (d.has("skeleton")) {
|
||||
int skeleton = d["skeleton"];
|
||||
ERR_FAIL_INDEX_V(skeleton, state.nodes.size(), ERR_PARSE_ERROR);
|
||||
state.nodes[skeleton]->skeleton_skin = state.skins.size();
|
||||
//state.nodes[skeleton]->skeleton_skin = state.skins.size();
|
||||
print_line("setting skeleton skin to" + itos(skeleton));
|
||||
skin.skeleton = skeleton;
|
||||
}
|
||||
|
@ -1341,7 +1345,7 @@ Error EditorSceneImporterGLTF::_parse_skins(GLTFState &state) {
|
|||
}
|
||||
|
||||
//locate the right place to put a Skeleton node
|
||||
|
||||
/*
|
||||
if (state.skin_users.has(i)) {
|
||||
Vector<int> users = state.skin_users[i];
|
||||
int skin_node = -1;
|
||||
|
@ -1382,6 +1386,7 @@ Error EditorSceneImporterGLTF::_parse_skins(GLTFState &state) {
|
|||
state.nodes[skin_node]->skeleton_children.push_back(i);
|
||||
}
|
||||
}
|
||||
*/
|
||||
state.skins.push_back(skin);
|
||||
}
|
||||
print_line("total skins: " + itos(state.skins.size()));
|
||||
|
@ -1577,7 +1582,7 @@ void EditorSceneImporterGLTF::_assign_scene_names(GLTFState &state) {
|
|||
if (n->name == "") {
|
||||
if (n->mesh >= 0) {
|
||||
n->name = "Mesh";
|
||||
} else if (n->joint_skin >= 0) {
|
||||
} else if (n->joints.size()) {
|
||||
n->name = "Bone";
|
||||
} else {
|
||||
n->name = "Node";
|
||||
|
@ -1607,6 +1612,7 @@ void EditorSceneImporterGLTF::_generate_node(GLTFState &state, int p_node, Node
|
|||
}
|
||||
|
||||
node = mi;
|
||||
|
||||
} else if (n->camera >= 0) {
|
||||
ERR_FAIL_INDEX(n->camera, state.cameras.size());
|
||||
Camera *camera = memnew(Camera);
|
||||
|
@ -1625,18 +1631,20 @@ void EditorSceneImporterGLTF::_generate_node(GLTFState &state, int p_node, Node
|
|||
|
||||
node->set_name(n->name);
|
||||
|
||||
if (n->child_of_skeleton >= 0) {
|
||||
//move skeleton around and place it on node, as the node _is_ a skeleton.
|
||||
Skeleton *s = skeletons[n->child_of_skeleton];
|
||||
p_parent = s;
|
||||
}
|
||||
|
||||
p_parent->add_child(node);
|
||||
node->set_owner(p_owner);
|
||||
node->set_transform(n->xform);
|
||||
|
||||
n->godot_node = node;
|
||||
n->godot_nodes.push_back(node);
|
||||
|
||||
if (n->skin >= 0 && Object::cast_to<MeshInstance>(node)) {
|
||||
MeshInstance *mi = Object::cast_to<MeshInstance>(node);
|
||||
//move skeleton around and place it on node, as the node _is_ a skeleton.
|
||||
Skeleton *s = skeletons[n->skin];
|
||||
mi->set_skeleton_path(mi->get_path_to(s));
|
||||
}
|
||||
|
||||
#if 0
|
||||
for (int i = 0; i < n->skeleton_children.size(); i++) {
|
||||
|
||||
Skeleton *s = skeletons[n->skeleton_children[i]];
|
||||
|
@ -1644,36 +1652,39 @@ void EditorSceneImporterGLTF::_generate_node(GLTFState &state, int p_node, Node
|
|||
node->add_child(s);
|
||||
s->set_owner(p_owner);
|
||||
}
|
||||
|
||||
#endif
|
||||
for (int i = 0; i < n->children.size(); i++) {
|
||||
if (state.nodes[n->children[i]]->joint_skin >= 0) {
|
||||
_generate_bone(state, n->children[i], skeletons, -1);
|
||||
if (state.nodes[n->children[i]]->joints.size()) {
|
||||
_generate_bone(state, n->children[i], skeletons, Vector<int>());
|
||||
} else {
|
||||
_generate_node(state, n->children[i], node, p_owner, skeletons);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EditorSceneImporterGLTF::_generate_bone(GLTFState &state, int p_node, Vector<Skeleton *> &skeletons, int p_parent_bone) {
|
||||
void EditorSceneImporterGLTF::_generate_bone(GLTFState &state, int p_node, Vector<Skeleton *> &skeletons, const Vector<int> &p_parent_bones) {
|
||||
ERR_FAIL_INDEX(p_node, state.nodes.size());
|
||||
|
||||
GLTFNode *n = state.nodes[p_node];
|
||||
Vector<int> parent_bones;
|
||||
|
||||
ERR_FAIL_COND(n->joint_skin < 0);
|
||||
for (int i = 0; i < n->joints.size(); i++) {
|
||||
ERR_FAIL_COND(n->joints[i].skin < 0);
|
||||
|
||||
int bone_index = skeletons[n->joint_skin]->get_bone_count();
|
||||
skeletons[n->joint_skin]->add_bone(n->name);
|
||||
if (p_parent_bone >= 0) {
|
||||
skeletons[n->joint_skin]->set_bone_parent(bone_index, p_parent_bone);
|
||||
int bone_index = skeletons[n->joints[i].skin]->get_bone_count();
|
||||
skeletons[n->joints[i].skin]->add_bone(n->name);
|
||||
if (p_parent_bones.size()) {
|
||||
skeletons[n->joints[i].skin]->set_bone_parent(bone_index, p_parent_bones[i]);
|
||||
}
|
||||
skeletons[n->joints[i].skin]->set_bone_rest(bone_index, state.skins[n->joints[i].skin].bones[n->joints[i].bone].inverse_bind.affine_inverse());
|
||||
|
||||
n->godot_nodes.push_back(skeletons[n->joints[i].skin]);
|
||||
n->joints[i].godot_bone_index = bone_index;
|
||||
parent_bones.push_back(bone_index);
|
||||
}
|
||||
skeletons[n->joint_skin]->set_bone_rest(bone_index, state.skins[n->joint_skin].bones[n->joint_bone].inverse_bind.affine_inverse());
|
||||
|
||||
n->godot_node = skeletons[n->joint_skin];
|
||||
n->godot_bone_index = bone_index;
|
||||
|
||||
for (int i = 0; i < n->children.size(); i++) {
|
||||
ERR_CONTINUE(state.nodes[n->children[i]]->joint_skin < 0);
|
||||
_generate_bone(state, n->children[i], skeletons, bone_index);
|
||||
_generate_bone(state, n->children[i], skeletons, parent_bones);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1818,141 +1829,104 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye
|
|||
NodePath node_path;
|
||||
|
||||
GLTFNode *node = state.nodes[E->key()];
|
||||
ERR_CONTINUE(!node->godot_node);
|
||||
for (int i = 0; i < node->godot_nodes.size(); i++) {
|
||||
|
||||
if (node->godot_bone_index >= 0) {
|
||||
Skeleton *sk = (Skeleton *)node->godot_node;
|
||||
String path = ap->get_parent()->get_path_to(sk);
|
||||
String bone = sk->get_bone_name(node->godot_bone_index);
|
||||
node_path = path + ":" + bone;
|
||||
} else {
|
||||
node_path = ap->get_parent()->get_path_to(node->godot_node);
|
||||
}
|
||||
|
||||
float length = 0;
|
||||
|
||||
for (int i = 0; i < track.rotation_track.times.size(); i++) {
|
||||
length = MAX(length, track.rotation_track.times[i]);
|
||||
}
|
||||
for (int i = 0; i < track.translation_track.times.size(); i++) {
|
||||
length = MAX(length, track.translation_track.times[i]);
|
||||
}
|
||||
for (int i = 0; i < track.scale_track.times.size(); i++) {
|
||||
length = MAX(length, track.scale_track.times[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < track.weight_tracks.size(); i++) {
|
||||
for (int j = 0; j < track.weight_tracks[i].times.size(); j++) {
|
||||
length = MAX(length, track.weight_tracks[i].times[j]);
|
||||
}
|
||||
}
|
||||
|
||||
animation->set_length(length);
|
||||
|
||||
if (track.rotation_track.values.size() || track.translation_track.values.size() || track.scale_track.values.size()) {
|
||||
//make transform track
|
||||
int track_idx = animation->get_track_count();
|
||||
animation->add_track(Animation::TYPE_TRANSFORM);
|
||||
animation->track_set_path(track_idx, node_path);
|
||||
//first determine animation length
|
||||
|
||||
float increment = 1.0 / float(bake_fps);
|
||||
float time = 0.0;
|
||||
|
||||
Vector3 base_pos;
|
||||
Quat base_rot;
|
||||
Vector3 base_scale = Vector3(1, 1, 1);
|
||||
|
||||
if (!track.rotation_track.values.size()) {
|
||||
base_rot = state.nodes[E->key()]->rotation;
|
||||
}
|
||||
|
||||
if (!track.translation_track.values.size()) {
|
||||
base_pos = state.nodes[E->key()]->translation;
|
||||
}
|
||||
|
||||
if (!track.scale_track.values.size()) {
|
||||
base_scale = state.nodes[E->key()]->scale;
|
||||
}
|
||||
|
||||
bool last = false;
|
||||
while (true) {
|
||||
|
||||
Vector3 pos = base_pos;
|
||||
Quat rot = base_rot;
|
||||
Vector3 scale = base_scale;
|
||||
|
||||
if (track.translation_track.times.size()) {
|
||||
|
||||
pos = _interpolate_track<Vector3>(track.translation_track.times, track.translation_track.values, time, track.translation_track.interpolation);
|
||||
}
|
||||
|
||||
if (track.rotation_track.times.size()) {
|
||||
|
||||
rot = _interpolate_track<Quat>(track.rotation_track.times, track.rotation_track.values, time, track.rotation_track.interpolation);
|
||||
}
|
||||
|
||||
if (track.scale_track.times.size()) {
|
||||
|
||||
scale = _interpolate_track<Vector3>(track.scale_track.times, track.scale_track.values, time, track.scale_track.interpolation);
|
||||
}
|
||||
|
||||
if (node->godot_bone_index >= 0) {
|
||||
|
||||
Transform xform;
|
||||
xform.basis = Basis(rot);
|
||||
xform.basis.scale(scale);
|
||||
xform.origin = pos;
|
||||
|
||||
Skeleton *skeleton = skeletons[node->joint_skin];
|
||||
int bone = node->godot_bone_index;
|
||||
xform = skeleton->get_bone_rest(bone).affine_inverse() * xform;
|
||||
|
||||
rot = xform.basis;
|
||||
rot.normalize();
|
||||
scale = xform.basis.get_scale();
|
||||
pos = xform.origin;
|
||||
}
|
||||
|
||||
animation->transform_track_insert_key(track_idx, time, pos, rot, scale);
|
||||
|
||||
if (last) {
|
||||
break;
|
||||
}
|
||||
time += increment;
|
||||
if (time >= length) {
|
||||
last = true;
|
||||
time = length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < track.weight_tracks.size(); i++) {
|
||||
ERR_CONTINUE(node->mesh < 0 || node->mesh >= state.meshes.size());
|
||||
const GLTFMesh &mesh = state.meshes[node->mesh];
|
||||
String prop = "blend_shapes/" + mesh.mesh->get_blend_shape_name(i);
|
||||
node_path = String(node_path) + ":" + prop;
|
||||
|
||||
int track_idx = animation->get_track_count();
|
||||
animation->add_track(Animation::TYPE_VALUE);
|
||||
animation->track_set_path(track_idx, node_path);
|
||||
|
||||
if (track.weight_tracks[i].interpolation <= GLTFAnimation::INTERP_STEP) {
|
||||
animation->track_set_interpolation_type(track_idx, track.weight_tracks[i].interpolation == GLTFAnimation::INTERP_STEP ? Animation::INTERPOLATION_NEAREST : Animation::INTERPOLATION_NEAREST);
|
||||
for (int j = 0; j < track.weight_tracks[i].times.size(); j++) {
|
||||
float t = track.weight_tracks[i].times[j];
|
||||
float w = track.weight_tracks[i].values[j];
|
||||
animation->track_insert_key(track_idx, t, w);
|
||||
}
|
||||
if (node->joints.size()) {
|
||||
Skeleton *sk = (Skeleton *)node->godot_nodes[i];
|
||||
String path = ap->get_parent()->get_path_to(sk);
|
||||
String bone = sk->get_bone_name(node->joints[i].godot_bone_index);
|
||||
node_path = path + ":" + bone;
|
||||
} else {
|
||||
//must bake, apologies.
|
||||
node_path = ap->get_parent()->get_path_to(node->godot_nodes[i]);
|
||||
}
|
||||
|
||||
float length = 0;
|
||||
|
||||
for (int i = 0; i < track.rotation_track.times.size(); i++) {
|
||||
length = MAX(length, track.rotation_track.times[i]);
|
||||
}
|
||||
for (int i = 0; i < track.translation_track.times.size(); i++) {
|
||||
length = MAX(length, track.translation_track.times[i]);
|
||||
}
|
||||
for (int i = 0; i < track.scale_track.times.size(); i++) {
|
||||
length = MAX(length, track.scale_track.times[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < track.weight_tracks.size(); i++) {
|
||||
for (int j = 0; j < track.weight_tracks[i].times.size(); j++) {
|
||||
length = MAX(length, track.weight_tracks[i].times[j]);
|
||||
}
|
||||
}
|
||||
|
||||
animation->set_length(length);
|
||||
|
||||
if (track.rotation_track.values.size() || track.translation_track.values.size() || track.scale_track.values.size()) {
|
||||
//make transform track
|
||||
int track_idx = animation->get_track_count();
|
||||
animation->add_track(Animation::TYPE_TRANSFORM);
|
||||
animation->track_set_path(track_idx, node_path);
|
||||
//first determine animation length
|
||||
|
||||
float increment = 1.0 / float(bake_fps);
|
||||
float time = 0.0;
|
||||
|
||||
Vector3 base_pos;
|
||||
Quat base_rot;
|
||||
Vector3 base_scale = Vector3(1, 1, 1);
|
||||
|
||||
if (!track.rotation_track.values.size()) {
|
||||
base_rot = state.nodes[E->key()]->rotation;
|
||||
}
|
||||
|
||||
if (!track.translation_track.values.size()) {
|
||||
base_pos = state.nodes[E->key()]->translation;
|
||||
}
|
||||
|
||||
if (!track.scale_track.values.size()) {
|
||||
base_scale = state.nodes[E->key()]->scale;
|
||||
}
|
||||
|
||||
bool last = false;
|
||||
while (true) {
|
||||
|
||||
_interpolate_track<float>(track.weight_tracks[i].times, track.weight_tracks[i].values, time, track.weight_tracks[i].interpolation);
|
||||
Vector3 pos = base_pos;
|
||||
Quat rot = base_rot;
|
||||
Vector3 scale = base_scale;
|
||||
|
||||
if (track.translation_track.times.size()) {
|
||||
|
||||
pos = _interpolate_track<Vector3>(track.translation_track.times, track.translation_track.values, time, track.translation_track.interpolation);
|
||||
}
|
||||
|
||||
if (track.rotation_track.times.size()) {
|
||||
|
||||
rot = _interpolate_track<Quat>(track.rotation_track.times, track.rotation_track.values, time, track.rotation_track.interpolation);
|
||||
}
|
||||
|
||||
if (track.scale_track.times.size()) {
|
||||
|
||||
scale = _interpolate_track<Vector3>(track.scale_track.times, track.scale_track.values, time, track.scale_track.interpolation);
|
||||
}
|
||||
|
||||
if (node->joints.size()) {
|
||||
|
||||
Transform xform;
|
||||
xform.basis = Basis(rot);
|
||||
xform.basis.scale(scale);
|
||||
xform.origin = pos;
|
||||
|
||||
Skeleton *skeleton = skeletons[node->joints[i].skin];
|
||||
int bone = node->joints[i].godot_bone_index;
|
||||
xform = skeleton->get_bone_rest(bone).affine_inverse() * xform;
|
||||
|
||||
rot = xform.basis;
|
||||
rot.normalize();
|
||||
scale = xform.basis.get_scale();
|
||||
pos = xform.origin;
|
||||
}
|
||||
|
||||
animation->transform_track_insert_key(track_idx, time, pos, rot, scale);
|
||||
|
||||
if (last) {
|
||||
break;
|
||||
}
|
||||
|
@ -1963,6 +1937,44 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < track.weight_tracks.size(); i++) {
|
||||
ERR_CONTINUE(node->mesh < 0 || node->mesh >= state.meshes.size());
|
||||
const GLTFMesh &mesh = state.meshes[node->mesh];
|
||||
String prop = "blend_shapes/" + mesh.mesh->get_blend_shape_name(i);
|
||||
node_path = String(node_path) + ":" + prop;
|
||||
|
||||
int track_idx = animation->get_track_count();
|
||||
animation->add_track(Animation::TYPE_VALUE);
|
||||
animation->track_set_path(track_idx, node_path);
|
||||
|
||||
if (track.weight_tracks[i].interpolation <= GLTFAnimation::INTERP_STEP) {
|
||||
animation->track_set_interpolation_type(track_idx, track.weight_tracks[i].interpolation == GLTFAnimation::INTERP_STEP ? Animation::INTERPOLATION_NEAREST : Animation::INTERPOLATION_NEAREST);
|
||||
for (int j = 0; j < track.weight_tracks[i].times.size(); j++) {
|
||||
float t = track.weight_tracks[i].times[j];
|
||||
float w = track.weight_tracks[i].values[j];
|
||||
animation->track_insert_key(track_idx, t, w);
|
||||
}
|
||||
} else {
|
||||
//must bake, apologies.
|
||||
float increment = 1.0 / float(bake_fps);
|
||||
float time = 0.0;
|
||||
|
||||
bool last = false;
|
||||
while (true) {
|
||||
|
||||
_interpolate_track<float>(track.weight_tracks[i].times, track.weight_tracks[i].values, time, track.weight_tracks[i].interpolation);
|
||||
if (last) {
|
||||
break;
|
||||
}
|
||||
time += increment;
|
||||
if (time >= length) {
|
||||
last = true;
|
||||
time = length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1987,8 +1999,8 @@ Spatial *EditorSceneImporterGLTF::_generate_scene(GLTFState &state, int p_bake_f
|
|||
skeletons.push_back(s);
|
||||
}
|
||||
for (int i = 0; i < state.root_nodes.size(); i++) {
|
||||
if (state.nodes[state.root_nodes[i]]->joint_skin >= 0) {
|
||||
_generate_bone(state, state.root_nodes[i], skeletons, -1);
|
||||
if (state.nodes[state.root_nodes[i]]->joints.size()) {
|
||||
_generate_bone(state, state.root_nodes[i], skeletons, Vector<int>());
|
||||
} else {
|
||||
_generate_node(state, state.root_nodes[i], root, root, skeletons);
|
||||
}
|
||||
|
|
|
@ -52,18 +52,29 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
|
|||
|
||||
Transform xform;
|
||||
String name;
|
||||
Node *godot_node;
|
||||
int godot_bone_index;
|
||||
//Node *godot_node;
|
||||
//int godot_bone_index;
|
||||
|
||||
int mesh;
|
||||
int camera;
|
||||
int skin;
|
||||
int skeleton_skin;
|
||||
int child_of_skeleton; // put as children of skeleton
|
||||
Vector<int> skeleton_children; //skeleton put as children of this
|
||||
//int skeleton_skin;
|
||||
//int child_of_skeleton; // put as children of skeleton
|
||||
//Vector<int> skeleton_children; //skeleton put as children of this
|
||||
|
||||
int joint_skin;
|
||||
int joint_bone;
|
||||
struct Joint {
|
||||
int skin;
|
||||
int bone;
|
||||
int godot_bone_index;
|
||||
|
||||
Joint() {
|
||||
skin = -1;
|
||||
bone = -1;
|
||||
godot_bone_index = -1;
|
||||
}
|
||||
};
|
||||
|
||||
Vector<Joint> joints;
|
||||
|
||||
//keep them for animation
|
||||
Vector3 translation;
|
||||
|
@ -71,17 +82,15 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
|
|||
Vector3 scale;
|
||||
|
||||
Vector<int> children;
|
||||
Vector<Node *> godot_nodes;
|
||||
|
||||
GLTFNode() {
|
||||
godot_node = NULL;
|
||||
godot_bone_index = -1;
|
||||
joint_skin = -1;
|
||||
joint_bone = -1;
|
||||
child_of_skeleton = -1;
|
||||
skeleton_skin = -1;
|
||||
// child_of_skeleton = -1;
|
||||
// skeleton_skin = -1;
|
||||
mesh = -1;
|
||||
camera = -1;
|
||||
parent = -1;
|
||||
skin = -1;
|
||||
scale = Vector3(1, 1, 1);
|
||||
}
|
||||
};
|
||||
|
@ -235,7 +244,7 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
|
|||
|
||||
Vector<GLTFAnimation> animations;
|
||||
|
||||
Map<int, Vector<int> > skin_users; //cache skin users
|
||||
//Map<int, Vector<int> > skin_users; //cache skin users
|
||||
|
||||
~GLTFState() {
|
||||
for (int i = 0; i < nodes.size(); i++) {
|
||||
|
@ -269,7 +278,7 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
|
|||
Vector<Basis> _decode_accessor_as_basis(GLTFState &state, int p_accessor, bool p_for_vertex);
|
||||
Vector<Transform> _decode_accessor_as_xform(GLTFState &state, int p_accessor, bool p_for_vertex);
|
||||
|
||||
void _generate_bone(GLTFState &state, int p_node, Vector<Skeleton *> &skeletons, int p_parent_bone);
|
||||
void _generate_bone(GLTFState &state, int p_node, Vector<Skeleton *> &skeletons, const Vector<int> &p_parent_bones);
|
||||
void _generate_node(GLTFState &state, int p_node, Node *p_parent, Node *p_owner, Vector<Skeleton *> &skeletons);
|
||||
void _import_animation(GLTFState &state, AnimationPlayer *ap, int index, int bake_fps, Vector<Skeleton *> skeletons);
|
||||
|
||||
|
|
|
@ -243,7 +243,6 @@ void Skeleton::_notification(int p_what) {
|
|||
}
|
||||
|
||||
Transform transform = b.pose_global * b.rest_global_inverse;
|
||||
|
||||
vs->skeleton_bone_set_transform(skeleton, i, global_transform * (transform * global_transform_inverse));
|
||||
|
||||
for (List<uint32_t>::Element *E = b.nodes_bound.front(); E; E = E->next()) {
|
||||
|
|
Loading…
Reference in a new issue