diff options
Diffstat (limited to 'scene')
-rw-r--r-- | scene/3d/light.cpp | 8 | ||||
-rw-r--r-- | scene/3d/light.h | 2 | ||||
-rw-r--r-- | scene/main/node.cpp | 13 | ||||
-rw-r--r-- | scene/main/node.h | 1 | ||||
-rw-r--r-- | scene/register_scene_types.cpp | 2 | ||||
-rw-r--r-- | scene/resources/environment.cpp | 9 | ||||
-rw-r--r-- | scene/resources/environment.h | 3 | ||||
-rw-r--r-- | scene/resources/polygon_path_finder.cpp | 413 | ||||
-rw-r--r-- | scene/resources/polygon_path_finder.h | 58 |
9 files changed, 501 insertions, 8 deletions
diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp index 7cc1d12daa..b79fd8617f 100644 --- a/scene/3d/light.cpp +++ b/scene/3d/light.cpp @@ -40,7 +40,9 @@ static const char* _light_param_names[VS::LIGHT_PARAM_MAX]={ "params/attenuation", "shadow/darkening", "shadow/z_offset", - "shadow/z_slope_scale" + "shadow/z_slope_scale", + "shadow/esm_multiplier", + "shadow/blur_passes" }; void Light::set_parameter(Parameter p_param, float p_value) { @@ -479,6 +481,8 @@ void Light::_bind_methods() { ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/darkening", PROPERTY_HINT_RANGE, "0,64,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_DARKENING ); ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/z_offset", PROPERTY_HINT_RANGE, "0,128,0.001"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_Z_OFFSET); ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/z_slope_scale", PROPERTY_HINT_RANGE, "0,128,0.001"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_Z_SLOPE_SCALE); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/esm_multiplier", PROPERTY_HINT_RANGE, "1.0,512.0,0.1"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_ESM_MULTIPLIER); + ADD_PROPERTYI( PropertyInfo( Variant::INT, "shadow/blur_passes", PROPERTY_HINT_RANGE, "0,4,1"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SHADOW_BLUR_PASSES); ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "projector",PROPERTY_HINT_RESOURCE_TYPE,"Texture"), _SCS("set_projector"), _SCS("get_projector")); ADD_PROPERTY( PropertyInfo( Variant::INT, "operator",PROPERTY_HINT_ENUM,"Add,Sub"), _SCS("set_operator"), _SCS("get_operator")); @@ -511,6 +515,8 @@ Light::Light(VisualServer::LightType p_type) { set_parameter(PARAM_SHADOW_DARKENING,0.0); set_parameter(PARAM_SHADOW_Z_OFFSET,0.05); set_parameter(PARAM_SHADOW_Z_SLOPE_SCALE,0); + set_parameter(PARAM_SHADOW_ESM_MULTIPLIER,60); + set_parameter(PARAM_SHADOW_BLUR_PASSES,1); set_color( COLOR_AMBIENT, Color(0,0,0)); set_color( COLOR_DIFFUSE, Color(1,1,1)); diff --git a/scene/3d/light.h b/scene/3d/light.h index 76b44c8712..f090ae5782 100644 --- a/scene/3d/light.h +++ b/scene/3d/light.h @@ -53,6 +53,8 @@ public: PARAM_SHADOW_DARKENING=VisualServer::LIGHT_PARAM_SHADOW_DARKENING, PARAM_SHADOW_Z_OFFSET=VisualServer::LIGHT_PARAM_SHADOW_Z_OFFSET, PARAM_SHADOW_Z_SLOPE_SCALE=VisualServer::LIGHT_PARAM_SHADOW_Z_SLOPE_SCALE, + PARAM_SHADOW_ESM_MULTIPLIER=VisualServer::LIGHT_PARAM_SHADOW_ESM_MULTIPLIER, + PARAM_SHADOW_BLUR_PASSES=VisualServer::LIGHT_PARAM_SHADOW_BLUR_PASSES, PARAM_MAX=VisualServer::LIGHT_PARAM_MAX }; diff --git a/scene/main/node.cpp b/scene/main/node.cpp index d4f043c538..042666988a 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -1078,6 +1078,18 @@ void Node::remove_from_group(const StringName& p_identifier) { } +Array Node::_get_groups() const { + + Array groups; + List<GroupInfo> gi; + get_groups(&gi); + for (List<GroupInfo>::Element *E=gi.front();E;E=E->next()) { + groups.push_back(E->get().name); + } + + return groups; +} + void Node::get_groups(List<GroupInfo> *p_groups) const { const StringName *K=NULL; @@ -1712,6 +1724,7 @@ void Node::_bind_methods() { ObjectTypeDB::bind_method(_MD("remove_from_group","group"),&Node::remove_from_group); ObjectTypeDB::bind_method(_MD("is_in_group","group"),&Node::is_in_group); ObjectTypeDB::bind_method(_MD("move_child","child_node:Node","to_pos"),&Node::move_child); + ObjectTypeDB::bind_method(_MD("get_groups"),&Node::_get_groups); ObjectTypeDB::bind_method(_MD("raise"),&Node::raise); ObjectTypeDB::bind_method(_MD("set_owner","owner:Node"),&Node::set_owner); ObjectTypeDB::bind_method(_MD("get_owner:Node"),&Node::get_owner); diff --git a/scene/main/node.h b/scene/main/node.h index b8981d3307..32c5d8ef38 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -125,6 +125,7 @@ private: void _duplicate_and_reown(Node* p_new_parent, const Map<Node*,Node*>& p_reown_map) const; Array _get_children() const; + Array _get_groups() const; friend class SceneMainLoop; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 30e6e01842..9a6454e416 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -140,6 +140,7 @@ #include "scene/resources/mesh_library.h" #include "scene/resources/image_path_finder.h" +#include "scene/resources/polygon_path_finder.h" #include "scene/resources/sample.h" #include "scene/audio/sample_player.h" @@ -536,6 +537,7 @@ void register_scene_types() { ObjectTypeDB::register_type<StyleBoxImageMask>(); ObjectTypeDB::register_type<Theme>(); ObjectTypeDB::register_type<ImagePathFinder>(); + ObjectTypeDB::register_type<PolygonPathFinder>(); ObjectTypeDB::register_type<BitMap>(); OS::get_singleton()->yield(); //may take time to init diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 99447c0a0e..5c1d190b2e 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -140,8 +140,8 @@ void Environment::_bind_methods() { ADD_PROPERTYI( PropertyInfo(Variant::REAL,"bcs/brightness",PROPERTY_HINT_RANGE,"0.01,8,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_BCS_BRIGHTNESS); ADD_PROPERTYI( PropertyInfo(Variant::REAL,"bcs/contrast",PROPERTY_HINT_RANGE,"0.01,8,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_BCS_CONTRAST); ADD_PROPERTYI( PropertyInfo(Variant::REAL,"bcs/saturation",PROPERTY_HINT_RANGE,"0.01,8,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_BCS_SATURATION); - ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"gamma/enabled"),_SCS("set_enable_fx"),_SCS("is_fx_enabled"), FX_GAMMA); - ADD_PROPERTYI( PropertyInfo(Variant::REAL,"gamma/gamma",PROPERTY_HINT_EXP_EASING,"0.01,8,0.01"),_SCS("fx_set_param"),_SCS("fx_get_param"), FX_PARAM_GAMMA); + ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"srgb/enabled"),_SCS("set_enable_fx"),_SCS("is_fx_enabled"), FX_SRGB); + @@ -194,7 +194,7 @@ void Environment::_bind_methods() { BIND_CONSTANT( FX_HDR ); BIND_CONSTANT( FX_FOG ); BIND_CONSTANT( FX_BCS); - BIND_CONSTANT( FX_GAMMA ); + BIND_CONSTANT( FX_SRGB ); BIND_CONSTANT( FX_MAX ); @@ -226,7 +226,6 @@ void Environment::_bind_methods() { BIND_CONSTANT( FX_PARAM_BCS_BRIGHTNESS ); BIND_CONSTANT( FX_PARAM_BCS_CONTRAST ); BIND_CONSTANT( FX_PARAM_BCS_SATURATION ); - BIND_CONSTANT( FX_PARAM_GAMMA ); BIND_CONSTANT( FX_PARAM_MAX ); } @@ -269,7 +268,7 @@ Environment::Environment() { fx_set_param(FX_PARAM_BCS_BRIGHTNESS,1.0); fx_set_param(FX_PARAM_BCS_CONTRAST,1.0); fx_set_param(FX_PARAM_BCS_SATURATION,1.0); - fx_set_param(FX_PARAM_GAMMA,1.0); + } Environment::~Environment() { diff --git a/scene/resources/environment.h b/scene/resources/environment.h index 627fbb7cc0..b72d6d74be 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -67,7 +67,7 @@ public: FX_HDR=VS::ENV_FX_HDR, FX_FOG=VS::ENV_FX_FOG, FX_BCS=VS::ENV_FX_BCS, - FX_GAMMA=VS::ENV_FX_GAMMA, + FX_SRGB=VS::ENV_FX_SRGB, FX_MAX=VS::ENV_FX_MAX, }; @@ -102,7 +102,6 @@ public: FX_PARAM_BCS_BRIGHTNESS=VS::ENV_FX_PARAM_BCS_BRIGHTNESS, FX_PARAM_BCS_CONTRAST=VS::ENV_FX_PARAM_BCS_CONTRAST, FX_PARAM_BCS_SATURATION=VS::ENV_FX_PARAM_BCS_SATURATION, - FX_PARAM_GAMMA=VS::ENV_FX_PARAM_GAMMA, FX_PARAM_MAX=VS::ENV_FX_PARAM_MAX }; private: diff --git a/scene/resources/polygon_path_finder.cpp b/scene/resources/polygon_path_finder.cpp new file mode 100644 index 0000000000..9f7b6d5b9e --- /dev/null +++ b/scene/resources/polygon_path_finder.cpp @@ -0,0 +1,413 @@ +#include "polygon_path_finder.h" +#include "geometry.h" + + +bool PolygonPathFinder::_is_point_inside(const Vector2& p_point) { + + int crosses=0; + + + for (Set<Edge>::Element *E=edges.front();E;E=E->next()) { + + + const Edge& e=E->get(); + + Vector2 a = points[e.points[0]].pos; + Vector2 b = points[e.points[1]].pos; + + + if (Geometry::segment_intersects_segment_2d(a,b,p_point,outside_point,NULL)) { + crosses++; + } + } + + return crosses&1; +} + +void PolygonPathFinder::setup(const Vector<Vector2>& p_points, const Vector<int>& p_connections) { + + + ERR_FAIL_COND(p_connections.size()&1); + + points.clear(); + edges.clear(); + + //insert points + + int point_count=p_points.size(); + points.resize(point_count+2); + + for(int i=0;i<p_points.size();i++) { + + points[i].pos=p_points[i]; + + outside_point.x = i==0?p_points[0].x:(MAX( p_points[i].x, outside_point.x )); + outside_point.y = i==0?p_points[0].y:(MAX( p_points[i].y, outside_point.y )); + } + + outside_point.x+=20.451+Math::randf()*10.2039; + outside_point.y+=21.193+Math::randf()*12.5412; + + //insert edges (which are also connetions) + + for(int i=0;i<p_connections.size();i+=2) { + + Edge e(p_connections[i],p_connections[i+1]); + ERR_FAIL_INDEX(e.points[0],point_count); + ERR_FAIL_INDEX(e.points[1],point_count); + points[p_connections[i]].connections.insert(p_connections[i+1]); + points[p_connections[i+1]].connections.insert(p_connections[i]); + edges.insert(e); + } + + + //fill the remaining connections based on visibility + + for(int i=0;i<point_count;i++) { + + for(int j=i+1;j<point_count;j++) { + + if (edges.has(Edge(i,j))) + continue; //if in edge ignore + + Vector2 from=points[i].pos; + Vector2 to=points[j].pos; + + if (!_is_point_inside(from*0.5+to*0.5)) //connection between points in inside space + continue; + + bool valid=true; + + for (Set<Edge>::Element *E=edges.front();E;E=E->next()) { + + const Edge& e=E->get(); + if (e.points[0]==i || e.points[1]==i || e.points[0]==j || e.points[1]==j ) + continue; + + + Vector2 a = points[e.points[0]].pos; + Vector2 b = points[e.points[1]].pos; + + + if (Geometry::segment_intersects_segment_2d(a,b,from,to,NULL)) { + valid=false; + break; + } + + } + + if (valid) { + points[i].connections.insert(j); + points[j].connections.insert(i); + } + } + } +} + + +Vector<Vector2> PolygonPathFinder::find_path(const Vector2& p_from, const Vector2& p_to) { + + Vector<Vector2> path; + if (!_is_point_inside(p_from)) + return path; + if (!_is_point_inside(p_to)) + return path; + + //test direct connection + { + + bool can_see_eachother=true; + + for (Set<Edge>::Element *E=edges.front();E;E=E->next()) { + + const Edge& e=E->get(); + Vector2 a = points[e.points[0]].pos; + Vector2 b = points[e.points[1]].pos; + + + if (Geometry::segment_intersects_segment_2d(a,b,p_from,p_to,NULL)) { + can_see_eachother=false; + break; + } + + } + + if (can_see_eachother) { + + path.push_back(p_from); + path.push_back(p_to); + return path; + } + } + + //add to graph + + int aidx = points.size()-2; + int bidx = points.size()-1; + points[aidx].pos=p_from; + points[bidx].pos=p_to; + points[aidx].distance=0; + points[bidx].distance=0; + points[aidx].distance=0; + points[bidx].distance=0; + + + for(int i=0;i<points.size()-2;i++) { + + + bool valid_a=true; + bool valid_b=true; + points[i].prev=-1; + points[i].distance=0; + + for (Set<Edge>::Element *E=edges.front();E;E=E->next()) { + + const Edge& e=E->get(); + + if (e.points[0]==i || e.points[1]==i) + continue; + + Vector2 a = points[e.points[0]].pos; + Vector2 b = points[e.points[1]].pos; + + if (valid_a) { + + if (Geometry::segment_intersects_segment_2d(a,b,p_from,points[i].pos,NULL)) { + valid_a=false; + } + } + + if (valid_b) { + + if (Geometry::segment_intersects_segment_2d(a,b,p_to,points[i].pos,NULL)) { + valid_b=false; + } + } + + if (!valid_a && !valid_b) + continue; + + } + + if (valid_a) { + points[i].connections.insert(aidx); + points[aidx].connections.insert(i); + } + + if (valid_b) { + points[i].connections.insert(bidx); + points[bidx].connections.insert(i); + } + + } + //solve graph + + Set<int> open_list; + + points[aidx].distance=0; + points[aidx].prev=aidx; + for(Set<int>::Element *E=points[aidx].connections.front();E;E=E->next()) { + + open_list.insert(E->get()); + points[E->get()].distance=p_from.distance_to(points[E->get()].pos); + points[E->get()].prev=aidx; + + } + + + bool found_route=false; + + while(true) { + + if (open_list.size()==0) { + break; + } + //check open list + + int least_cost_point=-1; + float least_cost=1e30; + + //this could be faster (cache previous results) + for (Set<int>::Element *E=open_list.front();E;E=E->next()) { + + const Point& p =points[E->get()]; + float cost = p.distance; + cost+=p.pos.distance_to(p_to); + if (cost<least_cost) { + + least_cost_point=E->get(); + least_cost=cost; + } + } + + + Point &np = points[least_cost_point]; + //open the neighbours for search + + for(Set<int>::Element *E=np.connections.front();E;E=E->next()) { + + Point& p =points[E->get()]; + float distance = np.pos.distance_to(p.pos) + np.distance; + + if (p.prev!=-1) { + //oh this was visited already, can we win the cost? + + if (p.distance>distance) { + + p.prev=least_cost_point; //reasign previous + p.distance=distance; + } + } else { + //add to open neighbours + + p.prev=least_cost_point; + p.distance=distance; + open_list.insert(E->get()); + + if (E->get()==bidx) { + //oh my reached end! stop algorithm + found_route=true; + break; + + } + + } + } + + if (found_route) + break; + + open_list.erase(least_cost_point); + } + + if (found_route) { + int at = bidx; + path.push_back(points[at].pos); + do { + at=points[at].prev; + path.push_back(points[at].pos); + } while (at!=aidx); + + path.invert();; + } + + for(int i=0;i<points.size()-2;i++) { + + points[i].connections.erase(aidx); + points[i].connections.erase(bidx); + points[i].prev=-1; + points[i].distance=0; + } + + points[aidx].connections.clear(); + points[aidx].prev=-1; + points[aidx].distance=0; + points[bidx].connections.clear(); + points[bidx].prev=-1; + points[bidx].distance=0; + + return path; +} + +void PolygonPathFinder::_set_data(const Dictionary& p_data) { + + + ERR_FAIL_COND(!p_data.has("points")); + ERR_FAIL_COND(!p_data.has("connections")); + ERR_FAIL_COND(!p_data.has("segments")); + + DVector<Vector2> p=p_data["points"]; + Array c=p_data["connections"]; + + ERR_FAIL_COND(c.size()!=p.size()); + if (c.size()) + return; + + int pc = p.size(); + points.resize(pc+2); + + DVector<Vector2>::Read pr=p.read(); + for(int i=0;i<pc;i++) { + points[i].pos=pr[i]; + DVector<int> con=c[i]; + DVector<int>::Read cr=con.read(); + int cc=con.size(); + for(int j=0;j<cc;j++) { + + points[i].connections.insert(cr[j]); + } + + } + + DVector<int> segs=p_data["segments"]; + int sc=segs.size(); + ERR_FAIL_COND(sc&1); + DVector<int>::Read sr = segs.read(); + for(int i=0;i<sc;i+=2) { + + Edge e(sr[i],sr[i+1]); + edges.insert(e); + } + +} + +Dictionary PolygonPathFinder::_get_data() const{ + + Dictionary d; + DVector<Vector2> p; + DVector<int> ind; + Array connections; + p.resize(points.size()-2); + connections.resize(points.size()-2); + ind.resize(edges.size()*2); + { + DVector<Vector2>::Write wp=p.write(); + for(int i=0;i<points.size()-2;i++) { + wp[i]=points[i].pos; + DVector<int> c; + c.resize(points[i].connections.size()); + { + DVector<int>::Write cw=c.write(); + int idx=0; + for (Set<int>::Element *E=points[i].connections.front();E;E=E->next()) { + cw[idx++]=E->get(); + } + } + connections[i]=c; + } + } + { + + DVector<int>::Write iw=ind.write(); + int idx=0; + for (Set<Edge>::Element *E=edges.front();E;E=E->next()) { + iw[idx++]=E->get().points[0]; + iw[idx++]=E->get().points[1]; + } + + } + + d["points"]=p; + d["connections"]=connections; + d["segments"]=ind; + + return d; + +} + +void PolygonPathFinder::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("setup","points","connections"),&PolygonPathFinder::setup); + ObjectTypeDB::bind_method(_MD("find_path","from","to"),&PolygonPathFinder::find_path); + ObjectTypeDB::bind_method(_MD("_set_data"),&PolygonPathFinder::_set_data); + ObjectTypeDB::bind_method(_MD("_get_data"),&PolygonPathFinder::_get_data); + + ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY,"data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_data"),_SCS("_get_data")); + +} + +PolygonPathFinder::PolygonPathFinder() +{ +} + + diff --git a/scene/resources/polygon_path_finder.h b/scene/resources/polygon_path_finder.h new file mode 100644 index 0000000000..31253e3177 --- /dev/null +++ b/scene/resources/polygon_path_finder.h @@ -0,0 +1,58 @@ +#ifndef POLYGON_PATH_FINDER_H +#define POLYGON_PATH_FINDER_H + +#include "resource.h" + +class PolygonPathFinder : public Resource { + + OBJ_TYPE(PolygonPathFinder,Resource); + + struct Point { + Vector2 pos; + Set<int> connections; + float distance; + int prev; + }; + + struct Edge { + + int points[2]; + + _FORCE_INLINE_ bool operator<(const Edge& p_edge) const { + + if (points[0]==p_edge.points[0]) + return points[1]<p_edge.points[1]; + else + return points[0]<p_edge.points[0]; + } + + Edge(int a=0, int b=0) { + + if (a>b) { + SWAP(a,b); + } + } + }; + + Vector2 outside_point; + + Vector<Point> points; + Set<Edge> edges; + + bool _is_point_inside(const Vector2& p_point); + + void _set_data(const Dictionary& p_data); + Dictionary _get_data() const; +protected: + + static void _bind_methods(); +public: + + + void setup(const Vector<Vector2>& p_points, const Vector<int>& p_connections); + Vector<Vector2> find_path(const Vector2& p_from, const Vector2& p_to); + + PolygonPathFinder(); +}; + +#endif // POLYGON_PATH_FINDER_H |