Merge pull request #104736 from szunami/master
Add one-way collision direction for CollisionShape2Ds
This commit is contained in:
commit
c44b01cd1f
25 changed files with 200 additions and 29 deletions
|
|
@ -73,6 +73,13 @@
|
|||
Returns the object's [RID].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_shape_owner_one_way_collision_direction" qualifiers="const">
|
||||
<return type="Vector2" />
|
||||
<param index="0" name="owner_id" type="int" />
|
||||
<description>
|
||||
Returns the [code]one_way_collision_direction[/code] of the shape owner identified by the given [param owner_id].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_shape_owner_one_way_collision_margin" qualifiers="const">
|
||||
<return type="float" />
|
||||
<param index="0" name="owner_id" type="int" />
|
||||
|
|
@ -206,6 +213,14 @@
|
|||
If [param enable] is [code]true[/code], collisions for the shape owner originating from this [CollisionObject2D] will not be reported to collided with [CollisionObject2D]s.
|
||||
</description>
|
||||
</method>
|
||||
<method name="shape_owner_set_one_way_collision_direction">
|
||||
<return type="void" />
|
||||
<param index="0" name="owner_id" type="int" />
|
||||
<param index="1" name="p_direction" type="Vector2" />
|
||||
<description>
|
||||
Sets the [code]one_way_collision_direction[/code] of the shape owner identified by the given [param owner_id] to [param p_direction].
|
||||
</description>
|
||||
</method>
|
||||
<method name="shape_owner_set_one_way_collision_margin">
|
||||
<return type="void" />
|
||||
<param index="0" name="owner_id" type="int" />
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@
|
|||
<member name="one_way_collision" type="bool" setter="set_one_way_collision" getter="is_one_way_collision_enabled" default="false">
|
||||
If [code]true[/code], only edges that face up, relative to [CollisionPolygon2D]'s rotation, will collide with other objects.
|
||||
[b]Note:[/b] This property has no effect if this [CollisionPolygon2D] is a child of an [Area2D] node.
|
||||
[b]Note:[/b] The one way collision direction can be configured by setting [member one_way_collision_direction].
|
||||
</member>
|
||||
<member name="one_way_collision_direction" type="Vector2" setter="set_one_way_collision_direction" getter="get_one_way_collision_direction" default="Vector2(0, 1)">
|
||||
The direction used for one-way collision.
|
||||
</member>
|
||||
<member name="one_way_collision_margin" type="float" setter="set_one_way_collision_margin" getter="get_one_way_collision_margin" default="1.0">
|
||||
The margin used for one-way collision (in pixels). Higher values will make the shape thicker, and work better for colliders that enter the polygon at a high velocity.
|
||||
|
|
|
|||
|
|
@ -23,6 +23,10 @@
|
|||
<member name="one_way_collision" type="bool" setter="set_one_way_collision" getter="is_one_way_collision_enabled" default="false">
|
||||
Sets whether this collision shape should only detect collision on one side (top or bottom).
|
||||
[b]Note:[/b] This property has no effect if this [CollisionShape2D] is a child of an [Area2D] node.
|
||||
[b]Note:[/b] The one way collision direction can be configured by setting [member one_way_collision_direction].
|
||||
</member>
|
||||
<member name="one_way_collision_direction" type="Vector2" setter="set_one_way_collision_direction" getter="get_one_way_collision_direction" default="Vector2(0, 1)">
|
||||
The direction used for one-way collision.
|
||||
</member>
|
||||
<member name="one_way_collision_margin" type="float" setter="set_one_way_collision_margin" getter="get_one_way_collision_margin" default="1.0">
|
||||
The margin used for one-way collision (in pixels). Higher values will make the shape thicker, and work better for colliders that enter the shape at a high velocity.
|
||||
|
|
|
|||
|
|
@ -651,8 +651,9 @@
|
|||
<param index="1" name="shape_idx" type="int" />
|
||||
<param index="2" name="enable" type="bool" />
|
||||
<param index="3" name="margin" type="float" />
|
||||
<param index="4" name="direction" type="Vector2" default="Vector2(0, 1)" />
|
||||
<description>
|
||||
Sets the one-way collision properties of the body's shape with the given index. If [param enable] is [code]true[/code], the one-way collision direction given by the shape's local upward axis [code]body_get_shape_transform(body, shape_idx).y[/code] will be used to ignore collisions with the shape in the opposite direction, and to ensure depenetration of kinematic bodies happens in this direction.
|
||||
Sets the one-way collision properties of the body's shape with the given index. If [param enable] is [code]true[/code], the one-way collision direction given by [param direction] in the shape's local space (that is [code]body_get_shape_transform(body, shape_idx).basis_xform(direction).normalized()[/code] in the body's local space) will be used to ignore collisions with the shape in the opposite direction, and to ensure depenetration of kinematic bodies happens in this direction.
|
||||
</description>
|
||||
</method>
|
||||
<method name="body_set_shape_disabled">
|
||||
|
|
|
|||
|
|
@ -668,6 +668,7 @@
|
|||
<param index="1" name="shape_idx" type="int" />
|
||||
<param index="2" name="enable" type="bool" />
|
||||
<param index="3" name="margin" type="float" />
|
||||
<param index="4" name="direction" type="Vector2" />
|
||||
<description>
|
||||
Overridable version of [method PhysicsServer2D.body_set_shape_as_one_way_collision].
|
||||
</description>
|
||||
|
|
|
|||
6
misc/extension_api_validation/4.6-stable/GH-104736.txt
Normal file
6
misc/extension_api_validation/4.6-stable/GH-104736.txt
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
GH-104736
|
||||
---------
|
||||
Validate extension JSON: Error: Field 'classes/PhysicsServer2D/methods/body_set_shape_as_one_way_collision/arguments': size changed value in new API, from 4 to 5.
|
||||
Validate extension JSON: Error: Field 'classes/PhysicsServer2DExtension/methods/_body_set_shape_as_one_way_collision/arguments': size changed value in new API, from 4 to 5.
|
||||
|
||||
Argument added. Compatibility methods registered.
|
||||
|
|
@ -221,7 +221,8 @@ bool GodotBodyPair2D::_test_ccd(real_t p_step, GodotBody2D *p_A, int p_shape_A,
|
|||
|
||||
// Check one-way collision based on motion direction.
|
||||
if (p_A->get_shape(p_shape_A)->allows_one_way_collision() && p_B->is_shape_set_as_one_way_collision(p_shape_B)) {
|
||||
Vector2 direction = predicted_xform_B.columns[1].normalized();
|
||||
Vector2 direction = predicted_xform_B.basis_xform(p_B->get_shape_one_way_collision_direction(p_shape_B)).normalized();
|
||||
|
||||
if (direction.dot(mnormal) < CMP_EPSILON) {
|
||||
collided = false;
|
||||
oneway_disabled = true;
|
||||
|
|
@ -318,7 +319,8 @@ bool GodotBodyPair2D::setup(real_t p_step) {
|
|||
|
||||
if (!prev_collided) {
|
||||
if (shape_B_ptr->allows_one_way_collision() && A->is_shape_set_as_one_way_collision(shape_A)) {
|
||||
Vector2 direction = xform_A.columns[1].normalized();
|
||||
Vector2 direction = xform_A.basis_xform(A->get_shape_one_way_collision_direction(shape_A)).normalized();
|
||||
|
||||
bool valid = false;
|
||||
for (int i = 0; i < contact_count; i++) {
|
||||
Contact &c = contacts[i];
|
||||
|
|
@ -336,7 +338,8 @@ bool GodotBodyPair2D::setup(real_t p_step) {
|
|||
}
|
||||
|
||||
if (shape_A_ptr->allows_one_way_collision() && B->is_shape_set_as_one_way_collision(shape_B)) {
|
||||
Vector2 direction = xform_B.columns[1].normalized();
|
||||
Vector2 direction = xform_B.basis_xform(B->get_shape_one_way_collision_direction(shape_B)).normalized();
|
||||
|
||||
bool valid = false;
|
||||
for (int i = 0; i < contact_count; i++) {
|
||||
Contact &c = contacts[i];
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ void GodotCollisionObject2D::add_shape(GodotShape2D *p_shape, const Transform2D
|
|||
s.disabled = p_disabled;
|
||||
s.one_way_collision = false;
|
||||
s.one_way_collision_margin = 0;
|
||||
s.one_way_collision_direction = Vector2(0, 1);
|
||||
shapes.push_back(s);
|
||||
p_shape->add_owner(this);
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ private:
|
|||
bool disabled = false;
|
||||
bool one_way_collision = false;
|
||||
real_t one_way_collision_margin = 0.0;
|
||||
Vector2 one_way_collision_direction = Vector2(0.0, 1.0);
|
||||
};
|
||||
|
||||
Vector<Shape> shapes;
|
||||
|
|
@ -139,10 +140,11 @@ public:
|
|||
return shapes[p_idx].disabled;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void set_shape_as_one_way_collision(int p_idx, bool p_one_way_collision, real_t p_margin) {
|
||||
_FORCE_INLINE_ void set_shape_as_one_way_collision(int p_idx, bool p_one_way_collision, real_t p_margin, const Vector2 &p_direction) {
|
||||
CRASH_BAD_INDEX(p_idx, shapes.size());
|
||||
shapes.write[p_idx].one_way_collision = p_one_way_collision;
|
||||
shapes.write[p_idx].one_way_collision_margin = p_margin;
|
||||
shapes.write[p_idx].one_way_collision_direction = p_direction;
|
||||
}
|
||||
_FORCE_INLINE_ bool is_shape_set_as_one_way_collision(int p_idx) const {
|
||||
CRASH_BAD_INDEX(p_idx, shapes.size());
|
||||
|
|
@ -154,6 +156,11 @@ public:
|
|||
return shapes[p_idx].one_way_collision_margin;
|
||||
}
|
||||
|
||||
Vector2 get_shape_one_way_collision_direction(int p_idx) const {
|
||||
CRASH_BAD_INDEX(p_idx, shapes.size());
|
||||
return shapes[p_idx].one_way_collision_direction;
|
||||
}
|
||||
|
||||
void set_collision_mask(uint32_t p_mask) {
|
||||
collision_mask = p_mask;
|
||||
_shape_changed();
|
||||
|
|
|
|||
|
|
@ -656,13 +656,13 @@ void GodotPhysicsServer2D::body_set_shape_disabled(RID p_body, int p_shape_idx,
|
|||
body->set_shape_disabled(p_shape_idx, p_disabled);
|
||||
}
|
||||
|
||||
void GodotPhysicsServer2D::body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable, real_t p_margin) {
|
||||
void GodotPhysicsServer2D::body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable, real_t p_margin, const Vector2 &p_direction) {
|
||||
GodotBody2D *body = body_owner.get_or_null(p_body);
|
||||
ERR_FAIL_NULL(body);
|
||||
ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count());
|
||||
FLUSH_QUERY_CHECK(body);
|
||||
|
||||
body->set_shape_as_one_way_collision(p_shape_idx, p_enable, p_margin);
|
||||
body->set_shape_as_one_way_collision(p_shape_idx, p_enable, p_margin, p_direction);
|
||||
}
|
||||
|
||||
void GodotPhysicsServer2D::body_set_continuous_collision_detection_mode(RID p_body, CCDMode p_mode) {
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ public:
|
|||
virtual void body_clear_shapes(RID p_body) override;
|
||||
|
||||
virtual void body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) override;
|
||||
virtual void body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable, real_t p_margin) override;
|
||||
virtual void body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable, real_t p_margin, const Vector2 &p_direction) override;
|
||||
|
||||
virtual void body_attach_object_instance_id(RID p_body, ObjectID p_id) override;
|
||||
virtual ObjectID body_get_object_instance_id(RID p_body) const override;
|
||||
|
|
|
|||
|
|
@ -637,7 +637,7 @@ bool GodotSpace2D::test_body_motion(GodotBody2D *p_body, const PhysicsServer2D::
|
|||
Transform2D col_obj_shape_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
|
||||
|
||||
if (body_shape->allows_one_way_collision() && col_obj->is_shape_set_as_one_way_collision(shape_idx)) {
|
||||
cbk.valid_dir = col_obj_shape_xform.columns[1].normalized();
|
||||
cbk.valid_dir = col_obj_shape_xform.basis_xform(col_obj->get_shape_one_way_collision_direction(shape_idx)).normalized();
|
||||
|
||||
real_t owc_margin = col_obj->get_shape_one_way_collision_margin(shape_idx);
|
||||
cbk.valid_depth = MAX(owc_margin, margin); //user specified, but never less than actual margin or it won't work
|
||||
|
|
@ -802,7 +802,8 @@ bool GodotSpace2D::test_body_motion(GodotBody2D *p_body, const PhysicsServer2D::
|
|||
//test initial overlap
|
||||
if (GodotCollisionSolver2D::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, nullptr, 0)) {
|
||||
if (body_shape->allows_one_way_collision() && col_obj->is_shape_set_as_one_way_collision(col_shape_idx)) {
|
||||
Vector2 direction = col_obj_shape_xform.columns[1].normalized();
|
||||
Vector2 direction = col_obj_shape_xform.basis_xform(col_obj->get_shape_one_way_collision_direction(col_shape_idx)).normalized();
|
||||
|
||||
if (motion_normal.dot(direction) < 0) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -852,8 +853,7 @@ bool GodotSpace2D::test_body_motion(GodotBody2D *p_body, const PhysicsServer2D::
|
|||
cbk.amount = 0;
|
||||
cbk.passed = 0;
|
||||
cbk.ptr = cd;
|
||||
cbk.valid_dir = col_obj_shape_xform.columns[1].normalized();
|
||||
|
||||
cbk.valid_dir = col_obj_shape_xform.basis_xform(col_obj->get_shape_one_way_collision_direction(col_shape_idx)).normalized();
|
||||
cbk.valid_depth = 10e20;
|
||||
|
||||
Vector2 sep = motion_normal; //important optimization for this to work fast enough
|
||||
|
|
@ -943,7 +943,7 @@ bool GodotSpace2D::test_body_motion(GodotBody2D *p_body, const PhysicsServer2D::
|
|||
Transform2D col_obj_shape_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
|
||||
|
||||
if (body_shape->allows_one_way_collision() && col_obj->is_shape_set_as_one_way_collision(shape_idx)) {
|
||||
rcd.valid_dir = col_obj_shape_xform.columns[1].normalized();
|
||||
rcd.valid_dir = col_obj_shape_xform.basis_xform(col_obj->get_shape_one_way_collision_direction(shape_idx)).normalized();
|
||||
|
||||
real_t owc_margin = col_obj->get_shape_one_way_collision_margin(shape_idx);
|
||||
rcd.valid_depth = MAX(owc_margin, margin); //user specified, but never less than actual margin or it won't work
|
||||
|
|
|
|||
|
|
@ -346,7 +346,7 @@ void CollisionObject2D::shape_owner_set_one_way_collision(uint32_t p_owner, bool
|
|||
ShapeData &sd = shapes[p_owner];
|
||||
sd.one_way_collision = p_enable;
|
||||
for (int i = 0; i < sd.shapes.size(); i++) {
|
||||
PhysicsServer2D::get_singleton()->body_set_shape_as_one_way_collision(rid, sd.shapes[i].index, sd.one_way_collision, sd.one_way_collision_margin);
|
||||
PhysicsServer2D::get_singleton()->body_set_shape_as_one_way_collision(rid, sd.shapes[i].index, sd.one_way_collision, sd.one_way_collision_margin, sd.one_way_collision_direction);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -366,7 +366,21 @@ void CollisionObject2D::shape_owner_set_one_way_collision_margin(uint32_t p_owne
|
|||
ShapeData &sd = shapes[p_owner];
|
||||
sd.one_way_collision_margin = p_margin;
|
||||
for (int i = 0; i < sd.shapes.size(); i++) {
|
||||
PhysicsServer2D::get_singleton()->body_set_shape_as_one_way_collision(rid, sd.shapes[i].index, sd.one_way_collision, sd.one_way_collision_margin);
|
||||
PhysicsServer2D::get_singleton()->body_set_shape_as_one_way_collision(rid, sd.shapes[i].index, sd.one_way_collision, sd.one_way_collision_margin, sd.one_way_collision_direction);
|
||||
}
|
||||
}
|
||||
|
||||
void CollisionObject2D::shape_owner_set_one_way_collision_direction(uint32_t p_owner, const Vector2 &p_direction) {
|
||||
if (area) {
|
||||
return; //not for areas
|
||||
}
|
||||
|
||||
ERR_FAIL_COND(!shapes.has(p_owner));
|
||||
|
||||
ShapeData &sd = shapes[p_owner];
|
||||
sd.one_way_collision_direction = p_direction.normalized();
|
||||
for (int i = 0; i < sd.shapes.size(); i++) {
|
||||
PhysicsServer2D::get_singleton()->body_set_shape_as_one_way_collision(rid, sd.shapes[i].index, sd.one_way_collision, sd.one_way_collision_margin, sd.one_way_collision_direction);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -376,6 +390,12 @@ real_t CollisionObject2D::get_shape_owner_one_way_collision_margin(uint32_t p_ow
|
|||
return shapes[p_owner].one_way_collision_margin;
|
||||
}
|
||||
|
||||
Vector2 CollisionObject2D::get_shape_owner_one_way_collision_direction(uint32_t p_owner) const {
|
||||
ERR_FAIL_COND_V(!shapes.has(p_owner), Vector2());
|
||||
|
||||
return shapes[p_owner].one_way_collision_direction;
|
||||
}
|
||||
|
||||
void CollisionObject2D::get_shape_owners(List<uint32_t> *r_owners) {
|
||||
for (const KeyValue<uint32_t, ShapeData> &E : shapes) {
|
||||
r_owners->push_back(E.key);
|
||||
|
|
@ -619,6 +639,8 @@ void CollisionObject2D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("is_shape_owner_one_way_collision_enabled", "owner_id"), &CollisionObject2D::is_shape_owner_one_way_collision_enabled);
|
||||
ClassDB::bind_method(D_METHOD("shape_owner_set_one_way_collision_margin", "owner_id", "margin"), &CollisionObject2D::shape_owner_set_one_way_collision_margin);
|
||||
ClassDB::bind_method(D_METHOD("get_shape_owner_one_way_collision_margin", "owner_id"), &CollisionObject2D::get_shape_owner_one_way_collision_margin);
|
||||
ClassDB::bind_method(D_METHOD("get_shape_owner_one_way_collision_direction", "owner_id"), &CollisionObject2D::get_shape_owner_one_way_collision_direction);
|
||||
ClassDB::bind_method(D_METHOD("shape_owner_set_one_way_collision_direction", "owner_id", "p_direction"), &CollisionObject2D::shape_owner_set_one_way_collision_direction);
|
||||
ClassDB::bind_method(D_METHOD("shape_owner_add_shape", "owner_id", "shape"), &CollisionObject2D::shape_owner_add_shape);
|
||||
ClassDB::bind_method(D_METHOD("shape_owner_get_shape_count", "owner_id"), &CollisionObject2D::shape_owner_get_shape_count);
|
||||
ClassDB::bind_method(D_METHOD("shape_owner_get_shape", "owner_id", "shape_id"), &CollisionObject2D::shape_owner_get_shape);
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ private:
|
|||
bool disabled = false;
|
||||
bool one_way_collision = false;
|
||||
real_t one_way_collision_margin = 0.0;
|
||||
Vector2 one_way_collision_direction = Vector2(0.0, 1.0);
|
||||
};
|
||||
|
||||
int total_subshapes = 0;
|
||||
|
|
@ -154,6 +155,9 @@ public:
|
|||
void shape_owner_set_one_way_collision_margin(uint32_t p_owner, real_t p_margin);
|
||||
real_t get_shape_owner_one_way_collision_margin(uint32_t p_owner) const;
|
||||
|
||||
void shape_owner_set_one_way_collision_direction(uint32_t p_owner, const Vector2 &p_direction);
|
||||
Vector2 get_shape_owner_one_way_collision_direction(uint32_t p_owner) const;
|
||||
|
||||
void shape_owner_add_shape(uint32_t p_owner, RequiredParam<Shape2D> rp_shape);
|
||||
int shape_owner_get_shape_count(uint32_t p_owner) const;
|
||||
Ref<Shape2D> shape_owner_get_shape(uint32_t p_owner, int p_shape) const;
|
||||
|
|
|
|||
|
|
@ -151,14 +151,14 @@ void CollisionPolygon2D::_notification(int p_what) {
|
|||
if (one_way_collision) {
|
||||
Color dcol = get_tree()->get_debug_collisions_color(); //0.9,0.2,0.2,0.4);
|
||||
dcol.a = 1.0;
|
||||
Vector2 line_to(0, 20);
|
||||
Vector2 line_to = 20.0 * one_way_collision_direction;
|
||||
draw_line(Vector2(), line_to, dcol, 3);
|
||||
real_t tsize = 8;
|
||||
|
||||
Vector<Vector2> pts = {
|
||||
line_to + Vector2(0, tsize),
|
||||
line_to + Vector2(Math::SQRT12 * tsize, 0),
|
||||
line_to + Vector2(-Math::SQRT12 * tsize, 0)
|
||||
line_to + tsize * one_way_collision_direction,
|
||||
line_to + Math::SQRT12 * tsize * one_way_collision_direction.orthogonal(),
|
||||
line_to - Math::SQRT12 * tsize * one_way_collision_direction.orthogonal(),
|
||||
};
|
||||
|
||||
Vector<Color> cols{ dcol, dcol, dcol };
|
||||
|
|
@ -292,6 +292,22 @@ real_t CollisionPolygon2D::get_one_way_collision_margin() const {
|
|||
return one_way_collision_margin;
|
||||
}
|
||||
|
||||
void CollisionPolygon2D::set_one_way_collision_direction(const Vector2 &p_direction) {
|
||||
if (p_direction == one_way_collision_direction) {
|
||||
return;
|
||||
}
|
||||
|
||||
one_way_collision_direction = p_direction.normalized();
|
||||
queue_redraw();
|
||||
if (collision_object) {
|
||||
collision_object->shape_owner_set_one_way_collision_direction(owner_id, p_direction);
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 CollisionPolygon2D::get_one_way_collision_direction() const {
|
||||
return one_way_collision_direction;
|
||||
}
|
||||
|
||||
void CollisionPolygon2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_polygon", "polygon"), &CollisionPolygon2D::set_polygon);
|
||||
ClassDB::bind_method(D_METHOD("get_polygon"), &CollisionPolygon2D::get_polygon);
|
||||
|
|
@ -304,6 +320,8 @@ void CollisionPolygon2D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("is_one_way_collision_enabled"), &CollisionPolygon2D::is_one_way_collision_enabled);
|
||||
ClassDB::bind_method(D_METHOD("set_one_way_collision_margin", "margin"), &CollisionPolygon2D::set_one_way_collision_margin);
|
||||
ClassDB::bind_method(D_METHOD("get_one_way_collision_margin"), &CollisionPolygon2D::get_one_way_collision_margin);
|
||||
ClassDB::bind_method(D_METHOD("set_one_way_collision_direction", "direction"), &CollisionPolygon2D::set_one_way_collision_direction);
|
||||
ClassDB::bind_method(D_METHOD("get_one_way_collision_direction"), &CollisionPolygon2D::get_one_way_collision_direction);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "build_mode", PROPERTY_HINT_ENUM, "Solids,Segments"), "set_build_mode", "get_build_mode");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon");
|
||||
|
|
@ -312,6 +330,7 @@ void CollisionPolygon2D::_bind_methods() {
|
|||
ADD_GROUP("One Way Collision", "one_way_collision");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_way_collision", PROPERTY_HINT_GROUP_ENABLE), "set_one_way_collision", "is_one_way_collision_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "one_way_collision_margin", PROPERTY_HINT_RANGE, "0,128,0.1,suffix:px"), "set_one_way_collision_margin", "get_one_way_collision_margin");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "one_way_collision_direction"), "set_one_way_collision_direction", "get_one_way_collision_direction");
|
||||
|
||||
BIND_ENUM_CONSTANT(BUILD_SOLIDS);
|
||||
BIND_ENUM_CONSTANT(BUILD_SEGMENTS);
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ protected:
|
|||
bool disabled = false;
|
||||
bool one_way_collision = false;
|
||||
real_t one_way_collision_margin = 1.0;
|
||||
Vector2 one_way_collision_direction = Vector2(0.0, 1.0);
|
||||
|
||||
Vector<Vector<Vector2>> _decompose_in_convex();
|
||||
|
||||
|
|
@ -87,6 +88,9 @@ public:
|
|||
void set_one_way_collision_margin(real_t p_margin);
|
||||
real_t get_one_way_collision_margin() const;
|
||||
|
||||
void set_one_way_collision_direction(const Vector2 &p_direction);
|
||||
Vector2 get_one_way_collision_direction() const;
|
||||
|
||||
CollisionPolygon2D();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ void CollisionShape2D::_update_in_shape_owner(bool p_xform_only) {
|
|||
collision_object->shape_owner_set_disabled(owner_id, disabled);
|
||||
collision_object->shape_owner_set_one_way_collision(owner_id, one_way_collision);
|
||||
collision_object->shape_owner_set_one_way_collision_margin(owner_id, one_way_collision_margin);
|
||||
collision_object->shape_owner_set_one_way_collision_direction(owner_id, one_way_collision_direction);
|
||||
}
|
||||
|
||||
void CollisionShape2D::_notification(int p_what) {
|
||||
|
|
@ -114,14 +115,15 @@ void CollisionShape2D::_notification(int p_what) {
|
|||
if (disabled) {
|
||||
draw_col = draw_col.darkened(0.25);
|
||||
}
|
||||
Vector2 line_to(0, 20);
|
||||
|
||||
Vector2 line_to = 20.0 * one_way_collision_direction;
|
||||
draw_line(Vector2(), line_to, draw_col, 2);
|
||||
real_t tsize = 8;
|
||||
|
||||
Vector<Vector2> pts{
|
||||
line_to + Vector2(0, tsize),
|
||||
line_to + Vector2(Math::SQRT12 * tsize, 0),
|
||||
line_to + Vector2(-Math::SQRT12 * tsize, 0)
|
||||
line_to + tsize * one_way_collision_direction,
|
||||
line_to + Math::SQRT12 * tsize * one_way_collision_direction.orthogonal(),
|
||||
line_to - Math::SQRT12 * tsize * one_way_collision_direction.orthogonal(),
|
||||
};
|
||||
|
||||
Vector<Color> cols{ draw_col, draw_col, draw_col };
|
||||
|
|
@ -227,6 +229,22 @@ real_t CollisionShape2D::get_one_way_collision_margin() const {
|
|||
return one_way_collision_margin;
|
||||
}
|
||||
|
||||
void CollisionShape2D::set_one_way_collision_direction(const Vector2 &p_direction) {
|
||||
if (p_direction == one_way_collision_direction) {
|
||||
return;
|
||||
}
|
||||
|
||||
one_way_collision_direction = p_direction.normalized();
|
||||
if (collision_object) {
|
||||
collision_object->shape_owner_set_one_way_collision_direction(owner_id, p_direction.normalized());
|
||||
}
|
||||
queue_redraw();
|
||||
}
|
||||
|
||||
Vector2 CollisionShape2D::get_one_way_collision_direction() const {
|
||||
return one_way_collision_direction;
|
||||
}
|
||||
|
||||
Color CollisionShape2D::_get_default_debug_color() const {
|
||||
const SceneTree *st = SceneTree::get_singleton();
|
||||
return st ? st->get_debug_collisions_color() : Color(0.0, 0.0, 0.0, 0.0);
|
||||
|
|
@ -283,12 +301,15 @@ void CollisionShape2D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("is_one_way_collision_enabled"), &CollisionShape2D::is_one_way_collision_enabled);
|
||||
ClassDB::bind_method(D_METHOD("set_one_way_collision_margin", "margin"), &CollisionShape2D::set_one_way_collision_margin);
|
||||
ClassDB::bind_method(D_METHOD("get_one_way_collision_margin"), &CollisionShape2D::get_one_way_collision_margin);
|
||||
ClassDB::bind_method(D_METHOD("set_one_way_collision_direction", "p_direction"), &CollisionShape2D::set_one_way_collision_direction);
|
||||
ClassDB::bind_method(D_METHOD("get_one_way_collision_direction"), &CollisionShape2D::get_one_way_collision_direction);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, Shape2D::get_class_static()), "set_shape", "get_shape");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled");
|
||||
ADD_GROUP("One Way Collision", "one_way_collision");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_way_collision", PROPERTY_HINT_GROUP_ENABLE), "set_one_way_collision", "is_one_way_collision_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "one_way_collision_margin", PROPERTY_HINT_RANGE, "0,128,0.1,suffix:px"), "set_one_way_collision_margin", "get_one_way_collision_margin");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "one_way_collision_direction", PROPERTY_HINT_NONE, "suffix:px"), "set_one_way_collision_direction", "get_one_way_collision_direction");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_debug_color", "color"), &CollisionShape2D::set_debug_color);
|
||||
ClassDB::bind_method(D_METHOD("get_debug_color"), &CollisionShape2D::get_debug_color);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ class CollisionShape2D : public Node2D {
|
|||
bool disabled = false;
|
||||
bool one_way_collision = false;
|
||||
real_t one_way_collision_margin = 1.0;
|
||||
Vector2 one_way_collision_direction = Vector2(0.0, 1.0);
|
||||
|
||||
void _shape_changed();
|
||||
void _update_in_shape_owner(bool p_xform_only = false);
|
||||
|
|
@ -83,6 +84,9 @@ public:
|
|||
void set_one_way_collision_margin(real_t p_margin);
|
||||
real_t get_one_way_collision_margin() const;
|
||||
|
||||
void set_one_way_collision_direction(const Vector2 &p_direction);
|
||||
Vector2 get_one_way_collision_direction() const;
|
||||
|
||||
void set_debug_color(const Color &p_color);
|
||||
Color get_debug_color() const;
|
||||
|
||||
|
|
|
|||
41
servers/physics_2d/physics_server_2d.compat.inc
Normal file
41
servers/physics_2d/physics_server_2d.compat.inc
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/**************************************************************************/
|
||||
/* physics_server_2d.compat.inc */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* 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 DISABLE_DEPRECATED
|
||||
|
||||
void PhysicsServer2D::_body_set_shape_as_one_way_collision_bind_compat_104736(RID p_body, int p_shape_idx, bool p_enable, real_t p_margin) {
|
||||
body_set_shape_as_one_way_collision(p_body, p_shape_idx, p_enable, p_margin, Vector2(0, 1));
|
||||
}
|
||||
|
||||
void PhysicsServer2D::_bind_compatibility_methods() {
|
||||
ClassDB::bind_compatibility_method(D_METHOD("body_set_shape_as_one_way_collision", "body", "shape_idx", "enable", "margin"), &PhysicsServer2D::_body_set_shape_as_one_way_collision_bind_compat_104736);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -29,6 +29,7 @@
|
|||
/**************************************************************************/
|
||||
|
||||
#include "physics_server_2d.h"
|
||||
#include "physics_server_2d.compat.inc"
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/variant/typed_array.h"
|
||||
|
|
@ -704,7 +705,7 @@ void PhysicsServer2D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("body_clear_shapes", "body"), &PhysicsServer2D::body_clear_shapes);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("body_set_shape_disabled", "body", "shape_idx", "disabled"), &PhysicsServer2D::body_set_shape_disabled);
|
||||
ClassDB::bind_method(D_METHOD("body_set_shape_as_one_way_collision", "body", "shape_idx", "enable", "margin"), &PhysicsServer2D::body_set_shape_as_one_way_collision);
|
||||
ClassDB::bind_method(D_METHOD("body_set_shape_as_one_way_collision", "body", "shape_idx", "enable", "margin", "direction"), &PhysicsServer2D::body_set_shape_as_one_way_collision, Vector2(0, 1));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("body_attach_object_instance_id", "body", "id"), &PhysicsServer2D::body_attach_object_instance_id);
|
||||
ClassDB::bind_method(D_METHOD("body_get_object_instance_id", "body"), &PhysicsServer2D::body_get_object_instance_id);
|
||||
|
|
|
|||
|
|
@ -221,6 +221,11 @@ class PhysicsServer2D : public Object {
|
|||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
void _body_set_shape_as_one_way_collision_bind_compat_104736(RID p_body, int p_shape_idx, bool p_enable, real_t p_margin);
|
||||
static void _bind_compatibility_methods();
|
||||
#endif
|
||||
|
||||
public:
|
||||
static PhysicsServer2D *get_singleton();
|
||||
|
||||
|
|
@ -380,7 +385,7 @@ public:
|
|||
virtual Transform2D body_get_shape_transform(RID p_body, int p_shape_idx) const = 0;
|
||||
|
||||
virtual void body_set_shape_disabled(RID p_body, int p_shape, bool p_disabled) = 0;
|
||||
virtual void body_set_shape_as_one_way_collision(RID p_body, int p_shape, bool p_enabled, real_t p_margin = 0) = 0;
|
||||
virtual void body_set_shape_as_one_way_collision(RID p_body, int p_shape, bool p_enabled, real_t p_margin = 0, const Vector2 &p_direction = Vector2(0, 1)) = 0;
|
||||
|
||||
virtual void body_remove_shape(RID p_body, int p_shape_idx) = 0;
|
||||
virtual void body_clear_shapes(RID p_body) = 0;
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ public:
|
|||
virtual Transform2D body_get_shape_transform(RID p_body, int p_shape_idx) const override { return Transform2D(); }
|
||||
|
||||
virtual void body_set_shape_disabled(RID p_body, int p_shape, bool p_disabled) override {}
|
||||
virtual void body_set_shape_as_one_way_collision(RID p_body, int p_shape, bool p_enabled, real_t p_margin = 0) override {}
|
||||
virtual void body_set_shape_as_one_way_collision(RID p_body, int p_shape, bool p_enabled, real_t p_margin = 0, const Vector2 &p_direction = Vector2(0, 1)) override {}
|
||||
|
||||
virtual void body_remove_shape(RID p_body, int p_shape_idx) override {}
|
||||
virtual void body_clear_shapes(RID p_body) override {}
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ void PhysicsServer2DExtension::_bind_methods() {
|
|||
GDVIRTUAL_BIND(_body_get_shape_transform, "body", "shape_idx");
|
||||
|
||||
GDVIRTUAL_BIND(_body_set_shape_disabled, "body", "shape_idx", "disabled");
|
||||
GDVIRTUAL_BIND(_body_set_shape_as_one_way_collision, "body", "shape_idx", "enable", "margin");
|
||||
GDVIRTUAL_BIND(_body_set_shape_as_one_way_collision, "body", "shape_idx", "enable", "margin", "direction");
|
||||
|
||||
GDVIRTUAL_BIND(_body_remove_shape, "body", "shape_idx");
|
||||
GDVIRTUAL_BIND(_body_clear_shapes, "body");
|
||||
|
|
@ -348,6 +348,10 @@ void PhysicsServer2DExtension::_bind_methods() {
|
|||
|
||||
GDVIRTUAL_BIND(_is_flushing_queries);
|
||||
GDVIRTUAL_BIND(_get_process_info, "process_info");
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
GDVIRTUAL_BIND_COMPAT(_body_set_shape_as_one_way_collision_bind_compat_104736, "body", "shape_idx", "enable", "margin");
|
||||
#endif
|
||||
}
|
||||
|
||||
PhysicsServer2DExtension::PhysicsServer2DExtension() {
|
||||
|
|
|
|||
|
|
@ -199,6 +199,10 @@ protected:
|
|||
|
||||
GDVIRTUAL8R_REQUIRED(bool, _body_collide_shape, RID, int, RID, const Transform2D &, const Vector2 &, GDExtensionPtr<Vector2>, int, GDExtensionPtr<int>)
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
GDVIRTUAL4_COMPAT(_body_set_shape_as_one_way_collision_bind_compat_104736, _body_set_shape_as_one_way_collision, RID, int, bool, real_t)
|
||||
#endif
|
||||
|
||||
public:
|
||||
// The warning is valid, but unavoidable. If the function is not overridden it will error anyway.
|
||||
|
||||
|
|
@ -305,7 +309,7 @@ public:
|
|||
EXBIND2RC(Transform2D, body_get_shape_transform, RID, int)
|
||||
|
||||
EXBIND3(body_set_shape_disabled, RID, int, bool)
|
||||
EXBIND4(body_set_shape_as_one_way_collision, RID, int, bool, real_t)
|
||||
EXBIND5(body_set_shape_as_one_way_collision, RID, int, bool, real_t, const Vector2 &)
|
||||
|
||||
EXBIND2(body_remove_shape, RID, int)
|
||||
EXBIND1(body_clear_shapes, RID)
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ public:
|
|||
FUNC2RC(RID, body_get_shape, RID, int);
|
||||
|
||||
FUNC3(body_set_shape_disabled, RID, int, bool);
|
||||
FUNC4(body_set_shape_as_one_way_collision, RID, int, bool, real_t);
|
||||
FUNC5(body_set_shape_as_one_way_collision, RID, int, bool, real_t, const Vector2 &);
|
||||
|
||||
FUNC2(body_remove_shape, RID, int);
|
||||
FUNC1(body_clear_shapes, RID);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue