Kaynağa Gözat

tools: add capsule collider

Raphael de Vasconcelos Nascimento 6 yıl önce
ebeveyn
işleme
7748826fc9

+ 86 - 195
tools/level_editor/project.vala

@@ -316,16 +316,20 @@ 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;
-			int collision_h = (int)sid.collision_h.value;
-			string actor_class = (string)sid.actor_class.value;
+			bool collision_enabled         = sid.collision_enabled.active;
+			string shape_active_name       = (string)sid.shape.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 capsule_collision_center_x = (int)sid.capsule_collision_center_x.value;
+			int capsule_collision_center_y = (int)sid.capsule_collision_center_y.value;
+			int capsule_collision_radius   = (int)sid.capsule_collision_radius.value;
+			int capsule_collision_height   = (int)sid.capsule_collision_height.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;
+			int collision_h                = (int)sid.collision_h.value;
+			string actor_class             = (string)sid.actor_class.value;
 
 			sid.destroy();
 
@@ -470,208 +474,95 @@ end
 
 				if (collision_enabled)
 				{
-					// Create collider (geometry)
-					if (circle_square_active_name == "square_collider")
-					{
-						// d-----a
-						// |     |
-						// |     |
-						// c-----b
-						Vector2 a = {};
-						Vector2 b = {};
-						Vector2 c = {};
-						Vector2 d = {};
-
-						double PIXELS_PER_METER = 32.0;
-
-						a.x = (collision_w + collision_x - pivot_xy.x) / PIXELS_PER_METER;
-						a.y = (              collision_y - pivot_xy.y) / PIXELS_PER_METER;
-
-						b.x = (collision_w + collision_x - pivot_xy.x) / PIXELS_PER_METER;
-						b.y = (collision_h + collision_y - pivot_xy.y) / PIXELS_PER_METER;
-
-						c.x = (              collision_x - pivot_xy.x) / PIXELS_PER_METER;
-						c.y = (collision_h + collision_y - pivot_xy.y) / PIXELS_PER_METER;
-
-						d.x = (              collision_x - pivot_xy.x) / PIXELS_PER_METER;
-						d.y = (              collision_y - pivot_xy.y) / PIXELS_PER_METER;
-
-						// Invert Y axis
-						a.y = a.y == 0.0f ? a.y : -a.y;
-						b.y = b.y == 0.0f ? b.y : -b.y;
-						c.y = c.y == 0.0f ? c.y : -c.y;
-						d.y = d.y == 0.0f ? d.y : -d.y;
-
-						ArrayList<Value?> position = new ArrayList<Value?>();
-						// Up face
-						position.add(a.x); position.add( 0.25); position.add(a.y);
-						position.add(b.x); position.add( 0.25); position.add(b.y);
-						position.add(c.x); position.add( 0.25); position.add(c.y);
-						position.add(d.x); position.add( 0.25); position.add(d.y);
-						// Bottom face
-						position.add(a.x); position.add(-0.25); position.add(a.y);
-						position.add(b.x); position.add(-0.25); position.add(b.y);
-						position.add(c.x); position.add(-0.25); position.add(c.y);
-						position.add(d.x); position.add(-0.25); position.add(d.y);
-
-						ArrayList<Value?> indices_data = new ArrayList<Value?>();
-						indices_data.add(0); indices_data.add(2); indices_data.add(3);
-						indices_data.add(7); indices_data.add(5); indices_data.add(4);
-						indices_data.add(4); indices_data.add(1); indices_data.add(0);
-						indices_data.add(5); indices_data.add(2); indices_data.add(1);
-						indices_data.add(6); indices_data.add(3); indices_data.add(2);
-						indices_data.add(0); indices_data.add(7); indices_data.add(4);
-						indices_data.add(0); indices_data.add(1); indices_data.add(2);
-						indices_data.add(7); indices_data.add(6); indices_data.add(5);
-						indices_data.add(4); indices_data.add(5); indices_data.add(1);
-						indices_data.add(5); indices_data.add(6); indices_data.add(2);
-						indices_data.add(6); indices_data.add(7); indices_data.add(3);
-						indices_data.add(0); indices_data.add(3); indices_data.add(7);
-
-						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");
-					}
-					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");
-					}
-
 					// Create collider
