diff options
Diffstat (limited to 'servers/physics_2d')
-rw-r--r-- | servers/physics_2d/area_2d_sw.cpp | 1 | ||||
-rw-r--r-- | servers/physics_2d/area_pair_2d_sw.cpp | 2 | ||||
-rw-r--r-- | servers/physics_2d/body_2d_sw.cpp | 30 | ||||
-rw-r--r-- | servers/physics_2d/body_2d_sw.h | 6 | ||||
-rw-r--r-- | servers/physics_2d/body_pair_2d_sw.cpp | 7 | ||||
-rw-r--r-- | servers/physics_2d/collision_object_2d_sw.cpp | 8 | ||||
-rw-r--r-- | servers/physics_2d/collision_object_2d_sw.h | 15 | ||||
-rw-r--r-- | servers/physics_2d/physics_2d_server_sw.cpp | 16 | ||||
-rw-r--r-- | servers/physics_2d/physics_2d_server_sw.h | 4 | ||||
-rw-r--r-- | servers/physics_2d/space_2d_sw.cpp | 4 |
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); |