فهرست منبع

Added more hacks to GLTF2 importer to support crap exporter (MakeHuman in this case), fixes #13393

Juan Linietsky 7 سال پیش
والد
کامیت
f11a138505
3فایلهای تغییر یافته به همراه171 افزوده شده و 151 حذف شده
  1. 147 135
      editor/import/editor_scene_importer_gltf.cpp
  2. 24 15
      editor/import/editor_scene_importer_gltf.h
  3. 0 1
      scene/3d/skeleton.cpp

+ 147 - 135
editor/import/editor_scene_importer_gltf.cpp

@@ -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);
-	}
-	skeletons[n->joint_skin]->set_bone_rest(bone_index, state.skins[n->joint_skin].bones[n->joint_bone].inverse_bind.affine_inverse());
+		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_node = skeletons[n->joint_skin];
-	n->godot_bone_index = bone_index;
+		n->godot_nodes.push_back(skeletons[n->joints[i].skin]);
+		n->joints[i].godot_bone_index = bone_index;
+		parent_bones.push_back(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);
-
-		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 < node->godot_nodes.size(); i++) {
 
-		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]);
+			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 {
+				node_path = ap->get_parent()->get_path_to(node->godot_nodes[i]);
 			}
-		}
-
-		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;
+			float length = 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;
+			for (int i = 0; i < track.rotation_track.times.size(); i++) {
+				length = MAX(length, track.rotation_track.times[i]);
 			}
-
-			if (!track.translation_track.values.size()) {
-				base_pos = state.nodes[E->key()]->translation;
+			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]);
 			}
 
-			if (!track.scale_track.values.size()) {
-				base_scale = state.nodes[E->key()]->scale;
+			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]);
+				}
 			}
 
-			bool last = false;
-			while (true) {
+			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
 
-				Vector3 pos = base_pos;
-				Quat rot = base_rot;
-				Vector3 scale = base_scale;
+				float increment = 1.0 / float(bake_fps);
+				float time = 0.0;
 
-				if (track.translation_track.times.size()) {
+				Vector3 base_pos;
+				Quat base_rot;
+				Vector3 base_scale = Vector3(1, 1, 1);
 
-					pos = _interpolate_track<Vector3>(track.translation_track.times, track.translation_track.values, time, track.translation_track.interpolation);
+				if (!track.rotation_track.values.size()) {
+					base_rot = state.nodes[E->key()]->rotation;
 				}
 
-				if (track.rotation_track.times.size()) {
+				if (!track.translation_track.values.size()) {
+					base_pos = state.nodes[E->key()]->translation;
+				}
 
-					rot = _interpolate_track<Quat>(track.rotation_track.times, track.rotation_track.values, time, track.rotation_track.interpolation);
+				if (!track.scale_track.values.size()) {
+					base_scale = state.nodes[E->key()]->scale;
 				}
 
-				if (track.scale_track.times.size()) {
+				bool last = false;
+				while (true) {
 
-					scale = _interpolate_track<Vector3>(track.scale_track.times, track.scale_track.values, time, track.scale_track.interpolation);
-				}
+					Vector3 pos = base_pos;
+					Quat rot = base_rot;
+					Vector3 scale = base_scale;
 
-				if (node->godot_bone_index >= 0) {
+					if (track.translation_track.times.size()) {
 
-					Transform xform;
-					xform.basis = Basis(rot);
-					xform.basis.scale(scale);
-					xform.origin = pos;
+						pos = _interpolate_track<Vector3>(track.translation_track.times, track.translation_track.values, time, track.translation_track.interpolation);
+					}
 
-					Skeleton *skeleton = skeletons[node->joint_skin];
-					int bone = node->godot_bone_index;
-					xform = skeleton->get_bone_rest(bone).affine_inverse() * xform;
+					if (track.rotation_track.times.size()) {
 
-					rot = xform.basis;
-					rot.normalize();
-					scale = xform.basis.get_scale();
-					pos = xform.origin;
-				}
+						rot = _interpolate_track<Quat>(track.rotation_track.times, track.rotation_track.values, time, track.rotation_track.interpolation);
+					}
 
-				animation->transform_track_insert_key(track_idx, time, pos, rot, scale);
+					if (track.scale_track.times.size()) {
 
-				if (last) {
-					break;
-				}
-				time += increment;
-				if (time >= length) {
-					last = true;
-					time = length;
-				}
-			}
-		}
+						scale = _interpolate_track<Vector3>(track.scale_track.times, track.scale_track.values, time, track.scale_track.interpolation);
+					}
 
-		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;
+					if (node->joints.size()) {
 
-			int track_idx = animation->get_track_count();
-			animation->add_track(Animation::TYPE_VALUE);
-			animation->track_set_path(track_idx, node_path);
+						Transform xform;
+						xform.basis = Basis(rot);
+						xform.basis.scale(scale);
+						xform.origin = pos;
 
-			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;
+						Skeleton *skeleton = skeletons[node->joints[i].skin];
+						int bone = node->joints[i].godot_bone_index;
+						xform = skeleton->get_bone_rest(bone).affine_inverse() * xform;
 
-				bool last = false;
-				while (true) {
+						rot = xform.basis;
+						rot.normalize();
+						scale = xform.basis.get_scale();
+						pos = xform.origin;
+					}
+
+					animation->transform_track_insert_key(track_idx, time, pos, rot, scale);
 
-					_interpolate_track<float>(track.weight_tracks[i].times, track.weight_tracks[i].values, time, track.weight_tracks[i].interpolation);
 					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);
 		}

+ 24 - 15
editor/import/editor_scene_importer_gltf.h

@@ -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
+
+		struct Joint {
+			int skin;
+			int bone;
+			int godot_bone_index;
+
+			Joint() {
+				skin = -1;
+				bone = -1;
+				godot_bone_index = -1;
+			}
+		};
 
-		int joint_skin;
-		int joint_bone;
+		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);
 

+ 0 - 1
scene/3d/skeleton.cpp

@@ -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()) {