Ver código fonte

added cylinder shape support

muiroc 7 anos atrás
pai
commit
0a36e974da

+ 25 - 0
doc/classes/CylinderShape.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="CylinderShape" inherits="Shape" category="Core" version="3.1">
+	<brief_description>
+		Cylinder shape for collisions.
+	</brief_description>
+	<description>
+		Cylinder shape for collisions.
+	</description>
+	<tutorials>
+	</tutorials>
+	<demos>
+	</demos>
+	<methods>
+	</methods>
+	<members>
+		<member name="height" type="float" setter="set_height" getter="get_height">
+			The cylinder's height.
+		</member>
+		<member name="radius" type="float" setter="set_radius" getter="get_radius">
+			The cylinder's radius.
+		</member>
+	</members>
+	<constants>
+	</constants>
+</class>

+ 7 - 4
doc/classes/PhysicsServer.xml

@@ -1413,16 +1413,19 @@
 		<constant name="SHAPE_CAPSULE" value="4" enum="ShapeType">
 			The [Shape] is a [CapsuleShape].
 		</constant>
-		<constant name="SHAPE_CONVEX_POLYGON" value="5" enum="ShapeType">
+		<constant name="SHAPE_CYLINDER" value="5" enum="ShapeType">
+			The [Shape] is a [CylinderShape].
+		</constant>
+		<constant name="SHAPE_CONVEX_POLYGON" value="6" enum="ShapeType">
 			The [Shape] is a [ConvexPolygonShape].
 		</constant>
-		<constant name="SHAPE_CONCAVE_POLYGON" value="6" enum="ShapeType">
+		<constant name="SHAPE_CONCAVE_POLYGON" value="7" enum="ShapeType">
 			The [Shape] is a [ConcavePolygonShape].
 		</constant>
-		<constant name="SHAPE_HEIGHTMAP" value="7" enum="ShapeType">
+		<constant name="SHAPE_HEIGHTMAP" value="8" enum="ShapeType">
 			The [Shape] is a [HeightMapShape].
 		</constant>
-		<constant name="SHAPE_CUSTOM" value="8" enum="ShapeType">
+		<constant name="SHAPE_CUSTOM" value="9" enum="ShapeType">
 			This constant is used internally by the engine. Any attempt to create this kind of shape results in an error.
 		</constant>
 		<constant name="AREA_PARAM_GRAVITY" value="0" enum="AreaParameter">

+ 6 - 0
editor/icons/icon_cylinder_shape.svg

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg width="16" height="16" version="1.1" viewBox="0 0 14.999999 14.999999" xmlns="http://www.w3.org/2000/svg">
+<rect fill="#68b6ff" width="13.171325" height="7.6993308" x="0.89037383" y="3.6879442"/>
+<ellipse fill="#a2d2ff" cx="7.4772978" cy="3.7229116" rx="6.5864792" ry="2.820821"/>
+<ellipse fill="#68b6ff" cx="7.4746876" cy="11.34481" rx="6.5864792" ry="2.8208208"/>
+</svg>

+ 116 - 0
editor/spatial_editor_gizmos.cpp

@@ -36,6 +36,7 @@
 #include "scene/resources/box_shape.h"
 #include "scene/resources/capsule_shape.h"
 #include "scene/resources/convex_polygon_shape.h"
+#include "scene/resources/cylinder_shape.h"
 #include "scene/resources/plane_shape.h"
 #include "scene/resources/primitive_meshes.h"
 #include "scene/resources/ray_shape.h"
@@ -1861,6 +1862,11 @@ String CollisionShapeSpatialGizmo::get_handle_name(int p_idx) const {
 		return p_idx == 0 ? "Radius" : "Height";
 	}
 