+					double PIXELS_PER_METER = 32.0;
 					{
 						Guid id = Guid.new_guid();
+						Quaternion rotation = QUATERNION_IDENTITY;
 
 						if (!unit.has_component("collider", ref id))
 						{
 							db.create(id);
-							if (circle_square_active_name == "square_collider")
+							db.set_property_string(id, "data.source", "inline");
+							if (shape_active_name == "square_collider") {
+								double pos_x = (collision_x + collision_w/2.0 - pivot_xy.x) / PIXELS_PER_METER;
+								double pos_y = -(collision_y + collision_h/2.0 - pivot_xy.y) / PIXELS_PER_METER;
+								Vector3 position = Vector3(pos_x, 0, pos_y);
+								db.set_property_vector3(id, "data.collider_data.position", position);
 								db.set_property_string(id, "data.shape", "box");
-							else
+								db.set_property_quaternion(id, "data.collider_data.rotation", rotation);
+								db.set_property_vector3(id, "data.collider_data.half_extents",
+														Vector3(collision_w/2/PIXELS_PER_METER,
+																0.5/PIXELS_PER_METER,
+																collision_h/2/PIXELS_PER_METER));
+							} else if (shape_active_name == "circle_collider") {
+								double pos_x = (circle_collision_center_x - pivot_xy.x) / PIXELS_PER_METER;
+								double pos_y = -(circle_collision_center_y - pivot_xy.y) / PIXELS_PER_METER;
+								Vector3 position = Vector3(pos_x, 0, pos_y);
+								db.set_property_vector3(id, "data.collider_data.position", position);
 								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_quaternion(id, "data.collider_data.rotation", rotation);
+								db.set_property_double(id, "data.collider_data.radius",
+													   circle_collision_radius / PIXELS_PER_METER);
+							} else if (shape_active_name == "capsule_collider") {
+								double pos_x = (capsule_collision_center_x - pivot_xy.x) / PIXELS_PER_METER;
+								double pos_y = -(capsule_collision_center_y - pivot_xy.y) / PIXELS_PER_METER;
+								Vector3 position = Vector3(pos_x, 0, pos_y);
+								db.set_property_vector3(id, "data.collider_data.position", position);
+								db.set_property_string(id, "data.shape", "capsule");
+								db.set_property_quaternion(id, "data.collider_data.rotation",
+													   Quaternion.from_axis_angle(Vector3(0, 0, 1),
+													   (float)Math.PI/2));
+								db.set_property_double(id, "data.collider_data.radius",
+													   capsule_collision_radius / PIXELS_PER_METER);
+								db.set_property_double(id, "data.collider_data.height",
+													   (capsule_collision_height -
+														2*capsule_collision_radius) / PIXELS_PER_METER);
+							}
 							db.set_property_string(id, "type", "collider");
 
 							db.add_to_set(GUID_ZERO, "components", id);
 						}
 						else
 						{
-							if (circle_square_active_name == "square_collider")
+							unit.set_component_property_string(id, "data.source", "inline");
+							if (shape_active_name == "square_collider") {
+								double pos_x = (collision_x + collision_w/2.0 - pivot_xy.x) / PIXELS_PER_METER;
+								double pos_y = -(collision_y + collision_h/2.0 - pivot_xy.y) / PIXELS_PER_METER;
+								Vector3 position = Vector3(pos_x, 0, pos_y);
+								unit.set_component_property_vector3(id, "data.collider_data.position", position);
+								unit.set_component_property_quaternion(id,"data.collider_data.rotation",
+											   rotation);
 								unit.set_component_property_string(id, "data.shape", "box");
-							else
+								unit.set_component_property_vector3(id, "data.collider_data.half_extents",
+														Vector3(collision_w/2/PIXELS_PER_METER,
+																0.5/PIXELS_PER_METER,
+																collision_h/2/PIXELS_PER_METER));
+							} else if (shape_active_name == "circle_collider") {
+								double pos_x = (circle_collision_center_x - pivot_xy.x) / PIXELS_PER_METER;
+								double pos_y = -(circle_collision_center_y - pivot_xy.y) / PIXELS_PER_METER;
+								Vector3 position = Vector3(pos_x, 0, pos_y);
+								unit.set_component_property_vector3(id, "data.collider_data.position", position);
+								unit.set_component_property_quaternion(id,"data.collider_data.rotation",
+											   rotation);
 								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_double(id, "data.collider_data.radius",
+													   circle_collision_radius / PIXELS_PER_METER);
+							} else if (shape_active_name == "capsule_collider") {
+								double pos_x = (capsule_collision_center_x - pivot_xy.x) / PIXELS_PER_METER;
+								double pos_y = -(capsule_collision_center_y - pivot_xy.y) / PIXELS_PER_METER;
+								Vector3 position = Vector3(pos_x, 0, pos_y);
+								unit.set_component_property_vector3(id, "data.collider_data.position", position);
+								unit.set_component_property_quaternion(id,"data.collider_data.rotation",
+											   Quaternion.from_axis_angle(Vector3(0, 0, 1),
+											   (float)Math.PI/2));
+								unit.set_component_property_string(id, "data.shape", "capsule");
+								unit.set_component_property_double(id, "data.collider_data.radius",
+													   capsule_collision_radius / PIXELS_PER_METER);
+								unit.set_component_property_double(id, "data.collider_data.height",
+													   (capsule_collision_height -
+														2*capsule_collision_radius) / PIXELS_PER_METER);
+							}
 							unit.set_component_property_string(id, "type", "collider");
 						}
 					}

