Pārlūkot izejas kodu

tools: import full node hierarchy from .mesh files

Daniele Bartolini 5 gadi atpakaļ
vecāks
revīzija
167a8e4398
1 mainītis faili ar 136 papildinājumiem un 70 dzēšanām
  1. 136 70
      tools/level_editor/project.vala

+ 136 - 70
tools/level_editor/project.vala

@@ -796,6 +796,126 @@ public class Project
 		return 0;
 	}
 
+	public void create_components(Database db, Guid parent_unit_id, Guid unit_id, string material_name, string resource_name, string node_name, Hashtable node)
+	{
+		Unit unit = new Unit(db, unit_id, null);
+
+		Matrix4x4 matrix_local = Matrix4x4.from_array((ArrayList<Value?>)node["matrix_local"]);
+		Vector3 position = matrix_local.t.to_vector3();
+		Quaternion rotation = matrix_local.rotation();
+		Vector3 scale = matrix_local.scale();
+
+		// Create transform
+		{
+			Guid component_id;
+			if (unit.has_component(out component_id, "transform"))
+			{
+				unit.set_component_property_vector3   (component_id, "data.position", position);
+				unit.set_component_property_quaternion(component_id, "data.rotation", rotation);
+				unit.set_component_property_vector3   (component_id, "data.scale", scale);
+				unit.set_component_property_string    (component_id, "type", "transform");
+			}
+			else
+			{
+				component_id = Guid.new_guid();
+				db.create(component_id);
+				db.set_property_vector3   (component_id, "data.position", position);
+				db.set_property_quaternion(component_id, "data.rotation", rotation);
+				db.set_property_vector3   (component_id, "data.scale", scale);
+				db.set_property_string    (component_id, "type", "transform");
+
+				db.add_to_set(unit_id, "components", component_id);
+			}
+		}
+
+		// Create mesh_renderer
+		{
+			Guid component_id;
+			if (unit.has_component(out component_id, "mesh_renderer"))
+			{
+				unit.set_component_property_string(component_id, "data.geometry_name", node_name);
+				unit.set_component_property_string(component_id, "data.material", material_name);
+				unit.set_component_property_string(component_id, "data.mesh_resource", resource_name);
+				unit.set_component_property_bool  (component_id, "data.visible", true);
+				unit.set_component_property_string(component_id, "type", "mesh_renderer");
+			}
+			else
+			{
+				component_id = Guid.new_guid();
+				db.create(component_id);
+				db.set_property_string(component_id, "data.geometry_name", node_name);
+				db.set_property_string(component_id, "data.material", material_name);
+				db.set_property_string(component_id, "data.mesh_resource", resource_name);
+				db.set_property_bool  (component_id, "data.visible", true);
+				db.set_property_string(component_id, "type", "mesh_renderer");
+
+				db.add_to_set(unit_id, "components", component_id);
+			}
+		}
+
+		// Create collider
+		{
+			Guid component_id;
+			if (unit.has_component(out component_id, "collider"))
+			{
+				unit.set_component_property_string(component_id, "data.shape", "mesh");
+				unit.set_component_property_string(component_id, "data.scene", resource_name);
+				unit.set_component_property_string(component_id, "data.name", node_name);
+				unit.set_component_property_string(component_id, "type", "collider");
+			}
+			else
+			{
+				component_id = Guid.new_guid();
+				db.create(component_id);
+				db.set_property_string(component_id, "data.shape", "mesh");
+				db.set_property_string(component_id, "data.scene", resource_name);
+				db.set_property_string(component_id, "data.name", node_name);
+				db.set_property_string(component_id, "type", "collider");
+
+				db.add_to_set(unit_id, "components", component_id);
+			}
+		}
+
+		// Create actor
+		{
+			Guid component_id;
+			if (unit.has_component(out component_id, "actor"))
+			{
+				unit.set_component_property_string(component_id, "data.class", "static");
+				unit.set_component_property_string(component_id, "data.collision_filter", "default");
+				unit.set_component_property_double(component_id, "data.mass", 10);
+				unit.set_component_property_string(component_id, "data.material", "default");
+				unit.set_component_property_string(component_id, "type", "actor");
+			}
+			else
+			{
+				component_id = Guid.new_guid();
+				db.create(component_id);
+				db.set_property_string(component_id, "data.class", "static");
+				db.set_property_string(component_id, "data.collision_filter", "default");
+				db.set_property_double(component_id, "data.mass", 10);
+				db.set_property_string(component_id, "data.material", "default");
+				db.set_property_string(component_id, "type", "actor");
+
+				db.add_to_set(unit_id, "components", component_id);
+			}
+		}
+
+		if (parent_unit_id != unit_id)
+			db.add_to_set(parent_unit_id, "children", unit_id);
+
+		if (node.has_key("children"))
+		{
+			Hashtable children = (Hashtable)node["children"];
+			foreach (var child in children.entries)
+			{
+				Guid new_unit_id = Guid.new_guid();
+				db.create(new_unit_id);
+				create_components(db, unit_id, new_unit_id, material_name, resource_name, child.key,(Hashtable)child.value);
+			}
+		}
+	}
+
 	public int import_meshes(SList<string> filenames, string destination_dir)
 	{
 		foreach (unowned string filename_i in filenames)
@@ -860,10 +980,16 @@ public class Project
 			if (File.new_for_path(unit_name).query_exists())
 				db.load(unit_name);
 
-			Unit unit = new Unit(db, GUID_ZERO, null);
+			Hashtable mesh = SJSON.load(filename_i);
+			Hashtable mesh_nodes = (Hashtable)mesh["nodes"];
 
-			// Create transform
+			if (mesh_nodes.size > 1)
 			{
+				// Create an extra "root" unit to accommodate multiple root objects. This
+				// "root" unit will only have a transform centered at origin to allow other
+				// objects to be linked to it via the SceneGraph.
+				Unit unit = new Unit(db, GUID_ZERO, null);
+
 				Guid component_id;
 				if (unit.has_component(out component_id, "transform"))
 				{
@@ -885,77 +1011,17 @@ public class Project
 				}
 			}
 
-			// Remove all existing mesh_renderer components
-			{
-				Guid component_id;
-				while (unit.has_component(out component_id, "mesh_renderer"))
-					unit.remove_component(component_id);
-			}
-
-			Hashtable mesh = SJSON.load(filename_i);
-			Hashtable mesh_nodes = (Hashtable)mesh["nodes"];
-			// Create mesh_renderer
-			{
-				foreach (var entry in mesh_nodes.entries)
-				{
-					Guid component_id = Guid.new_guid();
-					db.create(component_id);
-					db.set_property_string(component_id, "data.geometry_name", (string)entry.key);
-					db.set_property_string(component_id, "data.material", material_name);
-					db.set_property_string(component_id, "data.mesh_resource", resource_name);
-					db.set_property_bool  (component_id, "data.visible", true);
-					db.set_property_string(component_id, "type", "mesh_renderer");
-
-					db.add_to_set(GUID_ZERO, "components", component_id);
-				}
-			}
-
-			// Create collider
-			{
-				Guid component_id;
-				if (unit.has_component(out component_id, "collider"))
-				{
-					unit.set_component_property_string(component_id, "data.shape", "mesh");
-					unit.set_component_property_string(component_id, "data.scene", resource_name);
-					unit.set_component_property_string(component_id, "data.name", mesh_nodes.entries.to_array()[0].key);
-					unit.set_component_property_string(component_id, "type", "collider");
-				}
-				else
-				{
-					component_id = Guid.new_guid();
-					db.create(component_id);
-					db.set_property_string(component_id, "data.shape", "mesh");
-					db.set_property_string(component_id, "data.scene", resource_name);
-					db.set_property_string(component_id, "data.name", mesh_nodes.entries.to_array()[0].key);
-					db.set_property_string(component_id, "type", "collider");
-
-					db.add_to_set(GUID_ZERO, "components", component_id);
-				}
-			}
-
-			// Create actor
+			Guid new_unit_id = GUID_ZERO;
+			foreach (var entry in mesh_nodes.entries)
 			{
-				Guid component_id;
-				if (unit.has_component(out component_id, "actor"))
-				{
-					unit.set_component_property_string(component_id, "data.class", "static");
-					unit.set_component_property_string(component_id, "data.collision_filter", "default");
-					unit.set_component_property_double(component_id, "data.mass", 10);
-					unit.set_component_property_string(component_id, "data.material", "default");
-					unit.set_component_property_string(component_id, "type", "actor");
-				}
-				else
+				if (mesh_nodes.size > 1)
 				{
-					component_id = Guid.new_guid();
-					db.create(component_id);
-					db.set_property_string(component_id, "data.class", "static");
-					db.set_property_string(component_id, "data.collision_filter", "default");
-					db.set_property_double(component_id, "data.mass", 10);
-					db.set_property_string(component_id, "data.material", "default");
-					db.set_property_string(component_id, "type", "actor");
-
-					db.add_to_set(GUID_ZERO, "components", component_id);
+					// If the mesh contains multiple root objects, create a new GUID for each
+					// one of those, otherwise use the special GUID_ZERO.
+					new_unit_id = Guid.new_guid();
+					db.create(new_unit_id);
 				}
+				create_components(db, GUID_ZERO, new_unit_id, material_name, resource_name, entry.key, (Hashtable)entry.value);
 			}
 
 			db.save(unit_name);