summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/bind/core_bind.cpp31
-rw-r--r--core/bind/core_bind.h2
-rw-r--r--core/image.h8
-rw-r--r--core/math/geometry.cpp131
-rw-r--r--core/math/geometry.h4
-rw-r--r--core/variant_call.cpp25
-rw-r--r--demos/3d/truck_town/car_base.scnbin0 -> 11573 bytes
-rw-r--r--demos/3d/truck_town/cement.texbin0 -> 169836 bytes
-rw-r--r--demos/3d/truck_town/crane.scnbin0 -> 23916 bytes
-rw-r--r--demos/3d/truck_town/engine.cfg7
-rw-r--r--demos/3d/truck_town/follow_camera.gd69
-rw-r--r--demos/3d/truck_town/grass.texbin0 -> 177762 bytes
-rw-r--r--demos/3d/truck_town/trailer_truck.scnbin0 -> 19934 bytes
-rw-r--r--demos/3d/truck_town/truck_scene.scnbin0 -> 1874193 bytes
-rw-r--r--demos/3d/truck_town/trucktown.scnbin0 -> 161749 bytes
-rw-r--r--demos/3d/truck_town/vehicle.gd54
-rw-r--r--drivers/theoraplayer/video_stream_theoraplayer.cpp15
-rw-r--r--platform/winrt/SCsub5
-rw-r--r--platform/winrt/app.cpp162
-rw-r--r--platform/winrt/app.h51
-rw-r--r--platform/winrt/detect.py6
-rw-r--r--platform/winrt/gl_context_egl.cpp151
-rw-r--r--platform/winrt/gl_context_egl.h44
-rw-r--r--platform/winrt/os_winrt.cpp197
-rw-r--r--platform/winrt/os_winrt.h7
-rw-r--r--scene/2d/tile_map.cpp206
-rw-r--r--scene/2d/tile_map.h48
-rw-r--r--scene/2d/y_sort.cpp29
-rw-r--r--scene/2d/y_sort.h17
-rw-r--r--scene/3d/area.cpp15
-rw-r--r--scene/3d/area.h5
-rw-r--r--scene/3d/camera.cpp6
-rw-r--r--scene/3d/collision_object.cpp56
-rw-r--r--scene/3d/collision_object.h9
-rw-r--r--scene/3d/light.cpp2
-rw-r--r--scene/3d/navigation.cpp14
-rw-r--r--scene/3d/navigation.h7
-rw-r--r--scene/3d/navigation_mesh.cpp6
-rw-r--r--scene/3d/physics_joint.cpp25
-rw-r--r--scene/3d/physics_joint.h5
-rw-r--r--scene/3d/vehicle_body.cpp13
-rw-r--r--scene/animation/animation_player.cpp6
-rw-r--r--scene/animation/animation_player.h2
-rw-r--r--scene/audio/event_player.cpp4
-rw-r--r--scene/gui/button_group.cpp3
-rw-r--r--scene/gui/label.cpp5
-rw-r--r--scene/main/viewport.cpp16
-rw-r--r--scene/register_scene_types.cpp2
-rw-r--r--scene/resources/animation.cpp10
-rw-r--r--scene/resources/animation.h4
-rw-r--r--scene/resources/packed_scene.cpp20
-rw-r--r--servers/physics/area_pair_sw.cpp3
-rw-r--r--servers/physics/area_sw.cpp6
-rw-r--r--servers/physics/area_sw.h3
-rw-r--r--servers/physics/collision_object_sw.cpp1
-rw-r--r--servers/physics/collision_object_sw.h6
-rw-r--r--servers/physics/constraint_sw.h6
-rw-r--r--servers/physics/physics_server_sw.cpp31
-rw-r--r--servers/physics/physics_server_sw.h6
-rw-r--r--servers/physics/space_sw.cpp5
-rw-r--r--servers/physics/step_sw.cpp39
-rw-r--r--servers/physics_2d/area_2d_sw.cpp1
-rw-r--r--servers/physics_2d/area_pair_2d_sw.cpp2
-rw-r--r--servers/physics_server.cpp6
-rw-r--r--servers/physics_server.h6
-rw-r--r--servers/register_server_types.cpp1
-rw-r--r--servers/spatial_sound/spatial_sound_server_sw.cpp13
-rw-r--r--servers/spatial_sound_2d/spatial_sound_2d_server_sw.cpp2
-rw-r--r--servers/visual/visual_server_raster.cpp50
-rw-r--r--servers/visual/visual_server_raster.h15
-rw-r--r--servers/visual/visual_server_wrap_mt.h2
-rw-r--r--servers/visual_server.h1
-rw-r--r--tools/collada/collada.cpp4
-rw-r--r--tools/editor/io_plugins/editor_font_import_plugin.cpp16
-rw-r--r--tools/editor/io_plugins/editor_import_collada.cpp6
-rw-r--r--tools/editor/io_plugins/editor_scene_import_plugin.cpp57
-rw-r--r--tools/editor/io_plugins/editor_scene_import_plugin.h1
-rw-r--r--tools/editor/plugins/sample_player_editor_plugin.cpp5
-rw-r--r--tools/editor/plugins/spatial_editor_plugin.cpp31
-rw-r--r--tools/editor/plugins/spatial_editor_plugin.h5
-rw-r--r--tools/editor/plugins/tile_map_editor_plugin.cpp144
-rw-r--r--tools/editor/plugins/tile_set_editor_plugin.cpp5
-rw-r--r--tools/export/blender25/io_scene_dae/__init__.py5
-rw-r--r--tools/export/blender25/io_scene_dae/export_dae.py10
84 files changed, 1657 insertions, 341 deletions
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index 570ed33a5a..944bc531ff 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -856,6 +856,36 @@ Vector<int> _Geometry::triangulate_polygon(const Vector<Vector2>& p_polygon) {
return Geometry::triangulate_polygon(p_polygon);
}
+Dictionary _Geometry::make_atlas(const Vector<Size2>& p_rects) {
+
+ Dictionary ret;
+
+ Vector<Size2i> rects;
+ for (int i=0; i<p_rects.size(); i++) {
+
+ rects.push_back(p_rects[i]);
+ };
+
+ Vector<Point2i> result;
+ Size2i size;
+
+ Geometry::make_atlas(rects, result, size);
+
+ Size2 r_size = size;
+ Vector<Point2> r_result;
+ for (int i=0; i<result.size(); i++) {
+
+ r_result.push_back(result[i]);
+ };
+
+
+ ret["points"] = r_result;
+ ret["size"] = r_size;
+
+ return ret;
+};
+
+
void _Geometry::_bind_methods() {
@@ -878,6 +908,7 @@ void _Geometry::_bind_methods() {
ObjectTypeDB::bind_method(_MD("triangulate_polygon","polygon"),&_Geometry::triangulate_polygon);
+ ObjectTypeDB::bind_method(_MD("make_atlas","sizes"),&_Geometry::make_atlas);
}
diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h
index 0ef70e4b13..298345bfd9 100644
--- a/core/bind/core_bind.h
+++ b/core/bind/core_bind.h
@@ -236,6 +236,8 @@ public:
Vector<int> triangulate_polygon(const Vector<Vector2>& p_polygon);
+ Dictionary make_atlas(const Vector<Size2>& p_rects);
+
_Geometry();
};
diff --git a/core/image.h b/core/image.h
index 7a6ee1e4b0..31a815c587 100644
--- a/core/image.h
+++ b/core/image.h
@@ -216,6 +216,14 @@ public:
* Convert the image to another format, as close as it can be done.
*/
void convert( Format p_new_format );
+
+ Image converted(int p_new_format) {
+ ERR_FAIL_INDEX_V(p_new_format, FORMAT_MAX, Image());
+
+ Image ret = *this;
+ ret.convert((Format)p_new_format);
+ return ret;
+ };
/**
* Get the current image format.
diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp
index cb76b9ed0f..2d525dd1ce 100644
--- a/core/math/geometry.cpp
+++ b/core/math/geometry.cpp
@@ -1004,3 +1004,134 @@ DVector<Plane> Geometry::build_capsule_planes(float p_radius, float p_height, in
}
+
+struct _AtlasWorkRect {
+
+ Size2i s;
+ Point2i p;
+ int idx;
+ _FORCE_INLINE_ bool operator<(const _AtlasWorkRect& p_r) const { return s.width > p_r.s.width; };
+};
+
+struct _AtlasWorkRectResult {
+
+ Vector<_AtlasWorkRect> result;
+ int max_w;
+ int max_h;
+};
+
+void Geometry::make_atlas(const Vector<Size2i>& p_rects,Vector<Point2i>& r_result, Size2i& r_size) {
+
+ //super simple, almost brute force scanline stacking fitter
+ //it's pretty basic for now, but it tries to make sure that the aspect ratio of the
+ //resulting atlas is somehow square. This is necesary because video cards have limits
+ //on texture size (usually 2048 or 4096), so the more square a texture, the more chances
+ //it will work in every hardware.
+ // for example, it will prioritize a 1024x1024 atlas (works everywhere) instead of a
+ // 256x8192 atlas (won't work anywhere).
+
+ ERR_FAIL_COND(p_rects.size()==0);
+
+ Vector<_AtlasWorkRect> wrects;
+ wrects.resize(p_rects.size());
+ for(int i=0;i<p_rects.size();i++) {
+ wrects[i].s=p_rects[i];
+ wrects[i].idx=i;
+ }
+ wrects.sort();
+ int widest = wrects[0].s.width;
+
+ Vector<_AtlasWorkRectResult> results;
+
+ for(int i=0;i<=12;i++) {
+
+ int w = 1<<i;
+ int max_h=0;
+ int max_w=0;
+ if ( w < widest )
+ continue;
+
+ Vector<int> hmax;
+ hmax.resize(w);
+ for(int j=0;j<w;j++)
+ hmax[j]=0;
+
+ //place them
+ int ofs=0;
+ int limit_h=0;
+ for(int j=0;j<wrects.size();j++) {
+
+
+ if (ofs+wrects[j].s.width > w) {
+
+ ofs=0;
+ }
+
+ int from_y=0;
+ for(int k=0;k<wrects[j].s.width;k++) {
+
+ if (hmax[ofs+k] > from_y)
+ from_y=hmax[ofs+k];
+ }
+
+ wrects[j].p.x=ofs;
+ wrects[j].p.y=from_y;
+ int end_h = from_y+wrects[j].s.height;
+ int end_w = ofs+wrects[j].s.width;
+ if (ofs==0)
+ limit_h=end_h;
+
+ for(int k=0;k<wrects[j].s.width;k++) {
+
+ hmax[ofs+k]=end_h;
+ }
+
+ if (end_h > max_h)
+ max_h=end_h;
+
+ if (end_w > max_w)
+ max_w=end_w;
+
+ if (ofs==0 || end_h>limit_h ) //while h limit not reched, keep stacking
+ ofs+=wrects[j].s.width;
+
+ }
+
+ _AtlasWorkRectResult result;
+ result.result=wrects;
+ result.max_h=max_h;
+ result.max_w=max_w;
+ results.push_back(result);
+
+ }
+
+ //find the result with the best aspect ratio
+
+ int best=-1;
+ float best_aspect=1e20;
+
+ for(int i=0;i<results.size();i++) {
+
+ float h = nearest_power_of_2(results[i].max_h);
+ float w = nearest_power_of_2(results[i].max_w);
+ float aspect = h>w ? h/w : w/h;
+ if (aspect < best_aspect) {
+ best=i;
+ best_aspect=aspect;
+ }
+ }
+
+ r_result.resize(p_rects.size());
+
+ for(int i=0;i<p_rects.size();i++) {
+
+ r_result[ results[best].result[i].idx ]=results[best].result[i].p;
+ }
+
+ r_size=Size2(results[best].max_w,results[best].max_h );
+
+}
+
+
+
+
diff --git a/core/math/geometry.h b/core/math/geometry.h
index 5b21c25bec..48713fb91b 100644
--- a/core/math/geometry.h
+++ b/core/math/geometry.h
@@ -826,7 +826,9 @@ public:
static DVector<Plane> build_box_planes(const Vector3& p_extents);
static DVector<Plane> build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis=Vector3::AXIS_Z);
static DVector<Plane> build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis=Vector3::AXIS_Z);
-
+
+ static void make_atlas(const Vector<Size2i>& p_rects,Vector<Point2i>& r_result, Size2i& r_size);
+
};
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index e0ae7e2114..bd731abeaf 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -515,7 +515,7 @@ static void _call_##m_type##m_method(Variant& r_ret,Variant& p_self,const Varian
#define VCALL_PTR0R(m_type,m_method)\
static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Variant** p_args) { r_ret=reinterpret_cast<m_type*>(p_self._data._ptr)->m_method(); }
#define VCALL_PTR1(m_type,m_method)\
-static void _call_##m_type##m_method(Variant& r_ret,Variant& p_self,const Variant** p_args) { reinterpret_cast<m_type*>(p_self._data._ptr)->m_method(*p_args[0]); }
+static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Variant** p_args) { reinterpret_cast<m_type*>(p_self._data._ptr)->m_method(*p_args[0]); }
#define VCALL_PTR1R(m_type,m_method)\
static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Variant** p_args) { r_ret=reinterpret_cast<m_type*>(p_self._data._ptr)->m_method(*p_args[0]); }
#define VCALL_PTR2(m_type,m_method)\
@@ -551,6 +551,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var
VCALL_PTR3R(Image, resized);
VCALL_PTR0R(Image, get_data);
VCALL_PTR3(Image, blit_rect);
+ VCALL_PTR1R(Image, converted);
VCALL_PTR0R( AABB, get_area );
VCALL_PTR0R( AABB, has_no_area );
@@ -605,6 +606,25 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var
}
}
+ static void _call_Matrix32_basis_xform(Variant& r_ret,Variant& p_self,const Variant** p_args) {
+
+ switch(p_args[0]->type) {
+
+ case Variant::VECTOR2: r_ret=reinterpret_cast<Matrix32*>(p_self._data._ptr)->basis_xform( p_args[0]->operator Vector2()); return;
+ default: r_ret=Variant();
+ }
+
+ }
+
+ static void _call_Matrix32_basis_xform_inv(Variant& r_ret,Variant& p_self,const Variant** p_args) {
+
+ switch(p_args[0]->type) {
+
+ case Variant::VECTOR2: r_ret=reinterpret_cast<Matrix32*>(p_self._data._ptr)->basis_xform_inv( p_args[0]->operator Vector2()); return;
+ default: r_ret=Variant();
+ }
+ }
+
VCALL_PTR0R( Matrix3, inverse );
VCALL_PTR0R( Matrix3, transposed );
@@ -1313,6 +1333,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl
ADDFUNC3(IMAGE, IMAGE, Image, resized, INT, "x", INT, "y", INT, "interpolation", varray(((int)Image::INTERPOLATE_BILINEAR)));
ADDFUNC0(IMAGE, RAW_ARRAY, Image, get_data, varray());
ADDFUNC3(IMAGE, NIL, Image, blit_rect, IMAGE, "src", RECT2, "src_rect", VECTOR2, "dest", varray(0));
+ ADDFUNC1(IMAGE, IMAGE, Image, converted, INT, "format", varray(0));
ADDFUNC0(_RID,INT,RID,get_id,varray());
@@ -1430,6 +1451,8 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl
ADDFUNC1(MATRIX32,MATRIX32,Matrix32,translated,VECTOR2,"offset",varray());
ADDFUNC1(MATRIX32,MATRIX32,Matrix32,xform,NIL,"v",varray());
ADDFUNC1(MATRIX32,MATRIX32,Matrix32,xform_inv,NIL,"v",varray());
+ ADDFUNC1(MATRIX32,MATRIX32,Matrix32,basis_xform,NIL,"v",varray());
+ ADDFUNC1(MATRIX32,MATRIX32,Matrix32,basis_xform_inv,NIL,"v",varray());
ADDFUNC2(MATRIX32,MATRIX32,Matrix32,interpolate_with,MATRIX32,"m",REAL,"c",varray());
ADDFUNC0(MATRIX3,MATRIX3,Matrix3,inverse,varray());
diff --git a/demos/3d/truck_town/car_base.scn b/demos/3d/truck_town/car_base.scn
new file mode 100644
index 0000000000..d62c8dcb29
--- /dev/null
+++ b/demos/3d/truck_town/car_base.scn
Binary files differ
diff --git a/demos/3d/truck_town/cement.tex b/demos/3d/truck_town/cement.tex
new file mode 100644
index 0000000000..a80cde6464
--- /dev/null
+++ b/demos/3d/truck_town/cement.tex
Binary files differ
diff --git a/demos/3d/truck_town/crane.scn b/demos/3d/truck_town/crane.scn
new file mode 100644
index 0000000000..080bd8ea17
--- /dev/null
+++ b/demos/3d/truck_town/crane.scn
Binary files differ
diff --git a/demos/3d/truck_town/engine.cfg b/demos/3d/truck_town/engine.cfg
new file mode 100644
index 0000000000..8703a251d1
--- /dev/null
+++ b/demos/3d/truck_town/engine.cfg
@@ -0,0 +1,7 @@
+[application]
+
+main_scene="res://truck_scene.scn"
+
+[rasterizer]
+
+shadow_filter=3
diff --git a/demos/3d/truck_town/follow_camera.gd b/demos/3d/truck_town/follow_camera.gd
new file mode 100644
index 0000000000..cf7172d7bb
--- /dev/null
+++ b/demos/3d/truck_town/follow_camera.gd
@@ -0,0 +1,69 @@
+
+extends Camera
+
+# member variables here, example:
+# var a=2
+# var b="textvar"
+
+var collision_exception=[]
+export var min_distance=0.5
+export var max_distance=4.0
+export var angle_v_adjust=0.0
+export var autoturn_ray_aperture=25
+export var autoturn_speed=50
+var max_height = 2.0
+var min_height = 0
+
+func _fixed_process(dt):
+ var target = get_parent().get_global_transform().origin
+ var pos = get_global_transform().origin
+ var up = Vector3(0,1,0)
+
+ var delta = pos - target
+
+ #regular delta follow
+
+ #check ranges
+
+ if (delta.length() < min_distance):
+ delta = delta.normalized() * min_distance
+ elif (delta.length() > max_distance):
+ delta = delta.normalized() * max_distance
+
+ #check upper and lower height
+ if ( delta.y > max_height):
+ delta.y = max_height
+ if ( delta.y < min_height):
+ delta.y = min_height
+
+ pos = target + delta
+
+ look_at_from_pos(pos,target,up)
+
+ #turn a little up or down
+ var t = get_transform()
+ t.basis = Matrix3(t.basis[0],deg2rad(angle_v_adjust)) * t.basis
+ set_transform(t)
+
+
+
+func _ready():
+
+#find collision exceptions for ray
+ var node = self
+ while(node):
+ if (node extends RigidBody):
+ collision_exception.append(node.get_rid())
+ break
+ else:
+ node=node.get_parent()
+ # Initalization here
+ set_fixed_process(true)
+ #this detaches the camera transform from the parent spatial node
+ set_as_toplevel(true)
+
+
+
+
+
+
diff --git a/demos/3d/truck_town/grass.tex b/demos/3d/truck_town/grass.tex
new file mode 100644
index 0000000000..c28d060697
--- /dev/null
+++ b/demos/3d/truck_town/grass.tex
Binary files differ
diff --git a/demos/3d/truck_town/trailer_truck.scn b/demos/3d/truck_town/trailer_truck.scn
new file mode 100644
index 0000000000..0131e9e3a2
--- /dev/null
+++ b/demos/3d/truck_town/trailer_truck.scn
Binary files differ
diff --git a/demos/3d/truck_town/truck_scene.scn b/demos/3d/truck_town/truck_scene.scn
new file mode 100644
index 0000000000..8db74a2f7f
--- /dev/null
+++ b/demos/3d/truck_town/truck_scene.scn
Binary files differ
diff --git a/demos/3d/truck_town/trucktown.scn b/demos/3d/truck_town/trucktown.scn
new file mode 100644
index 0000000000..57a84315ee
--- /dev/null
+++ b/demos/3d/truck_town/trucktown.scn
Binary files differ
diff --git a/demos/3d/truck_town/vehicle.gd b/demos/3d/truck_town/vehicle.gd
new file mode 100644
index 0000000000..1aa7f0faa2
--- /dev/null
+++ b/demos/3d/truck_town/vehicle.gd
@@ -0,0 +1,54 @@
+
+extends VehicleBody
+
+# member variables here, example:
+# var a=2
+# var b="textvar"
+
+
+const STEER_SPEED=1
+const STEER_LIMIT=0.4
+
+var steer_angle=0
+var steer_target=0
+
+
+export var engine_force=40
+
+func _fixed_process(delta):
+
+
+ if (Input.is_action_pressed("ui_left")):
+ steer_target=-STEER_LIMIT
+ elif (Input.is_action_pressed("ui_right")):
+ steer_target=STEER_LIMIT
+ else:
+ steer_target=0
+
+ if (Input.is_action_pressed("ui_up")):
+ set_engine_force(engine_force)
+ else:
+ set_engine_force(0)
+
+ if (Input.is_action_pressed("ui_down")):
+ set_brake(1)
+ else:
+ set_brake(0.0)
+
+
+ if (steer_target < steer_angle):
+ steer_angle -= STEER_SPEED*delta
+ if (steer_target > steer_angle):
+ steer_angle=steer_target
+ elif (steer_target > steer_angle):
+ steer_angle += STEER_SPEED*delta
+ if (steer_target < steer_angle):
+ steer_angle=steer_target
+
+ set_steering(steer_angle)
+func _ready():
+ # Initalization here
+ set_fixed_process(true)
+ pass
+
+
diff --git a/drivers/theoraplayer/video_stream_theoraplayer.cpp b/drivers/theoraplayer/video_stream_theoraplayer.cpp
index 12ef5de88f..b2ff8062cc 100644
--- a/drivers/theoraplayer/video_stream_theoraplayer.cpp
+++ b/drivers/theoraplayer/video_stream_theoraplayer.cpp
@@ -86,12 +86,18 @@ public:
return fa->get_pos();
};
- TPDataFA(String p_path) {
+ TPDataFA(const String& p_path) {
fa = FileAccess::open(p_path, FileAccess::READ);
data_name = "File: " + p_path;
};
+ TPDataFA(FileAccess* p_fa, const String& p_path) {
+
+ fa = p_fa;
+ data_name = "File: " + p_path;
+ };
+
~TPDataFA() {
if (fa)
@@ -366,6 +372,10 @@ void VideoStreamTheoraplayer::update(float p_time) {
void VideoStreamTheoraplayer::set_file(const String& p_file) {
+ FileAccess* f = FileAccess::open(p_file, FileAccess::READ);
+ if (!f || !f->is_open())
+ return;
+
if (!audio_factory) {
audio_factory = memnew(TPAudioGodotFactory);
};
@@ -377,10 +387,11 @@ void VideoStreamTheoraplayer::set_file(const String& p_file) {
std::string file = p_file.replace("res://", "").utf8().get_data();
clip = mgr->createVideoClip(file);
+ memdelete(f);
} else {
- TheoraDataSource* ds = memnew(TPDataFA(p_file));
+ TheoraDataSource* ds = memnew(TPDataFA(f, p_file));
try {
clip = mgr->createVideoClip(ds);
diff --git a/platform/winrt/SCsub b/platform/winrt/SCsub
index c83f4fab32..07e2ba81a6 100644
--- a/platform/winrt/SCsub
+++ b/platform/winrt/SCsub
@@ -3,6 +3,9 @@ Import('env')
files = [
'thread_winrt.cpp',
# '#platform/windows/stream_peer_winsock.cpp',
+ 'gl_context_egl.cpp',
+ 'app.cpp',
+ 'os_winrt.cpp',
]
-env.Program('#bin/godot_rt.exe', files)
+env.Program('#bin/godot_rt', files)
diff --git a/platform/winrt/app.cpp b/platform/winrt/app.cpp
new file mode 100644
index 0000000000..e3213d574a
--- /dev/null
+++ b/platform/winrt/app.cpp
@@ -0,0 +1,162 @@
+//
+// This file demonstrates how to initialize EGL in a Windows Store app, using ICoreWindow.
+//
+
+#include "app.h"
+
+#include "main/main.h"
+
+using namespace Windows::ApplicationModel::Core;
+using namespace Windows::ApplicationModel::Activation;
+using namespace Windows::UI::Core;
+using namespace Windows::UI::Input;
+using namespace Windows::Foundation;
+using namespace Windows::Graphics::Display;
+using namespace Microsoft::WRL;
+using namespace Platform;
+
+using namespace $ext_safeprojectname$;
+
+// Helper to convert a length in device-independent pixels (DIPs) to a length in physical pixels.
+inline float ConvertDipsToPixels(float dips, float dpi)
+{
+ static const float dipsPerInch = 96.0f;
+ return floor(dips * dpi / dipsPerInch + 0.5f); // Round to nearest integer.
+}
+
+// Implementation of the IFrameworkViewSource interface, necessary to run our app.
+ref class HelloTriangleApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
+{
+public:
+ virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView()
+ {
+ return ref new App();
+ }
+};
+
+// The main function creates an IFrameworkViewSource for our app, and runs the app.
+[Platform::MTAThread]
+int main(Platform::Array<Platform::String^>^)
+{
+ auto helloTriangleApplicationSource = ref new HelloTriangleApplicationSource();
+ CoreApplication::Run(helloTriangleApplicationSource);
+ return 0;
+}
+
+App::App() :
+ mWindowClosed(false),
+ mWindowVisible(true),
+ mWindowWidth(0),
+ mWindowHeight(0),
+ mEglDisplay(EGL_NO_DISPLAY),
+ mEglContext(EGL_NO_CONTEXT),
+ mEglSurface(EGL_NO_SURFACE)
+{
+}
+
+// The first method called when the IFrameworkView is being created.
+void App::Initialize(CoreApplicationView^ applicationView)
+{
+ // Register event handlers for app lifecycle. This example includes Activated, so that we
+ // can make the CoreWindow active and start rendering on the window.
+ applicationView->Activated +=
+ ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &App::OnActivated);
+
+ // Logic for other event handlers could go here.
+ // Information about the Suspending and Resuming event handlers can be found here:
+ // http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh994930.aspx
+
+ os = new OSWinrt;
+}
+
+// Called when the CoreWindow object is created (or re-created).
+void App::SetWindow(CoreWindow^ window)
+{
+ window->VisibilityChanged +=
+ ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &App::OnVisibilityChanged);
+
+ window->Closed +=
+ ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &App::OnWindowClosed);
+
+ window->SizeChanged +=
+ ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &App::OnWindowSizeChanged);
+
+#if !(WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+ // Disable all pointer visual feedback for better performance when touching.
+ // This is not supported on Windows Phone applications.
+ auto pointerVisualizationSettings = PointerVisualizationSettings::GetForCurrentView();
+ pointerVisualizationSettings->IsContactFeedbackEnabled = false;
+ pointerVisualizationSettings->IsBarrelButtonFeedbackEnabled = false;
+#endif
+
+ // The CoreWindow has been created, so EGL can be initialized.
+ ContextEGL* context = memnew(ContextEGL(window));
+ os->set_gl_context(context);
+ UpdateWindowSize(Size(window->Bounds.Width, window->Bounds.Height));
+}
+
+// Initializes scene resources
+void App::Load(Platform::String^ entryPoint)
+{
+ char** args = {NULL};
+ Main::setup("winrt", 0, args);
+}
+
+// This method is called after the window becomes active.
+void App::Run()
+{
+
+ if (Main::start())
+ os->run();
+}
+
+// Terminate events do not cause Uninitialize to be called. It will be called if your IFrameworkView
+// class is torn down while the app is in the foreground.
+void App::Uninitialize()
+{
+ Main::cleanup();
+ delete os;
+}
+
+// Application lifecycle event handler.
+void App::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
+{
+ // Run() won't start until the CoreWindow is activated.
+ CoreWindow::GetForCurrentThread()->Activate();
+}
+
+// Window event handlers.
+void App::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
+{
+ mWindowVisible = args->Visible;
+}
+
+void App::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
+{
+ mWindowClosed = true;
+}
+
+void App::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
+{
+#if (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP)
+ // On Windows 8.1, apps are resized when they are snapped alongside other apps, or when the device is rotated.
+ // The default framebuffer will be automatically resized when either of these occur.
+ // In particular, on a 90 degree rotation, the default framebuffer's width and height will switch.
+ UpdateWindowSize(args->Size);
+#else if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+ // On Windows Phone 8.1, the window size changes when the device is rotated.
+ // The default framebuffer will not be automatically resized when this occurs.
+ // It is therefore up to the app to handle rotation-specific logic in its rendering code.
+#endif
+}
+
+void App::UpdateWindowSize(Size size)
+{
+ /*
+ DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView();
+ Size pixelSize(ConvertDipsToPixels(size.Width, currentDisplayInformation->LogicalDpi), ConvertDipsToPixels(size.Height, currentDisplayInformation->LogicalDpi));
+
+ mWindowWidth = static_cast<GLsizei>(pixelSize.Width);
+ mWindowHeight = static_cast<GLsizei>(pixelSize.Height);
+ */
+}
diff --git a/platform/winrt/app.h b/platform/winrt/app.h
new file mode 100644
index 0000000000..a67b936cdf
--- /dev/null
+++ b/platform/winrt/app.h
@@ -0,0 +1,51 @@
+#pragma once
+
+#include <string>
+
+#include <wrl.h>
+
+#include "os_winrt.h"
+#include "GLES2/gl2.h"
+
+namespace $ext_safeprojectname$
+{
+ ref class App sealed : public Windows::ApplicationModel::Core::IFrameworkView
+ {
+ public:
+ App();
+
+ // IFrameworkView Methods.
+ virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView);
+ virtual void SetWindow(Windows::UI::Core::CoreWindow^ window);
+ virtual void Load(Platform::String^ entryPoint);
+ virtual void Run();
+ virtual void Uninitialize();
+
+ private:
+ void RecreateRenderer();
+
+ // Application lifecycle event handlers.
+ void OnActivated(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs^ args);
+
+ // Window event handlers.
+ void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args);
+ void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args);
+ void OnWindowClosed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CoreWindowEventArgs^ args);
+
+ void UpdateWindowSize(Windows::Foundation::Size size);
+ void InitializeEGL(Windows::UI::Core::CoreWindow^ window);
+ void CleanupEGL();
+
+ bool mWindowClosed;
+ bool mWindowVisible;
+ GLsizei mWindowWidth;
+ GLsizei mWindowHeight;
+
+ EGLDisplay mEglDisplay;
+ EGLContext mEglContext;
+ EGLSurface mEglSurface;
+
+ OSWinrt* os;
+ };
+
+}
diff --git a/platform/winrt/detect.py b/platform/winrt/detect.py
index d09688b71c..00913b0ade 100644
--- a/platform/winrt/detect.py
+++ b/platform/winrt/detect.py
@@ -57,13 +57,13 @@ def configure(env):
env.Append(CCFLAGS=['-g','-pg'])
env.Append(LINKFLAGS=['-pg'])
- env.Append(CCFLAGS=['/Gd','/GR','/nologo', '/ZW', '/EHsc'])
- env.Append(CXXFLAGS=['/TP'])
+ env.Append(CCFLAGS=['/Gd','/GR','/nologo', '/EHsc'])
+ env.Append(CXXFLAGS=['/TP', '/ZW'])
env.Append(CPPFLAGS=['/DMSVC', '/GR', ])
#env.Append(CCFLAGS=['/I'+os.getenv("WindowsSdkDir")+"/Include"])
env.Append(CCFLAGS=['/DWINRT_ENABLED'])
env.Append(CCFLAGS=['/DWINDOWS_ENABLED'])
- env.Append(CCFLAGS=['/DWINAPI_FAMILY=WINAPI_FAMILY_APP'])
+ env.Append(CCFLAGS=['/DWINAPI_FAMILY=WINAPI_FAMILY_APP', '/D_WIN32_WINNT=0x0603', '/DNTDDI_VERSION=0x06030000'])
env.Append(CCFLAGS=['/DRTAUDIO_ENABLED'])
#env.Append(CCFLAGS=['/DWIN32'])
env.Append(CCFLAGS=['/DTYPED_METHOD_BIND'])
diff --git a/platform/winrt/gl_context_egl.cpp b/platform/winrt/gl_context_egl.cpp
new file mode 100644
index 0000000000..ca592c5d19
--- /dev/null
+++ b/platform/winrt/gl_context_egl.cpp
@@ -0,0 +1,151 @@
+#include "gl_context_egl.h"
+
+using namespace Platform;
+
+void ContextEGL::release_current() {
+
+ eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, mEglContext);
+};
+
+void ContextEGL::make_current() {
+
+ eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext);
+};
+
+int ContextEGL::get_window_width() {
+
+ return width;
+};
+
+int ContextEGL::get_window_height() {
+
+ return height;
+};
+
+void ContextEGL::swap_buffers() {
+
+ if (eglSwapBuffers(mEglDisplay, mEglSurface) != EGL_TRUE)
+ {
+ cleanup();
+
+ window = CoreWindow::GetForCurrentThread();
+ initialize();
+
+ // tell rasterizer to reload textures and stuff?
+ }
+};
+
+Error ContextEGL::initialize() {
+
+ EGLint configAttribList[] = {
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_DEPTH_SIZE, 8,
+ EGL_STENCIL_SIZE, 8,
+ EGL_SAMPLE_BUFFERS, 0,
+ EGL_NONE
+ };
+
+ EGLint surfaceAttribList[] = {
+ EGL_NONE, EGL_NONE
+ };
+
+ EGLint numConfigs = 0;
+ EGLint majorVersion = 1;
+ EGLint minorVersion = 0;
+ EGLDisplay display = EGL_NO_DISPLAY;
+ EGLContext context = EGL_NO_CONTEXT;
+ EGLSurface surface = EGL_NO_SURFACE;
+ EGLConfig config = nullptr;
+ EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE };
+
+ try {
+
+ display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (display == EGL_NO_DISPLAY)
+ {
+ throw Exception::CreateException(E_FAIL, L"Failed to get default EGL display");
+ }
+
+ if (eglInitialize(display, &majorVersion, &minorVersion) == EGL_FALSE)
+ {
+ throw Exception::CreateException(E_FAIL, L"Failed to initialize EGL");
+ }
+
+ if (eglGetConfigs(display, NULL, 0, &numConfigs) == EGL_FALSE)
+ {
+ throw Exception::CreateException(E_FAIL, L"Failed to get EGLConfig count");
+ }
+
+ if (eglChooseConfig(display, configAttribList, &config, 1, &numConfigs) == EGL_FALSE)
+ {
+ throw Exception::CreateException(E_FAIL, L"Failed to choose first EGLConfig count");
+ }
+
+ surface = eglCreateWindowSurface(display, config, reinterpret_cast<IInspectable*>(window), surfaceAttribList);
+ if (surface == EGL_NO_SURFACE)
+ {
+ throw Exception::CreateException(E_FAIL, L"Failed to create EGL fullscreen surface");
+ }
+
+ context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
+ if (context == EGL_NO_CONTEXT)
+ {
+ throw Exception::CreateException(E_FAIL, L"Failed to create EGL context");
+ }
+
+ if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE)
+ {
+ throw Exception::CreateException(E_FAIL, L"Failed to make fullscreen EGLSurface current");
+ }
+ } catch (...) {
+ return FAILED;
+ };
+
+ mEglDisplay = display;
+ mEglSurface = surface;
+ mEglContext = context;
+
+ eglQuerySurface(display,surface,EGL_WIDTH,&width);
+ eglQuerySurface(display,surface,EGL_HEIGHT,&height);
+
+ return OK;
+};
+
+void ContextEGL::cleanup() {
+
+ if (mEglDisplay != EGL_NO_DISPLAY && mEglSurface != EGL_NO_SURFACE)
+ {
+ eglDestroySurface(mEglDisplay, mEglSurface);
+ mEglSurface = EGL_NO_SURFACE;
+ }
+
+ if (mEglDisplay != EGL_NO_DISPLAY && mEglContext != EGL_NO_CONTEXT)
+ {
+ eglDestroyContext(mEglDisplay, mEglContext);
+ mEglContext = EGL_NO_CONTEXT;
+ }
+
+ if (mEglDisplay != EGL_NO_DISPLAY)
+ {
+ eglTerminate(mEglDisplay);
+ mEglDisplay = EGL_NO_DISPLAY;
+ }
+};
+
+ContextEGL::ContextEGL(CoreWindow^ p_window) :
+ mEglDisplay(EGL_NO_DISPLAY),
+ mEglContext(EGL_NO_CONTEXT),
+ mEglSurface(EGL_NO_SURFACE)
+ {
+
+ window = p_window;
+};
+
+ContextEGL::~ContextEGL() {
+
+ cleanup();
+};
+
diff --git a/platform/winrt/gl_context_egl.h b/platform/winrt/gl_context_egl.h
new file mode 100644
index 0000000000..56bf654ee5
--- /dev/null
+++ b/platform/winrt/gl_context_egl.h
@@ -0,0 +1,44 @@
+#ifndef CONTEXT_EGL_H
+#define CONTEXT_EGL_H
+
+#include <wrl.h>
+
+#include "os/os.h"
+#include "EGL/egl.h"
+#include "error_list.h"
+#include "drivers/gl_context/context_gl.h"
+
+using namespace Windows::UI::Core;
+
+class ContextEGL : public ContextGL {
+
+ CoreWindow^ window;
+
+ EGLDisplay mEglDisplay;
+ EGLContext mEglContext;
+ EGLSurface mEglSurface;
+
+ EGLint width;
+ EGLint height;
+
+public:
+
+ virtual void release_current();
+
+ virtual void make_current();
+
+ virtual int get_window_width();
+ virtual int get_window_height();
+ virtual void swap_buffers();
+
+ virtual Error initialize();
+
+ void cleanup();
+
+ ContextEGL(CoreWindow^ p_window);
+ ~ContextEGL();
+
+};
+
+#endif
+
diff --git a/platform/winrt/os_winrt.cpp b/platform/winrt/os_winrt.cpp
index 16a74c877c..99c4ad968e 100644
--- a/platform/winrt/os_winrt.cpp
+++ b/platform/winrt/os_winrt.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* os_windows.cpp */
+/* os_winrt.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,12 +28,12 @@
/*************************************************************************/
#include "drivers/gles2/rasterizer_gles2.h"
#include "drivers/gles1/rasterizer_gles1.h"
-#include "os_windows.h"
+#include "os_winrt.h"
#include "drivers/nedmalloc/memory_pool_static_nedmalloc.h"
#include "drivers/unix/memory_pool_static_malloc.h"
#include "os/memory_pool_dynamic_static.h"
-#include "drivers/windows/thread_windows.h"
-#include "drivers/windows/semaphore_windows.h"
+#include "thread_winrt.h"
+//#include "drivers/windows/semaphore_windows.h"
#include "drivers/windows/mutex_windows.h"
#include "main/main.h"
#include "drivers/windows/file_access_windows.h"
@@ -44,14 +44,22 @@
#include "servers/audio/audio_server_sw.h"
#include "servers/visual/visual_server_wrap_mt.h"
-#include "tcp_server_winsock.h"
-#include "stream_peer_winsock.h"
#include "os/pc_joystick_map.h"
-#include "lang_table.h"
#include "os/memory_pool_dynamic_prealloc.h"
#include "globals.h"
#include "io/marshalls.h"
+#include <wrl.h>
+
+using namespace Windows::ApplicationModel::Core;
+using namespace Windows::ApplicationModel::Activation;
+using namespace Windows::UI::Core;
+using namespace Windows::UI::Input;
+using namespace Windows::Foundation;
+using namespace Windows::Graphics::Display;
+using namespace Microsoft::WRL;
+
+
int OSWinrt::get_video_driver_count() const {
return 2;
@@ -129,59 +137,18 @@ bool OSWinrt::can_draw() const {
};
-void OSWinrt::_touch_event(int idx, UINT uMsg, WPARAM wParam, LPARAM lParam) {
-
- InputEvent event;
- event.type = InputEvent::SCREEN_TOUCH;
- event.ID=++last_id;
- event.screen_touch.index = idx;
+void OSWinrt::set_gl_context(ContextEGL* p_context) {
- switch (uMsg) {
- case WM_LBUTTONDOWN:
- case WM_MBUTTONDOWN:
- case WM_RBUTTONDOWN: {
-
- event.screen_touch.pressed = true;
- } break;
-
- case WM_LBUTTONUP:
- case WM_MBUTTONUP:
- case WM_RBUTTONUP: {
- event.screen_touch.pressed = false;
- } break;
- };
-
- event.screen_touch.x=GET_X_LPARAM(lParam);
- event.screen_touch.y=GET_Y_LPARAM(lParam);
-
- if (main_loop) {
- input->parse_input_event(event);
- }
+ gl_context = p_context;
};
-void OSWinrt::_drag_event(int idx,UINT uMsg, WPARAM wParam, LPARAM lParam) {
-
- InputEvent event;
- event.type = InputEvent::SCREEN_DRAG;
- event.ID=++last_id;
- event.screen_drag.index = idx;
-
- event.screen_drag.x=GET_X_LPARAM(lParam);
- event.screen_drag.y=GET_Y_LPARAM(lParam);
-
- if (main_loop)
- input->parse_input_event(event);
-};
-
-
void OSWinrt::initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver) {
-
-
main_loop=NULL;
outside=true;
-
+ gl_context->initialize();
+
visual_server = memnew( VisualServerRaster(rasterizer) );
if (get_render_thread_mode()!=RENDER_THREAD_UNSAFE) {
@@ -222,6 +189,7 @@ void OSWinrt::initialize(const VideoMode& p_desired,int p_video_driver,int p_aud
void OSWinrt::set_clipboard(const String& p_text) {
+ /*
if (!OpenClipboard(hWnd)) {
ERR_EXPLAIN("Unable to open clipboard.");
ERR_FAIL();
@@ -255,10 +223,12 @@ void OSWinrt::set_clipboard(const String& p_text) {
SetClipboardData(CF_TEXT, mem);
CloseClipboard();
+ */
};
String OSWinrt::get_clipboard() const {
+ /*
String ret;
if (!OpenClipboard(hWnd)) {
ERR_EXPLAIN("Unable to open clipboard.");
@@ -295,6 +265,8 @@ String OSWinrt::get_clipboard() const {
CloseClipboard();
return ret;
+ */
+ return "";
};
@@ -327,10 +299,6 @@ void OSWinrt::finalize() {
if (rasterizer)
memdelete(rasterizer);
- if (user_proc) {
- SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)user_proc);
- };
-
spatial_sound_server->finish();
memdelete(spatial_sound_server);
spatial_sound_2d_server->finish();
@@ -355,16 +323,11 @@ void OSWinrt::finalize() {
}
void OSWinrt::finalize_core() {
- memdelete(process_map);
-
if (mempool_dynamic)
memdelete( mempool_dynamic );
if (mempool_static)
delete mempool_static;
-
- TCPServerWinsock::cleanup();
- StreamPeerWinsock::cleanup();
}
void OSWinrt::vprint(const char* p_format, va_list p_list, bool p_stderr) {
@@ -399,10 +362,7 @@ void OSWinrt::vprint(const char* p_format, va_list p_list, bool p_stderr) {
void OSWinrt::alert(const String& p_alert,const String& p_title) {
- if (!is_no_window_mode_enabled())
- MessageBoxW(NULL,p_alert.c_str(),p_title.c_str(),MB_OK|MB_ICONEXCLAMATION);
- else
- print_line("ALERT: "+p_alert);
+ print_line("ALERT: "+p_alert);
}
void OSWinrt::set_mouse_mode(MouseMode p_mode) {
@@ -445,71 +405,16 @@ void OSWinrt::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) con
void OSWinrt::print_error(const char* p_function,const char* p_file,int p_line,const char *p_code,const char*p_rationale,ErrorType p_type) {
- HANDLE hCon=GetStdHandle(STD_OUTPUT_HANDLE);
- if (!hCon || hCon==INVALID_HANDLE_VALUE) {
- if (p_rationale && p_rationale[0]) {
-
- print("\E[1;31;40mERROR: %s: \E[1;37;40m%s\n",p_function,p_rationale);
- print("\E[0;31;40m At: %s:%i.\E[0;0;37m\n",p_file,p_line);
+ if (p_rationale && p_rationale[0]) {
- } else {
- print("\E[1;31;40mERROR: %s: \E[1;37;40m%s\n",p_function,p_code);
- print("\E[0;31;40m At: %s:%i.\E[0;0;37m\n",p_file,p_line);
+ print("\E[1;31;40mERROR: %s: \E[1;37;40m%s\n",p_function,p_rationale);
+ print("\E[0;31;40m At: %s:%i.\E[0;0;37m\n",p_file,p_line);
- }
} else {
+ print("\E[1;31;40mERROR: %s: \E[1;37;40m%s\n",p_function,p_code);
+ print("\E[0;31;40m At: %s:%i.\E[0;0;37m\n",p_file,p_line);
- CONSOLE_SCREEN_BUFFER_INFO sbi; //original
- GetConsoleScreenBufferInfo(hCon,&sbi);
-
- SetConsoleTextAttribute(hCon,sbi.wAttributes);
-
-
-
- uint32_t basecol=0;
- switch(p_type) {
- case ERR_ERROR: basecol = FOREGROUND_RED; break;
- case ERR_WARNING: basecol = FOREGROUND_RED|FOREGROUND_GREEN; break;
- case ERR_SCRIPT: basecol = FOREGROUND_GREEN; break;
- }
-
- if (p_rationale && p_rationale[0]) {
-
- SetConsoleTextAttribute(hCon,basecol|FOREGROUND_INTENSITY);
-
-
- switch(p_type) {
- case ERR_ERROR: print("ERROR: "); break;
- case ERR_WARNING: print("WARNING: "); break;
- case ERR_SCRIPT: print("SCRIPT ERROR: "); break;
- }
-
- SetConsoleTextAttribute(hCon,FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_INTENSITY);
- print(" %s\n",p_rationale);
- SetConsoleTextAttribute(hCon,basecol);
- print("At: ");
- SetConsoleTextAttribute(hCon,FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN);
- print(" %s:%i\n",p_file,p_line);
-
-
- } else {
- SetConsoleTextAttribute(hCon,basecol|FOREGROUND_INTENSITY);
- switch(p_type) {
- case ERR_ERROR: print("ERROR: %s: ",p_function); break;
- case ERR_WARNING: print("WARNING: %s: ",p_function); break;
- case ERR_SCRIPT: print("SCRIPT ERROR: %s: ",p_function); break;
- }
- SetConsoleTextAttribute(hCon,FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_INTENSITY);
- print(" %s\n",p_code);
- SetConsoleTextAttribute(hCon,basecol);
- print("At: ");
- SetConsoleTextAttribute(hCon,FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN);
- print(" %s:%i\n",p_file,p_line);
- }
-
- SetConsoleTextAttribute(hCon,sbi.wAttributes);
}
-
}
@@ -566,10 +471,10 @@ uint64_t OSWinrt::get_unix_time() const {
void OSWinrt::delay_usec(uint32_t p_usec) const {
- if (p_usec < 1000)
- Sleep(1);
- else
- Sleep(p_usec / 1000);
+ int msec = p_usec < 1000 ? 1 : p_usec / 1000;
+
+ // no Sleep()
+ WaitForSingleObjectEx(GetCurrentThread(), msec, false);
}
uint64_t OSWinrt::get_ticks_usec() const {
@@ -607,19 +512,12 @@ Error OSWinrt::kill(const ProcessID& p_pid) {
Error OSWinrt::set_cwd(const String& p_cwd) {
- if (_wchdir(p_cwd.c_str())!=0)
- return ERR_CANT_OPEN;
-
return OK;
}
String OSWinrt::get_executable_path() const {
- wchar_t bufname[4096];
- GetModuleFileNameW(NULL,bufname,4096);
- String s= bufname;
- print_line("EXEC PATHPó: "+s);
- return s;
+ return "";
}
void OSWinrt::set_icon(const Image& p_icon) {
@@ -629,25 +527,16 @@ void OSWinrt::set_icon(const Image& p_icon) {
bool OSWinrt::has_environment(const String& p_var) const {
- return getenv(p_var.utf8().get_data()) != NULL;
+ return false;
};
String OSWinrt::get_environment(const String& p_var) const {
- char* val = getenv(p_var.utf8().get_data());
- if (val)
- return val;
-
return "";
};
String OSWinrt::get_stdin_string(bool p_block) {
- if (p_block) {
- char buff[1024];
- return fgets(buff,1024,stdin);
- };
-
return String();
}
@@ -665,23 +554,22 @@ Error OSWinrt::shell_open(String p_uri) {
String OSWinrt::get_locale() const {
Platform::String ^language = Windows::Globalization::Language::CurrentInputMethodLanguageTag;
- return language.Data();
+ return language->Data();
}
void OSWinrt::release_rendering_thread() {
- //gl_context->release_current();
-
+ gl_context->release_current();
}
void OSWinrt::make_rendering_thread() {
- //gl_context->make_current();
+ gl_context->make_current();
}
void OSWinrt::swap_buffers() {
- //gl_context->swap_buffers();
+ gl_context->swap_buffers();
}
@@ -699,6 +587,7 @@ void OSWinrt::run() {
while (!force_quit) {
+ CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
process_events(); // get rid of pending events
if (Main::iteration()==true)
break;
@@ -724,7 +613,7 @@ String OSWinrt::get_data_dir() const {
}
-OSWinrt::OSWinrt(HINSTANCE _hInstance) {
+OSWinrt::OSWinrt() {
key_event_pos=0;
force_quit=false;
@@ -743,6 +632,8 @@ OSWinrt::OSWinrt(HINSTANCE _hInstance) {
stdo=fopen("stdout.txt","wb");
#endif
+ gl_context = NULL;
+
}
diff --git a/platform/winrt/os_winrt.h b/platform/winrt/os_winrt.h
index bc7e188c20..c309239af1 100644
--- a/platform/winrt/os_winrt.h
+++ b/platform/winrt/os_winrt.h
@@ -41,11 +41,10 @@
#include "servers/spatial_sound_2d/spatial_sound_2d_server_sw.h"
#include "servers/physics_2d/physics_2d_server_sw.h"
+#include "gl_context_egl.h"
#include <windows.h>
-#include "key_mapping_win.h"
-#include <windowsx.h>
#include <io.h>
#include <fcntl.h>
@@ -93,6 +92,8 @@ class OSWinrt : public OS {
Physics2DServer *physics_2d_server;
int pressrc;
+ ContextEGL* gl_context;
+
struct Joystick {
int id;
@@ -224,6 +225,8 @@ public:
virtual void move_window_to_foreground();
virtual String get_data_dir() const;
+ void set_gl_context(ContextEGL* p_context);
+
virtual void release_rendering_thread();
virtual void make_rendering_thread();
virtual void swap_buffers();
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 6403454588..8b72308afb 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -106,9 +106,9 @@ Ref<TileSet> TileMap::get_tileset() const {
return tile_set;
}
-void TileMap::set_cell_size(int p_size) {
+void TileMap::set_cell_size(Size2 p_size) {
- ERR_FAIL_COND(p_size<1);
+ ERR_FAIL_COND(p_size.x<1 || p_size.y<1);
_clear_quadrants();
cell_size=p_size;
@@ -117,7 +117,7 @@ void TileMap::set_cell_size(int p_size) {
}
-int TileMap::get_cell_size() const {
+Size2 TileMap::get_cell_size() const {
return cell_size;
}
@@ -171,6 +171,7 @@ void TileMap::_update_dirty_quadrants() {
VisualServer *vs = VisualServer::get_singleton();
Physics2DServer *ps = Physics2DServer::get_singleton();
+ Vector2 tofs = get_cell_draw_offset();
while (dirty_quadrant_list.first()) {
@@ -189,7 +190,7 @@ void TileMap::_update_dirty_quadrants() {
Ref<Texture> tex = tile_set->tile_get_texture(c.id);
Vector2 tile_ofs = tile_set->tile_get_texture_offset(c.id);
- Vector2 offset = Point2( E->key().x, E->key().y )*cell_size - q.pos;
+ Vector2 offset = _map_to_world(E->key().x, E->key().y) - q.pos + tofs;
if (!tex.is_valid())
continue;
@@ -299,7 +300,11 @@ void TileMap::_recompute_rect_cache() {
for (Map<PosKey,Quadrant>::Element *E=quadrant_map.front();E;E=E->next()) {
- Rect2 r( Point2(E->key().x, E->key().y)*cell_size*quadrant_size, Size2(1,1)*cell_size*quadrant_size );
+ Rect2 r;
+ r.pos=_map_to_world(E->key().x*quadrant_size, E->key().y*quadrant_size);
+ r.expand_to( _map_to_world(E->key().x*quadrant_size+quadrant_size, E->key().y*quadrant_size) );
+ r.expand_to( _map_to_world(E->key().x*quadrant_size+quadrant_size, E->key().y*quadrant_size+quadrant_size) );
+ r.expand_to( _map_to_world(E->key().x*quadrant_size, E->key().y*quadrant_size+quadrant_size) );
if (E==quadrant_map.front())
r_total=r;
else
@@ -323,8 +328,10 @@ void TileMap::_recompute_rect_cache() {
Map<TileMap::PosKey,TileMap::Quadrant>::Element *TileMap::_create_quadrant(const PosKey& p_qk) {
Matrix32 xform;
- xform.set_origin(Point2(p_qk.x,p_qk.y)*quadrant_size*cell_size);
+ //xform.set_origin(Point2(p_qk.x,p_qk.y)*cell_size*quadrant_size);
Quadrant q;
+ q.pos = _map_to_world(p_qk.x*quadrant_size,p_qk.y*quadrant_size);
+ xform.set_origin( q.pos );
q.canvas_item = VisualServer::get_singleton()->canvas_item_create();
VisualServer::get_singleton()->canvas_item_set_parent( q.canvas_item, get_canvas_item() );
VisualServer::get_singleton()->canvas_item_set_transform( q.canvas_item, xform );
@@ -341,7 +348,6 @@ Map<TileMap::PosKey,TileMap::Quadrant>::Element *TileMap::_create_quadrant(const
}
Physics2DServer::get_singleton()->body_set_state(q.static_body,Physics2DServer::BODY_STATE_TRANSFORM,xform);
- q.pos=Vector2(p_qk.x,p_qk.y)*quadrant_size*cell_size;
rect_cache_dirty=true;
quadrant_order_dirty=true;
@@ -478,8 +484,11 @@ void TileMap::_recreate_quadrants() {
}
Q->get().cells.insert(E->key());
-
+ _make_quadrant_dirty(Q);
}
+
+
+
}
void TileMap::_clear_quadrants() {
@@ -614,6 +623,152 @@ uint32_t TileMap::get_collision_layer_mask() const {
return collision_layer;
}
+void TileMap::set_mode(Mode p_mode) {
+
+ _clear_quadrants();
+ mode=p_mode;
+ _recreate_quadrants();
+ emit_signal("settings_changed");
+}
+
+TileMap::Mode TileMap::get_mode() const {
+ return mode;
+}
+
+void TileMap::set_half_offset(HalfOffset p_half_offset) {
+
+ _clear_quadrants();
+ half_offset=p_half_offset;
+ _recreate_quadrants();
+ emit_signal("settings_changed");
+}
+
+Vector2 TileMap::get_cell_draw_offset() const {
+
+ switch(mode) {
+
+ case MODE_SQUARE: {
+
+ return Vector2();
+ } break;
+ case MODE_ISOMETRIC: {
+
+ return Vector2(-cell_size.x*0.5,0);
+
+ } break;
+ case MODE_CUSTOM: {
+
+ Vector2 min;
+ min.x = MIN(custom_transform[0].x,min.x);
+ min.y = MIN(custom_transform[0].y,min.y);
+ min.x = MIN(custom_transform[1].x,min.x);
+ min.y = MIN(custom_transform[1].y,min.y);
+ return min;
+ } break;
+ }
+
+ return Vector2();
+
+}
+
+TileMap::HalfOffset TileMap::get_half_offset() const {
+ return half_offset;
+}
+
+Matrix32 TileMap::get_cell_transform() const {
+
+ switch(mode) {
+
+ case MODE_SQUARE: {
+
+ Matrix32 m;
+ m[0]*=cell_size.x;
+ m[1]*=cell_size.y;
+ return m;
+ } break;
+ case MODE_ISOMETRIC: {
+
+ //isometric only makes sense when y is positive in both x and y vectors, otherwise
+ //the drawing of tiles will overlap
+ Matrix32 m;
+ m[0]=Vector2(cell_size.x*0.5,cell_size.y*0.5);
+ m[1]=Vector2(-cell_size.x*0.5,cell_size.y*0.5);
+ return m;
+
+ } break;
+ case MODE_CUSTOM: {
+
+ return custom_transform;
+ } break;
+ }
+
+ return Matrix32();
+}
+
+void TileMap::set_custom_transform(const Matrix32& p_xform) {
+
+ _clear_quadrants();
+ custom_transform=p_xform;
+ _recreate_quadrants();
+ emit_signal("settings_changed");
+
+}
+
+Matrix32 TileMap::get_custom_transform() const{
+
+ return custom_transform;
+}
+
+Vector2 TileMap::_map_to_world(int x,int y,bool p_ignore_ofs) const {
+
+ Vector2 ret = get_cell_transform().xform(Vector2(x,y));
+ if (!p_ignore_ofs) {
+ switch(half_offset) {
+
+ case HALF_OFFSET_X: {
+ if (ABS(y)&1) {
+
+ ret+=get_cell_transform()[0]*0.5;
+ }
+ } break;
+ case HALF_OFFSET_Y: {
+ if (ABS(x)&1) {
+ ret+=get_cell_transform()[1]*0.5;
+ }
+ } break;
+ default: {}
+ }
+ }
+ return ret;
+}
+Vector2 TileMap::map_to_world(const Vector2& p_pos,bool p_ignore_ofs) const {
+
+ return _map_to_world(p_pos.x,p_pos.y,p_ignore_ofs);
+}
+Vector2 TileMap::world_to_map(const Vector2& p_pos) const{
+
+ Vector2 ret = get_cell_transform().affine_inverse().xform(p_pos);
+
+
+ switch(half_offset) {
+
+ case HALF_OFFSET_X: {
+ if (int(ret.y)&1) {
+
+ ret.x-=0.5;
+ }
+ } break;
+ case HALF_OFFSET_Y: {
+ if (int(ret.x)&1) {
+ ret.y-=0.5;
+ }
+ } break;
+ default: {}
+ }
+
+ return ret.floor();
+}
+
void TileMap::_bind_methods() {
@@ -621,10 +776,21 @@ void TileMap::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_tileset","tileset:TileSet"),&TileMap::set_tileset);
ObjectTypeDB::bind_method(_MD("get_tileset:TileSet"),&TileMap::get_tileset);
+ ObjectTypeDB::bind_method(_MD("set_mode","mode"),&TileMap::set_mode);
+ ObjectTypeDB::bind_method(_MD("get_mode"),&TileMap::get_mode);
+
+ ObjectTypeDB::bind_method(_MD("set_half_offset","half_offset"),&TileMap::set_half_offset);
+ ObjectTypeDB::bind_method(_MD("get_half_offset"),&TileMap::get_half_offset);
+
+ ObjectTypeDB::bind_method(_MD("set_custom_transform","custom_transform"),&TileMap::set_custom_transform);
+ ObjectTypeDB::bind_method(_MD("get_custom_transform"),&TileMap::get_custom_transform);
ObjectTypeDB::bind_method(_MD("set_cell_size","size"),&TileMap::set_cell_size);
ObjectTypeDB::bind_method(_MD("get_cell_size"),&TileMap::get_cell_size);
+ ObjectTypeDB::bind_method(_MD("_set_old_cell_size","size"),&TileMap::_set_old_cell_size);
+ ObjectTypeDB::bind_method(_MD("_get_old_cell_size"),&TileMap::_get_old_cell_size);
+
ObjectTypeDB::bind_method(_MD("set_quadrant_size","size"),&TileMap::set_quadrant_size);
ObjectTypeDB::bind_method(_MD("get_quadrant_size"),&TileMap::get_quadrant_size);
@@ -650,6 +816,9 @@ void TileMap::_bind_methods() {
ObjectTypeDB::bind_method(_MD("clear"),&TileMap::clear);
+ ObjectTypeDB::bind_method(_MD("map_to_world","mappos","ignore_half_ofs"),&TileMap::map_to_world,DEFVAL(false));
+ ObjectTypeDB::bind_method(_MD("world_to_map","worldpos"),&TileMap::world_to_map);
+
ObjectTypeDB::bind_method(_MD("_clear_quadrants"),&TileMap::_clear_quadrants);
ObjectTypeDB::bind_method(_MD("_recreate_quadrants"),&TileMap::_recreate_quadrants);
ObjectTypeDB::bind_method(_MD("_update_dirty_quadrants"),&TileMap::_update_dirty_quadrants);
@@ -657,17 +826,28 @@ void TileMap::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_set_tile_data"),&TileMap::_set_tile_data);
ObjectTypeDB::bind_method(_MD("_get_tile_data"),&TileMap::_get_tile_data);
- ADD_PROPERTY( PropertyInfo(Variant::INT,"cell_size",PROPERTY_HINT_RANGE,"1,8192,1"),_SCS("set_cell_size"),_SCS("get_cell_size"));
- ADD_PROPERTY( PropertyInfo(Variant::INT,"quadrant_size",PROPERTY_HINT_RANGE,"1,128,1"),_SCS("set_quadrant_size"),_SCS("get_quadrant_size"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"mode",PROPERTY_HINT_ENUM,"Square,Isometric,Custom"),_SCS("set_mode"),_SCS("get_mode"));
ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"tile_set",PROPERTY_HINT_RESOURCE_TYPE,"TileSet"),_SCS("set_tileset"),_SCS("get_tileset"));
- ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"tile_data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_tile_data"),_SCS("_get_tile_data"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"cell_size",PROPERTY_HINT_RANGE,"1,8192,1",0),_SCS("_set_old_cell_size"),_SCS("_get_old_cell_size"));
+ ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"cell/size",PROPERTY_HINT_RANGE,"1,8192,1"),_SCS("set_cell_size"),_SCS("get_cell_size"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"cell/quadrant_size",PROPERTY_HINT_RANGE,"1,128,1"),_SCS("set_quadrant_size"),_SCS("get_quadrant_size"));
+ ADD_PROPERTY( PropertyInfo(Variant::MATRIX32,"cell/custom_transform"),_SCS("set_custom_transform"),_SCS("get_custom_transform"));
+ ADD_PROPERTY( PropertyInfo(Variant::INT,"cell/half_offset",PROPERTY_HINT_ENUM,"Offset X,Offset Y,Disabled"),_SCS("set_half_offset"),_SCS("get_half_offset"));
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::OBJECT,"tile_data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_tile_data"),_SCS("_get_tile_data"));
ADD_SIGNAL(MethodInfo("settings_changed"));
BIND_CONSTANT( INVALID_CELL );
+ BIND_CONSTANT( MODE_SQUARE );
+ BIND_CONSTANT( MODE_ISOMETRIC );
+ BIND_CONSTANT( MODE_CUSTOM );
+ BIND_CONSTANT( HALF_OFFSET_X );
+ BIND_CONSTANT( HALF_OFFSET_Y );
+ BIND_CONSTANT( HALF_OFFSET_DISABLED );
+
}
TileMap::TileMap() {
@@ -678,12 +858,14 @@ TileMap::TileMap() {
pending_update=false;
quadrant_order_dirty=false;
quadrant_size=16;
- cell_size=64;
+ cell_size=Size2(64,64);
center_x=false;
center_y=false;
collision_layer=1;
friction=1;
bounce=0;
+ mode=MODE_SQUARE;
+ half_offset=HALF_OFFSET_DISABLED;
fp_adjust=0.01;
fp_adjust=0.01;
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index d21437e30f..4e9e2e7e97 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -37,12 +37,30 @@
class TileMap : public Node2D {
OBJ_TYPE( TileMap, Node2D );
+public:
+
+ enum Mode {
+ MODE_SQUARE,
+ MODE_ISOMETRIC,
+ MODE_CUSTOM
+ };
+
+ enum HalfOffset {
+ HALF_OFFSET_X,
+ HALF_OFFSET_Y,
+ HALF_OFFSET_DISABLED,
+ };
+private:
Ref<TileSet> tile_set;
- int cell_size;
+ Size2i cell_size;
int quadrant_size;
bool center_x,center_y;
+ Mode mode;
+ Matrix32 custom_transform;
+ HalfOffset half_offset;
+
union PosKey {
@@ -117,6 +135,12 @@ class TileMap : public Node2D {
void _set_tile_data(const DVector<int>& p_data);
DVector<int> _get_tile_data() const;
+
+ void _set_old_cell_size(int p_size) { set_cell_size(Size2(p_size,p_size)); }
+ int _get_old_cell_size() const { return cell_size.x; }
+
+ _FORCE_INLINE_ Vector2 _map_to_world(int p_x,int p_y,bool p_ignore_ofs=false) const;
+
protected:
@@ -132,8 +156,8 @@ public:
void set_tileset(const Ref<TileSet>& p_tileset);
Ref<TileSet> get_tileset() const;
- void set_cell_size(int p_size);
- int get_cell_size() const;
+ void set_cell_size(Size2 p_size);
+ Size2 get_cell_size() const;
void set_quadrant_size(int p_size);
int get_quadrant_size() const;
@@ -159,10 +183,28 @@ public:
void set_collision_bounce(float p_bounce);
float get_collision_bounce() const;
+ void set_mode(Mode p_mode);
+ Mode get_mode() const;
+
+ void set_half_offset(HalfOffset p_half_offset);
+ HalfOffset get_half_offset() const;
+
+ void set_custom_transform(const Matrix32& p_xform);
+ Matrix32 get_custom_transform() const;
+
+ Matrix32 get_cell_transform() const;
+ Vector2 get_cell_draw_offset() const;
+
+ Vector2 map_to_world(const Vector2& p_pos, bool p_ignore_ofs=false) const;
+ Vector2 world_to_map(const Vector2& p_pos) const;
+
void clear();
TileMap();
~TileMap();
};
+VARIANT_ENUM_CAST(TileMap::Mode);
+VARIANT_ENUM_CAST(TileMap::HalfOffset);
+
#endif // TILE_MAP_H
diff --git a/scene/2d/y_sort.cpp b/scene/2d/y_sort.cpp
new file mode 100644
index 0000000000..d441abfaf1
--- /dev/null
+++ b/scene/2d/y_sort.cpp
@@ -0,0 +1,29 @@
+#include "y_sort.h"
+
+
+
+void YSort::set_sort_enabled(bool p_enabled) {
+
+ sort_enabled=p_enabled;
+ VS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(),sort_enabled);
+}
+
+bool YSort::is_sort_enabled() const {
+
+ return sort_enabled;
+}
+
+void YSort::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("set_sort_enabled","enabled"),&YSort::set_sort_enabled);
+ ObjectTypeDB::bind_method(_MD("is_sort_enabled"),&YSort::is_sort_enabled);
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL,"sort/enabled"),_SCS("set_sort_enabled"),_SCS("is_sort_enabled"));
+}
+
+
+YSort::YSort() {
+
+ sort_enabled=true;
+ VS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(),true);
+}
diff --git a/scene/2d/y_sort.h b/scene/2d/y_sort.h
new file mode 100644
index 0000000000..6d04a67e42
--- /dev/null
+++ b/scene/2d/y_sort.h
@@ -0,0 +1,17 @@
+#ifndef Y_SORT_H
+#define Y_SORT_H
+
+#include "scene/2d/node_2d.h"
+
+class YSort : public Node2D {
+ OBJ_TYPE(YSort,Node2D);
+ bool sort_enabled;
+ static void _bind_methods();
+public:
+
+ void set_sort_enabled(bool p_enabled);
+ bool is_sort_enabled() const;
+ YSort();
+};
+
+#endif // Y_SORT_H
diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp
index f5895453cc..7370c36eb7 100644
--- a/scene/3d/area.cpp
+++ b/scene/3d/area.cpp
@@ -255,16 +255,6 @@ bool Area::is_monitoring_enabled() const {
}
-void Area::set_ray_pickable(bool p_ray_pickable) {
-
- ray_pickable=p_ray_pickable;
- PhysicsServer::get_singleton()->area_set_ray_pickable(get_rid(),p_ray_pickable);
-}
-
-bool Area::is_ray_pickable() const {
-
- return ray_pickable;
-}
void Area::_bind_methods() {
@@ -289,8 +279,6 @@ void Area::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_priority","priority"),&Area::set_priority);
ObjectTypeDB::bind_method(_MD("get_priority"),&Area::get_priority);
- ObjectTypeDB::bind_method(_MD("set_ray_pickable","ray_pickable"),&Area::set_ray_pickable);
- ObjectTypeDB::bind_method(_MD("is_ray_pickable"),&Area::is_ray_pickable);
ObjectTypeDB::bind_method(_MD("set_enable_monitoring","enable"),&Area::set_enable_monitoring);
ObjectTypeDB::bind_method(_MD("is_monitoring_enabled"),&Area::is_monitoring_enabled);
@@ -310,7 +298,6 @@ void Area::_bind_methods() {
ADD_PROPERTY( PropertyInfo(Variant::REAL,"density",PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_density"),_SCS("get_density"));
ADD_PROPERTY( 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,"ray_pickable"),_SCS("set_ray_pickable"),_SCS("is_ray_pickable"));
}
@@ -323,7 +310,7 @@ Area::Area() : CollisionObject(PhysicsServer::get_singleton()->area_create(),tru
density=0.1;
priority=0;
monitoring=false;
- ray_pickable=false;
+ set_ray_pickable(false);
set_enable_monitoring(true);
}
diff --git a/scene/3d/area.h b/scene/3d/area.h
index 92b5d39f59..5558e2c719 100644
--- a/scene/3d/area.h
+++ b/scene/3d/area.h
@@ -52,7 +52,7 @@ private:
real_t density;
int priority;
bool monitoring;
- bool ray_pickable;
+
void _body_inout(int p_status,const RID& p_body, int p_instance, int p_body_shape,int p_area_shape);
@@ -109,9 +109,6 @@ public:
void set_priority(real_t p_priority);
real_t get_priority() const;
- void set_ray_pickable(bool p_ray_pickable);
- bool is_ray_pickable() const;
-
void set_enable_monitoring(bool p_enable);
bool is_monitoring_enabled() const;
diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp
index 4245bfa2c9..c85ad70c63 100644
--- a/scene/3d/camera.cpp
+++ b/scene/3d/camera.cpp
@@ -262,7 +262,7 @@ void Camera::_notification(int p_what) {
Transform Camera::get_camera_transform() const {
- return get_global_transform();
+ return get_global_transform().orthonormalized();
}
void Camera::set_perspective(float p_fovy_degrees, float p_z_near, float p_z_far) {
@@ -695,7 +695,7 @@ Vector<Plane> Camera::get_frustum() const {
else
cm.set_orthogonal(size,viewport_size.get_aspect(),near,far,keep_aspect==KEEP_WIDTH);
- return cm.get_projection_planes(get_global_transform());
+ return cm.get_projection_planes(get_camera_transform());
}
@@ -704,7 +704,7 @@ Vector<Plane> Camera::get_frustum() const {
void Camera::look_at(const Vector3& p_target, const Vector3& p_up_normal) {
Transform lookat;
- lookat.origin=get_global_transform().origin;
+ lookat.origin=get_camera_transform().origin;
lookat=lookat.looking_at(p_target,p_up_normal);
set_global_transform(lookat);
}
diff --git a/scene/3d/collision_object.cpp b/scene/3d/collision_object.cpp
index 06564f5c49..e9d3e73906 100644
--- a/scene/3d/collision_object.cpp
+++ b/scene/3d/collision_object.cpp
@@ -53,8 +53,9 @@ void CollisionObject::_notification(int p_what) {
} else
PhysicsServer::get_singleton()->body_set_space(rid,space);
+ _update_pickable();
//get space
- }
+ };
case NOTIFICATION_TRANSFORM_CHANGED: {
@@ -64,6 +65,11 @@ void CollisionObject::_notification(int p_what) {
PhysicsServer::get_singleton()->body_set_state(rid,PhysicsServer::BODY_STATE_TRANSFORM,get_global_transform());
} break;
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+
+ _update_pickable();
+
+ } break;
case NOTIFICATION_EXIT_WORLD: {
if (area) {
@@ -91,11 +97,11 @@ void CollisionObject::_update_shapes() {
continue;
if (area)
PhysicsServer::get_singleton()->area_add_shape(rid,shapes[i].shape->get_rid(),shapes[i].xform);
- else {
+ else {
PhysicsServer::get_singleton()->body_add_shape(rid,shapes[i].shape->get_rid(),shapes[i].xform);
- if (shapes[i].trigger)
- PhysicsServer::get_singleton()->body_set_shape_as_trigger(rid,i,shapes[i].trigger);
- }
+ if (shapes[i].trigger)
+ PhysicsServer::get_singleton()->body_set_shape_as_trigger(rid,i,shapes[i].trigger);
+ }
}
}
@@ -160,18 +166,18 @@ void CollisionObject::_get_property_list( List<PropertyInfo> *p_list) const {
String path="shapes/"+itos(i)+"/";
p_list->push_back( PropertyInfo(Variant::OBJECT,path+"shape",PROPERTY_HINT_RESOURCE_TYPE,"Shape",PROPERTY_USAGE_NOEDITOR) );
p_list->push_back( PropertyInfo(Variant::TRANSFORM,path+"transform",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR) );
- p_list->push_back( PropertyInfo(Variant::BOOL,path+"trigger",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR) );
+ p_list->push_back( PropertyInfo(Variant::BOOL,path+"trigger",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR) );
}
}
-void CollisionObject::_input_event(const InputEvent& p_input_event,const Vector3& p_pos, const Vector3& p_normal, int p_shape) {
+void CollisionObject::_input_event(Node *p_camera, const InputEvent& p_input_event, const Vector3& p_pos, const Vector3& p_normal, int p_shape) {
if (get_script_instance()) {
- get_script_instance()->call(SceneStringNames::get_singleton()->_input_event,p_input_event,p_pos,p_normal,p_shape);
+ get_script_instance()->call(SceneStringNames::get_singleton()->_input_event,p_camera,p_input_event,p_pos,p_normal,p_shape);
}
- emit_signal(SceneStringNames::get_singleton()->input_event,p_input_event,p_pos,p_normal,p_shape);
+ emit_signal(SceneStringNames::get_singleton()->input_event,p_camera,p_input_event,p_pos,p_normal,p_shape);
}
void CollisionObject::_mouse_enter() {
@@ -192,6 +198,28 @@ void CollisionObject::_mouse_exit() {
}
+void CollisionObject::_update_pickable() {
+ if (!is_inside_scene())
+ return;
+ bool pickable = ray_pickable && is_inside_scene() && is_visible();
+ if (area)
+ PhysicsServer::get_singleton()->area_set_ray_pickable(rid,pickable);
+ else
+ PhysicsServer::get_singleton()->body_set_ray_pickable(rid,pickable);
+}
+
+void CollisionObject::set_ray_pickable(bool p_ray_pickable) {
+
+ ray_pickable=p_ray_pickable;
+ _update_pickable();
+
+}
+
+bool CollisionObject::is_ray_pickable() const {
+
+ return ray_pickable;
+}
+
void CollisionObject::_bind_methods() {
@@ -206,15 +234,18 @@ void CollisionObject::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_shape_transform","shape_idx"),&CollisionObject::get_shape_transform);
ObjectTypeDB::bind_method(_MD("remove_shape","shape_idx"),&CollisionObject::remove_shape);
ObjectTypeDB::bind_method(_MD("clear_shapes"),&CollisionObject::clear_shapes);
+ ObjectTypeDB::bind_method(_MD("set_ray_pickable","ray_pickable"),&CollisionObject::set_ray_pickable);
+ ObjectTypeDB::bind_method(_MD("is_ray_pickable"),&CollisionObject::is_ray_pickable);
ObjectTypeDB::bind_method(_MD("set_capture_input_on_drag","enable"),&CollisionObject::set_capture_input_on_drag);
ObjectTypeDB::bind_method(_MD("get_capture_input_on_drag"),&CollisionObject::get_capture_input_on_drag);
ObjectTypeDB::bind_method(_MD("get_rid"),&CollisionObject::get_rid);
- BIND_VMETHOD( MethodInfo("_input_event",PropertyInfo(Variant::INPUT_EVENT,"event"),PropertyInfo(Variant::VECTOR3,"click_pos"),PropertyInfo(Variant::VECTOR3,"click_normal"),PropertyInfo(Variant::INT,"shape_idx")));
+ BIND_VMETHOD( MethodInfo("_input_event",PropertyInfo(Variant::OBJECT,"camera"),PropertyInfo(Variant::INPUT_EVENT,"event"),PropertyInfo(Variant::VECTOR3,"click_pos"),PropertyInfo(Variant::VECTOR3,"click_normal"),PropertyInfo(Variant::INT,"shape_idx")));
- ADD_SIGNAL( MethodInfo("input_event",PropertyInfo(Variant::INPUT_EVENT,"event"),PropertyInfo(Variant::VECTOR3,"click_pos"),PropertyInfo(Variant::VECTOR3,"click_normal"),PropertyInfo(Variant::INT,"shape_idx")));
+ ADD_SIGNAL( MethodInfo("input_event",PropertyInfo(Variant::OBJECT,"camera"),PropertyInfo(Variant::INPUT_EVENT,"event"),PropertyInfo(Variant::VECTOR3,"click_pos"),PropertyInfo(Variant::VECTOR3,"click_normal"),PropertyInfo(Variant::INT,"shape_idx")));
ADD_SIGNAL( MethodInfo("mouse_enter"));
ADD_SIGNAL( MethodInfo("mouse_exit"));
+ ADD_PROPERTY( PropertyInfo(Variant::BOOL,"input/ray_pickable"),_SCS("set_ray_pickable"),_SCS("is_ray_pickable"));
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"input/capture_on_drag"),_SCS("set_capture_input_on_drag"),_SCS("get_capture_input_on_drag"));
}
@@ -296,6 +327,8 @@ CollisionObject::CollisionObject(RID p_rid, bool p_area) {
rid=p_rid;
area=p_area;
+ capture_input_on_drag=false;
+ ray_pickable=true;
if (p_area) {
PhysicsServer::get_singleton()->area_attach_object_instance_ID(rid,get_instance_ID());
} else {
@@ -321,6 +354,7 @@ CollisionObject::CollisionObject() {
capture_input_on_drag=false;
+ ray_pickable=true;
//owner=
diff --git a/scene/3d/collision_object.h b/scene/3d/collision_object.h
index afd73aa9cc..eafce2c82c 100644
--- a/scene/3d/collision_object.h
+++ b/scene/3d/collision_object.h
@@ -51,9 +51,10 @@ class CollisionObject : public Spatial {
};
bool capture_input_on_drag;
-
+ bool ray_pickable;
Vector<ShapeData> shapes;
+ void _update_pickable();
void _update_shapes();
friend class CollisionShape;
@@ -69,7 +70,7 @@ protected:
void _get_property_list( List<PropertyInfo> *p_list) const;
static void _bind_methods();
friend class Viewport;
- virtual void _input_event(const InputEvent& p_input_event,const Vector3& p_pos, const Vector3& p_normal, int p_shape);
+ virtual void _input_event(Node* p_camera,const InputEvent& p_input_event,const Vector3& p_pos, const Vector3& p_normal, int p_shape);
virtual void _mouse_enter();
virtual void _mouse_exit();
@@ -87,9 +88,13 @@ public:
void set_shape_as_trigger(int p_shape_idx, bool p_trigger);
bool is_shape_set_as_trigger(int p_shape_idx) const;
+ void set_ray_pickable(bool p_ray_pickable);
+ bool is_ray_pickable() const;
+
void set_capture_input_on_drag(bool p_capture);
bool get_capture_input_on_drag() const;
+
_FORCE_INLINE_ RID get_rid() const { return rid; }
CollisionObject();
diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp
index 1efc74e672..0d571b77cd 100644
--- a/scene/3d/light.cpp
+++ b/scene/3d/light.cpp
@@ -622,7 +622,7 @@ void SpotLight::_bind_methods() {
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_ATTENUATION );
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/spot_angle", PROPERTY_HINT_RANGE, "0.01,89.9,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SPOT_ANGLE );
- ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/spot_attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_ATTENUATION );
+ ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/spot_attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SPOT_ATTENUATION );
}
diff --git a/scene/3d/navigation.cpp b/scene/3d/navigation.cpp
index d2abdad079..d22198d47e 100644
--- a/scene/3d/navigation.cpp
+++ b/scene/3d/navigation.cpp
@@ -21,6 +21,7 @@ void Navigation::_navmesh_link(int p_id) {
List<Polygon>::Element *P=nm.polygons.push_back(Polygon());
Polygon &p=P->get();
+ p.owner=&nm;
Vector<int> poly = nm.navmesh->get_polygon(i);
int plen=poly.size();
@@ -145,13 +146,14 @@ void Navigation::_navmesh_unlink(int p_id) {
}
-int Navigation::navmesh_create(const Ref<NavigationMesh>& p_mesh,const Transform& p_xform) {
+int Navigation::navmesh_create(const Ref<NavigationMesh>& p_mesh, const Transform& p_xform, Object *p_owner) {
int id = last_id++;
NavMesh nm;
nm.linked=false;
nm.navmesh=p_mesh;
nm.xform=p_xform;
+ nm.owner=p_owner;
navmesh_map[id]=nm;
_navmesh_link(id);
@@ -453,6 +455,7 @@ Vector3 Navigation::get_closest_point_to_segment(const Vector3& p_from,const Vec
bool use_collision=false;
Vector3 closest_point;
float closest_point_d=1e20;
+ NavMesh *closest_navmesh=NULL;
for (Map<int,NavMesh>::Element*E=navmesh_map.front();E;E=E->next()) {
@@ -471,10 +474,12 @@ Vector3 Navigation::get_closest_point_to_segment(const Vector3& p_from,const Vec
closest_point=inters;
use_collision=true;
closest_point_d=p_from.distance_to(inters);
+ closest_navmesh=p.owner;
} else if (closest_point_d > inters.distance_to(p_from)){
closest_point=inters;
closest_point_d=p_from.distance_to(inters);
+ closest_navmesh=p.owner;
}
}
}
@@ -492,6 +497,7 @@ Vector3 Navigation::get_closest_point_to_segment(const Vector3& p_from,const Vec
closest_point_d=d;
closest_point=b;
+ closest_navmesh=p.owner;
}
}
@@ -499,6 +505,10 @@ Vector3 Navigation::get_closest_point_to_segment(const Vector3& p_from,const Vec
}
}
+ if (closest_navmesh && closest_navmesh->owner) {
+ //print_line("navmesh is: "+closest_navmesh->owner->cast_to<Node>()->get_name());
+ }
+
return closest_point;
}
@@ -577,7 +587,7 @@ Vector3 Navigation::get_up_vector() const{
void Navigation::_bind_methods() {
- ObjectTypeDB::bind_method(_MD("navmesh_create","mesh:NavigationMesh","xform"),&Navigation::navmesh_create);
+ ObjectTypeDB::bind_method(_MD("navmesh_create","mesh:NavigationMesh","xform","owner"),&Navigation::navmesh_create,DEFVAL(Variant()));
ObjectTypeDB::bind_method(_MD("navmesh_set_transform","id","xform"),&Navigation::navmesh_set_transform);
ObjectTypeDB::bind_method(_MD("navmesh_remove","id"),&Navigation::navmesh_remove);
diff --git a/scene/3d/navigation.h b/scene/3d/navigation.h
index e8a97a6591..9b6cf5fbc4 100644
--- a/scene/3d/navigation.h
+++ b/scene/3d/navigation.h
@@ -41,6 +41,8 @@ class Navigation : public Spatial {
};
+ struct NavMesh;
+
struct Polygon {
@@ -57,6 +59,8 @@ class Navigation : public Spatial {
float distance;
int prev_edge;
+
+ NavMesh *owner;
};
@@ -74,6 +78,7 @@ class Navigation : public Spatial {
struct NavMesh {
+ Object *owner;
Transform xform;
bool linked;
Ref<NavigationMesh> navmesh;
@@ -124,7 +129,7 @@ public:
Vector3 get_up_vector() const;
//API should be as dynamic as possible
- int navmesh_create(const Ref<NavigationMesh>& p_mesh,const Transform& p_xform);
+ int navmesh_create(const Ref<NavigationMesh>& p_mesh,const Transform& p_xform,Object* p_owner=NULL);
void navmesh_set_transform(int p_id, const Transform& p_xform);
void navmesh_remove(int p_id);
diff --git a/scene/3d/navigation_mesh.cpp b/scene/3d/navigation_mesh.cpp
index cf2e22a573..db416f24dd 100644
--- a/scene/3d/navigation_mesh.cpp
+++ b/scene/3d/navigation_mesh.cpp
@@ -129,7 +129,7 @@ void NavigationMeshInstance::set_enabled(bool p_enabled) {
if (navmesh.is_valid()) {
- nav_id = navigation->navmesh_create(navmesh,get_relative_transform(navigation));
+ nav_id = navigation->navmesh_create(navmesh,get_relative_transform(navigation),this);
}
}
@@ -162,7 +162,7 @@ void NavigationMeshInstance::_notification(int p_what) {
if (enabled && navmesh.is_valid()) {
- nav_id = navigation->navmesh_create(navmesh,get_relative_transform(navigation));
+ nav_id = navigation->navmesh_create(navmesh,get_relative_transform(navigation),this);
}
break;
}
@@ -205,7 +205,7 @@ void NavigationMeshInstance::set_navigation_mesh(const Ref<NavigationMesh>& p_na
navmesh=p_navmesh;
if (navigation && navmesh.is_valid() && enabled) {
- nav_id = navigation->navmesh_create(navmesh,get_relative_transform(navigation));
+ nav_id = navigation->navmesh_create(navmesh,get_relative_transform(navigation),this);
}
update_gizmo();
diff --git a/scene/3d/physics_joint.cpp b/scene/3d/physics_joint.cpp
index 341b02314d..8a79e17d87 100644
--- a/scene/3d/physics_joint.cpp
+++ b/scene/3d/physics_joint.cpp
@@ -66,6 +66,9 @@ void Joint::_update_joint(bool p_only_free) {
joint = _configure_joint(body_a,body_b);
+ if (joint.is_valid())
+ PhysicsServer::get_singleton()->joint_set_solver_priority(joint,solver_priority);
+
if (body_b && joint.is_valid()) {
ba=body_a->get_rid();
@@ -107,6 +110,20 @@ NodePath Joint::get_node_b() const{
}
+void Joint::set_solver_priority(int p_priority) {
+
+ solver_priority=p_priority;
+ if (joint.is_valid())
+ PhysicsServer::get_singleton()->joint_set_solver_priority(joint,solver_priority);
+
+}
+
+int Joint::get_solver_priority() const {
+
+ return solver_priority;
+}
+
+
void Joint::_notification(int p_what) {
switch(p_what) {
@@ -117,8 +134,6 @@ void Joint::_notification(int p_what) {
case NOTIFICATION_EXIT_SCENE: {
if (joint.is_valid()) {
_update_joint(true);
-
-
PhysicsServer::get_singleton()->free(joint);
joint=RID();
}
@@ -138,9 +153,13 @@ void Joint::_bind_methods() {
ObjectTypeDB::bind_method( _MD("set_node_b","node"), &Joint::set_node_b );
ObjectTypeDB::bind_method( _MD("get_node_b"), &Joint::get_node_b );
+ ObjectTypeDB::bind_method( _MD("set_solver_priority","priority"), &Joint::set_solver_priority );
+ ObjectTypeDB::bind_method( _MD("get_solver_priority"), &Joint::get_solver_priority );
ADD_PROPERTY( PropertyInfo( Variant::NODE_PATH, "nodes/node_a"), _SCS("set_node_a"),_SCS("get_node_a") );
ADD_PROPERTY( PropertyInfo( Variant::NODE_PATH, "nodes/node_b"), _SCS("set_node_b"),_SCS("get_node_b") );
+ ADD_PROPERTY( PropertyInfo( Variant::INT, "solver/priority",PROPERTY_HINT_RANGE,"1,8,1"), _SCS("set_solver_priority"),_SCS("get_solver_priority") );
+
}
@@ -148,7 +167,7 @@ void Joint::_bind_methods() {
Joint::Joint() {
-
+ solver_priority=1;
}
diff --git a/scene/3d/physics_joint.h b/scene/3d/physics_joint.h
index 6daa06da2b..32bec1bd6f 100644
--- a/scene/3d/physics_joint.h
+++ b/scene/3d/physics_joint.h
@@ -44,6 +44,8 @@ class Joint : public Spatial {
NodePath a;
NodePath b;
+ int solver_priority;
+
protected:
@@ -62,6 +64,9 @@ public:
void set_node_b(const NodePath& p_node_b);
NodePath get_node_b() const;
+ void set_solver_priority(int p_priority);
+ int get_solver_priority() const;
+
RID get_joint() const { return joint; }
Joint();
diff --git a/scene/3d/vehicle_body.cpp b/scene/3d/vehicle_body.cpp
index 07abd1dcd2..4cf905e4ee 100644
--- a/scene/3d/vehicle_body.cpp
+++ b/scene/3d/vehicle_body.cpp
@@ -179,7 +179,7 @@ void VehicleWheel::set_damping_compression(float p_value){
}
float VehicleWheel::get_damping_compression() const{
- return m_wheelsDampingRelaxation;
+ return m_wheelsDampingCompression;
}
void VehicleWheel::set_damping_relaxation(float p_value){
@@ -745,11 +745,12 @@ void VehicleBody::_update_friction(PhysicsDirectBodyState *s) {
{
if (engine_force != 0.f)
{
- rollingFriction = engine_force* s->get_step();
+ rollingFriction = -engine_force* s->get_step();
} else
{
real_t defaultRollingFrictionImpulse = 0.f;
- real_t maxImpulse = wheelInfo.m_brake ? wheelInfo.m_brake : defaultRollingFrictionImpulse;
+ float cbrake = MAX(wheelInfo.m_brake,brake);
+ real_t maxImpulse = cbrake ? cbrake : defaultRollingFrictionImpulse;
btVehicleWheelContactPoint contactPt(s,wheelInfo.m_raycastInfo.m_groundObject,wheelInfo.m_raycastInfo.m_contactPointWS,m_forwardWS[wheel],maxImpulse);
rollingFriction = _calc_rolling_friction(contactPt);
}
@@ -1009,9 +1010,9 @@ void VehicleBody::_bind_methods(){
ObjectTypeDB::bind_method(_MD("_direct_state_changed"),&VehicleBody::_direct_state_changed);
- ADD_PROPERTY( PropertyInfo(Variant::REAL,"motion/engine_force",PROPERTY_HINT_RANGE,"0.01,1024.0,0.01"),_SCS("set_engine_force"),_SCS("get_engine_force"));
- ADD_PROPERTY( PropertyInfo(Variant::REAL,"motion/brake",PROPERTY_HINT_RANGE,"0.01,1024.0,0.01"),_SCS("set_brake"),_SCS("get_brake"));
- ADD_PROPERTY( PropertyInfo(Variant::REAL,"motion/steering",PROPERTY_HINT_RANGE,"0.01,1024.0,0.01"),_SCS("set_steering"),_SCS("get_steering"));
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"motion/engine_force",PROPERTY_HINT_RANGE,"0.00,1024.0,0.01"),_SCS("set_engine_force"),_SCS("get_engine_force"));
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"motion/brake",PROPERTY_HINT_RANGE,"0.0,1.0,0.01"),_SCS("set_brake"),_SCS("get_brake"));
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"motion/steering",PROPERTY_HINT_RANGE,"-180,180.0,0.01"),_SCS("set_steering"),_SCS("get_steering"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"body/mass",PROPERTY_HINT_RANGE,"0.01,65536,0.01"),_SCS("set_mass"),_SCS("get_mass"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"body/friction",PROPERTY_HINT_RANGE,"0.01,1,0.01"),_SCS("set_friction"),_SCS("get_friction"));
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 030f3f27e0..88fabb3489 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -180,6 +180,10 @@ void AnimationPlayer::_get_property_list( List<PropertyInfo> *p_list) const {
}
+void AnimationPlayer::advance(float p_time) {
+
+ _animation_process( p_time );
+}
void AnimationPlayer::_notification(int p_what) {
@@ -1227,6 +1231,8 @@ void AnimationPlayer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_current_animation_pos"),&AnimationPlayer::get_current_animation_pos);
ObjectTypeDB::bind_method(_MD("get_current_animation_length"),&AnimationPlayer::get_current_animation_length);
+ ObjectTypeDB::bind_method(_MD("advance","delta"),&AnimationPlayer::advance);
+
ADD_PROPERTY( PropertyInfo( Variant::INT, "playback/process_mode", PROPERTY_HINT_ENUM, "Fixed,Idle"), _SCS("set_animation_process_mode"), _SCS("get_animation_process_mode"));
ADD_PROPERTY( PropertyInfo( Variant::REAL, "playback/default_blend_time", PROPERTY_HINT_RANGE, "0,4096,0.01"), _SCS("set_default_blend_time"), _SCS("get_default_blend_time"));
diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h
index 51c000d4d8..038c43d569 100644
--- a/scene/animation/animation_player.h
+++ b/scene/animation/animation_player.h
@@ -283,6 +283,8 @@ public:
float get_current_animation_pos() const;
float get_current_animation_length() const;
+ void advance(float p_time);
+
void set_root(const NodePath& p_root);
NodePath get_root() const;
diff --git a/scene/audio/event_player.cpp b/scene/audio/event_player.cpp
index 6bad94bf0e..e5b2be53ca 100644
--- a/scene/audio/event_player.cpp
+++ b/scene/audio/event_player.cpp
@@ -280,8 +280,8 @@ float EventPlayer::get_channel_last_note_time(int p_channel) const {
void EventPlayer::_bind_methods() {
- ObjectTypeDB::bind_method(_MD("set_stream","stream:Stream"),&EventPlayer::set_stream);
- ObjectTypeDB::bind_method(_MD("get_stream:Stream"),&EventPlayer::get_stream);
+ ObjectTypeDB::bind_method(_MD("set_stream","stream:EventStream"),&EventPlayer::set_stream);
+ ObjectTypeDB::bind_method(_MD("get_stream:EventStream"),&EventPlayer::get_stream);
ObjectTypeDB::bind_method(_MD("play"),&EventPlayer::play);
ObjectTypeDB::bind_method(_MD("stop"),&EventPlayer::stop);
diff --git a/scene/gui/button_group.cpp b/scene/gui/button_group.cpp
index 65cfd03505..58b323c24d 100644
--- a/scene/gui/button_group.cpp
+++ b/scene/gui/button_group.cpp
@@ -67,6 +67,9 @@ Array ButtonGroup::_get_button_list() const {
List<BaseButton*> b;
get_button_list(&b);
+
+ b.sort_custom<Node::Comparator>();
+
Array arr;
arr.resize(b.size());
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index b7918994d8..36940655d4 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -397,6 +397,7 @@ void Label::regenerate_word_cache() {
}
+
if (current=='\n') {
insert_newline=true;
} else {
@@ -446,7 +447,7 @@ void Label::regenerate_word_cache() {
}
- total_char_cache -= line_count + 1; // do not count new lines (including the first one)
+ //total_char_cache -= line_count + 1; // do not count new lines (including the first one)
if (!autowrap) {
@@ -535,7 +536,7 @@ void Label::set_percent_visible(float p_percent) {
if (p_percent<0)
set_visible_characters(-1);
else
- set_visible_characters(get_total_character_count()*p_percent);
+ set_visible_characters(get_total_character_count()*p_percent);
percent_visible=p_percent;
}
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 92dcef803c..bd39fafc8b 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -164,6 +164,9 @@ void Viewport::_parent_visibility_changed() {
Control *c = parent->cast_to<Control>();
VisualServer::get_singleton()->canvas_item_set_visible(canvas_item,c->is_visible());
+
+ _update_listener();
+ _update_listener_2d();
}
@@ -394,7 +397,7 @@ void Viewport::_notification(int p_what) {
if (obj) {
CollisionObject *co = obj->cast_to<CollisionObject>();
if (co) {
- co->_input_event(ev,Vector3(),Vector3(),0);
+ co->_input_event(camera,ev,Vector3(),Vector3(),0);
captured=true;
if (ev.type==InputEvent::MOUSE_BUTTON && ev.mouse_button.button_index==1 && !ev.mouse_button.pressed) {
physics_object_capture=0;
@@ -416,7 +419,7 @@ void Viewport::_notification(int p_what) {
if (last_id) {
if (ObjectDB::get_instance(last_id)) {
//good, exists
- last_object->_input_event(ev,result.position,result.normal,result.shape);
+ last_object->_input_event(camera,ev,result.position,result.normal,result.shape);
if (last_object->get_capture_input_on_drag() && ev.type==InputEvent::MOUSE_BUTTON && ev.mouse_button.button_index==1 && ev.mouse_button.pressed) {
physics_object_capture=last_id;
}
@@ -440,10 +443,13 @@ void Viewport::_notification(int p_what) {
bool col = space->intersect_ray(from,from+dir*10000,result,Set<RID>(),0xFFFFFFFF,0xFFFFFFFF);
ObjectID new_collider=0;
if (col) {
+
if (result.collider) {
+
CollisionObject *co = result.collider->cast_to<CollisionObject>();
if (co) {
- co->_input_event(ev,result.position,result.normal,result.shape);
+
+ co->_input_event(camera,ev,result.position,result.normal,result.shape);
last_object=co;
last_id=result.collider_id;
new_collider=last_id;
@@ -541,7 +547,7 @@ Rect2 Viewport::get_rect() const {
void Viewport::_update_listener() {
- if (is_inside_scene() && audio_listener && camera) {
+ if (is_inside_scene() && audio_listener && camera && (!get_parent() || (get_parent()->cast_to<Control>() && get_parent()->cast_to<Control>()->is_visible()))) {
SpatialSoundServer::get_singleton()->listener_set_space(listener,find_world()->get_sound_space());
} else {
SpatialSoundServer::get_singleton()->listener_set_space(listener,RID());
@@ -552,7 +558,7 @@ void Viewport::_update_listener() {
void Viewport::_update_listener_2d() {
- if (is_inside_scene() && audio_listener_2d)
+ if (is_inside_scene() && audio_listener && camera && (!get_parent() || (get_parent()->cast_to<Control>() && get_parent()->cast_to<Control>()->is_visible())))
SpatialSound2DServer::get_singleton()->listener_set_space(listener_2d,find_world_2d()->get_sound_space());
else
SpatialSound2DServer::get_singleton()->listener_set_space(listener_2d,RID());
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 2a1cca6a3a..1902ff686b 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -100,6 +100,7 @@
#include "scene/2d/sample_player_2d.h"
#include "scene/2d/screen_button.h"
#include "scene/2d/remote_transform_2d.h"
+#include "scene/2d/y_sort.h"
#include "scene/2d/position_2d.h"
#include "scene/2d/tile_map.h"
@@ -491,6 +492,7 @@ void register_scene_types() {
ObjectTypeDB::register_type<VisibilityNotifier2D>();
ObjectTypeDB::register_type<VisibilityEnabler2D>();
ObjectTypeDB::register_type<Polygon2D>();
+ ObjectTypeDB::register_type<YSort>();
ObjectTypeDB::set_type_enabled("CollisionShape2D",false);
ObjectTypeDB::set_type_enabled("CollisionPolygon2D",false);
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index 67f45ced2b..e6359f920b 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -1716,7 +1716,7 @@ void Animation::clear() {
}
-void Animation::_transform_track_optimize(int p_idx,float p_alowed_linear_err,float p_alowed_angular_err) {
+void Animation::_transform_track_optimize(int p_idx,float p_alowed_linear_err,float p_alowed_angular_err,float p_max_optimizable_angle) {
ERR_FAIL_INDEX(p_idx,tracks.size());
ERR_FAIL_COND(tracks[p_idx]->type!=TYPE_TRANSFORM);
@@ -1779,6 +1779,7 @@ void Animation::_transform_track_optimize(int p_idx,float p_alowed_linear_err,fl
} else {
+
Quat r02 = (q0.inverse() * q2).normalized();
Quat r01 = (q0.inverse() * q1).normalized();
@@ -1788,6 +1789,9 @@ void Animation::_transform_track_optimize(int p_idx,float p_alowed_linear_err,fl
r02.get_axis_and_angle(v02,a02);
r01.get_axis_and_angle(v01,a01);
+ if (Math::abs(a02)>p_max_optimizable_angle)
+ continue;
+
if (v01.dot(v02)<0) {
//make sure both rotations go the same way to compare
v02=-v02;
@@ -1905,7 +1909,7 @@ void Animation::_transform_track_optimize(int p_idx,float p_alowed_linear_err,fl
}
-void Animation::optimize(float p_allowed_linear_err,float p_allowed_angular_err) {
+void Animation::optimize(float p_allowed_linear_err,float p_allowed_angular_err,float p_angle_max) {
int total_tt=0;
@@ -1913,7 +1917,7 @@ void Animation::optimize(float p_allowed_linear_err,float p_allowed_angular_err)
for(int i=0;i<tracks.size();i++) {
if (tracks[i]->type==TYPE_TRANSFORM)
- _transform_track_optimize(i,p_allowed_linear_err,p_allowed_angular_err);
+ _transform_track_optimize(i,p_allowed_linear_err,p_allowed_angular_err,p_angle_max);
}
diff --git a/scene/resources/animation.h b/scene/resources/animation.h
index 4c4e2f0275..0c0290295a 100644
--- a/scene/resources/animation.h
+++ b/scene/resources/animation.h
@@ -204,7 +204,7 @@ private:
return idxr;
}
- void _transform_track_optimize(int p_idx, float p_allowed_err=0.05, float p_alowed_angular_err=0.01);
+ void _transform_track_optimize(int p_idx, float p_allowed_err=0.05, float p_alowed_angular_err=0.01,float p_max_optimizable_angle=Math_PI*0.125);
protected:
@@ -271,7 +271,7 @@ public:
void clear();
- void optimize(float p_allowed_linear_err=0.05,float p_allowed_angular_err=0.01);
+ void optimize(float p_allowed_linear_err=0.05,float p_allowed_angular_err=0.01,float p_max_optimizable_angle=Math_PI*0.125);
Animation();
~Animation();
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 3bd7314778..3109556922 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -225,22 +225,34 @@ Error PackedScene::_parse_node(Node *p_owner,Node *p_node,int p_parent_idx, Map<
p_node->get_property_list(&plist);
for (List<PropertyInfo>::Element *E=plist.front();E;E=E->next()) {
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
+
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue;
+ }
String name = E->get().name;
Variant value = p_node->get( E->get().name );
- if (E->get().usage & PROPERTY_USAGE_STORE_IF_NONZERO && value.is_zero())
+ if (E->get().usage & PROPERTY_USAGE_STORE_IF_NONZERO && value.is_zero()) {
continue;
+ }
if (nd.instance>=0) {
//only save changed properties in instance
- if (!instance_state.has(name))
+ /*
+ // this was commented because it would not save properties created from within script
+ // done with _get_property_list, that are not in the original node.
+ // if some property is not saved, check again
+
+ if (!instance_state.has(name)) {
+ print_line("skip not in instance");
continue;
- if (instance_state[name]==value)
+ }*/
+
+ if (instance_state[name]==value) {
continue;
+ }
}
diff --git a/servers/physics/area_pair_sw.cpp b/servers/physics/area_pair_sw.cpp
index 4a303d3fdd..5938e716e9 100644
--- a/servers/physics/area_pair_sw.cpp
+++ b/servers/physics/area_pair_sw.cpp
@@ -67,7 +67,6 @@ void AreaPairSW::solve(float p_step) {
AreaPairSW::AreaPairSW(BodySW *p_body,int p_body_shape, AreaSW *p_area,int p_area_shape) {
-
body=p_body;
area=p_area;
body_shape=p_body_shape;
@@ -75,6 +74,8 @@ AreaPairSW::AreaPairSW(BodySW *p_body,int p_body_shape, AreaSW *p_area,int p_are
colliding=false;
body->add_constraint(this,0);
area->add_constraint(this);
+ if (p_body->get_mode()==PhysicsServer::BODY_MODE_KINEMATIC)
+ p_body->set_active(true);
}
diff --git a/servers/physics/area_sw.cpp b/servers/physics/area_sw.cpp
index 8192a98400..4c9ac814be 100644
--- a/servers/physics/area_sw.cpp
+++ b/servers/physics/area_sw.cpp
@@ -148,8 +148,6 @@ void AreaSW::call_queries() {
return;
}
-
-
for (Map<BodyKey,BodyState>::Element *E=monitored_bodies.front();E;E=E->next()) {
if (E->get().state==0)
@@ -182,8 +180,8 @@ AreaSW::AreaSW() : CollisionObjectSW(TYPE_AREA), monitor_query_list(this), move
point_attenuation=1;
density=0.1;
priority=0;
- ray_pickable=false;
-
+ set_ray_pickable(false);
+ monitor_callback_id=0;
}
diff --git a/servers/physics/area_sw.h b/servers/physics/area_sw.h
index a864055d17..c0c6e5c2ae 100644
--- a/servers/physics/area_sw.h
+++ b/servers/physics/area_sw.h
@@ -48,7 +48,6 @@ class AreaSW : public CollisionObjectSW{
float point_attenuation;
float density;
int priority;
- bool ray_pickable;
ObjectID monitor_callback_id;
StringName monitor_callback_method;
@@ -139,8 +138,6 @@ public:
_FORCE_INLINE_ void remove_constraint( ConstraintSW* p_constraint) { constraints.erase(p_constraint); }
_FORCE_INLINE_ const Set<ConstraintSW*>& get_constraints() const { return constraints; }
- _FORCE_INLINE_ void set_ray_pickable(bool p_enable) { ray_pickable=p_enable; }
- _FORCE_INLINE_ bool is_ray_pickable() const { return ray_pickable; }
diff --git a/servers/physics/collision_object_sw.cpp b/servers/physics/collision_object_sw.cpp
index f34aa19cae..c8e1fc4022 100644
--- a/servers/physics/collision_object_sw.cpp
+++ b/servers/physics/collision_object_sw.cpp
@@ -217,4 +217,5 @@ CollisionObjectSW::CollisionObjectSW(Type p_type) {
space=NULL;
instance_id=0;
layer_mask=1;
+ ray_pickable=true;
}
diff --git a/servers/physics/collision_object_sw.h b/servers/physics/collision_object_sw.h
index e717cc257c..98d05538a8 100644
--- a/servers/physics/collision_object_sw.h
+++ b/servers/physics/collision_object_sw.h
@@ -94,6 +94,9 @@ protected:
virtual void _shapes_changed()=0;
void _set_space(SpaceSW *space);
+ bool ray_pickable;
+
+
CollisionObjectSW(Type p_type);
public:
@@ -119,6 +122,9 @@ public:
_FORCE_INLINE_ Transform get_inv_transform() const { return inv_transform; }
_FORCE_INLINE_ SpaceSW* get_space() const { return space; }
+ _FORCE_INLINE_ void set_ray_pickable(bool p_enable) { ray_pickable=p_enable; }
+ _FORCE_INLINE_ bool is_ray_pickable() const { return ray_pickable; }
+
_FORCE_INLINE_ void set_layer_mask(uint32_t p_mask) { layer_mask=p_mask; }
_FORCE_INLINE_ uint32_t get_layer_mask() const { return layer_mask; }
diff --git a/servers/physics/constraint_sw.h b/servers/physics/constraint_sw.h
index 1be96422e1..5e79c4b54c 100644
--- a/servers/physics/constraint_sw.h
+++ b/servers/physics/constraint_sw.h
@@ -38,12 +38,13 @@ class ConstraintSW {
uint64_t island_step;
ConstraintSW *island_next;
ConstraintSW *island_list_next;
+ int priority;
RID self;
protected:
- ConstraintSW(BodySW **p_body_ptr=NULL,int p_body_count=0) { _body_ptr=p_body_ptr; _body_count=p_body_count; island_step=0; }
+ ConstraintSW(BodySW **p_body_ptr=NULL,int p_body_count=0) { _body_ptr=p_body_ptr; _body_count=p_body_count; island_step=0; priority=1; }
public:
_FORCE_INLINE_ void set_self(const RID& p_self) { self=p_self; }
@@ -62,6 +63,9 @@ public:
_FORCE_INLINE_ BodySW **get_body_ptr() const { return _body_ptr; }
_FORCE_INLINE_ int get_body_count() const { return _body_count; }
+ _FORCE_INLINE_ void set_priority(int p_priority) { priority=p_priority; }
+ _FORCE_INLINE_ int get_priority() const { return priority; }
+
virtual bool setup(float p_step)=0;
virtual void solve(float p_step)=0;
diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp
index 043d2149fe..31c4d8f121 100644
--- a/servers/physics/physics_server_sw.cpp
+++ b/servers/physics/physics_server_sw.cpp
@@ -836,6 +836,22 @@ void PhysicsServerSW::body_set_force_integration_callback(RID p_body,Object *p_r
}
+void PhysicsServerSW::body_set_ray_pickable(RID p_body,bool p_enable) {
+
+ BodySW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+ body->set_ray_pickable(p_enable);
+
+}
+
+bool PhysicsServerSW::body_is_ray_pickable(RID p_body) const{
+
+ BodySW *body = body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body,false);
+ return body->is_ray_pickable();
+
+}
+
/* JOINT API */
@@ -1000,6 +1016,21 @@ bool PhysicsServerSW::hinge_joint_get_flag(RID p_joint,HingeJointFlag p_flag) co
return hinge_joint->get_flag(p_flag);
}
+void PhysicsServerSW::joint_set_solver_priority(RID p_joint,int p_priority) {
+
+ JointSW *joint = joint_owner.get(p_joint);
+ ERR_FAIL_COND(!joint);
+ joint->set_priority(p_priority);
+}
+
+int PhysicsServerSW::joint_get_solver_priority(RID p_joint) const{
+
+ JointSW *joint = joint_owner.get(p_joint);
+ ERR_FAIL_COND_V(!joint,0);
+ return joint->get_priority();
+
+}
+
PhysicsServerSW::JointType PhysicsServerSW::joint_get_type(RID p_joint) const {
JointSW *joint = joint_owner.get(p_joint);
diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h
index 76e5aecf55..6609a78662 100644
--- a/servers/physics/physics_server_sw.h
+++ b/servers/physics/physics_server_sw.h
@@ -201,6 +201,9 @@ public:
virtual void body_set_force_integration_callback(RID p_body,Object *p_receiver,const StringName& p_method,const Variant& p_udata=Variant());
+ virtual void body_set_ray_pickable(RID p_body,bool p_enable);
+ virtual bool body_is_ray_pickable(RID p_body) const;
+
/* JOINT API */
virtual RID joint_create_pin(RID p_body_A,const Vector3& p_local_A,RID p_body_B,const Vector3& p_local_B);
@@ -244,6 +247,9 @@ public:
virtual JointType joint_get_type(RID p_joint) const;
+ virtual void joint_set_solver_priority(RID p_joint,int p_priority);
+ virtual int joint_get_solver_priority(RID p_joint) const;
+
#if 0
virtual void joint_set_param(RID p_joint, JointParam p_param, real_t p_value);
virtual real_t joint_get_param(RID p_joint,JointParam p_param) const;
diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp
index 68d6b464ab..4e8b60b86b 100644
--- a/servers/physics/space_sw.cpp
+++ b/servers/physics/space_sw.cpp
@@ -71,12 +71,13 @@ bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3& p_from, const Vecto
real_t min_d=1e10;
+
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 (space->intersection_query_results[i]->get_type()==CollisionObjectSW::TYPE_AREA && !(static_cast<AreaSW*>(space->intersection_query_results[i])->is_ray_pickable()))
+ if (!(static_cast<AreaSW*>(space->intersection_query_results[i])->is_ray_pickable()))
continue;
if (p_exclude.has( space->intersection_query_results[i]->get_self()))
@@ -97,6 +98,8 @@ bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3& p_from, const Vecto
if (shape->intersect_segment(local_from,local_to,shape_point,shape_normal)) {
+
+
Transform xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
shape_point=xform.xform(shape_point);
diff --git a/servers/physics/step_sw.cpp b/servers/physics/step_sw.cpp
index 6d95804875..b7d06d207b 100644
--- a/servers/physics/step_sw.cpp
+++ b/servers/physics/step_sw.cpp
@@ -27,7 +27,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "step_sw.h"
-
+#include "joints_sw.h"
void StepSW::_populate_island(BodySW* p_body,BodySW** p_island,ConstraintSW **p_constraint_island) {
@@ -68,14 +68,41 @@ void StepSW::_setup_island(ConstraintSW *p_island,float p_delta) {
void StepSW::_solve_island(ConstraintSW *p_island,int p_iterations,float p_delta){
- for(int i=0;i<p_iterations;i++) {
+ int at_priority=1;
- ConstraintSW *ci=p_island;
- while(ci) {
- ci->solve(p_delta);
- ci=ci->get_island_next();
+ while(p_island) {
+
+ for(int i=0;i<p_iterations;i++) {
+
+ ConstraintSW *ci=p_island;
+ while(ci) {
+ ci->solve(p_delta);
+ ci=ci->get_island_next();
+ }
+ }
+
+ at_priority++;
+
+ {
+ ConstraintSW *ci=p_island;
+ ConstraintSW *prev=NULL;
+ while(ci) {
+ if (ci->get_priority()<at_priority) {
+ if (prev) {
+ prev->set_island_next(ci->get_island_next()); //remove
+ } else {
+ p_island=ci->get_island_next();
+ }
+ } else {
+
+ prev=ci;
+ }
+
+ ci=ci->get_island_next();
+ }
}
}
+
}
void StepSW::_check_suspend(BodySW *p_island,float p_delta) {
diff --git a/servers/physics_2d/area_2d_sw.cpp b/servers/physics_2d/area_2d_sw.cpp
index 58035eb656..8be583c235 100644
--- a/servers/physics_2d/area_2d_sw.cpp
+++ b/servers/physics_2d/area_2d_sw.cpp
@@ -180,6 +180,7 @@ Area2DSW::Area2DSW() : CollisionObject2DSW(TYPE_AREA), monitor_query_list(this),
gravity_vector=Vector2(0,-1);
gravity_is_point=false;
point_attenuation=1;
+
density=0.1;
priority=0;
monitor_callback_id=0;
diff --git a/servers/physics_2d/area_pair_2d_sw.cpp b/servers/physics_2d/area_pair_2d_sw.cpp
index 35286bdb67..1c7f73db5e 100644
--- a/servers/physics_2d/area_pair_2d_sw.cpp
+++ b/servers/physics_2d/area_pair_2d_sw.cpp
@@ -75,6 +75,8 @@ AreaPair2DSW::AreaPair2DSW(Body2DSW *p_body,int p_body_shape, Area2DSW *p_area,i
colliding=false;
body->add_constraint(this,0);
area->add_constraint(this);
+ if (p_body->get_mode()==Physics2DServer::BODY_MODE_KINEMATIC) //need to be active to process pair
+ p_body->set_active(true);
}
diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp
index dc8e4cc298..fbed5779ff 100644
--- a/servers/physics_server.cpp
+++ b/servers/physics_server.cpp
@@ -520,6 +520,9 @@ void PhysicsServer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("body_set_force_integration_callback","body","receiver","method","userdata"),&PhysicsServer::body_set_force_integration_callback,DEFVAL(Variant()));
+ ObjectTypeDB::bind_method(_MD("body_set_ray_pickable","body","enable"),&PhysicsServer::body_set_ray_pickable);
+ ObjectTypeDB::bind_method(_MD("body_is_ray_pickable","body"),&PhysicsServer::body_is_ray_pickable);
+
/* JOINT API */
BIND_CONSTANT( JOINT_PIN );
@@ -627,6 +630,9 @@ void PhysicsServer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("joint_get_type","joint"),&PhysicsServer::joint_get_type);
+ ObjectTypeDB::bind_method(_MD("joint_set_solver_priority","joint","priority"),&PhysicsServer::joint_set_solver_priority);
+ ObjectTypeDB::bind_method(_MD("joint_get_solver_priority","joint"),&PhysicsServer::joint_get_solver_priority);
+
ObjectTypeDB::bind_method(_MD("joint_create_generic_6dof","body_A","local_ref_A","body_B","local_ref_B"),&PhysicsServer::joint_create_generic_6dof);
ObjectTypeDB::bind_method(_MD("generic_6dof_joint_set_param","joint","axis","param","value"),&PhysicsServer::generic_6dof_joint_set_param);
diff --git a/servers/physics_server.h b/servers/physics_server.h
index 25a89775a8..0c2542a66c 100644
--- a/servers/physics_server.h
+++ b/servers/physics_server.h
@@ -450,6 +450,10 @@ public:
virtual void body_set_force_integration_callback(RID p_body,Object *p_receiver,const StringName& p_method,const Variant& p_udata=Variant())=0;
+ virtual void body_set_ray_pickable(RID p_body,bool p_enable)=0;
+ virtual bool body_is_ray_pickable(RID p_body) const=0;
+
+
/* JOINT API */
enum JointType {
@@ -464,6 +468,8 @@ public:
virtual JointType joint_get_type(RID p_joint) const=0;
+ virtual void joint_set_solver_priority(RID p_joint,int p_priority)=0;
+ virtual int joint_get_solver_priority(RID p_joint) const=0;
virtual RID joint_create_pin(RID p_body_A,const Vector3& p_local_A,RID p_body_B,const Vector3& p_local_B)=0;
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index f8d38d15c0..a2b1b71f99 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -57,6 +57,7 @@ void register_server_types() {
ObjectTypeDB::register_virtual_type<Physics2DShapeQueryResult>();
ObjectTypeDB::register_type<Physics2DShapeQueryParameters>();
+ ObjectTypeDB::register_type<PhysicsShapeQueryParameters>();
ObjectTypeDB::register_virtual_type<PhysicsDirectBodyState>();
ObjectTypeDB::register_virtual_type<PhysicsDirectSpaceState>();
ObjectTypeDB::register_virtual_type<PhysicsShapeQueryResult>();
diff --git a/servers/spatial_sound/spatial_sound_server_sw.cpp b/servers/spatial_sound/spatial_sound_server_sw.cpp
index 7ec29d32cb..d00deb3912 100644
--- a/servers/spatial_sound/spatial_sound_server_sw.cpp
+++ b/servers/spatial_sound/spatial_sound_server_sw.cpp
@@ -879,10 +879,13 @@ void SpatialSoundServerSW::update(float p_delta) {
float volume_attenuation = 0.0;
float air_absorption_hf_cutoff = 0.0;
float air_absorption = 0.0;
- float pitch_scale=0.0;
+ float pitch_scale=1.0;
Vector3 panning;
+ //print_line("listeners: "+itos(space->listeners.size()));
+
+
for(Set<RID>::Element *L=space->listeners.front();L;L=L->next()) {
Listener *listener=listener_owner.get(L->get());
@@ -899,9 +902,11 @@ void SpatialSoundServerSW::update(float p_delta) {
float attenuation_exp=source->params[SOURCE_PARAM_ATTENUATION_DISTANCE_EXP];
float attenuation=1;
+ //print_line("DIST MIN: "+rtos(distance_min));
+ //print_line("DIST MAX: "+rtos(distance_max));
if (distance_max>0) {
distance = CLAMP(distance,distance_min,distance_max);
- attenuation = Math::pow(1.0 - ((distance - distance_min)/distance_max),CLAMP(attenuation_exp,0.001,16));
+ attenuation = Math::pow(1.0 - ((distance - distance_min)/(distance_max-distance_min)),CLAMP(attenuation_exp,0.001,16));
}
float hf_attenuation_cutoff = room->params[ROOM_PARAM_ATTENUATION_HF_CUTOFF];
@@ -945,7 +950,7 @@ void SpatialSoundServerSW::update(float p_delta) {
air_absorption+=weight*absorption;
air_absorption_hf_cutoff+=weight*hf_attenuation_cutoff;
panning+=vpanning*weight;
- pitch_scale+=pscale*weight;
+ //pitch_scale+=pscale*weight;
}
@@ -991,8 +996,8 @@ void SpatialSoundServerSW::update(float p_delta) {
reverb_send*=volume_scale;
int mix_rate = v.sample_mix_rate*v.pitch_scale*pitch_scale*source->params[SOURCE_PARAM_PITCH_SCALE];
- if (mix_rate<=0) {
+ if (mix_rate<=0) {
ERR_PRINT("Invalid mix rate for voice (0) check for invalid pitch_scale param.");
to_disable.push_back(ActiveVoice(source,voice)); // oh well..
continue; //invalid mix rate, disabling
diff --git a/servers/spatial_sound_2d/spatial_sound_2d_server_sw.cpp b/servers/spatial_sound_2d/spatial_sound_2d_server_sw.cpp
index e3c8aba758..2aab0e7dc9 100644
--- a/servers/spatial_sound_2d/spatial_sound_2d_server_sw.cpp
+++ b/servers/spatial_sound_2d/spatial_sound_2d_server_sw.cpp
@@ -904,7 +904,7 @@ void SpatialSound2DServerSW::update(float p_delta) {
if (distance_max>0) {
distance = CLAMP(distance,distance_min,distance_max);
- attenuation = Math::pow(1.0 - ((distance - distance_min)/distance_max),CLAMP(attenuation_exp,0.001,16));
+ attenuation = Math::pow(1.0 - ((distance - distance_min)/(distance_max-distance_min)),CLAMP(attenuation_exp,0.001,16));
}
float hf_attenuation_cutoff = room->params[ROOM_PARAM_ATTENUATION_HF_CUTOFF];
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index 21ecd4030d..6d5627877b 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -1202,7 +1202,7 @@ RID VisualServerRaster::camera_create() {
}
void VisualServerRaster::camera_set_perspective(RID p_camera,float p_fovy_degrees, float p_z_near, float p_z_far) {
- VS_CHANGED;
+ VS_CHANGED
Camera *camera = camera_owner.get( p_camera );
ERR_FAIL_COND(!camera);
camera->type=Camera::PERSPECTIVE;
@@ -1226,7 +1226,7 @@ void VisualServerRaster::camera_set_transform(RID p_camera,const Transform& p_tr
VS_CHANGED;
Camera *camera = camera_owner.get( p_camera );
ERR_FAIL_COND(!camera);
- camera->transform=p_transform;
+ camera->transform=p_transform.orthonormalized();
}
@@ -3531,6 +3531,15 @@ void VisualServerRaster::canvas_item_add_set_blend_mode(RID p_item, MaterialBlen
canvas_item->commands.push_back(bm);
};
+void VisualServerRaster::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) {
+
+ VS_CHANGED;
+ CanvasItem *canvas_item = canvas_item_owner.get( p_item );
+ ERR_FAIL_COND(!canvas_item);
+ canvas_item->sort_y=p_enable;
+}
+
+
void VisualServerRaster::canvas_item_add_clip_ignore(RID p_item, bool p_ignore) {
VS_CHANGED;
@@ -5591,26 +5600,30 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
float opacity = ci->opacity * p_opacity;
-#ifndef ONTOP_DISABLED
- CanvasItem **child_items = ci->child_items.ptr();
+
int child_item_count=ci->child_items.size();
- int top_item_count=0;
- CanvasItem **top_items=(CanvasItem**)alloca(child_item_count*sizeof(CanvasItem*));
+ CanvasItem **child_items=(CanvasItem**)alloca(child_item_count*sizeof(CanvasItem*));
+ copymem(child_items,ci->child_items.ptr(),child_item_count*sizeof(CanvasItem*));
if (ci->clip) {
rasterizer->canvas_set_clip(true,global_rect);
canvas_clip=global_rect;
}
+ if (ci->sort_y) {
+
+ SortArray<CanvasItem*,CanvasItemPtrSort> sorter;
+ sorter.sort(child_items,child_item_count);
+ }
+
+
for(int i=0;i<child_item_count;i++) {
if (child_items[i]->ontop)
- top_items[top_item_count++]=child_items[i];
- else {
- _render_canvas_item(child_items[i],xform,p_clip_rect,opacity);
- }
+ continue;
+ _render_canvas_item(child_items[i],xform,p_clip_rect,opacity);
}
-#endif
+
if (s!=0) {
@@ -5746,19 +5759,12 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
rasterizer->canvas_set_clip(true,canvas_clip);
}
-#ifndef ONTOP_DISABLED
-
- for(int i=0;i<top_item_count;i++) {
-
- _render_canvas_item(top_items[i],xform,p_clip_rect,opacity);
- }
-
-#else
- for(int i=0;i<p_canvas_item->child_items.size();i++) {
+ for(int i=0;i<child_item_count;i++) {
- _render_canvas_item(p_canvas_item->child_items[i],xform,p_clip_rect,opacity);
+ if (!child_items[i]->ontop)
+ continue;
+ _render_canvas_item(child_items[i],xform,p_clip_rect,opacity);
}
-#endif
if (ci->clip) {
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 49e7996c59..41ad3aab15 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -328,7 +328,7 @@ class VisualServerRaster : public VisualServer {
-
+
struct CanvasItem {
@@ -446,13 +446,14 @@ class VisualServerRaster : public VisualServer {
bool clip;
bool visible;
bool ontop;
+ bool sort_y;
float opacity;
float self_opacity;
MaterialBlendMode blend_mode;
RID viewport;
mutable bool custom_rect;
- mutable bool rect_dirty;
+ mutable bool rect_dirty;
mutable Rect2 rect;
Vector<Command*> commands;
@@ -460,11 +461,18 @@ class VisualServerRaster : public VisualServer {
const Rect2& get_rect() const;
void clear() { for (int i=0;i<commands.size();i++) memdelete( commands[i] ); commands.clear(); clip=false; rect_dirty=true;};
- CanvasItem() { clip=false; E=NULL; opacity=1; self_opacity=1; blend_mode=MATERIAL_BLEND_MODE_MIX; visible=true; rect_dirty=true; custom_rect=false; ontop=true; }
+ CanvasItem() { clip=false; E=NULL; opacity=1; self_opacity=1; blend_mode=MATERIAL_BLEND_MODE_MIX; visible=true; rect_dirty=true; custom_rect=false; ontop=true; sort_y=false;}
~CanvasItem() { clear(); }
};
+ struct CanvasItemPtrSort {
+
+ _FORCE_INLINE_ bool operator()(const CanvasItem* p_left,const CanvasItem* p_right) const {
+
+ return p_left->xform.elements[2].y < p_right->xform.elements[2].y;
+ }
+ };
struct Canvas {
@@ -1135,6 +1143,7 @@ public:
virtual void canvas_item_add_set_transform(RID p_item,const Matrix32& p_transform);
virtual void canvas_item_add_set_blend_mode(RID p_item, MaterialBlendMode p_blend);
virtual void canvas_item_add_clip_ignore(RID p_item, bool p_ignore);
+ virtual void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable);
virtual void canvas_item_clear(RID p_item);
virtual void canvas_item_raise(RID p_item);
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index f1ba4c453b..73e736f684 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -1107,6 +1107,8 @@ public:
FUNC2(canvas_item_add_set_blend_mode,RID, MaterialBlendMode );
FUNC2(canvas_item_add_clip_ignore,RID, bool );
+ FUNC2(canvas_item_set_sort_children_by_y,RID,bool);
+
FUNC1(canvas_item_clear,RID);
FUNC1(canvas_item_raise,RID);
diff --git a/servers/visual_server.h b/servers/visual_server.h
index 8934fa7903..166e4907b5 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -944,6 +944,7 @@ public:
virtual void canvas_item_add_set_transform(RID p_item,const Matrix32& p_transform)=0;
virtual void canvas_item_add_set_blend_mode(RID p_item, MaterialBlendMode p_blend)=0;
virtual void canvas_item_add_clip_ignore(RID p_item, bool p_ignore)=0;
+ virtual void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable)=0;
virtual void canvas_item_clear(RID p_item)=0;
virtual void canvas_item_raise(RID p_item)=0;
diff --git a/tools/collada/collada.cpp b/tools/collada/collada.cpp
index e29888b433..16b15426df 100644
--- a/tools/collada/collada.cpp
+++ b/tools/collada/collada.cpp
@@ -2144,6 +2144,7 @@ void Collada::_parse_scene(XMLParser& parser) {
if (name=="instance_visual_scene") {
state.root_visual_scene=_uri_to_id(parser.get_attribute_value("url"));
+ print_line("***ROOT VISUAL SCENE: "+state.root_visual_scene);
} if (name=="instance_physics_scene") {
state.root_physics_scene=_uri_to_id(parser.get_attribute_value("url"));
@@ -2513,6 +2514,9 @@ bool Collada::_move_geometry_to_skeletons(VisualScene *p_vscene,Node *p_node,Lis
ERR_FAIL_COND_V( !state.scene_map.has( nodeid ), false); //weird, it should have it...
NodeJoint *nj = SAFE_CAST<NodeJoint*>(state.scene_map[nodeid]);
ERR_FAIL_COND_V(!nj,false);
+ if (!nj->owner) {
+ print_line("Has no owner: "+nj->name);
+ }
ERR_FAIL_COND_V( !nj->owner,false ); //weird, node should have a skeleton owner
NodeSkeleton *sk = nj->owner;
diff --git a/tools/editor/io_plugins/editor_font_import_plugin.cpp b/tools/editor/io_plugins/editor_font_import_plugin.cpp
index 4b3e052907..6a6ee8c614 100644
--- a/tools/editor/io_plugins/editor_font_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_font_import_plugin.cpp
@@ -92,6 +92,7 @@ public:
String gradient_image;
+ bool disable_filter;
bool round_advance;
@@ -153,6 +154,8 @@ public:
color_use_monochrome=p_value;
else if (n=="advanced/round_advance")
round_advance=p_value;
+ else if (n=="advanced/disable_filter")
+ disable_filter=p_value;
else
return false;
@@ -217,6 +220,8 @@ public:
r_ret=color_use_monochrome;
else if (n=="advanced/round_advance")
r_ret=round_advance;
+ else if (n=="advanced/disable_filter")
+ r_ret=disable_filter;
else
return false;
@@ -265,6 +270,7 @@ public:
}
p_list->push_back(PropertyInfo(Variant::BOOL,"color/monochrome"));
p_list->push_back(PropertyInfo(Variant::BOOL,"advanced/round_advance"));
+ p_list->push_back(PropertyInfo(Variant::BOOL,"advanced/disable_filter"));
}
@@ -302,6 +308,7 @@ public:
color_use_monochrome=false;
round_advance=true;
+ disable_filter=false;
}
@@ -331,6 +338,7 @@ public:
color_use_monochrome=false;
round_advance=true;
+ disable_filter=false;
}
@@ -1260,6 +1268,7 @@ Ref<Font> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata
int space_space = from->get_option("extra_space/space");
int top_space = from->get_option("extra_space/top");
int bottom_space = from->get_option("extra_space/bottom");
+ bool disable_filter = from->get_option("advanced/disable_filter");
Ref<Font> font;
@@ -1279,7 +1288,12 @@ Ref<Font> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata
//register texures
{
Ref<ImageTexture> t = memnew(ImageTexture);
- t->create_from_image(atlas);
+ int flags;
+ if (disable_filter)
+ flags=0;
+ else
+ flags=Texture::FLAG_FILTER;
+ t->create_from_image(atlas,flags);
t->set_storage( ImageTexture::STORAGE_COMPRESS_LOSSLESS );
font->add_texture(t);
diff --git a/tools/editor/io_plugins/editor_import_collada.cpp b/tools/editor/io_plugins/editor_import_collada.cpp
index 9bee47ca66..95ee1f92e2 100644
--- a/tools/editor/io_plugins/editor_import_collada.cpp
+++ b/tools/editor/io_plugins/editor_import_collada.cpp
@@ -1829,9 +1829,9 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
if (p_clip>=0 && collada.state.animation_clips[p_clip].end)
anim_length=collada.state.animation_clips[p_clip].end;
- while(f<collada.state.animation_length) {
- if (f>=collada.state.animation_length)
- f=collada.state.animation_length;
+ while(f<anim_length) {
+ if (f>=anim_length)
+ f=anim_length;
base_snapshots.push_back(f);
f+=snapshot_interval;
diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.cpp b/tools/editor/io_plugins/editor_scene_import_plugin.cpp
index 2482728c87..c2cd5ff525 100644
--- a/tools/editor/io_plugins/editor_scene_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_scene_import_plugin.cpp
@@ -40,6 +40,7 @@
#include "scene/3d/body_shape.h"
#include "scene/3d/physics_body.h"
#include "scene/3d/portal.h"
+#include "scene/3d/vehicle_body.h"
#include "os/os.h"
@@ -649,9 +650,10 @@ const EditorSceneImportDialog::FlagInfo EditorSceneImportDialog::scene_flag_name
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_BILLBOARDS,"Create","Create Billboards (-bb)",true},
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_IMPOSTORS,"Create","Create Impostors (-imp:dist)",true},
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_LODS,"Create","Create LODs (-lod:dist)",true},
- {EditorSceneImportPlugin::SCENE_FLAG_CREATE_CARS,"Create","Create Cars (-car)",true},
- {EditorSceneImportPlugin::SCENE_FLAG_CREATE_WHEELS,"Create","Create Car Wheels (-wheel)",true},
+ {EditorSceneImportPlugin::SCENE_FLAG_CREATE_CARS,"Create","Create Vehicles (-vehicle)",true},
+ {EditorSceneImportPlugin::SCENE_FLAG_CREATE_WHEELS,"Create","Create Vehicle Wheels (-wheel)",true},
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_NAVMESH,"Create","Create Navigation Meshes (-navmesh)",true},
+ {EditorSceneImportPlugin::SCENE_FLAG_DETECT_LIGHTMAP_LAYER,"Create","Detect LightMap Layer (-lm:<int>).",true},
{-1,NULL,NULL,false}
};
@@ -1199,6 +1201,17 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>
}
}
}
+
+
+ if (p_flags&SCENE_FLAG_DETECT_LIGHTMAP_LAYER && _teststr(name,"lm") && p_node->cast_to<MeshInstance>()) {
+
+ MeshInstance *mi = p_node->cast_to<MeshInstance>();
+
+ String str=name;
+ int layer = str.substr(str.find("lm")+3,str.length()).to_int();
+ mi->set_baked_light_texture_id(layer);
+ }
+
if (p_flags&SCENE_FLAG_CREATE_COLLISIONS && _teststr(name,"colonly") && p_node->cast_to<MeshInstance>()) {
if (isroot)
@@ -1262,6 +1275,46 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>
p_node->replace_by(nmi);
memdelete(p_node);
p_node=nmi;
+ } else if (p_flags&SCENE_FLAG_CREATE_CARS &&_teststr(name,"vehicle")) {
+
+ if (isroot)
+ return p_node;
+
+ Node *owner = p_node->get_owner();
+ Spatial *s = p_node->cast_to<Spatial>();
+ VehicleBody *bv = memnew( VehicleBody );
+ String n = _fixstr(p_node->get_name(),"vehicle");
+ bv->set_name(n);
+ p_node->replace_by(bv);
+ p_node->set_name(n);
+ bv->add_child(p_node);
+ bv->set_owner(owner);
+ p_node->set_owner(owner);
+ bv->set_transform(s->get_transform());
+ s->set_transform(Transform());
+
+ p_node=bv;
+
+
+ } else if (p_flags&SCENE_FLAG_CREATE_CARS &&_teststr(name,"wheel")) {
+
+ if (isroot)
+ return p_node;
+
+ Node *owner = p_node->get_owner();
+ Spatial *s = p_node->cast_to<Spatial>();
+ VehicleWheel *bv = memnew( VehicleWheel );
+ String n = _fixstr(p_node->get_name(),"wheel");
+ bv->set_name(n);
+ p_node->replace_by(bv);
+ p_node->set_name(n);
+ bv->add_child(p_node);
+ bv->set_owner(owner);
+ p_node->set_owner(owner);
+ bv->set_transform(s->get_transform());
+ s->set_transform(Transform());
+
+ p_node=bv;
} else if (p_flags&SCENE_FLAG_CREATE_ROOMS && _teststr(name,"room") && p_node->cast_to<MeshInstance>()) {
diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.h b/tools/editor/io_plugins/editor_scene_import_plugin.h
index 3b39f0c962..6095ecf387 100644
--- a/tools/editor/io_plugins/editor_scene_import_plugin.h
+++ b/tools/editor/io_plugins/editor_scene_import_plugin.h
@@ -125,6 +125,7 @@ public:
SCENE_FLAG_DETECT_ALPHA=1<<15,
SCENE_FLAG_DETECT_VCOLOR=1<<16,
SCENE_FLAG_CREATE_NAVMESH=1<<17,
+ SCENE_FLAG_DETECT_LIGHTMAP_LAYER=1<<18,
SCENE_FLAG_REMOVE_NOIMP=1<<24,
SCENE_FLAG_IMPORT_ANIMATIONS=1<<25,
diff --git a/tools/editor/plugins/sample_player_editor_plugin.cpp b/tools/editor/plugins/sample_player_editor_plugin.cpp
index fa8a285e4e..f3d6fe65da 100644
--- a/tools/editor/plugins/sample_player_editor_plugin.cpp
+++ b/tools/editor/plugins/sample_player_editor_plugin.cpp
@@ -64,6 +64,8 @@ void SamplePlayerEditor::_play() {
return;
node->call("play",samples->get_item_text( samples->get_selected() ));
+ stop->set_pressed(false);
+ play->set_pressed(true);
}
void SamplePlayerEditor::_stop() {
@@ -74,6 +76,9 @@ void SamplePlayerEditor::_stop() {
return;
node->call("stop_all");
+ print_line("STOP ALL!!");
+ stop->set_pressed(true);
+ play->set_pressed(false);
}
diff --git a/tools/editor/plugins/spatial_editor_plugin.cpp b/tools/editor/plugins/spatial_editor_plugin.cpp
index a5cddc20e6..b87b250b22 100644
--- a/tools/editor/plugins/spatial_editor_plugin.cpp
+++ b/tools/editor/plugins/spatial_editor_plugin.cpp
@@ -1925,6 +1925,15 @@ void SpatialEditorViewport::_menu_option(int p_option) {
call_deferred("update_transform_gizmo_view");
} break;
+ case VIEW_AUDIO_LISTENER: {
+
+ int idx = view_menu->get_popup()->get_item_index(VIEW_AUDIO_LISTENER);
+ bool current = view_menu->get_popup()->is_item_checked( idx );
+ current=!current;
+ viewport->set_as_audio_listener(current);
+ view_menu->get_popup()->set_item_checked( idx, current );
+
+ } break;
}
@@ -2055,6 +2064,13 @@ void SpatialEditorViewport::set_state(const Dictionary& p_state) {
_menu_option(VIEW_PERSPECTIVE);
if (env != camera->get_environment().is_valid())
_menu_option(VIEW_ENVIRONMENT);
+ if (p_state.has("listener")) {
+ bool listener = p_state["listener"];
+
+ int idx = view_menu->get_popup()->get_item_index(VIEW_AUDIO_LISTENER);
+ viewport->set_as_audio_listener(listener);
+ view_menu->get_popup()->set_item_checked( idx, listener );
+ }
}
@@ -2068,6 +2084,7 @@ Dictionary SpatialEditorViewport::get_state() const {
d["distance"]=cursor.distance;
d["use_environment"]=camera->get_environment().is_valid();
d["use_orthogonal"]=camera->get_projection()==Camera::PROJECTION_ORTHOGONAL;
+ d["listener"]=viewport->is_audio_listener();
return d;
}
@@ -2148,6 +2165,9 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
view_menu->get_popup()->add_check_item("Environment",VIEW_ENVIRONMENT);
view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_ENVIRONMENT),true);
view_menu->get_popup()->add_separator();
+ view_menu->get_popup()->add_check_item("Audio Listener",VIEW_AUDIO_LISTENER);
+
+ view_menu->get_popup()->add_separator();
view_menu->get_popup()->add_item("Selection (F)",VIEW_CENTER_TO_SELECTION);
view_menu->get_popup()->add_item("Align with view (Ctrl+Shift+F)",VIEW_ALIGN_SELECTION_WITH_VIEW);
view_menu->get_popup()->connect("item_pressed",this,"_menu_option");
@@ -2163,6 +2183,12 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
previewing=NULL;
preview=NULL;
gizmo_scale=1.0;
+
+ if (p_index==0) {
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_AUDIO_LISTENER),true);
+ viewport->set_as_audio_listener(true);
+ }
+
EditorSettings::get_singleton()->connect("settings_changed",this,"update_transform_gizmo_view");
}
@@ -3307,6 +3333,11 @@ void SpatialEditor::clear() {
}
}
+ for(int i=0;i<4;i++) {
+
+ viewports[i]->view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(SpatialEditorViewport::VIEW_AUDIO_LISTENER),i==0);
+ viewports[i]->viewport->set_as_audio_listener(i==0);
+ }
view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_GRID), true );
diff --git a/tools/editor/plugins/spatial_editor_plugin.h b/tools/editor/plugins/spatial_editor_plugin.h
index 4bbddbac58..0cfdbfaf47 100644
--- a/tools/editor/plugins/spatial_editor_plugin.h
+++ b/tools/editor/plugins/spatial_editor_plugin.h
@@ -65,7 +65,7 @@ public:
class SpatialEditorViewport : public Control {
OBJ_TYPE( SpatialEditorViewport, Control );
-
+friend class SpatialEditor;
enum {
VIEW_TOP,
@@ -78,7 +78,8 @@ class SpatialEditorViewport : public Control {
VIEW_ALIGN_SELECTION_WITH_VIEW,
VIEW_PERSPECTIVE,
VIEW_ENVIRONMENT,
- VIEW_ORTHOGONAL
+ VIEW_ORTHOGONAL,
+ VIEW_AUDIO_LISTENER,
};
enum {
GIZMO_BASE_LAYER=25
diff --git a/tools/editor/plugins/tile_map_editor_plugin.cpp b/tools/editor/plugins/tile_map_editor_plugin.cpp
index 09f26c8ca0..a25997108b 100644
--- a/tools/editor/plugins/tile_map_editor_plugin.cpp
+++ b/tools/editor/plugins/tile_map_editor_plugin.cpp
@@ -166,7 +166,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
Matrix32 xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * node->get_global_transform();
Matrix32 xform_inv = xform.affine_inverse();
- Vector2 snap = Vector2(1,1)*node->get_cell_size();
+ Vector2 snap = node->get_cell_size();
switch(p_event.type) {
@@ -218,7 +218,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
if (mb.mod.shift) {
tool=TOOL_SELECTING;
- selection_begin =(xform_inv.xform(Point2(mb.x,mb.y))/snap).floor();
+ selection_begin =node->world_to_map(xform_inv.xform(Point2(mb.x,mb.y)));
selection.pos=selection_begin;
selection.size=Point2(0,0);
selection_active=true;
@@ -229,7 +229,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
int id = get_selected_tile();
if (id!=TileMap::INVALID_CELL) {
tool=TOOL_PAINTING;
- Point2i local =(xform_inv.xform(Point2(mb.x,mb.y))/snap).floor();
+ Point2i local =node->world_to_map((xform_inv.xform(Point2(mb.x,mb.y))));
paint_undo.clear();
CellOp op;
op.idx = node->get_cell(local.x,local.y);
@@ -278,7 +278,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
} else if (mb.pressed && tool==TOOL_NONE) {
tool=TOOL_ERASING;
- Point2i local =(xform_inv.xform(Point2(mb.x,mb.y))/snap).floor();
+ Point2i local =node->world_to_map(xform_inv.xform(Point2(mb.x,mb.y)));
paint_undo.clear();
CellOp op;
op.idx = node->get_cell(local.x,local.y);
@@ -322,7 +322,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
const InputEventMouseMotion &mm=p_event.mouse_motion;
- Point2i new_over_tile = (xform_inv.xform(Point2(mm.x,mm.y))/snap).floor();
+ Point2i new_over_tile = node->world_to_map(xform_inv.xform(Point2(mm.x,mm.y)));//(xform_inv.xform(Point2(mm.x,mm.y))/snap).floor();
if (new_over_tile!=over_tile) {
over_tile=new_over_tile;
@@ -469,44 +469,104 @@ void TileMapEditor::_canvas_draw() {
if (!node)
return;
- int cell_size=node->get_cell_size();
+ Size2 cell_size=node->get_cell_size();
+ Matrix32 cell_xf = node->get_cell_transform();
Matrix32 xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * node->get_global_transform();
Matrix32 xform_inv = xform.affine_inverse();
Size2 screen_size=canvas_item_editor->get_size();
- Rect2 aabb;
- aabb.pos=xform_inv.xform(Vector2());
- aabb.expand_to(xform_inv.xform(Vector2(0,screen_size.height)));
- aabb.expand_to(xform_inv.xform(Vector2(screen_size.width,0)));
- aabb.expand_to(xform_inv.xform(screen_size));
- Rect2i si=aabb;
+ {
+ Rect2 aabb;
+ aabb.pos=node->world_to_map(xform_inv.xform(Vector2()));
+ aabb.expand_to(node->world_to_map(xform_inv.xform(Vector2(0,screen_size.height))));
+ aabb.expand_to(node->world_to_map(xform_inv.xform(Vector2(screen_size.width,0))));
+ aabb.expand_to(node->world_to_map(xform_inv.xform(screen_size)));
+ Rect2i si=aabb.grow(1.0);
- for(int i=(si.pos.x/cell_size)-1;i<=(si.pos.x+si.size.x)/cell_size;i++) {
+ if (node->get_half_offset()!=TileMap::HALF_OFFSET_X) {
- int ofs = i*cell_size;
+ for(int i=(si.pos.x)-1;i<=(si.pos.x+si.size.x);i++) {
- Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2);
- canvas_item_editor->draw_line(xform.xform(Point2(ofs,si.pos.y)),xform.xform(Point2(ofs,si.pos.y+si.size.y)),col,1);
+ Vector2 from = xform.xform(node->map_to_world(Vector2(i,si.pos.y)));
+ Vector2 to = xform.xform(node->map_to_world(Vector2(i,si.pos.y+si.size.y+1)));
- }
+ Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2);
+ canvas_item_editor->draw_line(from,to,col,1);
+
+ }
+ } else {
- for(int i=(si.pos.y/cell_size)-1;i<=(si.pos.y+si.size.y)/cell_size;i++) {
- int ofs = i*cell_size;
+ for(int i=(si.pos.x)-1;i<=(si.pos.x+si.size.x);i++) {
+
+ for(int j=(si.pos.y)-1;j<=(si.pos.y+si.size.y);j++) {
+
+ Vector2 ofs;
+ if (ABS(j)&1) {
+ ofs=cell_xf[0]*0.5;
+ }
+
+ Vector2 from = xform.xform(node->map_to_world(Vector2(i,j),true)+ofs);
+ Vector2 to = xform.xform(node->map_to_world(Vector2(i,j+1),true)+ofs);
+ Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2);
+ canvas_item_editor->draw_line(from,to,col,1);
+ }
+
+ }
+ }
+
+ if (node->get_half_offset()!=TileMap::HALF_OFFSET_Y) {
+
+ for(int i=(si.pos.y)-1;i<=(si.pos.y+si.size.y);i++) {
+
+ Vector2 from = xform.xform(node->map_to_world(Vector2(si.pos.x,i)));
+ Vector2 to = xform.xform(node->map_to_world(Vector2(si.pos.x+si.size.x+1,i)));
+
+ Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2);
+ canvas_item_editor->draw_line(from,to,col,1);
+
+ }
+ } else {
+
+
+ for(int i=(si.pos.y)-1;i<=(si.pos.y+si.size.y);i++) {
+
+ for(int j=(si.pos.x)-1;j<=(si.pos.x+si.size.x);j++) {
+
+ Vector2 ofs;
+ if (ABS(j)&1) {
+ ofs=cell_xf[1]*0.5;
+ }
+
+ Vector2 from = xform.xform(node->map_to_world(Vector2(j,i),true)+ofs);
+ Vector2 to = xform.xform(node->map_to_world(Vector2(j+1,i),true)+ofs);
+ Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2);
+ canvas_item_editor->draw_line(from,to,col,1);
+ }
+
+ }
+
+
+
+ }
+/*
+ for(int i=(si.pos.y/cell_size.y)-1;i<=(si.pos.y+si.size.y)/cell_size.y;i++) {
+
+ int ofs = i*cell_size.y;
Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2);
- canvas_item_editor->draw_line(xform.xform(Point2(si.pos.x,ofs)),xform.xform(Point2(si.pos.x+si.size.x,ofs)),col,1);
+ canvas_item_editor->draw_line(xform.xform(Point2(si.pos.x,ofs)),xform.xform(Point2(si.pos.x+si.size.x,ofs)),col,1);*/
}
if (selection_active) {
Vector<Vector2> points;
- points.push_back( xform.xform( selection.pos * cell_size) );
- points.push_back( xform.xform( (selection.pos+Point2(selection.size.x+1,0)) * cell_size) );
- points.push_back( xform.xform( (selection.pos+Point2(selection.size.x+1,selection.size.y+1)) * cell_size) );
- points.push_back( xform.xform( (selection.pos+Point2(0,selection.size.y+1)) * cell_size) );
+ points.push_back( xform.xform( node->map_to_world(( selection.pos ) )));
+ points.push_back( xform.xform( node->map_to_world((selection.pos+Point2(selection.size.x+1,0)) ) ));
+ points.push_back( xform.xform( node->map_to_world((selection.pos+Point2(selection.size.x+1,selection.size.y+1)) ) ));
+ points.push_back( xform.xform( node->map_to_world((selection.pos+Point2(0,selection.size.y+1)) ) ));
Color col=Color(0.2,0.8,1,0.4);
canvas_item_editor->draw_colored_polygon(points,col);
@@ -515,15 +575,22 @@ void TileMapEditor::_canvas_draw() {
if (mouse_over){
- const Vector2 endpoints[4]={
-
- xform.xform( over_tile * cell_size) ,
- xform.xform( (over_tile+Point2(1,0)) * cell_size) ,
- xform.xform( (over_tile+Point2(1,1)) * cell_size) ,
- xform.xform( (over_tile+Point2(0,1)) * cell_size) ,
+ Vector2 endpoints[4]={
+ ( node->map_to_world(over_tile,true) ) ,
+ ( node->map_to_world((over_tile+Point2(1,0)),true ) ),
+ ( node->map_to_world((over_tile+Point2(1,1)),true ) ),
+ ( node->map_to_world((over_tile+Point2(0,1)),true ) )
};
+
+ for(int i=0;i<4;i++) {
+ if (node->get_half_offset()==TileMap::HALF_OFFSET_X && ABS(over_tile.y)&1)
+ endpoints[i]+=cell_xf[0]*0.5;
+ if (node->get_half_offset()==TileMap::HALF_OFFSET_Y && ABS(over_tile.x)&1)
+ endpoints[i]+=cell_xf[1]*0.5;
+ endpoints[i]=xform.xform(endpoints[i]);
+ }
Color col;
if (node->get_cell(over_tile.x,over_tile.y)!=TileMap::INVALID_CELL)
col=Color(0.2,0.8,1.0,0.8);
@@ -542,10 +609,10 @@ void TileMapEditor::_canvas_draw() {
Vector<Vector2> points;
- points.push_back( xform.xform( duplicate.pos * cell_size) );
- points.push_back( xform.xform( (duplicate.pos+Point2(duplicate.size.x+1,0)) * cell_size) );
- points.push_back( xform.xform( (duplicate.pos+Point2(duplicate.size.x+1,duplicate.size.y+1)) * cell_size) );
- points.push_back( xform.xform( (duplicate.pos+Point2(0,duplicate.size.y+1)) * cell_size) );
+ points.push_back( xform.xform( node->map_to_world(duplicate.pos ) ));
+ points.push_back( xform.xform( node->map_to_world((duplicate.pos+Point2(duplicate.size.x+1,0)) ) ));
+ points.push_back( xform.xform( node->map_to_world((duplicate.pos+Point2(duplicate.size.x+1,duplicate.size.y+1))) ));
+ points.push_back( xform.xform( node->map_to_world((duplicate.pos+Point2(0,duplicate.size.y+1))) ));
Color col=Color(0.2,1.0,0.8,0.4);
canvas_item_editor->draw_colored_polygon(points,col);
@@ -562,18 +629,19 @@ void TileMapEditor::_canvas_draw() {
Ref<Texture> t = ts->tile_get_texture(st);
if (t.is_valid()) {
- Rect2 r = ts->tile_get_region(st);
- Size2 sc = (endpoints[2]-endpoints[0])/cell_size;
+ Vector2 from = xform.xform(ts->tile_get_texture_offset(st)+node->map_to_world(over_tile)+node->get_cell_draw_offset());
+ Rect2 r = ts->tile_get_region(st);
+ Size2 sc = xform.get_scale();
if (mirror_x->is_pressed())
sc.x*=-1.0;
if (mirror_y->is_pressed())
sc.y*=-1.0;
if (r==Rect2()) {
- canvas_item_editor->draw_texture_rect(t,Rect2(endpoints[0],t->get_size()*sc),false,Color(1,1,1,0.5));
+ canvas_item_editor->draw_texture_rect(t,Rect2(from,t->get_size()*sc),false,Color(1,1,1,0.5));
} else {
- canvas_item_editor->draw_texture_rect_region(t,Rect2(endpoints[0],r.get_size()*sc),r,Color(1,1,1,0.5));
+ canvas_item_editor->draw_texture_rect_region(t,Rect2(from,r.get_size()*sc),r,Color(1,1,1,0.5));
}
}
}
diff --git a/tools/editor/plugins/tile_set_editor_plugin.cpp b/tools/editor/plugins/tile_set_editor_plugin.cpp
index 6026cda4dc..a51caf7d54 100644
--- a/tools/editor/plugins/tile_set_editor_plugin.cpp
+++ b/tools/editor/plugins/tile_set_editor_plugin.cpp
@@ -44,6 +44,7 @@ void TileSetEditor::_import_scene(Node *scene, Ref<TileSet> p_library, bool p_me
Node *child = scene->get_child(i);
+
if (!child->cast_to<Sprite>()) {
if (child->get_child_count()>0) {
child=child->get_child(0);
@@ -72,7 +73,7 @@ void TileSetEditor::_import_scene(Node *scene, Ref<TileSet> p_library, bool p_me
p_library->tile_set_texture(id,texture);
- Vector2 phys_offset = mi->get_offset();
+ Vector2 phys_offset;
if (mi->is_centered()) {
Size2 s;
@@ -112,7 +113,7 @@ void TileSetEditor::_import_scene(Node *scene, Ref<TileSet> p_library, bool p_me
}
- p_library->tile_set_texture_offset(id,Vector2());
+ p_library->tile_set_texture_offset(id,mi->get_offset());
}
}
diff --git a/tools/export/blender25/io_scene_dae/__init__.py b/tools/export/blender25/io_scene_dae/__init__.py
index fe8a383383..29fa6ed114 100644
--- a/tools/export/blender25/io_scene_dae/__init__.py
+++ b/tools/export/blender25/io_scene_dae/__init__.py
@@ -108,6 +108,11 @@ class ExportDAE(bpy.types.Operator, ExportHelper):
description=("Export all actions for the first armature found in separate DAE files"),
default=False,
)
+ use_anim_skip_noexp = BoolProperty(
+ name="Skip (-noexp) Actions",
+ description="Skip exporting of actions whose name end in (-noexp). Useful to skip control animations.",
+ default=True,
+ )
use_anim_optimize = BoolProperty(
name="Optimize Keyframes",
description="Remove double keyframes",
diff --git a/tools/export/blender25/io_scene_dae/export_dae.py b/tools/export/blender25/io_scene_dae/export_dae.py
index 867b0a00e7..801eb7ae4c 100644
--- a/tools/export/blender25/io_scene_dae/export_dae.py
+++ b/tools/export/blender25/io_scene_dae/export_dae.py
@@ -317,6 +317,7 @@ class DaeExporter:
def export_mesh(self,node,armature=None,shapename=None):
+ mesh = node.data
if (node.data in self.mesh_cache) and shapename==None:
return self.mesh_cache[mesh]
@@ -475,7 +476,12 @@ class DaeExporter:
self.writel(S_GEOM,3,'<source id="'+meshid+'-texcoord-'+str(uvi)+'">')
float_values=""
for v in vertices:
- float_values+=" "+str(v.uv[uvi].x)+" "+str(v.uv[uvi].y)
+ try:
+ float_values+=" "+str(v.uv[uvi].x)+" "+str(v.uv[uvi].y)
+ except:
+ # I don't understand this weird multi-uv-layer API, but with this it seems to works
+ float_values+=" 0 0 "
+
self.writel(S_GEOM,4,'<float_array id="'+meshid+'-texcoord-'+str(uvi)+'-array" count="'+str(len(vertices)*2)+'">'+float_values+'</float_array>')
self.writel(S_GEOM,4,'<technique_common>')
self.writel(S_GEOM,4,'<accessor source="#'+meshid+'-texcoord-'+str(uvi)+'-array" count="'+str(len(vertices))+'" stride="2">')
@@ -1156,6 +1162,8 @@ class DaeExporter:
for x in bpy.data.actions[:]:
if x.users==0 or x in self.action_constraints:
continue
+ if (self.config["use_anim_skip_noexp"] and x.name.endswith("-noexp")):
+ continue
bones=[]
#find bones used