2
0
Эх сурвалжийг харах

tools: add circle sprite importer

Raphael de Vasconcelos Nascimento 6 жил өмнө
parent
commit
28f4fb818f

+ 97 - 2
tools/level_editor/project.vala

@@ -317,6 +317,10 @@ end
 			Vector2 pivot_xy = sprite_cell_pivot_xy(cell_w, cell_h, sid.pivot.active);
 
 			bool collision_enabled = sid.collision_enabled.active;
+            string circle_square_active_name = (string)sid.circle_square.visible_child_name;
+            int circle_collision_center_x = (int)sid.circle_collision_center_x.value;
+            int circle_collision_center_y = (int)sid.circle_collision_center_y.value;
+            int circle_collision_radius = (int)sid.circle_collision_radius.value;
 			int collision_x = (int)sid.collision_x.value;
 			int collision_y = (int)sid.collision_y.value;
 			int collision_w = (int)sid.collision_w.value;
@@ -466,6 +470,7 @@ end
 				if (collision_enabled)
 				{
 					// Create collider (geometry)
+                    if (circle_square_active_name == "square_collider")
 					{
 						// d-----a
 						// |     |
@@ -552,6 +557,90 @@ end
 						mesh["geometries"] = geometries;
 						mesh["nodes"] = nodes;
 
+						SJSON.save(mesh, Path.build_filename(_source_dir.get_path(), resource_name) + ".mesh");
+					} else {
+						// d-----a
+						// |     |
+						// |     |
+						// c-----b
+                        int radius = circle_collision_radius;
+
+						double PIXELS_PER_METER = 32.0;
+                        int rings = 2;
+                        int radial_segments = 20;
+                        Vector3 center = {};
+                        // dont used, because compile_sphere doesnt need it
+                        center.x = circle_collision_center_x / PIXELS_PER_METER;
+                        center.y = circle_collision_center_y / PIXELS_PER_METER;
+
+
+						ArrayList<Value?> position = new ArrayList<Value?>();
+						ArrayList<Value?> indices_data = new ArrayList<Value?>();
+                        int prevrow = 0;
+                        int thisrow = 0;
+                        int point = 0;
+                        for (int i = 0; i < rings; ++i) {
+                            double theta = 2*Math.PI*i/radial_segments;
+                            double phi = Math.PI*i/rings;
+                            for (int j = 0; j < radial_segments; ++j) {
+                                position.add(radius*Math.cos(theta)*Math.sin(phi)/PIXELS_PER_METER);
+                                position.add(radius*Math.cos(phi)/PIXELS_PER_METER);
+                                position.add(radius*Math.sin(theta)*Math.cos(phi)/PIXELS_PER_METER);
+                                // Create triangles in ring using indices.
+                                if (i > 0 && j > 0) {
+                                    indices_data.add(prevrow + j - 1);
+                                    indices_data.add(prevrow + j);
+                                    indices_data.add(thisrow + j - 1);
+
+                                    indices_data.add(prevrow + j);
+                                    indices_data.add(thisrow + j);
+                                    indices_data.add(thisrow + j - 1);
+                                }
+                                point++;
+                            }
+                            if (i > 0) {
+                                indices_data.add(prevrow + radial_segments - 1);
+                                indices_data.add(prevrow);
+                                indices_data.add(thisrow + radial_segments - 1);
+
+                                indices_data.add(prevrow);
+                                indices_data.add(prevrow + radial_segments);
+                                indices_data.add(thisrow + radial_segments - 1);
+                            }
+                            prevrow = thisrow;
+                            thisrow = point;
+                        }
+
+						ArrayList<Value?> data = new ArrayList<Value?>();
+						data.add(indices_data);
+
+						Hashtable indices = new Hashtable();
+						indices["size"] = indices_data.size;
+						indices["data"] = data;
+
+						Hashtable geometries_collider = new Hashtable();
+						geometries_collider["position"] = position;
+						geometries_collider["indices"] = indices;
+
+						Hashtable geometries = new Hashtable();
+						geometries["collider"] = geometries_collider;
+
+						ArrayList<Value?> matrix_local = new ArrayList<Value?>();
+						matrix_local.add(1.0); matrix_local.add(0.0); matrix_local.add(0.0); matrix_local.add(0.0);
+						matrix_local.add(0.0); matrix_local.add(1.0); matrix_local.add(0.0); matrix_local.add(0.0);
+						matrix_local.add(0.0); matrix_local.add(0.0); matrix_local.add(1.0); matrix_local.add(0.0);
+						matrix_local.add(0.0); matrix_local.add(0.0); matrix_local.add(0.0); matrix_local.add(1.0);
+
+						Hashtable nodes_collider = new Hashtable();
+						nodes_collider["matrix_local"] = matrix_local;
+
+						Hashtable nodes = new Hashtable();
+						nodes["collider"] = nodes_collider;
+
+						Hashtable mesh = new Hashtable();
+						mesh["geometries"] = geometries;
+						mesh["nodes"] = nodes;
+
 						SJSON.save(mesh, Path.build_filename(_source_dir.get_path(), resource_name) + ".mesh");
 					}
 
@@ -562,7 +651,10 @@ end
 						if (!unit.has_component("collider", ref id))
 						{
 							db.create(id);
-							db.set_property_string(id, "data.shape", "box");
+                            if (circle_square_active_name == "square_collider")
+                                db.set_property_string(id, "data.shape", "box");
+                            else
+                                db.set_property_string(id, "data.shape", "sphere");
 							db.set_property_string(id, "data.scene", resource_name);
 							db.set_property_string(id, "data.name", "collider");
 							db.set_property_string(id, "type", "collider");
@@ -571,7 +663,10 @@ end
 						}
 						else
 						{
-							unit.set_component_property_string(id, "data.shape", "box");
+                            if (circle_square_active_name == "square_collider")
+                                unit.set_component_property_string(id, "data.shape", "box");
+                            else
+                                unit.set_component_property_string(id, "data.shape", "sphere");
 							unit.set_component_property_string(id, "data.scene", resource_name);
 							unit.set_component_property_string(id, "data.name", "collider");
 							unit.set_component_property_string(id, "type", "collider");

+ 106 - 40
tools/level_editor/sprite_import_dialog.vala

@@ -119,6 +119,14 @@ public class SpriteImportDialog : Gtk.Dialog
 	public SpinButtonDouble depth;
 
 	public Gtk.CheckButton collision_enabled;
+    public string circle_square_active_name;
+    public Gtk.StackSwitcher circle_square_switcher;
+    public Gtk.Stack circle_square;
+
+    public Gtk.SpinButton circle_collision_center_x;
+    public Gtk.SpinButton circle_collision_center_y;
+    public Gtk.SpinButton circle_collision_radius;
+
 	public Gtk.SpinButton collision_x;
 	public Gtk.SpinButton collision_y;
 	public Gtk.SpinButton collision_w;
@@ -278,6 +286,10 @@ public class SpriteImportDialog : Gtk.Dialog
 				cr.set_source_rgba(0.3, 0.3, 0.3, 0.6);
 				cr.fill();
 
+                cr.arc(circle_collision_center_x.value, circle_collision_center_y.value, circle_collision_radius.value, 0, 2*Math.PI);
+				cr.set_source_rgba(0.3, 0.3, 0.3, 0.6);
+				cr.fill();
+
 				return true;
 			});
 
@@ -312,6 +324,13 @@ public class SpriteImportDialog : Gtk.Dialog
 		collision_h = new Gtk.SpinButton.with_range(-double.MAX, double.MAX, 1.0);
 		collision_h.value = 32;
 
+        circle_collision_center_x = new Gtk.SpinButton.with_range(-double.MAX, double.MAX, 1.0);
+        circle_collision_center_x.value = cell_w.value/2.0;
+        circle_collision_center_y = new Gtk.SpinButton.with_range(-double.MAX, double.MAX, 1.0);
+        circle_collision_center_y.value = cell_h.value/2.0;;
+        circle_collision_radius = new Gtk.SpinButton.with_range(-double.MAX, double.MAX, 1.0);
+        circle_collision_radius.value = 32;
+
 		cells_h.value_changed.connect (() => {
 			if (cell_wh_auto.active)
 			{
@@ -342,11 +361,13 @@ public class SpriteImportDialog : Gtk.Dialog
 		});
 
 		cell_w.value_changed.connect (() => {
+            circle_collision_center_x.value = cell_w.value/2.0;
 			_drawing_area.queue_draw();
 			_preview.queue_draw();
 		});
 
 		cell_h.value_changed.connect(() => {
+            circle_collision_center_y.value = cell_h.value/2.0;
 			_drawing_area.queue_draw();
 			_preview.queue_draw();
 		});
@@ -376,6 +397,9 @@ public class SpriteImportDialog : Gtk.Dialog
 			collision_y.sensitive = !collision_y.sensitive;
 			collision_w.sensitive = !collision_w.sensitive;
 			collision_h.sensitive = !collision_h.sensitive;
+            circle_collision_center_x.sensitive = !circle_collision_center_x.sensitive;
+            circle_collision_center_y.sensitive = !circle_collision_center_y.sensitive;
+            circle_collision_radius.sensitive = !circle_collision_radius.sensitive;
 		});
 
 		collision_x.value_changed.connect(() => {
@@ -394,6 +418,18 @@ public class SpriteImportDialog : Gtk.Dialog
 			_preview.queue_draw();
 		});
 