+	if (Object::cast_to<CylinderShape>(*s)) {
+
+		return p_idx == 0 ? "Radius" : "Height";
+	}
+
 	if (Object::cast_to<RayShape>(*s)) {
 
 		return "Length";
@@ -1892,6 +1898,12 @@ Variant CollisionShapeSpatialGizmo::get_handle_value(int p_idx) const {
 		return p_idx == 0 ? cs->get_radius() : cs->get_height();
 	}
 
+	if (Object::cast_to<CylinderShape>(*s)) {
+
+		Ref<CylinderShape> cs = s;
+		return p_idx == 0 ? cs->get_radius() : cs->get_height();
+	}
+
 	if (Object::cast_to<RayShape>(*s)) {
 
 		Ref<RayShape> cs = s;
@@ -1972,6 +1984,24 @@ void CollisionShapeSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const P
 		else if (p_idx == 1)
 			cs->set_height(d * 2.0);
 	}
+
+	if (Object::cast_to<CylinderShape>(*s)) {
+
+		Vector3 axis;
+		axis[p_idx == 0 ? 0 : 1] = 1.0;
+		Ref<CylinderShape> cs = s;
+		Vector3 ra, rb;
+		Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
+		float d = axis.dot(ra);
+
+		if (d < 0.001)
+			d = 0.001;
+
+		if (p_idx == 0)
+			cs->set_radius(d);
+		else if (p_idx == 1)
+			cs->set_height(d * 2.0);
+	}
 }
 void CollisionShapeSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
 	Ref<Shape> s = cs->get_shape();
@@ -2033,6 +2063,31 @@ void CollisionShapeSpatialGizmo::commit_handle(int p_idx, const Variant &p_resto
 		ur->commit_action();
 	}
 