+ 114 - 42
tools/level_editor/sprite_import_dialog.vala

@@ -119,14 +119,19 @@ 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 string shape_active_name;
+	public Gtk.StackSwitcher shape_switcher;
+	public Gtk.Stack shape;
 
 	public Gtk.SpinButton circle_collision_center_x;
 	public Gtk.SpinButton circle_collision_center_y;
 	public Gtk.SpinButton circle_collision_radius;
 
+	public Gtk.SpinButton capsule_collision_center_x;
+	public Gtk.SpinButton capsule_collision_center_y;
+	public Gtk.SpinButton capsule_collision_height;
+	public Gtk.SpinButton capsule_collision_radius;
+
 	public Gtk.SpinButton collision_x;
 	public Gtk.SpinButton collision_y;
 	public Gtk.SpinButton collision_w;
@@ -283,13 +288,25 @@ public class SpriteImportDialog : Gtk.Dialog
 				cr.restore();
 
 				// Draw collision
-				cr.rectangle(collision_x.value, collision_y.value, collision_w.value, collision_h.value);
-				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();
+				if (shape.visible_child_name == "square_collider") {
+					cr.rectangle(collision_x.value, collision_y.value, collision_w.value, collision_h.value);
+					cr.set_source_rgba(0.3, 0.3, 0.3, 0.6);
+					cr.fill();
+				} else if (shape.visible_child_name == "circle_collider") {
+					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();
+				} else if (shape.visible_child_name == "capsule_collider") {
+					double x = capsule_collision_center_x.value;
+					double y = capsule_collision_center_y.value;
+					double radius = capsule_collision_radius.value;
+					double height = capsule_collision_height.value - 2*radius;
+					cr.arc(x - height/2, y, radius, Math.PI/2, 3*Math.PI/2);
+					cr.rectangle(x - height/2, y - radius, height, 2*radius);
+					cr.arc(x + height/2, y, radius, 3*Math.PI/2, Math.PI/2);
+					cr.set_source_rgba(0.3, 0.3, 0.3, 0.6);
+					cr.fill();
+				}
 
 				return true;
 			});
@@ -338,6 +355,15 @@ public class SpriteImportDialog : Gtk.Dialog
 		circle_collision_radius = new Gtk.SpinButton.with_range(-double.MAX, double.MAX, 1.0);
 		circle_collision_radius.value = 32;
 
+		capsule_collision_center_x = new Gtk.SpinButton.with_range(-double.MAX, double.MAX, 1.0);
+		capsule_collision_center_x.value = cell_w.value/2.0;
+		capsule_collision_center_y = new Gtk.SpinButton.with_range(-double.MAX, double.MAX, 1.0);
+		capsule_collision_center_y.value = cell_h.value/2.0;;
+		capsule_collision_radius = new Gtk.SpinButton.with_range(-double.MAX, double.MAX, 1.0);
+		capsule_collision_radius.value = 32;
+		capsule_collision_height = new Gtk.SpinButton.with_range(-double.MAX, double.MAX, 1.0);
+		capsule_collision_height.value = 64;
+
 		cells_h.value_changed.connect (() => {
 			if (cell_wh_auto.active)
 			{
@@ -369,12 +395,14 @@ public class SpriteImportDialog : Gtk.Dialog
 
 		cell_w.value_changed.connect (() => {
 			circle_collision_center_x.value = cell_w.value/2.0;
+			capsule_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;
+			capsule_collision_center_y.value = cell_h.value/2.0;
 			_drawing_area.queue_draw();
 			_preview.queue_draw();
 		});
@@ -404,10 +432,14 @@ public class SpriteImportDialog : Gtk.Dialog
 			collision_y.sensitive = !collision_y.sensitive;
 			collision_w.sensitive = !collision_w.sensitive;
 			collision_h.sensitive = !collision_h.sensitive;
-			circle_square_switcher.sensitive = !circle_square_switcher.sensitive;
+			shape_switcher.sensitive = !shape_switcher.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;
+			capsule_collision_center_x.sensitive = !capsule_collision_center_x.sensitive;
+			capsule_collision_center_y.sensitive = !capsule_collision_center_y.sensitive;
+			capsule_collision_radius.sensitive = !capsule_collision_radius.sensitive;
+			capsule_collision_height.sensitive = !capsule_collision_height.sensitive;
 			actor_class.sensitive = !actor_class.sensitive;
 		});
 
@@ -439,6 +471,22 @@ public class SpriteImportDialog : Gtk.Dialog
 			_preview.queue_draw();
 		});
 
+		capsule_collision_center_x.value_changed.connect(() => {
+			_preview.queue_draw();
+		});
+
+		capsule_collision_center_y.value_changed.connect(() => {
+			_preview.queue_draw();
+		});
+
+		capsule_collision_radius.value_changed.connect(() => {
+			_preview.queue_draw();
+		});
+
+		capsule_collision_height.value_changed.connect(() => {
+			_preview.queue_draw();
+		});
+
 		pivot = new Gtk.ComboBoxText();
 		pivot.append_text("Top left");      // TOP_LEFT
 		pivot.append_text("Top center");    // TOP_CENTER
@@ -492,7 +540,7 @@ public class SpriteImportDialog : Gtk.Dialog
 
 		grid.attach(collision_enabled, 1, 13, 1, 1);
 		grid.attach(actor_class,       1, 14, 1, 1);
-		circle_square = new Gtk.Stack();
+		shape = 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);
@@ -515,12 +563,25 @@ public class SpriteImportDialog : Gtk.Dialog
 		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, 1, 15, 1, 1);
