From fdaa2920eb21fff3320a17e9239e04dfadecdb00 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sat, 18 Apr 2015 14:38:54 -0300 Subject: Updated copyright year in all headers --- servers/physics_2d_server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'servers/physics_2d_server.cpp') diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp index 098f89022..ffd240365 100644 --- a/servers/physics_2d_server.cpp +++ b/servers/physics_2d_server.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2015 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 */ -- cgit v1.2.3-70-g09d2 From 28c4afeb5733f9ca9725ab2a5f4066af8e02b2a6 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sun, 19 Apr 2015 20:50:55 -0300 Subject: -Rewritten KinematicBody2D::move to MUCH more efficient code. -KinematicBody2D::move now properly recognizes collision exceptions and masks, fixes #1649 -Removed object type masking for KinematicBody2D -Added a test_motion() function to RigidBody2D, allowing simlar behavior to KinematicBody2D::move there. --- demos/2d/kinematic_char/colworld.gd | 3 +- demos/2d/kinematic_char/colworld.scn | Bin 6367 -> 6596 bytes scene/2d/physics_body_2d.cpp | 142 ++------ scene/2d/physics_body_2d.h | 22 +- servers/physics_2d/physics_2d_server_sw.cpp | 12 + servers/physics_2d/physics_2d_server_sw.h | 3 + servers/physics_2d/space_2d_sw.cpp | 504 ++++++++++++++++++++++++++++ servers/physics_2d/space_2d_sw.h | 2 + servers/physics_2d_server.cpp | 75 +++++ servers/physics_2d_server.h | 50 +++ servers/register_server_types.cpp | 1 + 11 files changed, 687 insertions(+), 127 deletions(-) (limited to 'servers/physics_2d_server.cpp') diff --git a/demos/2d/kinematic_char/colworld.gd b/demos/2d/kinematic_char/colworld.gd index d13ff9236..fe2dc30bb 100644 --- a/demos/2d/kinematic_char/colworld.gd +++ b/demos/2d/kinematic_char/colworld.gd @@ -14,4 +14,5 @@ func _ready(): func _on_princess_body_enter( body ): #the name of this editor-generated callback is unfortunate - get_node("youwin").show() + if (body.get_name()=="player"): + get_node("youwin").show() diff --git a/demos/2d/kinematic_char/colworld.scn b/demos/2d/kinematic_char/colworld.scn index 7b79a1d88..6c73e8b12 100644 Binary files a/demos/2d/kinematic_char/colworld.scn and b/demos/2d/kinematic_char/colworld.scn differ diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 0fe828d2c..b55e9f28d 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -341,6 +341,16 @@ struct _RigidBody2DInOut { int local_shape; }; + +bool RigidBody2D::_test_motion(const Vector2& p_motion,float p_margin,const Ref& p_result) { + + Physics2DServer::MotionResult *r=NULL; + if (p_result.is_valid()) + r=p_result->get_result_ptr(); + return Physics2DServer::get_singleton()->body_test_motion(get_rid(),p_motion,p_margin,r); + +} + void RigidBody2D::_direct_state_changed(Object *p_state) { //eh.. fuck @@ -791,6 +801,8 @@ void RigidBody2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_can_sleep","able_to_sleep"),&RigidBody2D::set_can_sleep); ObjectTypeDB::bind_method(_MD("is_able_to_sleep"),&RigidBody2D::is_able_to_sleep); + ObjectTypeDB::bind_method(_MD("test_motion","motion","margin","result:Physics2DTestMotionResult"),&RigidBody2D::_test_motion,DEFVAL(0.08),DEFVAL(Variant())); + ObjectTypeDB::bind_method(_MD("_direct_state_changed"),&RigidBody2D::_direct_state_changed); ObjectTypeDB::bind_method(_MD("_body_enter_tree"),&RigidBody2D::_body_enter_tree); ObjectTypeDB::bind_method(_MD("_body_exit_tree"),&RigidBody2D::_body_exit_tree); @@ -888,20 +900,25 @@ Variant KinematicBody2D::_get_collider() const { } -bool KinematicBody2D::_ignores_mode(Physics2DServer::BodyMode p_mode) const { +Vector2 KinematicBody2D::move(const Vector2& p_motion) { - switch(p_mode) { - case Physics2DServer::BODY_MODE_STATIC: return !collide_static; - case Physics2DServer::BODY_MODE_KINEMATIC: return !collide_kinematic; - case Physics2DServer::BODY_MODE_RIGID: return !collide_rigid; - case Physics2DServer::BODY_MODE_CHARACTER: return !collide_character; - } +#if 1 + Physics2DServer::MotionResult result; + colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(),p_motion,margin,&result); - return true; -} + collider_metadata=result.collider_metadata; + collider_shape=result.collider_shape; + collider_vel=result.collider_velocity; + collision=result.collision_point; + normal=result.collision_normal; + collider=result.collider_id; -Vector2 KinematicBody2D::move(const Vector2& p_motion) { + Matrix32 gt = get_global_transform(); + gt.elements[2]+=result.motion; + set_global_transform(gt); + return result.remainder; +#else //give me back regular physics engine logic //this is madness //and most people using this function will think @@ -1051,7 +1068,7 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) { set_global_transform(gt); return p_motion-motion; - +#endif } Vector2 KinematicBody2D::move_to(const Vector2& p_position) { @@ -1059,58 +1076,22 @@ Vector2 KinematicBody2D::move_to(const Vector2& p_position) { return move(p_position-get_global_pos()); } -bool KinematicBody2D::can_move_to(const Vector2& p_position, bool p_discrete) { +bool KinematicBody2D::test_move(const Vector2& p_motion) { ERR_FAIL_COND_V(!is_inside_tree(),false); - Physics2DDirectSpaceState *dss = Physics2DServer::get_singleton()->space_get_direct_state(get_world_2d()->get_space()); - ERR_FAIL_COND_V(!dss,false); - uint32_t mask=0; - if (collide_static) - mask|=Physics2DDirectSpaceState::TYPE_MASK_STATIC_BODY; - if (collide_kinematic) - mask|=Physics2DDirectSpaceState::TYPE_MASK_KINEMATIC_BODY; - if (collide_rigid) - mask|=Physics2DDirectSpaceState::TYPE_MASK_RIGID_BODY; - if (collide_character) - mask|=Physics2DDirectSpaceState::TYPE_MASK_CHARACTER_BODY; - - Vector2 motion = p_position-get_global_pos(); - Matrix32 xform=get_global_transform(); - - if (p_discrete) { - - xform.elements[2]+=motion; - motion=Vector2(); - } - - Set exclude; - exclude.insert(get_rid()); - - //fill exclude list.. - for(int i=0;ibody_test_motion(get_rid(),p_motion,margin); - bool col = dss->intersect_shape(get_shape(i)->get_rid(), xform * get_shape_transform(i),motion,0,NULL,0,exclude,get_layer_mask(),mask); - if (col) - return false; - } - - return true; } -bool KinematicBody2D::is_colliding() const { - - ERR_FAIL_COND_V(!is_inside_tree(),false); - - return colliding; -} Vector2 KinematicBody2D::get_collision_pos() const { ERR_FAIL_COND_V(!colliding,Vector2()); return collision; } + Vector2 KinematicBody2D::get_collision_normal() const { ERR_FAIL_COND_V(!colliding,Vector2()); @@ -1143,43 +1124,10 @@ Variant KinematicBody2D::get_collider_metadata() const { } -void KinematicBody2D::set_collide_with_static_bodies(bool p_enable) { - - collide_static=p_enable; -} -bool KinematicBody2D::can_collide_with_static_bodies() const { - - return collide_static; -} - -void KinematicBody2D::set_collide_with_rigid_bodies(bool p_enable) { - - collide_rigid=p_enable; - -} -bool KinematicBody2D::can_collide_with_rigid_bodies() const { - - return collide_rigid; -} - -void KinematicBody2D::set_collide_with_kinematic_bodies(bool p_enable) { - - collide_kinematic=p_enable; - -} -bool KinematicBody2D::can_collide_with_kinematic_bodies() const { +bool KinematicBody2D::is_colliding() const{ - return collide_kinematic; -} - -void KinematicBody2D::set_collide_with_character_bodies(bool p_enable) { - - collide_character=p_enable; -} -bool KinematicBody2D::can_collide_with_character_bodies() const { - - return collide_character; + return colliding; } void KinematicBody2D::set_collision_margin(float p_margin) { @@ -1198,7 +1146,7 @@ void KinematicBody2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("move","rel_vec"),&KinematicBody2D::move); ObjectTypeDB::bind_method(_MD("move_to","position"),&KinematicBody2D::move_to); - ObjectTypeDB::bind_method(_MD("can_move_to","position","discrete"),&KinematicBody2D::can_move_to,DEFVAL(false)); + ObjectTypeDB::bind_method(_MD("test_move","rel_vec"),&KinematicBody2D::test_move); ObjectTypeDB::bind_method(_MD("is_colliding"),&KinematicBody2D::is_colliding); @@ -1209,26 +1157,9 @@ void KinematicBody2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_collider_shape"),&KinematicBody2D::get_collider_shape); ObjectTypeDB::bind_method(_MD("get_collider_metadata"),&KinematicBody2D::get_collider_metadata); - - ObjectTypeDB::bind_method(_MD("set_collide_with_static_bodies","enable"),&KinematicBody2D::set_collide_with_static_bodies); - ObjectTypeDB::bind_method(_MD("can_collide_with_static_bodies"),&KinematicBody2D::can_collide_with_static_bodies); - - ObjectTypeDB::bind_method(_MD("set_collide_with_kinematic_bodies","enable"),&KinematicBody2D::set_collide_with_kinematic_bodies); - ObjectTypeDB::bind_method(_MD("can_collide_with_kinematic_bodies"),&KinematicBody2D::can_collide_with_kinematic_bodies); - - ObjectTypeDB::bind_method(_MD("set_collide_with_rigid_bodies","enable"),&KinematicBody2D::set_collide_with_rigid_bodies); - ObjectTypeDB::bind_method(_MD("can_collide_with_rigid_bodies"),&KinematicBody2D::can_collide_with_rigid_bodies); - - ObjectTypeDB::bind_method(_MD("set_collide_with_character_bodies","enable"),&KinematicBody2D::set_collide_with_character_bodies); - ObjectTypeDB::bind_method(_MD("can_collide_with_character_bodies"),&KinematicBody2D::can_collide_with_character_bodies); - ObjectTypeDB::bind_method(_MD("set_collision_margin","pixels"),&KinematicBody2D::set_collision_margin); ObjectTypeDB::bind_method(_MD("get_collision_margin","pixels"),&KinematicBody2D::get_collision_margin); - ADD_PROPERTY( PropertyInfo(Variant::BOOL,"collide_with/static"),_SCS("set_collide_with_static_bodies"),_SCS("can_collide_with_static_bodies")); - ADD_PROPERTY( PropertyInfo(Variant::BOOL,"collide_with/kinematic"),_SCS("set_collide_with_kinematic_bodies"),_SCS("can_collide_with_kinematic_bodies")); - ADD_PROPERTY( PropertyInfo(Variant::BOOL,"collide_with/rigid"),_SCS("set_collide_with_rigid_bodies"),_SCS("can_collide_with_rigid_bodies")); - ADD_PROPERTY( PropertyInfo(Variant::BOOL,"collide_with/character"),_SCS("set_collide_with_character_bodies"),_SCS("can_collide_with_character_bodies")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/margin",PROPERTY_HINT_RANGE,"0.001,256,0.001"),_SCS("set_collision_margin"),_SCS("get_collision_margin")); @@ -1236,11 +1167,6 @@ void KinematicBody2D::_bind_methods() { KinematicBody2D::KinematicBody2D() : PhysicsBody2D(Physics2DServer::BODY_MODE_KINEMATIC){ - collide_static=true; - collide_rigid=true; - collide_kinematic=true; - collide_character=true; - colliding=false; collider=0; diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index c05a4ff05..b8cba6e5b 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -188,6 +188,7 @@ private: void _body_inout(int p_status, ObjectID p_instance, int p_body_shape,int p_local_shape); void _direct_state_changed(Object *p_state); + bool _test_motion(const Vector2& p_motion,float p_margin=0.08,const Ref& p_result=Ref()); protected: @@ -249,6 +250,8 @@ public: void set_applied_force(const Vector2& p_force); Vector2 get_applied_force() const; + + Array get_colliding_bodies() const; //function for script RigidBody2D(); @@ -266,11 +269,6 @@ class KinematicBody2D : public PhysicsBody2D { OBJ_TYPE(KinematicBody2D,PhysicsBody2D); float margin; - bool collide_static; - bool collide_rigid; - bool collide_kinematic; - bool collide_character; - bool colliding; Vector2 collision; Vector2 normal; @@ -290,7 +288,7 @@ public: Vector2 move(const Vector2& p_motion); Vector2 move_to(const Vector2& p_position); - bool can_move_to(const Vector2& p_position,bool p_discrete=false); + bool test_move(const Vector2& p_motion); bool is_colliding() const; Vector2 get_collision_pos() const; Vector2 get_collision_normal() const; @@ -299,18 +297,6 @@ public: int get_collider_shape() const; Variant get_collider_metadata() const; - void set_collide_with_static_bodies(bool p_enable); - bool can_collide_with_static_bodies() const; - - void set_collide_with_rigid_bodies(bool p_enable); - bool can_collide_with_rigid_bodies() const; - - void set_collide_with_kinematic_bodies(bool p_enable); - bool can_collide_with_kinematic_bodies() const; - - void set_collide_with_character_bodies(bool p_enable); - bool can_collide_with_character_bodies() const; - void set_collision_margin(float p_margin); float get_collision_margin() const; diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp index d8ad59d99..d0a0ff67d 100644 --- a/servers/physics_2d/physics_2d_server_sw.cpp +++ b/servers/physics_2d/physics_2d_server_sw.cpp @@ -959,6 +959,18 @@ void Physics2DServerSW::body_set_pickable(RID p_body,bool p_pickable) { } +bool Physics2DServerSW::body_test_motion(RID p_body,const Vector2& p_motion,float p_margin,MotionResult *r_result) { + + Body2DSW *body = body_owner.get(p_body); + ERR_FAIL_COND_V(!body,false); + ERR_FAIL_COND_V(!body->get_space(),false); + ERR_FAIL_COND_V(body->get_space()->is_locked(),false); + + return body->get_space()->test_body_motion(body,p_motion,p_margin,r_result); + +} + + /* JOINT API */ void Physics2DServerSW::joint_set_param(RID p_joint, JointParam p_param, real_t p_value) { diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h index 10143bdad..50675cbd0 100644 --- a/servers/physics_2d/physics_2d_server_sw.h +++ b/servers/physics_2d/physics_2d_server_sw.h @@ -223,6 +223,9 @@ public: virtual void body_set_pickable(RID p_body,bool p_pickable); + virtual bool body_test_motion(RID p_body,const Vector2& p_motion,float p_margin=0.001,MotionResult *r_result=NULL); + + /* JOINT API */ virtual void joint_set_param(RID p_joint, JointParam p_param, real_t p_value); diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index 064414776..9a1b977bd 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -556,7 +556,511 @@ Physics2DDirectSpaceStateSW::Physics2DDirectSpaceStateSW() { +bool Space2DSW::test_body_motion(Body2DSW *p_body,const Vector2&p_motion,float p_margin,Physics2DServer::MotionResult *r_result) { + //give me back regular physics engine logic + //this is madness + //and most people using this function will think + //what it does is simpler than using physics + //this took about a week to get right.. + //but is it right? who knows at this point.. + + Rect2 body_aabb; + + for(int i=0;iget_shape_count();i++) { + + if (i==0) + body_aabb=p_body->get_shape_aabb(i); + else + body_aabb=body_aabb.merge(p_body->get_shape_aabb(i)); + } + + body_aabb=body_aabb.grow(p_margin); + + { + //add motion + + Rect2 motion_aabb=body_aabb; + motion_aabb.pos+=p_motion; + body_aabb=body_aabb.merge(motion_aabb); + } + + + int amount = broadphase->cull_aabb(body_aabb,intersection_query_results,INTERSECTION_QUERY_MAX,intersection_query_subindex_results); + + for(int i=0;iget_type()==CollisionObject2DSW::TYPE_AREA) + keep=false; + else if ((static_cast(intersection_query_results[i])->get_layer_mask()&p_body->get_layer_mask())==0) + keep=false; + else if (static_cast(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self())) + keep=false; + else if (static_cast(intersection_query_results[i])->is_shape_set_as_trigger(intersection_query_subindex_results[i])) + keep=false; + + if (!keep) { + + if (iget_transform(); + + { + //STEP 1, FREE BODY IF STUCK + + const int max_results = 32; + int recover_attempts=4; + Vector2 sr[max_results*2]; + + do { + + Physics2DServerSW::CollCbkData cbk; + cbk.max=max_results; + cbk.amount=0; + cbk.ptr=sr; + + + CollisionSolver2DSW::CallbackResult cbkres=NULL; + + Physics2DServerSW::CollCbkData *cbkptr=NULL; + cbkptr=&cbk; + cbkres=Physics2DServerSW::_shape_col_cbk; + + bool collided=false; + + + for(int j=0;jget_shape_count();j++) { + if (p_body->is_shape_set_as_trigger(j)) + continue; + + Matrix32 body_shape_xform = body_transform * p_body->get_shape_transform(j); + Shape2DSW *body_shape = p_body->get_shape(j); + for(int i=0;iget_type()==CollisionObject2DSW::TYPE_BODY) { + + const Body2DSW *body=static_cast(col_obj); + cbk.valid_dir=body->get_one_way_collision_direction(); + cbk.valid_depth=body->get_one_way_collision_max_depth(); + } else { + cbk.valid_dir=Vector2(); + cbk.valid_depth=0; + } + + if (CollisionSolver2DSW::solve(body_shape,body_shape_xform,Vector2(),col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx),Vector2(),cbkres,cbkptr,NULL,p_margin)) { + collided=cbk.amount>0; + } + } + } + + + if (!collided) + break; + + Vector2 recover_motion; + + for(int i=0;iget_shape_count();j++) { + + if (p_body->is_shape_set_as_trigger(j)) + continue; + + Matrix32 body_shape_xform = body_transform * p_body->get_shape_transform(j); + Shape2DSW *body_shape = p_body->get_shape(j); + + bool stuck=false; + + float best_safe=1; + float best_unsafe=1; + + for(int i=0;iget_transform() * col_obj->get_shape_transform(shape_idx); + //test initial overlap, does it collide if going all the way? + if (!CollisionSolver2DSW::solve(body_shape,body_shape_xform,p_motion,col_obj->get_shape(shape_idx),col_obj_xform,Vector2() ,NULL,NULL,NULL,0)) { + continue; + } + + + //test initial overlap + if (CollisionSolver2DSW::solve(body_shape,body_shape_xform,Vector2(),col_obj->get_shape(shape_idx),col_obj_xform,Vector2() ,NULL,NULL,NULL,0)) { + + if (col_obj->get_type()==CollisionObject2DSW::TYPE_BODY) { + //if one way collision direction ignore initial overlap + const Body2DSW *body=static_cast(col_obj); + if (body->get_one_way_collision_direction()!=Vector2()) { + continue; + } + } + + stuck=true; + break; + } + + + //just do kinematic solving + float low=0; + float hi=1; + Vector2 mnormal=p_motion.normalized(); + + for(int i=0;i<8;i++) { //steps should be customizable.. + + //Matrix32 xfa = p_xform; + float ofs = (low+hi)*0.5; + + Vector2 sep=mnormal; //important optimization for this to work fast enough + bool collided = CollisionSolver2DSW::solve(body_shape,body_shape_xform,p_motion*ofs,col_obj->get_shape(shape_idx),col_obj_xform,Vector2(),NULL,NULL,&sep,0); + + if (collided) { + + hi=ofs; + } else { + + low=ofs; + } + } + + if (col_obj->get_type()==CollisionObject2DSW::TYPE_BODY) { + + const Body2DSW *body=static_cast(col_obj); + if (body->get_one_way_collision_direction()!=Vector2()) { + + Vector2 cd[2]; + Physics2DServerSW::CollCbkData cbk; + cbk.max=1; + cbk.amount=0; + cbk.ptr=cd; + cbk.valid_dir=body->get_one_way_collision_direction(); + cbk.valid_depth=body->get_one_way_collision_max_depth(); + + Vector2 sep=mnormal; //important optimization for this to work fast enough + bool collided = CollisionSolver2DSW::solve(body_shape,body_shape_xform,p_motion*(hi+contact_max_allowed_penetration),col_obj->get_shape(shape_idx),col_obj_xform,Vector2(),Physics2DServerSW::_shape_col_cbk,&cbk,&sep,0); + if (!collided || cbk.amount==0) { + continue; + } + + } + } + + + if (low=1) { + //not collided + collided=false; + if (r_result) { + + r_result->motion=p_motion+(body_transform.elements[2]-p_body->get_transform().elements[2]); + r_result->remainder=Vector2(); + } + + } else { + + //it collided, let's get the rest info in unsafe advance + Matrix32 ugt = body_transform; + ugt.elements[2]+=p_motion*unsafe; + + _RestCallbackData2D rcd; + rcd.best_len=0; + rcd.best_object=NULL; + rcd.best_shape=0; + + Matrix32 body_shape_xform = ugt * p_body->get_shape_transform(best_shape); + Shape2DSW *body_shape = p_body->get_shape(best_shape); + + + for(int i=0;iget_type()==CollisionObject2DSW::TYPE_BODY) { + + const Body2DSW *body=static_cast(col_obj); + rcd.valid_dir=body->get_one_way_collision_direction(); + rcd.valid_depth=body->get_one_way_collision_max_depth(); + } else { + rcd.valid_dir=Vector2(); + rcd.valid_depth=0; + } + + + rcd.object=col_obj; + rcd.shape=shape_idx; + bool sc = CollisionSolver2DSW::solve(body_shape,body_shape_xform,Vector2(),col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx),Vector2() ,_rest_cbk_result,&rcd,NULL,p_margin); + if (!sc) + continue; + + } + + if (rcd.best_len!=0) { + + if (r_result) { + r_result->collider=rcd.best_object->get_self(); + r_result->collider_id=rcd.best_object->get_instance_id(); + r_result->collider_shape=rcd.best_shape; + r_result->collision_normal=rcd.best_normal; + r_result->collision_point=rcd.best_contact; + r_result->collider_metadata=rcd.best_object->get_shape_metadata(rcd.best_shape); + + const Body2DSW *body = static_cast(rcd.best_object); + Vector2 rel_vec = r_result->collision_point-body->get_transform().get_origin(); + r_result->collider_velocity = Vector2(-body->get_angular_velocity() * rel_vec.y, body->get_angular_velocity() * rel_vec.x) + body->get_linear_velocity(); + + r_result->motion=safe*p_motion+(body_transform.elements[2]-p_body->get_transform().elements[2]); + r_result->remainder=p_motion - safe * p_motion; + } + + collided=true; + } else { + if (r_result) { + + r_result->motion=p_motion+(body_transform.elements[2]-p_body->get_transform().elements[2]); + r_result->remainder=Vector2(); + } + + collided=false; + + } + } + + return collided; + + +#if 0 + //give me back regular physics engine logic + //this is madness + //and most people using this function will think + //what it does is simpler than using physics + //this took about a week to get right.. + //but is it right? who knows at this point.. + + + colliding=false; + ERR_FAIL_COND_V(!is_inside_tree(),Vector2()); + Physics2DDirectSpaceState *dss = Physics2DServer::get_singleton()->space_get_direct_state(get_world_2d()->get_space()); + ERR_FAIL_COND_V(!dss,Vector2()); + const int max_shapes=32; + Vector2 sr[max_shapes*2]; + int res_shapes; + + Set exclude; + exclude.insert(get_rid()); + + + //recover first + int recover_attempts=4; + + bool collided=false; + uint32_t mask=0; + if (collide_static) + mask|=Physics2DDirectSpaceState::TYPE_MASK_STATIC_BODY; + if (collide_kinematic) + mask|=Physics2DDirectSpaceState::TYPE_MASK_KINEMATIC_BODY; + if (collide_rigid) + mask|=Physics2DDirectSpaceState::TYPE_MASK_RIGID_BODY; + if (collide_character) + mask|=Physics2DDirectSpaceState::TYPE_MASK_CHARACTER_BODY; + +// print_line("motion: "+p_motion+" margin: "+rtos(margin)); + + //print_line("margin: "+rtos(margin)); + do { + + //motion recover + for(int i=0;icollide_shape(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i),Vector2(),margin,sr,max_shapes,res_shapes,exclude,get_layer_mask(),mask)) + collided=true; + + } + + if (!collided) + break; + + Vector2 recover_motion; + + for(int i=0;icast_motion(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i), p_motion, 0,lsafe,lunsafe,exclude,get_layer_mask(),mask); + //print_line("shape: "+itos(i)+" travel:"+rtos(ltravel)); + if (!valid) { + + safe=0; + unsafe=0; + best_shape=i; //sadly it's the best + break; + } + if (lsafe==1.0) { + continue; + } + if (lsafe < safe) { + + safe=lsafe; + unsafe=lunsafe; + best_shape=i; + } + } + + + //print_line("best shape: "+itos(best_shape)+" motion "+p_motion); + + if (safe>=1) { + //not collided + colliding=false; + } else { + + //it collided, let's get the rest info in unsafe advance + Matrix32 ugt = get_global_transform(); + ugt.elements[2]+=p_motion*unsafe; + Physics2DDirectSpaceState::ShapeRestInfo rest_info; + bool c2 = dss->rest_info(get_shape(best_shape)->get_rid(), ugt*get_shape_transform(best_shape), Vector2(), margin,&rest_info,exclude,get_layer_mask(),mask); + if (!c2) { + //should not happen, but floating point precision is so weird.. + + colliding=false; + } else { + + + //print_line("Travel: "+rtos(travel)); + colliding=true; + collision=rest_info.point; + normal=rest_info.normal; + collider=rest_info.collider_id; + collider_vel=rest_info.linear_velocity; + collider_shape=rest_info.shape; + collider_metadata=rest_info.metadata; + } + + } + + Vector2 motion=p_motion*safe; + Matrix32 gt = get_global_transform(); + gt.elements[2]+=motion; + set_global_transform(gt); + + return p_motion-motion; + +#endif + return false; +} diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h index d100ada9d..95a576609 100644 --- a/servers/physics_2d/space_2d_sw.h +++ b/servers/physics_2d/space_2d_sw.h @@ -165,6 +165,8 @@ public: int get_collision_pairs() const { return collision_pairs; } + bool test_body_motion(Body2DSW *p_body, const Vector2&p_motion, float p_margin, Physics2DServer::MotionResult *r_result); + Physics2DDirectSpaceStateSW *get_direct_state(); Space2DSW(); diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp index ffd240365..16a15617f 100644 --- a/servers/physics_2d_server.cpp +++ b/servers/physics_2d_server.cpp @@ -421,13 +421,86 @@ void Physics2DShapeQueryResult::_bind_methods() { } +/////////////////////////////// +/*bool Physics2DTestMotionResult::is_colliding() const { + return colliding; +}*/ +Vector2 Physics2DTestMotionResult::get_motion() const{ + return result.motion; +} +Vector2 Physics2DTestMotionResult::get_motion_remainder() const{ + + return result.remainder; +} + +Vector2 Physics2DTestMotionResult::get_collision_point() const{ + + return result.collision_point; +} +Vector2 Physics2DTestMotionResult::get_collision_normal() const{ + + return result.collision_normal; +} +Vector2 Physics2DTestMotionResult::get_collider_velocity() const{ + + return result.collider_velocity; +} +ObjectID Physics2DTestMotionResult::get_collider_id() const{ + + return result.collider_id; +} +RID Physics2DTestMotionResult::get_collider_rid() const{ + + return result.collider; +} + +Object* Physics2DTestMotionResult::get_collider() const { + return ObjectDB::get_instance(result.collider_id); +} + +int Physics2DTestMotionResult::get_collider_shape() const{ + + return result.collider_shape; +} + +void Physics2DTestMotionResult::_bind_methods() { + + //ObjectTypeDB::bind_method(_MD("is_colliding"),&Physics2DTestMotionResult::is_colliding); + ObjectTypeDB::bind_method(_MD("get_motion"),&Physics2DTestMotionResult::get_motion); + ObjectTypeDB::bind_method(_MD("get_motion_remainder"),&Physics2DTestMotionResult::get_motion_remainder); + ObjectTypeDB::bind_method(_MD("get_collision_point"),&Physics2DTestMotionResult::get_collision_point); + ObjectTypeDB::bind_method(_MD("get_collision_normal"),&Physics2DTestMotionResult::get_collision_normal); + ObjectTypeDB::bind_method(_MD("get_collider_velocity"),&Physics2DTestMotionResult::get_collider_velocity); + ObjectTypeDB::bind_method(_MD("get_collider_id"),&Physics2DTestMotionResult::get_collider_id); + ObjectTypeDB::bind_method(_MD("get_collider_rid"),&Physics2DTestMotionResult::get_collider_rid); + ObjectTypeDB::bind_method(_MD("get_collider"),&Physics2DTestMotionResult::get_collider); + ObjectTypeDB::bind_method(_MD("get_collider_shape"),&Physics2DTestMotionResult::get_collider_shape); + +} + +Physics2DTestMotionResult::Physics2DTestMotionResult(){ + + colliding=false; + result.collider_id=0; + result.collider_shape=0; +} /////////////////////////////////////// + + +bool Physics2DServer::_body_test_motion(RID p_body,const Vector2& p_motion,float p_margin,const Ref& p_result) { + + MotionResult *r=NULL; + if (p_result.is_valid()) + r=p_result->get_result_ptr(); + return body_test_motion(p_body,p_motion,p_margin,r); +} + void Physics2DServer::_bind_methods() { @@ -543,6 +616,8 @@ void Physics2DServer::_bind_methods() { ObjectTypeDB::bind_method(_MD("body_set_force_integration_callback","body","receiver","method"),&Physics2DServer::body_set_force_integration_callback); + ObjectTypeDB::bind_method(_MD("body_test_motion","body","motion","margin","result:Physics2DTestMotionResult"),&Physics2DServer::_body_test_motion,DEFVAL(0.08),DEFVAL(Variant())); + /* JOINT API */ ObjectTypeDB::bind_method(_MD("joint_set_param","joint","param","value"),&Physics2DServer::joint_set_param); diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h index a3e65ec28..306144c2b 100644 --- a/servers/physics_2d_server.h +++ b/servers/physics_2d_server.h @@ -230,6 +230,7 @@ public: Physics2DShapeQueryResult(); }; +class Physics2DTestMotionResult; class Physics2DServer : public Object { @@ -237,6 +238,8 @@ class Physics2DServer : public Object { static Physics2DServer * singleton; + virtual bool _body_test_motion(RID p_body,const Vector2& p_motion,float p_margin=0.08,const Ref& p_result=Ref()); + protected: static void _bind_methods(); @@ -468,6 +471,22 @@ public: virtual void body_set_pickable(RID p_body,bool p_pickable)=0; + struct MotionResult { + + Vector2 motion; + Vector2 remainder; + + Vector2 collision_point; + Vector2 collision_normal; + Vector2 collider_velocity; + ObjectID collider_id; + RID collider; + int collider_shape; + Variant collider_metadata; + }; + + virtual bool body_test_motion(RID p_body,const Vector2& p_motion,float p_margin=0.001,MotionResult *r_result=NULL)=0; + /* JOINT API */ enum JointType { @@ -532,6 +551,37 @@ public: ~Physics2DServer(); }; + +class Physics2DTestMotionResult : public Reference { + + OBJ_TYPE( Physics2DTestMotionResult, Reference ); + + Physics2DServer::MotionResult result; + bool colliding; +friend class Physics2DServer; + +protected: + static void _bind_methods(); +public: + + Physics2DServer::MotionResult* get_result_ptr() const { return const_cast(&result); } + + //bool is_colliding() const; + Vector2 get_motion() const; + Vector2 get_motion_remainder() const; + + Vector2 get_collision_point() const; + Vector2 get_collision_normal() const; + Vector2 get_collider_velocity() const; + ObjectID get_collider_id() const; + RID get_collider_rid() const; + Object* get_collider() const; + int get_collider_shape() const; + + Physics2DTestMotionResult(); +}; + + VARIANT_ENUM_CAST( Physics2DServer::ShapeType ); VARIANT_ENUM_CAST( Physics2DServer::SpaceParameter ); VARIANT_ENUM_CAST( Physics2DServer::AreaParameter ); diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index 6ee01f9d4..d35b6e1e5 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -55,6 +55,7 @@ void register_server_types() { ObjectTypeDB::register_virtual_type(); ObjectTypeDB::register_virtual_type(); ObjectTypeDB::register_virtual_type(); + ObjectTypeDB::register_virtual_type(); ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); -- cgit v1.2.3-70-g09d2 From 4804462ee06c1b3e2d1b50b857ce8693d3c0936d Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Fri, 1 May 2015 10:44:08 -0300 Subject: -Fixes from source code analyzizer, closes #1768 --- bin/tests/test_physics_2d.cpp | 4 ++-- core/math/math_funcs.cpp | 4 ++-- core/variant_op.cpp | 2 +- drivers/unix/memory_pool_static_malloc.cpp | 2 +- platform/android/export/export.cpp | 8 ++++---- scene/3d/mesh_instance.cpp | 4 ++-- scene/animation/tween.cpp | 2 +- scene/gui/scroll_bar.cpp | 16 ++++++++-------- scene/gui/text_edit.cpp | 2 +- scene/resources/scene_preloader.cpp | 2 +- servers/physics/joints/generic_6dof_joint_sw.cpp | 2 +- servers/physics_2d_server.cpp | 2 +- servers/physics_server.cpp | 2 +- servers/visual/shader_language.cpp | 2 +- tools/collada/collada.cpp | 2 +- tools/editor/animation_editor.cpp | 2 +- tools/editor/io_plugins/editor_sample_import_plugin.cpp | 4 ++-- 17 files changed, 31 insertions(+), 31 deletions(-) (limited to 'servers/physics_2d_server.cpp') diff --git a/bin/tests/test_physics_2d.cpp b/bin/tests/test_physics_2d.cpp index a441bed43..70a7d868b 100644 --- a/bin/tests/test_physics_2d.cpp +++ b/bin/tests/test_physics_2d.cpp @@ -191,7 +191,7 @@ class TestPhysics2DMainLoop : public MainLoop { Image image(convex_png); - body_shape_data[Physics2DServer::SHAPE_CONVEX_POLYGON].image=vs->texture_create_from_image(image); + body_shape_data[Physics2DServer::SHAPE_CUSTOM+1].image=vs->texture_create_from_image(image); RID convex_polygon_shape = ps->shape_create(Physics2DServer::SHAPE_CONVEX_POLYGON); @@ -206,7 +206,7 @@ class TestPhysics2DMainLoop : public MainLoop { arr.push_back(Point2(11,7)-sb); ps->shape_set_data(convex_polygon_shape,arr); - body_shape_data[Physics2DServer::SHAPE_CONVEX_POLYGON].shape = convex_polygon_shape; + body_shape_data[Physics2DServer::SHAPE_CUSTOM+1].shape = convex_polygon_shape; } diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp index 490e529d8..6ad5c7499 100644 --- a/core/math/math_funcs.cpp +++ b/core/math/math_funcs.cpp @@ -48,8 +48,8 @@ uint32_t Math::rand_from_seed(uint32_t *seed) { s = 0x12345987; k = s / 127773; s = 16807 * (s - k * 127773) - 2836 * k; - if (s < 0) - s += 2147483647; +// if (s < 0) +// s += 2147483647; (*seed) = s; return (s & Math::RANDOM_MAX); #else diff --git a/core/variant_op.cpp b/core/variant_op.cpp index dafe3bd02..f68652b8c 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -2433,7 +2433,7 @@ Variant Variant::get(const Variant& p_index, bool *r_valid) const { } else if (str == "pressed") { valid=true; - ie.action.pressed; + return ie.action.pressed; } } diff --git a/drivers/unix/memory_pool_static_malloc.cpp b/drivers/unix/memory_pool_static_malloc.cpp index 62abe7d26..e0bab27a6 100644 --- a/drivers/unix/memory_pool_static_malloc.cpp +++ b/drivers/unix/memory_pool_static_malloc.cpp @@ -153,7 +153,7 @@ void* MemoryPoolStaticMalloc::_realloc(void *p_memory,size_t p_bytes) { return alloc( p_bytes ); } - if (p_bytes<=0) { + if (p_bytes==0) { this->free(p_memory); ERR_FAIL_COND_V( p_bytes < 0 , NULL ); diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 4d3f8f110..35ea7f15f 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -641,11 +641,11 @@ void EditorExportPlatformAndroid::_fix_manifest(Vector& p_manifest) { int iofs=ofs+8; - uint32_t string_count=decode_uint32(&p_manifest[iofs]); - uint32_t styles_count=decode_uint32(&p_manifest[iofs+4]); + string_count=decode_uint32(&p_manifest[iofs]); + styles_count=decode_uint32(&p_manifest[iofs+4]); uint32_t string_flags=decode_uint32(&p_manifest[iofs+8]); - uint32_t string_data_offset=decode_uint32(&p_manifest[iofs+12]); - uint32_t styles_offset=decode_uint32(&p_manifest[iofs+16]); + string_data_offset=decode_uint32(&p_manifest[iofs+12]); + styles_offset=decode_uint32(&p_manifest[iofs+16]); /* printf("string count: %i\n",string_count); printf("flags: %i\n",string_flags); diff --git a/scene/3d/mesh_instance.cpp b/scene/3d/mesh_instance.cpp index 66e29627c..62b32729c 100644 --- a/scene/3d/mesh_instance.cpp +++ b/scene/3d/mesh_instance.cpp @@ -168,7 +168,7 @@ Node* MeshInstance::create_trimesh_collision_node() { static_body->add_shape( shape ); return static_body; - return NULL; + } void MeshInstance::create_trimesh_collision() { @@ -202,7 +202,7 @@ Node* MeshInstance::create_convex_collision_node() { static_body->add_shape( shape ); return static_body; - return NULL; + } void MeshInstance::create_convex_collision() { diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index ffa1c09ab..a7a4129a5 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -269,7 +269,7 @@ Variant Tween::_run_equation(InterpolateData& p_data) { { case Variant::BOOL: - result = ((int) _run_equation(p_data.trans_type, p_data.ease_type, p_data.elapsed - p_data.delay, (int) initial_val, (int) delta_val, p_data.times_in_sec)) >= 0.5; + result = ( _run_equation(p_data.trans_type, p_data.ease_type, p_data.elapsed - p_data.delay, initial_val, delta_val, p_data.times_in_sec)) >= 0.5; break; case Variant::INT: diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp index 04a559124..b1fd914fc 100644 --- a/scene/gui/scroll_bar.cpp +++ b/scene/gui/scroll_bar.cpp @@ -51,20 +51,20 @@ void ScrollBar::_input_event(InputEvent p_event) { if (b.button_index==5 && b.pressed) { - if (orientation==VERTICAL) - set_val( get_val() + get_page() / 4.0 ); - else - set_val( get_val() + get_page() / 4.0 ); + //if (orientation==VERTICAL) + // set_val( get_val() + get_page() / 4.0 ); + //else + set_val( get_val() + get_page() / 4.0 ); accept_event(); } if (b.button_index==4 && b.pressed) { - if (orientation==HORIZONTAL) - set_val( get_val() - get_page() / 4.0 ); - else - set_val( get_val() - get_page() / 4.0 ); + //if (orientation==HORIZONTAL) + // set_val( get_val() - get_page() / 4.0 ); + //else + set_val( get_val() - get_page() / 4.0 ); accept_event(); } diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index c54333856..1e8243216 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -1552,7 +1552,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { case KEY_HOME: case KEY_END: // ignore arrows if any modifiers are held (shift = selecting, others may be used for editor hotkeys) - if (k.mod.command || k.mod.shift || k.mod.alt || k.mod.command) + if (k.mod.command || k.mod.shift || k.mod.alt) break; unselect=true; break; diff --git a/scene/resources/scene_preloader.cpp b/scene/resources/scene_preloader.cpp index 08e88b32c..09001c1a9 100644 --- a/scene/resources/scene_preloader.cpp +++ b/scene/resources/scene_preloader.cpp @@ -407,7 +407,7 @@ Dictionary ScenePreloader::_get_bundled_scene() const { rconns.push_back(cd.signal); rconns.push_back(cd.method); rconns.push_back(cd.binds.size()); - for(int j=0;jop==OP_CONSTRUCT && all_const) { - bool all_const=false; + Vector cdata; for(int i=0;iis_visible() && p_input.is_action("ui_page_up")) - selected_track=selected_track--;; + selected_track--;; if (selected_track<0) selected_track=0; diff --git a/tools/editor/io_plugins/editor_sample_import_plugin.cpp b/tools/editor/io_plugins/editor_sample_import_plugin.cpp index 49b8af67f..d1fe10df0 100644 --- a/tools/editor/io_plugins/editor_sample_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_sample_import_plugin.cpp @@ -719,8 +719,8 @@ void EditorSampleImportPlugin::_compress_ima_adpcm(const Vector& p_data,D xm_sample=CLAMP(in[i]*32767.0,-32768,32767); - if (xm_sample==32767 || xm_sample==-32768) - printf("clippy!\n",xm_sample); + //if (xm_sample==32767 || xm_sample==-32768) + // printf("clippy!\n",xm_sample); } // xm_sample=xm_sample+xm_prev; -- cgit v1.2.3-70-g09d2 From af068439829a3fec3a76c4c5d4dd2dba71ab6c5f Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sun, 3 May 2015 16:47:21 -0300 Subject: -new collision layer & mask system for 2D, for more flexible collision masking --- doc/base/classes.xml | 4 ++-- scene/2d/area_2d.cpp | 34 ++++++++++++++++++++++++++- scene/2d/area_2d.h | 8 +++++++ scene/2d/physics_body_2d.cpp | 18 +++++++++++++- scene/2d/physics_body_2d.h | 4 ++++ scene/2d/tile_map.cpp | 32 +++++++++++++++++++++---- scene/2d/tile_map.h | 9 +++++-- servers/physics_2d/area_pair_2d_sw.cpp | 4 ++-- servers/physics_2d/body_pair_2d_sw.cpp | 2 +- servers/physics_2d/collision_object_2d_sw.cpp | 2 +- servers/physics_2d/collision_object_2d_sw.h | 11 ++++++--- servers/physics_2d/physics_2d_server_sw.cpp | 24 +++++++++++++++---- servers/physics_2d/physics_2d_server_sw.h | 6 +++-- servers/physics_2d/space_2d_sw.cpp | 2 +- servers/physics_2d_server.cpp | 6 +++-- servers/physics_2d_server.h | 7 ++++-- servers/physics_server.cpp | 2 +- servers/physics_server.h | 4 ++-- 18 files changed, 147 insertions(+), 32 deletions(-) (limited to 'servers/physics_2d_server.cpp') diff --git a/doc/base/classes.xml b/doc/base/classes.xml index 905e99912..901bfa125 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -19442,7 +19442,7 @@ - + @@ -19450,7 +19450,7 @@ - + diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index a40b1fb39..827256c2f 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -512,6 +512,29 @@ bool Area2D::overlaps_body(Node* p_body) const{ } +void Area2D::set_collision_mask(uint32_t p_mask) { + + collision_mask=p_mask; + Physics2DServer::get_singleton()->area_set_collision_mask(get_rid(),p_mask); +} + +uint32_t Area2D::get_collision_mask() const { + + return collision_mask; +} + + +void Area2D::set_layer_mask(uint32_t p_mask) { + + layer_mask=p_mask; + Physics2DServer::get_singleton()->area_set_layer_mask(get_rid(),p_mask); +} + +uint32_t Area2D::get_layer_mask() const { + + return layer_mask; +} + void Area2D::_bind_methods() { @@ -542,6 +565,12 @@ void Area2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_priority","priority"),&Area2D::set_priority); ObjectTypeDB::bind_method(_MD("get_priority"),&Area2D::get_priority); + ObjectTypeDB::bind_method(_MD("set_collision_mask","collision_mask"),&Area2D::set_collision_mask); + ObjectTypeDB::bind_method(_MD("get_collision_mask"),&Area2D::get_collision_mask); + + ObjectTypeDB::bind_method(_MD("set_layer_mask","layer_mask"),&Area2D::set_layer_mask); + ObjectTypeDB::bind_method(_MD("get_layer_mask"),&Area2D::get_layer_mask); + ObjectTypeDB::bind_method(_MD("set_enable_monitoring","enable"),&Area2D::set_enable_monitoring); ObjectTypeDB::bind_method(_MD("is_monitoring_enabled"),&Area2D::is_monitoring_enabled); @@ -578,6 +607,8 @@ void Area2D::_bind_methods() { ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"priority",PROPERTY_HINT_RANGE,"0,128,1"),_SCS("set_priority"),_SCS("get_priority")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitoring"),_SCS("set_enable_monitoring"),_SCS("is_monitoring_enabled")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitorable"),_SCS("set_monitorable"),_SCS("is_monitorable")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_mask"),_SCS("get_collision_mask")); } @@ -593,9 +624,10 @@ Area2D::Area2D() : CollisionObject2D(Physics2DServer::get_singleton()->area_crea priority=0; monitoring=false; monitorable=false; + collision_mask=1; + layer_mask=1; set_enable_monitoring(true); set_monitorable(true); - } Area2D::~Area2D() { diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index 5964230a5..0c064f54c 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -51,6 +51,8 @@ private: bool gravity_is_point; real_t linear_damp; real_t angular_damp; + uint32_t collision_mask; + uint32_t layer_mask; int priority; bool monitoring; bool monitorable; @@ -151,6 +153,12 @@ public: void set_monitorable(bool p_enable); bool is_monitorable() const; + void set_collision_mask(uint32_t p_mask); + uint32_t get_collision_mask() const; + + void set_layer_mask(uint32_t p_mask); + uint32_t get_layer_mask() const; + Array get_overlapping_bodies() const; //function for script Array get_overlapping_areas() const; //function for script diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index e7bc19960..6fb798714 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -72,13 +72,16 @@ void PhysicsBody2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&PhysicsBody2D::set_layer_mask); ObjectTypeDB::bind_method(_MD("get_layer_mask"),&PhysicsBody2D::get_layer_mask); + ObjectTypeDB::bind_method(_MD("set_collision_mask","mask"),&PhysicsBody2D::set_collision_mask); + ObjectTypeDB::bind_method(_MD("get_collision_mask"),&PhysicsBody2D::get_collision_mask); ObjectTypeDB::bind_method(_MD("set_one_way_collision_direction","dir"),&PhysicsBody2D::set_one_way_collision_direction); ObjectTypeDB::bind_method(_MD("get_one_way_collision_direction"),&PhysicsBody2D::get_one_way_collision_direction); ObjectTypeDB::bind_method(_MD("set_one_way_collision_max_depth","depth"),&PhysicsBody2D::set_one_way_collision_max_depth); ObjectTypeDB::bind_method(_MD("get_one_way_collision_max_depth"),&PhysicsBody2D::get_one_way_collision_max_depth); ObjectTypeDB::bind_method(_MD("add_collision_exception_with","body:PhysicsBody2D"),&PhysicsBody2D::add_collision_exception_with); ObjectTypeDB::bind_method(_MD("remove_collision_exception_with","body:PhysicsBody2D"),&PhysicsBody2D::remove_collision_exception_with); - ADD_PROPERTY(PropertyInfo(Variant::INT,"layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask")); + ADD_PROPERTY(PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask")); + ADD_PROPERTY(PropertyInfo(Variant::INT,"collision/mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_mask"),_SCS("get_collision_mask")); ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2,"one_way_collision/direction"),_SCS("set_one_way_collision_direction"),_SCS("get_one_way_collision_direction")); ADD_PROPERTYNZ(PropertyInfo(Variant::REAL,"one_way_collision/max_depth"),_SCS("set_one_way_collision_max_depth"),_SCS("get_one_way_collision_max_depth")); } @@ -94,9 +97,22 @@ uint32_t PhysicsBody2D::get_layer_mask() const { return mask; } +void PhysicsBody2D::set_collision_mask(uint32_t p_mask) { + + collision_mask=p_mask; + Physics2DServer::get_singleton()->body_set_collision_mask(get_rid(),p_mask); +} + +uint32_t PhysicsBody2D::get_collision_mask() const { + + return collision_mask; +} + + PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) : CollisionObject2D( Physics2DServer::get_singleton()->body_create(p_mode), false) { mask=1; + collision_mask=1; set_one_way_collision_max_depth(0); set_pickable(false); diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index b8cba6e5b..3cb94b95d 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -39,6 +39,7 @@ class PhysicsBody2D : public CollisionObject2D { OBJ_TYPE(PhysicsBody2D,CollisionObject2D); uint32_t mask; + uint32_t collision_mask; Vector2 one_way_collision_direction; float one_way_collision_max_depth; protected: @@ -52,6 +53,9 @@ public: void set_layer_mask(uint32_t p_mask); uint32_t get_layer_mask() const; + void set_collision_mask(uint32_t p_mask); + uint32_t get_collision_mask() const; + void add_collision_exception_with(Node* p_node); //must be physicsbody void remove_collision_exception_with(Node* p_node); diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index bf1677ae6..2fca1e67e 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -519,6 +519,7 @@ Map::Element *TileMap::_create_quadrant(const q.body=Physics2DServer::get_singleton()->body_create(use_kinematic?Physics2DServer::BODY_MODE_KINEMATIC:Physics2DServer::BODY_MODE_STATIC); Physics2DServer::get_singleton()->body_attach_object_instance_ID(q.body,get_instance_ID()); Physics2DServer::get_singleton()->body_set_layer_mask(q.body,collision_layer); + Physics2DServer::get_singleton()->body_set_collision_mask(q.body,collision_mask); Physics2DServer::get_singleton()->body_set_param(q.body,Physics2DServer::BODY_PARAM_FRICTION,friction); Physics2DServer::get_singleton()->body_set_param(q.body,Physics2DServer::BODY_PARAM_BOUNCE,bounce); @@ -790,7 +791,7 @@ Rect2 TileMap::get_item_rect() const { return rect_cache; } -void TileMap::set_collision_layer_mask(uint32_t p_layer) { +void TileMap::set_collision_layer(uint32_t p_layer) { collision_layer=p_layer; for (Map::Element *E=quadrant_map.front();E;E=E->next()) { @@ -800,6 +801,16 @@ void TileMap::set_collision_layer_mask(uint32_t p_layer) { } } +void TileMap::set_collision_mask(uint32_t p_mask) { + + collision_mask=p_mask; + for (Map::Element *E=quadrant_map.front();E;E=E->next()) { + + Quadrant &q=E->get(); + Physics2DServer::get_singleton()->body_set_collision_mask(q.body,collision_mask); + } +} + bool TileMap::get_collision_use_kinematic() const{ return use_kinematic; @@ -844,11 +855,16 @@ float TileMap::get_collision_bounce() const{ } -uint32_t TileMap::get_collision_layer_mask() const { +uint32_t TileMap::get_collision_layer() const { return collision_layer; } +uint32_t TileMap::get_collision_mask() const { + + return collision_mask; +} + void TileMap::set_mode(Mode p_mode) { _clear_quadrants(); @@ -1077,8 +1093,11 @@ void TileMap::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_collision_use_kinematic","use_kinematic"),&TileMap::set_collision_use_kinematic); ObjectTypeDB::bind_method(_MD("get_collision_use_kinematic"),&TileMap::get_collision_use_kinematic); - ObjectTypeDB::bind_method(_MD("set_collision_layer_mask","mask"),&TileMap::set_collision_layer_mask); - ObjectTypeDB::bind_method(_MD("get_collision_layer_mask"),&TileMap::get_collision_layer_mask); + ObjectTypeDB::bind_method(_MD("set_collision_layer","mask"),&TileMap::set_collision_layer); + ObjectTypeDB::bind_method(_MD("get_collision_layer"),&TileMap::get_collision_layer); + + ObjectTypeDB::bind_method(_MD("set_collision_mask","mask"),&TileMap::set_collision_mask); + ObjectTypeDB::bind_method(_MD("get_collision_mask"),&TileMap::get_collision_mask); ObjectTypeDB::bind_method(_MD("set_collision_friction","value"),&TileMap::set_collision_friction); ObjectTypeDB::bind_method(_MD("get_collision_friction"),&TileMap::get_collision_friction); @@ -1117,7 +1136,9 @@ void TileMap::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::BOOL,"collision/use_kinematic",PROPERTY_HINT_NONE,""),_SCS("set_collision_use_kinematic"),_SCS("get_collision_use_kinematic")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/friction",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_friction"),_SCS("get_collision_friction")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/bounce",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_bounce"),_SCS("get_collision_bounce")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_layer_mask"),_SCS("get_collision_layer_mask")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_layer"),_SCS("get_collision_layer")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_mask"),_SCS("get_collision_mask")); + ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"tile_data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_tile_data"),_SCS("_get_tile_data")); ADD_SIGNAL(MethodInfo("settings_changed")); @@ -1146,6 +1167,7 @@ TileMap::TileMap() { center_x=false; center_y=false; collision_layer=1; + collision_mask=1; friction=1; bounce=0; mode=MODE_SQUARE; diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 233529f01..84ca65da4 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -146,6 +146,8 @@ private: float friction; float bounce; uint32_t collision_layer; + uint32_t collision_mask; + TileOrigin tile_origin; void _fix_cell_transform(Matrix32& xform, const Cell& p_cell, const Vector2 &p_offset, const Size2 &p_sc); @@ -207,8 +209,11 @@ public: Rect2 get_item_rect() const; - void set_collision_layer_mask(uint32_t p_layer); - uint32_t get_collision_layer_mask() const; + void set_collision_layer(uint32_t p_layer); + uint32_t get_collision_layer() const; + + void set_collision_mask(uint32_t p_mask); + uint32_t get_collision_mask() const; void set_collision_use_kinematic(bool p_use_kinematic); bool get_collision_use_kinematic() const; diff --git a/servers/physics_2d/area_pair_2d_sw.cpp b/servers/physics_2d/area_pair_2d_sw.cpp index f73fbb628..3b1705bd5 100644 --- a/servers/physics_2d/area_pair_2d_sw.cpp +++ b/servers/physics_2d/area_pair_2d_sw.cpp @@ -32,7 +32,7 @@ bool AreaPair2DSW::setup(float p_step) { - bool result = CollisionSolver2DSW::solve(body->get_shape(body_shape),body->get_transform() * body->get_shape_transform(body_shape),Vector2(),area->get_shape(area_shape),area->get_transform() * area->get_shape_transform(area_shape),Vector2(),NULL,this); + bool result = area->test_collision_mask(body) && CollisionSolver2DSW::solve(body->get_shape(body_shape),body->get_transform() * body->get_shape_transform(body_shape),Vector2(),area->get_shape(area_shape),area->get_transform() * area->get_shape_transform(area_shape),Vector2(),NULL,this); if (result!=colliding) { @@ -102,7 +102,7 @@ AreaPair2DSW::~AreaPair2DSW() { bool Area2Pair2DSW::setup(float p_step) { - bool result = CollisionSolver2DSW::solve(area_a->get_shape(shape_a),area_a->get_transform() * area_a->get_shape_transform(shape_a),Vector2(),area_b->get_shape(shape_b),area_b->get_transform() * area_b->get_shape_transform(shape_b),Vector2(),NULL,this); + bool result = area_a->test_collision_mask(area_b) && CollisionSolver2DSW::solve(area_a->get_shape(shape_a),area_a->get_transform() * area_a->get_shape_transform(shape_a),Vector2(),area_b->get_shape(shape_b),area_b->get_transform() * area_b->get_shape_transform(shape_b),Vector2(),NULL,this); if (result!=colliding) { diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp index a2402d147..8913e396d 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 && A->get_max_contacts_reported()==0 && B->get_max_contacts_reported()==0)) { + if (!A->test_collision_mask(B) || 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; } diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp index 8160f22a3..7c8e223c5 100644 --- a/servers/physics_2d/collision_object_2d_sw.cpp +++ b/servers/physics_2d/collision_object_2d_sw.cpp @@ -226,7 +226,7 @@ CollisionObject2DSW::CollisionObject2DSW(Type p_type) { type=p_type; space=NULL; instance_id=0; - user_mask=0; + collision_mask=1; layer_mask=1; pickable=true; } diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h index 58dc3e9cd..f3432060b 100644 --- a/servers/physics_2d/collision_object_2d_sw.h +++ b/servers/physics_2d/collision_object_2d_sw.h @@ -65,7 +65,7 @@ private: Space2DSW *space; Matrix32 transform; Matrix32 inv_transform; - uint32_t user_mask; + uint32_t collision_mask; uint32_t layer_mask; bool _static; @@ -117,8 +117,8 @@ public: _FORCE_INLINE_ bool is_shape_set_as_trigger(int p_idx) const { return shapes[p_idx].trigger; } - void set_user_mask(uint32_t p_mask) {user_mask=p_mask;} - _FORCE_INLINE_ uint32_t get_user_mask() const { return user_mask; } + void set_collision_mask(uint32_t p_mask) {collision_mask=p_mask;} + _FORCE_INLINE_ uint32_t get_collision_mask() const { return collision_mask; } void set_layer_mask(uint32_t p_mask) {layer_mask=p_mask;} _FORCE_INLINE_ uint32_t get_layer_mask() const { return layer_mask; } @@ -133,6 +133,11 @@ public: void set_pickable(bool p_pickable) { pickable=p_pickable; } _FORCE_INLINE_ bool is_pickable() const { return pickable; } + _FORCE_INLINE_ bool test_collision_mask(CollisionObject2DSW* p_other) const { + + return layer_mask&p_other->collision_mask || p_other->layer_mask&collision_mask; + } + virtual ~CollisionObject2DSW() {} }; diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp index d31606acf..08d871be6 100644 --- a/servers/physics_2d/physics_2d_server_sw.cpp +++ b/servers/physics_2d/physics_2d_server_sw.cpp @@ -480,6 +480,22 @@ void Physics2DServerSW::area_set_monitorable(RID p_area,bool p_monitorable) { } +void Physics2DServerSW::area_set_collision_mask(RID p_area,uint32_t p_mask) { + + Area2DSW *area = area_owner.get(p_area); + ERR_FAIL_COND(!area); + + area->set_collision_mask(p_mask); +} + +void Physics2DServerSW::area_set_layer_mask(RID p_area,uint32_t p_mask) { + + Area2DSW *area = area_owner.get(p_area); + ERR_FAIL_COND(!area); + + area->set_layer_mask(p_mask); +} + void Physics2DServerSW::area_set_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method) { @@ -726,20 +742,20 @@ uint32_t Physics2DServerSW::body_get_layer_mask(RID p_body, uint32_t p_flags) co }; -void Physics2DServerSW::body_set_user_mask(RID p_body, uint32_t p_flags) { +void Physics2DServerSW::body_set_collision_mask(RID p_body, uint32_t p_flags) { Body2DSW *body = body_owner.get(p_body); ERR_FAIL_COND(!body); - body->set_user_mask(p_flags); + body->set_collision_mask(p_flags); }; -uint32_t Physics2DServerSW::body_get_user_mask(RID p_body, uint32_t p_flags) const { +uint32_t Physics2DServerSW::body_get_collision_mask(RID p_body, uint32_t p_flags) const { Body2DSW *body = body_owner.get(p_body); ERR_FAIL_COND_V(!body,0); - return body->get_user_mask(); + return body->get_collision_mask(); }; void Physics2DServerSW::body_set_param(RID p_body, BodyParameter p_param, float p_value) { diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h index 50675cbd0..341df2fdc 100644 --- a/servers/physics_2d/physics_2d_server_sw.h +++ b/servers/physics_2d/physics_2d_server_sw.h @@ -134,6 +134,8 @@ public: virtual Variant area_get_param(RID p_parea,AreaParameter p_param) const; virtual Matrix32 area_get_transform(RID p_area) const; virtual void area_set_monitorable(RID p_area,bool p_monitorable); + virtual void area_set_collision_mask(RID p_area,uint32_t p_mask); + virtual void area_set_layer_mask(RID p_area,uint32_t p_mask); virtual void area_set_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method); virtual void area_set_area_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method); @@ -179,8 +181,8 @@ public: virtual void body_set_layer_mask(RID p_body, uint32_t p_mask); virtual uint32_t body_get_layer_mask(RID p_body, uint32_t p_mask) const; - virtual void body_set_user_mask(RID p_body, uint32_t p_mask); - virtual uint32_t body_get_user_mask(RID p_body, uint32_t p_mask) const; + virtual void body_set_collision_mask(RID p_body, uint32_t p_mask); + virtual uint32_t body_get_collision_mask(RID p_body, uint32_t p_mask) const; virtual void body_set_param(RID p_body, BodyParameter p_param, float p_value); virtual float body_get_param(RID p_body, BodyParameter p_param) const; diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index 9a1b977bd..40e7b19f6 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -596,7 +596,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body,const Vector2&p_motion,float p keep=false; else if (intersection_query_results[i]->get_type()==CollisionObject2DSW::TYPE_AREA) keep=false; - else if ((static_cast(intersection_query_results[i])->get_layer_mask()&p_body->get_layer_mask())==0) + else if ((static_cast(intersection_query_results[i])->test_collision_mask(p_body))==0) keep=false; else if (static_cast(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self())) keep=false; diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp index 088c092e7..279ad0d74 100644 --- a/servers/physics_2d_server.cpp +++ b/servers/physics_2d_server.cpp @@ -536,6 +536,8 @@ void Physics2DServer::_bind_methods() { ObjectTypeDB::bind_method(_MD("area_remove_shape","area","shape_idx"),&Physics2DServer::area_remove_shape); ObjectTypeDB::bind_method(_MD("area_clear_shapes","area"),&Physics2DServer::area_clear_shapes); + ObjectTypeDB::bind_method(_MD("area_set_layer_mask","area","mask"),&Physics2DServer::area_set_layer_mask); + ObjectTypeDB::bind_method(_MD("area_set_collision_mask","area","mask"),&Physics2DServer::area_set_collision_mask); ObjectTypeDB::bind_method(_MD("area_set_param","area","param","value"),&Physics2DServer::area_set_param); ObjectTypeDB::bind_method(_MD("area_set_transform","area","transform"),&Physics2DServer::area_set_transform); @@ -584,8 +586,8 @@ void Physics2DServer::_bind_methods() { ObjectTypeDB::bind_method(_MD("body_set_layer_mask","body","mask"),&Physics2DServer::body_set_layer_mask); ObjectTypeDB::bind_method(_MD("body_get_layer_mask","body"),&Physics2DServer::body_get_layer_mask); - ObjectTypeDB::bind_method(_MD("body_set_user_mask","body","mask"),&Physics2DServer::body_set_user_mask); - ObjectTypeDB::bind_method(_MD("body_get_user_mask","body"),&Physics2DServer::body_get_user_mask); + ObjectTypeDB::bind_method(_MD("body_set_collision_mask","body","mask"),&Physics2DServer::body_set_collision_mask); + ObjectTypeDB::bind_method(_MD("body_get_collision_mask","body"),&Physics2DServer::body_get_collision_mask); ObjectTypeDB::bind_method(_MD("body_set_param","body","param","value"),&Physics2DServer::body_set_param); diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h index 306144c2b..5411228c0 100644 --- a/servers/physics_2d_server.h +++ b/servers/physics_2d_server.h @@ -347,6 +347,9 @@ public: virtual Variant area_get_param(RID p_parea,AreaParameter p_param) const=0; virtual Matrix32 area_get_transform(RID p_area) const=0; + virtual void area_set_collision_mask(RID p_area,uint32_t p_mask)=0; + virtual void area_set_layer_mask(RID p_area,uint32_t p_mask)=0; + virtual void area_set_monitorable(RID p_area,bool p_monitorable)=0; virtual void area_set_pickable(RID p_area,bool p_pickable)=0; @@ -404,8 +407,8 @@ public: virtual void body_set_layer_mask(RID p_body, uint32_t p_mask)=0; virtual uint32_t body_get_layer_mask(RID p_body, uint32_t p_mask) const=0; - virtual void body_set_user_mask(RID p_body, uint32_t p_mask)=0; - virtual uint32_t body_get_user_mask(RID p_body, uint32_t p_mask) const=0; + virtual void body_set_collision_mask(RID p_body, uint32_t p_mask)=0; + virtual uint32_t body_get_collision_mask(RID p_body, uint32_t p_mask) const=0; // common body variables enum BodyParameter { diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp index 010e02d88..4feb1b526 100644 --- a/servers/physics_server.cpp +++ b/servers/physics_server.cpp @@ -221,7 +221,7 @@ PhysicsShapeQueryParameters::PhysicsShapeQueryParameters() { ///////////////////////////////////// /* -Variant PhysicsDirectSpaceState::_intersect_shape(const RID& p_shape, const Transform& p_xform,int p_result_max,const Vector& p_exclude,uint32_t p_user_mask) { +Variant PhysicsDirectSpaceState::_intersect_shape(const RID& p_shape, const Transform& p_xform,int p_result_max,const Vector& p_exclude,uint32_t p_collision_mask) { diff --git a/servers/physics_server.h b/servers/physics_server.h index 97a1d34e7..ffb462af2 100644 --- a/servers/physics_server.h +++ b/servers/physics_server.h @@ -131,8 +131,8 @@ class PhysicsDirectSpaceState : public Object { OBJ_TYPE( PhysicsDirectSpaceState, Object ); -// Variant _intersect_ray(const Vector3& p_from, const Vector3& p_to,const Vector& p_exclude=Vector(),uint32_t p_user_mask=0); -// Variant _intersect_shape(const RID& p_shape, const Transform& p_xform,int p_result_max=64,const Vector& p_exclude=Vector(),uint32_t p_user_mask=0); +// Variant _intersect_ray(const Vector3& p_from, const Vector3& p_to,const Vector& p_exclude=Vector(),uint32_t p_collision_mask=0); +// Variant _intersect_shape(const RID& p_shape, const Transform& p_xform,int p_result_max=64,const Vector& p_exclude=Vector(),uint32_t p_collision_mask=0); public: enum ObjectTypeMask { -- cgit v1.2.3-70-g09d2 From 590afbcac461f87b05391996ca85d32627c81a75 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Wed, 29 Apr 2015 16:06:25 +0000 Subject: Calculate gravity based on distance from body to gravity point (2D) --- scene/2d/area_2d.cpp | 16 ++++++++++++++++ scene/2d/area_2d.h | 4 ++++ scene/3d/area.cpp | 1 + servers/physics_2d/area_2d_sw.cpp | 3 +++ servers/physics_2d/area_2d_sw.h | 4 ++++ servers/physics_2d/body_2d_sw.cpp | 9 ++++++--- servers/physics_2d_server.cpp | 1 + servers/physics_2d_server.h | 1 + 8 files changed, 36 insertions(+), 3 deletions(-) (limited to 'servers/physics_2d_server.cpp') diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index 827256c2f..e16cf85a5 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -52,6 +52,17 @@ bool Area2D::is_gravity_a_point() const{ return gravity_is_point; } +void Area2D::set_gravity_distance_scale(real_t p_scale){ + + gravity_distance_scale=p_scale; + Physics2DServer::get_singleton()->area_set_param(get_rid(),Physics2DServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE,p_scale); + +} + +real_t Area2D::get_gravity_distance_scale() const{ + return gravity_distance_scale; +} + void Area2D::set_gravity_vector(const Vector2& p_vec){ gravity_vec=p_vec; @@ -550,6 +561,9 @@ void Area2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_gravity_is_point","enable"),&Area2D::set_gravity_is_point); ObjectTypeDB::bind_method(_MD("is_gravity_a_point"),&Area2D::is_gravity_a_point); + ObjectTypeDB::bind_method(_MD("set_gravity_distance_scale","distance_scale"),&Area2D::set_gravity_distance_scale); + ObjectTypeDB::bind_method(_MD("get_gravity_distance_scale"),&Area2D::get_gravity_distance_scale); + ObjectTypeDB::bind_method(_MD("set_gravity_vector","vector"),&Area2D::set_gravity_vector); ObjectTypeDB::bind_method(_MD("get_gravity_vector"),&Area2D::get_gravity_vector); @@ -600,6 +614,7 @@ void Area2D::_bind_methods() { ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"space_override",PROPERTY_HINT_ENUM,"Disabled,Combine,Replace"),_SCS("set_space_override_mode"),_SCS("get_space_override_mode")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"gravity_point"),_SCS("set_gravity_is_point"),_SCS("is_gravity_a_point")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"gravity_distance_scale", PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_gravity_distance_scale"),_SCS("get_gravity_distance_scale")); ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"gravity_vec"),_SCS("set_gravity_vector"),_SCS("get_gravity_vector")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"gravity",PROPERTY_HINT_RANGE,"-1024,1024,0.01"),_SCS("set_gravity"),_SCS("get_gravity")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"linear_damp",PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_linear_damp"),_SCS("get_linear_damp")); @@ -618,6 +633,7 @@ Area2D::Area2D() : CollisionObject2D(Physics2DServer::get_singleton()->area_crea set_gravity(98);; set_gravity_vector(Vector2(0,1)); gravity_is_point=false; + gravity_distance_scale=0; linear_damp=0.1; angular_damp=1; locked=false; diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index 0c064f54c..704ad0a59 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -49,6 +49,7 @@ private: Vector2 gravity_vec; real_t gravity; bool gravity_is_point; + real_t gravity_distance_scale; real_t linear_damp; real_t angular_damp; uint32_t collision_mask; @@ -132,6 +133,9 @@ public: void set_gravity_is_point(bool p_enabled); bool is_gravity_a_point() const; + void set_gravity_distance_scale(real_t p_scale); + real_t get_gravity_distance_scale() const; + void set_gravity_vector(const Vector2& p_vec); Vector2 get_gravity_vector() const; diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp index bcc58c700..76527c72e 100644 --- a/scene/3d/area.cpp +++ b/scene/3d/area.cpp @@ -42,6 +42,7 @@ Area::SpaceOverride Area::get_space_override_mode() const{ } void Area::set_gravity_is_point(bool p_enabled){ + gravity_is_point=p_enabled; PhysicsServer::get_singleton()->area_set_param(get_rid(),PhysicsServer::AREA_PARAM_GRAVITY_IS_POINT,p_enabled); diff --git a/servers/physics_2d/area_2d_sw.cpp b/servers/physics_2d/area_2d_sw.cpp index dad1891b7..1a41cda48 100644 --- a/servers/physics_2d/area_2d_sw.cpp +++ b/servers/physics_2d/area_2d_sw.cpp @@ -120,6 +120,7 @@ void Area2DSW::set_param(Physics2DServer::AreaParameter p_param, const Variant& case Physics2DServer::AREA_PARAM_GRAVITY: gravity=p_value; ; break; case Physics2DServer::AREA_PARAM_GRAVITY_VECTOR: gravity_vector=p_value; ; break; case Physics2DServer::AREA_PARAM_GRAVITY_IS_POINT: gravity_is_point=p_value; ; break; + case Physics2DServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE: gravity_distance_scale=p_value; ; break; case Physics2DServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION: point_attenuation=p_value; ; break; case Physics2DServer::AREA_PARAM_LINEAR_DAMP: linear_damp=p_value; ; break; case Physics2DServer::AREA_PARAM_ANGULAR_DAMP: angular_damp=p_value; ; break; @@ -136,6 +137,7 @@ Variant Area2DSW::get_param(Physics2DServer::AreaParameter p_param) const { case Physics2DServer::AREA_PARAM_GRAVITY: return gravity; case Physics2DServer::AREA_PARAM_GRAVITY_VECTOR: return gravity_vector; case Physics2DServer::AREA_PARAM_GRAVITY_IS_POINT: return gravity_is_point; + case Physics2DServer::AREA_PARAM_GRAVITY_DISTANCE_SCALE: return gravity_distance_scale; case Physics2DServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION: return point_attenuation; case Physics2DServer::AREA_PARAM_LINEAR_DAMP: return linear_damp; case Physics2DServer::AREA_PARAM_ANGULAR_DAMP: return angular_damp; @@ -248,6 +250,7 @@ Area2DSW::Area2DSW() : CollisionObject2DSW(TYPE_AREA), monitor_query_list(this), gravity=9.80665; gravity_vector=Vector2(0,-1); gravity_is_point=false; + gravity_distance_scale=0; point_attenuation=1; angular_damp=1.0; diff --git a/servers/physics_2d/area_2d_sw.h b/servers/physics_2d/area_2d_sw.h index 4a54a337e..6d99764c6 100644 --- a/servers/physics_2d/area_2d_sw.h +++ b/servers/physics_2d/area_2d_sw.h @@ -46,6 +46,7 @@ class Area2DSW : public CollisionObject2DSW{ float gravity; Vector2 gravity_vector; bool gravity_is_point; + float gravity_distance_scale; float point_attenuation; float linear_damp; float angular_damp; @@ -139,6 +140,9 @@ public: _FORCE_INLINE_ void set_gravity_as_point(bool p_enable) { gravity_is_point=p_enable; } _FORCE_INLINE_ bool is_gravity_point() const { return gravity_is_point; } + _FORCE_INLINE_ void set_gravity_distance_scale(float scale) { gravity_distance_scale=scale; } + _FORCE_INLINE_ float get_gravity_distance_scale() const { return gravity_distance_scale; } + _FORCE_INLINE_ void set_point_attenuation(float p_point_attenuation) { point_attenuation=p_point_attenuation; } _FORCE_INLINE_ float get_point_attenuation() const { return point_attenuation; } diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp index ccce058f1..38835c9a8 100644 --- a/servers/physics_2d/body_2d_sw.cpp +++ b/servers/physics_2d/body_2d_sw.cpp @@ -383,9 +383,12 @@ void Body2DSW::set_space(Space2DSW *p_space){ void Body2DSW::_compute_area_gravity(const Area2DSW *p_area) { if (p_area->is_gravity_point()) { - - gravity += (p_area->get_transform().xform(p_area->get_gravity_vector()) - get_transform().get_origin()).normalized() * p_area->get_gravity(); - + if(p_area->get_gravity_distance_scale() > 0) { + Vector2 v = p_area->get_transform().xform(p_area->get_gravity_vector()) - get_transform().get_origin(); + gravity += v.normalized() * (p_area->get_gravity() / Math::pow(v.length() * p_area->get_gravity_distance_scale()+1, 2) ); + } else { + gravity += (p_area->get_transform().xform(p_area->get_gravity_vector()) - get_transform().get_origin()).normalized() * p_area->get_gravity(); + } } else { gravity += p_area->get_gravity_vector() * p_area->get_gravity(); } diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp index 279ad0d74..8db7ae116 100644 --- a/servers/physics_2d_server.cpp +++ b/servers/physics_2d_server.cpp @@ -657,6 +657,7 @@ void Physics2DServer::_bind_methods() { BIND_CONSTANT( AREA_PARAM_GRAVITY ); BIND_CONSTANT( AREA_PARAM_GRAVITY_VECTOR ); BIND_CONSTANT( AREA_PARAM_GRAVITY_IS_POINT ); + BIND_CONSTANT( AREA_PARAM_GRAVITY_DISTANCE_SCALE ); BIND_CONSTANT( AREA_PARAM_GRAVITY_POINT_ATTENUATION ); BIND_CONSTANT( AREA_PARAM_LINEAR_DAMP); BIND_CONSTANT( AREA_PARAM_ANGULAR_DAMP); diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h index 5411228c0..e7694aa2f 100644 --- a/servers/physics_2d_server.h +++ b/servers/physics_2d_server.h @@ -306,6 +306,7 @@ public: AREA_PARAM_GRAVITY, AREA_PARAM_GRAVITY_VECTOR, AREA_PARAM_GRAVITY_IS_POINT, + AREA_PARAM_GRAVITY_DISTANCE_SCALE, AREA_PARAM_GRAVITY_POINT_ATTENUATION, AREA_PARAM_LINEAR_DAMP, AREA_PARAM_ANGULAR_DAMP, -- cgit v1.2.3-70-g09d2 From b1b7826ea7e04a3eb4d9b3d011e9a2a8dff5db03 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Tue, 26 May 2015 01:30:36 -0300 Subject: oops, previous commit was not working it is working now --- demos/2d/platformer/engine.cfg | 1 - servers/physics_2d/physics_2d_server_wrap_mt.cpp | 10 +++++++++- servers/physics_2d/physics_2d_server_wrap_mt.h | 8 +++++--- servers/physics_2d_server.cpp | 2 +- 4 files changed, 15 insertions(+), 6 deletions(-) (limited to 'servers/physics_2d_server.cpp') diff --git a/demos/2d/platformer/engine.cfg b/demos/2d/platformer/engine.cfg index 5461cbddc..50b6b862e 100644 --- a/demos/2d/platformer/engine.cfg +++ b/demos/2d/platformer/engine.cfg @@ -28,7 +28,6 @@ spawn=[key(F1), jbutton(0, 11)] [physics_2d] default_gravity=700 -thread_model=1 [rasterizer] diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.cpp b/servers/physics_2d/physics_2d_server_wrap_mt.cpp index 0ee78afba..c5f023f16 100644 --- a/servers/physics_2d/physics_2d_server_wrap_mt.cpp +++ b/servers/physics_2d/physics_2d_server_wrap_mt.cpp @@ -61,7 +61,12 @@ void Physics2DServerWrapMT::step(float p_step) { void Physics2DServerWrapMT::sync() { - step_sem->wait(); + if (step_sem) { + if (first_frame) + first_frame=false; + else + step_sem->wait(); //must not wait if a step was not issued + } physics_2d_server->sync();; } @@ -147,6 +152,9 @@ Physics2DServerWrapMT::Physics2DServerWrapMT(Physics2DServer* p_contained,bool p } else { server_thread=0; } + + main_thread = Thread::get_caller_ID(); + first_frame=true; } diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h index 4c18464e3..48382498e 100644 --- a/servers/physics_2d/physics_2d_server_wrap_mt.h +++ b/servers/physics_2d/physics_2d_server_wrap_mt.h @@ -24,6 +24,7 @@ class Physics2DServerWrapMT : public Physics2DServer { void thread_loop(); Thread::ID server_thread; + Thread::ID main_thread; volatile bool exit; Thread *thread; volatile bool step_thread_up; @@ -37,6 +38,7 @@ class Physics2DServerWrapMT : public Physics2DServer { void thread_exit(); Mutex*alloc_mutex; + bool first_frame; int shape_pool_max_size; List shape_id_pool; @@ -72,7 +74,7 @@ public: //these work well, but should be used from the main thread only bool shape_collide(RID p_shape_A, const Matrix32& p_xform_A,const Vector2& p_motion_A,RID p_shape_B, const Matrix32& p_xform_B, const Vector2& p_motion_B,Vector2 *r_results,int p_result_max,int &r_result_count) { - ERR_FAIL_COND_V(server_thread!=Thread::get_caller_ID(),false); + ERR_FAIL_COND_V(main_thread!=Thread::get_caller_ID(),false); return physics_2d_server->shape_collide(p_shape_A,p_xform_A,p_motion_A,p_shape_B,p_xform_B,p_motion_B,r_results,p_result_max,r_result_count); } @@ -88,7 +90,7 @@ public: // this function only works on fixed process, errors and returns null otherwise Physics2DDirectSpaceState* space_get_direct_state(RID p_space) { - ERR_FAIL_COND_V(server_thread!=Thread::get_caller_ID(),NULL); + ERR_FAIL_COND_V(main_thread!=Thread::get_caller_ID(),NULL); return physics_2d_server->space_get_direct_state(p_space); } @@ -221,7 +223,7 @@ public: bool body_test_motion(RID p_body,const Vector2& p_motion,float p_margin=0.001,MotionResult *r_result=NULL) { - ERR_FAIL_COND_V(server_thread!=Thread::get_caller_ID(),false); + ERR_FAIL_COND_V(main_thread!=Thread::get_caller_ID(),false); return body_test_motion(p_body,p_motion,p_margin,r_result); } diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp index 279ad0d74..c2ad7b216 100644 --- a/servers/physics_2d_server.cpp +++ b/servers/physics_2d_server.cpp @@ -713,7 +713,7 @@ void Physics2DServer::_bind_methods() { Physics2DServer::Physics2DServer() { - ERR_FAIL_COND( singleton!=NULL ); + //ERR_FAIL_COND( singleton!=NULL ); singleton=this; } -- cgit v1.2.3-70-g09d2