+	if (Object::cast_to<CylinderShape>(*s)) {
+
+		Ref<CylinderShape> ss = s;
+		if (p_cancel) {
+			if (p_idx == 0)
+				ss->set_radius(p_restore);
+			else
+				ss->set_height(p_restore);
+			return;
+		}
+
+		UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
+		if (p_idx == 0) {
+			ur->create_action(TTR("Change Cylinder Shape Radius"));
+			ur->add_do_method(ss.ptr(), "set_radius", ss->get_radius());
+			ur->add_undo_method(ss.ptr(), "set_radius", p_restore);
+		} else {
+			ur->create_action(TTR("Change Cylinder Shape Height"));
+			ur->add_do_method(ss.ptr(), "set_height", ss->get_height());
+			ur->add_undo_method(ss.ptr(), "set_height", p_restore);
+		}
+
+		ur->commit_action();
+	}
+
 	if (Object::cast_to<RayShape>(*s)) {
 
 		Ref<RayShape> ss = s;
@@ -2209,6 +2264,67 @@ void CollisionShapeSpatialGizmo::redraw() {
 		add_handles(handles);
 	}
 
+	if (Object::cast_to<CylinderShape>(*s)) {
+
+		Ref<CylinderShape> cs = s;
+		float radius = cs->get_radius();
+		float height = cs->get_height();
+
+		Vector<Vector3> points;
+
+		Vector3 d(0, height * 0.5, 0);
+		for (int i = 0; i < 360; i++) {
+
+			float ra = Math::deg2rad((float)i);
+			float rb = Math::deg2rad((float)i + 1);
+			Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius;
+			Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius;
+
+			points.push_back(Vector3(a.x, 0, a.y) + d);
+			points.push_back(Vector3(b.x, 0, b.y) + d);
+
+			points.push_back(Vector3(a.x, 0, a.y) - d);
+			points.push_back(Vector3(b.x, 0, b.y) - d);
+
+			if (i % 90 == 0) {
+
+				points.push_back(Vector3(a.x, 0, a.y) + d);
+				points.push_back(Vector3(a.x, 0, a.y) - d);
+			}
+		}
+
+		add_lines(points, material);
+
+		Vector<Vector3> collision_segments;
+
+		for (int i = 0; i < 64; i++) {
+
+			float ra = i * Math_PI * 2.0 / 64.0;
+			float rb = (i + 1) * Math_PI * 2.0 / 64.0;
+			Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius;
+			Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius;
+
+			collision_segments.push_back(Vector3(a.x, 0, a.y) + d);
+			collision_segments.push_back(Vector3(b.x, 0, b.y) + d);
+
+			collision_segments.push_back(Vector3(a.x, 0, a.y) - d);
+			collision_segments.push_back(Vector3(b.x, 0, b.y) - d);
+
+			if (i % 16 == 0) {
+
+				collision_segments.push_back(Vector3(a.x, 0, a.y) + d);
+				collision_segments.push_back(Vector3(a.x, 0, a.y) - d);
+			}
+		}
+
+		add_collision_segments(collision_segments);
+
+		Vector<Vector3> handles;
+		handles.push_back(Vector3(cs->get_radius(), 0, 0));
+		handles.push_back(Vector3(0, cs->get_height() * 0.5, 0));
+		add_handles(handles);
+	}
+
 	if (Object::cast_to<PlaneShape>(*s)) {
 
 		Ref<PlaneShape> ps = s;

+ 4 - 0
modules/bullet/bullet_physics_server.cpp

@@ -113,6 +113,10 @@ RID BulletPhysicsServer::shape_create(ShapeType p_shape) {
 
 			shape = bulletnew(CapsuleShapeBullet);
 		} break;
+		case SHAPE_CYLINDER: {
+
+			shape = bulletnew(CylinderShapeBullet);
+		} break;
 		case SHAPE_CONVEX_POLYGON: {
 
 			shape = bulletnew(ConvexPolygonShapeBullet);

+ 1 - 0
modules/bullet/rigid_body_bullet.cpp

@@ -226,6 +226,7 @@ void RigidBodyBullet::KinematicUtilities::copyAllOwnerShapes() {
 			case PhysicsServer::SHAPE_SPHERE:
 			case PhysicsServer::SHAPE_BOX:
 			case PhysicsServer::SHAPE_CAPSULE:
+			case PhysicsServer::SHAPE_CYLINDER:
 			case PhysicsServer::SHAPE_CONVEX_POLYGON:
 			case PhysicsServer::SHAPE_RAY: {
 				shapes[i].shape = static_cast<btConvexShape *>(shape_wrapper->shape->create_bt_shape(owner_scale * shape_wrapper->scale, safe_margin));

+ 37 - 0
modules/bullet/shape_bullet.cpp

@@ -113,6 +113,10 @@ btCapsuleShapeZ *ShapeBullet::create_shape_capsule(btScalar radius, btScalar hei
 	return bulletnew(btCapsuleShapeZ(radius, height));
 }
 
+btCylinderShape *ShapeBullet::create_shape_cylinder(btScalar radius, btScalar height) {
+	return bulletnew(btCylinderShape(btVector3(radius, height / 2.0, radius)));
+}
+
 btConvexPointCloudShape *ShapeBullet::create_shape_convex(btAlignedObjectArray<btVector3> &p_vertices, const btVector3 &p_local_scaling) {
 	return bulletnew(btConvexPointCloudShape(&p_vertices[0], p_vertices.size(), p_local_scaling));
 }
@@ -254,6 +258,39 @@ btCollisionShape *CapsuleShapeBullet::create_bt_shape(const btVector3 &p_implici
 	return prepare(ShapeBullet::create_shape_capsule(radius * p_implicit_scale[0] + p_margin, height * p_implicit_scale[1] + p_margin));
 }
 
+/* Cylinder */
+
+CylinderShapeBullet::CylinderShapeBullet() :
+		ShapeBullet() {}
+
+void CylinderShapeBullet::set_data(const Variant &p_data) {
+	Dictionary d = p_data;
+	ERR_FAIL_COND(!d.has("radius"));
+	ERR_FAIL_COND(!d.has("height"));
+	setup(d["height"], d["radius"]);
+}
+
+Variant CylinderShapeBullet::get_data() const {
+	Dictionary d;
+	d["radius"] = radius;
+	d["height"] = height;
+	return d;
+}
+
+PhysicsServer::ShapeType CylinderShapeBullet::get_type() const {
+	return PhysicsServer::SHAPE_CYLINDER;
+}
+
+void CylinderShapeBullet::setup(real_t p_height, real_t p_radius) {
+	radius = p_radius;
+	height = p_height;
+	notifyShapeChanged();
+}
+
+btCollisionShape *CylinderShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin) {
+	return prepare(ShapeBullet::create_shape_cylinder(radius * p_implicit_scale[0] + p_margin, height * p_implicit_scale[1] + p_margin));
+}
+
 /* Convex polygon */
 
 ConvexPolygonShapeBullet::ConvexPolygonShapeBullet() :

+ 20 - 0
modules/bullet/shape_bullet.h

@@ -82,6 +82,7 @@ public:
 	static class btSphereShape *create_shape_sphere(btScalar radius);
 	static class btBoxShape *create_shape_box(const btVector3 &boxHalfExtents);
 	static class btCapsuleShapeZ *create_shape_capsule(btScalar radius, btScalar height);
+	static class btCylinderShape *create_shape_cylinder(btScalar radius, btScalar height);
 	/// IMPORTANT: Remember to delete the shape interface by calling: delete my_shape->getMeshInterface();
 	static class btConvexPointCloudShape *create_shape_convex(btAlignedObjectArray<btVector3> &p_vertices, const btVector3 &p_local_scaling = btVector3(1, 1, 1));
 	static class btScaledBvhTriangleMeshShape *create_shape_concave(btBvhTriangleMeshShape *p_mesh_shape, const btVector3 &p_local_scaling = btVector3(1, 1, 1));
@@ -158,6 +159,25 @@ private:
 	void setup(real_t p_height, real_t p_radius);
 };
 
+class CylinderShapeBullet : public ShapeBullet {
+
+	real_t height;
+	real_t radius;
+
+public:
+	CylinderShapeBullet();
+
+	_FORCE_INLINE_ real_t get_height() { return height; }
+	_FORCE_INLINE_ real_t get_radius() { return radius; }
+	virtual void set_data(const Variant &p_data);
+	virtual Variant get_data() const;
+	virtual PhysicsServer::ShapeType get_type() const;
+	virtual btCollisionShape *create_bt_shape(const btVector3 &p_implicit_scale, real_t p_margin = 0);
+
+private:
+	void setup(real_t p_height, real_t p_radius);
+};
+
 class ConvexPolygonShapeBullet : public ShapeBullet {
 
 public:

+ 2 - 0
scene/register_scene_types.cpp

@@ -128,6 +128,7 @@
 #include "scene/resources/concave_polygon_shape_2d.h"
 #include "scene/resources/convex_polygon_shape.h"
 #include "scene/resources/convex_polygon_shape_2d.h"
+#include "scene/resources/cylinder_shape.h"
 #include "scene/resources/default_theme/default_theme.h"
 #include "scene/resources/dynamic_font.h"
 #include "scene/resources/dynamic_font_stb.h"
@@ -510,6 +511,7 @@ void register_scene_types() {
 	ClassDB::register_class<SphereShape>();
 	ClassDB::register_class<BoxShape>();
 	ClassDB::register_class<CapsuleShape>();
+	ClassDB::register_class<CylinderShape>();
 	ClassDB::register_class<PlaneShape>();
 	ClassDB::register_class<ConvexPolygonShape>();
 	ClassDB::register_class<ConcavePolygonShape>();

+ 116 - 0
scene/resources/cylinder_shape.cpp

@@ -0,0 +1,116 @@
+/*************************************************************************/
+/*  cylinder_shape.cpp                                                   */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)    */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#include "cylinder_shape.h"
+#include "servers/physics_server.h"
+
+Vector<Vector3> CylinderShape::_gen_debug_mesh_lines() {
+
+	float radius = get_radius();
+	float height = get_height();
+
+	Vector<Vector3> points;
+
+	Vector3 d(0, height * 0.5, 0);
+	for (int i = 0; i < 360; i++) {
+
+		float ra = Math::deg2rad((float)i);
+		float rb = Math::deg2rad((float)i + 1);
+		Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius;
+		Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * radius;
+
+		points.push_back(Vector3(a.x, 0, a.y) + d);
+		points.push_back(Vector3(b.x, 0, b.y) + d);
+
+		points.push_back(Vector3(a.x, 0, a.y) - d);
+		points.push_back(Vector3(b.x, 0, b.y) - d);
+
+		if (i % 90 == 0) {
+
+			points.push_back(Vector3(a.x, 0, a.y) + d);
+			points.push_back(Vector3(a.x, 0, a.y) - d);
+		}
+	}
+
+	return points;
+}
+
+void CylinderShape::_update_shape() {
+
+	Dictionary d;
+	d["radius"] = radius;
+	d["height"] = height;
+	PhysicsServer::get_singleton()->shape_set_data(get_shape(), d);
+}
+
+void CylinderShape::set_radius(float p_radius) {
+
+	radius = p_radius;
+	_update_shape();
+	notify_change_to_owners();
+	_change_notify("radius");
+}
+
+float CylinderShape::get_radius() const {
+
+	return radius;
+}
+
+void CylinderShape::set_height(float p_height) {
+
+	height = p_height;
+	_update_shape();
+	notify_change_to_owners();
+	_change_notify("height");
+}
+
+float CylinderShape::get_height() const {
+
+	return height;
+}
+
+void CylinderShape::_bind_methods() {
+
+	ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CylinderShape::set_radius);
+	ClassDB::bind_method(D_METHOD("get_radius"), &CylinderShape::get_radius);
+	ClassDB::bind_method(D_METHOD("set_height", "height"), &CylinderShape::set_height);
+	ClassDB::bind_method(D_METHOD("get_height"), &CylinderShape::get_height);
+
+	ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), "set_radius", "get_radius");
+	ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), "set_height", "get_height");
+}
+
+CylinderShape::CylinderShape() :
+		Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CYLINDER)) {
+
+	radius = 1.0;
+	height = 2.0;
+	_update_shape();
+}

