summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/area_2d.cpp34
-rw-r--r--scene/2d/area_2d.h8
-rw-r--r--scene/2d/navigation2d.cpp38
-rw-r--r--scene/2d/navigation2d.h2
-rw-r--r--scene/2d/physics_body_2d.cpp18
-rw-r--r--scene/2d/physics_body_2d.h4
-rw-r--r--scene/2d/tile_map.cpp32
-rw-r--r--scene/2d/tile_map.h9
-rw-r--r--scene/3d/navigation.cpp15
-rw-r--r--scene/3d/navigation.h2
10 files changed, 149 insertions, 13 deletions
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp
index a40b1fb397..827256c2fa 100644
--- a/scene/2d/area_2d.cpp
+++ b/scene/2d/area_2d.cpp
@@ -512,6 +512,29 @@ bool Area2D::overlaps_body(Node* p_body) const{
}
+void Area2D::set_collision_mask(uint32_t p_mask) {
+
+ collision_mask=p_mask;
+ Physics2DServer::get_singleton()->area_set_collision_mask(get_rid(),p_mask);
+}
+
+uint32_t Area2D::get_collision_mask() const {
+
+ return collision_mask;
+}
+
+
+void Area2D::set_layer_mask(uint32_t p_mask) {
+
+ layer_mask=p_mask;
+ Physics2DServer::get_singleton()->area_set_layer_mask(get_rid(),p_mask);
+}
+
+uint32_t Area2D::get_layer_mask() const {
+
+ return layer_mask;
+}
+
void Area2D::_bind_methods() {
@@ -542,6 +565,12 @@ void Area2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_priority","priority"),&Area2D::set_priority);
ObjectTypeDB::bind_method(_MD("get_priority"),&Area2D::get_priority);
+ ObjectTypeDB::bind_method(_MD("set_collision_mask","collision_mask"),&Area2D::set_collision_mask);
+ ObjectTypeDB::bind_method(_MD("get_collision_mask"),&Area2D::get_collision_mask);
+
+ ObjectTypeDB::bind_method(_MD("set_layer_mask","layer_mask"),&Area2D::set_layer_mask);
+ ObjectTypeDB::bind_method(_MD("get_layer_mask"),&Area2D::get_layer_mask);
+
ObjectTypeDB::bind_method(_MD("set_enable_monitoring","enable"),&Area2D::set_enable_monitoring);
ObjectTypeDB::bind_method(_MD("is_monitoring_enabled"),&Area2D::is_monitoring_enabled);
@@ -578,6 +607,8 @@ void Area2D::_bind_methods() {
ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"priority",PROPERTY_HINT_RANGE,"0,128,1"),_SCS("set_priority"),_SCS("get_priority"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitoring"),_SCS("set_enable_monitoring"),_SCS("is_monitoring_enabled"));
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitorable"),_SCS("set_monitorable"),_SCS("is_monitorable"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_mask"),_SCS("get_collision_mask"));
}
@@ -593,9 +624,10 @@ Area2D::Area2D() : CollisionObject2D(Physics2DServer::get_singleton()->area_crea
priority=0;
monitoring=false;
monitorable=false;
+ collision_mask=1;
+ layer_mask=1;
set_enable_monitoring(true);
set_monitorable(true);
-
}
Area2D::~Area2D() {
diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h
index 5964230a52..0c064f54cd 100644
--- a/scene/2d/area_2d.h
+++ b/scene/2d/area_2d.h
@@ -51,6 +51,8 @@ private:
bool gravity_is_point;
real_t linear_damp;
real_t angular_damp;
+ uint32_t collision_mask;
+ uint32_t layer_mask;
int priority;
bool monitoring;
bool monitorable;
@@ -151,6 +153,12 @@ public:
void set_monitorable(bool p_enable);
bool is_monitorable() const;
+ void set_collision_mask(uint32_t p_mask);
+ uint32_t get_collision_mask() const;
+
+ void set_layer_mask(uint32_t p_mask);
+ uint32_t get_layer_mask() const;
+
Array get_overlapping_bodies() const; //function for script
Array get_overlapping_areas() const; //function for script
diff --git a/scene/2d/navigation2d.cpp b/scene/2d/navigation2d.cpp
index d427bf4bc3..5a02501816 100644
--- a/scene/2d/navigation2d.cpp
+++ b/scene/2d/navigation2d.cpp
@@ -32,6 +32,7 @@ void Navigation2D::_navpoly_link(int p_id) {
p.edges.resize(plen);
Vector2 center;
+ float sum=0;
for(int j=0;j<plen;j++) {
@@ -46,8 +47,23 @@ void Navigation2D::_navpoly_link(int p_id) {
center+=ep;
e.point=_get_point(ep);
p.edges[j]=e;
+
+
+ int idxn = indices[(j+1)%plen];
+ if (idxn<0 || idxn>=len) {
+ valid=false;
+ break;
+ }
+
+ Vector2 epn = nm.xform.xform(r[idxn]);
+
+ sum+=(epn.x-ep.x)*(epn.y+ep.y);
+
+
}
+ p.clockwise=sum>0;
+
if (!valid) {
nm.polygons.pop_back();
ERR_CONTINUE(!valid);
@@ -493,17 +509,30 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2& p_start, const Vect
left = _get_vertex(p->edges[prev].point);
right = _get_vertex(p->edges[prev_n].point);
- if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5) < 0){
+ if (p->clockwise) {
SWAP(left,right);
}
+ /*if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5) < 0){
+ SWAP(left,right);
+ }*/
}
bool skip=false;
+ /* print_line("-----\nAPEX: "+(apex_point-end_point));
+ print_line("LEFT:");
+ print_line("\tPortal: "+(portal_left-end_point));
+ print_line("\tPoint: "+(left-end_point));
+ print_line("\tFree: "+itos(CLOCK_TANGENT(apex_point,portal_left,left) >= 0));
+ print_line("RIGHT:");
+ print_line("\tPortal: "+(portal_right-end_point));
+ print_line("\tPoint: "+(right-end_point));
+ print_line("\tFree: "+itos(CLOCK_TANGENT(apex_point,portal_right,right) <= 0));
+*/
if (CLOCK_TANGENT(apex_point,portal_left,left) >= 0){
//process
- if (portal_left==apex_point || CLOCK_TANGENT(apex_point,left,portal_right) > 0) {
+ if (portal_left.distance_squared_to(apex_point)<CMP_EPSILON || CLOCK_TANGENT(apex_point,left,portal_right) > 0) {
left_poly=p;
portal_left=left;
} else {
@@ -519,12 +548,13 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2& p_start, const Vect
if (path[path.size()-1].distance_to(apex_point)>CMP_EPSILON)
path.push_back(apex_point);
skip=true;
+ //print_line("addpoint left");
}
}
if (!skip && CLOCK_TANGENT(apex_point,portal_right,right) <= 0){
//process
- if (portal_right==apex_point || CLOCK_TANGENT(apex_point,right,portal_left) < 0) {
+ if (portal_right.distance_squared_to(apex_point)<CMP_EPSILON || CLOCK_TANGENT(apex_point,right,portal_left) < 0) {
right_poly=p;
portal_right=right;
} else {
@@ -539,6 +569,8 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2& p_start, const Vect
portal_left=apex_point;
if (path[path.size()-1].distance_to(apex_point)>CMP_EPSILON)
path.push_back(apex_point);
+ //print_line("addpoint right");
+
}
}
diff --git a/scene/2d/navigation2d.h b/scene/2d/navigation2d.h
index 7a33105b77..829b0f544b 100644
--- a/scene/2d/navigation2d.h
+++ b/scene/2d/navigation2d.h
@@ -60,6 +60,8 @@ class Navigation2D : public Node2D {
float distance;
int prev_edge;
+ bool clockwise;
+
NavMesh *owner;
};
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index e7bc199608..6fb798714f 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -72,13 +72,16 @@ void PhysicsBody2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&PhysicsBody2D::set_layer_mask);
ObjectTypeDB::bind_method(_MD("get_layer_mask"),&PhysicsBody2D::get_layer_mask);
+ ObjectTypeDB::bind_method(_MD("set_collision_mask","mask"),&PhysicsBody2D::set_collision_mask);
+ ObjectTypeDB::bind_method(_MD("get_collision_mask"),&PhysicsBody2D::get_collision_mask);
ObjectTypeDB::bind_method(_MD("set_one_way_collision_direction","dir"),&PhysicsBody2D::set_one_way_collision_direction);
ObjectTypeDB::bind_method(_MD("get_one_way_collision_direction"),&PhysicsBody2D::get_one_way_collision_direction);
ObjectTypeDB::bind_method(_MD("set_one_way_collision_max_depth","depth"),&PhysicsBody2D::set_one_way_collision_max_depth);
ObjectTypeDB::bind_method(_MD("get_one_way_collision_max_depth"),&PhysicsBody2D::get_one_way_collision_max_depth);
ObjectTypeDB::bind_method(_MD("add_collision_exception_with","body:PhysicsBody2D"),&PhysicsBody2D::add_collision_exception_with);
ObjectTypeDB::bind_method(_MD("remove_collision_exception_with","body:PhysicsBody2D"),&PhysicsBody2D::remove_collision_exception_with);
- ADD_PROPERTY(PropertyInfo(Variant::INT,"layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
+ ADD_PROPERTY(PropertyInfo(Variant::INT,"collision/mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_mask"),_SCS("get_collision_mask"));
ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2,"one_way_collision/direction"),_SCS("set_one_way_collision_direction"),_SCS("get_one_way_collision_direction"));
ADD_PROPERTYNZ(PropertyInfo(Variant::REAL,"one_way_collision/max_depth"),_SCS("set_one_way_collision_max_depth"),_SCS("get_one_way_collision_max_depth"));
}
@@ -94,9 +97,22 @@ uint32_t PhysicsBody2D::get_layer_mask() const {
return mask;
}
+void PhysicsBody2D::set_collision_mask(uint32_t p_mask) {
+
+ collision_mask=p_mask;
+ Physics2DServer::get_singleton()->body_set_collision_mask(get_rid(),p_mask);
+}
+
+uint32_t PhysicsBody2D::get_collision_mask() const {
+
+ return collision_mask;
+}
+
+
PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) : CollisionObject2D( Physics2DServer::get_singleton()->body_create(p_mode), false) {
mask=1;
+ collision_mask=1;
set_one_way_collision_max_depth(0);
set_pickable(false);
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index b8cba6e5ba..3cb94b95da 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -39,6 +39,7 @@ class PhysicsBody2D : public CollisionObject2D {
OBJ_TYPE(PhysicsBody2D,CollisionObject2D);
uint32_t mask;
+ uint32_t collision_mask;
Vector2 one_way_collision_direction;
float one_way_collision_max_depth;
protected:
@@ -52,6 +53,9 @@ public:
void set_layer_mask(uint32_t p_mask);
uint32_t get_layer_mask() const;
+ void set_collision_mask(uint32_t p_mask);
+ uint32_t get_collision_mask() const;
+
void add_collision_exception_with(Node* p_node); //must be physicsbody
void remove_collision_exception_with(Node* p_node);
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index bf1677ae63..2fca1e67e8 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -519,6 +519,7 @@ Map<TileMap::PosKey,TileMap::Quadrant>::Element *TileMap::_create_quadrant(const
q.body=Physics2DServer::get_singleton()->body_create(use_kinematic?Physics2DServer::BODY_MODE_KINEMATIC:Physics2DServer::BODY_MODE_STATIC);
Physics2DServer::get_singleton()->body_attach_object_instance_ID(q.body,get_instance_ID());
Physics2DServer::get_singleton()->body_set_layer_mask(q.body,collision_layer);
+ Physics2DServer::get_singleton()->body_set_collision_mask(q.body,collision_mask);
Physics2DServer::get_singleton()->body_set_param(q.body,Physics2DServer::BODY_PARAM_FRICTION,friction);
Physics2DServer::get_singleton()->body_set_param(q.body,Physics2DServer::BODY_PARAM_BOUNCE,bounce);
@@ -790,7 +791,7 @@ Rect2 TileMap::get_item_rect() const {
return rect_cache;
}
-void TileMap::set_collision_layer_mask(uint32_t p_layer) {
+void TileMap::set_collision_layer(uint32_t p_layer) {
collision_layer=p_layer;
for (Map<PosKey,Quadrant>::Element *E=quadrant_map.front();E;E=E->next()) {
@@ -800,6 +801,16 @@ void TileMap::set_collision_layer_mask(uint32_t p_layer) {
}
}
+void TileMap::set_collision_mask(uint32_t p_mask) {
+
+ collision_mask=p_mask;
+ for (Map<PosKey,Quadrant>::Element *E=quadrant_map.front();E;E=E->next()) {
+
+ Quadrant &q=E->get();
+ Physics2DServer::get_singleton()->body_set_collision_mask(q.body,collision_mask);
+ }
+}
+
bool TileMap::get_collision_use_kinematic() const{
return use_kinematic;
@@ -844,11 +855,16 @@ float TileMap::get_collision_bounce() const{
}
-uint32_t TileMap::get_collision_layer_mask() const {
+uint32_t TileMap::get_collision_layer() const {
return collision_layer;
}
+uint32_t TileMap::get_collision_mask() const {
+
+ return collision_mask;
+}
+
void TileMap::set_mode(Mode p_mode) {
_clear_quadrants();
@@ -1077,8 +1093,11 @@ void TileMap::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_collision_use_kinematic","use_kinematic"),&TileMap::set_collision_use_kinematic);
ObjectTypeDB::bind_method(_MD("get_collision_use_kinematic"),&TileMap::get_collision_use_kinematic);
- ObjectTypeDB::bind_method(_MD("set_collision_layer_mask","mask"),&TileMap::set_collision_layer_mask);
- ObjectTypeDB::bind_method(_MD("get_collision_layer_mask"),&TileMap::get_collision_layer_mask);
+ ObjectTypeDB::bind_method(_MD("set_collision_layer","mask"),&TileMap::set_collision_layer);
+ ObjectTypeDB::bind_method(_MD("get_collision_layer"),&TileMap::get_collision_layer);
+
+ ObjectTypeDB::bind_method(_MD("set_collision_mask","mask"),&TileMap::set_collision_mask);
+ ObjectTypeDB::bind_method(_MD("get_collision_mask"),&TileMap::get_collision_mask);
ObjectTypeDB::bind_method(_MD("set_collision_friction","value"),&TileMap::set_collision_friction);
ObjectTypeDB::bind_method(_MD("get_collision_friction"),&TileMap::get_collision_friction);
@@ -1117,7 +1136,9 @@ void TileMap::_bind_methods() {
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"collision/use_kinematic",PROPERTY_HINT_NONE,""),_SCS("set_collision_use_kinematic"),_SCS("get_collision_use_kinematic"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/friction",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_friction"),_SCS("get_collision_friction"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/bounce",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_bounce"),_SCS("get_collision_bounce"));
- ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_layer_mask"),_SCS("get_collision_layer_mask"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_layer"),_SCS("get_collision_layer"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_mask"),_SCS("get_collision_mask"));
+
ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"tile_data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_tile_data"),_SCS("_get_tile_data"));
ADD_SIGNAL(MethodInfo("settings_changed"));
@@ -1146,6 +1167,7 @@ TileMap::TileMap() {
center_x=false;
center_y=false;
collision_layer=1;
+ collision_mask=1;
friction=1;
bounce=0;
mode=MODE_SQUARE;
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index 233529f018..84ca65da4f 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -146,6 +146,8 @@ private:
float friction;
float bounce;
uint32_t collision_layer;
+ uint32_t collision_mask;
+
TileOrigin tile_origin;
void _fix_cell_transform(Matrix32& xform, const Cell& p_cell, const Vector2 &p_offset, const Size2 &p_sc);
@@ -207,8 +209,11 @@ public:
Rect2 get_item_rect() const;
- void set_collision_layer_mask(uint32_t p_layer);
- uint32_t get_collision_layer_mask() const;
+ void set_collision_layer(uint32_t p_layer);
+ uint32_t get_collision_layer() const;
+
+ void set_collision_mask(uint32_t p_mask);
+ uint32_t get_collision_mask() const;
void set_collision_use_kinematic(bool p_use_kinematic);
bool get_collision_use_kinematic() const;
diff --git a/scene/3d/navigation.cpp b/scene/3d/navigation.cpp
index 8866a65801..48820706dd 100644
--- a/scene/3d/navigation.cpp
+++ b/scene/3d/navigation.cpp
@@ -30,6 +30,7 @@ void Navigation::_navmesh_link(int p_id) {
p.edges.resize(plen);
Vector3 center;
+ float sum=0;
for(int j=0;j<plen;j++) {
@@ -44,8 +45,19 @@ void Navigation::_navmesh_link(int p_id) {
center+=ep;
e.point=_get_point(ep);
p.edges[j]=e;
+
+ if (j>=2) {
+ Vector3 epa = nm.xform.xform(r[indices[j-2]]);
+ Vector3 epb = nm.xform.xform(r[indices[j-1]]);
+
+ sum+=up.dot((epb-epa).cross(ep-epa));
+
+ }
+
}
+ p.clockwise=sum>0;
+
if (!valid) {
nm.polygons.pop_back();
ERR_CONTINUE(!valid);
@@ -399,7 +411,8 @@ Vector<Vector3> Navigation::get_simple_path(const Vector3& p_start, const Vector
left = _get_vertex(p->edges[prev].point);
right = _get_vertex(p->edges[prev_n].point);
- if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5).dot(up) < 0){
+ //if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5).dot(up) < 0){
+ if (p->clockwise) {
SWAP(left,right);
}
}
diff --git a/scene/3d/navigation.h b/scene/3d/navigation.h
index 54cec8f1f7..0f7f67571f 100644
--- a/scene/3d/navigation.h
+++ b/scene/3d/navigation.h
@@ -59,6 +59,8 @@ class Navigation : public Spatial {
float distance;
int prev_edge;
+ bool clockwise;
+
NavMesh *owner;
};