-		grid.attach(circle_square, 1, 16, 1, 5);
+		Gtk.Grid capsule_grid = new Gtk.Grid();
+		capsule_grid.attach(label_with_alignment("Collision X", Gtk.Align.END),  0, 0, 1, 1);
+		capsule_grid.attach(label_with_alignment("Collision Y", Gtk.Align.END),  0, 1, 1, 1);
+		capsule_grid.attach(label_with_alignment("Radius", Gtk.Align.END),  0, 2, 1, 1);
+		capsule_grid.attach(label_with_alignment("Height", Gtk.Align.END),  0, 3, 1, 1);
+		capsule_grid.attach(capsule_collision_center_x, 1, 0, 1, 1);
+		capsule_grid.attach(capsule_collision_center_y, 1, 1, 1, 1);
+		capsule_grid.attach(capsule_collision_radius, 1, 2, 1, 1);
+		capsule_grid.attach(capsule_collision_height, 1, 3, 1, 1);
+		capsule_grid.row_spacing = 6;
+		capsule_grid.column_spacing = 12;
+
+		shape.add_titled(square_grid, "square_collider", "Square Collider");
+		shape.add_titled(circle_grid, "circle_collider", "Circle Collider");
+		shape.add_titled(capsule_grid, "capsule_collider", "Capsule Collider");
+		shape_switcher = new Gtk.StackSwitcher();
+		shape_switcher.set_stack(shape);
+		grid.attach(shape_switcher, 1, 15, 1, 1);
+		grid.attach(shape, 1, 16, 1, 5);
 
 		grid.row_spacing = 6;
 		grid.column_spacing = 12;
@@ -572,36 +633,47 @@ public class SpriteImportDialog : Gtk.Dialog
 		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  = importer_settings.has_key("circle_collision_center_x") ? (double)importer_settings["circle_collision_center_x"] : cell_w.value;
-		circle_collision_center_y.value  = importer_settings.has_key("circle_collision_center_y") ? (double)importer_settings["circle_collision_center_y"] : cell_h.value;
+
+		circle_collision_center_x.value  = importer_settings.has_key("circle_collision_center_x") ? (double)importer_settings["circle_collision_center_x"] : cell_w.value/2.0;
+		circle_collision_center_y.value  = importer_settings.has_key("circle_collision_center_y") ? (double)importer_settings["circle_collision_center_y"] : cell_h.value/2.0;
 		circle_collision_radius.value    = importer_settings.has_key("circle_collision_radius") ? (double)importer_settings["circle_collision_radius"] : 32;
-		circle_square.visible_child_name = importer_settings.has_key("circle_square_active_name") ? (string)importer_settings["circle_square_active_name"] : "square_collider";
+
+		capsule_collision_center_x.value = importer_settings.has_key("capsule_collision_center_x") ? (double)importer_settings["capsule_collision_center_x"] : cell_w.value/2.0;
+		capsule_collision_center_y.value = importer_settings.has_key("capsule_collision_center_y") ? (double)importer_settings["capsule_collision_center_y"] : cell_h.value/2.0;
+		capsule_collision_radius.value   = importer_settings.has_key("capsule_collision_radius") ? (double)importer_settings["capsule_collision_radius"] : 32;
+		capsule_collision_height.value   = importer_settings.has_key("capsule_collision_height") ? (double)importer_settings["capsule_collision_height"] : 64;
+
+		shape.visible_child_name         = importer_settings.has_key("shape_active_name") ? (string)importer_settings["shape_active_name"] : "square_collider";
 		actor_class.value                = importer_settings.has_key("actor_class") ? (string)importer_settings["actor_class"] : "static";
 	}
 
 	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["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;
-		importer_settings["actor_class"]               = actor_class.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["capsule_collision_center_x"] = capsule_collision_center_x.value;
+		importer_settings["capsule_collision_center_y"] = capsule_collision_center_y.value;
+		importer_settings["capsule_collision_radius"]   = capsule_collision_radius.value;
+		importer_settings["capsule_collision_height"]   = capsule_collision_height.value;
+		importer_settings["shape_active_name"]          = shape.visible_child_name;
+		importer_settings["actor_class"]                = actor_class.value;
 	}
 }