+		circle_collision_center_x.value_changed.connect(() => {
+			_preview.queue_draw();
+		});
+
+		circle_collision_center_y.value_changed.connect(() => {
+			_preview.queue_draw();
+		});
+
+		circle_collision_radius.value_changed.connect(() => {
+			_preview.queue_draw();
+		});
+
 		pivot = new Gtk.ComboBoxText();
 		pivot.append_text("Top left");      // TOP_LEFT
 		pivot.append_text("Top center");    // TOP_CENTER
@@ -430,10 +466,6 @@ public class SpriteImportDialog : Gtk.Dialog
 		grid.attach(label_with_alignment("Depth", Gtk.Align.END),        0, 12, 1, 1);
 
 		grid.attach(label_with_alignment("Collision", Gtk.Align.END),    0, 13, 1, 1);
-		grid.attach(label_with_alignment("Collision X", Gtk.Align.END),  0, 14, 1, 1);
-		grid.attach(label_with_alignment("Collision Y", Gtk.Align.END),  0, 15, 1, 1);
-		grid.attach(label_with_alignment("Collision W", Gtk.Align.END),  0, 16, 1, 1);
-		grid.attach(label_with_alignment("Collision H", Gtk.Align.END),  0, 17, 1, 1);
 
 		grid.attach(resolution,   1,  0, 1, 1);
 		grid.attach(cells_h,      1,  1, 1, 1);
@@ -450,10 +482,36 @@ public class SpriteImportDialog : Gtk.Dialog
 		grid.attach(depth,        1, 12, 1, 1);
 
 		grid.attach(collision_enabled, 1, 13, 1, 1);
-		grid.attach(collision_x,       1, 14, 1, 1);
-		grid.attach(collision_y,       1, 15, 1, 1);
-		grid.attach(collision_w,       1, 16, 1, 1);
-		grid.attach(collision_h,       1, 17, 1, 1);
+        circle_square = new Gtk.Stack();
+        Gtk.Grid square_grid = new Gtk.Grid();
+		square_grid.attach(label_with_alignment("Collision X", Gtk.Align.END),  0, 0, 1, 1);
+		square_grid.attach(label_with_alignment("Collision Y", Gtk.Align.END),  0, 1, 1, 1);
+		square_grid.attach(label_with_alignment("Collision W", Gtk.Align.END),  0, 2, 1, 1);
+		square_grid.attach(label_with_alignment("Collision H", Gtk.Align.END),  0, 3, 1, 1);
+		square_grid.attach(collision_x,       1, 0, 1, 1);
+		square_grid.attach(collision_y,       1, 1, 1, 1);
+		square_grid.attach(collision_w,       1, 2, 1, 1);
+		square_grid.attach(collision_h,       1, 3, 1, 1);
+		square_grid.row_spacing = 6;
+		square_grid.column_spacing = 12;
+
+        Gtk.Grid circle_grid = new Gtk.Grid();
+		circle_grid.attach(label_with_alignment("Collision X", Gtk.Align.END),  0, 0, 1, 1);
+		circle_grid.attach(label_with_alignment("Collision Y", Gtk.Align.END),  0, 1, 1, 1);
+		circle_grid.attach(label_with_alignment("Radius", Gtk.Align.END),  0, 2, 1, 1);
+        circle_grid.attach(circle_collision_center_x, 1, 0, 1, 1);
+        circle_grid.attach(circle_collision_center_y, 1, 1, 1, 1);
+        circle_grid.attach(circle_collision_radius, 1, 2, 1, 1);
+		circle_grid.row_spacing = 6;
+		circle_grid.column_spacing = 12;
+
+        circle_square.add_titled(square_grid, "square_collider", "Square Collider");
+        circle_square.add_titled(circle_grid, "circle_collider", "Circle Collider");
+        circle_square_switcher = new Gtk.StackSwitcher();
+        circle_square_switcher.set_stack(circle_square);
+        grid.attach(circle_square_switcher, 0, 14, 2, 1);
+        grid.attach(circle_square, 0, 15, 2, 5);
+        
 
 		grid.row_spacing = 6;
 		grid.column_spacing = 12;