+ 57 - 0
scene/resources/cylinder_shape.h

@@ -0,0 +1,57 @@
+/*************************************************************************/
+/*  cylinder_shape.h                                                     */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)    */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#ifndef CYLINDER_SHAPE_H
+#define CYLINDER_SHAPE_H
+
+#include "scene/resources/shape.h"
+
+class CylinderShape : public Shape {
+
+	GDCLASS(CylinderShape, Shape);
+	float radius;
+	float height;
+
+protected:
+	static void _bind_methods();
+	virtual void _update_shape();
+
+	virtual Vector<Vector3> _gen_debug_mesh_lines();
+
+public:
+	void set_radius(float p_radius);
+	float get_radius() const;
+	void set_height(float p_height);
+	float get_height() const;
+
+	CylinderShape();
+};
+
+#endif // CYLINDER_SHAPE_H

+ 5 - 0
servers/physics/physics_server_sw.cpp

@@ -65,6 +65,11 @@ RID PhysicsServerSW::shape_create(ShapeType p_shape) {
 
 			shape = memnew(CapsuleShapeSW);
 		} break;
+		case SHAPE_CYLINDER: {
+
+			ERR_EXPLAIN("CylinderShape is not supported in GodotPhysics. Please switch to Bullet in the Project Settings.");
+			ERR_FAIL_V(RID());
+		} break;
 		case SHAPE_CONVEX_POLYGON: {
 
 			shape = memnew(ConvexPolygonShapeSW);

+ 1 - 0
servers/physics_server.cpp

@@ -664,6 +664,7 @@ void PhysicsServer::_bind_methods() {
 	BIND_ENUM_CONSTANT(SHAPE_SPHERE);
 	BIND_ENUM_CONSTANT(SHAPE_BOX);
 	BIND_ENUM_CONSTANT(SHAPE_CAPSULE);
+	BIND_ENUM_CONSTANT(SHAPE_CYLINDER);
 	BIND_ENUM_CONSTANT(SHAPE_CONVEX_POLYGON);
 	BIND_ENUM_CONSTANT(SHAPE_CONCAVE_POLYGON);
 	BIND_ENUM_CONSTANT(SHAPE_HEIGHTMAP);

+ 1 - 0
servers/physics_server.h

@@ -228,6 +228,7 @@ public:
 		SHAPE_SPHERE, ///< float:"radius"
 		SHAPE_BOX, ///< vec3:"extents"
 		SHAPE_CAPSULE, ///< dict( float:"radius", float:"height"):capsule
+		SHAPE_CYLINDER, ///< dict( float:"radius", float:"height"):cylinder
 		SHAPE_CONVEX_POLYGON, ///< array of planes:"planes"
 		SHAPE_CONCAVE_POLYGON, ///< vector3 array:"triangles" , or Dictionary with "indices" (int array) and "triangles" (Vector3 array)
 		SHAPE_HEIGHTMAP, ///< dict( int:"width", int:"depth",float:"cell_size", float_array:"heights"