input events on Area2D is now supported
also added a demo showing how this works
This commit is contained in:
parent
40496dd76a
commit
c6c72a3c37
23 changed files with 392 additions and 6 deletions
|
|
@ -228,4 +228,5 @@ CollisionObject2DSW::CollisionObject2DSW(Type p_type) {
|
|||
instance_id=0;
|
||||
user_mask=0;
|
||||
layer_mask=1;
|
||||
pickable=true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ private:
|
|||
Type type;
|
||||
RID self;
|
||||
ObjectID instance_id;
|
||||
bool pickable;
|
||||
|
||||
struct Shape {
|
||||
|
||||
|
|
@ -129,6 +130,9 @@ public:
|
|||
|
||||
_FORCE_INLINE_ bool is_static() const { return _static; }
|
||||
|
||||
void set_pickable(bool p_pickable) { pickable=p_pickable; }
|
||||
_FORCE_INLINE_ bool is_pickable() const { return pickable; }
|
||||
|
||||
virtual ~CollisionObject2DSW() {}
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -463,6 +463,14 @@ Matrix32 Physics2DServerSW::area_get_transform(RID p_area) const {
|
|||
return area->get_transform();
|
||||
};
|
||||
|
||||
void Physics2DServerSW::area_set_pickable(RID p_area,bool p_pickable) {
|
||||
|
||||
Area2DSW *area = area_owner.get(p_area);
|
||||
ERR_FAIL_COND(!area);
|
||||
area->set_pickable(p_pickable);
|
||||
|
||||
}
|
||||
|
||||
void Physics2DServerSW::area_set_monitorable(RID p_area,bool p_monitorable) {
|
||||
|
||||
Area2DSW *area = area_owner.get(p_area);
|
||||
|
|
@ -943,6 +951,13 @@ bool Physics2DServerSW::body_collide_shape(RID p_body, int p_body_shape, RID p_s
|
|||
|
||||
}
|
||||
|
||||
void Physics2DServerSW::body_set_pickable(RID p_body,bool p_pickable) {
|
||||
|
||||
Body2DSW *body = body_owner.get(p_body);
|
||||
ERR_FAIL_COND(!body);
|
||||
body->set_pickable(p_pickable);
|
||||
|
||||
}
|
||||
|
||||
/* JOINT API */
|
||||
|
||||
|
|
|
|||
|
|
@ -138,6 +138,9 @@ public:
|
|||
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);
|
||||
|
||||
virtual void area_set_pickable(RID p_area,bool p_pickable);
|
||||
|
||||
|
||||
/* BODY API */
|
||||
|
||||
// create a body of a given type
|
||||
|
|
@ -218,6 +221,8 @@ public:
|
|||
virtual void body_set_force_integration_callback(RID p_body,Object *p_receiver,const StringName& p_method,const Variant& p_udata=Variant());
|
||||
virtual bool body_collide_shape(RID p_body, int p_body_shape,RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,Vector2 *r_results,int p_result_max,int &r_result_count);
|
||||
|
||||
virtual void body_set_pickable(RID p_body,bool p_pickable);
|
||||
|
||||
/* JOINT API */
|
||||
|
||||
virtual void joint_set_param(RID p_joint, JointParam p_param, real_t p_value);
|
||||
|
|
|
|||
|
|
@ -106,6 +106,11 @@ void LineShape2DSW::get_supports(const Vector2& p_normal,Vector2 *r_supports,int
|
|||
r_amount=0;
|
||||
}
|
||||
|
||||
bool LineShape2DSW::contains_point(const Vector2& p_point) const {
|
||||
|
||||
return normal.dot(p_point) < d;
|
||||
}
|
||||
|
||||
bool LineShape2DSW::intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const {
|
||||
|
||||
Vector2 segment= p_begin - p_end;
|
||||
|
|
@ -175,6 +180,11 @@ void RayShape2DSW::get_supports(const Vector2& p_normal,Vector2 *r_supports,int
|
|||
|
||||
}
|
||||
|
||||
bool RayShape2DSW::contains_point(const Vector2& p_point) const {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RayShape2DSW::intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const {
|
||||
|
||||
return false; //rays can't be intersected
|
||||
|
|
@ -223,6 +233,11 @@ void SegmentShape2DSW::get_supports(const Vector2& p_normal,Vector2 *r_supports,
|
|||
|
||||
}
|
||||
|
||||
bool SegmentShape2DSW::contains_point(const Vector2& p_point) const {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SegmentShape2DSW::intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const {
|
||||
|
||||
if (!Geometry::segment_intersects_segment_2d(p_begin,p_end,a,b,&r_point))
|
||||
|
|
@ -288,6 +303,13 @@ void CircleShape2DSW::get_supports(const Vector2& p_normal,Vector2 *r_supports,i
|
|||
|
||||
}
|
||||
|
||||
|
||||
bool CircleShape2DSW::contains_point(const Vector2& p_point) const {
|
||||
|
||||
return p_point.length_squared() < radius*radius;
|
||||
}
|
||||
|
||||
|
||||
bool CircleShape2DSW::intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const {
|
||||
|
||||
|
||||
|
|
@ -375,6 +397,11 @@ void RectangleShape2DSW::get_supports(const Vector2& p_normal,Vector2 *r_support
|
|||
|
||||
}
|
||||
|
||||
bool RectangleShape2DSW::contains_point(const Vector2& p_point) const {
|
||||
|
||||
return Math::abs(p_point.x)<half_extents.x && Math::abs(p_point.y)<half_extents.y;
|
||||
}
|
||||
|
||||
bool RectangleShape2DSW::intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const {
|
||||
|
||||
|
||||
|
|
@ -439,6 +466,17 @@ void CapsuleShape2DSW::get_supports(const Vector2& p_normal,Vector2 *r_supports,
|
|||
}
|
||||
}
|
||||
|
||||
bool CapsuleShape2DSW::contains_point(const Vector2& p_point) const {
|
||||
|
||||
Vector2 p = p_point;
|
||||
p.y=Math::abs(p.y);
|
||||
p.y-=height*0.5;
|
||||
if (p.y<0)
|
||||
p.y=0;
|
||||
|
||||
return p.length_squared() < radius*radius;
|
||||
}
|
||||
|
||||
bool CapsuleShape2DSW::intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const {
|
||||
|
||||
|
||||
|
|
@ -574,6 +612,25 @@ void ConvexPolygonShape2DSW::get_supports(const Vector2& p_normal,Vector2 *r_sup
|
|||
|
||||
}
|
||||
|
||||
|
||||
bool ConvexPolygonShape2DSW::contains_point(const Vector2& p_point) const {
|
||||
|
||||
bool out=false;
|
||||
bool in=false;
|
||||
|
||||
for(int i=0;i<point_count;i++) {
|
||||
|
||||
float d = points[i].normal.dot(p_point) - points[i].normal.dot(points[i].pos);
|
||||
if (d>0)
|
||||
out=true;
|
||||
else
|
||||
in=true;
|
||||
}
|
||||
|
||||
return (in && !out) || (!in && out);
|
||||
}
|
||||
|
||||
|
||||
bool ConvexPolygonShape2DSW::intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const {
|
||||
|
||||
Vector2 n = (p_end-p_begin).normalized();
|
||||
|
|
@ -734,6 +791,12 @@ void ConcavePolygonShape2DSW::get_supports(const Vector2& p_normal,Vector2 *r_su
|
|||
|
||||
}
|
||||
|
||||
bool ConcavePolygonShape2DSW::contains_point(const Vector2& p_point) const {
|
||||
|
||||
return false; //sorry
|
||||
}
|
||||
|
||||
|
||||
bool ConcavePolygonShape2DSW::intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const{
|
||||
|
||||
uint32_t* stack = (uint32_t*)alloca(sizeof(int)*bvh_depth);
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ public:
|
|||
|
||||
virtual bool is_concave() const { return false; }
|
||||
|
||||
virtual bool contains_point(const Vector2& p_point) const=0;
|
||||
|
||||
virtual void project_rangev(const Vector2& p_normal, const Matrix32& p_transform, real_t &r_min, real_t &r_max) const=0;
|
||||
virtual void project_range_castv(const Vector2& p_cast, const Vector2& p_normal, const Matrix32& p_transform, real_t &r_min, real_t &r_max) const=0;
|
||||
virtual Vector2 get_support(const Vector2& p_normal) const;
|
||||
|
|
@ -171,6 +173,7 @@ public:
|
|||
virtual void project_rangev(const Vector2& p_normal, const Matrix32& p_transform, real_t &r_min, real_t &r_max) const { project_range(p_normal,p_transform,r_min,r_max); }
|
||||
virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const;
|
||||
|
||||
virtual bool contains_point(const Vector2& p_point) const;
|
||||
virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const;
|
||||
virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const;
|
||||
|
||||
|
|
@ -213,6 +216,7 @@ public:
|
|||
virtual void project_rangev(const Vector2& p_normal, const Matrix32& p_transform, real_t &r_min, real_t &r_max) const { project_range(p_normal,p_transform,r_min,r_max); }
|
||||
virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const;
|
||||
|
||||
virtual bool contains_point(const Vector2& p_point) const;
|
||||
virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const;
|
||||
virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const;
|
||||
|
||||
|
|
@ -260,6 +264,7 @@ public:
|
|||
virtual void project_rangev(const Vector2& p_normal, const Matrix32& p_transform, real_t &r_min, real_t &r_max) const { project_range(p_normal,p_transform,r_min,r_max); }
|
||||
virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const;
|
||||
|
||||
virtual bool contains_point(const Vector2& p_point) const;
|
||||
virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const;
|
||||
virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const;
|
||||
|
||||
|
|
@ -297,6 +302,7 @@ public:
|
|||
virtual void project_rangev(const Vector2& p_normal, const Matrix32& p_transform, real_t &r_min, real_t &r_max) const { project_range(p_normal,p_transform,r_min,r_max); }
|
||||
virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const;
|
||||
|
||||
virtual bool contains_point(const Vector2& p_point) const;
|
||||
virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const;
|
||||
virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const;
|
||||
|
||||
|
|
@ -336,6 +342,7 @@ public:
|
|||
virtual void project_rangev(const Vector2& p_normal, const Matrix32& p_transform, real_t &r_min, real_t &r_max) const { project_range(p_normal,p_transform,r_min,r_max); }
|
||||
virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const;
|
||||
|
||||
virtual bool contains_point(const Vector2& p_point) const;
|
||||
virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const;
|
||||
virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const;
|
||||
|
||||
|
|
@ -423,6 +430,7 @@ public:
|
|||
virtual void project_rangev(const Vector2& p_normal, const Matrix32& p_transform, real_t &r_min, real_t &r_max) const { project_range(p_normal,p_transform,r_min,r_max); }
|
||||
virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const;
|
||||
|
||||
virtual bool contains_point(const Vector2& p_point) const;
|
||||
virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const;
|
||||
virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const;
|
||||
|
||||
|
|
@ -485,6 +493,7 @@ public:
|
|||
virtual void project_rangev(const Vector2& p_normal, const Matrix32& p_transform, real_t &r_min, real_t &r_max) const { project_range(p_normal,p_transform,r_min,r_max); }
|
||||
virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const;
|
||||
|
||||
virtual bool contains_point(const Vector2& p_point) const;
|
||||
virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const;
|
||||
virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const;
|
||||
|
||||
|
|
@ -572,6 +581,7 @@ public:
|
|||
virtual void project_range(const Vector2& p_normal, const Matrix32& p_transform, real_t &r_min, real_t &r_max) const { /*project_range(p_normal,p_transform,r_min,r_max);*/ }
|
||||
virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const;
|
||||
|
||||
virtual bool contains_point(const Vector2& p_point) const;
|
||||
virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const;
|
||||
|
||||
virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const { return 0; }
|
||||
|
|
|
|||
|
|
@ -45,6 +45,57 @@ _FORCE_INLINE_ static bool _match_object_type_query(CollisionObject2DSW *p_objec
|
|||
|
||||
}
|
||||
|
||||
|
||||
int Physics2DDirectSpaceStateSW::intersect_point(const Vector2& p_point,ShapeResult *r_results,int p_result_max,const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) {
|
||||
|
||||
if (p_result_max<=0)
|
||||
return 0;
|
||||
|
||||
Rect2 aabb;
|
||||
aabb.pos=p_point-Vector2(0.00001,0.00001);
|
||||
aabb.size=Vector2(0.00002,0.00002);
|
||||
|
||||
int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,Space2DSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results);
|
||||
|
||||
int cc=0;
|
||||
|
||||
for(int i=0;i<amount;i++) {
|
||||
|
||||
if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask))
|
||||
continue;
|
||||
|
||||
if (p_exclude.has( space->intersection_query_results[i]->get_self()))
|
||||
continue;
|
||||
|
||||
const CollisionObject2DSW *col_obj=space->intersection_query_results[i];
|
||||
|
||||
if (!col_obj->is_pickable())
|
||||
continue;
|
||||
|
||||
int shape_idx=space->intersection_query_subindex_results[i];
|
||||
|
||||
Shape2DSW * shape = col_obj->get_shape(shape_idx);
|
||||
|
||||
Vector2 local_point = (col_obj->get_transform() * col_obj->get_shape_transform(shape_idx)).affine_inverse().xform(p_point);
|
||||
|
||||
if (!shape->contains_point(local_point))
|
||||
continue;
|
||||
|
||||
r_results[cc].collider_id=col_obj->get_instance_id();
|
||||
if (r_results[cc].collider_id!=0)
|
||||
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++;
|
||||
}
|
||||
|
||||
return cc;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2& p_from, const Vector2& p_to,RayResult &r_result,const Set<RID>& p_exclude,uint32_t p_layer_mask,uint32_t p_object_type_mask) {
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ public:
|
|||
|
||||
Space2DSW *space;
|
||||
|
||||
virtual int intersect_point(const Vector2& p_point,ShapeResult *r_results,int p_result_max,const Set<RID>& p_exclude=Set<RID>(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION);
|
||||
virtual bool intersect_ray(const Vector2& p_from, const Vector2& p_to,RayResult &r_result,const Set<RID>& p_exclude=Set<RID>(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION);
|
||||
virtual int intersect_shape(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,ShapeResult *r_results,int p_result_max,const Set<RID>& p_exclude=Set<RID>(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION);
|
||||
virtual bool cast_motion(const RID& p_shape, const Matrix32& p_xform,const Vector2& p_motion,float p_margin,float &p_closest_safe,float &p_closest_unsafe, const Set<RID>& p_exclude=Set<RID>(),uint32_t p_layer_mask=0xFFFFFFFF,uint32_t p_object_type_mask=TYPE_MASK_COLLISION);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue