summaryrefslogtreecommitdiff
path: root/servers/physics_2d
diff options
context:
space:
mode:
Diffstat (limited to 'servers/physics_2d')
-rw-r--r--servers/physics_2d/area_2d_sw.cpp1
-rw-r--r--servers/physics_2d/area_pair_2d_sw.cpp2
-rw-r--r--servers/physics_2d/body_2d_sw.cpp30
-rw-r--r--servers/physics_2d/body_2d_sw.h6
-rw-r--r--servers/physics_2d/body_pair_2d_sw.cpp7
-rw-r--r--servers/physics_2d/collision_object_2d_sw.cpp8
-rw-r--r--servers/physics_2d/collision_object_2d_sw.h15
-rw-r--r--servers/physics_2d/physics_2d_server_sw.cpp16
-rw-r--r--servers/physics_2d/physics_2d_server_sw.h4
-rw-r--r--servers/physics_2d/space_2d_sw.cpp4
10 files changed, 72 insertions, 21 deletions
diff --git a/servers/physics_2d/area_2d_sw.cpp b/servers/physics_2d/area_2d_sw.cpp
index 58035eb656..8be583c235 100644
--- a/servers/physics_2d/area_2d_sw.cpp
+++ b/servers/physics_2d/area_2d_sw.cpp
@@ -180,6 +180,7 @@ Area2DSW::Area2DSW() : CollisionObject2DSW(TYPE_AREA), monitor_query_list(this),
gravity_vector=Vector2(0,-1);
gravity_is_point=false;
point_attenuation=1;
+
density=0.1;
priority=0;
monitor_callback_id=0;
diff --git a/servers/physics_2d/area_pair_2d_sw.cpp b/servers/physics_2d/area_pair_2d_sw.cpp
index 35286bdb67..1c7f73db5e 100644
--- a/servers/physics_2d/area_pair_2d_sw.cpp
+++ b/servers/physics_2d/area_pair_2d_sw.cpp
@@ -75,6 +75,8 @@ AreaPair2DSW::AreaPair2DSW(Body2DSW *p_body,int p_body_shape, Area2DSW *p_area,i
colliding=false;
body->add_constraint(this,0);
area->add_constraint(this);
+ if (p_body->get_mode()==Physics2DServer::BODY_MODE_KINEMATIC) //need to be active to process pair
+ p_body->set_active(true);
}
diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp
index f10cdadf4e..fbad19f6be 100644
--- a/servers/physics_2d/body_2d_sw.cpp
+++ b/servers/physics_2d/body_2d_sw.cpp
@@ -176,6 +176,7 @@ float Body2DSW::get_param(Physics2DServer::BodyParameter p_param) const {
void Body2DSW::set_mode(Physics2DServer::BodyMode p_mode) {
+ Physics2DServer::BodyMode prev=mode;
mode=p_mode;
switch(p_mode) {
@@ -186,9 +187,12 @@ void Body2DSW::set_mode(Physics2DServer::BodyMode p_mode) {
_set_inv_transform(get_transform().affine_inverse());
_inv_mass=0;
_set_static(p_mode==Physics2DServer::BODY_MODE_STATIC);
- //set_active(p_mode==Physics2DServer::BODY_MODE_KINEMATIC);
+ set_active(p_mode==Physics2DServer::BODY_MODE_KINEMATIC && contacts.size());
linear_velocity=Vector2();
angular_velocity=0;
+ if (mode==Physics2DServer::BODY_MODE_KINEMATIC && prev!=mode) {
+ first_time_kinematic=true;
+ }
} break;
case Physics2DServer::BODY_MODE_RIGID: {
@@ -226,9 +230,15 @@ void Body2DSW::set_state(Physics2DServer::BodyState p_state, const Variant& p_va
if (mode==Physics2DServer::BODY_MODE_KINEMATIC) {
- new_transform=p_variant;
+
+ new_transform=p_variant;
//wakeup_neighbours();
set_active(true);
+ if (first_time_kinematic) {
+ _set_transform(p_variant);
+ _set_inv_transform(get_transform().affine_inverse());
+ first_time_kinematic=false;
+ }
} else if (mode==Physics2DServer::BODY_MODE_STATIC) {
_set_transform(p_variant);
_set_inv_transform(get_transform().affine_inverse());
@@ -385,10 +395,10 @@ void Body2DSW::integrate_forces(real_t p_step) {
motion = new_transform.elements[2] - get_transform().elements[2];
do_motion=true;
- for(int i=0;i<get_shape_count();i++) {
- set_shape_kinematic_advance(i,Vector2());
- set_shape_kinematic_retreat(i,0);
- }
+ //for(int i=0;i<get_shape_count();i++) {
+ // set_shape_kinematic_advance(i,Vector2());
+ // set_shape_kinematic_retreat(i,0);
+ //}
} else {
if (!omit_force_integration) {
@@ -434,7 +444,7 @@ void Body2DSW::integrate_forces(real_t p_step) {
}
current_area=NULL; // clear the area, so it is set in the next frame
- contact_count=0;
+ contact_count=0;
}
@@ -449,8 +459,8 @@ void Body2DSW::integrate_velocities(real_t p_step) {
if (mode==Physics2DServer::BODY_MODE_KINEMATIC) {
_set_transform(new_transform,false);
- _set_inv_transform(new_transform.affine_inverse()); ;
- if (linear_velocity==Vector2() && angular_velocity==0)
+ _set_inv_transform(new_transform.affine_inverse());
+ if (contacts.size()==0 && linear_velocity==Vector2() && angular_velocity==0)
set_active(false); //stopped moving, deactivate
return;
}
@@ -507,6 +517,7 @@ void Body2DSW::call_queries() {
Variant v=dbs;
const Variant *vp[2]={&v,&fi_callback->callback_udata};
+
Object *obj = ObjectDB::get_instance(fi_callback->id);
if (!obj) {
@@ -590,6 +601,7 @@ Body2DSW::Body2DSW() : CollisionObject2DSW(TYPE_BODY), active_list(this), inerti
island_next=NULL;
island_list_next=NULL;
_set_static(false);
+ first_time_kinematic=false;
density=0;
contact_count=0;
diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h
index ffe47e0267..789fb1cfee 100644
--- a/servers/physics_2d/body_2d_sw.h
+++ b/servers/physics_2d/body_2d_sw.h
@@ -72,6 +72,7 @@ class Body2DSW : public CollisionObject2DSW {
bool omit_force_integration;
bool active;
bool can_sleep;
+ bool first_time_kinematic;
void _update_inertia();
virtual void _shapes_changed();
Matrix32 new_transform;
@@ -134,7 +135,8 @@ public:
_FORCE_INLINE_ void add_area(Area2DSW *p_area) { areas.insert(AreaCMP(p_area)); }
_FORCE_INLINE_ void remove_area(Area2DSW *p_area) { areas.erase(AreaCMP(p_area)); }
- _FORCE_INLINE_ void set_max_contacts_reported(int p_size) { contacts.resize(p_size); contact_count=0; }
+ _FORCE_INLINE_ void set_max_contacts_reported(int p_size) { contacts.resize(p_size); contact_count=0; if (mode==Physics2DServer::BODY_MODE_KINEMATIC && p_size) set_active(true);}
+
_FORCE_INLINE_ int get_max_contacts_reported() const { return contacts.size(); }
_FORCE_INLINE_ bool can_report_contacts() const { return !contacts.empty(); }
@@ -334,6 +336,8 @@ public:
virtual Vector2 get_contact_collider_pos(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx,body->contact_count,Vector2()); return body->contacts[p_contact_idx].collider_pos; }
virtual ObjectID get_contact_collider_id(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx,body->contact_count,0); return body->contacts[p_contact_idx].collider_instance_id; }
virtual int get_contact_collider_shape(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx,body->contact_count,0); return body->contacts[p_contact_idx].collider_shape; }
+ virtual Variant get_contact_collider_shape_metadata(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx,body->contact_count,Variant()); return body->get_shape_metadata(body->contacts[p_contact_idx].collider_shape); }
+
virtual Vector2 get_contact_collider_velocity_at_pos(int p_contact_idx) const { ERR_FAIL_INDEX_V(p_contact_idx,body->contact_count,Vector2()); return body->contacts[p_contact_idx].collider_velocity_at_pos; }
virtual Physics2DDirectSpaceState* get_space_state();
diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp
index ee169cde28..9abdd01791 100644
--- a/servers/physics_2d/body_pair_2d_sw.cpp
+++ b/servers/physics_2d/body_pair_2d_sw.cpp
@@ -234,7 +234,7 @@ bool BodyPair2DSW::setup(float p_step) {
//cannot collide
- if ((A->get_layer_mask()&B->get_layer_mask())==0 || A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC && B->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC)) {
+ if ((A->get_layer_mask()&B->get_layer_mask())==0 || A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC && B->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC && A->get_max_contacts_reported()==0 && B->get_max_contacts_reported()==0)) {
collided=false;
return false;
}
@@ -343,9 +343,11 @@ bool BodyPair2DSW::setup(float p_step) {
}
}
- if (A->is_shape_set_as_trigger(shape_A) || B->is_shape_set_as_trigger(shape_B)) {
+ if (A->is_shape_set_as_trigger(shape_A) || B->is_shape_set_as_trigger(shape_B) || (A->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC && B->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC)) {
c.active=false;
collided=false;
+ continue;
+
}
// Precompute normal mass, tangent mass, and bias.
@@ -476,6 +478,7 @@ BodyPair2DSW::BodyPair2DSW(Body2DSW *p_A, int p_shape_A,Body2DSW *p_B, int p_sha
BodyPair2DSW::~BodyPair2DSW() {
+
A->remove_constraint(this);
B->remove_constraint(this);
diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp
index 277a286144..d0443f8110 100644
--- a/servers/physics_2d/collision_object_2d_sw.cpp
+++ b/servers/physics_2d/collision_object_2d_sw.cpp
@@ -55,6 +55,14 @@ void CollisionObject2DSW::set_shape(int p_index,Shape2DSW *p_shape){
_shapes_changed();
}
+
+void CollisionObject2DSW::set_shape_metadata(int p_index,const Variant& p_metadata) {
+
+ ERR_FAIL_INDEX(p_index,shapes.size());
+ shapes[p_index].metadata=p_metadata;
+
+}
+
void CollisionObject2DSW::set_shape_transform(int p_index,const Matrix32& p_transform){
ERR_FAIL_INDEX(p_index,shapes.size());
diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h
index cc7f8f50bd..00ad361245 100644
--- a/servers/physics_2d/collision_object_2d_sw.h
+++ b/servers/physics_2d/collision_object_2d_sw.h
@@ -55,10 +55,9 @@ private:
BroadPhase2DSW::ID bpid;
Rect2 aabb_cache; //for rayqueries
Shape2DSW *shape;
- Vector2 kinematic_advance;
- float kinematic_retreat;
+ Variant metadata;
bool trigger;
- Shape() { trigger=false; kinematic_retreat=0; }
+ Shape() { trigger=false; }
};
Vector<Shape> shapes;
@@ -99,17 +98,15 @@ public:
void add_shape(Shape2DSW *p_shape,const Matrix32& p_transform=Matrix32());
void set_shape(int p_index,Shape2DSW *p_shape);
void set_shape_transform(int p_index,const Matrix32& p_transform);
+ void set_shape_metadata(int p_index,const Variant& p_metadata);
+
+
_FORCE_INLINE_ int get_shape_count() const { return shapes.size(); }
_FORCE_INLINE_ Shape2DSW *get_shape(int p_index) const { return shapes[p_index].shape; }
_FORCE_INLINE_ const Matrix32& get_shape_transform(int p_index) const { return shapes[p_index].xform; }
_FORCE_INLINE_ const Matrix32& get_shape_inv_transform(int p_index) const { return shapes[p_index].xform_inv; }
_FORCE_INLINE_ const Rect2& get_shape_aabb(int p_index) const { return shapes[p_index].aabb_cache; }
-
- _FORCE_INLINE_ void set_shape_kinematic_advance(int p_index,const Vector2& p_advance) { shapes[p_index].kinematic_advance=p_advance; }
- _FORCE_INLINE_ Vector2 get_shape_kinematic_advance(int p_index) const { return shapes[p_index].kinematic_advance; }
-
- _FORCE_INLINE_ void set_shape_kinematic_retreat(int p_index,float p_retreat) { shapes[p_index].kinematic_retreat=p_retreat; }
- _FORCE_INLINE_ float get_shape_kinematic_retreat(int p_index) const { return shapes[p_index].kinematic_retreat; }
+ _FORCE_INLINE_ const Variant& get_shape_metadata(int p_index) const { return shapes[p_index].metadata; }
_FORCE_INLINE_ Matrix32 get_transform() const { return transform; }
_FORCE_INLINE_ Matrix32 get_inv_transform() const { return inv_transform; }
diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp
index 09fa3f9b6a..ab85f5e1d6 100644
--- a/servers/physics_2d/physics_2d_server_sw.cpp
+++ b/servers/physics_2d/physics_2d_server_sw.cpp
@@ -548,6 +548,22 @@ void Physics2DServerSW::body_set_shape_transform(RID p_body, int p_shape_idx, co
body->set_shape_transform(p_shape_idx,p_transform);
}
+void Physics2DServerSW::body_set_shape_metadata(RID p_body, int p_shape_idx, const Variant& p_metadata) {
+
+ Body2DSW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+ body->set_shape_metadata(p_shape_idx,p_metadata);
+}
+
+
+Variant Physics2DServerSW::body_get_shape_metadata(RID p_body, int p_shape_idx) const {
+
+ Body2DSW *body = body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body,Variant());
+ return body->get_shape_metadata(p_shape_idx);
+}
+
+
int Physics2DServerSW::body_get_shape_count(RID p_body) const {
Body2DSW *body = body_owner.get(p_body);
diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h
index 7ffffe669f..9edd4eee11 100644
--- a/servers/physics_2d/physics_2d_server_sw.h
+++ b/servers/physics_2d/physics_2d_server_sw.h
@@ -149,10 +149,14 @@ public:
virtual void body_add_shape(RID p_body, RID p_shape, const Matrix32& p_transform=Matrix32());
virtual void body_set_shape(RID p_body, int p_shape_idx,RID p_shape);
virtual void body_set_shape_transform(RID p_body, int p_shape_idx, const Matrix32& p_transform);
+ virtual void body_set_shape_metadata(RID p_body, int p_shape_idx, const Variant& p_metadata);
+
virtual int body_get_shape_count(RID p_body) const;
virtual RID body_get_shape(RID p_body, int p_shape_idx) const;
virtual Matrix32 body_get_shape_transform(RID p_body, int p_shape_idx) const;
+ virtual Variant body_get_shape_metadata(RID p_body, int p_shape_idx) const;
+
virtual void body_remove_shape(RID p_body, int p_shape_idx);
virtual void body_clear_shapes(RID p_body);
diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp
index 21a99cd4b2..8b72436936 100644
--- a/servers/physics_2d/space_2d_sw.cpp
+++ b/servers/physics_2d/space_2d_sw.cpp
@@ -126,6 +126,7 @@ bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2& p_from, const Vec
if (r_result.collider_id!=0)
r_result.collider=ObjectDB::get_instance(r_result.collider_id);
r_result.normal=res_normal;
+ r_result.metadata=res_obj->get_shape_metadata(res_shape);
r_result.position=res_point;
r_result.rid=res_obj->get_self();
r_result.shape=res_shape;
@@ -171,6 +172,7 @@ int Physics2DDirectSpaceStateSW::intersect_shape(const RID& p_shape, const Matri
r_results[cc].collider=ObjectDB::get_instance(r_results[cc].collider_id);
r_results[cc].rid=col_obj->get_self();
r_results[cc].shape=shape_idx;
+ r_results[cc].metadata=col_obj->get_shape_metadata(shape_idx);
cc++;
@@ -350,6 +352,7 @@ static void _rest_cbk_result(const Vector2& p_point_A,const Vector2& p_point_B,v
rd->best_object=rd->object;
rd->best_shape=rd->shape;
+
}
@@ -399,6 +402,7 @@ bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Matrix32& p_shape
r_info->normal=rcd.best_normal;
r_info->point=rcd.best_contact;
r_info->rid=rcd.best_object->get_self();
+ r_info->metadata=rcd.best_object->get_shape_metadata(rcd.best_shape);
if (rcd.best_object->get_type()==CollisionObject2DSW::TYPE_BODY) {
const Body2DSW *body = static_cast<const Body2DSW*>(rcd.best_object);