@@ -489,42 +547,50 @@ public class SpriteImportDialog : Gtk.Dialog
 	public void load(Hashtable importer_settings)
 	{
 		// Load settings
-		cells_h.value            = (double)importer_settings["num_h"];
-		cells_v.value            = (double)importer_settings["num_v"];
-		cell_w.value             = (double)importer_settings["cell_w"];
-		cell_h.value             = (double)importer_settings["cell_h"];
-		offset_x.value           = (double)importer_settings["offset_x"];
-		offset_y.value           = (double)importer_settings["offset_y"];
-		spacing_x.value          = (double)importer_settings["spacing_x"];
-		spacing_y.value          = (double)importer_settings["spacing_y"];
-		layer.value              = (double)importer_settings["layer"];
-		depth.value              = (double)importer_settings["depth"];
-		pivot.active             = (int)(double)importer_settings["pivot"];
-		collision_enabled.active = (bool)importer_settings["collision_enabled"];
-		collision_x.value        = (double)importer_settings["collision_x"];
-		collision_y.value        = (double)importer_settings["collision_y"];
-		collision_w.value        = (double)importer_settings["collision_w"];
-		collision_h.value        = (double)importer_settings["collision_h"];
+		cells_h.value                           = (double)importer_settings["num_h"];
+		cells_v.value                           = (double)importer_settings["num_v"];
+		cell_w.value                            = (double)importer_settings["cell_w"];
+		cell_h.value                            = (double)importer_settings["cell_h"];
+		offset_x.value                          = (double)importer_settings["offset_x"];
+		offset_y.value                          = (double)importer_settings["offset_y"];
+		spacing_x.value                         = (double)importer_settings["spacing_x"];
+		spacing_y.value                         = (double)importer_settings["spacing_y"];
+		layer.value                             = (double)importer_settings["layer"];
+		depth.value                             = (double)importer_settings["depth"];
+		pivot.active                            = (int)(double)importer_settings["pivot"];
+		collision_enabled.active                = (bool)importer_settings["collision_enabled"];
+		collision_x.value                       = (double)importer_settings["collision_x"];
+		collision_y.value                       = (double)importer_settings["collision_y"];
+		collision_w.value                       = (double)importer_settings["collision_w"];
+		collision_h.value                       = (double)importer_settings["collision_h"];
+		circle_collision_center_x.value         = (double)importer_settings["circle_collision_center_x"];
+		circle_collision_center_y.value         = (double)importer_settings["circle_collision_center_y"];
+		circle_collision_radius.value           = (double)importer_settings["circle_collision_radius"];
+		circle_square.visible_child_name        = (string)importer_settings["circle_square_active_name"];
 	}
 
 	public void save(Hashtable importer_settings)
 	{
-		importer_settings["num_h"]             = cells_h.value;
-		importer_settings["num_v"]             = cells_v.value;
-		importer_settings["cell_w"]            = cell_w.value;
-		importer_settings["cell_h"]            = cell_h.value;
-		importer_settings["offset_x"]          = offset_x.value;
-		importer_settings["offset_y"]          = offset_y.value;
-		importer_settings["spacing_x"]         = spacing_x.value;
-		importer_settings["spacing_y"]         = spacing_y.value;
-		importer_settings["layer"]             = layer.value;
-		importer_settings["depth"]             = depth.value;
-		importer_settings["pivot"]             = pivot.active;
-		importer_settings["collision_enabled"] = collision_enabled.active;
-		importer_settings["collision_x"]       = collision_x.value;
-		importer_settings["collision_y"]       = collision_y.value;
-		importer_settings["collision_w"]       = collision_w.value;
-		importer_settings["collision_h"]       = collision_h.value;
+		importer_settings["num_h"]                      = cells_h.value;
+		importer_settings["num_v"]                      = cells_v.value;
+		importer_settings["cell_w"]                     = cell_w.value;
+		importer_settings["cell_h"]                     = cell_h.value;
+		importer_settings["offset_x"]                   = offset_x.value;
+		importer_settings["offset_y"]                   = offset_y.value;
+		importer_settings["spacing_x"]                  = spacing_x.value;
+		importer_settings["spacing_y"]                  = spacing_y.value;
+		importer_settings["layer"]                      = layer.value;
+		importer_settings["depth"]                      = depth.value;
+		importer_settings["pivot"]                      = pivot.active;
+		importer_settings["collision_enabled"]          = collision_enabled.active;
+		importer_settings["collision_x"]                = collision_x.value;
+		importer_settings["collision_y"]                = collision_y.value;
+		importer_settings["collision_w"]                = collision_w.value;
+		importer_settings["collision_h"]                = collision_h.value;
+        importer_settings["circle_collision_center_x"]  = circle_collision_center_x.value;
+        importer_settings["circle_collision_center_y"]  = circle_collision_center_y.value;
+        importer_settings["circle_collision_radius"]    = circle_collision_radius.value;
+        importer_settings["circle_square_active_name"]  = circle_square.visible_child_name;
 	}
 }