diff options
Diffstat (limited to 'servers')
24 files changed, 1196 insertions, 121 deletions
diff --git a/servers/physics/shape_sw.h b/servers/physics/shape_sw.h index cdb21556b8..bcf8fbdc8d 100644 --- a/servers/physics/shape_sw.h +++ b/servers/physics/shape_sw.h @@ -438,7 +438,7 @@ struct MotionShapeSW : public ShapeSW { } return support; } - virtual void get_supports(const Vector3& p_normal,int p_max,Vector3 *r_supports,int & r_amount) const {} + virtual void get_supports(const Vector3& p_normal,int p_max,Vector3 *r_supports,int & r_amount) const { r_amount=0; } bool intersect_segment(const Vector3& p_begin,const Vector3& p_end,Vector3 &r_result, Vector3 &r_normal) const { return false; } Vector3 get_moment_of_inertia(float p_mass) const { return Vector3(); } diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp index 4e8b60b86b..3fc34889f2 100644 --- a/servers/physics/space_sw.cpp +++ b/servers/physics/space_sw.cpp @@ -77,7 +77,7 @@ bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3& p_from, const Vecto if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask))
continue;
- if (!(static_cast<AreaSW*>(space->intersection_query_results[i])->is_ray_pickable()))
+ if (!(static_cast<CollisionObjectSW*>(space->intersection_query_results[i])->is_ray_pickable()))
continue;
if (p_exclude.has( space->intersection_query_results[i]->get_self()))
diff --git a/servers/physics_2d/area_2d_sw.cpp b/servers/physics_2d/area_2d_sw.cpp index 2e911288ae..65f3b80dd3 100644 --- a/servers/physics_2d/area_2d_sw.cpp +++ b/servers/physics_2d/area_2d_sw.cpp @@ -31,6 +31,7 @@ #include "body_2d_sw.h" Area2DSW::BodyKey::BodyKey(Body2DSW *p_body, uint32_t p_body_shape,uint32_t p_area_shape) { rid=p_body->get_self(); instance_id=p_body->get_instance_id(); body_shape=p_body_shape; area_shape=p_area_shape; } +Area2DSW::BodyKey::BodyKey(Area2DSW *p_body, uint32_t p_body_shape,uint32_t p_area_shape) { rid=p_body->get_self(); instance_id=p_body->get_instance_id(); body_shape=p_body_shape; area_shape=p_area_shape; } void Area2DSW::_shapes_changed() { @@ -57,6 +58,7 @@ void Area2DSW::set_space(Space2DSW *p_space) { } monitored_bodies.clear(); + monitored_areas.clear(); _set_space(p_space); } @@ -76,11 +78,31 @@ void Area2DSW::set_monitor_callback(ObjectID p_id, const StringName& p_method) { monitor_callback_method=p_method; monitored_bodies.clear(); + monitored_areas.clear(); _shape_changed(); } +void Area2DSW::set_area_monitor_callback(ObjectID p_id, const StringName& p_method) { + + + if (p_id==area_monitor_callback_id) { + area_monitor_callback_method=p_method; + return; + } + + _unregister_shapes(); + + area_monitor_callback_id=p_id; + area_monitor_callback_method=p_method; + + monitored_bodies.clear(); + monitored_areas.clear(); + + _shape_changed(); + +} void Area2DSW::set_space_override_mode(Physics2DServer::AreaSpaceOverrideMode p_mode) { @@ -134,6 +156,15 @@ void Area2DSW::_queue_monitor_update() { } +void Area2DSW::set_monitorable(bool p_monitorable) { + + if (monitorable==p_monitorable) + return; + + monitorable=p_monitorable; + _set_static(!monitorable); +} + void Area2DSW::call_queries() { if (monitor_callback_id && !monitored_bodies.empty()) { @@ -170,13 +201,49 @@ void Area2DSW::call_queries() { monitored_bodies.clear(); + if (area_monitor_callback_id && !monitored_areas.empty()) { + + + Variant res[5]; + Variant *resptr[5]; + for(int i=0;i<5;i++) + resptr[i]=&res[i]; + + Object *obj = ObjectDB::get_instance(area_monitor_callback_id); + if (!obj) { + monitored_areas.clear(); + area_monitor_callback_id=0; + return; + } + + + + for (Map<BodyKey,BodyState>::Element *E=monitored_areas.front();E;E=E->next()) { + + if (E->get().state==0) + continue; //nothing happened + + res[0]=E->get().state>0 ? Physics2DServer::AREA_BODY_ADDED : Physics2DServer::AREA_BODY_REMOVED; + res[1]=E->key().rid; + res[2]=E->key().instance_id; + res[3]=E->key().body_shape; + res[4]=E->key().area_shape; + + + Variant::CallError ce; + obj->call(area_monitor_callback_method,(const Variant**)resptr,5,ce); + } + } + + monitored_areas.clear(); + //get_space()->area_remove_from_monitor_query_list(&monitor_query_list); } Area2DSW::Area2DSW() : CollisionObject2DSW(TYPE_AREA), monitor_query_list(this), moved_list(this) { - _set_static(true); //areas are never active + _set_static(true); //areas are not active by default space_override_mode=Physics2DServer::AREA_SPACE_OVERRIDE_DISABLED; gravity=9.80665; gravity_vector=Vector2(0,-1); @@ -187,6 +254,8 @@ Area2DSW::Area2DSW() : CollisionObject2DSW(TYPE_AREA), monitor_query_list(this), linear_damp=0.1; priority=0; monitor_callback_id=0; + area_monitor_callback_id=0; + monitorable=false; } diff --git a/servers/physics_2d/area_2d_sw.h b/servers/physics_2d/area_2d_sw.h index d94b2f9ccf..26b7b2516c 100644 --- a/servers/physics_2d/area_2d_sw.h +++ b/servers/physics_2d/area_2d_sw.h @@ -50,10 +50,14 @@ class Area2DSW : public CollisionObject2DSW{ float linear_damp; float angular_damp; int priority; + bool monitorable; ObjectID monitor_callback_id; StringName monitor_callback_method; + ObjectID area_monitor_callback_id; + StringName area_monitor_callback_method; + SelfList<Area2DSW> monitor_query_list; SelfList<Area2DSW> moved_list; @@ -80,6 +84,7 @@ class Area2DSW : public CollisionObject2DSW{ _FORCE_INLINE_ BodyKey() {} BodyKey(Body2DSW *p_body, uint32_t p_body_shape,uint32_t p_area_shape); + BodyKey(Area2DSW *p_body, uint32_t p_body_shape,uint32_t p_area_shape); }; struct BodyState { @@ -91,6 +96,7 @@ class Area2DSW : public CollisionObject2DSW{ }; Map<BodyKey,BodyState> monitored_bodies; + Map<BodyKey,BodyState> monitored_areas; //virtual void shape_changed_notify(Shape2DSW *p_shape); //virtual void shape_deleted_notify(Shape2DSW *p_shape); @@ -108,9 +114,16 @@ public: void set_monitor_callback(ObjectID p_id, const StringName& p_method); _FORCE_INLINE_ bool has_monitor_callback() const { return monitor_callback_id; } + void set_area_monitor_callback(ObjectID p_id, const StringName& p_method); + _FORCE_INLINE_ bool has_area_monitor_callback() const { return area_monitor_callback_id; } + + _FORCE_INLINE_ void add_body_to_query(Body2DSW *p_body, uint32_t p_body_shape,uint32_t p_area_shape); _FORCE_INLINE_ void remove_body_from_query(Body2DSW *p_body, uint32_t p_body_shape,uint32_t p_area_shape); + _FORCE_INLINE_ void add_area_to_query(Area2DSW *p_area, uint32_t p_area_shape,uint32_t p_self_shape); + _FORCE_INLINE_ void remove_area_from_query(Area2DSW *p_area, uint32_t p_area_shape,uint32_t p_self_shape); + void set_param(Physics2DServer::AreaParameter p_param, const Variant& p_value); Variant get_param(Physics2DServer::AreaParameter p_param) const; @@ -142,6 +155,9 @@ public: _FORCE_INLINE_ void remove_constraint( Constraint2DSW* p_constraint) { constraints.erase(p_constraint); } _FORCE_INLINE_ const Set<Constraint2DSW*>& get_constraints() const { return constraints; } + void set_monitorable(bool p_monitorable); + _FORCE_INLINE_ bool is_monitorable() const { return monitorable; } + void set_transform(const Matrix32& p_transform); void set_space(Space2DSW *p_space); @@ -168,6 +184,24 @@ void Area2DSW::remove_body_from_query(Body2DSW *p_body, uint32_t p_body_shape,ui _queue_monitor_update(); } +void Area2DSW::add_area_to_query(Area2DSW *p_area, uint32_t p_area_shape,uint32_t p_self_shape) { + + + BodyKey bk(p_area,p_area_shape,p_self_shape); + monitored_areas[bk].inc(); + if (!monitor_query_list.in_list()) + _queue_monitor_update(); + + +} +void Area2DSW::remove_area_from_query(Area2DSW *p_area, uint32_t p_area_shape,uint32_t p_self_shape) { + + + BodyKey bk(p_area,p_area_shape,p_self_shape); + monitored_areas[bk].dec(); + if (!monitor_query_list.in_list()) + _queue_monitor_update(); +} diff --git a/servers/physics_2d/area_pair_2d_sw.cpp b/servers/physics_2d/area_pair_2d_sw.cpp index 1c7f73db5e..ed2e34c972 100644 --- a/servers/physics_2d/area_pair_2d_sw.cpp +++ b/servers/physics_2d/area_pair_2d_sw.cpp @@ -94,3 +94,72 @@ AreaPair2DSW::~AreaPair2DSW() { body->remove_constraint(this); area->remove_constraint(this); } + + +////////////////////////////////// + + + +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); + + if (result!=colliding) { + + if (result) { + + if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) + area_b->add_area_to_query(area_a,shape_a,shape_b); + + if (area_a->has_area_monitor_callback() && area_b->is_monitorable()) + area_a->add_area_to_query(area_b,shape_b,shape_a); + + } else { + + if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) + area_b->remove_area_from_query(area_a,shape_a,shape_b); + + if (area_a->has_area_monitor_callback() && area_b->is_monitorable()) + area_a->remove_area_from_query(area_b,shape_b,shape_a); + } + + colliding=result; + + } + + return false; //never do any post solving +} + +void Area2Pair2DSW::solve(float p_step) { + + +} + + +Area2Pair2DSW::Area2Pair2DSW(Area2DSW *p_area_a,int p_shape_a, Area2DSW *p_area_b,int p_shape_b) { + + + area_a=p_area_a; + area_b=p_area_b; + shape_a=p_shape_a; + shape_b=p_shape_b; + colliding=false; + area_a->add_constraint(this); + area_b->add_constraint(this); + +} + +Area2Pair2DSW::~Area2Pair2DSW() { + + if (colliding) { + + if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) + area_b->remove_area_from_query(area_a,shape_a,shape_b); + + if (area_a->has_area_monitor_callback() && area_b->is_monitorable()) + area_a->remove_area_from_query(area_b,shape_b,shape_a); + } + + area_a->remove_constraint(this); + area_b->remove_constraint(this); +} diff --git a/servers/physics_2d/area_pair_2d_sw.h b/servers/physics_2d/area_pair_2d_sw.h index 5dad8c7a12..575490b109 100644 --- a/servers/physics_2d/area_pair_2d_sw.h +++ b/servers/physics_2d/area_pair_2d_sw.h @@ -49,5 +49,23 @@ public: ~AreaPair2DSW(); }; + +class Area2Pair2DSW : public Constraint2DSW { + + Area2DSW *area_a; + Area2DSW *area_b; + int shape_a; + int shape_b; + bool colliding; +public: + + bool setup(float p_step); + void solve(float p_step); + + Area2Pair2DSW(Area2DSW *p_area_a,int p_shape_a, Area2DSW *p_area_b,int p_shape_b); + ~Area2Pair2DSW(); +}; + + #endif // AREA_PAIR_2D_SW_H diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp index d0443f8110..eefc598b39 100644 --- a/servers/physics_2d/collision_object_2d_sw.cpp +++ b/servers/physics_2d/collision_object_2d_sw.cpp @@ -228,4 +228,5 @@ CollisionObject2DSW::CollisionObject2DSW(Type p_type) { instance_id=0; user_mask=0; 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 00ad361245..0c91237876 100644 --- a/servers/physics_2d/collision_object_2d_sw.h +++ b/servers/physics_2d/collision_object_2d_sw.h @@ -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() {} }; diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp index be49955055..883acd0200 100644 --- a/servers/physics_2d/physics_2d_server_sw.cpp +++ b/servers/physics_2d/physics_2d_server_sw.cpp @@ -463,6 +463,24 @@ 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); + ERR_FAIL_COND(!area); + + area->set_monitorable(p_monitorable); + +} + + void Physics2DServerSW::area_set_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method) { Area2DSW *area = area_owner.get(p_area); @@ -473,6 +491,14 @@ void Physics2DServerSW::area_set_monitor_callback(RID p_area,Object *p_receiver, } +void Physics2DServerSW::area_set_area_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method) { + + + Area2DSW *area = area_owner.get(p_area); + ERR_FAIL_COND(!area); + + area->set_area_monitor_callback(p_receiver?p_receiver->get_instance_ID():0,p_method); +} /* BODY API */ @@ -925,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 */ diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h index e9c499aaff..58fc4eeb33 100644 --- a/servers/physics_2d/physics_2d_server_sw.h +++ b/servers/physics_2d/physics_2d_server_sw.h @@ -133,8 +133,12 @@ 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_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 */ @@ -217,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); diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/shape_2d_sw.cpp index ed63870a12..9a4b52d563 100644 --- a/servers/physics_2d/shape_2d_sw.cpp +++ b/servers/physics_2d/shape_2d_sw.cpp @@ -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); diff --git a/servers/physics_2d/shape_2d_sw.h b/servers/physics_2d/shape_2d_sw.h index 931491efd5..05ea5b21cd 100644 --- a/servers/physics_2d/shape_2d_sw.h +++ b/servers/physics_2d/shape_2d_sw.h @@ -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; } diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index f2ed74ffbf..5aaf9a7613 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -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) { @@ -527,13 +578,20 @@ void* Space2DSW::_broadphase_pair(CollisionObject2DSW *A,int p_subindex_A,Collis if (type_A==CollisionObject2DSW::TYPE_AREA) { - ERR_FAIL_COND_V(type_B!=CollisionObject2DSW::TYPE_BODY,NULL); Area2DSW *area=static_cast<Area2DSW*>(A); - Body2DSW *body=static_cast<Body2DSW*>(B); + if (type_B==CollisionObject2DSW::TYPE_AREA) { + + Area2DSW *area_b=static_cast<Area2DSW*>(B); + Area2Pair2DSW *area2_pair = memnew(Area2Pair2DSW(area_b,p_subindex_B,area,p_subindex_A) ); + return area2_pair; + } else { + + Body2DSW *body=static_cast<Body2DSW*>(B); + AreaPair2DSW *area_pair = memnew(AreaPair2DSW(body,p_subindex_B,area,p_subindex_A) ); + return area_pair; + } - AreaPair2DSW *area_pair = memnew(AreaPair2DSW(body,p_subindex_B,area,p_subindex_A) ); - return area_pair; } else { diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h index 7977b19063..05b55fe807 100644 --- a/servers/physics_2d/space_2d_sw.h +++ b/servers/physics_2d/space_2d_sw.h @@ -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); diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp index 07389bc912..098f890222 100644 --- a/servers/physics_2d_server.cpp +++ b/servers/physics_2d_server.cpp @@ -289,6 +289,36 @@ Array Physics2DDirectSpaceState::_cast_motion(const Ref<Physics2DShapeQueryParam return ret; } + +Array Physics2DDirectSpaceState::_intersect_point(const Vector2& p_point,int p_max_results,const Vector<RID>& p_exclude,uint32_t p_layers,uint32_t p_object_type_mask) { + + Set<RID> exclude; + for(int i=0;i<p_exclude.size();i++) + exclude.insert(p_exclude[i]); + + Vector<ShapeResult> ret; + ret.resize(p_max_results); + + int rc = intersect_point(p_point,ret.ptr(),ret.size(),exclude,p_layers,p_object_type_mask); + if (rc==0) + return Array(); + + Array r; + r.resize(rc); + for(int i=0;i<rc;i++) { + + Dictionary d; + d["rid"]=ret[i].rid; + d["collider_id"]=ret[i].collider_id; + d["collider"]=ret[i].collider; + d["shape"]=ret[i].shape; + d["metadata"]=ret[i].metadata; + r[i]=d; + } + return r; + +} + Array Physics2DDirectSpaceState::_collide_shape(const Ref<Physics2DShapeQueryParameters> &psq, int p_max_results){ Vector<Vector2> ret; @@ -336,6 +366,7 @@ Physics2DDirectSpaceState::Physics2DDirectSpaceState() { void Physics2DDirectSpaceState::_bind_methods() { + ObjectTypeDB::bind_method(_MD("intersect_point","point","max_results","exclude","layer_mask","type_mask"),&Physics2DDirectSpaceState::_intersect_point,DEFVAL(32),DEFVAL(Array()),DEFVAL(0x7FFFFFFF),DEFVAL(TYPE_MASK_COLLISION)); ObjectTypeDB::bind_method(_MD("intersect_ray:Dictionary","from","to","exclude","layer_mask","type_mask"),&Physics2DDirectSpaceState::_intersect_ray,DEFVAL(Array()),DEFVAL(0x7FFFFFFF),DEFVAL(TYPE_MASK_COLLISION)); ObjectTypeDB::bind_method(_MD("intersect_shape","shape:Physics2DShapeQueryParameters","max_results"),&Physics2DDirectSpaceState::_intersect_shape,DEFVAL(32)); ObjectTypeDB::bind_method(_MD("cast_motion","shape:Physics2DShapeQueryParameters"),&Physics2DDirectSpaceState::_cast_motion); diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h index 765cebf45f..01670ace7e 100644 --- a/servers/physics_2d_server.h +++ b/servers/physics_2d_server.h @@ -137,6 +137,7 @@ class Physics2DDirectSpaceState : public Object { Dictionary _intersect_ray(const Vector2& p_from, const Vector2& p_to,const Vector<RID>& p_exclude=Vector<RID>(),uint32_t p_layers=0,uint32_t p_object_type_mask=TYPE_MASK_COLLISION); + Array _intersect_point(const Vector2& p_point,int p_max_results=32,const Vector<RID>& p_exclude=Vector<RID>(),uint32_t p_layers=0,uint32_t p_object_type_mask=TYPE_MASK_COLLISION); Array _intersect_shape(const Ref<Physics2DShapeQueryParameters> &p_shape_query,int p_max_results=32); Array _cast_motion(const Ref<Physics2DShapeQueryParameters> &p_shape_query); Array _collide_shape(const Ref<Physics2DShapeQueryParameters> &p_shape_query,int p_max_results=32); @@ -181,6 +182,8 @@ public: }; + 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)=0; + 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)=0; 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)=0; @@ -341,7 +344,11 @@ 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_monitorable(RID p_area,bool p_monitorable)=0; + virtual void area_set_pickable(RID p_area,bool p_pickable)=0; + virtual void area_set_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method)=0; + virtual void area_set_area_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method)=0; /* BODY API */ @@ -459,6 +466,8 @@ public: 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)=0; + virtual void body_set_pickable(RID p_body,bool p_pickable)=0; + /* JOINT API */ enum JointType { diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 2ae283f3b7..ebc210fe3d 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -564,42 +564,50 @@ public: CANVAS_RECT_REGION=1, CANVAS_RECT_TILE=2, CANVAS_RECT_FLIP_H=4, - CANVAS_RECT_FLIP_V=8 + CANVAS_RECT_FLIP_V=8, + CANVAS_RECT_TRANSPOSE=16 }; struct CanvasLight { + bool enabled; - bool shadow; Color color; Matrix32 xform; float height; + float scale; int z_min; int z_max; int layer_min; int layer_max; int item_mask; + int item_shadow_mask; bool subtract; RID texture; Vector2 texture_offset; RID canvas; + RID shadow_buffer; + int shadow_buffer_size; + float shadow_esm_mult; void *texture_cache; // implementation dependent Rect2 rect_cache; Matrix32 xform_cache; + float radius_cache; //used for shadow far plane + CameraMatrix shadow_matrix_cache; Matrix32 light_shader_xform; Vector2 light_shader_pos; + CanvasLight *shadows_next_ptr; CanvasLight *filter_next_ptr; CanvasLight *next_ptr; CanvasLight() { - enabled=true; - shadow=false; + enabled=true; color=Color(1,1,1); height=0; z_min=-1024; @@ -607,13 +615,30 @@ public: layer_min=0; layer_max=0; item_mask=1; + scale=1.0; + item_shadow_mask=-1; subtract=false; texture_cache=NULL; next_ptr=NULL; filter_next_ptr=NULL; + shadow_buffer_size=2048; + shadow_esm_mult=80; + } }; + struct CanvasItem; + + struct CanvasItemMaterial { + + RID shader; + Map<StringName,Variant> shader_param; + uint32_t shader_version; + Set<CanvasItem*> owners; + bool unshaded; + + CanvasItemMaterial() {unshaded=false; shader_version=0; } + }; struct CanvasItem { @@ -743,17 +768,22 @@ public: mutable bool rect_dirty; mutable Rect2 rect; CanvasItem*next; - RID shader; - Map<StringName,Variant> shader_param; - uint32_t shader_version; + CanvasItemMaterial* material; + struct CopyBackBuffer { + Rect2 rect; + Rect2 screen_rect; + bool full; + }; + CopyBackBuffer *copy_back_buffer; float final_opacity; Matrix32 final_transform; Rect2 final_clip_rect; CanvasItem* final_clip_owner; - CanvasItem* shader_owner; + CanvasItem* material_owner; ViewportRender *vp_render; + bool distance_field; Rect2 global_rect_cache; @@ -880,15 +910,16 @@ public: return rect; } - void clear() { for (int i=0;i<commands.size();i++) memdelete( commands[i] ); commands.clear(); clip=false; rect_dirty=true; final_clip_owner=NULL; shader_owner=NULL;} - CanvasItem() { light_mask=1; vp_render=NULL; next=NULL; final_clip_owner=NULL; clip=false; final_opacity=1; blend_mode=VS::MATERIAL_BLEND_MODE_MIX; visible=true; rect_dirty=true; custom_rect=false; ontop=true; shader_version=0; shader_owner=NULL;} - virtual ~CanvasItem() { clear(); } + void clear() { for (int i=0;i<commands.size();i++) memdelete( commands[i] ); commands.clear(); clip=false; rect_dirty=true; final_clip_owner=NULL; material_owner=NULL;} + CanvasItem() { light_mask=1; vp_render=NULL; next=NULL; final_clip_owner=NULL; clip=false; final_opacity=1; blend_mode=VS::MATERIAL_BLEND_MODE_MIX; visible=true; rect_dirty=true; custom_rect=false; ontop=true; material_owner=NULL; material=NULL; copy_back_buffer=NULL; distance_field=false; } + virtual ~CanvasItem() { clear(); if (copy_back_buffer) memdelete(copy_back_buffer); } }; CanvasItemDrawViewportFunc draw_viewport_func; + virtual void begin_canvas_bg()=0; virtual void canvas_begin()=0; virtual void canvas_disable_blending()=0; virtual void canvas_set_opacity(float p_opacity)=0; @@ -904,7 +935,36 @@ public: virtual void canvas_set_transform(const Matrix32& p_transform)=0; virtual void canvas_render_items(CanvasItem *p_item_list,int p_z,const Color& p_modulate,CanvasLight *p_light)=0; + virtual void canvas_debug_viewport_shadows(CanvasLight* p_lights_with_shadow)=0; + /* LIGHT SHADOW MAPPING */ + + virtual RID canvas_light_occluder_create()=0; + virtual void canvas_light_occluder_set_polylines(RID p_occluder, const DVector<Vector2>& p_lines)=0; + + virtual RID canvas_light_shadow_buffer_create(int p_width)=0; + + struct CanvasLightOccluderInstance { + + + bool enabled; + RID canvas; + RID polygon; + RID polygon_buffer; + Rect2 aabb_cache; + Matrix32 xform; + Matrix32 xform_cache; + int light_mask; + VS::CanvasOccluderPolygonCullMode cull_cache; + + CanvasLightOccluderInstance *next; + + CanvasLightOccluderInstance() { enabled=true; next=NULL; light_mask=1; cull_cache=VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; } + }; + + + + virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Matrix32& p_light_xform, int p_light_mask,float p_near, float p_far, CanvasLightOccluderInstance* p_occluders, CameraMatrix *p_xform_cache)=0; /* ENVIRONMENT */ @@ -944,6 +1004,8 @@ public: virtual bool is_environment(const RID& p_rid) const=0; virtual bool is_shader(const RID& p_rid) const=0; + virtual bool is_canvas_light_occluder(const RID& p_rid) const=0; + virtual void free(const RID& p_rid)=0; virtual void init()=0; diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index dfa0172e82..af65a7a639 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -56,6 +56,7 @@ const char * ShaderLanguage::token_names[TK_MAX]={ "TYPE_VEC2", "TYPE_VEC3", "TYPE_VEC4", + "TYPE_MAT2", "TYPE_MAT3", "TYPE_MAT4", "TYPE_TEXTURE", @@ -403,9 +404,9 @@ ShaderLanguage::Token ShaderLanguage::read_token(const CharType* p_text,int p_le {TK_TYPE_TEXTURE,"texture"}, {TK_TYPE_CUBEMAP,"cubemap"}, {TK_TYPE_COLOR,"color"}, - /* + {TK_TYPE_MAT2,"mat2"}, - {TK_TYPE_MAT3,"mat3"}, + /*{TK_TYPE_MAT3,"mat3"}, {TK_TYPE_MAT4,"mat3"},*/ {TK_TYPE_MAT3,"mat3"}, {TK_TYPE_MAT4,"mat4"}, @@ -511,6 +512,7 @@ bool ShaderLanguage::is_token_datatype(TokenType p_type) { (p_type==TK_TYPE_VEC3) || (p_type==TK_TYPE_VEC4) || (p_type==TK_TYPE_COLOR) || + (p_type==TK_TYPE_MAT2) || (p_type==TK_TYPE_MAT3) || (p_type==TK_TYPE_MAT4) || (p_type==TK_TYPE_CUBEMAP) || @@ -529,6 +531,7 @@ ShaderLanguage::DataType ShaderLanguage::get_token_datatype(TokenType p_type) { case TK_TYPE_VEC3: return TYPE_VEC3; case TK_TYPE_VEC4: return TYPE_VEC4; case TK_TYPE_COLOR: return TYPE_VEC4; + case TK_TYPE_MAT2: return TYPE_MAT2; case TK_TYPE_MAT3: return TYPE_MAT3; case TK_TYPE_MAT4: return TYPE_MAT4; case TK_TYPE_TEXTURE: return TYPE_TEXTURE; @@ -550,6 +553,7 @@ String ShaderLanguage::get_datatype_name(DataType p_type) { case TYPE_VEC2: return "vec2"; case TYPE_VEC3: return "vec3"; case TYPE_VEC4: return "vec4"; + case TYPE_MAT2: return "mat2"; case TYPE_MAT3: return "mat3"; case TYPE_MAT4: return "mat4"; case TYPE_TEXTURE: return "texture"; @@ -570,6 +574,7 @@ bool ShaderLanguage::is_token_nonvoid_datatype(TokenType p_type) { (p_type==TK_TYPE_VEC3) || (p_type==TK_TYPE_VEC4) || (p_type==TK_TYPE_COLOR) || + (p_type==TK_TYPE_MAT2) || (p_type==TK_TYPE_MAT3) || (p_type==TK_TYPE_MAT4) || (p_type==TK_TYPE_TEXTURE) || @@ -782,6 +787,7 @@ const ShaderLanguage::IntrinsicFuncDef ShaderLanguage::intrinsic_func_defs[]={ {"vec4",TYPE_VEC4,{TYPE_FLOAT,TYPE_VEC3,TYPE_VOID}}, {"vec4",TYPE_VEC4,{TYPE_VEC3,TYPE_FLOAT,TYPE_VOID}}, {"vec4",TYPE_VEC4,{TYPE_VEC2,TYPE_VEC2,TYPE_VOID}}, + {"mat2",TYPE_MAT2,{TYPE_VEC2,TYPE_VEC2,TYPE_VOID}}, {"mat3",TYPE_MAT3,{TYPE_VEC3,TYPE_VEC3,TYPE_VEC3,TYPE_VOID}}, {"mat4",TYPE_MAT4,{TYPE_VEC4,TYPE_VEC4,TYPE_VEC4,TYPE_VEC4,TYPE_VOID}}, //intrinsics - trigonometry @@ -918,6 +924,7 @@ const ShaderLanguage::OperatorDef ShaderLanguage::operator_defs[]={ {OP_ASSIGN,TYPE_VOID,{TYPE_VEC2,TYPE_VEC2}}, {OP_ASSIGN,TYPE_VOID,{TYPE_VEC3,TYPE_VEC3}}, {OP_ASSIGN,TYPE_VOID,{TYPE_VEC4,TYPE_VEC4}}, + {OP_ASSIGN,TYPE_VOID,{TYPE_MAT2,TYPE_MAT2}}, {OP_ASSIGN,TYPE_VOID,{TYPE_MAT3,TYPE_MAT3}}, {OP_ASSIGN,TYPE_VOID,{TYPE_MAT4,TYPE_MAT4}}, {OP_ADD,TYPE_FLOAT,{TYPE_FLOAT,TYPE_FLOAT}}, @@ -933,6 +940,8 @@ const ShaderLanguage::OperatorDef ShaderLanguage::operator_defs[]={ {OP_MUL,TYPE_VEC2,{TYPE_VEC2,TYPE_FLOAT}}, {OP_MUL,TYPE_VEC2,{TYPE_FLOAT,TYPE_VEC2}}, {OP_MUL,TYPE_VEC2,{TYPE_VEC2,TYPE_MAT3}}, + {OP_MUL,TYPE_VEC2,{TYPE_MAT2,TYPE_VEC2}}, + {OP_MUL,TYPE_VEC2,{TYPE_VEC2,TYPE_MAT2}}, {OP_MUL,TYPE_VEC2,{TYPE_MAT3,TYPE_VEC2}}, {OP_MUL,TYPE_VEC2,{TYPE_VEC2,TYPE_MAT4}}, {OP_MUL,TYPE_VEC2,{TYPE_MAT4,TYPE_VEC2}}, @@ -947,6 +956,7 @@ const ShaderLanguage::OperatorDef ShaderLanguage::operator_defs[]={ {OP_MUL,TYPE_VEC4,{TYPE_FLOAT,TYPE_VEC4}}, {OP_MUL,TYPE_VEC4,{TYPE_MAT4,TYPE_VEC4}}, {OP_MUL,TYPE_VEC4,{TYPE_VEC4,TYPE_MAT4}}, + {OP_MUL,TYPE_MAT2,{TYPE_MAT2,TYPE_MAT2}}, {OP_MUL,TYPE_MAT3,{TYPE_MAT3,TYPE_MAT3}}, {OP_MUL,TYPE_MAT4,{TYPE_MAT4,TYPE_MAT4}}, {OP_DIV,TYPE_FLOAT,{TYPE_FLOAT,TYPE_FLOAT}}, @@ -976,15 +986,15 @@ const ShaderLanguage::OperatorDef ShaderLanguage::operator_defs[]={ {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_FLOAT,TYPE_FLOAT}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC2,TYPE_VEC2}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC2,TYPE_FLOAT}}, - {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT3,TYPE_VEC2}}, - {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT4,TYPE_VEC2}}, + {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC2,TYPE_MAT2}}, + {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT2,TYPE_MAT2}}, + {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC3,TYPE_MAT3}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC3,TYPE_VEC3}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC3,TYPE_FLOAT}}, - {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT3,TYPE_VEC3}}, - {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT4,TYPE_VEC3}}, + {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC3,TYPE_MAT4}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC4,TYPE_VEC4}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC4,TYPE_FLOAT}}, - {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT4,TYPE_VEC4}}, + {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC4,TYPE_MAT4}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT3,TYPE_MAT3}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_MAT4,TYPE_MAT4}}, {OP_ASSIGN_DIV,TYPE_VOID,{TYPE_FLOAT,TYPE_FLOAT}}, @@ -1149,11 +1159,19 @@ const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_fragment_builtins_defs[]={ const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_light_builtins_defs[]={ - { "COLOR", TYPE_VEC4}, + { "POSITION", TYPE_VEC4}, { "NORMAL", TYPE_VEC3}, - { "LIGHT_DIR", TYPE_VEC2}, - { "LIGHT_DISTANCE", TYPE_FLOAT}, - { "LIGHT", TYPE_VEC3}, + { "UV", TYPE_VEC2}, + { "COLOR", TYPE_VEC4}, + { "TEXTURE", TYPE_TEXTURE}, + { "TEXTURE_PIXEL_SIZE", TYPE_VEC2}, + { "VAR1", TYPE_VEC4}, + { "VAR2", TYPE_VEC4}, + { "SCREEN_UV", TYPE_VEC2}, + { "LIGHT_VEC", TYPE_VEC2}, + { "LIGHT_HEIGHT", TYPE_FLOAT}, + { "LIGHT_COLOR", TYPE_VEC4}, + { "LIGHT", TYPE_VEC4}, { "POINT_COORD", TYPE_VEC2}, // { "SCREEN_POS", TYPE_VEC2}, // { "SCREEN_TEXEL_SIZE", TYPE_VEC2}, @@ -1558,6 +1576,7 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex case TYPE_VEC2: name="vec2"; break; case TYPE_VEC3: name="vec3"; break; case TYPE_VEC4: name="vec4"; break; + case TYPE_MAT2: name="mat2"; break; case TYPE_MAT3: name="mat3"; break; case TYPE_MAT4: name="mat4"; break; default: ERR_FAIL_V(ERR_BUG); @@ -1852,6 +1871,7 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex } } break; + case TYPE_MAT2: ok=(ident=="x" || ident=="y"); member_type=TYPE_VEC2; break; case TYPE_MAT3: ok=(ident=="x" || ident=="y" || ident=="z" ); member_type=TYPE_VEC3; break; case TYPE_MAT4: ok=(ident=="x" || ident=="y" || ident=="z" || ident=="w"); member_type=TYPE_VEC4; break; default: {} @@ -2059,7 +2079,9 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex at+=get_datatype_name(compute_node_type(op->arguments[i])); } - parser.set_error("Invalid arguments to operator "+String(token_names[op->op])+": "+at); + static const char *op_names[OP_MAX]={"=","+","-","*","/","+=","-=","*=","/=","-","!","==","!=","<=",">=","<",">","||","&&","call","()"}; + + parser.set_error("Invalid arguments to operator "+String(op_names[op->op])+": "+at); return ERR_PARSE_ERROR; } expression.remove(next_op); @@ -2236,6 +2258,7 @@ Error ShaderLanguage::parse_variable_declaration(Parser& parser,BlockNode *p_blo case TYPE_VEC2: con->value=Vector2(); break; case TYPE_VEC3: con->value=Vector3(); break; case TYPE_VEC4: con->value=iscolor?Variant(Color()):Variant(Plane()); break; + case TYPE_MAT2: con->value=Matrix32(); break; case TYPE_MAT3: con->value=Matrix3(); break; case TYPE_MAT4: con->value=Transform(); break; case TYPE_TEXTURE: @@ -2618,12 +2641,20 @@ void ShaderLanguage::get_keyword_list(ShaderType p_type, List<String> *p_keyword int idx=0; + p_keywords->push_back("uniform"); + p_keywords->push_back("texture"); + p_keywords->push_back("cubemap"); + p_keywords->push_back("color"); + p_keywords->push_back("if"); + p_keywords->push_back("else"); + while(intrinsic_func_defs[idx].name) { p_keywords->push_back(intrinsic_func_defs[idx].name); idx++; } + switch(p_type) { case SHADER_MATERIAL_VERTEX: { idx=0; diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h index f79c219d85..7777c8bcf3 100644 --- a/servers/visual/shader_language.h +++ b/servers/visual/shader_language.h @@ -56,6 +56,7 @@ public: TK_TYPE_VEC2, TK_TYPE_VEC3, TK_TYPE_VEC4, + TK_TYPE_MAT2, TK_TYPE_MAT3, TK_TYPE_MAT4, TK_TYPE_TEXTURE, @@ -118,6 +119,7 @@ public: TYPE_VEC2, TYPE_VEC3, TYPE_VEC4, + TYPE_MAT2, TYPE_MAT3, TYPE_MAT4, TYPE_TEXTURE, diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index cef6fe567d..83bfbbc6c3 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -1576,6 +1576,15 @@ void VisualServerRaster::viewport_set_render_target_vflip(RID p_viewport,bool p_ } +void VisualServerRaster::viewport_set_render_target_clear_on_new_frame(RID p_viewport,bool p_enable) { + + Viewport *viewport = viewport_owner.get( p_viewport ); + ERR_FAIL_COND(!viewport); + + viewport->render_target_clear_on_new_frame=p_enable; + +} + void VisualServerRaster::viewport_set_render_target_to_screen_rect(RID p_viewport,const Rect2& p_rect) { Viewport *viewport = viewport_owner.get( p_viewport ); @@ -1594,6 +1603,23 @@ bool VisualServerRaster::viewport_get_render_target_vflip(RID p_viewport) const{ } +bool VisualServerRaster::viewport_get_render_target_clear_on_new_frame(RID p_viewport) const{ + + const Viewport *viewport = viewport_owner.get( p_viewport ); + ERR_FAIL_COND_V(!viewport,false); + + return viewport->render_target_clear_on_new_frame; + +} + +void VisualServerRaster::viewport_render_target_clear(RID p_viewport) { + + Viewport *viewport = viewport_owner.get( p_viewport ); + ERR_FAIL_COND(!viewport); + + viewport->render_target_clear=true; + +} void VisualServerRaster::viewport_queue_screen_capture(RID p_viewport) { @@ -1667,6 +1693,17 @@ void VisualServerRaster::viewport_set_hide_canvas(RID p_viewport,bool p_hide) { } +void VisualServerRaster::viewport_set_disable_environment(RID p_viewport,bool p_disable) { + + VS_CHANGED; + + Viewport *viewport=NULL; + viewport = viewport_owner.get( p_viewport ); + ERR_FAIL_COND(!viewport); + viewport->disable_environment=p_disable; + +} + void VisualServerRaster::viewport_attach_camera(RID p_viewport,RID p_camera) { VS_CHANGED; @@ -3374,6 +3411,14 @@ void VisualServerRaster::canvas_item_set_clip(RID p_item, bool p_clip) { canvas_item->clip=p_clip; } +void VisualServerRaster::canvas_item_set_distance_field_mode(RID p_item, bool p_distance_field) { + VS_CHANGED; + CanvasItem *canvas_item = canvas_item_owner.get( p_item ); + ERR_FAIL_COND(!canvas_item); + + canvas_item->distance_field=p_distance_field; +} + void VisualServerRaster::canvas_item_set_transform(RID p_item, const Matrix32& p_transform) { @@ -3492,7 +3537,7 @@ void VisualServerRaster::canvas_item_add_circle(RID p_item, const Point2& p_pos, } -void VisualServerRaster::canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile,const Color& p_modulate) { +void VisualServerRaster::canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile,const Color& p_modulate,bool p_transpose) { VS_CHANGED; CanvasItem *canvas_item = canvas_item_owner.get( p_item ); ERR_FAIL_COND(!canvas_item); @@ -3515,12 +3560,16 @@ void VisualServerRaster::canvas_item_add_texture_rect(RID p_item, const Rect2& p rect->flags|=Rasterizer::CANVAS_RECT_FLIP_V; rect->rect.size.y = -rect->rect.size.y; } + if (p_transpose) { + rect->flags|=Rasterizer::CANVAS_RECT_TRANSPOSE; + SWAP(rect->rect.size.x, rect->rect.size.y); + } rect->texture=p_texture; canvas_item->rect_dirty=true; canvas_item->commands.push_back(rect); } -void VisualServerRaster::canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate) { +void VisualServerRaster::canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate,bool p_transpose) { VS_CHANGED; CanvasItem *canvas_item = canvas_item_owner.get( p_item ); ERR_FAIL_COND(!canvas_item); @@ -3543,12 +3592,17 @@ void VisualServerRaster::canvas_item_add_texture_rect_region(RID p_item, const R rect->flags|=Rasterizer::CANVAS_RECT_FLIP_V; rect->rect.size.y = -rect->rect.size.y; } + if (p_transpose) { + rect->flags|=Rasterizer::CANVAS_RECT_TRANSPOSE; + SWAP(rect->rect.size.x, rect->rect.size.y); + } canvas_item->rect_dirty=true; canvas_item->commands.push_back(rect); } + void VisualServerRaster::canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center,const Color& p_modulate) { VS_CHANGED; @@ -3730,55 +3784,53 @@ void VisualServerRaster::canvas_item_set_z_as_relative_to_parent(RID p_item, boo } -void VisualServerRaster::canvas_item_set_use_parent_shader(RID p_item, bool p_enable) { +void VisualServerRaster::canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable, const Rect2& p_rect) { VS_CHANGED; CanvasItem *canvas_item = canvas_item_owner.get( p_item ); ERR_FAIL_COND(!canvas_item); - canvas_item->use_parent_shader=p_enable; + if (bool(canvas_item->copy_back_buffer!=NULL) !=p_enable) { + if (p_enable) { + canvas_item->copy_back_buffer = memnew( Rasterizer::CanvasItem::CopyBackBuffer ); + } else { + memdelete(canvas_item->copy_back_buffer); + canvas_item->copy_back_buffer=NULL; + } + } + + if (p_enable) { + canvas_item->copy_back_buffer->rect=p_rect; + canvas_item->copy_back_buffer->full=p_rect==Rect2(); + } } -void VisualServerRaster::canvas_item_set_shader(RID p_item, RID p_shader) { +void VisualServerRaster::canvas_item_set_use_parent_material(RID p_item, bool p_enable) { VS_CHANGED; CanvasItem *canvas_item = canvas_item_owner.get( p_item ); ERR_FAIL_COND(!canvas_item); - canvas_item->shader=p_shader; -} - -RID VisualServerRaster::canvas_item_get_shader(RID p_item) const{ - - CanvasItem *canvas_item = canvas_item_owner.get( p_item ); - ERR_FAIL_COND_V(!canvas_item,RID()); - return canvas_item->shader; + canvas_item->use_parent_material=p_enable; } -void VisualServerRaster::canvas_item_set_shader_param(RID p_canvas_item, const StringName& p_param, const Variant& p_value){ +void VisualServerRaster::canvas_item_set_material(RID p_item, RID p_material) { VS_CHANGED; - CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item ); + CanvasItem *canvas_item = canvas_item_owner.get( p_item ); ERR_FAIL_COND(!canvas_item); - if (p_value.get_type()==Variant::NIL) - canvas_item->shader_param.erase(p_param); - else - canvas_item->shader_param[p_param]=p_value; -} -Variant VisualServerRaster::canvas_item_get_shader_param(RID p_canvas_item, const StringName& p_param) const{ + if (canvas_item->material) + canvas_item->material->owners.erase(canvas_item); - CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item ); - ERR_FAIL_COND_V(!canvas_item,Variant()); - if (!canvas_item->shader_param.has(p_param)) { - ERR_FAIL_COND_V(!canvas_item->shader.is_valid(),Variant()); - return rasterizer->shader_get_default_param(canvas_item->shader,p_param); - } + canvas_item->material=NULL; - return canvas_item->shader_param[p_param]; + if (canvas_item_material_owner.owns(p_material)) { + canvas_item->material=canvas_item_material_owner.get(p_material); + canvas_item->material->owners.insert(canvas_item); + } } - void VisualServerRaster::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) { VS_CHANGED; @@ -3887,6 +3939,15 @@ void VisualServerRaster::canvas_light_set_transform(RID p_light, const Matrix32& clight->xform=p_transform; } +void VisualServerRaster::canvas_light_set_scale(RID p_light, float p_scale) { + + Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); + ERR_FAIL_COND(!clight); + clight->scale=p_scale; + +} + + void VisualServerRaster::canvas_light_set_texture(RID p_light, RID p_texture){ Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); @@ -3942,6 +4003,15 @@ void VisualServerRaster::canvas_light_set_item_mask(RID p_light, int p_mask){ } +void VisualServerRaster::canvas_light_set_item_shadow_mask(RID p_light, int p_mask){ + + Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); + ERR_FAIL_COND(!clight); + clight->item_shadow_mask=p_mask; + +} + + void VisualServerRaster::canvas_light_set_subtract_mode(RID p_light, bool p_enable) { @@ -3954,19 +4024,41 @@ void VisualServerRaster::canvas_light_set_shadow_enabled(RID p_light, bool p_ena Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); ERR_FAIL_COND(!clight); - clight->shadow=p_enabled; + + if (clight->shadow_buffer.is_valid()==p_enabled) + return; + if (p_enabled) { + clight->shadow_buffer=rasterizer->canvas_light_shadow_buffer_create(clight->shadow_buffer_size); + } else { + rasterizer->free(clight->shadow_buffer); + clight->shadow_buffer=RID(); + + } } + void VisualServerRaster::canvas_light_set_shadow_buffer_size(RID p_light, int p_size){ Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); ERR_FAIL_COND(!clight); + ERR_FAIL_COND(p_size<32 || p_size>16384); + + clight->shadow_buffer_size=nearest_power_of_2(p_size); + + + if (clight->shadow_buffer.is_valid()) { + rasterizer->free(clight->shadow_buffer); + clight->shadow_buffer=rasterizer->canvas_light_shadow_buffer_create(clight->shadow_buffer_size); + } + } -void VisualServerRaster::canvas_light_set_shadow_filter(RID p_light, int p_size){ + +void VisualServerRaster::canvas_light_set_shadow_esm_multiplier(RID p_light, float p_multiplier) { Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light); ERR_FAIL_COND(!clight); + clight->shadow_esm_mult=p_multiplier; } @@ -3974,26 +4066,217 @@ void VisualServerRaster::canvas_light_set_shadow_filter(RID p_light, int p_size) RID VisualServerRaster::canvas_light_occluder_create() { - return RID(); + Rasterizer::CanvasLightOccluderInstance *occluder = memnew( Rasterizer::CanvasLightOccluderInstance ); + + return canvas_light_occluder_owner.make_rid( occluder ); + } void VisualServerRaster::canvas_light_occluder_attach_to_canvas(RID p_occluder,RID p_canvas) { + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder); + ERR_FAIL_COND(!occluder); + + if (occluder->canvas.is_valid()) { + + Canvas *canvas = canvas_owner.get(occluder->canvas); + canvas->occluders.erase(occluder); + } + + if (!canvas_owner.owns(p_canvas)) + p_canvas=RID(); + + occluder->canvas=p_canvas; + + if (occluder->canvas.is_valid()) { + Canvas *canvas = canvas_owner.get(occluder->canvas); + canvas->occluders.insert(occluder); + } } void VisualServerRaster::canvas_light_occluder_set_enabled(RID p_occluder,bool p_enabled){ + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder); + ERR_FAIL_COND(!occluder); + + occluder->enabled=p_enabled; } -void VisualServerRaster::canvas_light_occluder_set_shape(RID p_occluder,const DVector<Vector2>& p_shape){ +void VisualServerRaster::canvas_light_occluder_set_polygon(RID p_occluder,RID p_polygon) { + + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder); + ERR_FAIL_COND(!occluder); + + if (occluder->polygon.is_valid()) { + CanvasLightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(p_polygon); + if (occluder_poly) { + occluder_poly->owners.erase(occluder); + } + } + occluder->polygon=p_polygon; + occluder->polygon_buffer=RID(); + + if (occluder->polygon.is_valid()) { + CanvasLightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(p_polygon); + if (!occluder_poly) + occluder->polygon=RID(); + ERR_FAIL_COND(!occluder_poly); + occluder_poly->owners.insert(occluder); + occluder->polygon_buffer=occluder_poly->occluder; + occluder->aabb_cache=occluder_poly->aabb; + occluder->cull_cache=occluder_poly->cull_mode; + } } + +void VisualServerRaster::canvas_light_occluder_set_transform(RID p_occluder,const Matrix32& p_xform) { + + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder); + ERR_FAIL_COND(!occluder); + + occluder->xform=p_xform; + +} + +void VisualServerRaster::canvas_light_occluder_set_light_mask(RID p_occluder,int p_mask) { + + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder); + ERR_FAIL_COND(!occluder); + + occluder->light_mask=p_mask; + +} + + +RID VisualServerRaster::canvas_occluder_polygon_create() { + + CanvasLightOccluderPolygon * occluder_poly = memnew( CanvasLightOccluderPolygon ); + occluder_poly->occluder=rasterizer->canvas_light_occluder_create(); + return canvas_light_occluder_polygon_owner.make_rid(occluder_poly); + +} + +void VisualServerRaster::canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const DVector<Vector2>& p_shape, bool p_close){ + + if (p_shape.size()<3) { + canvas_occluder_polygon_set_shape_as_lines(p_occluder_polygon,p_shape); + return; + } + + DVector<Vector2> lines; + int lc = p_shape.size()*2; + + lines.resize(lc-(p_close?0:2)); + { + DVector<Vector2>::Write w = lines.write(); + DVector<Vector2>::Read r = p_shape.read(); + + int max=lc/2; + if (!p_close) { + max--; + } + for(int i=0;i<max;i++) { + + Vector2 a = r[i]; + Vector2 b = r[(i+1)%(lc/2)]; + w[i*2+0]=a; + w[i*2+1]=b; + } + + } + + canvas_occluder_polygon_set_shape_as_lines(p_occluder_polygon,lines); +} + +void VisualServerRaster::canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon,const DVector<Vector2>& p_shape) { + + CanvasLightOccluderPolygon * occluder_poly = canvas_light_occluder_polygon_owner.get(p_occluder_polygon); + ERR_FAIL_COND(!occluder_poly); + ERR_FAIL_COND(p_shape.size()&1); + + int lc = p_shape.size(); + occluder_poly->aabb=Rect2(); + { + DVector<Vector2>::Read r = p_shape.read(); + for(int i=0;i<lc;i++) { + if (i==0) + occluder_poly->aabb.pos=r[i]; + else + occluder_poly->aabb.expand_to(r[i]); + } + } + + rasterizer->canvas_light_occluder_set_polylines(occluder_poly->occluder,p_shape); + for( Set<Rasterizer::CanvasLightOccluderInstance*>::Element *E=occluder_poly->owners.front();E;E=E->next()) { + E->get()->aabb_cache=occluder_poly->aabb; + } +} + +void VisualServerRaster::canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon,CanvasOccluderPolygonCullMode p_mode) { + + CanvasLightOccluderPolygon * occluder_poly = canvas_light_occluder_polygon_owner.get(p_occluder_polygon); + ERR_FAIL_COND(!occluder_poly); + occluder_poly->cull_mode=p_mode; + for( Set<Rasterizer::CanvasLightOccluderInstance*>::Element *E=occluder_poly->owners.front();E;E=E->next()) { + E->get()->cull_cache=p_mode; + } + +} + +RID VisualServerRaster::canvas_item_material_create() { + + Rasterizer::CanvasItemMaterial *material = memnew( Rasterizer::CanvasItemMaterial ); + return canvas_item_material_owner.make_rid(material); + +} + +void VisualServerRaster::canvas_item_material_set_shader(RID p_material, RID p_shader){ + + VS_CHANGED; + Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material ); + ERR_FAIL_COND(!material); + material->shader=p_shader; + +} +void VisualServerRaster::canvas_item_material_set_shader_param(RID p_material, const StringName& p_param, const Variant& p_value){ + + VS_CHANGED; + Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material ); + ERR_FAIL_COND(!material); + if (p_value.get_type()==Variant::NIL) + material->shader_param.erase(p_param); + else + material->shader_param[p_param]=p_value; + + +} +Variant VisualServerRaster::canvas_item_material_get_shader_param(RID p_material, const StringName& p_param) const{ + Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material ); + ERR_FAIL_COND_V(!material,Variant()); + if (!material->shader_param.has(p_param)) { + ERR_FAIL_COND_V(!material->shader.is_valid(),Variant()); + return rasterizer->shader_get_default_param(material->shader,p_param); + } + + return material->shader_param[p_param]; +} + +void VisualServerRaster::canvas_item_material_set_unshaded(RID p_material, bool p_unshaded){ + + VS_CHANGED; + Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material ); + ERR_FAIL_COND(!material); + material->unshaded=p_unshaded; + +} + + /******** CANVAS *********/ @@ -4250,6 +4533,10 @@ void VisualServerRaster::free( RID p_rid ) { E->get()->canvas=RID(); } + for (Set<Rasterizer::CanvasLightOccluderInstance*>::Element *E=canvas->occluders.front();E;E=E->next()) { + + E->get()->canvas=RID(); + } canvas_owner.free( p_rid ); @@ -4279,10 +4566,26 @@ void VisualServerRaster::free( RID p_rid ) { canvas_item->child_items[i]->parent=RID(); } + if (canvas_item->material) { + canvas_item->material->owners.erase(canvas_item); + } + canvas_item_owner.free( p_rid ); memdelete( canvas_item ); + } else if (canvas_item_material_owner.owns(p_rid)) { + + Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get(p_rid); + ERR_FAIL_COND(!material); + for(Set<Rasterizer::CanvasItem*>::Element *E=material->owners.front();E;E=E->next()) { + + E->get()->material=NULL; + } + + canvas_item_material_owner.free(p_rid); + memdelete(material); + } else if (canvas_light_owner.owns(p_rid)) { Rasterizer::CanvasLight *canvas_light = canvas_light_owner.get(p_rid); @@ -4294,9 +4597,51 @@ void VisualServerRaster::free( RID p_rid ) { canvas->lights.erase(canvas_light); } + if (canvas_light->shadow_buffer.is_valid()) + rasterizer->free(canvas_light->shadow_buffer); + canvas_light_owner.free( p_rid ); memdelete( canvas_light ); + } else if (canvas_light_occluder_owner.owns(p_rid)) { + + Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_rid); + ERR_FAIL_COND(!occluder); + + if (occluder->polygon.is_valid()) { + + CanvasLightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(occluder->polygon); + if (occluder_poly) { + occluder_poly->owners.erase(occluder); + } + + } + + if (occluder->canvas.is_valid() && canvas_owner.owns(occluder->canvas)) { + + Canvas *canvas = canvas_owner.get(occluder->canvas); + canvas->occluders.erase(occluder); + + } + + canvas_light_occluder_owner.free( p_rid ); + memdelete(occluder); + + } else if (canvas_light_occluder_polygon_owner.owns(p_rid)) { + + CanvasLightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(p_rid); + ERR_FAIL_COND(!occluder_poly); + rasterizer->free(occluder_poly->occluder); + + while(occluder_poly->owners.size()) { + + occluder_poly->owners.front()->get()->polygon=RID(); + occluder_poly->owners.erase( occluder_poly->owners.front() ); + } + + canvas_light_occluder_polygon_owner.free( p_rid ); + memdelete(occluder_poly); + } else if (scenario_owner.owns(p_rid)) { Scenario *scenario=scenario_owner.get(p_rid); @@ -5941,6 +6286,20 @@ void VisualServerRaster::_process_sampled_light(const Transform& p_camera,Instan } +void VisualServerRaster::_render_no_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario) { + RID environment; + if (p_scenario->environment.is_valid()) + environment=p_scenario->environment; + else + environment=p_scenario->fallback_environment; + + rasterizer->set_camera(Transform(),CameraMatrix()); + rasterizer->begin_scene(p_viewport->viewport_data,environment,p_scenario->debug); + rasterizer->set_viewport(viewport_rect); + rasterizer->end_scene(); +} + + void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario) { @@ -6375,7 +6734,7 @@ void VisualServerRaster::_render_canvas_item_viewport(VisualServer* p_self,void } -void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,int p_z,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_shader_owner) { +void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,int p_z,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_material_owner) { CanvasItem *ci = p_canvas_item; @@ -6420,11 +6779,11 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat ci->vp_render=NULL; } - if (ci->use_parent_shader && p_shader_owner) - ci->shader_owner=p_shader_owner; + if (ci->use_parent_material && p_material_owner) + ci->material_owner=p_material_owner; else { - p_shader_owner=ci; - ci->shader_owner=NULL; + p_material_owner=ci; + ci->material_owner=NULL; } @@ -6458,11 +6817,15 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat if (child_items[i]->ontop) continue; - _render_canvas_item(child_items[i],xform,p_clip_rect,opacity,p_z,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_shader_owner); + _render_canvas_item(child_items[i],xform,p_clip_rect,opacity,p_z,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_material_owner); } + if (ci->copy_back_buffer) { + + ci->copy_back_buffer->screen_rect = xform.xform(ci->copy_back_buffer->rect).clip(p_clip_rect); + } - if ((!ci->commands.empty() && p_clip_rect.intersects(global_rect)) || ci->vp_render) { + if ((!ci->commands.empty() && p_clip_rect.intersects(global_rect)) || ci->vp_render || ci->copy_back_buffer) { //something to draw? ci->final_transform=xform; ci->final_opacity=opacity * ci->self_opacity; @@ -6489,7 +6852,7 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat if (!child_items[i]->ontop) continue; - _render_canvas_item(child_items[i],xform,p_clip_rect,opacity,p_z,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_shader_owner); + _render_canvas_item(child_items[i],xform,p_clip_rect,opacity,p_z,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_material_owner); } } @@ -6559,6 +6922,23 @@ void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_trans } +void VisualServerRaster::_draw_viewport_camera(Viewport *p_viewport,bool p_ignore_camera) { + + + Camera *camera=NULL; + if (camera_owner.owns( p_viewport->camera )) + camera=camera_owner.get( p_viewport->camera ); + Scenario *scenario = scenario_owner.get( p_viewport->scenario ); + + _update_instances(); // check dirty instances before rendering + + if (p_ignore_camera) + _render_no_camera(p_viewport, camera,scenario ); + else + _render_camera(p_viewport, camera,scenario ); + +} + void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ofs_y,int p_parent_w,int p_parent_h) { ViewportRect desired_rect=p_viewport->rect; @@ -6593,19 +6973,47 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ /* Camera should always be BEFORE any other 3D */ - if (!p_viewport->hide_scenario && camera_owner.owns(p_viewport->camera) && scenario_owner.owns(p_viewport->scenario)) { + bool scenario_draw_canvas_bg=false; + int scenario_canvas_max_layer=0; - Camera *camera = camera_owner.get( p_viewport->camera ); - Scenario *scenario = scenario_owner.get( p_viewport->scenario ); + if (!p_viewport->hide_canvas && !p_viewport->disable_environment && scenario_owner.owns(p_viewport->scenario)) { - _update_instances(); // check dirty instances before rendering + Scenario *scenario=scenario_owner.get(p_viewport->scenario); + if (scenario->environment.is_valid()) { + if (rasterizer->is_environment(scenario->environment)) { + scenario_draw_canvas_bg=rasterizer->environment_get_background(scenario->environment)==VS::ENV_BG_CANVAS; + scenario_canvas_max_layer=rasterizer->environment_get_background_param(scenario->environment,VS::ENV_BG_PARAM_CANVAS_MAX_LAYER); + } + } + } + + bool can_draw_3d=!p_viewport->hide_scenario && camera_owner.owns(p_viewport->camera) && scenario_owner.owns(p_viewport->scenario); - _render_camera(p_viewport, camera,scenario ); + + if (scenario_draw_canvas_bg) { + + rasterizer->begin_canvas_bg(); + } + + if (!scenario_draw_canvas_bg && can_draw_3d) { + + _draw_viewport_camera(p_viewport,false); } else if (true /*|| !p_viewport->canvas_list.empty()*/){ //clear the viewport black because of no camera? i seriously should.. - rasterizer->clear_viewport(clear_color); + if (p_viewport->render_target_clear_on_new_frame || p_viewport->render_target_clear) { + if (p_viewport->transparent_bg) { + rasterizer->clear_viewport(Color(0,0,0,0)); + } + else { + Color cc=clear_color; + if (scenario_draw_canvas_bg) + cc.a=0; + rasterizer->clear_viewport(cc); + } + p_viewport->render_target_clear=false; + } } if (!p_viewport->hide_canvas) { @@ -6615,6 +7023,10 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ Rect2 clip_rect(0,0,viewport_rect.width,viewport_rect.height); Rasterizer::CanvasLight *lights=NULL; + Rasterizer::CanvasLight *lights_with_shadow=NULL; + Rect2 shadow_rect; + + int light_count=0; for (Map<RID,Viewport::CanvasData>::Element *E=p_viewport->canvas_map.front();E;E=E->next()) { @@ -6629,10 +7041,12 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ if (cl->enabled && cl->texture.is_valid()) { //not super efficient.. Size2 tsize(rasterizer->texture_get_width(cl->texture),rasterizer->texture_get_height(cl->texture)); + tsize*=cl->scale; Vector2 offset=tsize/2.0; cl->rect_cache=Rect2(-offset+cl->texture_offset,tsize); cl->xform_cache=xf * cl->xform; + if (clip_rect.intersects_transformed(cl->xform_cache,cl->rect_cache)) { cl->filter_next_ptr=lights; lights=cl; @@ -6642,15 +7056,67 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ scale.elements[2]=cl->rect_cache.pos; cl->light_shader_xform = (cl->xform_cache * scale).affine_inverse(); cl->light_shader_pos=cl->xform_cache[2]; + if (cl->shadow_buffer.is_valid()) { + cl->shadows_next_ptr=lights_with_shadow; + if (lights_with_shadow==NULL) { + shadow_rect = cl->xform_cache.xform(cl->rect_cache); + } else { + shadow_rect=shadow_rect.merge( cl->xform_cache.xform(cl->rect_cache) ); + } + lights_with_shadow=cl; + cl->radius_cache=cl->rect_cache.size.length(); + + } + + light_count++; } + } + } + //print_line("lights: "+itos(light_count)); + canvas_map[ Viewport::CanvasKey( E->key(), E->get().layer) ]=&E->get(); + } + + if (lights_with_shadow) { + //update shadows if any + + Rasterizer::CanvasLightOccluderInstance * occluders=NULL; + + //make list of occluders + for (Map<RID,Viewport::CanvasData>::Element *E=p_viewport->canvas_map.front();E;E=E->next()) { + Matrix32 xf = p_viewport->global_transform * E->get().transform; + for(Set<Rasterizer::CanvasLightOccluderInstance*>::Element *F=E->get().canvas->occluders.front();F;F=F->next()) { + + F->get()->xform_cache = xf * F->get()->xform; + if (shadow_rect.intersects_transformed(F->get()->xform_cache,F->get()->aabb_cache)) { + + F->get()->next=occluders; + occluders=F->get(); + + } } } + //update the light shadowmaps with them + Rasterizer::CanvasLight *light=lights_with_shadow; + while(light) { - canvas_map[ Viewport::CanvasKey( E->key(), E->get().layer) ]=&E->get(); + rasterizer->canvas_light_shadow_buffer_update(light->shadow_buffer,light->xform_cache.affine_inverse(),light->item_mask,light->radius_cache/1000.0,light->radius_cache*1.1,occluders,&light->shadow_matrix_cache); + light=light->shadows_next_ptr; + } + + rasterizer->set_viewport(viewport_rect); //must reset viewport afterwards + } + + + + + if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().layer>scenario_canvas_max_layer) { + + _draw_viewport_camera(p_viewport,!can_draw_3d); + scenario_draw_canvas_bg=false; } @@ -6675,7 +7141,21 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ _render_canvas( E->get()->canvas,xform,canvas_lights ); i++; + if (scenario_draw_canvas_bg && E->key().layer>=scenario_canvas_max_layer) { + _draw_viewport_camera(p_viewport,!can_draw_3d); + scenario_draw_canvas_bg=false; + } + + } + + if (scenario_draw_canvas_bg) { + _draw_viewport_camera(p_viewport,!can_draw_3d); + scenario_draw_canvas_bg=false; + } + + + //rasterizer->canvas_debug_viewport_shadows(lights_with_shadow); } //capture diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index eec677068e..72af793278 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -371,7 +371,7 @@ class VisualServerRaster : public VisualServer { - + mutable RID_Owner<Rasterizer::CanvasItemMaterial> canvas_item_material_owner; struct CanvasItem : public Rasterizer::CanvasItem { @@ -384,7 +384,7 @@ class VisualServerRaster : public VisualServer { bool sort_y; float opacity; float self_opacity; - bool use_parent_shader; + bool use_parent_material; Vector<CanvasItem*> child_items; @@ -396,7 +396,7 @@ class VisualServerRaster : public VisualServer { opacity=1; self_opacity=1; sort_y=false; - use_parent_shader=false; + use_parent_material=false; z_relative=true; } }; @@ -410,6 +410,24 @@ class VisualServerRaster : public VisualServer { } }; + struct CanvasLightOccluder; + + struct CanvasLightOccluderPolygon { + + bool active; + Rect2 aabb; + CanvasOccluderPolygonCullMode cull_mode; + RID occluder; + Set<Rasterizer::CanvasLightOccluderInstance*> owners; + + CanvasLightOccluderPolygon() { active=false; cull_mode=CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; } + }; + + + RID_Owner<CanvasLightOccluderPolygon> canvas_light_occluder_polygon_owner; + + RID_Owner<Rasterizer::CanvasLightOccluderInstance> canvas_light_occluder_owner; + struct CanvasLight; struct Canvas { @@ -422,6 +440,7 @@ class VisualServerRaster : public VisualServer { }; Set<Rasterizer::CanvasLight*> lights; + Set<Rasterizer::CanvasLightOccluderInstance*> occluders; Vector<ChildItem> child_items; Color modulate; @@ -468,6 +487,10 @@ class VisualServerRaster : public VisualServer { bool transparent_bg; bool queue_capture; bool render_target_vflip; + bool render_target_clear_on_new_frame; + bool render_target_clear; + bool disable_environment; + Image capture; bool rendered_in_prev_frame; @@ -494,7 +517,7 @@ class VisualServerRaster : public VisualServer { SelfList<Viewport> update_list; - Viewport() : update_list(this) { transparent_bg=false; render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE; queue_capture=false; rendered_in_prev_frame=false; render_target_vflip=false;} + Viewport() : update_list(this) { transparent_bg=false; render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE; queue_capture=false; rendered_in_prev_frame=false; render_target_vflip=false; render_target_clear_on_new_frame=true; render_target_clear=true; disable_environment=false; } }; SelfList<Viewport>::List viewport_update_list; @@ -605,10 +628,11 @@ class VisualServerRaster : public VisualServer { void _cull_room(Camera *p_camera, Instance *p_room,Instance *p_from_portal=NULL); void _process_sampled_light(const Transform &p_camera, Instance *p_sampled_light, bool p_linear_colorspace); + void _render_no_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario); void _render_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario); static void _render_canvas_item_viewport(VisualServer* p_self,void *p_vp,const Rect2& p_rect); void _render_canvas_item_tree(CanvasItem *p_canvas_item, const Matrix32& p_transform, const Rect2& p_clip_rect, const Color &p_modulate, Rasterizer::CanvasLight *p_lights); - void _render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,int p_z,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_shader_owner); + void _render_canvas_item(CanvasItem *p_canvas_item, const Matrix32& p_transform, const Rect2& p_clip_rect, float p_opacity, int p_z, Rasterizer::CanvasItem **z_list, Rasterizer::CanvasItem **z_last_list, CanvasItem *p_canvas_clip, CanvasItem *p_material_owner); void _render_canvas(Canvas *p_canvas, const Matrix32 &p_transform, Rasterizer::CanvasLight *p_lights); Vector<Vector3> _camera_generate_endpoints(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max); Vector<Plane> _camera_generate_orthogonal_planes(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max); @@ -622,6 +646,7 @@ class VisualServerRaster : public VisualServer { int changes; bool draw_extra_frame; + void _draw_viewport_camera(Viewport *p_viewport, bool p_ignore_camera); void _draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_ofs_y,int p_parent_w,int p_parent_h); void _draw_viewports(); void _draw_cursors_and_margins(); @@ -957,8 +982,12 @@ public: virtual RID viewport_get_render_target_texture(RID p_viewport) const; virtual void viewport_set_render_target_vflip(RID p_viewport,bool p_enable); virtual bool viewport_get_render_target_vflip(RID p_viewport) const; + virtual void viewport_set_render_target_clear_on_new_frame(RID p_viewport,bool p_enable); + virtual bool viewport_get_render_target_clear_on_new_frame(RID p_viewport) const; + virtual void viewport_render_target_clear(RID p_viewport); virtual void viewport_set_render_target_to_screen_rect(RID p_viewport,const Rect2& p_rect); + virtual void viewport_queue_screen_capture(RID p_viewport); virtual Image viewport_get_screen_capture(RID p_viewport) const; @@ -967,6 +996,7 @@ public: virtual void viewport_set_hide_scenario(RID p_viewport,bool p_hide); virtual void viewport_set_hide_canvas(RID p_viewport,bool p_hide); + virtual void viewport_set_disable_environment(RID p_viewport,bool p_disable); virtual void viewport_attach_camera(RID p_viewport,RID p_camera); virtual void viewport_set_scenario(RID p_viewport,RID p_scenario); @@ -1098,6 +1128,7 @@ public: //virtual void canvas_item_set_rect(RID p_item, const Rect2& p_rect); virtual void canvas_item_set_transform(RID p_item, const Matrix32& p_transform); virtual void canvas_item_set_clip(RID p_item, bool p_clip); + virtual void canvas_item_set_distance_field_mode(RID p_item, bool p_enable); virtual void canvas_item_set_custom_rect(RID p_item, bool p_custom_rect,const Rect2& p_rect=Rect2()); virtual void canvas_item_set_opacity(RID p_item, float p_opacity); virtual float canvas_item_get_opacity(RID p_item, float p_opacity) const; @@ -1112,8 +1143,8 @@ public: virtual void canvas_item_add_line(RID p_item, const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width=1.0); virtual void canvas_item_add_rect(RID p_item, const Rect2& p_rect, const Color& p_color); virtual void canvas_item_add_circle(RID p_item, const Point2& p_pos, float p_radius,const Color& p_color); - virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1)); - virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1)); + virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1),bool p_transpose=false); + virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1),bool p_transpose=false); virtual void canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1)); virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width=1.0); virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs=Vector<Point2>(), RID p_texture=RID()); @@ -1125,21 +1156,16 @@ public: virtual void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable); virtual void canvas_item_set_z(RID p_item, int p_z); virtual void canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable); + virtual void canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable,const Rect2& p_rect); - virtual void canvas_item_set_shader(RID p_item, RID p_shader); - virtual RID canvas_item_get_shader(RID p_item) const; - - virtual void canvas_item_set_use_parent_shader(RID p_item, bool p_enable); - - - - virtual void canvas_item_set_shader_param(RID p_canvas_item, const StringName& p_param, const Variant& p_value); - virtual Variant canvas_item_get_shader_param(RID p_canvas_item, const StringName& p_param) const; + virtual void canvas_item_set_material(RID p_item, RID p_material); + virtual void canvas_item_set_use_parent_material(RID p_item, bool p_enable); virtual RID canvas_light_create(); virtual void canvas_light_attach_to_canvas(RID p_light,RID p_canvas); virtual void canvas_light_set_enabled(RID p_light, bool p_enabled); virtual void canvas_light_set_transform(RID p_light, const Matrix32& p_transform); + virtual void canvas_light_set_scale(RID p_light, float p_scale); virtual void canvas_light_set_texture(RID p_light, RID p_texture); virtual void canvas_light_set_texture_offset(RID p_light, const Vector2& p_offset); virtual void canvas_light_set_color(RID p_light, const Color& p_color); @@ -1147,21 +1173,41 @@ public: virtual void canvas_light_set_z_range(RID p_light, int p_min_z,int p_max_z); virtual void canvas_light_set_layer_range(RID p_light, int p_min_layer,int p_max_layer); virtual void canvas_light_set_item_mask(RID p_light, int p_mask); + virtual void canvas_light_set_item_shadow_mask(RID p_light, int p_mask); virtual void canvas_light_set_subtract_mode(RID p_light, bool p_enable); virtual void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled); virtual void canvas_light_set_shadow_buffer_size(RID p_light, int p_size); - virtual void canvas_light_set_shadow_filter(RID p_light, int p_size); + virtual void canvas_light_set_shadow_esm_multiplier(RID p_light, float p_multiplier); virtual RID canvas_light_occluder_create(); virtual void canvas_light_occluder_attach_to_canvas(RID p_occluder,RID p_canvas); virtual void canvas_light_occluder_set_enabled(RID p_occluder,bool p_enabled); - virtual void canvas_light_occluder_set_shape(RID p_occluder,const DVector<Vector2>& p_shape); + virtual void canvas_light_occluder_set_polygon(RID p_occluder,RID p_polygon); + virtual void canvas_light_occluder_set_transform(RID p_occluder,const Matrix32& p_xform); + virtual void canvas_light_occluder_set_light_mask(RID p_occluder,int p_mask); + + + virtual RID canvas_occluder_polygon_create(); + virtual void canvas_occluder_polygon_set_shape(RID p_occluder_polygon,const DVector<Vector2>& p_shape,bool p_close); + virtual void canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon,const DVector<Vector2>& p_shape); + virtual void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon,CanvasOccluderPolygonCullMode p_mode); + + virtual void canvas_item_clear(RID p_item); virtual void canvas_item_raise(RID p_item); + /* CANVAS ITEM MATERIAL */ + + virtual RID canvas_item_material_create(); + virtual void canvas_item_material_set_shader(RID p_material, RID p_shader); + virtual void canvas_item_material_set_shader_param(RID p_material, const StringName& p_param, const Variant& p_value); + virtual Variant canvas_item_material_get_shader_param(RID p_material, const StringName& p_param) const; + virtual void canvas_item_material_set_unshaded(RID p_material, bool p_unshaded); + + /* CURSOR */ virtual void cursor_set_rotation(float p_rotation, int p_cursor = 0); // radians virtual void cursor_set_texture(RID p_texture, const Point2 &p_center_offset, int p_cursor=0); diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index c94425c586..ded4c6fc00 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -967,6 +967,10 @@ public: FUNC2(viewport_set_render_target_vflip,RID,bool); FUNC1RC(bool,viewport_get_render_target_vflip,RID); FUNC2(viewport_set_render_target_to_screen_rect,RID,const Rect2&); + + FUNC2(viewport_set_render_target_clear_on_new_frame,RID,bool); + FUNC1RC(bool,viewport_get_render_target_clear_on_new_frame,RID); + FUNC1(viewport_render_target_clear,RID); FUNC1(viewport_queue_screen_capture,RID); FUNC1RC(Image,viewport_get_screen_capture,RID); @@ -978,6 +982,7 @@ public: FUNC2(viewport_set_hide_canvas,RID,bool ); FUNC2(viewport_attach_camera,RID,RID ); FUNC2(viewport_set_scenario,RID,RID ); + FUNC2(viewport_set_disable_environment,RID,bool ); FUNC1RC(RID,viewport_get_attached_camera,RID); FUNC1RC(RID,viewport_get_scenario,RID ); @@ -1104,6 +1109,7 @@ public: //FUNC(canvas_item_set_rect,RID, const Rect2& p_rect); FUNC2(canvas_item_set_transform,RID, const Matrix32& ); FUNC2(canvas_item_set_clip,RID, bool ); + FUNC2(canvas_item_set_distance_field_mode,RID, bool ); FUNC3(canvas_item_set_custom_rect,RID, bool ,const Rect2&); FUNC2(canvas_item_set_opacity,RID, float ); FUNC2RC(float,canvas_item_get_opacity,RID, float ); @@ -1118,9 +1124,8 @@ public: FUNC5(canvas_item_add_line,RID, const Point2& , const Point2& ,const Color& ,float ); FUNC3(canvas_item_add_rect,RID, const Rect2& , const Color& ); FUNC4(canvas_item_add_circle,RID, const Point2& , float ,const Color& ); - FUNC5(canvas_item_add_texture_rect,RID, const Rect2& , RID ,bool ,const Color& ); - FUNC5(canvas_item_add_texture_rect_region,RID, const Rect2& , RID ,const Rect2& ,const Color& ); - + FUNC6(canvas_item_add_texture_rect,RID, const Rect2& , RID ,bool ,const Color&,bool ); + FUNC6(canvas_item_add_texture_rect_region,RID, const Rect2& , RID ,const Rect2& ,const Color&,bool ); FUNC7(canvas_item_add_style_box,RID, const Rect2& , RID ,const Vector2& ,const Vector2&, bool ,const Color& ); FUNC6(canvas_item_add_primitive,RID, const Vector<Point2>& , const Vector<Color>& ,const Vector<Point2>& , RID ,float ); FUNC5(canvas_item_add_polygon,RID, const Vector<Point2>& , const Vector<Color>& ,const Vector<Point2>& , RID ); @@ -1135,15 +1140,12 @@ public: FUNC2(canvas_item_set_sort_children_by_y,RID,bool); FUNC2(canvas_item_set_z,RID,int); FUNC2(canvas_item_set_z_as_relative_to_parent,RID,bool); + FUNC3(canvas_item_set_copy_to_backbuffer,RID,bool,const Rect2&); - FUNC2(canvas_item_set_shader,RID, RID ); - FUNC1RC(RID,canvas_item_get_shader,RID ); - FUNC2(canvas_item_set_use_parent_shader,RID, bool ); + FUNC2(canvas_item_set_material,RID, RID ); - - FUNC3(canvas_item_set_shader_param,RID,const StringName&,const Variant&); - FUNC2RC(Variant,canvas_item_get_shader_param,RID,const StringName&); + FUNC2(canvas_item_set_use_parent_material,RID, bool ); FUNC1(canvas_item_clear,RID); FUNC1(canvas_item_raise,RID); @@ -1153,6 +1155,7 @@ public: FUNC2(canvas_light_attach_to_canvas,RID,RID); FUNC2(canvas_light_set_enabled,RID,bool); FUNC2(canvas_light_set_transform,RID,const Matrix32&); + FUNC2(canvas_light_set_scale,RID,float); FUNC2(canvas_light_set_texture,RID,RID); FUNC2(canvas_light_set_texture_offset,RID,const Vector2&); FUNC2(canvas_light_set_color,RID,const Color&); @@ -1160,18 +1163,36 @@ public: FUNC3(canvas_light_set_layer_range,RID,int,int); FUNC3(canvas_light_set_z_range,RID,int,int); FUNC2(canvas_light_set_item_mask,RID,int); + FUNC2(canvas_light_set_item_shadow_mask,RID,int); FUNC2(canvas_light_set_subtract_mode,RID,bool); FUNC2(canvas_light_set_shadow_enabled,RID,bool); FUNC2(canvas_light_set_shadow_buffer_size,RID,int); - FUNC2(canvas_light_set_shadow_filter,RID,int); + FUNC2(canvas_light_set_shadow_esm_multiplier,RID,float); + /* CANVAS OCCLUDER */ FUNC0R(RID,canvas_light_occluder_create); FUNC2(canvas_light_occluder_attach_to_canvas,RID,RID); FUNC2(canvas_light_occluder_set_enabled,RID,bool); - FUNC2(canvas_light_occluder_set_shape,RID,const DVector<Vector2>&); + FUNC2(canvas_light_occluder_set_polygon,RID,RID); + FUNC2(canvas_light_occluder_set_transform,RID,const Matrix32&); + FUNC2(canvas_light_occluder_set_light_mask,RID,int); + + + FUNC0R(RID,canvas_occluder_polygon_create); + FUNC3(canvas_occluder_polygon_set_shape,RID,const DVector<Vector2>&,bool); + FUNC2(canvas_occluder_polygon_set_shape_as_lines,RID,const DVector<Vector2>&); + FUNC2(canvas_occluder_polygon_set_cull_mode,RID,CanvasOccluderPolygonCullMode); + + /* CANVAS MATERIAL */ + + FUNC0R(RID,canvas_item_material_create); + FUNC2(canvas_item_material_set_shader,RID,RID); + FUNC3(canvas_item_material_set_shader_param,RID,const StringName&,const Variant&); + FUNC2RC(Variant,canvas_item_material_get_shader_param,RID,const StringName&); + FUNC2(canvas_item_material_set_unshaded,RID,bool); /* CURSOR */ FUNC2(cursor_set_rotation,float , int ); // radians diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index e0238c8042..5ddfaf7967 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -28,6 +28,7 @@ /*************************************************************************/ #include "visual_server.h" #include "globals.h" +#include "method_bind_ext.inc" VisualServer *VisualServer::singleton=NULL; VisualServer* (*VisualServer::create_func)()=NULL; @@ -510,8 +511,9 @@ void VisualServer::_bind_methods() { ObjectTypeDB::bind_method(_MD("canvas_item_add_line"),&VisualServer::canvas_item_add_line, DEFVAL(1.0)); ObjectTypeDB::bind_method(_MD("canvas_item_add_rect"),&VisualServer::canvas_item_add_rect); - ObjectTypeDB::bind_method(_MD("canvas_item_add_texture_rect"),&VisualServer::canvas_item_add_texture_rect, DEFVAL(Color(1,1,1))); - ObjectTypeDB::bind_method(_MD("canvas_item_add_texture_rect_region"),&VisualServer::canvas_item_add_texture_rect_region, DEFVAL(Color(1,1,1))); + ObjectTypeDB::bind_method(_MD("canvas_item_add_texture_rect"),&VisualServer::canvas_item_add_texture_rect, DEFVAL(Color(1,1,1)), DEFVAL(false)); + ObjectTypeDB::bind_method(_MD("canvas_item_add_texture_rect_region"),&VisualServer::canvas_item_add_texture_rect_region, DEFVAL(Color(1,1,1)), DEFVAL(false)); + ObjectTypeDB::bind_method(_MD("canvas_item_add_style_box"),&VisualServer::_canvas_item_add_style_box, DEFVAL(Color(1,1,1))); // ObjectTypeDB::bind_method(_MD("canvas_item_add_primitive"),&VisualServer::canvas_item_add_primitive,DEFVAL(Vector<Vector2>()),DEFVAL(RID())); ObjectTypeDB::bind_method(_MD("canvas_item_add_circle"),&VisualServer::canvas_item_add_circle); diff --git a/servers/visual_server.h b/servers/visual_server.h index e9bc97628f..b6d354454e 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -684,6 +684,9 @@ public: virtual RID viewport_get_render_target_texture(RID p_viewport) const=0; virtual void viewport_set_render_target_vflip(RID p_viewport,bool p_enable)=0; virtual bool viewport_get_render_target_vflip(RID p_viewport) const=0; + virtual void viewport_set_render_target_clear_on_new_frame(RID p_viewport,bool p_enable)=0; + virtual bool viewport_get_render_target_clear_on_new_frame(RID p_viewport) const=0; + virtual void viewport_render_target_clear(RID p_viewport)=0; virtual void viewport_queue_screen_capture(RID p_viewport)=0; virtual Image viewport_get_screen_capture(RID p_viewport) const=0; @@ -701,6 +704,7 @@ public: virtual void viewport_set_hide_scenario(RID p_viewport,bool p_hide)=0; virtual void viewport_set_hide_canvas(RID p_viewport,bool p_hide)=0; + virtual void viewport_set_disable_environment(RID p_viewport,bool p_disable)=0; virtual void viewport_attach_camera(RID p_viewport,RID p_camera)=0; virtual void viewport_set_scenario(RID p_viewport,RID p_scenario)=0; @@ -731,8 +735,7 @@ public: ENV_BG_COLOR, ENV_BG_TEXTURE, ENV_BG_CUBEMAP, - ENV_BG_TEXTURE_RGBE, - ENV_BG_CUBEMAP_RGBE, + ENV_BG_CANVAS, ENV_BG_MAX }; @@ -741,6 +744,7 @@ public: enum EnvironmentBGParam { + ENV_BG_PARAM_CANVAS_MAX_LAYER, ENV_BG_PARAM_COLOR, ENV_BG_PARAM_TEXTURE, ENV_BG_PARAM_CUBEMAP, @@ -965,6 +969,7 @@ public: virtual void canvas_item_set_transform(RID p_item, const Matrix32& p_transform)=0; virtual void canvas_item_set_clip(RID p_item, bool p_clip)=0; + virtual void canvas_item_set_distance_field_mode(RID p_item, bool p_enable)=0; virtual void canvas_item_set_custom_rect(RID p_item, bool p_custom_rect,const Rect2& p_rect=Rect2())=0; virtual void canvas_item_set_opacity(RID p_item, float p_opacity)=0; virtual float canvas_item_get_opacity(RID p_item, float p_opacity) const=0; @@ -978,8 +983,8 @@ public: virtual void canvas_item_add_line(RID p_item, const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width=1.0)=0; virtual void canvas_item_add_rect(RID p_item, const Rect2& p_rect, const Color& p_color)=0; virtual void canvas_item_add_circle(RID p_item, const Point2& p_pos, float p_radius,const Color& p_color)=0; - virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1))=0; - virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1))=0; + virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1),bool p_transpose=false)=0; + virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1),bool p_transpose=false)=0; virtual void canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1))=0; virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width=1.0)=0; virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs=Vector<Point2>(), RID p_texture=RID())=0; @@ -991,21 +996,19 @@ public: virtual void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable)=0; virtual void canvas_item_set_z(RID p_item, int p_z)=0; virtual void canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable)=0; + virtual void canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable,const Rect2& p_rect)=0; virtual void canvas_item_clear(RID p_item)=0; virtual void canvas_item_raise(RID p_item)=0; - virtual void canvas_item_set_shader(RID p_item, RID p_shader)=0; - virtual RID canvas_item_get_shader(RID p_item) const=0; + virtual void canvas_item_set_material(RID p_item, RID p_material)=0; - virtual void canvas_item_set_use_parent_shader(RID p_item, bool p_enable)=0; - - virtual void canvas_item_set_shader_param(RID p_canvas_item, const StringName& p_param, const Variant& p_value)=0; - virtual Variant canvas_item_get_shader_param(RID p_canvas_item, const StringName& p_param) const=0; + virtual void canvas_item_set_use_parent_material(RID p_item, bool p_enable)=0; virtual RID canvas_light_create()=0; virtual void canvas_light_attach_to_canvas(RID p_light,RID p_canvas)=0; virtual void canvas_light_set_enabled(RID p_light, bool p_enabled)=0; + virtual void canvas_light_set_scale(RID p_light, float p_scale)=0; virtual void canvas_light_set_transform(RID p_light, const Matrix32& p_transform)=0; virtual void canvas_light_set_texture(RID p_light, RID p_texture)=0; virtual void canvas_light_set_texture_offset(RID p_light, const Vector2& p_offset)=0; @@ -1014,17 +1017,39 @@ public: virtual void canvas_light_set_z_range(RID p_light, int p_min_z,int p_max_z)=0; virtual void canvas_light_set_layer_range(RID p_light, int p_min_layer,int p_max_layer)=0; virtual void canvas_light_set_item_mask(RID p_light, int p_mask)=0; + virtual void canvas_light_set_item_shadow_mask(RID p_light, int p_mask)=0; virtual void canvas_light_set_subtract_mode(RID p_light, bool p_enable)=0; virtual void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled)=0; virtual void canvas_light_set_shadow_buffer_size(RID p_light, int p_size)=0; - virtual void canvas_light_set_shadow_filter(RID p_light, int p_size)=0; + virtual void canvas_light_set_shadow_esm_multiplier(RID p_light, float p_multiplier)=0; + virtual RID canvas_light_occluder_create()=0; virtual void canvas_light_occluder_attach_to_canvas(RID p_occluder,RID p_canvas)=0; virtual void canvas_light_occluder_set_enabled(RID p_occluder,bool p_enabled)=0; - virtual void canvas_light_occluder_set_shape(RID p_occluder,const DVector<Vector2>& p_shape)=0; + virtual void canvas_light_occluder_set_polygon(RID p_occluder,RID p_polygon)=0; + virtual void canvas_light_occluder_set_transform(RID p_occluder,const Matrix32& p_xform)=0; + virtual void canvas_light_occluder_set_light_mask(RID p_occluder,int p_mask)=0; + + virtual RID canvas_occluder_polygon_create()=0; + virtual void canvas_occluder_polygon_set_shape(RID p_occluder_polygon,const DVector<Vector2>& p_shape,bool p_closed)=0; + virtual void canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon,const DVector<Vector2>& p_shape)=0; + enum CanvasOccluderPolygonCullMode { + CANVAS_OCCLUDER_POLYGON_CULL_DISABLED, + CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE, + CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE, + }; + virtual void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon,CanvasOccluderPolygonCullMode p_mode)=0; + + /* CANVAS ITEM MATERIAL */ + + virtual RID canvas_item_material_create()=0; + virtual void canvas_item_material_set_shader(RID p_material, RID p_shader)=0; + virtual void canvas_item_material_set_shader_param(RID p_material, const StringName& p_param, const Variant& p_value)=0; + virtual Variant canvas_item_material_get_shader_param(RID p_material, const StringName& p_param) const=0; + virtual void canvas_item_material_set_unshaded(RID p_material, bool p_unshaded)=0; /* CURSOR */ virtual void cursor_set_rotation(float p_rotation, int p_cursor = 0)=0; // radians |